Skip to content

Commit b9f00de

Browse files
committed
Create AttrTarget for attribute parsing
1 parent 25cf7d1 commit b9f00de

File tree

17 files changed

+351
-43
lines changed

17 files changed

+351
-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
@@ -3,6 +3,7 @@ use rustc_ast::ptr::P;
33
use rustc_ast::visit::AssocCtxt;
44
use rustc_ast::*;
55
use rustc_attr_data_structures::{AttributeKind, find_attr};
6+
use rustc_attr_parsing::{AttrTarget, Position};
67
use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};
78
use rustc_hir::def::{DefKind, PerNS, Res};
89
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
@@ -84,7 +85,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
8485
self.with_lctx(CRATE_NODE_ID, |lctx| {
8586
let module = lctx.lower_mod(&c.items, &c.spans);
8687
// FIXME(jdonszelman): is dummy span ever a problem here?
87-
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP);
88+
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP, AttrTarget::Crate);
8889
hir::OwnerNode::Crate(module)
8990
})
9091
}
@@ -140,7 +141,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
140141
fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
141142
let vis_span = self.lower_span(i.vis.span);
142143
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
143-
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
144+
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, AttrTarget::from_item(&i.kind));
144145
let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind);
145146
let item = hir::Item {
146147
owner_id: hir_id.expect_owner(),
@@ -230,6 +231,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
230231
body.as_deref(),
231232
attrs,
232233
contract.as_deref(),
234+
AttrTarget::from_item(i),
233235
);
234236

235237
let itctx = ImplTraitContext::Universal;
@@ -643,7 +645,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
643645
fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
644646
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
645647
let owner_id = hir_id.expect_owner();
646-
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
648+
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, AttrTarget::from_foreign(i));
647649
let (ident, kind) = match &i.kind {
648650
ForeignItemKind::Fn(box Fn { sig, ident, generics, define_opaque, .. }) => {
649651
let fdec = &sig.decl;
@@ -718,7 +720,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
718720

719721
fn lower_variant(&mut self, item_kind: &ItemKind, v: &Variant) -> hir::Variant<'hir> {
720722
let hir_id = self.lower_node_id(v.id);
721-
self.lower_attrs(hir_id, &v.attrs, v.span);
723+
self.lower_attrs(hir_id, &v.attrs, v.span, AttrTarget::EnumVariant);
722724
hir::Variant {
723725
hir_id,
724726
def_id: self.local_def_id(v.id),
@@ -801,7 +803,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
801803
) -> hir::FieldDef<'hir> {
802804
let ty = self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy));
803805
let hir_id = self.lower_node_id(f.id);
804-
self.lower_attrs(hir_id, &f.attrs, f.span);
806+
self.lower_attrs(hir_id, &f.attrs, f.span, AttrTarget::Field);
805807
hir::FieldDef {
806808
span: self.lower_span(f.span),
807809
hir_id,
@@ -820,7 +822,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
820822

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

826829
let (ident, generics, kind, has_default) = match &i.kind {
@@ -903,6 +906,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
903906
Some(body),
904907
attrs,
905908
contract.as_deref(),
909+
target,
906910
);
907911
let (generics, sig) = self.lower_method_sig(
908912
generics,
@@ -1014,7 +1018,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
10141018
let has_value = true;
10151019
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
10161020
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
1017-
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
1021+
1022+
let target = AttrTarget::from_impl_item(
1023+
if is_in_trait_impl { Position::TraitImpl } else { Position::Impl },
1024+
i,
1025+
);
1026+
1027+
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, target);
10181028

10191029
let (ident, (generics, kind)) = match &i.kind {
10201030
AssocItemKind::Const(box ConstItem {
@@ -1057,6 +1067,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10571067
body.as_deref(),
10581068
attrs,
10591069
contract.as_deref(),
1070+
target,
10601071
);
10611072
let (generics, sig) = self.lower_method_sig(
10621073
generics,
@@ -1208,7 +1219,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12081219

12091220
fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
12101221
let hir_id = self.lower_node_id(param.id);
1211-
self.lower_attrs(hir_id, &param.attrs, param.span);
1222+
self.lower_attrs(hir_id, &param.attrs, param.span, AttrTarget::Param);
12121223
hir::Param {
12131224
hir_id,
12141225
pat: self.lower_pat(&param.pat),
@@ -1336,6 +1347,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13361347
body: Option<&Block>,
13371348
attrs: &'hir [hir::Attribute],
13381349
contract: Option<&FnContract>,
1350+
target: AttrTarget<'_>,
13391351
) -> hir::BodyId {
13401352
let Some(body) = body else {
13411353
// Functions without a body are an error, except if this is an intrinsic. For those we
@@ -1383,7 +1395,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13831395

13841396
// FIXME(async_fn_track_caller): Can this be moved above?
13851397
let hir_id = expr.hir_id;
1386-
this.maybe_forward_track_caller(body.span, fn_id, hir_id);
1398+
this.maybe_forward_track_caller(body.span, fn_id, hir_id, target);
13871399

13881400
(parameters, expr)
13891401
})
@@ -1937,7 +1949,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
19371949
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
19381950
let hir_id = self.lower_node_id(pred.id);
19391951
let span = self.lower_span(pred.span);
1940-
self.lower_attrs(hir_id, &pred.attrs, span);
1952+
self.lower_attrs(hir_id, &pred.attrs, span, AttrTarget::WherePredicate);
19411953
let kind = self.arena.alloc(match &pred.kind {
19421954
WherePredicateKind::BoundPredicate(WhereBoundPredicate {
19431955
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| {
@@ -1900,7 +1904,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
19001904
let (name, kind) = self.lower_generic_param_kind(param, source);
19011905

19021906
let hir_id = self.lower_node_id(param.id);
1903-
self.lower_attrs(hir_id, &param.attrs, param.span());
1907+
self.lower_attrs(hir_id, &param.attrs, param.span(), AttrTarget::from_generic(param));
19041908
hir::GenericParam {
19051909
hir_id,
19061910
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
@@ -317,7 +317,7 @@ pub enum AttributeKind {
317317
RustcObjectLifetimeDefault,
318318

319319
/// Represents `#[rustc_skip_during_method_dispatch]`.
320-
SkipDuringMethodDispatch { array: bool, boxed_slice: bool, span: Span },
320+
SkipDuringMethodDispatch { array: bool, boxed_slice: bool },
321321

322322
/// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`.
323323
Stability {

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ attr_parsing_rustc_allowed_unstable_pairing =
114114
attr_parsing_rustc_promotable_pairing =
115115
`rustc_promotable` attribute must be paired with either a `rustc_const_unstable` or a `rustc_const_stable` attribute
116116
117+
attr_parsing_should_be_applied_to_trait =
118+
attribute should be applied to a trait
119+
.label = not a trait
120+
117121
attr_parsing_soft_no_args =
118122
`soft` should not have any arguments
119123

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)