about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorChayim Refael Friedman <chayimfr@gmail.com>2024-12-04 04:02:54 +0200
committerChayim Refael Friedman <chayimfr@gmail.com>2024-12-04 04:02:54 +0200
commit45f0e817bbcf36320a90eeb0da212a5c804bcb47 (patch)
treea794727e4819d575822517caf8662a552a7cf872 /src
parentfef7ca07bfd5a75da9716a861707fa8abe95fa5f (diff)
downloadrust-45f0e817bbcf36320a90eeb0da212a5c804bcb47.tar.gz
rust-45f0e817bbcf36320a90eeb0da212a5c804bcb47.zip
Fix shadowing of record enum variant in patterns
Diffstat (limited to 'src')
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs14
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs23
2 files changed, 30 insertions, 7 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
index 1ab49e91569..3b73d409634 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
@@ -1510,20 +1510,20 @@ impl ExprCollector<'_> {
                         BuiltinShadowMode::Other,
                         None,
                     );
+                    // Funnily enough, record structs/variants *can* be shadowed
+                    // by pattern bindings (but unit or tuple structs/variants
+                    // can't).
                     match resolved.take_values() {
                         Some(ModuleDefId::ConstId(_)) => (None, Pat::Path(name.into())),
-                        Some(ModuleDefId::EnumVariantId(_)) => {
-                            // this is only really valid for unit variants, but
-                            // shadowing other enum variants with a pattern is
-                            // an error anyway
+                        Some(ModuleDefId::EnumVariantId(variant))
+                            if self.db.variant_data(variant.into()).kind()
+                                != StructKind::Record =>
+                        {
                             (None, Pat::Path(name.into()))
                         }
                         Some(ModuleDefId::AdtId(AdtId::StructId(s)))
                             if self.db.struct_data(s).variant_data.kind() != StructKind::Record =>
                         {
-                            // Funnily enough, record structs *can* be shadowed
-                            // by pattern bindings (but unit or tuple structs
-                            // can't).
                             (None, Pat::Path(name.into()))
                         }
                         // shadowing statics is an error as well, so we just ignore that case here
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs
index 3b29d98d198..82d46d2e492 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs
@@ -404,3 +404,26 @@ fn foo() {
         }"#]]
     .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
 }
+
+#[test]
+fn shadowing_record_variant() {
+    let (_, body, _) = lower(
+        r#"
+enum A {
+    B { field: i32 },
+}
+fn f() {
+    use A::*;
+    match () {
+        B => {}
+    };
+}
+    "#,
+    );
+    assert_eq!(body.bindings.len(), 1, "should have a binding for `B`");
+    assert_eq!(
+        body.bindings[BindingId::from_raw(RawIdx::from_u32(0))].name.as_str(),
+        "B",
+        "should have a binding for `B`",
+    );
+}