Skip to content

Commit 5054789

Browse files
committed
convert entire codebase to parsed inline attrs
1 parent c5fada9 commit 5054789

File tree

7 files changed

+105
-119
lines changed

7 files changed

+105
-119
lines changed

compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,18 @@ pub enum AttributeKind {
183183
ConstStabilityIndirect,
184184

185185
/// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute).
186-
Deprecation { deprecation: Deprecation, span: Span },
186+
Deprecation {
187+
deprecation: Deprecation,
188+
span: Span,
189+
},
187190

188191
/// Represents [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html).
189-
DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol },
192+
DocComment {
193+
style: AttrStyle,
194+
kind: CommentKind,
195+
span: Span,
196+
comment: Symbol,
197+
},
190198

191199
/// Represents `#[rustc_macro_transparency]`.
192200
Inline(InlineAttr, Span),

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 8 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
use std::str::FromStr;
22

33
use rustc_abi::ExternAbi;
4-
use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode};
4+
use rustc_ast::expand::autodiff_attrs::{
5+
AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity,
6+
};
57
use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr};
68
use rustc_attr_data_structures::ReprAttr::ReprAlign;
7-
use rustc_attr_data_structures::{AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr};
9+
use rustc_attr_data_structures::{
10+
AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr, find_attr,
11+
};
812
use rustc_data_structures::fx::FxHashMap;
913
use rustc_hir::def::DefKind;
1014
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
@@ -21,7 +25,6 @@ use rustc_session::parse::feature_err;
2125
use rustc_session::{Session, lint};
2226
use rustc_span::{Ident, Span, sym};
2327
use rustc_target::spec::SanitizerSet;
24-
use tracing::debug;
2528

2629
use crate::errors;
2730
use crate::target_features::{check_target_feature_trait_unsafe, from_target_feature_attr};
@@ -449,48 +452,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
449452

450453
mixed_export_name_no_mangle_lint_state.lint_if_mixed(tcx);
451454

452-
codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
453-
if !attr.has_name(sym::inline) {
454-
return ia;
455-
}
456-
457-
if attr.is_word() {
458-
return InlineAttr::Hint;
459-
}
460-
let Some(ref items) = attr.meta_item_list() else {
461-
return ia;
462-
};
463-
inline_span = Some(attr.span());
464-
465-
let [item] = &items[..] else {
466-
tcx.dcx().emit_err(errors::ExpectedOneArgument { span: attr.span() });
467-
return InlineAttr::None;
468-
};
469-
470-
if item.has_name(sym::always) {
471-
InlineAttr::Always
472-
} else if item.has_name(sym::never) {
473-
InlineAttr::Never
474-
} else {
475-
tcx.dcx().emit_err(errors::InvalidArgument { span: items[0].span() });
476-
477-
InlineAttr::None
478-
}
479-
});
480-
codegen_fn_attrs.inline = attrs.iter().fold(codegen_fn_attrs.inline, |ia, attr| {
481-
if !attr.has_name(sym::rustc_force_inline) || !tcx.features().rustc_attrs() {
482-
return ia;
483-
}
484-
485-
if attr.is_word() {
486-
InlineAttr::Force { attr_span: attr.span(), reason: None }
487-
} else if let Some(val) = attr.value_str() {
488-
InlineAttr::Force { attr_span: attr.span(), reason: Some(val) }
489-
} else {
490-
debug!("`rustc_force_inline` not checked by attribute validation");
491-
ia
492-
}
493-
});
455+
codegen_fn_attrs.inline =
456+
find_attr!(attrs, AttributeKind::Inline(i, _) => *i).unwrap_or(InlineAttr::None);
494457

495458
// naked function MUST NOT be inlined! This attribute is required for the rust compiler itself,
496459
// but not for the code generation backend because at that point the naked function will just be

compiler/rustc_passes/src/check_attr.rs

Lines changed: 59 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::collections::hash_map::Entry;
1010

1111
use rustc_abi::{Align, ExternAbi, Size};
1212
use rustc_ast::{AttrStyle, LitKind, MetaItemInner, MetaItemKind, MetaItemLit, ast};
13-
use rustc_attr_data_structures::{AttributeKind, ReprAttr, find_attr};
13+
use rustc_attr_data_structures::{AttributeKind, InlineAttr, ReprAttr, find_attr};
1414
use rustc_data_structures::fx::FxHashMap;
1515
use rustc_errors::{Applicability, DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey};
1616
use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
@@ -124,6 +124,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
124124
AttributeKind::Stability { span, .. }
125125
| AttributeKind::ConstStability { span, .. },
126126
) => self.check_stability_promotable(*span, target),
127+
Attribute::Parsed(AttributeKind::Inline(kind, attr_span)) => {
128+
self.check_inline(hir_id, *attr_span, span, kind, target)
129+
}
127130
Attribute::Parsed(AttributeKind::AllowInternalUnstable(syms)) => self
128131
.check_allow_internal_unstable(
129132
hir_id,
@@ -155,7 +158,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
155158
[sym::diagnostic, sym::on_unimplemented, ..] => {
156159
self.check_diagnostic_on_unimplemented(attr.span(), hir_id, target)
157160
}
158-
[sym::inline, ..] => self.check_inline(hir_id, attr, span, target),
159161
[sym::coverage, ..] => self.check_coverage(attr, span, target),
160162
[sym::optimize, ..] => self.check_optimize(hir_id, attr, span, target),
161163
[sym::no_sanitize, ..] => {
@@ -367,11 +369,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
367369
self.check_rustc_force_inline(hir_id, attrs, span, target);
368370
}
369371

370-
fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) {
372+
fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr_span: Span, sym: &str) {
371373
self.tcx.emit_node_span_lint(
372374
UNUSED_ATTRIBUTES,
373375
hir_id,
374-
attr.span(),
376+
attr_span,
375377
errors::IgnoredAttrWithMacro { sym },
376378
);
377379
}
@@ -431,7 +433,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
431433
}
432434

433435
/// Checks if an `#[inline]` is applied to a function or a closure.
434-
fn check_inline(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
436+
fn check_inline(
437+
&self,
438+
hir_id: HirId,
439+
attr_span: Span,
440+
defn_span: Span,
441+
kind: &InlineAttr,
442+
target: Target,
443+
) {
435444
match target {
436445
Target::Fn
437446
| Target::Closure
@@ -440,7 +449,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
440449
self.tcx.emit_node_span_lint(
441450
UNUSED_ATTRIBUTES,
442451
hir_id,
443-
attr.span(),
452+
attr_span,
444453
errors::IgnoredInlineAttrFnProto,
445454
)
446455
}
@@ -451,33 +460,30 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
451460
Target::AssocConst => self.tcx.emit_node_span_lint(
452461
UNUSED_ATTRIBUTES,
453462
hir_id,
454-
attr.span(),
463+
attr_span,
455464
errors::IgnoredInlineAttrConstants,
456465
),
457466
// FIXME(#80564): Same for fields, arms, and macro defs
458467
Target::Field | Target::Arm | Target::MacroDef => {
459-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "inline")
468+
self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "inline")
460469
}
461470
_ => {
462-
self.dcx().emit_err(errors::InlineNotFnOrClosure {
463-
attr_span: attr.span(),
464-
defn_span: span,
465-
});
471+
self.dcx().emit_err(errors::InlineNotFnOrClosure { attr_span, defn_span });
466472
}
467473
}
468474

469475
// `#[inline]` is ignored if the symbol must be codegened upstream because it's exported.
470476
if let Some(did) = hir_id.as_owner()
471477
&& self.tcx.def_kind(did).has_codegen_attrs()
472-
&& !matches!(attr.meta_item_list().as_deref(), Some([item]) if item.has_name(sym::never))
478+
&& kind != &InlineAttr::Never
473479
{
474480
let attrs = self.tcx.codegen_fn_attrs(did);
475481
// Not checking naked as `#[inline]` is forbidden for naked functions anyways.
476482
if attrs.contains_extern_indicator() {
477483
self.tcx.emit_node_span_lint(
478484
UNUSED_ATTRIBUTES,
479485
hir_id,
480-
attr.span(),
486+
attr_span,
481487
errors::InlineIgnoredForExported {},
482488
);
483489
}
@@ -711,6 +717,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
711717
}
712718
}
713719
}
720+
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
721+
// `#[naked]` attribute with just a lint, because we previously
722+
// erroneously allowed it and some crates used it accidentally, to be compatible
723+
// with crates depending on them, we can't throw an error here.
724+
Target::Field | Target::Arm | Target::MacroDef => {
725+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "naked")
726+
}
714727
_ => {
715728
self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
716729
attr_span: attr.span(),
@@ -787,7 +800,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
787800
// with crates depending on them, we can't throw an error here.
788801
Target::Field | Target::Arm | Target::MacroDef => {
789802
for attr in attrs {
790-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "track_caller");
803+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "track_caller");
791804
}
792805
}
793806
_ => {
@@ -830,7 +843,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
830843
// erroneously allowed it and some crates used it accidentally, to be compatible
831844
// with crates depending on them, we can't throw an error here.
832845
Target::Field | Target::Arm | Target::MacroDef => {
833-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "non_exhaustive");
846+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "non_exhaustive");
834847
}
835848
_ => {
836849
self.dcx().emit_err(errors::NonExhaustiveWrongLocation {
@@ -850,7 +863,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
850863
// erroneously allowed it and some crates used it accidentally, to be compatible
851864
// with crates depending on them, we can't throw an error here.
852865
Target::Field | Target::Arm | Target::MacroDef => {
853-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "marker");
866+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "marker");
854867
}
855868
_ => {
856869
self.dcx().emit_err(errors::AttrShouldBeAppliedToTrait {
@@ -904,7 +917,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
904917
// erroneously allowed it and some crates used it accidentally, to be compatible
905918
// with crates depending on them, we can't throw an error here.
906919
Target::Field | Target::Arm | Target::MacroDef => {
907-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "target_feature");
920+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "target_feature");
908921
}
909922
_ => {
910923
self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
@@ -1619,7 +1632,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16191632
// erroneously allowed it and some crates used it accidentally, to be compatible
16201633
// with crates depending on them, we can't throw an error here.
16211634
Target::Field | Target::Arm | Target::MacroDef => {
1622-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "cold");
1635+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "cold");
16231636
}
16241637
_ => {
16251638
// FIXME: #[cold] was previously allowed on non-functions and some crates used
@@ -1661,7 +1674,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16611674
// erroneously allowed it and some crates used it accidentally, to be compatible
16621675
// with crates depending on them, we can't throw an error here.
16631676
Target::Field | Target::Arm | Target::MacroDef => {
1664-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "link_name");
1677+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "link_name");
16651678
}
16661679
_ => {
16671680
// FIXME: #[cold] was previously allowed on non-functions/statics and some crates
@@ -1695,7 +1708,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16951708
// erroneously allowed it and some crates used it accidentally, to be compatible
16961709
// with crates depending on them, we can't throw an error here.
16971710
Target::Field | Target::Arm | Target::MacroDef => {
1698-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "no_link");
1711+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "no_link");
16991712
}
17001713
_ => {
17011714
self.dcx().emit_err(errors::NoLink { attr_span: attr.span(), span });
@@ -1717,7 +1730,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
17171730
// erroneously allowed it and some crates used it accidentally, to be compatible
17181731
// with crates depending on them, we can't throw an error here.
17191732
Target::Field | Target::Arm | Target::MacroDef => {
1720-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "export_name");
1733+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "export_name");
17211734
}
17221735
_ => {
17231736
self.dcx().emit_err(errors::ExportName { attr_span: attr.span(), span });
@@ -1891,7 +1904,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18911904
// erroneously allowed it and some crates used it accidentally, to be compatible
18921905
// with crates depending on them, we can't throw an error here.
18931906
Target::Field | Target::Arm | Target::MacroDef => {
1894-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "link_section");
1907+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "link_section");
18951908
}
18961909
_ => {
18971910
// FIXME: #[link_section] was previously allowed on non-functions/statics and some
@@ -1916,7 +1929,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
19161929
// erroneously allowed it and some crates used it accidentally, to be compatible
19171930
// with crates depending on them, we can't throw an error here.
19181931
Target::Field | Target::Arm | Target::MacroDef => {
1919-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "no_mangle");
1932+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "no_mangle");
19201933
}
19211934
// FIXME: #[no_mangle] was previously allowed on non-functions/statics, this should be an error
19221935
// The error should specify that the item that is wrong is specifically a *foreign* fn/static
@@ -2263,9 +2276,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
22632276
// `#[allow_internal_unstable]` attribute with just a lint, because we previously
22642277
// erroneously allowed it and some crates used it accidentally, to be compatible
22652278
// with crates depending on them, we can't throw an error here.
2266-
Target::Field | Target::Arm | Target::MacroDef => {
2267-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "allow_internal_unstable")
2268-
}
2279+
Target::Field | Target::Arm | Target::MacroDef => self
2280+
.inline_attr_str_error_with_macro_def(
2281+
hir_id,
2282+
attr.span(),
2283+
"allow_internal_unstable",
2284+
),
22692285
_ => {
22702286
self.tcx
22712287
.dcx()
@@ -2638,8 +2654,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
26382654
span: Span,
26392655
target: Target,
26402656
) {
2641-
let force_inline_attr = attrs.iter().find(|attr| attr.has_name(sym::rustc_force_inline));
2642-
match (target, force_inline_attr) {
2657+
match (
2658+
target,
2659+
find_attr!(attrs, AttributeKind::Inline(InlineAttr::Force { attr_span, .. }, _) => *attr_span),
2660+
) {
26432661
(Target::Closure, None) => {
26442662
let is_coro = matches!(
26452663
self.tcx.hir_expect_expr(hir_id).kind,
@@ -2651,20 +2669,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
26512669
);
26522670
let parent_did = self.tcx.hir_get_parent_item(hir_id).to_def_id();
26532671
let parent_span = self.tcx.def_span(parent_did);
2654-
let parent_force_inline_attr =
2655-
self.tcx.get_attr(parent_did, sym::rustc_force_inline);
2656-
if let Some(attr) = parent_force_inline_attr
2657-
&& is_coro
2672+
2673+
if let Some(attr_span) = find_attr!(
2674+
self.tcx.get_all_attrs(parent_did),
2675+
AttributeKind::Inline(InlineAttr::Force { attr_span, .. }, _) => *attr_span
2676+
) && is_coro
26582677
{
2659-
self.dcx().emit_err(errors::RustcForceInlineCoro {
2660-
attr_span: attr.span(),
2661-
span: parent_span,
2662-
});
2678+
self.dcx()
2679+
.emit_err(errors::RustcForceInlineCoro { attr_span, span: parent_span });
26632680
}
26642681
}
26652682
(Target::Fn, _) => (),
2666-
(_, Some(attr)) => {
2667-
self.dcx().emit_err(errors::RustcForceInline { attr_span: attr.span(), span });
2683+
(_, Some(attr_span)) => {
2684+
self.dcx().emit_err(errors::RustcForceInline { attr_span, span });
26682685
}
26692686
(_, None) => (),
26702687
}
@@ -2885,10 +2902,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
28852902
fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) {
28862903
let attrs = tcx.hir_attrs(item.hir_id());
28872904

2888-
for attr in attrs {
2889-
if attr.has_name(sym::inline) {
2890-
tcx.dcx().emit_err(errors::NonExportedMacroInvalidAttrs { attr_span: attr.span() });
2891-
}
2905+
if let Some(attr_span) = find_attr!(attrs, AttributeKind::Inline(_, span) => *span) {
2906+
tcx.dcx().emit_err(errors::NonExportedMacroInvalidAttrs { attr_span });
28922907
}
28932908
}
28942909

@@ -2908,6 +2923,7 @@ pub(crate) fn provide(providers: &mut Providers) {
29082923
*providers = Providers { check_mod_attrs, ..*providers };
29092924
}
29102925

2926+
// FIXME(jdonszelmann): remove, check during parsing
29112927
fn check_duplicates(
29122928
tcx: TyCtxt<'_>,
29132929
attr: &Attribute,

0 commit comments

Comments
 (0)