Skip to content

Commit 5e10d24

Browse files
committed
Create AttrTarget for attribute parsing
1 parent 86e05cd commit 5e10d24

File tree

17 files changed

+352
-43
lines changed

17 files changed

+352
-43
lines changed

compiler/rustc_ast_lowering/src/block.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use rustc_ast::{Block, BlockCheckMode, Local, LocalKind, Stmt, StmtKind};
2+
use rustc_attr_parsing::AttrTarget;
23
use rustc_hir as hir;
34
use rustc_span::sym;
45
use smallvec::SmallVec;
@@ -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, AttrTarget::Let);
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: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_ast::ptr::P as AstP;
55
use rustc_ast::*;
66
use rustc_ast_pretty::pprust::expr_to_string;
77
use rustc_attr_data_structures::{AttributeKind, find_attr};
8+
use rustc_attr_parsing::AttrTarget;
89
use rustc_data_structures::stack::ensure_sufficient_stack;
910
use rustc_hir as hir;
1011
use rustc_hir::HirId;
@@ -14,7 +15,7 @@ use rustc_middle::ty::TyCtxt;
1415
use rustc_session::errors::report_lit_error;
1516
use rustc_span::source_map::{Spanned, respan};
1617
use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, sym};
17-
use thin_vec::{ThinVec, thin_vec};
18+
use thin_vec::ThinVec;
1819
use visit::{Visitor, walk_expr};
1920

2021
use super::errors::{
@@ -75,7 +76,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
7576
if !e.attrs.is_empty() {
7677
let old_attrs = self.attrs.get(&ex.hir_id.local_id).copied().unwrap_or(&[]);
7778
let new_attrs = self
78-
.lower_attrs_vec(&e.attrs, e.span, ex.hir_id)
79+
.lower_attrs_vec(&e.attrs, e.span, ex.hir_id, AttrTarget::from_expr(e))
7980
.into_iter()
8081
.chain(old_attrs.iter().cloned());
8182
let new_attrs = &*self.arena.alloc_from_iter(new_attrs);
@@ -98,7 +99,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
9899
}
99100

100101
let expr_hir_id = self.lower_node_id(e.id);
101-
self.lower_attrs(expr_hir_id, &e.attrs, e.span);
102+
self.lower_attrs(expr_hir_id, &e.attrs, e.span, AttrTarget::from_expr(e));
102103

103104
let kind = match &e.kind {
104105
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
@@ -674,7 +675,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
674675
let guard = arm.guard.as_ref().map(|cond| self.lower_expr(cond));
675676
let hir_id = self.next_id();
676677
let span = self.lower_span(arm.span);
677-
self.lower_attrs(hir_id, &arm.attrs, arm.span);
678+
self.lower_attrs(hir_id, &arm.attrs, arm.span, AttrTarget::Arm);
678679
let is_never_pattern = pat.is_never_pattern();
679680
// We need to lower the body even if it's unneeded for never pattern in match,
680681
// ensure that we can get HirId for DefId if need (issue #137708).
@@ -825,6 +826,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
825826
span: Span,
826827
outer_hir_id: HirId,
827828
inner_hir_id: HirId,
829+
target: AttrTarget<'_>,
828830
) {
829831
if self.tcx.features().async_fn_track_caller()
830832
&& let Some(attrs) = self.attrs.get(&outer_hir_id.local_id)
@@ -847,6 +849,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
847849
span: unstable_span,
848850
}],
849851
span,
852+
target,
850853
);
851854
}
852855
}
@@ -1218,7 +1221,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
12181221
hir::CoroutineSource::Closure,
12191222
);
12201223

1221-
this.maybe_forward_track_caller(body.span, closure_hir_id, expr.hir_id);
1224+
this.maybe_forward_track_caller(
1225+
body.span,
1226+
closure_hir_id,
1227+
expr.hir_id,
1228+
AttrTarget::from_expr(body),
1229+
);
12221230

12231231
(parameters, expr)
12241232
});
@@ -1687,7 +1695,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
16871695

16881696
fn lower_expr_field(&mut self, f: &ExprField) -> hir::ExprField<'hir> {
16891697
let hir_id = self.lower_node_id(f.id);
1690-
self.lower_attrs(hir_id, &f.attrs, f.span);
1698+
self.lower_attrs(hir_id, &f.attrs, f.span, AttrTarget::ExprField);
16911699
hir::ExprField {
16921700
hir_id,
16931701
ident: self.lower_ident(f.ident),
@@ -1943,7 +1951,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
19431951
//
19441952
// Also, add the attributes to the outer returned expr node.
19451953
let expr = self.expr_drop_temps_mut(for_span, match_expr);
1946-
self.lower_attrs(expr.hir_id, &e.attrs, e.span);
1954+
self.lower_attrs(expr.hir_id, &e.attrs, e.span, AttrTarget::from_expr(e));
19471955
expr
19481956
}
19491957

@@ -1985,22 +1993,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
19851993
};
19861994

19871995
// `#[allow(unreachable_code)]`
1988-
let attr = attr::mk_attr_nested_word(
1996+
let attrs = &[attr::mk_attr_nested_word(
19891997
&self.tcx.sess.psess.attr_id_generator,
19901998
AttrStyle::Outer,
19911999
Safety::Default,
19922000
sym::allow,
19932001
sym::unreachable_code,
19942002
try_span,
1995-
);
1996-
let attrs: AttrVec = thin_vec![attr];
2003+
)];
19972004

19982005
// `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,`
19992006
let continue_arm = {
20002007
let val_ident = Ident::with_dummy_span(sym::val);
20012008
let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident);
20022009
let val_expr = self.expr_ident(span, val_ident, val_pat_nid);
2003-
self.lower_attrs(val_expr.hir_id, &attrs, span);
2010+
self.lower_attrs(val_expr.hir_id, attrs, span, AttrTarget::Expression { kind: None });
20042011
let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
20052012
self.arm(continue_pat, val_expr)
20062013
};
@@ -2031,7 +2038,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
20312038
let ret_expr = self.checked_return(Some(from_residual_expr));
20322039
self.arena.alloc(self.expr(try_span, ret_expr))
20332040
};
2034-
self.lower_attrs(ret_expr.hir_id, &attrs, span);
2041+
self.lower_attrs(ret_expr.hir_id, attrs, span, AttrTarget::Expression { kind: None });
20352042

20362043
let break_pat = self.pat_cf_break(try_span, residual_local);
20372044
self.arm(break_pat, ret_expr)

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc_abi::ExternAbi;
22
use rustc_ast::ptr::P;
33
use rustc_ast::visit::AssocCtxt;
44
use rustc_ast::*;
5+
use rustc_attr_parsing::{AttrTarget, Position};
56
use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};
67
use rustc_hir::def::{DefKind, PerNS, Res};
78
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
@@ -83,7 +84,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
8384
self.with_lctx(CRATE_NODE_ID, |lctx| {
8485
let module = lctx.lower_mod(&c.items, &c.spans);
8586
// FIXME(jdonszelman): is dummy span ever a problem here?
86-
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP);
87+
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP, AttrTarget::Crate);
8788
hir::OwnerNode::Crate(module)
8889
})
8990
}
@@ -139,7 +140,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
139140
fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
140141
let vis_span = self.lower_span(i.vis.span);
141142
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
142-
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
143+
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, AttrTarget::from_item(&i.kind));
143144
let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind);
144145
let item = hir::Item {
145146
owner_id: hir_id.expect_owner(),
@@ -229,6 +230,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
229230
body.as_deref(),
230231
attrs,
231232
contract.as_deref(),
233+
AttrTarget::from_item(i),
232234
);
233235

234236
let itctx = ImplTraitContext::Universal;
@@ -642,7 +644,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
642644
fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
643645
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
644646
let owner_id = hir_id.expect_owner();
645-
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
647+
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, AttrTarget::from_foreign(i));
646648
let (ident, kind) = match &i.kind {
647649
ForeignItemKind::Fn(box Fn { sig, ident, generics, define_opaque, .. }) => {
648650
let fdec = &sig.decl;
@@ -717,7 +719,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
717719

718720
fn lower_variant(&mut self, item_kind: &ItemKind, v: &Variant) -> hir::Variant<'hir> {
719721
let hir_id = self.lower_node_id(v.id);
720-
self.lower_attrs(hir_id, &v.attrs, v.span);
722+
self.lower_attrs(hir_id, &v.attrs, v.span, AttrTarget::EnumVariant);
721723
hir::Variant {
722724
hir_id,
723725
def_id: self.local_def_id(v.id),
@@ -800,7 +802,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
800802
) -> hir::FieldDef<'hir> {
801803
let ty = self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy));
802804
let hir_id = self.lower_node_id(f.id);
803-
self.lower_attrs(hir_id, &f.attrs, f.span);
805+
self.lower_attrs(hir_id, &f.attrs, f.span, AttrTarget::Field);
804806
hir::FieldDef {
805807
span: self.lower_span(f.span),
806808
hir_id,
@@ -819,7 +821,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
819821

820822
fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
821823
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
822-
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
824+
let target = AttrTarget::from_trait_item(i);
825+
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, target);
823826
let trait_item_def_id = hir_id.expect_owner();
824827

825828
let (ident, generics, kind, has_default) = match &i.kind {
@@ -902,6 +905,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
902905
Some(body),
903906
attrs,
904907
contract.as_deref(),
908+
target,
905909
);
906910
let (generics, sig) = self.lower_method_sig(
907911
generics,
@@ -1013,7 +1017,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
10131017
let has_value = true;
10141018
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
10151019
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
1016-
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
1020+
1021+
let target = AttrTarget::from_impl_item(
1022+
if is_in_trait_impl { Position::TraitImpl } else { Position::Impl },
1023+
i,
1024+
);
1025+
1026+
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, target);
10171027

10181028
let (ident, (generics, kind)) = match &i.kind {
10191029
AssocItemKind::Const(box ConstItem {
@@ -1056,6 +1066,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10561066
body.as_deref(),
10571067
attrs,
10581068
contract.as_deref(),
1069+
target,
10591070
);
10601071
let (generics, sig) = self.lower_method_sig(
10611072
generics,
@@ -1207,7 +1218,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12071218

12081219
fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
12091220
let hir_id = self.lower_node_id(param.id);
1210-
self.lower_attrs(hir_id, &param.attrs, param.span);
1221+
self.lower_attrs(hir_id, &param.attrs, param.span, AttrTarget::Param);
12111222
hir::Param {
12121223
hir_id,
12131224
pat: self.lower_pat(&param.pat),
@@ -1335,6 +1346,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13351346
body: Option<&Block>,
13361347
attrs: &'hir [hir::Attribute],
13371348
contract: Option<&FnContract>,
1349+
target: AttrTarget<'_>,
13381350
) -> hir::BodyId {
13391351
let Some(body) = body else {
13401352
// Functions without a body are an error, except if this is an intrinsic. For those we
@@ -1382,7 +1394,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13821394

13831395
// FIXME(async_fn_track_caller): Can this be moved above?
13841396
let hir_id = expr.hir_id;
1385-
this.maybe_forward_track_caller(body.span, fn_id, hir_id);
1397+
this.maybe_forward_track_caller(body.span, fn_id, hir_id, target);
13861398

13871399
(parameters, expr)
13881400
})
@@ -1936,7 +1948,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
19361948
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
19371949
let hir_id = self.lower_node_id(pred.id);
19381950
let span = self.lower_span(pred.span);
1939-
self.lower_attrs(hir_id, &pred.attrs, span);
1951+
self.lower_attrs(hir_id, &pred.attrs, span, AttrTarget::WherePredicate);
19401952
let kind = self.arena.alloc(match &pred.kind {
19411953
WherePredicateKind::BoundPredicate(WhereBoundPredicate {
19421954
bound_generic_params,

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use std::sync::Arc;
4242

4343
use rustc_ast::node_id::NodeMap;
4444
use rustc_ast::{self as ast, *};
45-
use rustc_attr_parsing::{AttributeParser, OmitDoc};
45+
use rustc_attr_parsing::{AttrTarget, AttributeParser, OmitDoc};
4646
use rustc_data_structures::fingerprint::Fingerprint;
4747
use rustc_data_structures::sorted_map::SortedMap;
4848
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -912,11 +912,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
912912
id: HirId,
913913
attrs: &[Attribute],
914914
target_span: Span,
915+
target: AttrTarget<'_>,
915916
) -> &'hir [hir::Attribute] {
916917
if attrs.is_empty() {
917918
&[]
918919
} else {
919-
let lowered_attrs = self.lower_attrs_vec(attrs, self.lower_span(target_span), id);
920+
let lowered_attrs =
921+
self.lower_attrs_vec(attrs, self.lower_span(target_span), id, target);
920922

921923
assert_eq!(id.owner, self.current_hir_id_owner);
922924
let ret = self.arena.alloc_from_iter(lowered_attrs);
@@ -941,12 +943,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
941943
attrs: &[Attribute],
942944
target_span: Span,
943945
target_hir_id: HirId,
946+
target: AttrTarget<'_>,
944947
) -> Vec<hir::Attribute> {
945948
let l = self.span_lowerer();
946949
self.attribute_parser.parse_attribute_list(
947950
attrs,
948951
target_span,
949952
target_hir_id,
953+
target,
950954
OmitDoc::Lower,
951955
|s| l.lower(s),
952956
|l| {
@@ -1899,7 +1903,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18991903
let (name, kind) = self.lower_generic_param_kind(param, source);
19001904

19011905
let hir_id = self.lower_node_id(param.id);
1902-
self.lower_attrs(hir_id, &param.attrs, param.span());
1906+
self.lower_attrs(hir_id, &param.attrs, param.span(), AttrTarget::from_generic(param));
19031907
hir::GenericParam {
19041908
hir_id,
19051909
def_id: self.local_def_id(param.id),

compiler/rustc_ast_lowering/src/pat.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::sync::Arc;
22

33
use rustc_ast::ptr::P;
44
use rustc_ast::*;
5+
use rustc_attr_parsing::AttrTarget;
56
use rustc_data_structures::stack::ensure_sufficient_stack;
67
use rustc_hir::def::{DefKind, Res};
78
use rustc_hir::{self as hir, LangItem};
@@ -94,7 +95,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
9495

9596
let fs = self.arena.alloc_from_iter(fields.iter().map(|f| {
9697
let hir_id = self.lower_node_id(f.id);
97-
self.lower_attrs(hir_id, &f.attrs, f.span);
98+
self.lower_attrs(hir_id, &f.attrs, f.span, AttrTarget::PatField);
9899

99100
hir::PatField {
100101
hir_id,

compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ pub enum AttributeKind {
297297
RustcLayoutScalarValidRangeStart(Box<u128>, Span),
298298

299299
/// Represents `#[rustc_skip_during_method_dispatch]`.
300-
SkipDuringMethodDispatch { array: bool, boxed_slice: bool, span: Span },
300+
SkipDuringMethodDispatch { array: bool, boxed_slice: bool },
301301

302302
/// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`.
303303
Stability {

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ attr_parsing_rustc_allowed_unstable_pairing =
110110
attr_parsing_rustc_promotable_pairing =
111111
`rustc_promotable` attribute must be paired with either a `rustc_const_unstable` or a `rustc_const_stable` attribute
112112
113+
attr_parsing_should_be_applied_to_trait =
114+
attribute should be applied to a trait
115+
.label = not a trait
116+
113117
attr_parsing_soft_no_args =
114118
`soft` should not have any arguments
115119

compiler/rustc_attr_parsing/src/attributes/traits.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ use rustc_attr_data_structures::AttributeKind;
44
use rustc_feature::{AttributeTemplate, template};
55
use rustc_span::{Symbol, sym};
66

7+
use crate::AttrTarget;
78
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
89
use crate::context::{AcceptContext, Stage};
910
use crate::parser::ArgParser;
11+
use crate::session_diagnostics::AttrShouldBeAppliedToTrait;
1012

1113
pub(crate) struct SkipDuringMethodDispatchParser;
1214

@@ -18,6 +20,14 @@ impl<S: Stage> SingleAttributeParser<S> for SkipDuringMethodDispatchParser {
1820
const TEMPLATE: AttributeTemplate = template!(List: "array, boxed_slice");
1921

2022
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
23+
if !matches!(cx.target, AttrTarget::Trait { .. }) {
24+
cx.dcx().emit_err(AttrShouldBeAppliedToTrait {
25+
attr_span: cx.attr_span,
26+
defn_span: cx.target_span,
27+
});
28+
return None;
29+
}
30+
2131
let mut array = false;
2232
let mut boxed_slice = false;
2333
let Some(args) = args.list() else {
@@ -49,6 +59,6 @@ impl<S: Stage> SingleAttributeParser<S> for SkipDuringMethodDispatchParser {
4959
cx.duplicate_key(arg.span(), key);
5060
}
5161
}
52-
Some(AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span: cx.attr_span })
62+
Some(AttributeKind::SkipDuringMethodDispatch { array, boxed_slice })
5363
}
5464
}

0 commit comments

Comments
 (0)