Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use hir::Node helper methods instead of repeating the same impl multiple times #122021

Merged
merged 2 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 21 additions & 14 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3640,35 +3640,42 @@ impl<'hir> Node<'hir> {
}
}

pub fn body_id(&self) -> Option<BodyId> {
#[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<BodyId> {
Some(self.associated_body()?.1)
}

pub fn generics(self) -> Option<&'hir Generics<'hir>> {
match self {
Node::ForeignItem(ForeignItem {
Expand Down
26 changes: 3 additions & 23 deletions compiler/rustc_hir_analysis/src/collect/generics_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,29 +508,9 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
visitor.has_late_bound_regions
}

match node {
Node::TraitItem(item) => 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 {
Expand Down
83 changes: 17 additions & 66 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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(
Expand Down
24 changes: 1 addition & 23 deletions compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
54 changes: 7 additions & 47 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
}
Expand All @@ -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<BodyId> {
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.
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}

Expand All @@ -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);
}

Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_mir_transform/src/coverage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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();
Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 4 additions & 2 deletions src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Loading