Add duplicate lowering check

This commit is contained in:
Adwin White 2024-09-15 11:10:16 +08:00
parent cb08e08722
commit 1a39247d8d
6 changed files with 38 additions and 38 deletions

View File

@ -14,15 +14,6 @@ pub(super) fn lower_block(
self.arena.alloc(self.lower_block_noalloc(hir_id, b, targeted_by_break)) self.arena.alloc(self.lower_block_noalloc(hir_id, b, targeted_by_break))
} }
pub(super) fn lower_block_with_hir_id(
&mut self,
b: &Block,
hir_id: hir::HirId,
targeted_by_break: bool,
) -> &'hir hir::Block<'hir> {
self.arena.alloc(self.lower_block_noalloc(hir_id, b, targeted_by_break))
}
pub(super) fn lower_block_noalloc( pub(super) fn lower_block_noalloc(
&mut self, &mut self,
hir_id: hir::HirId, hir_id: hir::HirId,

View File

@ -260,7 +260,7 @@ fn lower_delegation_body(
}; };
self_resolver.visit_block(block); self_resolver.visit_block(block);
// Target expr needs to lower `self` path. // Target expr needs to lower `self` path.
this.ident_to_local_id.insert(pat_node_id, param.pat.hir_id.local_id); this.ident_and_label_to_local_id.insert(pat_node_id, param.pat.hir_id.local_id);
this.lower_target_expr(&block) this.lower_target_expr(&block)
} else { } else {
this.generate_arg(param.pat.hir_id, span) this.generate_arg(param.pat.hir_id, span)

View File

@ -261,10 +261,12 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
// expr node id. // expr node id.
let block_hir_id = self.lower_node_id(blk.id); let block_hir_id = self.lower_node_id(blk.id);
let opt_label = self.lower_label(*opt_label, blk.id, block_hir_id); let opt_label = self.lower_label(*opt_label, blk.id, block_hir_id);
hir::ExprKind::Block( let hir_block = self.arena.alloc(self.lower_block_noalloc(
self.lower_block_with_hir_id(blk, block_hir_id, opt_label.is_some()), block_hir_id,
opt_label, blk,
) opt_label.is_some(),
));
hir::ExprKind::Block(hir_block, opt_label)
} }
ExprKind::Assign(el, er, span) => self.lower_expr_assign(el, er, *span, e.span), ExprKind::Assign(el, er, span) => self.lower_expr_assign(el, er, *span, e.span),
ExprKind::AssignOp(op, el, er) => hir::ExprKind::AssignOp( ExprKind::AssignOp(op, el, er) => hir::ExprKind::AssignOp(
@ -1486,7 +1488,7 @@ fn lower_label(
dest_hir_id: hir::HirId, dest_hir_id: hir::HirId,
) -> Option<Label> { ) -> Option<Label> {
let label = opt_label?; let label = opt_label?;
self.labelled_node_id_to_local_id.insert(dest_id, dest_hir_id.local_id); self.ident_and_label_to_local_id.insert(dest_id, dest_hir_id.local_id);
Some(Label { ident: self.lower_ident(label.ident) }) Some(Label { ident: self.lower_ident(label.ident) })
} }
@ -1494,7 +1496,7 @@ fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hi
let target_id = match destination { let target_id = match destination {
Some((id, _)) => { Some((id, _)) => {
if let Some(loop_id) = self.resolver.get_label_res(id) { if let Some(loop_id) = self.resolver.get_label_res(id) {
let local_id = self.labelled_node_id_to_local_id[&loop_id]; let local_id = self.ident_and_label_to_local_id[&loop_id];
let loop_hir_id = HirId { owner: self.current_hir_id_owner, local_id }; let loop_hir_id = HirId { owner: self.current_hir_id_owner, local_id };
Ok(loop_hir_id) Ok(loop_hir_id)
} else { } else {

View File

@ -154,8 +154,7 @@ pub(super) fn lower_mod(
fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> { fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
let mut ident = i.ident; let mut ident = i.ident;
let vis_span = self.lower_span(i.vis.span); let vis_span = self.lower_span(i.vis.span);
let hir_id = let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
hir::HirId { owner: self.current_hir_id_owner, local_id: hir::ItemLocalId::ZERO };
let attrs = self.lower_attrs(hir_id, &i.attrs); let attrs = self.lower_attrs(hir_id, &i.attrs);
let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, vis_span, &i.kind); let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, vis_span, &i.kind);
let item = hir::Item { let item = hir::Item {
@ -605,8 +604,7 @@ fn lower_assoc_item(
} }
fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> { fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
let hir_id = let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
hir::HirId { owner: self.current_hir_id_owner, local_id: hir::ItemLocalId::ZERO };
let owner_id = hir_id.expect_owner(); let owner_id = hir_id.expect_owner();
self.lower_attrs(hir_id, &i.attrs); self.lower_attrs(hir_id, &i.attrs);
let item = hir::ForeignItem { let item = hir::ForeignItem {
@ -730,8 +728,7 @@ pub(super) fn lower_field_def(
} }
fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> { fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
let hir_id = let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
hir::HirId { owner: self.current_hir_id_owner, local_id: hir::ItemLocalId::ZERO };
self.lower_attrs(hir_id, &i.attrs); self.lower_attrs(hir_id, &i.attrs);
let trait_item_def_id = hir_id.expect_owner(); let trait_item_def_id = hir_id.expect_owner();
@ -861,8 +858,7 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
// Since `default impl` is not yet implemented, this is always true in impls. // Since `default impl` is not yet implemented, this is always true in impls.
let has_value = true; let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value); let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
let hir_id = let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
hir::HirId { owner: self.current_hir_id_owner, local_id: hir::ItemLocalId::ZERO };
self.lower_attrs(hir_id, &i.attrs); self.lower_attrs(hir_id, &i.attrs);
let (generics, kind) = match &i.kind { let (generics, kind) = match &i.kind {

View File

@ -138,10 +138,10 @@ struct LoweringContext<'a, 'hir> {
impl_trait_defs: Vec<hir::GenericParam<'hir>>, impl_trait_defs: Vec<hir::GenericParam<'hir>>,
impl_trait_bounds: Vec<hir::WherePredicate<'hir>>, impl_trait_bounds: Vec<hir::WherePredicate<'hir>>,
/// NodeIds of labelled nodes that are lowered inside the current HIR owner. /// NodeIds of pattern identifiers and labelled nodes that are lowered inside the current HIR owner.
labelled_node_id_to_local_id: NodeMap<hir::ItemLocalId>, ident_and_label_to_local_id: NodeMap<hir::ItemLocalId>,
/// NodeIds of identifier that are lowered inside the current HIR owner. /// NodeIds that are lowered inside the current HIR owner. Only used for duplicate lowering check.
ident_to_local_id: NodeMap<hir::ItemLocalId>, node_id_to_local_id: NodeMap<hir::ItemLocalId>,
allow_try_trait: Lrc<[Symbol]>, allow_try_trait: Lrc<[Symbol]>,
allow_gen_future: Lrc<[Symbol]>, allow_gen_future: Lrc<[Symbol]>,
@ -171,8 +171,8 @@ fn new(tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering) -> Self {
current_hir_id_owner: hir::CRATE_OWNER_ID, current_hir_id_owner: hir::CRATE_OWNER_ID,
current_def_id_parent: CRATE_DEF_ID, current_def_id_parent: CRATE_DEF_ID,
item_local_id_counter: hir::ItemLocalId::ZERO, item_local_id_counter: hir::ItemLocalId::ZERO,
labelled_node_id_to_local_id: Default::default(), ident_and_label_to_local_id: Default::default(),
ident_to_local_id: Default::default(), node_id_to_local_id: Default::default(),
trait_map: Default::default(), trait_map: Default::default(),
// Lowering state. // Lowering state.
@ -589,9 +589,9 @@ fn with_hir_id_owner(
let current_attrs = std::mem::take(&mut self.attrs); let current_attrs = std::mem::take(&mut self.attrs);
let current_bodies = std::mem::take(&mut self.bodies); let current_bodies = std::mem::take(&mut self.bodies);
let current_labelled_node_id_to_local_id = let current_ident_and_label_to_local_id =
std::mem::take(&mut self.labelled_node_id_to_local_id); std::mem::take(&mut self.ident_and_label_to_local_id);
let current_ident_to_local_id = std::mem::take(&mut self.ident_to_local_id); 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_trait_map = std::mem::take(&mut self.trait_map);
let current_owner = let current_owner =
std::mem::replace(&mut self.current_hir_id_owner, hir::OwnerId { def_id }); std::mem::replace(&mut self.current_hir_id_owner, hir::OwnerId { def_id });
@ -604,6 +604,10 @@ fn with_hir_id_owner(
// we want `f` to be able to refer to the `LocalDefId`s that the caller created. // we want `f` to be able to refer to the `LocalDefId`s that the caller created.
// and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s. // 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);
let item = self.with_def_id_parent(def_id, f); let item = self.with_def_id_parent(def_id, f);
debug_assert_eq!(def_id, item.def_id().def_id); debug_assert_eq!(def_id, item.def_id().def_id);
// `f` should have consumed all the elements in these vectors when constructing `item`. // `f` should have consumed all the elements in these vectors when constructing `item`.
@ -613,8 +617,8 @@ fn with_hir_id_owner(
self.attrs = current_attrs; self.attrs = current_attrs;
self.bodies = current_bodies; self.bodies = current_bodies;
self.labelled_node_id_to_local_id = current_labelled_node_id_to_local_id; self.ident_and_label_to_local_id = current_ident_and_label_to_local_id;
self.ident_to_local_id = current_ident_to_local_id; self.node_id_to_local_id = current_node_id_to_local_id;
self.trait_map = current_trait_map; self.trait_map = current_trait_map;
self.current_hir_id_owner = current_owner; self.current_hir_id_owner = current_owner;
self.item_local_id_counter = current_local_counter; self.item_local_id_counter = current_local_counter;
@ -703,6 +707,13 @@ fn lower_node_id(&mut self, ast_node_id: NodeId) -> HirId {
self.trait_map.insert(hir_id.local_id, traits.into_boxed_slice()); self.trait_map.insert(hir_id.local_id, traits.into_boxed_slice());
} }
// Check whether the same `NodeId` is lowered more than once.
#[cfg(debug_assertions)]
{
let old = self.node_id_to_local_id.insert(ast_node_id, local_id);
assert_eq!(old, None);
}
hir_id hir_id
} }
@ -720,7 +731,7 @@ fn next_id(&mut self) -> HirId {
fn lower_res(&mut self, res: Res<NodeId>) -> Res { fn lower_res(&mut self, res: Res<NodeId>) -> Res {
let res: Result<Res, ()> = res.apply_id(|id| { let res: Result<Res, ()> = res.apply_id(|id| {
let owner = self.current_hir_id_owner; let owner = self.current_hir_id_owner;
let local_id = self.ident_to_local_id.get(&id).copied().ok_or(())?; let local_id = self.ident_and_label_to_local_id.get(&id).copied().ok_or(())?;
Ok(HirId { owner, local_id }) Ok(HirId { owner, local_id })
}); });
trace!(?res); trace!(?res);

View File

@ -270,12 +270,12 @@ fn lower_pat_ident(
}; };
// All identifiers resolves to this canonical identifier share its `HirId`. // All identifiers resolves to this canonical identifier share its `HirId`.
let binding_id = if canonical_id == p.id { let binding_id = if canonical_id == p.id {
self.ident_to_local_id.insert(canonical_id, hir_id.local_id); self.ident_and_label_to_local_id.insert(canonical_id, hir_id.local_id);
hir_id hir_id
} else { } else {
hir::HirId { hir::HirId {
owner: self.current_hir_id_owner, owner: self.current_hir_id_owner,
local_id: self.ident_to_local_id[&canonical_id], local_id: self.ident_and_label_to_local_id[&canonical_id],
} }
}; };
hir::PatKind::Binding( hir::PatKind::Binding(