diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 6ee02e9f47f15..d15eca6927010 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -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()) { diff --git a/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs new file mode 100644 index 0000000000000..17a5bad0e6c0f --- /dev/null +++ b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs @@ -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 as Iterator>::Item { .. } = 1 { + //~^ ERROR E0658 + //~| ERROR E0071 + //~| ERROR E0277 + x //~ ERROR E0425 + } +} diff --git a/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr new file mode 100644 index 0000000000000..793c2d1e97fc0 --- /dev/null +++ b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr @@ -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 as Iterator>::Item { .. } = 1 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #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 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 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`. diff --git a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs index 225891e390ff5..39f9f5a2c0208 100644 --- a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs +++ b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs @@ -3,6 +3,10 @@ struct Website { title: Option, } +enum Foo { + Bar { a: i32 }, +} + fn main() { let website = Website { url: "http://www.example.com".into(), @@ -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 + } } diff --git a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr index 80fcd714400d6..b985b771754ee 100644 --- a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr +++ b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr @@ -1,5 +1,5 @@ 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 { | ------- ^ @@ -7,13 +7,21 @@ 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`.