Skip to content
Closed
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
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/fn_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 19 additions & 7 deletions compiler/rustc_hir/src/attrs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ pub mod diagnostic;
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.
Expand All @@ -34,10 +43,12 @@ mod pretty_printing;
///
/// 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.
Expand All @@ -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
)
}};


Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/loops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'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 });
Expand Down Expand Up @@ -420,7 +420,7 @@ impl<'hir> CheckLoopVisitor<'hir> {
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;
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_interface/src/proc_macro_decls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
30 changes: 30 additions & 0 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2172,6 +2172,36 @@ impl<'tcx> TyCtxt<'tcx> {
}
}

// `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);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ impl<'tcx> ThirBuildCx<'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 {
Expand Down Expand Up @@ -982,7 +982,7 @@ impl<'tcx> ThirBuildCx<'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;`.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/thir/cx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
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(..)),
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/tools/clippy/clippy_lints/src/functions/must_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT};

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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,5 +269,5 @@ impl<'tcx> LateLintPass<'tcx> for IncompatibleMsrv {
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))
}
4 changes: 2 additions & 2 deletions src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive {
.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));
}
Expand All @@ -113,7 +113,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive {
"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 {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/methods/is_empty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions src/tools/clippy/clippy_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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, .. }))
Expand Down
9 changes: 8 additions & 1 deletion src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1919,8 +1919,15 @@ impl<'test> TestCx<'test> {
compiler.args(&["-A", "unused", "-W", "unused_attributes"]);
}

// Allow tests to use internal features.
// Allow tests to use internal and incomplete features.
compiler.args(&["-A", "internal_features"]);
// FIXME(#154168); temporarily exclude some directories to make the transition easier
if !input_file
.iter()
.any(|p| p == "traits" || p == "specialization" || p == "const-generics")
{
compiler.args(&["-A", "incomplete_features"]);
}

// Allow tests to have unused parens and braces.
// Add #![deny(unused_parens, unused_braces)] to the test file if you want to
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#![feature(generic_const_exprs)]
//~^ WARN the feature `generic_const_exprs` is incomplete
#![feature(min_generic_const_args)]
//~^ WARN the feature `min_generic_const_args` is incomplete
#![feature(inherent_associated_types)]
//~^ WARN the feature `inherent_associated_types` is incomplete

struct OnDiskDirEntry<'a>(&'a ());

Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,10 @@
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/type-const-in-array-len-wrong-type.rs:1:12
|
LL | #![feature(generic_const_exprs)]
| ^^^^^^^^^^^^^^^^^^^
|
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
= note: `#[warn(incomplete_features)]` on by default

warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/type-const-in-array-len-wrong-type.rs:3:12
|
LL | #![feature(min_generic_const_args)]
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #132980 <https://github.com/rust-lang/rust/issues/132980> for more information

warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/type-const-in-array-len-wrong-type.rs:5:12
|
LL | #![feature(inherent_associated_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information

error: the constant `2` is not of type `usize`
--> $DIR/type-const-in-array-len-wrong-type.rs:13:26
--> $DIR/type-const-in-array-len-wrong-type.rs:10:26
|
LL | fn lfn_contents() -> [char; Self::LFN_FRAGMENT_LEN] {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i64`
|
= note: the length of array `[char; 2]` must be type `usize`

error: aborting due to 1 previous error; 3 warnings emitted
error: aborting due to 1 previous error

2 changes: 0 additions & 2 deletions tests/ui/associated-consts/type-const-in-array-len.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
//@ check-pass

#![feature(min_generic_const_args)]
//~^ WARN the feature `min_generic_const_args` is incomplete
#![feature(inherent_associated_types)]
//~^ WARN the feature `inherent_associated_types` is incomplete

// Test case from #138226: generic impl with multiple type parameters
struct Foo<A, B>(A, B);
Expand Down
19 changes: 0 additions & 19 deletions tests/ui/associated-consts/type-const-in-array-len.stderr

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

// Regression test for #146467.
#![feature(inherent_associated_types)]
//~^ WARN the feature `inherent_associated_types` is incomplete

struct Foo<T>(T);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:4:12
|
LL | #![feature(inherent_associated_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
= note: `#[warn(incomplete_features)]` on by default

error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:9:6
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:8:6
|
LL | impl<'a> Foo<fn(&())> {
| ^^ unconstrained lifetime parameter

error[E0308]: mismatched types
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:11
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:13:11
|
LL | fn foo(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
Expand All @@ -23,12 +14,12 @@ LL | fn foo(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
found struct `Foo<for<'a> fn(&'a ())>`

error: higher-ranked subtype error
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:1
--> $DIR/hr-do-not-blame-outlives-static-ice.rs:13:1
|
LL | fn foo(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors; 1 warning emitted
error: aborting due to 3 previous errors

Some errors have detailed explanations: E0207, E0308.
For more information about an error, try `rustc --explain E0207`.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//@ check-pass

#![feature(inherent_associated_types)]
//~^ WARN the feature `inherent_associated_types` is incomplete

struct D<T> {
a: T
Expand Down
Loading
Loading