Skip to content

Commit 3495d94

Browse files
committed
don't suggest turning crate-level attributes into outer style
1 parent 70591dc commit 3495d94

13 files changed

+71
-53
lines changed

compiler/rustc_ast/src/ast.rs

+11
Original file line numberDiff line numberDiff line change
@@ -2898,6 +2898,17 @@ pub struct AttrItem {
28982898
pub tokens: Option<LazyAttrTokenStream>,
28992899
}
29002900

2901+
impl AttrItem {
2902+
pub fn is_valid_for_inner_outer_sytle(&self) -> bool {
2903+
self.path == sym::cfg_attr
2904+
|| self.path == sym::cfg
2905+
|| self.path == sym::forbid
2906+
|| self.path == sym::warn
2907+
|| self.path == sym::allow
2908+
|| self.path == sym::deny
2909+
}
2910+
}
2911+
29012912
/// `TraitRef`s appear in impls.
29022913
///
29032914
/// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all

compiler/rustc_parse/src/parser/attr.rs

+27-12
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub enum InnerAttrForbiddenReason {
2525
AfterOuterAttribute { prev_outer_attr_sp: Span },
2626
}
2727

28+
#[derive(PartialEq)]
2829
enum OuterAttributeType {
2930
DocComment,
3031
DocBlockComment,
@@ -67,6 +68,7 @@ impl<'a> Parser<'a> {
6768
token::CommentKind::Line => OuterAttributeType::DocComment,
6869
token::CommentKind::Block => OuterAttributeType::DocBlockComment,
6970
},
71+
true,
7072
) {
7173
err.note(fluent::parse_note);
7274
err.span_suggestion_verbose(
@@ -130,7 +132,11 @@ impl<'a> Parser<'a> {
130132

131133
// Emit error if inner attribute is encountered and forbidden.
132134
if style == ast::AttrStyle::Inner {
133-
this.error_on_forbidden_inner_attr(attr_sp, inner_parse_policy);
135+
this.error_on_forbidden_inner_attr(
136+
attr_sp,
137+
inner_parse_policy,
138+
item.is_valid_for_inner_outer_sytle(),
139+
);
134140
}
135141

136142
Ok(attr::mk_attr_from_item(&self.psess.attr_id_generator, item, None, style, attr_sp))
@@ -142,6 +148,7 @@ impl<'a> Parser<'a> {
142148
err: &mut Diag<'_>,
143149
span: Span,
144150
attr_type: OuterAttributeType,
151+
suggest_to_outer: bool,
145152
) -> Option<Span> {
146153
let mut snapshot = self.create_snapshot_for_diagnostic();
147154
let lo = span.lo()
@@ -176,16 +183,18 @@ impl<'a> Parser<'a> {
176183
// FIXME(#100717)
177184
err.arg("item", item.kind.descr());
178185
err.span_label(item.span, fluent::parse_label_does_not_annotate_this);
179-
err.span_suggestion_verbose(
180-
replacement_span,
181-
fluent::parse_sugg_change_inner_to_outer,
182-
match attr_type {
183-
OuterAttributeType::Attribute => "",
184-
OuterAttributeType::DocBlockComment => "*",
185-
OuterAttributeType::DocComment => "/",
186-
},
187-
rustc_errors::Applicability::MachineApplicable,
188-
);
186+
if suggest_to_outer {
187+
err.span_suggestion_verbose(
188+
replacement_span,
189+
fluent::parse_sugg_change_inner_to_outer,
190+
match attr_type {
191+
OuterAttributeType::Attribute => "",
192+
OuterAttributeType::DocBlockComment => "*",
193+
OuterAttributeType::DocComment => "/",
194+
},
195+
rustc_errors::Applicability::MachineApplicable,
196+
);
197+
}
189198
return None;
190199
}
191200
Err(item_err) => {
@@ -196,7 +205,12 @@ impl<'a> Parser<'a> {
196205
Some(replacement_span)
197206
}
198207

199-
pub(super) fn error_on_forbidden_inner_attr(&self, attr_sp: Span, policy: InnerAttrPolicy) {
208+
pub(super) fn error_on_forbidden_inner_attr(
209+
&self,
210+
attr_sp: Span,
211+
policy: InnerAttrPolicy,
212+
suggest_to_outer: bool,
213+
) {
200214
if let InnerAttrPolicy::Forbidden(reason) = policy {
201215
let mut diag = match reason.as_ref().copied() {
202216
Some(InnerAttrForbiddenReason::AfterOuterDocComment { prev_doc_comment_span }) => {
@@ -230,6 +244,7 @@ impl<'a> Parser<'a> {
230244
&mut diag,
231245
attr_sp,
232246
OuterAttributeType::Attribute,
247+
suggest_to_outer,
233248
)
234249
.is_some()
235250
{

compiler/rustc_parse/src/parser/stmt.rs

+5
Original file line numberDiff line numberDiff line change
@@ -439,11 +439,16 @@ impl<'a> Parser<'a> {
439439
pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
440440
let (attrs, block) = self.parse_inner_attrs_and_block()?;
441441
if let [.., last] = &*attrs {
442+
let suggest_to_outer = match &last.kind {
443+
ast::AttrKind::Normal(attr) => attr.item.is_valid_for_inner_outer_sytle(),
444+
_ => false,
445+
};
442446
self.error_on_forbidden_inner_attr(
443447
last.span,
444448
super::attr::InnerAttrPolicy::Forbidden(Some(
445449
InnerAttrForbiddenReason::InCodeBlock,
446450
)),
451+
suggest_to_outer,
447452
);
448453
}
449454
Ok(block)

tests/ui/delegation/inner-attr.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@ LL | fn main() {}
88
| ------------ the inner attribute doesn't annotate this function
99
|
1010
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
11-
help: to annotate the function, change the attribute from inner to outer style
12-
|
13-
LL - reuse a as b { #![rustc_dummy] self }
14-
LL + reuse a as b { #[rustc_dummy] self }
15-
|
1611

1712
error: aborting due to 1 previous error
1813

tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr

-15
Original file line numberDiff line numberDiff line change
@@ -359,11 +359,6 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); }
359359
| previous outer attribute
360360
|
361361
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
362-
help: to annotate the item macro invocation, change the attribute from inner to outer style
363-
|
364-
LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); }
365-
LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!(); }
366-
|
367362

368363
error: an inner attribute is not permitted following an outer attribute
369364
--> $DIR/attr-stmt-expr-attr-bad.rs:77:32
@@ -375,11 +370,6 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; }
375370
| previous outer attribute
376371
|
377372
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
378-
help: to annotate the item macro invocation, change the attribute from inner to outer style
379-
|
380-
LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; }
381-
LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo![]; }
382-
|
383373

384374
error: an inner attribute is not permitted following an outer attribute
385375
--> $DIR/attr-stmt-expr-attr-bad.rs:79:32
@@ -391,11 +381,6 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; }
391381
| previous outer attribute
392382
|
393383
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
394-
help: to annotate the item macro invocation, change the attribute from inner to outer style
395-
|
396-
LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; }
397-
LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!{}; }
398-
|
399384

400385
error[E0586]: inclusive range with no end
401386
--> $DIR/attr-stmt-expr-attr-bad.rs:85:35

tests/ui/parser/attribute/attr.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@ LL | fn foo() {}
77
| ----------- the inner attribute doesn't annotate this function
88
|
99
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
10-
help: to annotate the function, change the attribute from inner to outer style
11-
|
12-
LL - #![lang = "foo"]
13-
LL + #[lang = "foo"]
14-
|
1510

1611
error: aborting due to 1 previous error
1712

tests/ui/parser/inner-attr-after-doc-comment.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@ LL | fn main() {}
1313
| ------------ the inner attribute doesn't annotate this function
1414
|
1515
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
16-
help: to annotate the function, change the attribute from inner to outer style
17-
|
18-
LL - #![recursion_limit="100"]
19-
LL + #[recursion_limit="100"]
20-
|
2116

2217
error: aborting due to 1 previous error
2318

tests/ui/parser/inner-attr.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@ LL | fn main() {}
1010
| ------------ the inner attribute doesn't annotate this function
1111
|
1212
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
13-
help: to annotate the function, change the attribute from inner to outer style
14-
|
15-
LL - #![recursion_limit="100"]
16-
LL + #[recursion_limit="100"]
17-
|
1813

1914
error: aborting due to 1 previous error
2015

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![allow(dead_code)]
2+
fn foo() {}
3+
4+
#![feature(iter_array_chunks)] //~ ERROR an inner attribute is not permitted in this context
5+
fn bar() {}
6+
7+
fn main() {
8+
foo();
9+
bar();
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error: an inner attribute is not permitted in this context
2+
--> $DIR/isgg-invalid-outer-attttr-issue-127930.rs:4:1
3+
|
4+
LL | #![feature(iter_array_chunks)]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
LL | fn bar() {}
7+
| ----------- the inner attribute doesn't annotate this function
8+
|
9+
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
10+
11+
error: aborting due to 1 previous error
12+

tests/ui/parser/issues/issue-30318.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ fn foo() { }
66
//~^ ERROR expected outer doc comment
77
fn bar() { } //~ NOTE the inner doc comment doesn't annotate this function
88

9-
#[test] //~ ERROR an inner attribute is not permitted in this context
9+
#[cfg(test)] //~ ERROR an inner attribute is not permitted in this context
1010
fn baz() { } //~ NOTE the inner attribute doesn't annotate this function
1111
//~^^ NOTE inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually
1212

tests/ui/parser/issues/issue-30318.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ fn foo() { }
66
//~^ ERROR expected outer doc comment
77
fn bar() { } //~ NOTE the inner doc comment doesn't annotate this function
88

9-
#![test] //~ ERROR an inner attribute is not permitted in this context
9+
#![cfg(test)] //~ ERROR an inner attribute is not permitted in this context
1010
fn baz() { } //~ NOTE the inner attribute doesn't annotate this function
1111
//~^^ NOTE inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually
1212

tests/ui/parser/issues/issue-30318.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ LL | /// Misplaced comment...
1515
error: an inner attribute is not permitted in this context
1616
--> $DIR/issue-30318.rs:9:1
1717
|
18-
LL | #![test]
19-
| ^^^^^^^^
18+
LL | #![cfg(test)]
19+
| ^^^^^^^^^^^^^
2020
LL | fn baz() { }
2121
| ------------ the inner attribute doesn't annotate this function
2222
|
2323
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
2424
help: to annotate the function, change the attribute from inner to outer style
2525
|
26-
LL - #![test]
27-
LL + #[test]
26+
LL - #![cfg(test)]
27+
LL + #[cfg(test)]
2828
|
2929

3030
error[E0753]: expected outer doc comment

0 commit comments

Comments
 (0)