Unnamed repository; edit this file 'description' to name the repository.
Fix shadowing of record enum variant in patterns
Chayim Refael Friedman 2024-12-04
parent e6276c8 · commit 4ec7e61
-rw-r--r--crates/hir-def/src/body/lower.rs14
-rw-r--r--crates/hir-def/src/body/tests.rs23
2 files changed, 30 insertions, 7 deletions
diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs
index 1ab49e9156..3b73d40963 100644
--- a/crates/hir-def/src/body/lower.rs
+++ b/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/crates/hir-def/src/body/tests.rs b/crates/hir-def/src/body/tests.rs
index 3b29d98d19..82d46d2e49 100644
--- a/crates/hir-def/src/body/tests.rs
+++ b/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`",
+ );
+}