Skip to content

Commit 8dc1995

Browse files
committed
convert entire codebase to parsed inline attrs
1 parent e0c5b1c commit 8dc1995

File tree

6 files changed

+86
-117
lines changed

6 files changed

+86
-117
lines changed

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
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::{find_attr, AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr};
810
use rustc_data_structures::fx::FxHashMap;
911
use rustc_hir::def::DefKind;
1012
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
@@ -21,7 +23,6 @@ use rustc_session::parse::feature_err;
2123
use rustc_session::{Session, lint};
2224
use rustc_span::{Ident, Span, sym};
2325
use rustc_target::spec::SanitizerSet;
24-
use tracing::debug;
2526

2627
use crate::errors;
2728
use crate::target_features::{check_target_feature_trait_unsafe, from_target_feature_attr};
@@ -449,48 +450,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
449450

450451
mixed_export_name_no_mangle_lint_state.lint_if_mixed(tcx);
451452

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-
});
453+
codegen_fn_attrs.inline =
454+
find_attr!(attrs, AttributeKind::Inline(i, _) => *i).unwrap_or(InlineAttr::None);
494455

495456
// naked function MUST NOT be inlined! This attribute is required for the rust compiler itself,
496457
// 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: 52 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::{find_attr, AttributeKind, InlineAttr, ReprAttr};
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,
@@ -140,7 +143,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
140143
[sym::diagnostic, sym::on_unimplemented, ..] => {
141144
self.check_diagnostic_on_unimplemented(attr.span(), hir_id, target)
142145
}
143-
[sym::inline, ..] => self.check_inline(hir_id, attr, span, target),
144146
[sym::coverage, ..] => self.check_coverage(attr, span, target),
145147
[sym::optimize, ..] => self.check_optimize(hir_id, attr, span, target),
146148
[sym::no_sanitize, ..] => {
@@ -357,11 +359,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
357359
self.check_rustc_force_inline(hir_id, attrs, span, target);
358360
}
359361

360-
fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) {
362+
fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr_span: Span, sym: &str) {
361363
self.tcx.emit_node_span_lint(
362364
UNUSED_ATTRIBUTES,
363365
hir_id,
364-
attr.span(),
366+
attr_span,
365367
errors::IgnoredAttrWithMacro { sym },
366368
);
367369
}
@@ -421,7 +423,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
421423
}
422424

423425
/// Checks if an `#[inline]` is applied to a function or a closure.
424-
fn check_inline(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
426+
fn check_inline(&self, hir_id: HirId, attr_span: Span, defn_span: Span, kind: &InlineAttr, target: Target) {
425427
match target {
426428
Target::Fn
427429
| Target::Closure
@@ -430,7 +432,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
430432
self.tcx.emit_node_span_lint(
431433
UNUSED_ATTRIBUTES,
432434
hir_id,
433-
attr.span(),
435+
attr_span,
434436
errors::IgnoredInlineAttrFnProto,
435437
)
436438
}
@@ -441,33 +443,30 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
441443
Target::AssocConst => self.tcx.emit_node_span_lint(
442444
UNUSED_ATTRIBUTES,
443445
hir_id,
444-
attr.span(),
446+
attr_span,
445447
errors::IgnoredInlineAttrConstants,
446448
),
447449
// FIXME(#80564): Same for fields, arms, and macro defs
448450
Target::Field | Target::Arm | Target::MacroDef => {
449-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "inline")
451+
self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "inline")
450452
}
451453
_ => {
452-
self.dcx().emit_err(errors::InlineNotFnOrClosure {
453-
attr_span: attr.span(),
454-
defn_span: span,
455-
});
454+
self.dcx().emit_err(errors::InlineNotFnOrClosure { attr_span, defn_span });
456455
}
457456
}
458457

459458
// `#[inline]` is ignored if the symbol must be codegened upstream because it's exported.
460459
if let Some(did) = hir_id.as_owner()
461460
&& self.tcx.def_kind(did).has_codegen_attrs()
462-
&& !matches!(attr.meta_item_list().as_deref(), Some([item]) if item.has_name(sym::never))
461+
&& kind != &InlineAttr::Never
463462
{
464463
let attrs = self.tcx.codegen_fn_attrs(did);
465464
// Not checking naked as `#[inline]` is forbidden for naked functions anyways.
466465
if attrs.contains_extern_indicator() {
467466
self.tcx.emit_node_span_lint(
468467
UNUSED_ATTRIBUTES,
469468
hir_id,
470-
attr.span(),
469+
attr_span,
471470
errors::InlineIgnoredForExported {},
472471
);
473472
}
@@ -701,6 +700,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
701700
}
702701
}
703702
}
703+
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
704+
// `#[naked]` attribute with just a lint, because we previously
705+
// erroneously allowed it and some crates used it accidentally, to be compatible
706+
// with crates depending on them, we can't throw an error here.
707+
Target::Field | Target::Arm | Target::MacroDef => {
708+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "naked")
709+
}
704710
_ => {
705711
self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
706712
attr_span: attr.span(),
@@ -777,7 +783,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
777783
// with crates depending on them, we can't throw an error here.
778784
Target::Field | Target::Arm | Target::MacroDef => {
779785
for attr in attrs {
780-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "track_caller");
786+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "track_caller");
781787
}
782788
}
783789
_ => {
@@ -820,7 +826,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
820826
// erroneously allowed it and some crates used it accidentally, to be compatible
821827
// with crates depending on them, we can't throw an error here.
822828
Target::Field | Target::Arm | Target::MacroDef => {
823-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "non_exhaustive");
829+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "non_exhaustive");
824830
}
825831
_ => {
826832
self.dcx().emit_err(errors::NonExhaustiveWrongLocation {
@@ -840,7 +846,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
840846
// erroneously allowed it and some crates used it accidentally, to be compatible
841847
// with crates depending on them, we can't throw an error here.
842848
Target::Field | Target::Arm | Target::MacroDef => {
843-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "marker");
849+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "marker");
844850
}
845851
_ => {
846852
self.dcx().emit_err(errors::AttrShouldBeAppliedToTrait {
@@ -894,7 +900,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
894900
// erroneously allowed it and some crates used it accidentally, to be compatible
895901
// with crates depending on them, we can't throw an error here.
896902
Target::Field | Target::Arm | Target::MacroDef => {
897-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "target_feature");
903+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "target_feature");
898904
}
899905
_ => {
900906
self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
@@ -1609,7 +1615,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16091615
// erroneously allowed it and some crates used it accidentally, to be compatible
16101616
// with crates depending on them, we can't throw an error here.
16111617
Target::Field | Target::Arm | Target::MacroDef => {
1612-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "cold");
1618+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "cold");
16131619
}
16141620
_ => {
16151621
// FIXME: #[cold] was previously allowed on non-functions and some crates used
@@ -1651,7 +1657,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16511657
// erroneously allowed it and some crates used it accidentally, to be compatible
16521658
// with crates depending on them, we can't throw an error here.
16531659
Target::Field | Target::Arm | Target::MacroDef => {
1654-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "link_name");
1660+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "link_name");
16551661
}
16561662
_ => {
16571663
// FIXME: #[cold] was previously allowed on non-functions/statics and some crates
@@ -1685,7 +1691,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16851691
// erroneously allowed it and some crates used it accidentally, to be compatible
16861692
// with crates depending on them, we can't throw an error here.
16871693
Target::Field | Target::Arm | Target::MacroDef => {
1688-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "no_link");
1694+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "no_link");
16891695
}
16901696
_ => {
16911697
self.dcx().emit_err(errors::NoLink { attr_span: attr.span(), span });
@@ -1707,7 +1713,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
17071713
// erroneously allowed it and some crates used it accidentally, to be compatible
17081714
// with crates depending on them, we can't throw an error here.
17091715
Target::Field | Target::Arm | Target::MacroDef => {
1710-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "export_name");
1716+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "export_name");
17111717
}
17121718
_ => {
17131719
self.dcx().emit_err(errors::ExportName { attr_span: attr.span(), span });
@@ -1881,7 +1887,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18811887
// erroneously allowed it and some crates used it accidentally, to be compatible
18821888
// with crates depending on them, we can't throw an error here.
18831889
Target::Field | Target::Arm | Target::MacroDef => {
1884-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "link_section");
1890+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "link_section");
18851891
}
18861892
_ => {
18871893
// FIXME: #[link_section] was previously allowed on non-functions/statics and some
@@ -1906,7 +1912,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
19061912
// erroneously allowed it and some crates used it accidentally, to be compatible
19071913
// with crates depending on them, we can't throw an error here.
19081914
Target::Field | Target::Arm | Target::MacroDef => {
1909-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "no_mangle");
1915+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "no_mangle");
19101916
}
19111917
// FIXME: #[no_mangle] was previously allowed on non-functions/statics, this should be an error
19121918
// The error should specify that the item that is wrong is specifically a *foreign* fn/static
@@ -2253,9 +2259,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
22532259
// `#[allow_internal_unstable]` attribute with just a lint, because we previously
22542260
// erroneously allowed it and some crates used it accidentally, to be compatible
22552261
// with crates depending on them, we can't throw an error here.
2256-
Target::Field | Target::Arm | Target::MacroDef => {
2257-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "allow_internal_unstable")
2258-
}
2262+
Target::Field | Target::Arm | Target::MacroDef => self
2263+
.inline_attr_str_error_with_macro_def(
2264+
hir_id,
2265+
attr.span(),
2266+
"allow_internal_unstable",
2267+
),
22592268
_ => {
22602269
self.tcx
22612270
.dcx()
@@ -2628,8 +2637,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
26282637
span: Span,
26292638
target: Target,
26302639
) {
2631-
let force_inline_attr = attrs.iter().find(|attr| attr.has_name(sym::rustc_force_inline));
2632-
match (target, force_inline_attr) {
2640+
match (
2641+
target,
2642+
find_attr!(attrs, AttributeKind::Inline(InlineAttr::Force { attr_span, .. }, _) => *attr_span),
2643+
) {
26332644
(Target::Closure, None) => {
26342645
let is_coro = matches!(
26352646
self.tcx.hir_expect_expr(hir_id).kind,
@@ -2641,20 +2652,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
26412652
);
26422653
let parent_did = self.tcx.hir_get_parent_item(hir_id).to_def_id();
26432654
let parent_span = self.tcx.def_span(parent_did);
2644-
let parent_force_inline_attr =
2645-
self.tcx.get_attr(parent_did, sym::rustc_force_inline);
2646-
if let Some(attr) = parent_force_inline_attr
2647-
&& is_coro
2655+
2656+
if let Some(attr_span) = find_attr!(
2657+
self.tcx.get_all_attrs(parent_did),
2658+
AttributeKind::Inline(InlineAttr::Force { attr_span, .. }, _) => *attr_span
2659+
) && is_coro
26482660
{
2649-
self.dcx().emit_err(errors::RustcForceInlineCoro {
2650-
attr_span: attr.span(),
2651-
span: parent_span,
2652-
});
2661+
self.dcx()
2662+
.emit_err(errors::RustcForceInlineCoro { attr_span, span: parent_span });
26532663
}
26542664
}
26552665
(Target::Fn, _) => (),
2656-
(_, Some(attr)) => {
2657-
self.dcx().emit_err(errors::RustcForceInline { attr_span: attr.span(), span });
2666+
(_, Some(attr_span)) => {
2667+
self.dcx().emit_err(errors::RustcForceInline { attr_span, span });
26582668
}
26592669
(_, None) => (),
26602670
}
@@ -2875,10 +2885,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
28752885
fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) {
28762886
let attrs = tcx.hir_attrs(item.hir_id());
28772887

2878-
for attr in attrs {
2879-
if attr.has_name(sym::inline) {
2880-
tcx.dcx().emit_err(errors::NonExportedMacroInvalidAttrs { attr_span: attr.span() });
2881-
}
2888+
if let Some(attr_span) = find_attr!(attrs, AttributeKind::Inline(_, span) => *span) {
2889+
tcx.dcx().emit_err(errors::NonExportedMacroInvalidAttrs { attr_span });
28822890
}
28832891
}
28842892

@@ -2898,6 +2906,7 @@ pub(crate) fn provide(providers: &mut Providers) {
28982906
*providers = Providers { check_mod_attrs, ..*providers };
28992907
}
29002908

2909+
// FIXME(jdonszelmann): remove, check during parsing
29012910
fn check_duplicates(
29022911
tcx: TyCtxt<'_>,
29032912
attr: &Attribute,
Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,22 @@
11
use super::INLINE_ALWAYS;
2-
use super::utils::is_word;
32
use clippy_utils::diagnostics::span_lint;
3+
use rustc_attr_parsing::{find_attr, AttributeKind, InlineAttr};
44
use rustc_hir::Attribute;
55
use rustc_lint::LateContext;
66
use rustc_span::symbol::Symbol;
7-
use rustc_span::{Span, sym};
7+
use rustc_span::Span;
88

99
pub(super) fn check(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Attribute]) {
1010
if span.from_expansion() {
1111
return;
1212
}
1313

14-
for attr in attrs {
15-
if let Some(values) = attr.meta_item_list() {
16-
if values.len() != 1 || !attr.has_name(sym::inline) {
17-
continue;
18-
}
19-
if is_word(&values[0], sym::always) {
20-
span_lint(
21-
cx,
22-
INLINE_ALWAYS,
23-
attr.span(),
24-
format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"),
25-
);
26-
}
27-
}
14+
if let Some(span) = find_attr!(attrs, AttributeKind::Inline(InlineAttr::Always, span) => *span) {
15+
span_lint(
16+
cx,
17+
INLINE_ALWAYS,
18+
span,
19+
format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"),
20+
);
2821
}
2922
}

0 commit comments

Comments
 (0)