Skip to content

Commit adedc2b

Browse files
Rollup merge of #145243 - jdonszelmann:inner-attr-errors, r=petrochenkov
take attr style into account in diagnostics when the original attribute was specified as an inner attribute, the suggestion will now match that attribute style
2 parents 3c309b0 + 0241292 commit adedc2b

File tree

13 files changed

+53
-37
lines changed

13 files changed

+53
-37
lines changed

compiler/rustc_attr_parsing/src/attributes/inline.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ impl<S: Stage> SingleAttributeParser<S> for InlineParser {
4747
}
4848
}
4949
ArgParser::NameValue(_) => {
50-
let suggestions =
51-
<Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "inline");
50+
let suggestions = <Self as SingleAttributeParser<S>>::TEMPLATE
51+
.suggestions(cx.attr_style, "inline");
5252
let span = cx.attr_span;
5353
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
5454
return None;

compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ impl<S: Stage> AttributeParser<S> for MacroUseParser {
9999
}
100100
}
101101
ArgParser::NameValue(_) => {
102-
let suggestions = MACRO_USE_TEMPLATE.suggestions(false, sym::macro_use);
102+
let suggestions = MACRO_USE_TEMPLATE.suggestions(cx.attr_style, sym::macro_use);
103103
cx.emit_err(session_diagnostics::IllFormedAttributeInputLint {
104104
num_suggestions: suggestions.len(),
105105
suggestions: DiagArgValue::StrListSepByAnd(

compiler/rustc_attr_parsing/src/attributes/must_use.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ impl<S: Stage> SingleAttributeParser<S> for MustUseParser {
3535
Some(value_str)
3636
}
3737
ArgParser::List(_) => {
38-
let suggestions =
39-
<Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "must_use");
38+
let suggestions = <Self as SingleAttributeParser<S>>::TEMPLATE
39+
.suggestions(cx.attr_style, "must_use");
4040
cx.emit_err(session_diagnostics::IllFormedAttributeInputLint {
4141
num_suggestions: suggestions.len(),
4242
suggestions: DiagArgValue::StrListSepByAnd(

compiler/rustc_attr_parsing/src/attributes/test_attrs.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl<S: Stage> SingleAttributeParser<S> for IgnoreParser {
2626
ArgParser::NameValue(name_value) => {
2727
let Some(str_value) = name_value.value_as_str() else {
2828
let suggestions = <Self as SingleAttributeParser<S>>::TEMPLATE
29-
.suggestions(false, "ignore");
29+
.suggestions(cx.attr_style, "ignore");
3030
let span = cx.attr_span;
3131
cx.emit_lint(
3232
AttributeLintKind::IllFormedAttributeInput { suggestions },
@@ -37,8 +37,8 @@ impl<S: Stage> SingleAttributeParser<S> for IgnoreParser {
3737
Some(str_value)
3838
}
3939
ArgParser::List(_) => {
40-
let suggestions =
41-
<Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "ignore");
40+
let suggestions = <Self as SingleAttributeParser<S>>::TEMPLATE
41+
.suggestions(cx.attr_style, "ignore");
4242
let span = cx.attr_span;
4343
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
4444
return None;

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::ops::{Deref, DerefMut};
44
use std::sync::LazyLock;
55

66
use private::Sealed;
7-
use rustc_ast::{self as ast, LitKind, MetaItemLit, NodeId};
7+
use rustc_ast::{self as ast, AttrStyle, LitKind, MetaItemLit, NodeId};
88
use rustc_errors::{DiagCtxtHandle, Diagnostic};
99
use rustc_feature::{AttributeTemplate, Features};
1010
use rustc_hir::attrs::AttributeKind;
@@ -305,6 +305,7 @@ pub struct AcceptContext<'f, 'sess, S: Stage> {
305305
/// The span of the attribute currently being parsed
306306
pub(crate) attr_span: Span,
307307

308+
pub(crate) attr_style: AttrStyle,
308309
/// The expected structure of the attribute.
309310
///
310311
/// Used in reporting errors to give a hint to users what the attribute *should* look like.
@@ -386,6 +387,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
386387
i.kind.is_bytestr().then(|| self.sess().source_map().start_point(i.span))
387388
}),
388389
},
390+
attr_style: self.attr_style,
389391
})
390392
}
391393

@@ -396,6 +398,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
396398
template: self.template.clone(),
397399
attribute: self.attr_path.clone(),
398400
reason: AttributeParseErrorReason::ExpectedIntegerLiteral,
401+
attr_style: self.attr_style,
399402
})
400403
}
401404

@@ -406,6 +409,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
406409
template: self.template.clone(),
407410
attribute: self.attr_path.clone(),
408411
reason: AttributeParseErrorReason::ExpectedList,
412+
attr_style: self.attr_style,
409413
})
410414
}
411415

@@ -416,6 +420,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
416420
template: self.template.clone(),
417421
attribute: self.attr_path.clone(),
418422
reason: AttributeParseErrorReason::ExpectedNoArgs,
423+
attr_style: self.attr_style,
419424
})
420425
}
421426

@@ -427,6 +432,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
427432
template: self.template.clone(),
428433
attribute: self.attr_path.clone(),
429434
reason: AttributeParseErrorReason::ExpectedIdentifier,
435+
attr_style: self.attr_style,
430436
})
431437
}
432438

@@ -439,6 +445,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
439445
template: self.template.clone(),
440446
attribute: self.attr_path.clone(),
441447
reason: AttributeParseErrorReason::ExpectedNameValue(name),
448+
attr_style: self.attr_style,
442449
})
443450
}
444451

@@ -450,6 +457,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
450457
template: self.template.clone(),
451458
attribute: self.attr_path.clone(),
452459
reason: AttributeParseErrorReason::DuplicateKey(key),
460+
attr_style: self.attr_style,
453461
})
454462
}
455463

@@ -462,6 +470,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
462470
template: self.template.clone(),
463471
attribute: self.attr_path.clone(),
464472
reason: AttributeParseErrorReason::UnexpectedLiteral,
473+
attr_style: self.attr_style,
465474
})
466475
}
467476

@@ -472,6 +481,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
472481
template: self.template.clone(),
473482
attribute: self.attr_path.clone(),
474483
reason: AttributeParseErrorReason::ExpectedSingleArgument,
484+
attr_style: self.attr_style,
475485
})
476486
}
477487

@@ -482,6 +492,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
482492
template: self.template.clone(),
483493
attribute: self.attr_path.clone(),
484494
reason: AttributeParseErrorReason::ExpectedAtLeastOneArgument,
495+
attr_style: self.attr_style,
485496
})
486497
}
487498

@@ -500,6 +511,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
500511
strings: false,
501512
list: false,
502513
},
514+
attr_style: self.attr_style,
503515
})
504516
}
505517

@@ -518,6 +530,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
518530
strings: false,
519531
list: true,
520532
},
533+
attr_style: self.attr_style,
521534
})
522535
}
523536

@@ -536,6 +549,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
536549
strings: true,
537550
list: false,
538551
},
552+
attr_style: self.attr_style,
539553
})
540554
}
541555

@@ -735,6 +749,7 @@ impl<'sess> AttributeParser<'sess, Early> {
735749
},
736750
},
737751
attr_span: attr.span,
752+
attr_style: attr.style,
738753
template,
739754
attr_path: path.get_attribute_path(),
740755
};
@@ -844,6 +859,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
844859
emit_lint: &mut emit_lint,
845860
},
846861
attr_span: lower_span(attr.span),
862+
attr_style: attr.style,
847863
template: &accept.template,
848864
attr_path: path.get_attribute_path(),
849865
};

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::num::IntErrorKind;
22

3-
use rustc_ast as ast;
3+
use rustc_ast::{self as ast, AttrStyle};
44
use rustc_errors::codes::*;
55
use rustc_errors::{
66
Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level,
@@ -556,6 +556,7 @@ pub(crate) enum AttributeParseErrorReason {
556556
pub(crate) struct AttributeParseError {
557557
pub(crate) span: Span,
558558
pub(crate) attr_span: Span,
559+
pub(crate) attr_style: AttrStyle,
559560
pub(crate) template: AttributeTemplate,
560561
pub(crate) attribute: AttrPath,
561562
pub(crate) reason: AttributeParseErrorReason,
@@ -694,7 +695,8 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError {
694695
if let Some(link) = self.template.docs {
695696
diag.note(format!("for more information, visit <{link}>"));
696697
}
697-
let suggestions = self.template.suggestions(false, &name);
698+
let suggestions = self.template.suggestions(self.attr_style, &name);
699+
698700
diag.span_suggestions(
699701
self.attr_span,
700702
if suggestions.len() == 1 {

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use AttributeDuplicates::*;
66
use AttributeGate::*;
77
use AttributeType::*;
88
use rustc_data_structures::fx::FxHashMap;
9+
use rustc_hir::AttrStyle;
910
use rustc_hir::attrs::EncodeCrossCrate;
1011
use rustc_span::edition::Edition;
1112
use rustc_span::{Symbol, sym};
@@ -132,9 +133,12 @@ pub struct AttributeTemplate {
132133
}
133134

134135
impl AttributeTemplate {
135-
pub fn suggestions(&self, inner: bool, name: impl std::fmt::Display) -> Vec<String> {
136+
pub fn suggestions(&self, style: AttrStyle, name: impl std::fmt::Display) -> Vec<String> {
136137
let mut suggestions = vec![];
137-
let inner = if inner { "!" } else { "" };
138+
let inner = match style {
139+
AttrStyle::Outer => "",
140+
AttrStyle::Inner => "!",
141+
};
138142
if self.word {
139143
suggestions.push(format!("#{inner}[{name}]"));
140144
}

tests/ui/attributes/lint_on_root.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// NOTE: this used to panic in debug builds (by a sanity assertion)
22
// and not emit any lint on release builds. See https://github.com/rust-lang/rust/issues/142891.
33
#![inline = ""]
4-
//~^ ERROR: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` [ill_formed_attribute_input]
4+
//~^ ERROR: valid forms for the attribute are `#![inline(always)]`, `#![inline(never)]`, and `#![inline]` [ill_formed_attribute_input]
55
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
66

77
fn main() {}

tests/ui/attributes/lint_on_root.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]`
1+
error: valid forms for the attribute are `#![inline(always)]`, `#![inline(never)]`, and `#![inline]`
22
--> $DIR/lint_on_root.rs:3:1
33
|
44
LL | #![inline = ""]
@@ -11,7 +11,7 @@ LL | #![inline = ""]
1111
error: aborting due to 1 previous error
1212

1313
Future incompatibility report: Future breakage diagnostic:
14-
error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]`
14+
error: valid forms for the attribute are `#![inline(always)]`, `#![inline(never)]`, and `#![inline]`
1515
--> $DIR/lint_on_root.rs:3:1
1616
|
1717
LL | #![inline = ""]

tests/ui/attributes/malformed-reprs.stderr

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,14 @@ LL | #![repr]
77
= note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html#representations>
88
help: try changing it to one of the following valid forms of the attribute
99
|
10-
LL - #![repr]
11-
LL + #[repr(<integer type>)]
12-
|
13-
LL - #![repr]
14-
LL + #[repr(C)]
15-
|
16-
LL - #![repr]
17-
LL + #[repr(Rust)]
18-
|
19-
LL - #![repr]
20-
LL + #[repr(align(...))]
21-
|
10+
LL | #![repr(<integer type>)]
11+
| ++++++++++++++++
12+
LL | #![repr(C)]
13+
| +++
14+
LL | #![repr(Rust)]
15+
| ++++++
16+
LL | #![repr(align(...))]
17+
| ++++++++++++
2218
= and 2 other candidates
2319

2420
error[E0589]: invalid `repr(align)` attribute: not a power of two

0 commit comments

Comments
 (0)