summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2025-01-07 22:06:58 +0000
committerJosh Stone <jistone@redhat.com>2025-02-06 09:53:26 -0800
commit887965ddb9cbd9d40ee20a7136cca18c28ac98a7 (patch)
treeb1c1fe8fc0d129c8065fb90be1998ca3b52f0d67
parent0277061b9a4096437b9b35f471c915e1cbe3128f (diff)
downloadrust-887965ddb9cbd9d40ee20a7136cca18c28ac98a7.tar.gz
rust-887965ddb9cbd9d40ee20a7136cca18c28ac98a7.zip
Ensure that we don't try to access fields on a non-struct pattern type in diagnostic
Fix #135209.

(cherry picked from commit 5f04f98c9aaf04e5f670e04dc12d4665489859fd)
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs4
-rw-r--r--tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs7
-rw-r--r--tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr28
3 files changed, 38 insertions, 1 deletions
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 6ee02e9f47f..3957a057fdb 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 = 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 00000000000..c74c77fea60
--- /dev/null
+++ b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs
@@ -0,0 +1,7 @@
+// Regression test for #135209.
+// We ensure that we don't try to access fields on a non-struct pattern type.
+fn main() {
+    if let Iterator::Item { .. } = 1 { //~ ERROR E0223
+        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 00000000000..e31b19ab6bc
--- /dev/null
+++ b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr
@@ -0,0 +1,28 @@
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:5:9
+   |
+LL |         x
+   |         ^ not found in this scope
+
+error[E0223]: ambiguous associated type
+  --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12
+   |
+LL |     if let Iterator::Item { .. } = 1 {
+   |            ^^^^^^^^^^^^^^
+   |
+help: use fully-qualified syntax
+   |
+LL |     if let <Ancestors<'_> as Iterator>::Item { .. } = 1 {
+   |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     if let <Args as Iterator>::Item { .. } = 1 {
+   |            ~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     if let <ArgsOs as Iterator>::Item { .. } = 1 {
+   |            ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     if let <CharIndices<'_> as Iterator>::Item { .. } = 1 {
+   |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+     and 71 other candidates
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0223, E0425.
+For more information about an error, try `rustc --explain E0223`.