Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure that we don't try to access fields on a non-struct pattern type #135222

Merged
merged 3 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1130,7 +1130,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
let None = following_seg else { return };
for rib in self.ribs[ValueNS].iter().rev() {
for (def_id, spans) in &rib.patterns_with_skipped_bindings {
if let Some(fields) = self.r.field_idents(*def_id) {
if let DefKind::Struct | DefKind::Variant = self.r.tcx.def_kind(*def_id)
&& let Some(fields) = self.r.field_idents(*def_id)
{
for field in fields {
if field.name == segment.ident.name {
if spans.iter().all(|(_, had_error)| had_error.is_err()) {
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Regression test for #135209.
// We ensure that we don't try to access fields on a non-struct pattern type.
fn main() {
if let <Vec<()> as Iterator>::Item { .. } = 1 {
//~^ ERROR E0658
//~| ERROR E0071
//~| ERROR E0277
x //~ ERROR E0425
}
}
34 changes: 34 additions & 0 deletions tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
error[E0425]: cannot find value `x` in this scope
--> $DIR/struct-pattern-on-non-struct-resolve-error.rs:8:9
|
LL | x
| ^ not found in this scope

error[E0658]: usage of qualified paths in this context is experimental
--> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12
|
LL | if let <Vec<()> as Iterator>::Item { .. } = 1 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #86935 <https://github.com/rust-lang/rust/issues/86935> for more information
= help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0071]: expected struct, variant or union type, found inferred type
--> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12
|
LL | if let <Vec<()> as Iterator>::Item { .. } = 1 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a struct

error[E0277]: `Vec<()>` is not an iterator
--> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12
|
LL | if let <Vec<()> as Iterator>::Item { .. } = 1 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Vec<()>` is not an iterator
|
= help: the trait `Iterator` is not implemented for `Vec<()>`

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0071, E0277, E0425, E0658.
For more information about an error, try `rustc --explain E0071`.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ struct Website {
title: Option<String>,
}

enum Foo {
Bar { a: i32 },
}

fn main() {
let website = Website {
url: "http://www.example.com".into(),
Expand All @@ -18,4 +22,9 @@ fn main() {
println!("[{}]({})", title, url); //~ ERROR cannot find value `title` in this scope
//~^ NOTE not found in this scope
}

let x = Foo::Bar { a: 1 };
if let Foo::Bar { .. } = x { //~ NOTE this pattern
println!("{a}"); //~ ERROR cannot find value `a` in this scope
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
error: expected `,`
--> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:12:31
--> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:16:31
|
LL | if let Website { url, Some(title) } = website {
| ------- ^
| |
| while parsing the fields for this pattern

error[E0425]: cannot find value `title` in this scope
--> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:18:30
--> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:22:30
|
LL | if let Website { url, .. } = website {
| ------------------- this pattern doesn't include `title`, which is available in `Website`
LL | println!("[{}]({})", title, url);
| ^^^^^ not found in this scope

error: aborting due to 2 previous errors
error[E0425]: cannot find value `a` in this scope
--> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:28:20
|
LL | if let Foo::Bar { .. } = x {
| --------------- this pattern doesn't include `a`, which is available in `Bar`
LL | println!("{a}");
| ^ help: a local variable with a similar name exists: `x`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0425`.
Loading