Skip to content

Commit 5d8fa68

Browse files
committed
convert entire codebase to parsed inline attrs
1 parent 1326652 commit 5d8fa68

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};
@@ -474,48 +475,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
474475

475476
mixed_export_name_no_mangle_lint_state.lint_if_mixed(tcx);
476477

477-
codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
478-
if !attr.has_name(sym::inline) {
479-
return ia;
480-
}
481-
482-
if attr.is_word() {
483-
return InlineAttr::Hint;
484-
}
485-
let Some(ref items) = attr.meta_item_list() else {
486-
return ia;
487-
};
488-
inline_span = Some(attr.span());
489-
490-
let [item] = &items[..] else {
491-
tcx.dcx().emit_err(errors::ExpectedOneArgument { span: attr.span() });
492-
return InlineAttr::None;
493-
};
494-
495-
if item.has_name(sym::always) {
496-
InlineAttr::Always
497-
} else if item.has_name(sym::never) {
498-
InlineAttr::Never
499-
} else {
500-
tcx.dcx().emit_err(errors::InvalidArgument { span: items[0].span() });
501-
502-
InlineAttr::None
503-
}
504-
});
505-
codegen_fn_attrs.inline = attrs.iter().fold(codegen_fn_attrs.inline, |ia, attr| {
506-
if !attr.has_name(sym::rustc_force_inline) || !tcx.features().rustc_attrs() {
507-
return ia;
508-
}
509-
510-
if attr.is_word() {
511-
InlineAttr::Force { attr_span: attr.span(), reason: None }
512-
} else if let Some(val) = attr.value_str() {
513-
InlineAttr::Force { attr_span: attr.span(), reason: Some(val) }
514-
} else {
515-
debug!("`rustc_force_inline` not checked by attribute validation");
516-
ia
517-
}
518-
});
478+
codegen_fn_attrs.inline =
479+
find_attr!(attrs, AttributeKind::Inline(i, _) => *i).unwrap_or(InlineAttr::None);
519480

520481
// naked function MUST NOT be inlined! This attribute is required for the rust compiler itself,
521482
// 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 {
@@ -1607,7 +1613,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16071613
// erroneously allowed it and some crates used it accidentally, to be compatible
16081614
// with crates depending on them, we can't throw an error here.
16091615
Target::Field | Target::Arm | Target::MacroDef => {
1610-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "cold");
1616+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "cold");
16111617
}
16121618
_ => {
16131619
// FIXME: #[cold] was previously allowed on non-functions and some crates used
@@ -1649,7 +1655,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16491655
// erroneously allowed it and some crates used it accidentally, to be compatible
16501656
// with crates depending on them, we can't throw an error here.
16511657
Target::Field | Target::Arm | Target::MacroDef => {
1652-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "link_name");
1658+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "link_name");
16531659
}
16541660
_ => {
16551661
// FIXME: #[cold] was previously allowed on non-functions/statics and some crates
@@ -1683,7 +1689,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
16831689
// erroneously allowed it and some crates used it accidentally, to be compatible
16841690
// with crates depending on them, we can't throw an error here.
16851691
Target::Field | Target::Arm | Target::MacroDef => {
1686-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "no_link");
1692+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "no_link");
16871693
}
16881694
_ => {
16891695
self.dcx().emit_err(errors::NoLink { attr_span: attr.span(), span });
@@ -1705,7 +1711,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
17051711
// erroneously allowed it and some crates used it accidentally, to be compatible
17061712
// with crates depending on them, we can't throw an error here.
17071713
Target::Field | Target::Arm | Target::MacroDef => {
1708-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "export_name");
1714+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "export_name");
17091715
}
17101716
_ => {
17111717
self.dcx().emit_err(errors::ExportName { attr_span: attr.span(), span });
@@ -1879,7 +1885,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18791885
// erroneously allowed it and some crates used it accidentally, to be compatible
18801886
// with crates depending on them, we can't throw an error here.
18811887
Target::Field | Target::Arm | Target::MacroDef => {
1882-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "link_section");
1888+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "link_section");
18831889
}
18841890
_ => {
18851891
// FIXME: #[link_section] was previously allowed on non-functions/statics and some
@@ -1904,7 +1910,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
19041910
// erroneously allowed it and some crates used it accidentally, to be compatible
19051911
// with crates depending on them, we can't throw an error here.
19061912
Target::Field | Target::Arm | Target::MacroDef => {
1907-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "no_mangle");
1913+
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "no_mangle");
19081914
}
19091915
// FIXME: #[no_mangle] was previously allowed on non-functions/statics, this should be an error
19101916
// The error should specify that the item that is wrong is specifically a *foreign* fn/static
@@ -2251,9 +2257,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
22512257
// `#[allow_internal_unstable]` attribute with just a lint, because we previously
22522258
// erroneously allowed it and some crates used it accidentally, to be compatible
22532259
// with crates depending on them, we can't throw an error here.
2254-
Target::Field | Target::Arm | Target::MacroDef => {
2255-
self.inline_attr_str_error_with_macro_def(hir_id, attr, "allow_internal_unstable")
2256-
}
2260+
Target::Field | Target::Arm | Target::MacroDef => self
2261+
.inline_attr_str_error_with_macro_def(
2262+
hir_id,
2263+
attr.span(),
2264+
"allow_internal_unstable",
2265+
),
22572266
_ => {
22582267
self.tcx
22592268
.dcx()
@@ -2624,8 +2633,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
26242633
span: Span,
26252634
target: Target,
26262635
) {
2627-
let force_inline_attr = attrs.iter().find(|attr| attr.has_name(sym::rustc_force_inline));
2628-
match (target, force_inline_attr) {
2636+
match (
2637+
target,
2638+
find_attr!(attrs, AttributeKind::Inline(InlineAttr::Force { attr_span, .. }, _) => *attr_span),
2639+
) {
26292640
(Target::Closure, None) => {
26302641
let is_coro = matches!(
26312642
self.tcx.hir_expect_expr(hir_id).kind,
@@ -2637,20 +2648,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
26372648
);
26382649
let parent_did = self.tcx.hir_get_parent_item(hir_id).to_def_id();
26392650
let parent_span = self.tcx.def_span(parent_did);
2640-
let parent_force_inline_attr =
2641-
self.tcx.get_attr(parent_did, sym::rustc_force_inline);
2642-
if let Some(attr) = parent_force_inline_attr
2643-
&& is_coro
2651+
2652+
if let Some(attr_span) = find_attr!(
2653+
self.tcx.get_all_attrs(parent_did),
2654+
AttributeKind::Inline(InlineAttr::Force { attr_span, .. }, _) => *attr_span
2655+
) && is_coro
26442656
{
2645-
self.dcx().emit_err(errors::RustcForceInlineCoro {
2646-
attr_span: attr.span(),
2647-
span: parent_span,
2648-
});
2657+
self.dcx()
2658+
.emit_err(errors::RustcForceInlineCoro { attr_span, span: parent_span });
26492659
}
26502660
}
26512661
(Target::Fn, _) => (),
2652-
(_, Some(attr)) => {
2653-
self.dcx().emit_err(errors::RustcForceInline { attr_span: attr.span(), span });
2662+
(_, Some(attr_span)) => {
2663+
self.dcx().emit_err(errors::RustcForceInline { attr_span, span });
26542664
}
26552665
(_, None) => (),
26562666
}
@@ -2871,10 +2881,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
28712881
fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) {
28722882
let attrs = tcx.hir_attrs(item.hir_id());
28732883

2874-
for attr in attrs {
2875-
if attr.has_name(sym::inline) {
2876-
tcx.dcx().emit_err(errors::NonExportedMacroInvalidAttrs { attr_span: attr.span() });
2877-
}
2884+
if let Some(attr_span) = find_attr!(attrs, AttributeKind::Inline(_, span) => *span) {
2885+
tcx.dcx().emit_err(errors::NonExportedMacroInvalidAttrs { attr_span });
28782886
}
28792887
}
28802888

@@ -2894,6 +2902,7 @@ pub(crate) fn provide(providers: &mut Providers) {
28942902
*providers = Providers { check_mod_attrs, ..*providers };
28952903
}
28962904

2905+
// FIXME(jdonszelmann): remove, check during parsing
28972906
fn check_duplicates(
28982907
tcx: TyCtxt<'_>,
28992908
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)