diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 4ca878a1be0da..59dc369fe17f7 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -141,6 +141,7 @@ struct LoweringContext<'a, 'hir> { /// NodeIds of pattern identifiers and labelled nodes that are lowered inside the current HIR owner. ident_and_label_to_local_id: NodeMap, /// NodeIds that are lowered inside the current HIR owner. Only used for duplicate lowering check. + #[cfg(debug_assertions)] node_id_to_local_id: NodeMap, allow_try_trait: Lrc<[Symbol]>, @@ -172,6 +173,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { current_def_id_parent: CRATE_DEF_ID, item_local_id_counter: hir::ItemLocalId::ZERO, ident_and_label_to_local_id: Default::default(), + #[cfg(debug_assertions)] node_id_to_local_id: Default::default(), trait_map: Default::default(), @@ -591,6 +593,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let current_bodies = std::mem::take(&mut self.bodies); let current_ident_and_label_to_local_id = std::mem::take(&mut self.ident_and_label_to_local_id); + + #[cfg(debug_assertions)] let current_node_id_to_local_id = std::mem::take(&mut self.node_id_to_local_id); let current_trait_map = std::mem::take(&mut self.trait_map); let current_owner = @@ -605,8 +609,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s. // Always allocate the first `HirId` for the owner itself. - let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::ZERO); - debug_assert_eq!(_old, None); + #[cfg(debug_assertions)] + { + let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::ZERO); + debug_assert_eq!(_old, None); + } let item = self.with_def_id_parent(def_id, f); debug_assert_eq!(def_id, item.def_id().def_id); @@ -618,7 +625,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.attrs = current_attrs; self.bodies = current_bodies; self.ident_and_label_to_local_id = current_ident_and_label_to_local_id; - self.node_id_to_local_id = current_node_id_to_local_id; + + #[cfg(debug_assertions)] + { + self.node_id_to_local_id = current_node_id_to_local_id; + } self.trait_map = current_trait_map; self.current_hir_id_owner = current_owner; self.item_local_id_counter = current_local_counter; diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 59c0e24479a09..ace7bfb5c73f2 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -264,18 +264,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { match self.resolver.get_partial_res(p.id).map(|d| d.expect_full_res()) { // `None` can occur in body-less function signatures res @ (None | Some(Res::Local(_))) => { - let canonical_id = match res { - Some(Res::Local(id)) => id, - _ => p.id, - }; - // All identifiers resolves to this canonical identifier share its `HirId`. - let binding_id = if canonical_id == p.id { - self.ident_and_label_to_local_id.insert(canonical_id, hir_id.local_id); - hir_id - } else { - hir::HirId { - owner: self.current_hir_id_owner, - local_id: self.ident_and_label_to_local_id[&canonical_id], + let binding_id = match res { + Some(Res::Local(id)) => { + // In `Or` patterns like `VariantA(s) | VariantB(s, _)`, multiple identifier patterns + // will be resolved to the same `Res::Local`. Thus they just share a single + // `HirId`. + if id == p.id { + self.ident_and_label_to_local_id.insert(id, hir_id.local_id); + hir_id + } else { + hir::HirId { + owner: self.current_hir_id_owner, + local_id: self.ident_and_label_to_local_id[&id], + } + } + } + _ => { + self.ident_and_label_to_local_id.insert(p.id, hir_id.local_id); + hir_id } }; hir::PatKind::Binding(