Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 45f0e81

Browse files
Fix shadowing of record enum variant in patterns
1 parent fef7ca0 commit 45f0e81

File tree

2 files changed

+30
-7
lines changed

2 files changed

+30
-7
lines changed

src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,20 +1510,20 @@ impl ExprCollector<'_> {
15101510
BuiltinShadowMode::Other,
15111511
None,
15121512
);
1513+
// Funnily enough, record structs/variants *can* be shadowed
1514+
// by pattern bindings (but unit or tuple structs/variants
1515+
// can't).
15131516
match resolved.take_values() {
15141517
Some(ModuleDefId::ConstId(_)) => (None, Pat::Path(name.into())),
1515-
Some(ModuleDefId::EnumVariantId(_)) => {
1516-
// this is only really valid for unit variants, but
1517-
// shadowing other enum variants with a pattern is
1518-
// an error anyway
1518+
Some(ModuleDefId::EnumVariantId(variant))
1519+
if self.db.variant_data(variant.into()).kind()
1520+
!= StructKind::Record =>
1521+
{
15191522
(None, Pat::Path(name.into()))
15201523
}
15211524
Some(ModuleDefId::AdtId(AdtId::StructId(s)))
15221525
if self.db.struct_data(s).variant_data.kind() != StructKind::Record =>
15231526
{
1524-
// Funnily enough, record structs *can* be shadowed
1525-
// by pattern bindings (but unit or tuple structs
1526-
// can't).
15271527
(None, Pat::Path(name.into()))
15281528
}
15291529
// shadowing statics is an error as well, so we just ignore that case here

src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,3 +404,26 @@ fn foo() {
404404
}"#]]
405405
.assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
406406
}
407+
408+
#[test]
409+
fn shadowing_record_variant() {
410+
let (_, body, _) = lower(
411+
r#"
412+
enum A {
413+
B { field: i32 },
414+
}
415+
fn f() {
416+
use A::*;
417+
match () {
418+
B => {}
419+
};
420+
}
421+
"#,
422+
);
423+
assert_eq!(body.bindings.len(), 1, "should have a binding for `B`");
424+
assert_eq!(
425+
body.bindings[BindingId::from_raw(RawIdx::from_u32(0))].name.as_str(),
426+
"B",
427+
"should have a binding for `B`",
428+
);
429+
}

0 commit comments

Comments
 (0)