mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Rollup merge of #130259 - adwinwhite:lower-node-id-once, r=cjgillot
Lower AST node id only once Fixes #96346. I basically followed the given instructions except the inline part. `lower_jump_destination` can't reuse local existing `HirId` due to unknown name resolution result so I created an additional mapping for labels. r? ```@cjgillot```
This commit is contained in:
commit
a24b3778d6
@ -10,17 +10,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
b: &Block,
|
||||
targeted_by_break: bool,
|
||||
) -> &'hir hir::Block<'hir> {
|
||||
self.arena.alloc(self.lower_block_noalloc(b, targeted_by_break))
|
||||
let hir_id = self.lower_node_id(b.id);
|
||||
self.arena.alloc(self.lower_block_noalloc(hir_id, b, targeted_by_break))
|
||||
}
|
||||
|
||||
pub(super) fn lower_block_noalloc(
|
||||
&mut self,
|
||||
hir_id: hir::HirId,
|
||||
b: &Block,
|
||||
targeted_by_break: bool,
|
||||
) -> hir::Block<'hir> {
|
||||
let (stmts, expr) = self.lower_stmts(&b.stmts);
|
||||
let rules = self.lower_block_check_mode(&b.rules);
|
||||
let hir_id = self.lower_node_id(b.id);
|
||||
hir::Block { hir_id, stmts, expr, rules, span: self.lower_span(b.span), targeted_by_break }
|
||||
}
|
||||
|
||||
|
@ -259,10 +259,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
self_param_id: pat_node_id,
|
||||
};
|
||||
self_resolver.visit_block(block);
|
||||
// Target expr needs to lower `self` path.
|
||||
this.ident_and_label_to_local_id.insert(pat_node_id, param.pat.hir_id.local_id);
|
||||
this.lower_target_expr(&block)
|
||||
} else {
|
||||
let pat_hir_id = this.lower_node_id(pat_node_id);
|
||||
this.generate_arg(pat_hir_id, span)
|
||||
this.generate_arg(param.pat.hir_id, span)
|
||||
};
|
||||
args.push(arg);
|
||||
}
|
||||
|
@ -70,8 +70,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
_ => (),
|
||||
}
|
||||
|
||||
let hir_id = self.lower_node_id(e.id);
|
||||
self.lower_attrs(hir_id, &e.attrs);
|
||||
let expr_hir_id = self.lower_node_id(e.id);
|
||||
self.lower_attrs(expr_hir_id, &e.attrs);
|
||||
|
||||
let kind = match &e.kind {
|
||||
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
|
||||
@ -175,18 +175,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
ExprKind::If(cond, then, else_opt) => {
|
||||
self.lower_expr_if(cond, then, else_opt.as_deref())
|
||||
}
|
||||
ExprKind::While(cond, body, opt_label) => self.with_loop_scope(e.id, |this| {
|
||||
let span = this.mark_span_with_reason(DesugaringKind::WhileLoop, e.span, None);
|
||||
this.lower_expr_while_in_loop_scope(span, cond, body, *opt_label)
|
||||
}),
|
||||
ExprKind::Loop(body, opt_label, span) => self.with_loop_scope(e.id, |this| {
|
||||
hir::ExprKind::Loop(
|
||||
this.lower_block(body, false),
|
||||
this.lower_label(*opt_label),
|
||||
hir::LoopSource::Loop,
|
||||
this.lower_span(*span),
|
||||
)
|
||||
}),
|
||||
ExprKind::While(cond, body, opt_label) => {
|
||||
self.with_loop_scope(expr_hir_id, |this| {
|
||||
let span =
|
||||
this.mark_span_with_reason(DesugaringKind::WhileLoop, e.span, None);
|
||||
let opt_label = this.lower_label(*opt_label, e.id, expr_hir_id);
|
||||
this.lower_expr_while_in_loop_scope(span, cond, body, opt_label)
|
||||
})
|
||||
}
|
||||
ExprKind::Loop(body, opt_label, span) => {
|
||||
self.with_loop_scope(expr_hir_id, |this| {
|
||||
let opt_label = this.lower_label(*opt_label, e.id, expr_hir_id);
|
||||
hir::ExprKind::Loop(
|
||||
this.lower_block(body, false),
|
||||
opt_label,
|
||||
hir::LoopSource::Loop,
|
||||
this.lower_span(*span),
|
||||
)
|
||||
})
|
||||
}
|
||||
ExprKind::TryBlock(body) => self.lower_expr_try_block(body),
|
||||
ExprKind::Match(expr, arms, kind) => hir::ExprKind::Match(
|
||||
self.lower_expr(expr),
|
||||
@ -212,7 +219,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
binder,
|
||||
*capture_clause,
|
||||
e.id,
|
||||
hir_id,
|
||||
expr_hir_id,
|
||||
*coroutine_kind,
|
||||
fn_decl,
|
||||
body,
|
||||
@ -223,7 +230,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
binder,
|
||||
*capture_clause,
|
||||
e.id,
|
||||
hir_id,
|
||||
expr_hir_id,
|
||||
*constness,
|
||||
*movability,
|
||||
fn_decl,
|
||||
@ -250,8 +257,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
)
|
||||
}
|
||||
ExprKind::Block(blk, opt_label) => {
|
||||
let opt_label = self.lower_label(*opt_label);
|
||||
hir::ExprKind::Block(self.lower_block(blk, opt_label.is_some()), opt_label)
|
||||
// Different from loops, label of block resolves to block id rather than
|
||||
// expr node 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 hir_block = self.arena.alloc(self.lower_block_noalloc(
|
||||
block_hir_id,
|
||||
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::AssignOp(op, el, er) => hir::ExprKind::AssignOp(
|
||||
@ -354,7 +369,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span),
|
||||
};
|
||||
|
||||
hir::Expr { hir_id, kind, span: self.lower_span(e.span) }
|
||||
hir::Expr { hir_id: expr_hir_id, kind, span: self.lower_span(e.span) }
|
||||
})
|
||||
}
|
||||
|
||||
@ -504,7 +519,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let if_expr = self.expr(span, if_kind);
|
||||
let block = self.block_expr(self.arena.alloc(if_expr));
|
||||
let span = self.lower_span(span.with_hi(cond.span.hi()));
|
||||
let opt_label = self.lower_label(opt_label);
|
||||
hir::ExprKind::Loop(block, opt_label, hir::LoopSource::While, span)
|
||||
}
|
||||
|
||||
@ -512,8 +526,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
/// `try { <stmts>; }` into `{ <stmts>; ::std::ops::Try::from_output(()) }`
|
||||
/// and save the block id to use it as a break target for desugaring of the `?` operator.
|
||||
fn lower_expr_try_block(&mut self, body: &Block) -> hir::ExprKind<'hir> {
|
||||
self.with_catch_scope(body.id, |this| {
|
||||
let mut block = this.lower_block_noalloc(body, true);
|
||||
let body_hir_id = self.lower_node_id(body.id);
|
||||
self.with_catch_scope(body_hir_id, |this| {
|
||||
let mut block = this.lower_block_noalloc(body_hir_id, body, true);
|
||||
|
||||
// Final expression of the block (if present) or `()` with span at the end of block
|
||||
let (try_span, tail_expr) = if let Some(expr) = block.expr.take() {
|
||||
@ -869,7 +884,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let x_expr = self.expr_ident(gen_future_span, x_ident, x_pat_hid);
|
||||
let ready_field = self.single_pat_field(gen_future_span, x_pat);
|
||||
let ready_pat = self.pat_lang_item_variant(span, hir::LangItem::PollReady, ready_field);
|
||||
let break_x = self.with_loop_scope(loop_node_id, move |this| {
|
||||
let break_x = self.with_loop_scope(loop_hir_id, move |this| {
|
||||
let expr_break =
|
||||
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
|
||||
this.arena.alloc(this.expr(gen_future_span, expr_break))
|
||||
@ -1101,8 +1116,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
hir::CoroutineSource::Closure,
|
||||
);
|
||||
|
||||
let hir_id = this.lower_node_id(coroutine_kind.closure_id());
|
||||
this.maybe_forward_track_caller(body.span, closure_hir_id, hir_id);
|
||||
this.maybe_forward_track_caller(body.span, closure_hir_id, expr.hir_id);
|
||||
|
||||
(parameters, expr)
|
||||
});
|
||||
@ -1465,8 +1479,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
)
|
||||
}
|
||||
|
||||
fn lower_label(&self, opt_label: Option<Label>) -> Option<Label> {
|
||||
// Record labelled expr's HirId so that we can retrieve it in `lower_jump_destination` without
|
||||
// lowering node id again.
|
||||
fn lower_label(
|
||||
&mut self,
|
||||
opt_label: Option<Label>,
|
||||
dest_id: NodeId,
|
||||
dest_hir_id: hir::HirId,
|
||||
) -> Option<Label> {
|
||||
let label = opt_label?;
|
||||
self.ident_and_label_to_local_id.insert(dest_id, dest_hir_id.local_id);
|
||||
Some(Label { ident: self.lower_ident(label.ident) })
|
||||
}
|
||||
|
||||
@ -1474,17 +1496,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let target_id = match destination {
|
||||
Some((id, _)) => {
|
||||
if let Some(loop_id) = self.resolver.get_label_res(id) {
|
||||
Ok(self.lower_node_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 };
|
||||
Ok(loop_hir_id)
|
||||
} else {
|
||||
Err(hir::LoopIdError::UnresolvedLabel)
|
||||
}
|
||||
}
|
||||
None => self
|
||||
.loop_scope
|
||||
.map(|id| Ok(self.lower_node_id(id)))
|
||||
.unwrap_or(Err(hir::LoopIdError::OutsideLoopScope)),
|
||||
None => {
|
||||
self.loop_scope.map(|id| Ok(id)).unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
|
||||
}
|
||||
};
|
||||
let label = self.lower_label(destination.map(|(_, label)| label));
|
||||
let label = destination
|
||||
.map(|(_, label)| label)
|
||||
.map(|label| Label { ident: self.lower_ident(label.ident) });
|
||||
hir::Destination { label, target_id }
|
||||
}
|
||||
|
||||
@ -1499,14 +1524,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
}
|
||||
|
||||
fn with_catch_scope<T>(&mut self, catch_id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T {
|
||||
fn with_catch_scope<T>(&mut self, catch_id: hir::HirId, f: impl FnOnce(&mut Self) -> T) -> T {
|
||||
let old_scope = self.catch_scope.replace(catch_id);
|
||||
let result = f(self);
|
||||
self.catch_scope = old_scope;
|
||||
result
|
||||
}
|
||||
|
||||
fn with_loop_scope<T>(&mut self, loop_id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T {
|
||||
fn with_loop_scope<T>(&mut self, loop_id: hir::HirId, f: impl FnOnce(&mut Self) -> T) -> T {
|
||||
// We're no longer in the base loop's condition; we're in another loop.
|
||||
let was_in_loop_condition = self.is_in_loop_condition;
|
||||
self.is_in_loop_condition = false;
|
||||
@ -1658,9 +1683,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let head_span = self.mark_span_with_reason(DesugaringKind::ForLoop, head.span, None);
|
||||
let pat_span = self.mark_span_with_reason(DesugaringKind::ForLoop, pat.span, None);
|
||||
|
||||
let loop_hir_id = self.lower_node_id(e.id);
|
||||
let label = self.lower_label(opt_label, e.id, loop_hir_id);
|
||||
|
||||
// `None => break`
|
||||
let none_arm = {
|
||||
let break_expr = self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span));
|
||||
let break_expr =
|
||||
self.with_loop_scope(loop_hir_id, |this| this.expr_break_alloc(for_span));
|
||||
let pat = self.pat_none(for_span);
|
||||
self.arm(pat, break_expr)
|
||||
};
|
||||
@ -1668,7 +1697,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// Some(<pat>) => <body>,
|
||||
let some_arm = {
|
||||
let some_pat = self.pat_some(pat_span, pat);
|
||||
let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
|
||||
let body_block =
|
||||
self.with_loop_scope(loop_hir_id, |this| this.lower_block(body, false));
|
||||
let body_expr = self.arena.alloc(self.expr_block(body_block));
|
||||
self.arm(some_pat, body_expr)
|
||||
};
|
||||
@ -1722,12 +1752,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// `[opt_ident]: loop { ... }`
|
||||
let kind = hir::ExprKind::Loop(
|
||||
loop_block,
|
||||
self.lower_label(opt_label),
|
||||
label,
|
||||
hir::LoopSource::ForLoop,
|
||||
self.lower_span(for_span.with_hi(head.span.hi())),
|
||||
);
|
||||
let loop_expr =
|
||||
self.arena.alloc(hir::Expr { hir_id: self.lower_node_id(e.id), kind, span: for_span });
|
||||
let loop_expr = self.arena.alloc(hir::Expr { hir_id: loop_hir_id, kind, span: for_span });
|
||||
|
||||
// `mut iter => { ... }`
|
||||
let iter_arm = self.arm(iter_pat, loop_expr);
|
||||
@ -1867,8 +1896,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
self.arena.alloc(residual_expr),
|
||||
unstable_span,
|
||||
);
|
||||
let ret_expr = if let Some(catch_node) = self.catch_scope {
|
||||
let target_id = Ok(self.lower_node_id(catch_node));
|
||||
let ret_expr = if let Some(catch_id) = self.catch_scope {
|
||||
let target_id = Ok(catch_id);
|
||||
self.arena.alloc(self.expr(
|
||||
try_span,
|
||||
hir::ExprKind::Break(
|
||||
@ -1922,8 +1951,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
yeeted_span,
|
||||
);
|
||||
|
||||
if let Some(catch_node) = self.catch_scope {
|
||||
let target_id = Ok(self.lower_node_id(catch_node));
|
||||
if let Some(catch_id) = self.catch_scope {
|
||||
let target_id = Ok(catch_id);
|
||||
hir::ExprKind::Break(hir::Destination { label: None, target_id }, Some(from_yeet_expr))
|
||||
} else {
|
||||
hir::ExprKind::Ret(Some(from_yeet_expr))
|
||||
|
@ -154,7 +154,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
|
||||
let mut ident = i.ident;
|
||||
let vis_span = self.lower_span(i.vis.span);
|
||||
let hir_id = self.lower_node_id(i.id);
|
||||
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
|
||||
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 item = hir::Item {
|
||||
@ -604,7 +604,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
|
||||
fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
|
||||
let hir_id = self.lower_node_id(i.id);
|
||||
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
|
||||
let owner_id = hir_id.expect_owner();
|
||||
self.lower_attrs(hir_id, &i.attrs);
|
||||
let item = hir::ForeignItem {
|
||||
@ -728,7 +728,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
|
||||
fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
|
||||
let hir_id = self.lower_node_id(i.id);
|
||||
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
|
||||
self.lower_attrs(hir_id, &i.attrs);
|
||||
let trait_item_def_id = hir_id.expect_owner();
|
||||
|
||||
@ -858,7 +858,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// Since `default impl` is not yet implemented, this is always true in impls.
|
||||
let has_value = true;
|
||||
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
|
||||
let hir_id = self.lower_node_id(i.id);
|
||||
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
|
||||
self.lower_attrs(hir_id, &i.attrs);
|
||||
|
||||
let (generics, kind) = match &i.kind {
|
||||
@ -1086,7 +1086,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
|
||||
// FIXME(async_fn_track_caller): Can this be moved above?
|
||||
let hir_id = this.lower_node_id(coroutine_kind.closure_id());
|
||||
let hir_id = expr.hir_id;
|
||||
this.maybe_forward_track_caller(body.span, fn_id, hir_id);
|
||||
|
||||
(parameters, expr)
|
||||
|
@ -40,8 +40,6 @@
|
||||
#![warn(unreachable_pub)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
use std::collections::hash_map::Entry;
|
||||
|
||||
use rustc_ast::node_id::NodeMap;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::{self as ast, *};
|
||||
@ -115,8 +113,8 @@ struct LoweringContext<'a, 'hir> {
|
||||
/// outside of an `async fn`.
|
||||
current_item: Option<Span>,
|
||||
|
||||
catch_scope: Option<NodeId>,
|
||||
loop_scope: Option<NodeId>,
|
||||
catch_scope: Option<HirId>,
|
||||
loop_scope: Option<HirId>,
|
||||
is_in_loop_condition: bool,
|
||||
is_in_trait_impl: bool,
|
||||
is_in_dyn_type: bool,
|
||||
@ -140,7 +138,10 @@ struct LoweringContext<'a, 'hir> {
|
||||
impl_trait_defs: Vec<hir::GenericParam<'hir>>,
|
||||
impl_trait_bounds: Vec<hir::WherePredicate<'hir>>,
|
||||
|
||||
/// NodeIds that are lowered inside the current HIR owner.
|
||||
/// NodeIds of pattern identifiers and labelled nodes that are lowered inside the current HIR owner.
|
||||
ident_and_label_to_local_id: NodeMap<hir::ItemLocalId>,
|
||||
/// NodeIds that are lowered inside the current HIR owner. Only used for duplicate lowering check.
|
||||
#[cfg(debug_assertions)]
|
||||
node_id_to_local_id: NodeMap<hir::ItemLocalId>,
|
||||
|
||||
allow_try_trait: Lrc<[Symbol]>,
|
||||
@ -171,6 +172,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
current_hir_id_owner: hir::CRATE_OWNER_ID,
|
||||
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(),
|
||||
|
||||
@ -588,7 +591,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
let current_attrs = std::mem::take(&mut self.attrs);
|
||||
let current_bodies = std::mem::take(&mut self.bodies);
|
||||
let current_node_ids = std::mem::take(&mut self.node_id_to_local_id);
|
||||
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 =
|
||||
std::mem::replace(&mut self.current_hir_id_owner, hir::OwnerId { def_id });
|
||||
@ -602,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);
|
||||
@ -614,7 +624,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
self.attrs = current_attrs;
|
||||
self.bodies = current_bodies;
|
||||
self.node_id_to_local_id = current_node_ids;
|
||||
self.ident_and_label_to_local_id = current_ident_and_label_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;
|
||||
@ -680,39 +695,37 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
|
||||
}
|
||||
|
||||
/// This method allocates a new `HirId` for the given `NodeId` and stores it in
|
||||
/// the `LoweringContext`'s `NodeId => HirId` map.
|
||||
/// This method allocates a new `HirId` for the given `NodeId`.
|
||||
/// Take care not to call this method if the resulting `HirId` is then not
|
||||
/// actually used in the HIR, as that would trigger an assertion in the
|
||||
/// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped
|
||||
/// properly. Calling the method twice with the same `NodeId` is fine though.
|
||||
/// properly. Calling the method twice with the same `NodeId` is also forbidden.
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn lower_node_id(&mut self, ast_node_id: NodeId) -> HirId {
|
||||
assert_ne!(ast_node_id, DUMMY_NODE_ID);
|
||||
|
||||
match self.node_id_to_local_id.entry(ast_node_id) {
|
||||
Entry::Occupied(o) => HirId { owner: self.current_hir_id_owner, local_id: *o.get() },
|
||||
Entry::Vacant(v) => {
|
||||
// Generate a new `HirId`.
|
||||
let owner = self.current_hir_id_owner;
|
||||
let local_id = self.item_local_id_counter;
|
||||
let hir_id = HirId { owner, local_id };
|
||||
let owner = self.current_hir_id_owner;
|
||||
let local_id = self.item_local_id_counter;
|
||||
assert_ne!(local_id, hir::ItemLocalId::ZERO);
|
||||
self.item_local_id_counter.increment_by(1);
|
||||
let hir_id = HirId { owner, local_id };
|
||||
|
||||
v.insert(local_id);
|
||||
self.item_local_id_counter.increment_by(1);
|
||||
|
||||
assert_ne!(local_id, hir::ItemLocalId::ZERO);
|
||||
if let Some(def_id) = self.opt_local_def_id(ast_node_id) {
|
||||
self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
|
||||
}
|
||||
|
||||
if let Some(traits) = self.resolver.trait_map.remove(&ast_node_id) {
|
||||
self.trait_map.insert(hir_id.local_id, traits.into_boxed_slice());
|
||||
}
|
||||
|
||||
hir_id
|
||||
}
|
||||
if let Some(def_id) = self.opt_local_def_id(ast_node_id) {
|
||||
self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
|
||||
}
|
||||
|
||||
if let Some(traits) = self.resolver.trait_map.remove(&ast_node_id) {
|
||||
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
|
||||
}
|
||||
|
||||
/// Generate a new `HirId` without a backing `NodeId`.
|
||||
@ -729,7 +742,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn lower_res(&mut self, res: Res<NodeId>) -> Res {
|
||||
let res: Result<Res, ()> = res.apply_id(|id| {
|
||||
let owner = self.current_hir_id_owner;
|
||||
let local_id = self.node_id_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 })
|
||||
});
|
||||
trace!(?res);
|
||||
|
@ -21,13 +21,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> {
|
||||
ensure_sufficient_stack(|| {
|
||||
// loop here to avoid recursion
|
||||
let pat_hir_id = self.lower_node_id(pattern.id);
|
||||
let node = loop {
|
||||
match &pattern.kind {
|
||||
PatKind::Wild => break hir::PatKind::Wild,
|
||||
PatKind::Never => break hir::PatKind::Never,
|
||||
PatKind::Ident(binding_mode, ident, sub) => {
|
||||
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(s));
|
||||
break self.lower_pat_ident(pattern, *binding_mode, *ident, lower_sub);
|
||||
break self.lower_pat_ident(
|
||||
pattern,
|
||||
*binding_mode,
|
||||
*ident,
|
||||
pat_hir_id,
|
||||
lower_sub,
|
||||
);
|
||||
}
|
||||
PatKind::Lit(e) => {
|
||||
break hir::PatKind::Lit(self.lower_expr_within_pat(e, false));
|
||||
@ -119,7 +126,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
};
|
||||
|
||||
self.pat_with_node_id_of(pattern, node)
|
||||
self.pat_with_node_id_of(pattern, node, pat_hir_id)
|
||||
})
|
||||
}
|
||||
|
||||
@ -187,10 +194,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let mut prev_rest_span = None;
|
||||
|
||||
// Lowers `$bm $ident @ ..` to `$bm $ident @ _`.
|
||||
let lower_rest_sub = |this: &mut Self, pat, &ann, &ident, sub| {
|
||||
let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub));
|
||||
let node = this.lower_pat_ident(pat, ann, ident, lower_sub);
|
||||
this.pat_with_node_id_of(pat, node)
|
||||
let lower_rest_sub = |this: &mut Self, pat: &Pat, &ann, &ident, sub: &Pat| {
|
||||
let sub_hir_id = this.lower_node_id(sub.id);
|
||||
let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub, sub_hir_id));
|
||||
let pat_hir_id = this.lower_node_id(pat.id);
|
||||
let node = this.lower_pat_ident(pat, ann, ident, pat_hir_id, lower_sub);
|
||||
this.pat_with_node_id_of(pat, node, pat_hir_id)
|
||||
};
|
||||
|
||||
let mut iter = pats.iter();
|
||||
@ -200,7 +209,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// Found a sub-slice pattern `..`. Record, lower it to `_`, and stop here.
|
||||
PatKind::Rest => {
|
||||
prev_rest_span = Some(pat.span);
|
||||
slice = Some(self.pat_wild_with_node_id_of(pat));
|
||||
let hir_id = self.lower_node_id(pat.id);
|
||||
slice = Some(self.pat_wild_with_node_id_of(pat, hir_id));
|
||||
break;
|
||||
}
|
||||
// Found a sub-slice pattern `$binding_mode $ident @ ..`.
|
||||
@ -248,19 +258,35 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
p: &Pat,
|
||||
annotation: BindingMode,
|
||||
ident: Ident,
|
||||
hir_id: hir::HirId,
|
||||
lower_sub: impl FnOnce(&mut Self) -> Option<&'hir hir::Pat<'hir>>,
|
||||
) -> hir::PatKind<'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,
|
||||
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(
|
||||
annotation,
|
||||
self.lower_node_id(canonical_id),
|
||||
binding_id,
|
||||
self.lower_ident(ident),
|
||||
lower_sub(self),
|
||||
)
|
||||
@ -280,18 +306,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
}
|
||||
|
||||
fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> {
|
||||
self.arena.alloc(self.pat_with_node_id_of(p, hir::PatKind::Wild))
|
||||
fn pat_wild_with_node_id_of(&mut self, p: &Pat, hir_id: hir::HirId) -> &'hir hir::Pat<'hir> {
|
||||
self.arena.alloc(self.pat_with_node_id_of(p, hir::PatKind::Wild, hir_id))
|
||||
}
|
||||
|
||||
/// Construct a `Pat` with the `HirId` of `p.id` lowered.
|
||||
fn pat_with_node_id_of(&mut self, p: &Pat, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
|
||||
hir::Pat {
|
||||
hir_id: self.lower_node_id(p.id),
|
||||
kind,
|
||||
span: self.lower_span(p.span),
|
||||
default_binding_modes: true,
|
||||
}
|
||||
/// Construct a `Pat` with the `HirId` of `p.id` already lowered.
|
||||
fn pat_with_node_id_of(
|
||||
&mut self,
|
||||
p: &Pat,
|
||||
kind: hir::PatKind<'hir>,
|
||||
hir_id: hir::HirId,
|
||||
) -> hir::Pat<'hir> {
|
||||
hir::Pat { hir_id, kind, span: self.lower_span(p.span), default_binding_modes: true }
|
||||
}
|
||||
|
||||
/// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern.
|
||||
|
@ -41,7 +41,7 @@ body:
|
||||
Block {
|
||||
targeted_by_break: false
|
||||
span: $DIR/thir-tree-match.rs:15:32: 21:2 (#0)
|
||||
region_scope: Node(25)
|
||||
region_scope: Node(3)
|
||||
safety_mode: Safe
|
||||
stmts: []
|
||||
expr:
|
||||
@ -51,8 +51,8 @@ body:
|
||||
span: $DIR/thir-tree-match.rs:16:5: 20:6 (#0)
|
||||
kind:
|
||||
Scope {
|
||||
region_scope: Node(3)
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).3))
|
||||
region_scope: Node(4)
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).4))
|
||||
value:
|
||||
Expr {
|
||||
ty: bool
|
||||
@ -67,8 +67,8 @@ body:
|
||||
span: $DIR/thir-tree-match.rs:16:11: 16:14 (#0)
|
||||
kind:
|
||||
Scope {
|
||||
region_scope: Node(4)
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).4))
|
||||
region_scope: Node(5)
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).5))
|
||||
value:
|
||||
Expr {
|
||||
ty: Foo
|
||||
@ -123,16 +123,16 @@ body:
|
||||
body:
|
||||
Expr {
|
||||
ty: bool
|
||||
temp_lifetime: Some(Node(12))
|
||||
temp_lifetime: Some(Node(13))
|
||||
span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0)
|
||||
kind:
|
||||
Scope {
|
||||
region_scope: Node(13)
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).13))
|
||||
region_scope: Node(14)
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).14))
|
||||
value:
|
||||
Expr {
|
||||
ty: bool
|
||||
temp_lifetime: Some(Node(12))
|
||||
temp_lifetime: Some(Node(13))
|
||||
span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0)
|
||||
kind:
|
||||
Literal( lit: Spanned { node: Bool(true), span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0) }, neg: false)
|
||||
@ -140,8 +140,8 @@ body:
|
||||
}
|
||||
}
|
||||
}
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).12))
|
||||
scope: Node(12)
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).13))
|
||||
scope: Node(13)
|
||||
span: $DIR/thir-tree-match.rs:17:9: 17:40 (#0)
|
||||
}
|
||||
Arm {
|
||||
@ -175,16 +175,16 @@ body:
|
||||
body:
|
||||
Expr {
|
||||
ty: bool
|
||||
temp_lifetime: Some(Node(18))
|
||||
temp_lifetime: Some(Node(19))
|
||||
span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0)
|
||||
kind:
|
||||
Scope {
|
||||
region_scope: Node(19)
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).19))
|
||||
region_scope: Node(20)
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).20))
|
||||
value:
|
||||
Expr {
|
||||
ty: bool
|
||||
temp_lifetime: Some(Node(18))
|
||||
temp_lifetime: Some(Node(19))
|
||||
span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0)
|
||||
kind:
|
||||
Literal( lit: Spanned { node: Bool(false), span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0) }, neg: false)
|
||||
@ -192,8 +192,8 @@ body:
|
||||
}
|
||||
}
|
||||
}
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).18))
|
||||
scope: Node(18)
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).19))
|
||||
scope: Node(19)
|
||||
span: $DIR/thir-tree-match.rs:18:9: 18:32 (#0)
|
||||
}
|
||||
Arm {
|
||||
@ -219,16 +219,16 @@ body:
|
||||
body:
|
||||
Expr {
|
||||
ty: bool
|
||||
temp_lifetime: Some(Node(23))
|
||||
temp_lifetime: Some(Node(24))
|
||||
span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0)
|
||||
kind:
|
||||
Scope {
|
||||
region_scope: Node(24)
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).24))
|
||||
region_scope: Node(25)
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).25))
|
||||
value:
|
||||
Expr {
|
||||
ty: bool
|
||||
temp_lifetime: Some(Node(23))
|
||||
temp_lifetime: Some(Node(24))
|
||||
span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0)
|
||||
kind:
|
||||
Literal( lit: Spanned { node: Bool(true), span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0) }, neg: false)
|
||||
@ -236,8 +236,8 @@ body:
|
||||
}
|
||||
}
|
||||
}
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).23))
|
||||
scope: Node(23)
|
||||
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).24))
|
||||
scope: Node(24)
|
||||
span: $DIR/thir-tree-match.rs:19:9: 19:28 (#0)
|
||||
}
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user