Rollup merge of #120206 - petrochenkov:somehir, r=compiler-errors

hir: Make sure all `HirId`s have corresponding HIR `Node`s

And then remove `tcx.opt_hir_node(hir_id)` in favor of `tcx.hir_node(hir_id)`.
This commit is contained in:
Matthias Krüger 2024-02-08 09:06:32 +01:00 committed by GitHub
commit bf2ba8611e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
50 changed files with 348 additions and 359 deletions

View File

@ -15,7 +15,7 @@ struct NodeCollector<'a, 'hir> {
bodies: &'a SortedMap<ItemLocalId, &'hir Body<'hir>>,
/// Outputs
nodes: IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>,
nodes: IndexVec<ItemLocalId, ParentedNode<'hir>>,
parenting: LocalDefIdMap<ItemLocalId>,
/// The parent of this node
@ -29,16 +29,19 @@ pub(super) fn index_hir<'hir>(
tcx: TyCtxt<'hir>,
item: hir::OwnerNode<'hir>,
bodies: &SortedMap<ItemLocalId, &'hir Body<'hir>>,
) -> (IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>, LocalDefIdMap<ItemLocalId>) {
let mut nodes = IndexVec::new();
num_nodes: usize,
) -> (IndexVec<ItemLocalId, ParentedNode<'hir>>, LocalDefIdMap<ItemLocalId>) {
let zero_id = ItemLocalId::new(0);
let err_node = ParentedNode { parent: zero_id, node: Node::Err(item.span()) };
let mut nodes = IndexVec::from_elem_n(err_node, num_nodes);
// This node's parent should never be accessed: the owner's parent is computed by the
// hir_owner_parent query. Make it invalid (= ItemLocalId::MAX) to force an ICE whenever it is
// used.
nodes.push(Some(ParentedNode { parent: ItemLocalId::INVALID, node: item.into() }));
nodes[zero_id] = ParentedNode { parent: ItemLocalId::INVALID, node: item.into() };
let mut collector = NodeCollector {
tcx,
owner: item.def_id(),
parent_node: ItemLocalId::new(0),
parent_node: zero_id,
nodes,
bodies,
parenting: Default::default(),
@ -54,6 +57,14 @@ pub(super) fn index_hir<'hir>(
OwnerNode::ForeignItem(item) => collector.visit_foreign_item(item),
};
for (local_id, node) in collector.nodes.iter_enumerated() {
if let Node::Err(span) = node.node {
let hir_id = HirId { owner: item.def_id(), local_id };
let msg = format!("ID {hir_id} not encountered when visiting item HIR");
tcx.dcx().span_delayed_bug(*span, msg);
}
}
(collector.nodes, collector.parenting)
}
@ -88,7 +99,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
}
}
self.nodes.insert(hir_id.local_id, ParentedNode { parent: self.parent_node, node });
self.nodes[hir_id.local_id] = ParentedNode { parent: self.parent_node, node };
}
fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_node_id: HirId, f: F) {
@ -254,6 +265,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
}
fn visit_path_segment(&mut self, path_segment: &'hir PathSegment<'hir>) {
// FIXME: walk path segment with `path_segment.hir_id` parent.
self.insert(path_segment.ident.span, path_segment.hir_id, Node::PathSegment(path_segment));
intravisit::walk_path_segment(self, path_segment);
}
@ -348,4 +360,23 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
self.visit_nested_foreign_item(id);
}
fn visit_where_predicate(&mut self, predicate: &'hir WherePredicate<'hir>) {
match predicate {
WherePredicate::BoundPredicate(pred) => {
self.insert(pred.span, pred.hir_id, Node::WhereBoundPredicate(pred));
self.with_parent(pred.hir_id, |this| {
intravisit::walk_where_predicate(this, predicate)
})
}
_ => intravisit::walk_where_predicate(self, predicate),
}
}
fn visit_array_length(&mut self, len: &'hir ArrayLen) {
match len {
ArrayLen::Infer(inf) => self.insert(inf.span, inf.hir_id, Node::ArrayLenInfer(inf)),
ArrayLen::Body(..) => intravisit::walk_array_len(self, len),
}
}
}

View File

@ -675,7 +675,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} else {
(None, None)
};
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies);
let num_nodes = self.item_local_id_counter.as_usize();
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash };

View File

@ -401,66 +401,60 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
let typeck = self.infcx.tcx.typeck(self.mir_def_id());
let hir_id = hir.parent_id(expr.hir_id);
if let Some(parent) = self.infcx.tcx.opt_hir_node(hir_id) {
let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
&& let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id)
{
(def_id.as_local(), args, 1)
} else if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::Call(call, args) = parent_expr.kind
&& let ty::FnDef(def_id, _) = typeck.node_type(call.hir_id).kind()
{
(def_id.as_local(), args, 0)
} else {
(None, &[][..], 0)
let parent = self.infcx.tcx.hir_node(hir_id);
let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
&& let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id)
{
(def_id.as_local(), args, 1)
} else if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::Call(call, args) = parent_expr.kind
&& let ty::FnDef(def_id, _) = typeck.node_type(call.hir_id).kind()
{
(def_id.as_local(), args, 0)
} else {
(None, &[][..], 0)
};
if let Some(def_id) = def_id
&& let node =
self.infcx.tcx.hir_node(self.infcx.tcx.local_def_id_to_hir_id(def_id))
&& let Some(fn_sig) = node.fn_sig()
&& let Some(ident) = node.ident()
&& let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
&& let Some(arg) = fn_sig.decl.inputs.get(pos + offset)
{
let mut span: MultiSpan = arg.span.into();
span.push_span_label(
arg.span,
"this parameter takes ownership of the value".to_string(),
);
let descr = match node.fn_kind() {
Some(hir::intravisit::FnKind::ItemFn(..)) | None => "function",
Some(hir::intravisit::FnKind::Method(..)) => "method",
Some(hir::intravisit::FnKind::Closure) => "closure",
};
if let Some(def_id) = def_id
&& let Some(node) = self
.infcx
.tcx
.opt_hir_node(self.infcx.tcx.local_def_id_to_hir_id(def_id))
&& let Some(fn_sig) = node.fn_sig()
&& let Some(ident) = node.ident()
&& let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
&& let Some(arg) = fn_sig.decl.inputs.get(pos + offset)
{
let mut span: MultiSpan = arg.span.into();
span.push_span_label(
arg.span,
"this parameter takes ownership of the value".to_string(),
);
let descr = match node.fn_kind() {
Some(hir::intravisit::FnKind::ItemFn(..)) | None => "function",
Some(hir::intravisit::FnKind::Method(..)) => "method",
Some(hir::intravisit::FnKind::Closure) => "closure",
};
span.push_span_label(ident.span, format!("in this {descr}"));
err.span_note(
span,
format!(
"consider changing this parameter type in {descr} `{ident}` to \
span.push_span_label(ident.span, format!("in this {descr}"));
err.span_note(
span,
format!(
"consider changing this parameter type in {descr} `{ident}` to \
borrow instead if owning the value isn't necessary",
),
);
}
let place = &self.move_data.move_paths[mpi].place;
let ty = place.ty(self.body, self.infcx.tcx).ty;
if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::Call(call_expr, _) = parent_expr.kind
&& let hir::ExprKind::Path(hir::QPath::LangItem(
LangItem::IntoIterIntoIter,
_,
)) = call_expr.kind
{
// Do not suggest `.clone()` in a `for` loop, we already suggest borrowing.
} else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } =
move_spans
{
// We already suggest cloning for these cases in `explain_captures`.
} else {
self.suggest_cloning(err, ty, expr, move_span);
}
),
);
}
let place = &self.move_data.move_paths[mpi].place;
let ty = place.ty(self.body, self.infcx.tcx).ty;
if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::Call(call_expr, _) = parent_expr.kind
&& let hir::ExprKind::Path(hir::QPath::LangItem(LangItem::IntoIterIntoIter, _)) =
call_expr.kind
{
// Do not suggest `.clone()` in a `for` loop, we already suggest borrowing.
} else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } = move_spans
{
// We already suggest cloning for these cases in `explain_captures`.
} else {
self.suggest_cloning(err, ty, expr, move_span);
}
}
if let Some(pat) = finder.pat {
@ -1762,7 +1756,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn_decl: hir::FnDecl { inputs, .. },
..
}) = e.kind
&& let Some(hir::Node::Expr(body)) = self.tcx.opt_hir_node(body.hir_id)
&& let hir::Node::Expr(body) = self.tcx.hir_node(body.hir_id)
{
self.suggest_arg = "this: &Self".to_string();
if inputs.len() > 0 {
@ -1828,11 +1822,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}
if let Some(hir::Node::ImplItem(hir::ImplItem {
if let hir::Node::ImplItem(hir::ImplItem {
kind: hir::ImplItemKind::Fn(_fn_sig, body_id),
..
})) = self.infcx.tcx.opt_hir_node(self.mir_hir_id())
&& let Some(hir::Node::Expr(expr)) = self.infcx.tcx.opt_hir_node(body_id.hir_id)
}) = self.infcx.tcx.hir_node(self.mir_hir_id())
&& let hir::Node::Expr(expr) = self.infcx.tcx.hir_node(body_id.hir_id)
{
let mut finder = ExpressionFinder {
capture_span: *capture_kind_span,
@ -2400,8 +2394,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let proper_span = proper_span.source_callsite();
if let Some(scope) = self.body.source_scopes.get(source_info.scope)
&& let ClearCrossCrate::Set(scope_data) = &scope.local_data
&& let Some(node) = self.infcx.tcx.opt_hir_node(scope_data.lint_root)
&& let Some(id) = node.body_id()
&& let Some(id) = self.infcx.tcx.hir_node(scope_data.lint_root).body_id()
&& let hir::ExprKind::Block(block, _) = self.infcx.tcx.hir().body(id).value.kind
{
for stmt in block.stmts {

View File

@ -87,7 +87,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
if let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind
&& let [hir::PathSegment { ident, args: None, .. }] = p.segments
&& let hir::def::Res::Local(hir_id) = p.res
&& let Some(hir::Node::Pat(pat)) = tcx.opt_hir_node(hir_id)
&& let hir::Node::Pat(pat) = tcx.hir_node(hir_id)
{
err.span_label(pat.span, format!("binding `{ident}` declared here"));
}

View File

@ -396,7 +396,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let upvar_hir_id = captured_place.get_root_variable();
if let Some(Node::Pat(pat)) = self.infcx.tcx.opt_hir_node(upvar_hir_id)
if let Node::Pat(pat) = self.infcx.tcx.hir_node(upvar_hir_id)
&& let hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, upvar_ident, _) =
pat.kind
{
@ -688,15 +688,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
break;
}
f_in_trait_opt.and_then(|f_in_trait| {
match self.infcx.tcx.opt_hir_node(f_in_trait) {
Some(Node::TraitItem(hir::TraitItem {
match self.infcx.tcx.hir_node(f_in_trait) {
Node::TraitItem(hir::TraitItem {
kind:
hir::TraitItemKind::Fn(
hir::FnSig { decl: hir::FnDecl { inputs, .. }, .. },
_,
),
..
})) => {
}) => {
let hir::Ty { span, .. } = inputs[local.index() - 1];
Some(span)
}
@ -759,10 +759,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
//
// `let &b = a;` -> `let &(mut b) = a;`
if let Some(hir_id) = hir_id
&& let Some(hir::Node::Local(hir::Local {
&& let hir::Node::Local(hir::Local {
pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. },
..
})) = self.infcx.tcx.opt_hir_node(hir_id)
}) = self.infcx.tcx.hir_node(hir_id)
&& let Ok(name) =
self.infcx.tcx.sess.source_map().span_to_snippet(local_decl.source_info.span)
{
@ -1206,7 +1206,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};
if let Some(hir_id) = hir_id
&& let Some(hir::Node::Local(local)) = self.infcx.tcx.opt_hir_node(hir_id)
&& let hir::Node::Local(local) = self.infcx.tcx.hir_node(hir_id)
{
let tables = self.infcx.tcx.typeck(def_id.as_local().unwrap());
if let Some(clone_trait) = self.infcx.tcx.lang_items().clone_trait()

View File

@ -216,7 +216,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if let Some(id) = placeholder.bound.kind.get_id()
&& let Some(placeholder_id) = id.as_local()
&& let gat_hir_id = self.infcx.tcx.local_def_id_to_hir_id(placeholder_id)
&& let Some(generics_impl) = hir.get_parent(gat_hir_id).generics()
&& let Some(generics_impl) =
hir.get_parent(hir.parent_id(gat_hir_id)).generics()
{
Some((gat_hir_id, generics_impl))
} else {

View File

@ -835,7 +835,7 @@ pub struct OwnerNodes<'tcx> {
// The zeroth node's parent should never be accessed: the owner's parent is computed by the
// hir_owner_parent query. It is set to `ItemLocalId::INVALID` to force an ICE if accidentally
// used.
pub nodes: IndexVec<ItemLocalId, Option<ParentedNode<'tcx>>>,
pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
/// Content of local bodies.
pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
}
@ -843,9 +843,8 @@ pub struct OwnerNodes<'tcx> {
impl<'tcx> OwnerNodes<'tcx> {
pub fn node(&self) -> OwnerNode<'tcx> {
use rustc_index::Idx;
let node = self.nodes[ItemLocalId::new(0)].as_ref().unwrap().node;
let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode.
node
// Indexing must ensure it is an OwnerNode.
self.nodes[ItemLocalId::new(0)].node.as_owner().unwrap()
}
}
@ -860,9 +859,7 @@ impl fmt::Debug for OwnerNodes<'_> {
.nodes
.iter_enumerated()
.map(|(id, parented_node)| {
let parented_node = parented_node.as_ref().map(|node| node.parent);
debug_fn(move |f| write!(f, "({id:?}, {parented_node:?})"))
debug_fn(move |f| write!(f, "({id:?}, {:?})", parented_node.parent))
})
.collect::<Vec<_>>(),
)
@ -3351,13 +3348,15 @@ impl<'hir> OwnerNode<'hir> {
}
}
pub fn span(&self) -> Span {
// Span by reference to pass to `Node::Err`.
#[allow(rustc::pass_by_value)]
pub fn span(&self) -> &'hir Span {
match self {
OwnerNode::Item(Item { span, .. })
| OwnerNode::ForeignItem(ForeignItem { span, .. })
| OwnerNode::ImplItem(ImplItem { span, .. })
| OwnerNode::TraitItem(TraitItem { span, .. }) => *span,
OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span,
| OwnerNode::TraitItem(TraitItem { span, .. }) => span,
OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => inner_span,
}
}
@ -3486,17 +3485,19 @@ pub enum Node<'hir> {
Arm(&'hir Arm<'hir>),
Block(&'hir Block<'hir>),
Local(&'hir Local<'hir>),
/// `Ctor` refers to the constructor of an enum variant or struct. Only tuple or unit variants
/// with synthesized constructors.
Ctor(&'hir VariantData<'hir>),
Lifetime(&'hir Lifetime),
GenericParam(&'hir GenericParam<'hir>),
Crate(&'hir Mod<'hir>),
Infer(&'hir InferArg),
WhereBoundPredicate(&'hir WhereBoundPredicate<'hir>),
// FIXME: Merge into `Node::Infer`.
ArrayLenInfer(&'hir InferArg),
// Span by reference to minimize `Node`'s size
#[allow(rustc::pass_by_value)]
Err(&'hir Span),
}
impl<'hir> Node<'hir> {
@ -3541,7 +3542,10 @@ impl<'hir> Node<'hir> {
| Node::Crate(..)
| Node::Ty(..)
| Node::TraitRef(..)
| Node::Infer(..) => None,
| Node::Infer(..)
| Node::WhereBoundPredicate(..)
| Node::ArrayLenInfer(..)
| Node::Err(..) => None,
}
}

View File

@ -108,8 +108,8 @@ impl<'a> FnKind<'a> {
/// An abstract representation of the HIR `rustc_middle::hir::map::Map`.
pub trait Map<'hir> {
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
fn find(&self, hir_id: HirId) -> Option<Node<'hir>>;
/// Retrieves the `Node` corresponding to `id`.
fn hir_node(&self, hir_id: HirId) -> Node<'hir>;
fn body(&self, id: BodyId) -> &'hir Body<'hir>;
fn item(&self, id: ItemId) -> &'hir Item<'hir>;
fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
@ -119,7 +119,7 @@ pub trait Map<'hir> {
// Used when no map is actually available, forcing manual implementation of nested visitors.
impl<'hir> Map<'hir> for ! {
fn find(&self, _: HirId) -> Option<Node<'hir>> {
fn hir_node(&self, _: HirId) -> Node<'hir> {
*self;
}
fn body(&self, _: BodyId) -> &'hir Body<'hir> {
@ -669,6 +669,7 @@ pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'
pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen) {
match len {
// FIXME: Use `visit_infer` here.
ArrayLen::Infer(InferArg { hir_id, span: _ }) => visitor.visit_id(*hir_id),
ArrayLen::Body(c) => visitor.visit_anon_const(c),
}

View File

@ -43,8 +43,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
return None;
}
let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
match tcx.opt_hir_node(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
match tcx.hir_node(hir_id) {
Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }) => {
generics.params.is_empty().not().then_some(generics.span)
}
_ => {
@ -58,8 +58,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
return None;
}
let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
match tcx.opt_hir_node(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
match tcx.hir_node(hir_id) {
Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }) => {
Some(generics.where_clause_span)
}
_ => {
@ -80,8 +80,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
return None;
}
let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
match tcx.opt_hir_node(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. })) => {
match tcx.hir_node(hir_id) {
Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. }) => {
Some(fn_sig.decl.output.span())
}
_ => {
@ -202,7 +202,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
let start_t = tcx.type_of(start_def_id).instantiate_identity();
match start_t.kind() {
ty::FnDef(..) => {
if let Some(Node::Item(it)) = tcx.opt_hir_node(start_id) {
if let Node::Item(it) = tcx.hir_node(start_id) {
if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
let mut error = false;
if !generics.params.is_empty() {

View File

@ -509,6 +509,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
},
Node::ArrayLenInfer(_) => tcx.types.usize,
x => {
bug!("unexpected sort of node in type_of(): {:?}", x);
}

View File

@ -771,8 +771,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
);
if let Some(parent_node) = self.tcx.hir().opt_parent_id(self.path_segment.hir_id)
&& let Some(parent_node) = self.tcx.opt_hir_node(parent_node)
&& let hir::Node::Expr(expr) = parent_node
&& let hir::Node::Expr(expr) = self.tcx.hir_node(parent_node)
{
match &expr.kind {
hir::ExprKind::Path(qpath) => self

View File

@ -23,7 +23,7 @@ use std::cell::Cell;
use std::vec;
pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: hir::HirId) -> String {
to_string(&map, |s| s.print_node(map.find(hir_id).unwrap()))
to_string(&map, |s| s.print_node(map.hir_node(hir_id)))
}
pub enum AnnNode<'a> {
@ -117,6 +117,13 @@ impl<'a> State<'a> {
Node::Ctor(..) => panic!("cannot print isolated Ctor"),
Node::Local(a) => self.print_local_decl(a),
Node::Crate(..) => panic!("cannot print Crate"),
Node::WhereBoundPredicate(pred) => {
self.print_formal_generic_params(pred.bound_generic_params);
self.print_type(pred.bounded_ty);
self.print_bounds(":", pred.bounds);
}
Node::ArrayLenInfer(_) => self.word("_"),
Node::Err(_) => self.word("/*ERROR*/"),
}
}
}

View File

@ -1715,8 +1715,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
let ret_msg = "return a value for the case when the loop has zero elements to iterate on";
let ret_ty_msg =
"otherwise consider changing the return type to account for that possibility";
if let Some(node) = tcx.opt_hir_node(item.into())
&& let Some(body_id) = node.body_id()
let node = tcx.hir_node(item.into());
if let Some(body_id) = node.body_id()
&& let Some(sig) = node.fn_sig()
&& let hir::ExprKind::Block(block, _) = hir.body(body_id).value.kind
&& !ty.is_never()

View File

@ -561,11 +561,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut parent;
'outer: loop {
// Climb the HIR tree to see if the current `Expr` is part of a `break;` statement.
let Some(
hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Semi(&ref p), .. })
| hir::Node::Block(hir::Block { expr: Some(&ref p), .. })
| hir::Node::Expr(&ref p),
) = self.tcx.opt_hir_node(parent_id)
let (hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Semi(&ref p), .. })
| hir::Node::Block(hir::Block { expr: Some(&ref p), .. })
| hir::Node::Expr(&ref p)) = self.tcx.hir_node(parent_id)
else {
break;
};
@ -578,20 +576,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut direct = false;
loop {
// Climb the HIR tree to find the (desugared) `loop` this `break` corresponds to.
let parent = match self.tcx.opt_hir_node(parent_id) {
Some(hir::Node::Expr(&ref parent)) => {
let parent = match self.tcx.hir_node(parent_id) {
hir::Node::Expr(&ref parent) => {
parent_id = self.tcx.hir().parent_id(parent.hir_id);
parent
}
Some(hir::Node::Stmt(hir::Stmt {
hir::Node::Stmt(hir::Stmt {
hir_id,
kind: hir::StmtKind::Semi(&ref parent) | hir::StmtKind::Expr(&ref parent),
..
})) => {
}) => {
parent_id = self.tcx.hir().parent_id(*hir_id);
parent
}
Some(hir::Node::Block(_)) => {
hir::Node::Block(_) => {
parent_id = self.tcx.hir().parent_id(parent_id);
parent
}
@ -680,17 +678,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
error: Option<TypeError<'tcx>>,
) {
let parent = self.tcx.hir().parent_id(expr.hir_id);
match (self.tcx.opt_hir_node(parent), error) {
(Some(hir::Node::Local(hir::Local { ty: Some(ty), init: Some(init), .. })), _)
match (self.tcx.hir_node(parent), error) {
(hir::Node::Local(hir::Local { ty: Some(ty), init: Some(init), .. }), _)
if init.hir_id == expr.hir_id =>
{
// Point at `let` assignment type.
err.span_label(ty.span, "expected due to this");
}
(
Some(hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Assign(lhs, rhs, _), ..
})),
hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. }),
Some(TypeError::Sorts(ExpectedFound { expected, .. })),
) if rhs.hir_id == expr.hir_id && !expected.is_closure() => {
// We ignore closures explicitly because we already point at them elsewhere.
@ -725,7 +721,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None,
hir::Path { res: hir::def::Res::Local(hir_id), .. },
)) => {
if let Some(hir::Node::Pat(pat)) = self.tcx.opt_hir_node(*hir_id) {
if let hir::Node::Pat(pat) = self.tcx.hir_node(*hir_id) {
primary_span = pat.span;
secondary_span = pat.span;
match self.tcx.hir().find_parent(pat.hir_id) {
@ -774,9 +770,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
(
Some(hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Binary(_, lhs, rhs), ..
})),
hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(_, lhs, rhs), .. }),
Some(TypeError::Sorts(ExpectedFound { expected, .. })),
) if rhs.hir_id == expr.hir_id
&& self.typeck_results.borrow().expr_ty_adjusted_opt(lhs) == Some(expected) =>
@ -797,8 +791,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let Some(TypeError::Sorts(ExpectedFound { expected, .. })) = error else {
return;
};
let Some(hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. })) =
self.tcx.opt_hir_node(parent)
let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. }) =
self.tcx.hir_node(parent)
else {
return;
};
@ -1022,13 +1016,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::Path { res: hir::def::Res::Local(bind_hir_id), .. },
)) = expr.kind
{
let bind = self.tcx.opt_hir_node(*bind_hir_id);
let parent = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*bind_hir_id));
if let Some(hir::Node::Pat(hir::Pat {
kind: hir::PatKind::Binding(_, _hir_id, _, _),
..
})) = bind
&& let Some(hir::Node::Pat(hir::Pat { default_binding_modes: false, .. })) = parent
let bind = self.tcx.hir_node(*bind_hir_id);
let parent = self.tcx.hir_node(self.tcx.hir().parent_id(*bind_hir_id));
if let hir::Node::Pat(hir::Pat {
kind: hir::PatKind::Binding(_, _hir_id, _, _), ..
}) = bind
&& let hir::Node::Pat(hir::Pat { default_binding_modes: false, .. }) = parent
{
return true;
}

View File

@ -1017,7 +1017,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
then: impl FnOnce(&hir::Expr<'_>),
) {
let mut parent = self.tcx.hir().parent_id(original_expr_id);
while let Some(node) = self.tcx.opt_hir_node(parent) {
loop {
let node = self.tcx.hir_node(parent);
match node {
hir::Node::Expr(hir::Expr {
kind:
@ -1471,8 +1472,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
if let hir::TyKind::Array(_, length) = ty.peel_refs().kind
&& let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length
&& let Some(span) = self.tcx.hir().opt_span(hir_id)
{
let span = self.tcx.hir().span(hir_id);
match self.dcx().steal_diagnostic(span, StashKey::UnderscoreForArrayLengths) {
Some(mut err) => {
err.span_suggestion(

View File

@ -2060,7 +2060,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let node = self
.tcx
.opt_local_def_id_to_hir_id(self.tcx.hir().get_parent_item(call_expr.hir_id))
.and_then(|hir_id| self.tcx.opt_hir_node(hir_id));
.map(|hir_id| self.tcx.hir_node(hir_id));
match node {
Some(hir::Node::Item(item)) => call_finder.visit_item(item),
Some(hir::Node::TraitItem(item)) => call_finder.visit_trait_item(item),

View File

@ -682,8 +682,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// is and we were expecting a Box, ergo Pin<Box<expected>>, we
// can suggest Box::pin.
let parent = self.tcx.hir().parent_id(expr.hir_id);
let Some(Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. })) =
self.tcx.opt_hir_node(parent)
let Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. }) =
self.tcx.hir_node(parent)
else {
return false;
};
@ -908,9 +908,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ty::Param(expected_ty_as_param) = expected.kind() else { return };
let fn_node = self.tcx.opt_hir_node(fn_id);
let fn_node = self.tcx.hir_node(fn_id);
let Some(hir::Node::Item(hir::Item {
let hir::Node::Item(hir::Item {
kind:
hir::ItemKind::Fn(
hir::FnSig {
@ -921,7 +921,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_body_id,
),
..
})) = fn_node
}) = fn_node
else {
return;
};
@ -1053,9 +1053,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
let ty = self.normalize(expr.span, ty);
if self.can_coerce(found, ty) {
if let Some(node) = self.tcx.opt_hir_node(fn_id)
&& let Some(owner_node) = node.as_owner()
&& let Some(span) = expr.span.find_ancestor_inside(owner_node.span())
if let Some(owner_node) = self.tcx.hir_node(fn_id).as_owner()
&& let Some(span) = expr.span.find_ancestor_inside(*owner_node.span())
{
err.multipart_suggestion(
"you might have meant to return this value",
@ -1684,15 +1683,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None,
hir::Path { segments: [_], res: crate::Res::Local(binding), .. },
)) => {
let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) = self.tcx.opt_hir_node(*binding)
else {
return expr;
};
let Some(parent) = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*hir_id)) else {
let hir::Node::Pat(hir::Pat { hir_id, .. }) = self.tcx.hir_node(*binding) else {
return expr;
};
match parent {
match self.tcx.hir_node(self.tcx.hir().parent_id(*hir_id)) {
// foo.clone()
hir::Node::Local(hir::Local { init: Some(init), .. }) => {
self.note_type_is_not_clone_inner_expr(init)
@ -1703,8 +1698,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
kind: hir::PatKind::Tuple(pats, ..),
..
}) => {
let Some(hir::Node::Local(hir::Local { init: Some(init), .. })) =
self.tcx.opt_hir_node(self.tcx.hir().parent_id(*pat_hir_id))
let hir::Node::Local(hir::Local { init: Some(init), .. }) =
self.tcx.hir_node(self.tcx.hir().parent_id(*pat_hir_id))
else {
return expr;
};
@ -1736,10 +1731,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
call_expr_kind
&& let hir::Path { segments: [_], res: crate::Res::Local(binding), .. } =
call_expr_path
&& let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) =
self.tcx.opt_hir_node(*binding)
&& let Some(closure) = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*hir_id))
&& let hir::Node::Local(hir::Local { init: Some(init), .. }) = closure
&& let hir::Node::Pat(hir::Pat { hir_id, .. }) = self.tcx.hir_node(*binding)
&& let hir::Node::Local(hir::Local { init: Some(init), .. }) =
self.tcx.hir_node(self.tcx.hir().parent_id(*hir_id))
&& let Expr {
kind: hir::ExprKind::Closure(hir::Closure { body: body_id, .. }),
..
@ -1979,20 +1973,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Unroll desugaring, to make sure this works for `for` loops etc.
loop {
parent = self.tcx.hir().parent_id(id);
if let Some(parent_span) = self.tcx.hir().opt_span(parent) {
if parent_span.find_ancestor_inside(expr.span).is_some() {
// The parent node is part of the same span, so is the result of the
// same expansion/desugaring and not the 'real' parent node.
id = parent;
continue;
}
let parent_span = self.tcx.hir().span(parent);
if parent_span.find_ancestor_inside(expr.span).is_some() {
// The parent node is part of the same span, so is the result of the
// same expansion/desugaring and not the 'real' parent node.
id = parent;
continue;
}
break;
}
if let Some(hir::Node::Block(&hir::Block {
span: block_span, expr: Some(e), ..
})) = self.tcx.opt_hir_node(parent)
if let hir::Node::Block(&hir::Block { span: block_span, expr: Some(e), .. }) =
self.tcx.hir_node(parent)
{
if e.hir_id == id {
if let Some(span) = expr.span.find_ancestor_inside(block_span) {
@ -2220,30 +2212,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
let local_parent = self.tcx.hir().parent_id(local_id);
let Some(Node::Param(hir::Param { hir_id: param_hir_id, .. })) =
self.tcx.opt_hir_node(local_parent)
let Node::Param(hir::Param { hir_id: param_hir_id, .. }) = self.tcx.hir_node(local_parent)
else {
return None;
};
let param_parent = self.tcx.hir().parent_id(*param_hir_id);
let Some(Node::Expr(hir::Expr {
let Node::Expr(hir::Expr {
hir_id: expr_hir_id,
kind: hir::ExprKind::Closure(hir::Closure { fn_decl: closure_fn_decl, .. }),
..
})) = self.tcx.opt_hir_node(param_parent)
}) = self.tcx.hir_node(param_parent)
else {
return None;
};
let expr_parent = self.tcx.hir().parent_id(*expr_hir_id);
let hir = self.tcx.opt_hir_node(expr_parent);
let hir = self.tcx.hir_node(expr_parent);
let closure_params_len = closure_fn_decl.inputs.len();
let (
Some(Node::Expr(hir::Expr {
Node::Expr(hir::Expr {
kind: hir::ExprKind::MethodCall(method_path, receiver, ..),
..
})),
}),
1,
) = (hir, closure_params_len)
else {
@ -2674,10 +2665,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn is_else_if_block(&self, expr: &hir::Expr<'_>) -> bool {
if let hir::ExprKind::If(..) = expr.kind {
let parent_id = self.tcx.hir().parent_id(expr.hir_id);
if let Some(Node::Expr(hir::Expr {
kind: hir::ExprKind::If(_, _, Some(else_expr)),
..
})) = self.tcx.opt_hir_node(parent_id)
if let Node::Expr(hir::Expr {
kind: hir::ExprKind::If(_, _, Some(else_expr)), ..
}) = self.tcx.hir_node(parent_id)
{
return else_expr.hir_id == expr.hir_id;
}
@ -3067,7 +3057,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return;
};
let parent = self.tcx.hir().parent_id(expr.hir_id);
if let Some(hir::Node::ExprField(_)) = self.tcx.opt_hir_node(parent) {
if let hir::Node::ExprField(_) = self.tcx.hir_node(parent) {
// Ignore `Foo { field: a..Default::default() }`
return;
}
@ -3146,7 +3136,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let hir::def::Res::Local(hir_id) = path.res else {
return;
};
let Some(hir::Node::Pat(pat)) = self.tcx.opt_hir_node(hir_id) else {
let hir::Node::Pat(pat) = self.tcx.hir_node(hir_id) else {
return;
};
let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. })) =

View File

@ -230,7 +230,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = kind
&& let hir::def::Res::Local(hir_id) = path.res
&& let Some(hir::Node::Pat(b)) = self.tcx.opt_hir_node(hir_id)
&& let hir::Node::Pat(b) = self.tcx.hir_node(hir_id)
&& let Some(hir::Node::Param(p)) = self.tcx.hir().find_parent(b.hir_id)
&& let Some(node) = self.tcx.hir().find_parent(p.hir_id)
&& let Some(decl) = node.fn_decl()
@ -2017,7 +2017,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
visitor.visit_body(body);
let parent = self.tcx.hir().parent_id(seg1.hir_id);
if let Some(Node::Expr(call_expr)) = self.tcx.opt_hir_node(parent)
if let Node::Expr(call_expr) = self.tcx.hir_node(parent)
&& let Some(expr) = visitor.result
&& let Some(self_ty) = self.node_ty_opt(expr.hir_id)
{
@ -3251,7 +3251,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
let parent = self.tcx.hir().parent_id(expr.hir_id);
if let Some(Node::Expr(call_expr)) = self.tcx.opt_hir_node(parent)
if let Node::Expr(call_expr) = self.tcx.hir_node(parent)
&& let hir::ExprKind::MethodCall(
hir::PathSegment { ident: method_name, .. },
self_expr,

View File

@ -73,9 +73,7 @@ pub fn resolve_rvalue_scopes<'a, 'tcx>(
debug!("start resolving rvalue scopes, def_id={def_id:?}");
debug!("rvalue_scope: rvalue_candidates={:?}", scope_tree.rvalue_candidates);
for (&hir_id, candidate) in &scope_tree.rvalue_candidates {
let Some(Node::Expr(expr)) = tcx.opt_hir_node(hir_id) else {
bug!("hir node does not exist")
};
let Node::Expr(expr) = tcx.hir_node(hir_id) else { bug!("hir node does not exist") };
record_rvalue_scope(&mut rvalue_scopes, expr, candidate);
}
rvalue_scopes

View File

@ -972,9 +972,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Ok(mut s) = self.tcx.sess.source_map().span_to_snippet(closure_body_span) {
if s.starts_with('$') {
// Looks like a macro fragment. Try to find the real block.
if let Some(hir::Node::Expr(&hir::Expr {
if let hir::Node::Expr(&hir::Expr {
kind: hir::ExprKind::Block(block, ..), ..
})) = self.tcx.opt_hir_node(body_id.hir_id) {
}) = self.tcx.hir_node(body_id.hir_id) {
// If the body is a block (with `{..}`), we use the span of that block.
// E.g. with a `|| $body` expanded from a `m!({ .. })`, we use `{ .. }`, and not `$body`.
// Since we know it's a block, we know we can insert the `let _ = ..` without

View File

@ -2182,8 +2182,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if let Some(tykind) = tykind
&& let hir::TyKind::Array(_, length) = tykind
&& let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length
&& let Some(span) = self.tcx.hir().opt_span(*hir_id)
{
let span = self.tcx.hir().span(*hir_id);
Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength { span, length: sz.found })
} else {
None

View File

@ -687,7 +687,7 @@ fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_hir_id: hi
let res = hir_id == scope;
trace!(
"may_define_opaque_type(def={:?}, opaque_node={:?}) = {}",
tcx.opt_hir_node(hir_id),
tcx.hir_node(hir_id),
tcx.hir_node(opaque_hir_id),
res
);

View File

@ -5,7 +5,6 @@ use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{codes::*, struct_span_code_err, Applicability, DiagnosticBuilder, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Map;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::Span;
@ -62,7 +61,7 @@ pub fn report_object_safety_error<'tcx>(
err.span_label(span, format!("`{trait_str}` cannot be made into an object"));
if let Some(hir_id) = hir_id
&& let Some(hir::Node::Ty(ty)) = tcx.hir().find(hir_id)
&& let hir::Node::Ty(ty) = tcx.hir_node(hir_id)
&& let hir::TyKind::TraitObject([trait_ref, ..], ..) = ty.kind
{
let mut hir_id = hir_id;

View File

@ -1388,13 +1388,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
if should_encode_fn_sig(def_kind) {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
}
// FIXME: Some anonymous constants produced by `#[rustc_legacy_const_generics]`
// do not have corresponding HIR nodes, so some queries usually making sense for
// anonymous constants will not work on them and panic. It's not clear whether it
// can cause any observable issues or not.
let anon_const_without_hir = def_kind == DefKind::AnonConst
&& tcx.opt_hir_node(tcx.local_def_id_to_hir_id(local_id)).is_none();
if should_encode_generics(def_kind) && !anon_const_without_hir {
if should_encode_generics(def_kind) {
let g = tcx.generics_of(def_id);
record!(self.tables.generics_of[def_id] <- g);
record!(self.tables.explicit_predicates_of[def_id] <- self.tcx.explicit_predicates_of(def_id));
@ -1408,7 +1402,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}
}
if should_encode_type(tcx, local_id, def_kind) && !anon_const_without_hir {
if should_encode_type(tcx, local_id, def_kind) {
record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
}
if should_encode_constness(def_kind) {

View File

@ -157,23 +157,15 @@ impl<'tcx> TyCtxt<'tcx> {
self.hir_owner_nodes(owner_id).node()
}
/// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
pub fn opt_hir_node(self, id: HirId) -> Option<Node<'tcx>> {
let owner = self.hir_owner_nodes(id.owner);
let node = owner.nodes[id.local_id].as_ref()?;
Some(node.node)
}
/// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
#[inline]
pub fn opt_hir_node_by_def_id(self, id: LocalDefId) -> Option<Node<'tcx>> {
self.opt_hir_node(self.opt_local_def_id_to_hir_id(id)?)
Some(self.hir_node(self.opt_local_def_id_to_hir_id(id)?))
}
/// Retrieves the `hir::Node` corresponding to `id`, panicking if it cannot be found.
#[track_caller]
/// Retrieves the `hir::Node` corresponding to `id`.
pub fn hir_node(self, id: HirId) -> Node<'tcx> {
self.opt_hir_node(id).unwrap_or_else(|| bug!("couldn't find HIR node for hir id {id:?}"))
self.hir_owner_nodes(id.owner).nodes[id.local_id].node
}
/// Retrieves the `hir::Node` corresponding to `id`, panicking if it cannot be found.
@ -230,10 +222,13 @@ impl<'hir> Map<'hir> {
/// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`].
pub fn opt_parent_id(self, id: HirId) -> Option<HirId> {
if id.local_id == ItemLocalId::from_u32(0) {
// FIXME: This function never returns `None` right now, and the parent chain end is
// determined by checking for `parent(id) == id`. This function should return `None`
// for the crate root instead.
Some(self.tcx.hir_owner_parent(id.owner))
} else {
let owner = self.tcx.hir_owner_nodes(id.owner);
let node = owner.nodes[id.local_id].as_ref()?;
let node = &owner.nodes[id.local_id];
let hir_id = HirId { owner: id.owner, local_id: node.parent };
// HIR indexing should have checked that.
debug_assert_ne!(id.local_id, node.parent);
@ -252,11 +247,12 @@ impl<'hir> Map<'hir> {
}
pub fn find_parent(self, hir_id: HirId) -> Option<Node<'hir>> {
self.tcx.opt_hir_node(self.opt_parent_id(hir_id)?)
Some(self.tcx.hir_node(self.opt_parent_id(hir_id)?))
}
pub fn get_if_local(self, id: DefId) -> Option<Node<'hir>> {
id.as_local().and_then(|id| self.tcx.opt_hir_node(self.tcx.opt_local_def_id_to_hir_id(id)?))
id.as_local()
.and_then(|id| Some(self.tcx.hir_node(self.tcx.opt_local_def_id_to_hir_id(id)?)))
}
pub fn get_generics(self, id: LocalDefId) -> Option<&'hir Generics<'hir>> {
@ -285,20 +281,12 @@ impl<'hir> Map<'hir> {
#[track_caller]
pub fn fn_decl_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> {
if let Some(node) = self.tcx.opt_hir_node(hir_id) {
node.fn_decl()
} else {
bug!("no node for hir_id `{}`", hir_id)
}
self.tcx.hir_node(hir_id).fn_decl()
}
#[track_caller]
pub fn fn_sig_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnSig<'hir>> {
if let Some(node) = self.tcx.opt_hir_node(hir_id) {
node.fn_sig()
} else {
bug!("no node for hir_id `{}`", hir_id)
}
self.tcx.hir_node(hir_id).fn_sig()
}
#[track_caller]
@ -317,10 +305,7 @@ impl<'hir> Map<'hir> {
/// item (possibly associated), a closure, or a `hir::AnonConst`.
pub fn body_owner(self, BodyId { hir_id }: BodyId) -> HirId {
let parent = self.parent_id(hir_id);
assert!(
self.tcx.opt_hir_node(parent).is_some_and(|n| is_body_owner(n, hir_id)),
"{hir_id:?}"
);
assert!(is_body_owner(self.tcx.hir_node(parent), hir_id), "{hir_id:?}");
parent
}
@ -572,7 +557,7 @@ impl<'hir> Map<'hir> {
/// until the crate root is reached. Prefer this over your own loop using `parent_id`.
#[inline]
pub fn parent_iter(self, current_id: HirId) -> impl Iterator<Item = (HirId, Node<'hir>)> {
self.parent_id_iter(current_id).filter_map(move |id| Some((id, self.tcx.opt_hir_node(id)?)))
self.parent_id_iter(current_id).map(move |id| (id, self.tcx.hir_node(id)))
}
/// Returns an iterator for the nodes in the ancestor tree of the `current_id`
@ -624,7 +609,7 @@ impl<'hir> Map<'hir> {
pub fn get_return_block(self, id: HirId) -> Option<HirId> {
let mut iter = self.parent_iter(id).peekable();
let mut ignore_tail = false;
if let Some(Node::Expr(Expr { kind: ExprKind::Ret(_), .. })) = self.tcx.opt_hir_node(id) {
if let Node::Expr(Expr { kind: ExprKind::Ret(_), .. }) = self.tcx.hir_node(id) {
// When dealing with `return` statements, we don't care about climbing only tail
// expressions.
ignore_tail = true;
@ -777,8 +762,8 @@ impl<'hir> Map<'hir> {
}
pub fn expect_variant(self, id: HirId) -> &'hir Variant<'hir> {
match self.tcx.opt_hir_node(id) {
Some(Node::Variant(variant)) => variant,
match self.tcx.hir_node(id) {
Node::Variant(variant) => variant,
_ => bug!("expected variant, found {}", self.node_to_string(id)),
}
}
@ -796,18 +781,18 @@ impl<'hir> Map<'hir> {
}
pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> {
match self.tcx.opt_hir_node(id) {
Some(Node::Expr(expr)) => expr,
match self.tcx.hir_node(id) {
Node::Expr(expr) => expr,
_ => bug!("expected expr, found {}", self.node_to_string(id)),
}
}
#[inline]
fn opt_ident(self, id: HirId) -> Option<Ident> {
match self.tcx.opt_hir_node(id)? {
match self.tcx.hir_node(id) {
Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident),
// A `Ctor` doesn't have an identifier itself, but its parent
// struct/variant does. Compare with `hir::Map::opt_span`.
// struct/variant does. Compare with `hir::Map::span`.
Node::Ctor(..) => match self.find_parent(id)? {
Node::Item(item) => Some(item.ident),
Node::Variant(variant) => Some(variant.ident),
@ -845,11 +830,6 @@ impl<'hir> Map<'hir> {
/// Gets the span of the definition of the specified HIR node.
/// This is used by `tcx.def_span`.
pub fn span(self, hir_id: HirId) -> Span {
self.opt_span(hir_id)
.unwrap_or_else(|| bug!("hir::map::Map::span: id not in map: {:?}", hir_id))
}
pub fn opt_span(self, hir_id: HirId) -> Option<Span> {
fn until_within(outer: Span, end: Span) -> Span {
if let Some(end) = end.find_ancestor_inside(outer) {
outer.with_hi(end.hi())
@ -873,7 +853,7 @@ impl<'hir> Map<'hir> {
}
}
let span = match self.tcx.opt_hir_node(hir_id)? {
let span = match self.tcx.hir_node(hir_id) {
// Function-like.
Node::Item(Item { kind: ItemKind::Fn(sig, ..), span: outer_span, .. })
| Node::TraitItem(TraitItem {
@ -945,7 +925,7 @@ impl<'hir> Map<'hir> {
ForeignItemKind::Fn(decl, _, _) => until_within(item.span, decl.output.span()),
_ => named_span(item.span, item.ident, None),
},
Node::Ctor(_) => return self.opt_span(self.parent_id(hir_id)),
Node::Ctor(_) => return self.span(self.parent_id(hir_id)),
Node::Expr(Expr {
kind: ExprKind::Closure(Closure { fn_decl_span, .. }),
span,
@ -957,7 +937,7 @@ impl<'hir> Map<'hir> {
_ => self.span_with_body(hir_id),
};
debug_assert_eq!(span.ctxt(), self.span_with_body(hir_id).ctxt());
Some(span)
span
}
/// Like `hir.span()`, but includes the body of items
@ -994,6 +974,9 @@ impl<'hir> Map<'hir> {
Node::Infer(i) => i.span,
Node::Local(local) => local.span,
Node::Crate(item) => item.spans.inner_span,
Node::WhereBoundPredicate(pred) => pred.span,
Node::ArrayLenInfer(inf) => inf.span,
Node::Err(span) => *span,
}
}
@ -1057,8 +1040,8 @@ impl<'hir> Map<'hir> {
}
impl<'hir> intravisit::Map<'hir> for Map<'hir> {
fn find(&self, hir_id: HirId) -> Option<Node<'hir>> {
self.tcx.opt_hir_node(hir_id)
fn hir_node(&self, hir_id: HirId) -> Node<'hir> {
self.tcx.hir_node(hir_id)
}
fn body(&self, id: BodyId) -> &'hir Body<'hir> {
@ -1175,8 +1158,8 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
let span_str = || map.tcx.sess.source_map().span_to_snippet(map.span(id)).unwrap_or_default();
let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str());
match map.tcx.opt_hir_node(id) {
Some(Node::Item(item)) => {
match map.tcx.hir_node(id) {
Node::Item(item) => {
let item_str = match item.kind {
ItemKind::ExternCrate(..) => "extern crate",
ItemKind::Use(..) => "use",
@ -1204,10 +1187,10 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
};
format!("{id} ({item_str} {})", path_str(item.owner_id.def_id))
}
Some(Node::ForeignItem(item)) => {
Node::ForeignItem(item) => {
format!("{id} (foreign item {})", path_str(item.owner_id.def_id))
}
Some(Node::ImplItem(ii)) => {
Node::ImplItem(ii) => {
let kind = match ii.kind {
ImplItemKind::Const(..) => "assoc const",
ImplItemKind::Fn(..) => "method",
@ -1215,7 +1198,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
};
format!("{id} ({kind} `{}` in {})", ii.ident, path_str(ii.owner_id.def_id))
}
Some(Node::TraitItem(ti)) => {
Node::TraitItem(ti) => {
let kind = match ti.kind {
TraitItemKind::Const(..) => "assoc constant",
TraitItemKind::Fn(..) => "trait method",
@ -1224,38 +1207,40 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
format!("{id} ({kind} `{}` in {})", ti.ident, path_str(ti.owner_id.def_id))
}
Some(Node::Variant(variant)) => {
Node::Variant(variant) => {
format!("{id} (variant `{}` in {})", variant.ident, path_str(variant.def_id))
}
Some(Node::Field(field)) => {
Node::Field(field) => {
format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id))
}
Some(Node::AnonConst(_)) => node_str("const"),
Some(Node::ConstBlock(_)) => node_str("const"),
Some(Node::Expr(_)) => node_str("expr"),
Some(Node::ExprField(_)) => node_str("expr field"),
Some(Node::Stmt(_)) => node_str("stmt"),
Some(Node::PathSegment(_)) => node_str("path segment"),
Some(Node::Ty(_)) => node_str("type"),
Some(Node::TypeBinding(_)) => node_str("type binding"),
Some(Node::TraitRef(_)) => node_str("trait ref"),
Some(Node::Pat(_)) => node_str("pat"),
Some(Node::PatField(_)) => node_str("pattern field"),
Some(Node::Param(_)) => node_str("param"),
Some(Node::Arm(_)) => node_str("arm"),
Some(Node::Block(_)) => node_str("block"),
Some(Node::Infer(_)) => node_str("infer"),
Some(Node::Local(_)) => node_str("local"),
Some(Node::Ctor(ctor)) => format!(
Node::AnonConst(_) => node_str("const"),
Node::ConstBlock(_) => node_str("const"),
Node::Expr(_) => node_str("expr"),
Node::ExprField(_) => node_str("expr field"),
Node::Stmt(_) => node_str("stmt"),
Node::PathSegment(_) => node_str("path segment"),
Node::Ty(_) => node_str("type"),
Node::TypeBinding(_) => node_str("type binding"),
Node::TraitRef(_) => node_str("trait ref"),
Node::Pat(_) => node_str("pat"),
Node::PatField(_) => node_str("pattern field"),
Node::Param(_) => node_str("param"),
Node::Arm(_) => node_str("arm"),
Node::Block(_) => node_str("block"),
Node::Infer(_) => node_str("infer"),
Node::Local(_) => node_str("local"),
Node::Ctor(ctor) => format!(
"{id} (ctor {})",
ctor.ctor_def_id().map_or("<missing path>".into(), |def_id| path_str(def_id)),
),
Some(Node::Lifetime(_)) => node_str("lifetime"),
Some(Node::GenericParam(param)) => {
Node::Lifetime(_) => node_str("lifetime"),
Node::GenericParam(param) => {
format!("{id} (generic_param {})", path_str(param.def_id))
}
Some(Node::Crate(..)) => String::from("(root_crate)"),
None => format!("{id} (unknown node)"),
Node::Crate(..) => String::from("(root_crate)"),
Node::WhereBoundPredicate(_) => node_str("where bound predicate"),
Node::ArrayLenInfer(_) => node_str("array len infer"),
Node::Err(_) => node_str("error"),
}
}

View File

@ -12,7 +12,7 @@ use rustc_data_structures::sync::{try_par_for_each_in, DynSend, DynSync};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
use rustc_hir::*;
use rustc_span::{ErrorGuaranteed, ExpnId, DUMMY_SP};
use rustc_span::{ErrorGuaranteed, ExpnId};
/// Gather the LocalDefId for each item-like within a module, including items contained within
/// bodies. The Ids are in visitor order. This is used to partition a pass between modules.
@ -148,10 +148,7 @@ pub fn provide(providers: &mut Providers) {
providers.hir_attrs = |tcx, id| {
tcx.hir_crate(()).owners[id.def_id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs)
};
providers.def_span = |tcx, def_id| {
let hir_id = tcx.local_def_id_to_hir_id(def_id);
tcx.hir().opt_span(hir_id).unwrap_or(DUMMY_SP)
};
providers.def_span = |tcx, def_id| tcx.hir().span(tcx.local_def_id_to_hir_id(def_id));
providers.def_ident_span = |tcx, def_id| {
let hir_id = tcx.local_def_id_to_hir_id(def_id);
tcx.hir().opt_ident_span(hir_id)

View File

@ -827,10 +827,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.doc_attr_str_error(meta, "keyword");
return false;
}
match self.tcx.opt_hir_node(hir_id).and_then(|node| match node {
let item_kind = match self.tcx.hir_node(hir_id) {
hir::Node::Item(item) => Some(&item.kind),
_ => None,
}) {
};
match item_kind {
Some(ItemKind::Mod(module)) => {
if !module.item_ids.is_empty() {
self.dcx().emit_err(errors::DocKeywordEmptyMod { span: meta.span() });
@ -853,10 +854,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
fn check_doc_fake_variadic(&self, meta: &NestedMetaItem, hir_id: HirId) -> bool {
match self.tcx.opt_hir_node(hir_id).and_then(|node| match node {
let item_kind = match self.tcx.hir_node(hir_id) {
hir::Node::Item(item) => Some(&item.kind),
_ => None,
}) {
};
match item_kind {
Some(ItemKind::Impl(i)) => {
let is_valid = matches!(&i.self_ty.kind, hir::TyKind::Tup([_]))
|| if let hir::TyKind::BareFn(bare_fn_ty) = &i.self_ty.kind {
@ -2221,8 +2223,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
} else {
// special case when `#[macro_export]` is applied to a macro 2.0
let (macro_definition, _) =
self.tcx.opt_hir_node(hir_id).unwrap().expect_item().expect_macro();
let (macro_definition, _) = self.tcx.hir_node(hir_id).expect_item().expect_macro();
let is_decl_macro = !macro_definition.macro_rules;
if is_decl_macro {

View File

@ -134,7 +134,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
Err(hir::LoopIdError::UnresolvedLabel) => None,
};
if let Some(Node::Block(_)) = loop_id.and_then(|id| self.tcx.opt_hir_node(id)) {
if let Some(Node::Block(_)) = loop_id.map(|id| self.tcx.hir_node(id)) {
return;
}
@ -186,7 +186,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
match destination.target_id {
Ok(loop_id) => {
if let Node::Block(block) = self.tcx.opt_hir_node(loop_id).unwrap() {
if let Node::Block(block) = self.tcx.hir_node(loop_id) {
self.sess.dcx().emit_err(ContinueLabeledBlock {
span: e.span,
block_span: block.span,

View File

@ -19,7 +19,7 @@ use rustc_errors::{
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{Map, Visitor};
use rustc_hir::intravisit::Visitor;
use rustc_hir::is_range_literal;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId, Node};
@ -774,7 +774,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if steps > 0 {
// Don't care about `&mut` because `DerefMut` is used less
// often and user will not expect that an autoderef happens.
if let Some(hir::Node::Expr(hir::Expr {
if let hir::Node::Expr(hir::Expr {
kind:
hir::ExprKind::AddrOf(
hir::BorrowKind::Ref,
@ -782,7 +782,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
expr,
),
..
})) = self.tcx.opt_hir_node(*arg_hir_id)
}) = self.tcx.hir_node(*arg_hir_id)
{
let derefs = "*".repeat(steps);
err.span_suggestion_verbose(
@ -1199,7 +1199,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let Res::Local(hir_id) = path.res else {
return;
};
let Some(hir::Node::Pat(pat)) = self.tcx.opt_hir_node(hir_id) else {
let hir::Node::Pat(pat) = self.tcx.hir_node(hir_id) else {
return;
};
let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. })) =
@ -1786,7 +1786,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
&& let Res::Local(hir_id) = path.res
&& let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(hir_id)
&& let hir::Node::Pat(binding) = self.tcx.hir_node(hir_id)
&& let Some(hir::Node::Local(local)) = self.tcx.hir().find_parent(binding.hir_id)
&& let None = local.ty
&& let Some(binding_expr) = local.init
@ -2198,7 +2198,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let ty::FnPtr(found) = found.kind() else {
return;
};
let Some(Node::Expr(arg)) = self.tcx.opt_hir_node(*arg_hir_id) else {
let Node::Expr(arg) = self.tcx.hir_node(*arg_hir_id) else {
return;
};
let hir::ExprKind::Path(path) = arg.kind else {
@ -3186,8 +3186,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
ObligationCauseCode::VariableType(hir_id) => {
let parent_node = tcx.hir().parent_id(hir_id);
match tcx.opt_hir_node(parent_node) {
Some(Node::Local(hir::Local { ty: Some(ty), .. })) => {
match tcx.hir_node(parent_node) {
Node::Local(hir::Local { ty: Some(ty), .. }) => {
err.span_suggestion_verbose(
ty.span.shrink_to_lo(),
"consider borrowing here",
@ -3196,10 +3196,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
);
err.note("all local variables must have a statically known size");
}
Some(Node::Local(hir::Local {
Node::Local(hir::Local {
init: Some(hir::Expr { kind: hir::ExprKind::Index(..), span, .. }),
..
})) => {
}) => {
// When encountering an assignment of an unsized trait, like
// `let x = ""[..];`, provide a suggestion to borrow the initializer in
// order to use have a slice instead.
@ -3211,7 +3211,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
);
err.note("all local variables must have a statically known size");
}
Some(Node::Param(param)) => {
Node::Param(param) => {
err.span_suggestion_verbose(
param.ty_span.shrink_to_lo(),
"function arguments must have a statically known size, borrowed types \
@ -3233,7 +3233,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let borrowed_msg = "function arguments must have a statically known size, borrowed \
types always have a known size";
if let Some(hir_id) = hir_id
&& let Some(hir::Node::Param(param)) = self.tcx.hir().find(hir_id)
&& let hir::Node::Param(param) = self.tcx.hir_node(hir_id)
&& let Some(item) = self.tcx.hir().find_parent(hir_id)
&& let Some(decl) = item.fn_decl()
&& let Some(t) = decl.inputs.iter().find(|t| param.ty_span.contains(t.span))
@ -3247,7 +3247,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// param._ty_span
ty = Some(t);
} else if let Some(hir_id) = hir_id
&& let Some(hir::Node::Ty(t)) = self.tcx.hir().find(hir_id)
&& let hir::Node::Ty(t) = self.tcx.hir_node(hir_id)
{
ty = Some(t);
}
@ -3958,7 +3958,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
call_hir_id: HirId,
) {
let tcx = self.tcx;
if let Some(Node::Expr(expr)) = tcx.opt_hir_node(arg_hir_id)
if let Node::Expr(expr) = tcx.hir_node(arg_hir_id)
&& let Some(typeck_results) = &self.typeck_results
{
if let hir::Expr { kind: hir::ExprKind::Block(block, _), .. } = expr {
@ -4074,9 +4074,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
&& let hir::Path { res: Res::Local(hir_id), .. } = path
&& let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(*hir_id)
&& let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id)
&& let parent_hir_id = self.tcx.hir().parent_id(binding.hir_id)
&& let Some(hir::Node::Local(local)) = self.tcx.opt_hir_node(parent_hir_id)
&& let hir::Node::Local(local) = self.tcx.hir_node(parent_hir_id)
&& let Some(binding_expr) = local.init
{
// If the expression we're calling on is a binding, we want to point at the
@ -4087,17 +4087,16 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
self.point_at_chain(expr, typeck_results, type_diffs, param_env, err);
}
}
let call_node = tcx.opt_hir_node(call_hir_id);
if let Some(Node::Expr(hir::Expr {
kind: hir::ExprKind::MethodCall(path, rcvr, ..), ..
})) = call_node
let call_node = tcx.hir_node(call_hir_id);
if let Node::Expr(hir::Expr { kind: hir::ExprKind::MethodCall(path, rcvr, ..), .. }) =
call_node
{
if Some(rcvr.span) == err.span.primary_span() {
err.replace_span_with(path.ident.span, true);
}
}
if let Some(Node::Expr(expr)) = tcx.opt_hir_node(call_hir_id) {
if let Node::Expr(expr) = tcx.hir_node(call_hir_id) {
if let hir::ExprKind::Call(hir::Expr { span, .. }, _)
| hir::ExprKind::MethodCall(
hir::PathSegment { ident: Ident { span, .. }, .. },
@ -4334,7 +4333,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
&& let hir::Path { res: Res::Local(hir_id), .. } = path
&& let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(*hir_id)
&& let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id)
&& let Some(parent) = self.tcx.hir().find_parent(binding.hir_id)
{
// We've reached the root of the method call chain...

View File

@ -993,13 +993,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
) -> Result<(), ErrorGuaranteed> {
if let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } =
obligation.cause.code()
&& let Some(Node::Expr(arg)) = self.tcx.opt_hir_node(*arg_hir_id)
&& let Node::Expr(arg) = self.tcx.hir_node(*arg_hir_id)
&& let arg = arg.peel_borrows()
&& let hir::ExprKind::Path(hir::QPath::Resolved(
None,
hir::Path { res: hir::def::Res::Local(hir_id), .. },
)) = arg.kind
&& let Some(Node::Pat(pat)) = self.tcx.opt_hir_node(*hir_id)
&& let Node::Pat(pat) = self.tcx.hir_node(*hir_id)
&& let Some((preds, guar)) = self.reported_trait_errors.borrow().get(&pat.span)
&& preds.contains(&obligation.predicate)
{
@ -1037,10 +1037,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
}
let hir_id = self.tcx.local_def_id_to_hir_id(obligation.cause.body_id);
let body_id = match self.tcx.opt_hir_node(hir_id) {
Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) => {
body_id
}
let body_id = match self.tcx.hir_node(hir_id) {
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. }) => body_id,
_ => return false,
};
let mut v = V { search_span: span, found: None };
@ -1163,7 +1161,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
&& let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
&& let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(*hir_id)
&& let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id)
&& let Some(parent) = self.tcx.hir().find_parent(binding.hir_id)
{
// We've reached the root of the method call chain...

View File

@ -94,7 +94,7 @@ impl<'tcx> SpanMapVisitor<'tcx> {
/// Used to generate links on items' definition to go to their documentation page.
pub(crate) fn extract_info_from_hir_id(&mut self, hir_id: HirId) {
if let Some(Node::Item(item)) = self.tcx.opt_hir_node(hir_id) {
if let Node::Item(item) = self.tcx.hir_node(hir_id) {
if let Some(span) = self.tcx.def_ident_span(item.owner_id) {
let cspan = clean::Span::new(span);
// If the span isn't from the current crate, we ignore it.
@ -199,7 +199,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
if !span.overlaps(m.spans.inner_span) {
// Now that we confirmed it's a file import, we want to get the span for the module
// name only and not all the "mod foo;".
if let Some(Node::Item(item)) = self.tcx.opt_hir_node(id) {
if let Node::Item(item) = self.tcx.hir_node(id) {
self.matches.insert(
item.ident.span,
LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)),

View File

@ -62,7 +62,7 @@ impl LateLintPass<'_> for AbsolutePaths {
} = self;
if !path.span.from_expansion()
&& let Some(node) = cx.tcx.opt_hir_node(hir_id)
&& let node = cx.tcx.hir_node(hir_id)
&& !matches!(node, Node::Item(item) if matches!(item.kind, ItemKind::Use(_, _)))
&& let [first, rest @ ..] = path.segments
// Handle `::std`

View File

@ -68,9 +68,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: &Msrv
fn is_child_of_cast(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
let map = cx.tcx.hir();
if let Some(parent_id) = map.opt_parent_id(expr.hir_id)
&& let Some(parent) = cx.tcx.opt_hir_node(parent_id)
{
if let Some(parent_id) = map.opt_parent_id(expr.hir_id) {
let parent = cx.tcx.hir_node(parent_id);
let expr = match parent {
Node::Block(block) => {
if let Some(parent_expr) = block.expr {

View File

@ -144,8 +144,7 @@ pub(super) fn check<'tcx>(
if cast_from.kind() == cast_to.kind() && !in_external_macro(cx.sess(), expr.span) {
if let Some(id) = path_to_local(cast_expr)
&& let Some(span) = cx.tcx.hir().opt_span(id)
&& !span.eq_ctxt(cast_expr.span)
&& !cx.tcx.hir().span(id).eq_ctxt(cast_expr.span)
{
// Binding context is different than the identifiers context.
// Weird macro wizardry could be involved here.

View File

@ -195,7 +195,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
&& let Some(def_id) = trait_ref.trait_def_id()
&& cx.tcx.is_diagnostic_item(sym::Default, def_id)
&& let impl_item_hir = child.id.hir_id()
&& let Some(Node::ImplItem(impl_item)) = cx.tcx.opt_hir_node(impl_item_hir)
&& let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir)
&& let ImplItemKind::Fn(_, b) = &impl_item.kind
&& let Body { value: func_expr, .. } = cx.tcx.hir().body(*b)
&& let &Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()

View File

@ -42,7 +42,7 @@ impl LateLintPass<'_> for EmptyDrop {
}) = item.kind
&& trait_ref.trait_def_id() == cx.tcx.lang_items().drop_trait()
&& let impl_item_hir = child.id.hir_id()
&& let Some(Node::ImplItem(impl_item)) = cx.tcx.opt_hir_node(impl_item_hir)
&& let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir)
&& let ImplItemKind::Fn(_, b) = &impl_item.kind
&& let Body { value: func_expr, .. } = cx.tcx.hir().body(*b)
&& let func_expr = peel_blocks(func_expr)

View File

@ -123,11 +123,11 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
// TODO: Replace with Map::is_argument(..) when it's fixed
fn is_argument(tcx: TyCtxt<'_>, id: HirId) -> bool {
match tcx.opt_hir_node(id) {
Some(Node::Pat(Pat {
match tcx.hir_node(id) {
Node::Pat(Pat {
kind: PatKind::Binding(..),
..
})) => (),
}) => (),
_ => return false,
}

View File

@ -111,7 +111,7 @@ fn look_in_block<'tcx, 'hir>(cx: &LateContext<'tcx>, kind: &'tcx ExprKind<'hir>)
// Find id of the local that expr_end_of_block resolves to
&& let ExprKind::Path(QPath::Resolved(None, expr_path)) = expr_end_of_block.kind
&& let Res::Local(expr_res) = expr_path.res
&& let Some(Node::Pat(res_pat)) = cx.tcx.opt_hir_node(expr_res)
&& let Node::Pat(res_pat) = cx.tcx.hir_node(expr_res)
// Find id of the local we found in the block
&& let PatKind::Binding(BindingAnnotation::NONE, local_hir_id, _ident, None) = local.pat.kind

View File

@ -248,7 +248,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
// Checking for slice indexing
&& let parent_id = map.parent_id(expr.hir_id)
&& let Some(hir::Node::Expr(parent_expr)) = cx.tcx.opt_hir_node(parent_id)
&& let hir::Node::Expr(parent_expr) = cx.tcx.hir_node(parent_id)
&& let hir::ExprKind::Index(_, index_expr, _) = parent_expr.kind
&& let Some(Constant::Int(index_value)) = constant(cx, cx.typeck_results(), index_expr)
&& let Ok(index_value) = index_value.try_into()
@ -256,7 +256,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
// Make sure that this slice index is read only
&& let maybe_addrof_id = map.parent_id(parent_id)
&& let Some(hir::Node::Expr(maybe_addrof_expr)) = cx.tcx.opt_hir_node(maybe_addrof_id)
&& let hir::Node::Expr(maybe_addrof_expr) = cx.tcx.hir_node(maybe_addrof_id)
&& let hir::ExprKind::AddrOf(_kind, hir::Mutability::Not, _inner_expr) = maybe_addrof_expr.kind
{
use_info.index_use.push((index_value, map.span(parent_expr.hir_id)));

View File

@ -147,9 +147,9 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
&& let Some(output) =
parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder())
{
let (name, kind) = match cx.tcx.opt_hir_node(ty_hir_id) {
Some(Node::ForeignItem(x)) => (x.ident.name, "extern type"),
Some(Node::Item(x)) => match x.kind {
let (name, kind) = match cx.tcx.hir_node(ty_hir_id) {
Node::ForeignItem(x) => (x.ident.name, "extern type"),
Node::Item(x) => match x.kind {
ItemKind::Struct(..) => (x.ident.name, "struct"),
ItemKind::Enum(..) => (x.ident.name, "enum"),
ItemKind::Union(..) => (x.ident.name, "union"),

View File

@ -63,7 +63,7 @@ pub(super) fn check<'tcx>(
&& let PatKind::Binding(bind_ann, ..) = pat.kind
&& !matches!(bind_ann, BindingAnnotation(_, Mutability::Mut))
&& let parent_node = cx.tcx.hir().parent_id(hir_id)
&& let Some(Node::Local(parent_let_expr)) = cx.tcx.opt_hir_node(parent_node)
&& let Node::Local(parent_let_expr) = cx.tcx.hir_node(parent_node)
&& let Some(init) = parent_let_expr.init
{
match init.kind {

View File

@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
// Also ensures the const is nonzero since zero can't be a divisor
&& const1 == const2 && const2 == const3
&& let Some(hir_id) = path_to_local(expr3)
&& let Some(Node::Pat(_)) = cx.tcx.opt_hir_node(hir_id)
&& let Node::Pat(_) = cx.tcx.hir_node(hir_id)
{
// Apply only to params or locals with annotated types
match cx.tcx.hir().find_parent(hir_id) {

View File

@ -44,7 +44,7 @@ pub(super) fn check<'tcx>(
// add note if not multi-line
span_lint_and_then(cx, FILTER_NEXT, expr.span, msg, |diag| {
let (applicability, pat) = if let Some(id) = path_to_local(recv)
&& let Some(hir::Node::Pat(pat)) = cx.tcx.opt_hir_node(id)
&& let hir::Node::Pat(pat) = cx.tcx.hir_node(id)
&& let hir::PatKind::Binding(BindingAnnotation(_, Mutability::Not), _, ident, _) = pat.kind
{
(Applicability::Unspecified, Some((pat.span, ident)))

View File

@ -135,7 +135,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrapVisitor<'a, 'tcx> {
fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) {
if let Res::Local(local_id) = path.res
&& let Some(Node::Pat(pat)) = self.cx.tcx.opt_hir_node(local_id)
&& let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)
&& let PatKind::Binding(_, local_id, ..) = pat.kind
{
self.identifiers.insert(local_id);
@ -166,7 +166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReferenceVisitor<'a, 'tcx> {
&& let ExprKind::Path(ref path) = expr.kind
&& let QPath::Resolved(_, path) = path
&& let Res::Local(local_id) = path.res
&& let Some(Node::Pat(pat)) = self.cx.tcx.opt_hir_node(local_id)
&& let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)
&& let PatKind::Binding(_, local_id, ..) = pat.kind
&& self.identifiers.contains(&local_id)
{

View File

@ -91,10 +91,10 @@ impl Visitor<'_> for IdentVisitor<'_, '_> {
let node = if hir_id.local_id == ItemLocalId::from_u32(0) {
// In this case, we can just use `find`, `Owner`'s `node` field is private anyway so we can't
// reimplement it even if we wanted to
cx.tcx.opt_hir_node(hir_id)
Some(cx.tcx.hir_node(hir_id))
} else {
let owner = cx.tcx.hir_owner_nodes(hir_id.owner);
owner.nodes.get(hir_id.local_id).copied().flatten().map(|p| p.node)
owner.nodes.get(hir_id.local_id).copied().map(|p| p.node)
};
let Some(node) = node else {
return;

View File

@ -213,11 +213,8 @@ fn check_for_unsequenced_reads(vis: &mut ReadVisitor<'_, '_>) {
if parent_id == cur_id {
break;
}
let Some(parent_node) = vis.cx.tcx.opt_hir_node(parent_id) else {
break;
};
let stop_early = match parent_node {
let stop_early = match vis.cx.tcx.hir_node(parent_id) {
Node::Expr(expr) => check_expr(vis, expr),
Node::Stmt(stmt) => check_stmt(vis, stmt),
Node::Item(_) => {

View File

@ -453,7 +453,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
if parent_id == cur_expr.hir_id {
break;
}
if let Some(Node::Expr(parent_expr)) = cx.tcx.opt_hir_node(parent_id) {
if let Node::Expr(parent_expr) = cx.tcx.hir_node(parent_id) {
match &parent_expr.kind {
ExprKind::AddrOf(..) => {
// `&e` => `e` must be referenced.

View File

@ -76,8 +76,8 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
match of_trait {
Some(trait_ref) => {
let mut methods_in_trait: BTreeSet<Symbol> =
if let Some(Node::TraitRef(TraitRef { path, .. })) =
cx.tcx.opt_hir_node(trait_ref.hir_ref_id)
if let Node::TraitRef(TraitRef { path, .. }) =
cx.tcx.hir_node(trait_ref.hir_ref_id)
&& let Res::Def(DefKind::Trait, did) = path.res
{
// FIXME: if

View File

@ -73,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {
if let Some(self_def) = self_ty.ty_adt_def()
&& let Some(self_local_did) = self_def.did().as_local()
&& let self_id = cx.tcx.local_def_id_to_hir_id(self_local_did)
&& let Some(Node::Item(x)) = cx.tcx.opt_hir_node(self_id)
&& let Node::Item(x) = cx.tcx.hir_node(self_id)
&& let type_name = x.ident.name.as_str().to_lowercase()
&& (impl_item.ident.name.as_str() == type_name
|| impl_item.ident.name.as_str().replace('_', "") == type_name)

View File

@ -177,10 +177,10 @@ pub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr
/// canonical binding `HirId`.
pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> {
let hir = cx.tcx.hir();
if let Some(Node::Pat(pat)) = cx.tcx.opt_hir_node(hir_id)
if let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
&& matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..))
&& let parent = hir.parent_id(hir_id)
&& let Some(Node::Local(local)) = cx.tcx.opt_hir_node(parent)
&& let Node::Local(local) = cx.tcx.hir_node(parent)
{
return local.init;
}
@ -1327,7 +1327,7 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio
let map = &cx.tcx.hir();
let enclosing_node = map
.get_enclosing_scope(hir_id)
.and_then(|enclosing_id| cx.tcx.opt_hir_node(enclosing_id));
.map(|enclosing_id| cx.tcx.hir_node(enclosing_id));
enclosing_node.and_then(|node| match node {
Node::Block(block) => Some(block),
Node::Item(&Item {
@ -2696,10 +2696,10 @@ impl<'tcx> ExprUseNode<'tcx> {
)),
Self::Return(id) => {
let hir_id = cx.tcx.local_def_id_to_hir_id(id.def_id);
if let Some(Node::Expr(Expr {
if let Node::Expr(Expr {
kind: ExprKind::Closure(c),
..
})) = cx.tcx.opt_hir_node(hir_id)
}) = cx.tcx.hir_node(hir_id)
{
match c.fn_decl.output {
FnRetTy::DefaultReturn(_) => None,