Skip to content

Commit 85f0a70

Browse files
committed
Auto merge of #145085 - JonathanBrouwer:target_checking, r=jdonszelmann
Rework target checking for built-in attributes This is a refactoring of target checking for built-in attributes. This PR has the following goals: - Only refactor the 80% of the attributes that are simple to target check. More complicated ones like `#[repr]` will be in a future PR. Tho I have written the code in such a way that this will be possible to add in the future. - No breaking changes. - This part of the codebase is not very well tested though, we can do a crater run if we want to be sure. - I've spotted quite a few weird situations (like I don't think an impl block should be deprecated?). We can propose fixing these to in a future PR Fixes #143780 Fixes #138510 I've split it in commits and left a description on some of the commits to help review. r? `@jdonszelmann`
2 parents 350d0ef + 7a85aa9 commit 85f0a70

File tree

155 files changed

+3424
-3632
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

155 files changed

+3424
-3632
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3480,6 +3480,7 @@ dependencies = [
34803480
name = "rustc_attr_parsing"
34813481
version = "0.0.0"
34823482
dependencies = [
3483+
"itertools",
34833484
"rustc_abi",
34843485
"rustc_ast",
34853486
"rustc_ast_pretty",

compiler/rustc_ast_lowering/src/block.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use rustc_ast::{Block, BlockCheckMode, Local, LocalKind, Stmt, StmtKind};
22
use rustc_hir as hir;
3+
use rustc_hir::Target;
34
use rustc_span::sym;
45
use smallvec::SmallVec;
56

@@ -109,7 +110,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
109110
};
110111
let span = self.lower_span(l.span);
111112
let source = hir::LocalSource::Normal;
112-
self.lower_attrs(hir_id, &l.attrs, l.span);
113+
self.lower_attrs(hir_id, &l.attrs, l.span, Target::Statement);
113114
self.arena.alloc(hir::LetStmt { hir_id, super_, ty, pat, init, els, span, source })
114115
}
115116

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
77
use rustc_hir as hir;
88
use rustc_hir::attrs::AttributeKind;
99
use rustc_hir::def::{DefKind, Res};
10-
use rustc_hir::{HirId, find_attr};
10+
use rustc_hir::{HirId, Target, find_attr};
1111
use rustc_middle::span_bug;
1212
use rustc_middle::ty::TyCtxt;
1313
use rustc_session::errors::report_lit_error;
@@ -74,7 +74,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
7474
if !e.attrs.is_empty() {
7575
let old_attrs = self.attrs.get(&ex.hir_id.local_id).copied().unwrap_or(&[]);
7676
let new_attrs = self
77-
.lower_attrs_vec(&e.attrs, e.span, ex.hir_id)
77+
.lower_attrs_vec(&e.attrs, e.span, ex.hir_id, Target::from_expr(e))
7878
.into_iter()
7979
.chain(old_attrs.iter().cloned());
8080
let new_attrs = &*self.arena.alloc_from_iter(new_attrs);
@@ -97,7 +97,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
9797
}
9898

9999
let expr_hir_id = self.lower_node_id(e.id);
100-
let attrs = self.lower_attrs(expr_hir_id, &e.attrs, e.span);
100+
let attrs = self.lower_attrs(expr_hir_id, &e.attrs, e.span, Target::from_expr(e));
101101

102102
let kind = match &e.kind {
103103
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
@@ -639,7 +639,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
639639
let guard = arm.guard.as_ref().map(|cond| self.lower_expr(cond));
640640
let hir_id = self.next_id();
641641
let span = self.lower_span(arm.span);
642-
self.lower_attrs(hir_id, &arm.attrs, arm.span);
642+
self.lower_attrs(hir_id, &arm.attrs, arm.span, Target::Arm);
643643
let is_never_pattern = pat.is_never_pattern();
644644
// We need to lower the body even if it's unneeded for never pattern in match,
645645
// ensure that we can get HirId for DefId if need (issue #137708).
@@ -820,6 +820,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
820820
span: unstable_span,
821821
}],
822822
span,
823+
Target::Fn,
823824
);
824825
}
825826
}
@@ -1654,7 +1655,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
16541655

16551656
fn lower_expr_field(&mut self, f: &ExprField) -> hir::ExprField<'hir> {
16561657
let hir_id = self.lower_node_id(f.id);
1657-
self.lower_attrs(hir_id, &f.attrs, f.span);
1658+
self.lower_attrs(hir_id, &f.attrs, f.span, Target::ExprField);
16581659
hir::ExprField {
16591660
hir_id,
16601661
ident: self.lower_ident(f.ident),
@@ -1910,7 +1911,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
19101911
//
19111912
// Also, add the attributes to the outer returned expr node.
19121913
let expr = self.expr_drop_temps_mut(for_span, match_expr);
1913-
self.lower_attrs(expr.hir_id, &e.attrs, e.span);
1914+
self.lower_attrs(expr.hir_id, &e.attrs, e.span, Target::from_expr(e));
19141915
expr
19151916
}
19161917

@@ -1967,7 +1968,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
19671968
let val_ident = Ident::with_dummy_span(sym::val);
19681969
let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident);
19691970
let val_expr = self.expr_ident(span, val_ident, val_pat_nid);
1970-
self.lower_attrs(val_expr.hir_id, &attrs, span);
1971+
self.lower_attrs(val_expr.hir_id, &attrs, span, Target::Expression);
19711972
let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
19721973
self.arm(continue_pat, val_expr)
19731974
};
@@ -1998,7 +1999,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
19981999
let ret_expr = self.checked_return(Some(from_residual_expr));
19992000
self.arena.alloc(self.expr(try_span, ret_expr))
20002001
};
2001-
self.lower_attrs(ret_expr.hir_id, &attrs, span);
2002+
self.lower_attrs(ret_expr.hir_id, &attrs, span, Target::Expression);
20022003

20032004
let break_pat = self.pat_cf_break(try_span, residual_local);
20042005
self.arm(break_pat, ret_expr)

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};
55
use rustc_hir::attrs::AttributeKind;
66
use rustc_hir::def::{DefKind, PerNS, Res};
77
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
8-
use rustc_hir::{self as hir, HirId, LifetimeSource, PredicateOrigin, find_attr};
8+
use rustc_hir::{self as hir, HirId, LifetimeSource, PredicateOrigin, Target, find_attr};
99
use rustc_index::{IndexSlice, IndexVec};
1010
use rustc_middle::span_bug;
1111
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
@@ -80,7 +80,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
8080
self.with_lctx(CRATE_NODE_ID, |lctx| {
8181
let module = lctx.lower_mod(&c.items, &c.spans);
8282
// FIXME(jdonszelman): is dummy span ever a problem here?
83-
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP);
83+
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP, Target::Crate);
8484
hir::OwnerNode::Crate(module)
8585
})
8686
}
@@ -136,7 +136,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
136136
fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
137137
let vis_span = self.lower_span(i.vis.span);
138138
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
139-
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
139+
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, Target::from_ast_item(i));
140140
let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind);
141141
let item = hir::Item {
142142
owner_id: hir_id.expect_owner(),
@@ -621,7 +621,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
621621
fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
622622
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
623623
let owner_id = hir_id.expect_owner();
624-
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
624+
let attrs =
625+
self.lower_attrs(hir_id, &i.attrs, i.span, Target::from_foreign_item_kind(&i.kind));
625626
let (ident, kind) = match &i.kind {
626627
ForeignItemKind::Fn(box Fn { sig, ident, generics, define_opaque, .. }) => {
627628
let fdec = &sig.decl;
@@ -690,7 +691,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
690691

691692
fn lower_variant(&mut self, item_kind: &ItemKind, v: &Variant) -> hir::Variant<'hir> {
692693
let hir_id = self.lower_node_id(v.id);
693-
self.lower_attrs(hir_id, &v.attrs, v.span);
694+
self.lower_attrs(hir_id, &v.attrs, v.span, Target::Variant);
694695
hir::Variant {
695696
hir_id,
696697
def_id: self.local_def_id(v.id),
@@ -773,7 +774,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
773774
) -> hir::FieldDef<'hir> {
774775
let ty = self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy));
775776
let hir_id = self.lower_node_id(f.id);
776-
self.lower_attrs(hir_id, &f.attrs, f.span);
777+
self.lower_attrs(hir_id, &f.attrs, f.span, Target::Field);
777778
hir::FieldDef {
778779
span: self.lower_span(f.span),
779780
hir_id,
@@ -792,7 +793,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
792793

793794
fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
794795
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
795-
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
796+
let attrs = self.lower_attrs(
797+
hir_id,
798+
&i.attrs,
799+
i.span,
800+
Target::from_assoc_item_kind(&i.kind, AssocCtxt::Trait),
801+
);
796802
let trait_item_def_id = hir_id.expect_owner();
797803

798804
let (ident, generics, kind, has_default) = match &i.kind {
@@ -1001,7 +1007,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
10011007
let has_value = true;
10021008
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
10031009
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
1004-
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
1010+
let attrs = self.lower_attrs(
1011+
hir_id,
1012+
&i.attrs,
1013+
i.span,
1014+
Target::from_assoc_item_kind(&i.kind, AssocCtxt::Impl { of_trait: is_in_trait_impl }),
1015+
);
10051016

10061017
let (ident, (generics, kind)) = match &i.kind {
10071018
AssocItemKind::Const(box ConstItem {
@@ -1171,7 +1182,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11711182

11721183
fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
11731184
let hir_id = self.lower_node_id(param.id);
1174-
self.lower_attrs(hir_id, &param.attrs, param.span);
1185+
self.lower_attrs(hir_id, &param.attrs, param.span, Target::Param);
11751186
hir::Param {
11761187
hir_id,
11771188
pat: self.lower_pat(&param.pat),
@@ -1851,7 +1862,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
18511862
) -> hir::WherePredicate<'hir> {
18521863
let hir_id = self.lower_node_id(pred.id);
18531864
let span = self.lower_span(pred.span);
1854-
self.lower_attrs(hir_id, &pred.attrs, span);
1865+
self.lower_attrs(hir_id, &pred.attrs, span, Target::WherePredicate);
18551866
let kind = self.arena.alloc(match &pred.kind {
18561867
WherePredicateKind::BoundPredicate(WhereBoundPredicate {
18571868
bound_generic_params,

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
5454
use rustc_hir::lints::DelayedLint;
5555
use rustc_hir::{
5656
self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource,
57-
LifetimeSyntax, ParamName, TraitCandidate,
57+
LifetimeSyntax, ParamName, Target, TraitCandidate,
5858
};
5959
use rustc_index::{Idx, IndexSlice, IndexVec};
6060
use rustc_macros::extension;
@@ -943,11 +943,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
943943
id: HirId,
944944
attrs: &[Attribute],
945945
target_span: Span,
946+
target: Target,
946947
) -> &'hir [hir::Attribute] {
947948
if attrs.is_empty() {
948949
&[]
949950
} else {
950-
let lowered_attrs = self.lower_attrs_vec(attrs, self.lower_span(target_span), id);
951+
let lowered_attrs =
952+
self.lower_attrs_vec(attrs, self.lower_span(target_span), id, target);
951953

952954
assert_eq!(id.owner, self.current_hir_id_owner);
953955
let ret = self.arena.alloc_from_iter(lowered_attrs);
@@ -972,12 +974,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
972974
attrs: &[Attribute],
973975
target_span: Span,
974976
target_hir_id: HirId,
977+
target: Target,
975978
) -> Vec<hir::Attribute> {
976979
let l = self.span_lowerer();
977980
self.attribute_parser.parse_attribute_list(
978981
attrs,
979982
target_span,
980983
target_hir_id,
984+
target,
981985
OmitDoc::Lower,
982986
|s| l.lower(s),
983987
|l| {
@@ -1942,7 +1946,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
19421946
let (name, kind) = self.lower_generic_param_kind(param, source);
19431947

19441948
let hir_id = self.lower_node_id(param.id);
1945-
self.lower_attrs(hir_id, &param.attrs, param.span());
1949+
self.lower_attrs(hir_id, &param.attrs, param.span(), Target::Param);
19461950
hir::GenericParam {
19471951
hir_id,
19481952
def_id: self.local_def_id(param.id),

compiler/rustc_ast_lowering/src/pat.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::sync::Arc;
33
use rustc_ast::*;
44
use rustc_data_structures::stack::ensure_sufficient_stack;
55
use rustc_hir::def::{DefKind, Res};
6-
use rustc_hir::{self as hir, LangItem};
6+
use rustc_hir::{self as hir, LangItem, Target};
77
use rustc_middle::span_bug;
88
use rustc_span::source_map::{Spanned, respan};
99
use rustc_span::{DesugaringKind, Ident, Span};
@@ -93,7 +93,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
9393

9494
let fs = self.arena.alloc_from_iter(fields.iter().map(|f| {
9595
let hir_id = self.lower_node_id(f.id);
96-
self.lower_attrs(hir_id, &f.attrs, f.span);
96+
self.lower_attrs(hir_id, &f.attrs, f.span, Target::PatField);
9797

9898
hir::PatField {
9999
hir_id,

compiler/rustc_attr_parsing/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ edition = "2024"
55

66
[dependencies]
77
# tidy-alphabetical-start
8+
itertools = "0.12"
89
rustc_abi = { path = "../rustc_abi" }
910
rustc_ast = { path = "../rustc_ast" }
1011
rustc_ast_pretty = { path = "../rustc_ast_pretty" }

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ attr_parsing_empty_attribute =
1010
unused attribute
1111
.suggestion = remove this attribute
1212
13+
attr_parsing_invalid_target = `#[{$name}]` attribute cannot be used on {$target}
14+
.help = `#[{$name}]` can {$only}be applied to {$applied}
15+
attr_parsing_invalid_target_lint = `#[{$name}]` attribute cannot be used on {$target}
16+
.warn = {-attr_parsing_previously_accepted}
17+
.help = `#[{$name}]` can {$only}be applied to {$applied}
18+
1319
attr_parsing_empty_confusables =
1420
expected at least one confusable name
1521
attr_parsing_expected_one_cfg_pattern =

compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ use std::iter;
22

33
use rustc_feature::{AttributeTemplate, template};
44
use rustc_hir::attrs::AttributeKind;
5+
use rustc_hir::{MethodKind, Target};
56
use rustc_span::{Span, Symbol, sym};
67

78
use super::{CombineAttributeParser, ConvertFn};
8-
use crate::context::{AcceptContext, Stage};
9+
use crate::context::MaybeWarn::{Allow, Warn};
10+
use crate::context::{AcceptContext, AllowedTargets, Stage};
911
use crate::parser::ArgParser;
1012
use crate::session_diagnostics;
1113

@@ -15,6 +17,12 @@ impl<S: Stage> CombineAttributeParser<S> for AllowInternalUnstableParser {
1517
type Item = (Symbol, Span);
1618
const CONVERT: ConvertFn<Self::Item> =
1719
|items, span| AttributeKind::AllowInternalUnstable(items, span);
20+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
21+
Allow(Target::MacroDef),
22+
Allow(Target::Fn),
23+
Warn(Target::Field),
24+
Warn(Target::Arm),
25+
]);
1826
const TEMPLATE: AttributeTemplate = template!(Word, List: &["feat1, feat2, ..."]);
1927

2028
fn extend<'c>(
@@ -32,6 +40,11 @@ impl<S: Stage> CombineAttributeParser<S> for UnstableFeatureBoundParser {
3240
const PATH: &'static [rustc_span::Symbol] = &[sym::unstable_feature_bound];
3341
type Item = (Symbol, Span);
3442
const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::UnstableFeatureBound(items);
43+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
44+
Allow(Target::Fn),
45+
Allow(Target::Impl { of_trait: true }),
46+
Allow(Target::Trait),
47+
]);
3548
const TEMPLATE: AttributeTemplate = template!(Word, List: &["feat1, feat2, ..."]);
3649

3750
fn extend<'c>(
@@ -53,6 +66,13 @@ impl<S: Stage> CombineAttributeParser<S> for AllowConstFnUnstableParser {
5366
type Item = Symbol;
5467
const CONVERT: ConvertFn<Self::Item> =
5568
|items, first_span| AttributeKind::AllowConstFnUnstable(items, first_span);
69+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
70+
Allow(Target::Fn),
71+
Allow(Target::Method(MethodKind::Inherent)),
72+
Allow(Target::Method(MethodKind::Trait { body: false })),
73+
Allow(Target::Method(MethodKind::Trait { body: true })),
74+
Allow(Target::Method(MethodKind::TraitImpl)),
75+
]);
5676
const TEMPLATE: AttributeTemplate = template!(Word, List: &["feat1, feat2, ..."]);
5777

5878
fn extend<'c>(
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
//! Attributes that can be found in function body.
22
3+
use rustc_hir::Target;
34
use rustc_hir::attrs::AttributeKind;
45
use rustc_span::{Symbol, sym};
56

67
use super::{NoArgsAttributeParser, OnDuplicate};
7-
use crate::context::Stage;
8+
use crate::context::MaybeWarn::Allow;
9+
use crate::context::{AllowedTargets, Stage};
810

911
pub(crate) struct CoroutineParser;
1012

1113
impl<S: Stage> NoArgsAttributeParser<S> for CoroutineParser {
1214
const PATH: &[Symbol] = &[sym::coroutine];
1315
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
16+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Closure)]);
1417
const CREATE: fn(rustc_span::Span) -> AttributeKind = |span| AttributeKind::Coroutine(span);
1518
}

0 commit comments

Comments
 (0)