diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 186b8716d9a51..bcd1e547d3d2c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3640,35 +3640,42 @@ impl<'hir> Node<'hir> { } } - pub fn body_id(&self) -> Option { + #[inline] + pub fn associated_body(&self) -> Option<(LocalDefId, BodyId)> { match self { Node::Item(Item { + owner_id, kind: - ItemKind::Static(_, _, body) - | ItemKind::Const(_, _, body) - | ItemKind::Fn(_, _, body), + ItemKind::Const(_, _, body) | ItemKind::Static(.., body) | ItemKind::Fn(.., body), .. }) | Node::TraitItem(TraitItem { + owner_id, kind: - TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)), + TraitItemKind::Const(_, Some(body)) | TraitItemKind::Fn(_, TraitFn::Provided(body)), .. }) | Node::ImplItem(ImplItem { - kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body), - .. - }) - | Node::Expr(Expr { - kind: - ExprKind::ConstBlock(ConstBlock { body, .. }) - | ExprKind::Closure(Closure { body, .. }) - | ExprKind::Repeat(_, ArrayLen::Body(AnonConst { body, .. })), + owner_id, + kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body), .. - }) => Some(*body), + }) => Some((owner_id.def_id, *body)), + + Node::Expr(Expr { kind: ExprKind::Closure(Closure { def_id, body, .. }), .. }) => { + Some((*def_id, *body)) + } + + Node::AnonConst(constant) => Some((constant.def_id, constant.body)), + Node::ConstBlock(constant) => Some((constant.def_id, constant.body)), + _ => None, } } + pub fn body_id(&self) -> Option { + Some(self.associated_body()?.1) + } + pub fn generics(self) -> Option<&'hir Generics<'hir>> { match self { Node::ForeignItem(ForeignItem { diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index c86788db988eb..bc6abc53cadf4 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -508,29 +508,9 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option match &item.kind { - hir::TraitItemKind::Fn(sig, _) => has_late_bound_regions(tcx, item.generics, sig.decl), - _ => None, - }, - Node::ImplItem(item) => match &item.kind { - hir::ImplItemKind::Fn(sig, _) => has_late_bound_regions(tcx, item.generics, sig.decl), - _ => None, - }, - Node::ForeignItem(item) => match item.kind { - hir::ForeignItemKind::Fn(fn_decl, _, generics) => { - has_late_bound_regions(tcx, generics, fn_decl) - } - _ => None, - }, - Node::Item(item) => match &item.kind { - hir::ItemKind::Fn(sig, .., generics, _) => { - has_late_bound_regions(tcx, generics, sig.decl) - } - _ => None, - }, - _ => None, - } + let decl = node.fn_decl()?; + let generics = node.generics()?; + has_late_bound_regions(tcx, generics, decl) } struct AnonConstInParamTyDetector { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 6aae4aa21b878..66c9fb93500f6 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -123,43 +123,22 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // Preserving the order of insertion is important here so as not to break UI tests. let mut predicates: FxIndexSet<(ty::Clause<'_>, Span)> = FxIndexSet::default(); - let ast_generics = match node { - Node::TraitItem(item) => item.generics, - - Node::ImplItem(item) => item.generics, - - Node::Item(item) => match item.kind { + let ast_generics = node.generics().unwrap_or(NO_GENERICS); + if let Node::Item(item) = node { + match item.kind { ItemKind::Impl(impl_) => { if impl_.defaultness.is_default() { is_default_impl_trait = tcx .impl_trait_ref(def_id) .map(|t| ty::Binder::dummy(t.instantiate_identity())); } - impl_.generics } - ItemKind::Fn(.., generics, _) - | ItemKind::TyAlias(_, generics) - | ItemKind::Const(_, generics, _) - | ItemKind::Enum(_, generics) - | ItemKind::Struct(_, generics) - | ItemKind::Union(_, generics) => generics, - - ItemKind::Trait(_, _, generics, self_bounds, ..) - | ItemKind::TraitAlias(generics, self_bounds) => { + + ItemKind::Trait(_, _, _, self_bounds, ..) | ItemKind::TraitAlias(_, self_bounds) => { is_trait = Some(self_bounds); - generics } - ItemKind::OpaqueTy(OpaqueTy { generics, .. }) => generics, - _ => NO_GENERICS, - }, - - Node::ForeignItem(item) => match item.kind { - ForeignItemKind::Static(..) => NO_GENERICS, - ForeignItemKind::Fn(_, _, generics) => generics, - ForeignItemKind::Type => NO_GENERICS, - }, - - _ => NO_GENERICS, + _ => {} + } }; let generics = tcx.generics_of(def_id); @@ -703,45 +682,17 @@ pub(super) fn type_param_predicates( let mut extend = None; let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id); - let ast_generics = match tcx.hir_node(item_hir_id) { - Node::TraitItem(item) => item.generics, - - Node::ImplItem(item) => item.generics, - - Node::Item(item) => { - match item.kind { - ItemKind::Fn(.., generics, _) - | ItemKind::Impl(&hir::Impl { generics, .. }) - | ItemKind::TyAlias(_, generics) - | ItemKind::Const(_, generics, _) - | ItemKind::OpaqueTy(&OpaqueTy { - generics, - origin: hir::OpaqueTyOrigin::TyAlias { .. }, - .. - }) - | ItemKind::Enum(_, generics) - | ItemKind::Struct(_, generics) - | ItemKind::Union(_, generics) => generics, - ItemKind::Trait(_, _, generics, ..) => { - // Implied `Self: Trait` and supertrait bounds. - if param_id == item_hir_id { - let identity_trait_ref = - ty::TraitRef::identity(tcx, item_def_id.to_def_id()); - extend = Some((identity_trait_ref.to_predicate(tcx), item.span)); - } - generics - } - _ => return result, - } - } - - Node::ForeignItem(item) => match item.kind { - ForeignItemKind::Fn(_, _, generics) => generics, - _ => return result, - }, - _ => return result, - }; + let hir_node = tcx.hir_node(item_hir_id); + let Some(ast_generics) = hir_node.generics() else { return result }; + if let Node::Item(item) = hir_node + && let ItemKind::Trait(..) = item.kind + // Implied `Self: Trait` and supertrait bounds. + && param_id == item_hir_id + { + let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id.to_def_id()); + extend = Some((identity_trait_ref.to_predicate(tcx), item.span)); + } let icx = ItemCtxt::new(tcx, item_def_id); let extra_predicates = extend.into_iter().chain( diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index d86b4912c89bd..bc6e09addce21 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -95,29 +95,7 @@ macro_rules! type_error_struct { fn primary_body_of( node: Node<'_>, ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnSig<'_>>)> { - match node { - Node::Item(item) => match item.kind { - hir::ItemKind::Const(ty, _, body) | hir::ItemKind::Static(ty, _, body) => { - Some((body, Some(ty), None)) - } - hir::ItemKind::Fn(ref sig, .., body) => Some((body, None, Some(sig))), - _ => None, - }, - Node::TraitItem(item) => match item.kind { - hir::TraitItemKind::Const(ty, Some(body)) => Some((body, Some(ty), None)), - hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { - Some((body, None, Some(sig))) - } - _ => None, - }, - Node::ImplItem(item) => match item.kind { - hir::ImplItemKind::Const(ty, body) => Some((body, Some(ty), None)), - hir::ImplItemKind::Fn(ref sig, body) => Some((body, None, Some(sig))), - _ => None, - }, - Node::AnonConst(constant) => Some((constant.body, None, None)), - _ => None, - } + Some((node.body_id()?, node.ty(), node.fn_sig())) } fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 5043bd855ccb9..ed05ffef205e6 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -20,44 +20,6 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{ErrorGuaranteed, Span}; use rustc_target::spec::abi::Abi; -#[inline] -pub fn associated_body(node: Node<'_>) -> Option<(LocalDefId, BodyId)> { - match node { - Node::Item(Item { - owner_id, - kind: ItemKind::Const(_, _, body) | ItemKind::Static(.., body) | ItemKind::Fn(.., body), - .. - }) - | Node::TraitItem(TraitItem { - owner_id, - kind: - TraitItemKind::Const(_, Some(body)) | TraitItemKind::Fn(_, TraitFn::Provided(body)), - .. - }) - | Node::ImplItem(ImplItem { - owner_id, - kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body), - .. - }) => Some((owner_id.def_id, *body)), - - Node::Expr(Expr { kind: ExprKind::Closure(Closure { def_id, body, .. }), .. }) => { - Some((*def_id, *body)) - } - - Node::AnonConst(constant) => Some((constant.def_id, constant.body)), - Node::ConstBlock(constant) => Some((constant.def_id, constant.body)), - - _ => None, - } -} - -fn is_body_owner(node: Node<'_>, hir_id: HirId) -> bool { - match associated_body(node) { - Some((_, b)) => b.hir_id == hir_id, - None => false, - } -} - // FIXME: the structure was necessary in the past but now it // only serves as "namespace" for HIR-related methods, and can be // removed if all the methods are reasonably renamed and moved to tcx @@ -273,7 +235,7 @@ impl<'hir> Map<'hir> { #[track_caller] pub fn enclosing_body_owner(self, hir_id: HirId) -> LocalDefId { for (_, node) in self.parent_iter(hir_id) { - if let Some((def_id, _)) = associated_body(node) { + if let Some((def_id, _)) = node.associated_body() { return def_id; } } @@ -286,20 +248,18 @@ 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.tcx.parent_hir_id(hir_id); - assert!(is_body_owner(self.tcx.hir_node(parent), hir_id), "{hir_id:?}"); + assert_eq!(self.tcx.hir_node(parent).body_id().unwrap().hir_id, hir_id, "{hir_id:?}"); parent } pub fn body_owner_def_id(self, BodyId { hir_id }: BodyId) -> LocalDefId { - associated_body(self.tcx.parent_hir_node(hir_id)).unwrap().0 + self.tcx.parent_hir_node(hir_id).associated_body().unwrap().0 } /// Given a `LocalDefId`, returns the `BodyId` associated with it, /// if the node is a body owner, otherwise returns `None`. pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option { - let node = self.tcx.hir_node_by_def_id(id); - let (_, body_id) = associated_body(node)?; - Some(body_id) + self.tcx.hir_node_by_def_id(id).body_id() } /// Given a body owner's id, returns the `BodyId` associated with it. @@ -1314,7 +1274,7 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> { } fn visit_item(&mut self, item: &'hir Item<'hir>) { - if associated_body(Node::Item(item)).is_some() { + if Node::Item(item).associated_body().is_some() { self.body_owners.push(item.owner_id.def_id); } @@ -1355,7 +1315,7 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> { } fn visit_trait_item(&mut self, item: &'hir TraitItem<'hir>) { - if associated_body(Node::TraitItem(item)).is_some() { + if Node::TraitItem(item).associated_body().is_some() { self.body_owners.push(item.owner_id.def_id); } @@ -1364,7 +1324,7 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> { } fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) { - if associated_body(Node::ImplItem(item)).is_some() { + if Node::ImplItem(item).associated_body().is_some() { self.body_owners.push(item.owner_id.def_id); } diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index b2407c545071b..83189c6a50a77 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -13,7 +13,6 @@ use self::spans::{BcbMapping, BcbMappingKind, CoverageSpans}; use crate::MirPass; -use rustc_middle::hir; use rustc_middle::mir::coverage::*; use rustc_middle::mir::{ self, BasicBlock, BasicBlockData, Coverage, SourceInfo, Statement, StatementKind, Terminator, @@ -368,8 +367,7 @@ fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ExtractedHir // to HIR for it. let hir_node = tcx.hir_node_by_def_id(def_id); - let (_, fn_body_id) = - hir::map::associated_body(hir_node).expect("HIR node is a function with body"); + let fn_body_id = hir_node.body_id().expect("HIR node is a function with body"); let hir_body = tcx.hir().body(fn_body_id); let maybe_fn_sig = hir_node.fn_sig(); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index eb2399f7a64f4..1254ae8cfc8db 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -609,13 +609,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { && !self.tcx.sess.target.is_like_wasm && !self.tcx.sess.opts.actually_rustdoc { - let hir::Node::Item(item) = self.tcx.hir_node(hir_id) else { - unreachable!(); - }; - let hir::ItemKind::Fn(sig, _, _) = item.kind else { - // target is `Fn` - unreachable!(); - }; + let sig = self.tcx.hir_node(hir_id).fn_sig().unwrap(); self.dcx().emit_err(errors::LangItemWithTargetFeature { attr_span: attr.span, diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index a450dee305005..30d3e86dc4ed7 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -13,7 +13,6 @@ use rustc_hir::{ use rustc_hir_typeck::expr_use_visitor as euv; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::hir::map::associated_body; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{self, Ty, TyCtxt, UpvarId, UpvarPath}; use rustc_session::impl_lint_pass; @@ -112,7 +111,10 @@ fn check_closures<'tcx>( } ctx.prev_bind = None; ctx.prev_move_to_closure.clear(); - if let Some(body) = associated_body(cx.tcx.hir_node_by_def_id(closure)) + if let Some(body) = cx + .tcx + .hir_node_by_def_id(closure) + .associated_body() .map(|(_, body_id)| hir.body(body_id)) { euv::ExprUseVisitor::new(ctx, infcx, closure, cx.param_env, cx.typeck_results()).consume_body(body);