mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #153582 - mehdiakiki:simplify-find-attr-hir-id, r=JonathanBrouwer
Simplify find_attr! for HirId usage Add a `HasAttrs<'tcx, Tcx>` trait to `rustc_hir` that allows `find_attr!` to accept `DefId`, `LocalDefId`, `OwnerId`, and `HirId` directly, instead of requiring callers to manually fetch the attribute slice first. Before: `find_attr!(tcx.hir_attrs(hir_id), SomeAttr)` After: `find_attr!(tcx, hir_id, SomeAttr)` The trait is defined in `rustc_hir` with a generic `Tcx` parameter to avoid a dependency cycle (`rustc_hir` cannot depend on `rustc_middle`). The four concrete impls for `TyCtxt` are in `rustc_middle`. Fixes https://github.com/rust-lang/rust/issues/153103
This commit is contained in:
@@ -37,7 +37,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Constness {
|
||||
}
|
||||
}
|
||||
Node::TraitItem(ti @ TraitItem { kind: TraitItemKind::Fn(..), .. }) => {
|
||||
if find_attr!(tcx.hir_attrs(ti.hir_id()), RustcNonConstTraitMethod) {
|
||||
if find_attr!(tcx, ti.hir_id(), RustcNonConstTraitMethod) {
|
||||
Constness::NotConst
|
||||
} else {
|
||||
tcx.trait_def(tcx.local_parent(def_id)).constness
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
mod encode_cross_crate;
|
||||
mod pretty_printing;
|
||||
|
||||
/// A trait for types that can provide a list of attributes given a `TyCtxt`.
|
||||
///
|
||||
/// It allows `find_attr!` to accept either a `DefId`, `LocalDefId`, `OwnerId`, or `HirId`.
|
||||
/// It is defined here with a generic `Tcx` because `rustc_hir` can't depend on `rustc_middle`.
|
||||
/// The concrete implementations are in `rustc_middle`.
|
||||
pub trait HasAttrs<'tcx, Tcx> {
|
||||
fn get_attrs(self, tcx: &Tcx) -> &'tcx [crate::Attribute];
|
||||
}
|
||||
|
||||
/// Finds attributes in sequences of attributes by pattern matching.
|
||||
///
|
||||
/// A little like `matches` but for attributes.
|
||||
@@ -34,10 +43,12 @@
|
||||
///
|
||||
/// As a convenience, this macro can do that for you!
|
||||
///
|
||||
/// Instead of providing an attribute list, provide the `tcx` and a `DefId`.
|
||||
/// Instead of providing an attribute list, provide the `tcx` and an id
|
||||
/// (a `DefId`, `LocalDefId`, `OwnerId` or `HirId`).
|
||||
///
|
||||
/// ```rust,ignore (illustrative)
|
||||
/// find_attr!(tcx, def_id, <pattern>)
|
||||
/// find_attr!(tcx, hir_id, <pattern>)
|
||||
/// ```
|
||||
///
|
||||
/// Another common case is finding attributes applied to the root of the current crate.
|
||||
@@ -55,13 +66,14 @@ macro_rules! find_attr {
|
||||
$crate::find_attr!($tcx.hir_krate_attrs(), $pattern $(if $guard)? => $e)
|
||||
};
|
||||
|
||||
($tcx: expr, $def_id: expr, $pattern: pat $(if $guard: expr)?) => {
|
||||
$crate::find_attr!($tcx, $def_id, $pattern $(if $guard)? => ()).is_some()
|
||||
($tcx: expr, $id: expr, $pattern: pat $(if $guard: expr)?) => {
|
||||
$crate::find_attr!($tcx, $id, $pattern $(if $guard)? => ()).is_some()
|
||||
};
|
||||
($tcx: expr, $def_id: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{
|
||||
#[allow(deprecated)] {
|
||||
$crate::find_attr!($tcx.get_all_attrs($def_id), $pattern $(if $guard)? => $e)
|
||||
}
|
||||
($tcx: expr, $id: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{
|
||||
$crate::find_attr!(
|
||||
$crate::attrs::HasAttrs::get_attrs($id, &$tcx),
|
||||
$pattern $(if $guard)? => $e
|
||||
)
|
||||
}};
|
||||
|
||||
|
||||
|
||||
@@ -207,7 +207,7 @@ fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
|
||||
};
|
||||
|
||||
// A `#[const_continue]` must break to a block in a `#[loop_match]`.
|
||||
if find_attr!(self.tcx.hir_attrs(e.hir_id), ConstContinue(_)) {
|
||||
if find_attr!(self.tcx, e.hir_id, ConstContinue(_)) {
|
||||
let Some(label) = break_destination.label else {
|
||||
let span = e.span;
|
||||
self.tcx.dcx().emit_fatal(ConstContinueBadLabel { span });
|
||||
@@ -420,7 +420,7 @@ fn is_loop_match(
|
||||
e: &'hir hir::Expr<'hir>,
|
||||
body: &'hir hir::Block<'hir>,
|
||||
) -> Option<Destination> {
|
||||
if !find_attr!(self.tcx.hir_attrs(e.hir_id), LoopMatch(_)) {
|
||||
if !find_attr!(self.tcx, e.hir_id, LoopMatch(_)) {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option<LocalDefId> {
|
||||
let mut decls = None;
|
||||
|
||||
for id in tcx.hir_free_items() {
|
||||
if find_attr!(tcx.hir_attrs(id.hir_id()), RustcProcMacroDecls) {
|
||||
if find_attr!(tcx, id.hir_id(), RustcProcMacroDecls) {
|
||||
decls = Some(id.owner_id.def_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2172,6 +2172,36 @@ pub fn fn_abi_of_instance(
|
||||
}
|
||||
}
|
||||
|
||||
// `HasAttrs` impls: allow `find_attr!(tcx, id, ...)` to work with both DefId-like types and HirId.
|
||||
|
||||
impl<'tcx> hir::attrs::HasAttrs<'tcx, TyCtxt<'tcx>> for DefId {
|
||||
fn get_attrs(self, tcx: &TyCtxt<'tcx>) -> &'tcx [hir::Attribute] {
|
||||
if let Some(did) = self.as_local() {
|
||||
tcx.hir_attrs(tcx.local_def_id_to_hir_id(did))
|
||||
} else {
|
||||
tcx.attrs_for_def(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> hir::attrs::HasAttrs<'tcx, TyCtxt<'tcx>> for LocalDefId {
|
||||
fn get_attrs(self, tcx: &TyCtxt<'tcx>) -> &'tcx [hir::Attribute] {
|
||||
tcx.hir_attrs(tcx.local_def_id_to_hir_id(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> hir::attrs::HasAttrs<'tcx, TyCtxt<'tcx>> for hir::OwnerId {
|
||||
fn get_attrs(self, tcx: &TyCtxt<'tcx>) -> &'tcx [hir::Attribute] {
|
||||
hir::attrs::HasAttrs::get_attrs(self.def_id, tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> hir::attrs::HasAttrs<'tcx, TyCtxt<'tcx>> for hir::HirId {
|
||||
fn get_attrs(self, tcx: &TyCtxt<'tcx>) -> &'tcx [hir::Attribute] {
|
||||
tcx.hir_attrs(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
closure::provide(providers);
|
||||
context::provide(providers);
|
||||
|
||||
@@ -491,7 +491,7 @@ fn construct_fn<'tcx>(
|
||||
};
|
||||
|
||||
if let Some((dialect, phase)) =
|
||||
find_attr!(tcx.hir_attrs(fn_id), CustomMir(dialect, phase, _) => (dialect, phase))
|
||||
find_attr!(tcx, fn_id, CustomMir(dialect, phase, _) => (dialect, phase))
|
||||
{
|
||||
return custom::build_custom_mir(
|
||||
tcx,
|
||||
|
||||
@@ -917,7 +917,7 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx>
|
||||
hir::ExprKind::Ret(v) => ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) },
|
||||
hir::ExprKind::Become(call) => ExprKind::Become { value: self.mirror_expr(call) },
|
||||
hir::ExprKind::Break(dest, ref value) => {
|
||||
if find_attr!(self.tcx.hir_attrs(expr.hir_id), ConstContinue(_)) {
|
||||
if find_attr!(self.tcx, expr.hir_id, ConstContinue(_)) {
|
||||
match dest.target_id {
|
||||
Ok(target_id) => {
|
||||
let (Some(value), Some(_)) = (value, dest.label) else {
|
||||
@@ -982,7 +982,7 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx>
|
||||
match_source,
|
||||
},
|
||||
hir::ExprKind::Loop(body, ..) => {
|
||||
if find_attr!(self.tcx.hir_attrs(expr.hir_id), LoopMatch(_)) {
|
||||
if find_attr!(self.tcx, expr.hir_id, LoopMatch(_)) {
|
||||
let dcx = self.tcx.dcx();
|
||||
|
||||
// Accept either `state = expr` or `state = expr;`.
|
||||
|
||||
@@ -104,7 +104,7 @@ fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self {
|
||||
typing_env: ty::TypingEnv::non_body_analysis(tcx, def),
|
||||
typeck_results,
|
||||
body_owner: def.to_def_id(),
|
||||
apply_adjustments: !find_attr!(tcx.hir_attrs(hir_id), CustomMir(..) => ()).is_some(),
|
||||
apply_adjustments: !find_attr!(tcx, hir_id, CustomMir(..)),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
|
||||
let attrs = cx.tcx.hir_attrs(item.hir_id());
|
||||
let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), MustUse { span, reason } => (span, reason));
|
||||
let attr = find_attr!(cx.tcx, item.hir_id(), MustUse { span, reason } => (span, reason));
|
||||
if let hir::ItemKind::Fn {
|
||||
ref sig,
|
||||
body: ref body_id,
|
||||
@@ -65,7 +65,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
|
||||
let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
|
||||
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
|
||||
let attrs = cx.tcx.hir_attrs(item.hir_id());
|
||||
let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), MustUse { span, reason } => (span, reason));
|
||||
let attr = find_attr!(cx.tcx, item.hir_id(), MustUse { span, reason } => (span, reason));
|
||||
if let Some((attr_span, reason)) = attr {
|
||||
check_needless_must_use(
|
||||
cx,
|
||||
@@ -98,7 +98,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr
|
||||
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
|
||||
|
||||
let attrs = cx.tcx.hir_attrs(item.hir_id());
|
||||
let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), MustUse { span, reason } => (span, reason));
|
||||
let attr = find_attr!(cx.tcx, item.hir_id(), MustUse { span, reason } => (span, reason));
|
||||
if let Some((attr_span, reason)) = attr {
|
||||
check_needless_must_use(
|
||||
cx,
|
||||
|
||||
@@ -269,5 +269,5 @@ fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &'tcx hir::Ty<'tcx, Ambig
|
||||
fn is_under_cfg_attribute(cx: &LateContext<'_>, hir_id: HirId) -> bool {
|
||||
cx.tcx
|
||||
.hir_parent_id_iter(hir_id)
|
||||
.any(|id| find_attr!(cx.tcx.hir_attrs(id), CfgTrace(..) | CfgAttrTrace))
|
||||
.any(|id| find_attr!(cx.tcx, id, CfgTrace(..) | CfgAttrTrace))
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
|
||||
.then_some((v.def_id, v.span))
|
||||
});
|
||||
if let Ok((id, span)) = iter.exactly_one()
|
||||
&& !find_attr!(cx.tcx.hir_attrs(item.hir_id()), NonExhaustive(..))
|
||||
&& !find_attr!(cx.tcx, item.hir_id(), NonExhaustive(..))
|
||||
{
|
||||
self.potential_enums.push((item.owner_id.def_id, id, item.span, span));
|
||||
}
|
||||
@@ -113,7 +113,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
|
||||
"this seems like a manual implementation of the non-exhaustive pattern",
|
||||
|diag| {
|
||||
if let Some(non_exhaustive_span) =
|
||||
find_attr!(cx.tcx.hir_attrs(item.hir_id()), NonExhaustive(span) => *span)
|
||||
find_attr!(cx.tcx, item.hir_id(), NonExhaustive(span) => *span)
|
||||
{
|
||||
diag.span_note(non_exhaustive_span, "the struct is already non-exhaustive");
|
||||
} else {
|
||||
|
||||
@@ -39,7 +39,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_
|
||||
fn is_under_cfg(cx: &LateContext<'_>, id: HirId) -> bool {
|
||||
cx.tcx
|
||||
.hir_parent_id_iter(id)
|
||||
.any(|id| find_attr!(cx.tcx.hir_attrs(id), CfgTrace(..)))
|
||||
.any(|id| find_attr!(cx.tcx, id, CfgTrace(..)))
|
||||
}
|
||||
|
||||
/// Similar to [`clippy_utils::expr_or_init`], but does not go up the chain if the initialization
|
||||
|
||||
@@ -1710,7 +1710,7 @@ pub fn has_attr(attrs: &[hir::Attribute], symbol: Symbol) -> bool {
|
||||
}
|
||||
|
||||
pub fn has_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool {
|
||||
find_attr!(cx.tcx.hir_attrs(hir_id), Repr { .. })
|
||||
find_attr!(cx.tcx, hir_id, Repr { .. })
|
||||
}
|
||||
|
||||
pub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool {
|
||||
@@ -2410,7 +2410,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl FnOnce(&
|
||||
&& let TyKind::Path(QPath::Resolved(_, path)) = ty.kind
|
||||
// We could also check for the type name `test::TestDescAndFn`
|
||||
&& let Res::Def(DefKind::Struct, _) = path.res
|
||||
&& find_attr!(tcx.hir_attrs(item.hir_id()), RustcTestMarker(..))
|
||||
&& find_attr!(tcx, item.hir_id(), RustcTestMarker(..))
|
||||
{
|
||||
names.push(ident.name);
|
||||
}
|
||||
@@ -2468,7 +2468,7 @@ pub fn is_test_function(tcx: TyCtxt<'_>, fn_def_id: LocalDefId) -> bool {
|
||||
/// This only checks directly applied attributes, to see if a node is inside a `#[cfg(test)]` parent
|
||||
/// use [`is_in_cfg_test`]
|
||||
pub fn is_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool {
|
||||
if let Some(cfgs) = find_attr!(tcx.hir_attrs(id), CfgTrace(cfgs) => cfgs)
|
||||
if let Some(cfgs) = find_attr!(tcx, id, CfgTrace(cfgs) => cfgs)
|
||||
&& cfgs
|
||||
.iter()
|
||||
.any(|(cfg, _)| matches!(cfg, CfgEntry::NameValue { name: sym::test, .. }))
|
||||
|
||||
Reference in New Issue
Block a user