Skip to content

Commit 42245d3

Browse files
committed
Auto merge of #142906 - jdonszelmann:rollup-togt1dl, r=jdonszelmann
Rollup of 5 pull requests Successful merges: - #142493 (rework `#[naked]` attribute parser) - #142636 (bootstrap.example.toml: use less contextual format) - #142822 (Make `PartialEq` a `const_trait`) - #142892 (Fix ICE on debug builds where lints are delayed on the crate root) - #142904 (notify me when rdg is touched) Failed merges: - #142827 (Move error code explanation removal check into tidy) r? `@ghost` `@rustbot` modify labels: rollup
2 parents ae2fc97 + 3e8e065 commit 42245d3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+633
-1010
lines changed

bootstrap.example.toml

Lines changed: 198 additions & 195 deletions
Large diffs are not rendered by default.

compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ pub enum AttributeKind {
244244
reason: Option<Symbol>,
245245
},
246246

247+
/// Represents `#[naked]`
248+
Naked(Span),
249+
247250
/// Represents `#[no_mangle]`
248251
NoMangle(Span),
249252

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ attr_parsing_missing_since =
8989
attr_parsing_multiple_stability_levels =
9090
multiple stability levels
9191
92+
attr_parsing_naked_functions_incompatible_attribute =
93+
attribute incompatible with `#[unsafe(naked)]`
94+
.label = the `{$attr}` attribute is incompatible with `#[unsafe(naked)]`
95+
.naked_attribute = function marked with `#[unsafe(naked)]` here
9296
attr_parsing_non_ident_feature =
9397
'feature' is not an identifier
9498

compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs

Lines changed: 113 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use rustc_attr_data_structures::{AttributeKind, OptimizeAttr};
22
use rustc_feature::{AttributeTemplate, template};
3-
use rustc_span::sym;
3+
use rustc_session::parse::feature_err;
4+
use rustc_span::{Span, sym};
45

5-
use super::{AttributeOrder, OnDuplicate, SingleAttributeParser};
6-
use crate::context::{AcceptContext, Stage};
6+
use super::{AcceptMapping, AttributeOrder, AttributeParser, OnDuplicate, SingleAttributeParser};
7+
use crate::context::{AcceptContext, FinalizeContext, Stage};
78
use crate::parser::ArgParser;
9+
use crate::session_diagnostics::NakedFunctionIncompatibleAttribute;
810

911
pub(crate) struct OptimizeParser;
1012

@@ -51,12 +53,119 @@ impl<S: Stage> SingleAttributeParser<S> for ColdParser {
5153
if !args.no_args() {
5254
cx.expected_no_args(args.span().unwrap_or(cx.attr_span));
5355
return None;
54-
};
56+
}
5557

5658
Some(AttributeKind::Cold(cx.attr_span))
5759
}
5860
}
5961

62+
#[derive(Default)]
63+
pub(crate) struct NakedParser {
64+
span: Option<Span>,
65+
}
66+
67+
impl<S: Stage> AttributeParser<S> for NakedParser {
68+
const ATTRIBUTES: AcceptMapping<Self, S> =
69+
&[(&[sym::naked], template!(Word), |this, cx, args| {
70+
if !args.no_args() {
71+
cx.expected_no_args(args.span().unwrap_or(cx.attr_span));
72+
return;
73+
}
74+
75+
if let Some(earlier) = this.span {
76+
let span = cx.attr_span;
77+
cx.warn_unused_duplicate(earlier, span);
78+
} else {
79+
this.span = Some(cx.attr_span);
80+
}
81+
})];
82+
83+
fn finalize(self, cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
84+
// FIXME(jdonszelmann): upgrade this list to *parsed* attributes
85+
// once all of these have parsed forms. That'd make the check much nicer...
86+
//
87+
// many attributes don't make sense in combination with #[naked].
88+
// Notable attributes that are incompatible with `#[naked]` are:
89+
//
90+
// * `#[inline]`
91+
// * `#[track_caller]`
92+
// * `#[test]`, `#[ignore]`, `#[should_panic]`
93+
//
94+
// NOTE: when making changes to this list, check that `error_codes/E0736.md` remains
95+
// accurate.
96+
const ALLOW_LIST: &[rustc_span::Symbol] = &[
97+
// conditional compilation
98+
sym::cfg_trace,
99+
sym::cfg_attr_trace,
100+
// testing (allowed here so better errors can be generated in `rustc_builtin_macros::test`)
101+
sym::test,
102+
sym::ignore,
103+
sym::should_panic,
104+
sym::bench,
105+
// diagnostics
106+
sym::allow,
107+
sym::warn,
108+
sym::deny,
109+
sym::forbid,
110+
sym::deprecated,
111+
sym::must_use,
112+
// abi, linking and FFI
113+
sym::cold,
114+
sym::export_name,
115+
sym::link_section,
116+
sym::linkage,
117+
sym::no_mangle,
118+
sym::instruction_set,
119+
sym::repr,
120+
sym::rustc_std_internal_symbol,
121+
sym::align,
122+
// obviously compatible with self
123+
sym::naked,
124+
// documentation
125+
sym::doc,
126+
];
127+
128+
let span = self.span?;
129+
130+
// only if we found a naked attribute do we do the somewhat expensive check
131+
'outer: for other_attr in cx.all_attrs {
132+
for allowed_attr in ALLOW_LIST {
133+
if other_attr.segments().next().is_some_and(|i| cx.tools.contains(&i.name)) {
134+
// effectively skips the error message being emitted below
135+
// if it's a tool attribute
136+
continue 'outer;
137+
}
138+
if other_attr.word_is(*allowed_attr) {
139+
// effectively skips the error message being emitted below
140+
// if its an allowed attribute
141+
continue 'outer;
142+
}
143+
144+
if other_attr.word_is(sym::target_feature) {
145+
if !cx.features().naked_functions_target_feature() {
146+
feature_err(
147+
&cx.sess(),
148+
sym::naked_functions_target_feature,
149+
other_attr.span(),
150+
"`#[target_feature(/* ... */)]` is currently unstable on `#[naked]` functions",
151+
).emit();
152+
}
153+
154+
continue 'outer;
155+
}
156+
}
157+
158+
cx.emit_err(NakedFunctionIncompatibleAttribute {
159+
span: other_attr.span(),
160+
naked_span: span,
161+
attr: other_attr.get_attribute_path().to_string(),
162+
});
163+
}
164+
165+
Some(AttributeKind::Naked(span))
166+
}
167+
}
168+
60169
pub(crate) struct NoMangleParser;
61170

62171
impl<S: Stage> SingleAttributeParser<S> for NoMangleParser {

compiler/rustc_attr_parsing/src/attributes/inline.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,8 @@ impl<S: Stage> SingleAttributeParser<S> for InlineParser {
4545
ArgParser::NameValue(_) => {
4646
let suggestions =
4747
<Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "inline");
48-
cx.emit_lint(
49-
AttributeLintKind::IllFormedAttributeInput { suggestions },
50-
cx.attr_span,
51-
);
48+
let span = cx.attr_span;
49+
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
5250
return None;
5351
}
5452
}

compiler/rustc_attr_parsing/src/attributes/mod.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use std::marker::PhantomData;
1818

1919
use rustc_attr_data_structures::AttributeKind;
20-
use rustc_attr_data_structures::lints::AttributeLintKind;
2120
use rustc_feature::AttributeTemplate;
2221
use rustc_span::{Span, Symbol};
2322
use thin_vec::ThinVec;
@@ -189,14 +188,8 @@ impl<S: Stage> OnDuplicate<S> {
189188
unused: Span,
190189
) {
191190
match self {
192-
OnDuplicate::Warn => cx.emit_lint(
193-
AttributeLintKind::UnusedDuplicate { this: unused, other: used, warning: false },
194-
unused,
195-
),
196-
OnDuplicate::WarnButFutureError => cx.emit_lint(
197-
AttributeLintKind::UnusedDuplicate { this: unused, other: used, warning: true },
198-
unused,
199-
),
191+
OnDuplicate::Warn => cx.warn_unused_duplicate(used, unused),
192+
OnDuplicate::WarnButFutureError => cx.warn_unused_duplicate_future_error(used, unused),
200193
OnDuplicate::Error => {
201194
cx.emit_err(UnusedMultiple {
202195
this: used,

0 commit comments

Comments
 (0)