Skip to content

Commit c8d68a9

Browse files
Add ParsedDescription to the attribute parsers
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
1 parent 2b8a742 commit c8d68a9

File tree

9 files changed

+73
-29
lines changed

9 files changed

+73
-29
lines changed

compiler/rustc_attr_parsing/src/attributes/cfg.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::context::{AcceptContext, ShouldEmit, Stage};
1919
use crate::parser::{ArgParser, MetaItemListParser, MetaItemOrLitParser, NameValueParser};
2020
use crate::session_diagnostics::{
2121
AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg,
22+
ParsedDescription,
2223
};
2324
use crate::{
2425
AttributeParser, CfgMatchesLintEmitter, fluent_generated, parse_version, session_diagnostics,
@@ -352,7 +353,8 @@ pub fn parse_cfg_attr(
352353
span,
353354
attr_span: cfg_attr.span,
354355
template: CFG_ATTR_TEMPLATE,
355-
attribute: AttrPath::from_ast(&cfg_attr.get_normal_item().path),
356+
path: AttrPath::from_ast(&cfg_attr.get_normal_item().path),
357+
description: ParsedDescription::Attribute,
356358
reason,
357359
suggestions: CFG_ATTR_TEMPLATE.suggestions(Some(cfg_attr.style), sym::cfg_attr),
358360
});
@@ -395,6 +397,7 @@ fn parse_cfg_attr_internal<'a>(
395397
.into_boxed_slice(),
396398
span: attribute.span,
397399
},
400+
ParsedDescription::Attribute,
398401
pred_span,
399402
CRATE_NODE_ID,
400403
features,

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ use crate::attributes::traits::{
7070
use crate::attributes::transparency::TransparencyParser;
7171
use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
7272
use crate::parser::{ArgParser, PathParser};
73-
use crate::session_diagnostics::{AttributeParseError, AttributeParseErrorReason, UnknownMetaItem};
73+
use crate::session_diagnostics::{
74+
AttributeParseError, AttributeParseErrorReason, ParsedDescription, UnknownMetaItem,
75+
};
7476
use crate::target_checking::AllowedTargets;
7577

7678
type GroupType<S> = LazyLock<GroupTypeInner<S>>;
@@ -351,6 +353,10 @@ pub struct AcceptContext<'f, 'sess, S: Stage> {
351353
/// Whether it is an inner or outer attribute
352354
pub(crate) attr_style: AttrStyle,
353355

356+
/// A description of the thing we are parsing using this attribute parser
357+
/// We are not only using these parsers for attributes, but also for macros such as the `cfg!()` macro.
358+
pub(crate) parsed_description: ParsedDescription,
359+
354360
/// The expected structure of the attribute.
355361
///
356362
/// Used in reporting errors to give a hint to users what the attribute *should* look like.
@@ -429,7 +435,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
429435
span,
430436
attr_span: self.attr_span,
431437
template: self.template.clone(),
432-
attribute: self.attr_path.clone(),
438+
path: self.attr_path.clone(),
439+
description: self.parsed_description,
433440
reason: AttributeParseErrorReason::ExpectedStringLiteral {
434441
byte_string: actual_literal.and_then(|i| {
435442
i.kind.is_bytestr().then(|| self.sess().source_map().start_point(i.span))
@@ -444,7 +451,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
444451
span,
445452
attr_span: self.attr_span,
446453
template: self.template.clone(),
447-
attribute: self.attr_path.clone(),
454+
path: self.attr_path.clone(),
455+
description: self.parsed_description,
448456
reason: AttributeParseErrorReason::ExpectedIntegerLiteral,
449457
suggestions: self.suggestions(),
450458
})
@@ -455,7 +463,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
455463
span,
456464
attr_span: self.attr_span,
457465
template: self.template.clone(),
458-
attribute: self.attr_path.clone(),
466+
path: self.attr_path.clone(),
467+
description: self.parsed_description,
459468
reason: AttributeParseErrorReason::ExpectedList,
460469
suggestions: self.suggestions(),
461470
})
@@ -466,7 +475,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
466475
span: args_span,
467476
attr_span: self.attr_span,
468477
template: self.template.clone(),
469-
attribute: self.attr_path.clone(),
478+
path: self.attr_path.clone(),
479+
description: self.parsed_description,
470480
reason: AttributeParseErrorReason::ExpectedNoArgs,
471481
suggestions: self.suggestions(),
472482
})
@@ -478,7 +488,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
478488
span,
479489
attr_span: self.attr_span,
480490
template: self.template.clone(),
481-
attribute: self.attr_path.clone(),
491+
path: self.attr_path.clone(),
492+
description: self.parsed_description,
482493
reason: AttributeParseErrorReason::ExpectedIdentifier,
483494
suggestions: self.suggestions(),
484495
})
@@ -491,7 +502,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
491502
span,
492503
attr_span: self.attr_span,
493504
template: self.template.clone(),
494-
attribute: self.attr_path.clone(),
505+
path: self.attr_path.clone(),
506+
description: self.parsed_description,
495507
reason: AttributeParseErrorReason::ExpectedNameValue(name),
496508
suggestions: self.suggestions(),
497509
})
@@ -503,7 +515,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
503515
span,
504516
attr_span: self.attr_span,
505517
template: self.template.clone(),
506-
attribute: self.attr_path.clone(),
518+
path: self.attr_path.clone(),
519+
description: self.parsed_description,
507520
reason: AttributeParseErrorReason::DuplicateKey(key),
508521
suggestions: self.suggestions(),
509522
})
@@ -516,7 +529,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
516529
span,
517530
attr_span: self.attr_span,
518531
template: self.template.clone(),
519-
attribute: self.attr_path.clone(),
532+
path: self.attr_path.clone(),
533+
description: self.parsed_description,
520534
reason: AttributeParseErrorReason::UnexpectedLiteral,
521535
suggestions: self.suggestions(),
522536
})
@@ -527,7 +541,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
527541
span,
528542
attr_span: self.attr_span,
529543
template: self.template.clone(),
530-
attribute: self.attr_path.clone(),
544+
path: self.attr_path.clone(),
545+
description: self.parsed_description,
531546
reason: AttributeParseErrorReason::ExpectedSingleArgument,
532547
suggestions: self.suggestions(),
533548
})
@@ -538,7 +553,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
538553
span,
539554
attr_span: self.attr_span,
540555
template: self.template.clone(),
541-
attribute: self.attr_path.clone(),
556+
path: self.attr_path.clone(),
557+
description: self.parsed_description,
542558
reason: AttributeParseErrorReason::ExpectedAtLeastOneArgument,
543559
suggestions: self.suggestions(),
544560
})
@@ -554,7 +570,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
554570
span,
555571
attr_span: self.attr_span,
556572
template: self.template.clone(),
557-
attribute: self.attr_path.clone(),
573+
path: self.attr_path.clone(),
574+
description: self.parsed_description,
558575
reason: AttributeParseErrorReason::ExpectedSpecificArgument {
559576
possibilities,
560577
strings: false,
@@ -575,7 +592,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
575592
span,
576593
attr_span: self.attr_span,
577594
template: self.template.clone(),
578-
attribute: self.attr_path.clone(),
595+
path: self.attr_path.clone(),
596+
description: self.parsed_description,
579597
reason: AttributeParseErrorReason::ExpectedSpecificArgument {
580598
possibilities,
581599
strings: false,
@@ -595,7 +613,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
595613
span,
596614
attr_span: self.attr_span,
597615
template: self.template.clone(),
598-
attribute: self.attr_path.clone(),
616+
path: self.attr_path.clone(),
617+
description: self.parsed_description,
599618
reason: AttributeParseErrorReason::ExpectedSpecificArgument {
600619
possibilities,
601620
strings: true,

compiler/rustc_attr_parsing/src/interface.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_span::{DUMMY_SP, Span, Symbol, sym};
1212

1313
use crate::context::{AcceptContext, FinalizeContext, SharedContext, Stage};
1414
use crate::parser::{ArgParser, MetaItemParser, PathParser};
15+
use crate::session_diagnostics::ParsedDescription;
1516
use crate::{Early, Late, OmitDoc, ShouldEmit};
1617

1718
/// Context created once, for example as part of the ast lowering
@@ -145,6 +146,7 @@ impl<'sess> AttributeParser<'sess, Early> {
145146
normal_attr.item.span(),
146147
attr.style,
147148
path.get_attribute_path(),
149+
ParsedDescription::Attribute,
148150
target_span,
149151
target_node_id,
150152
features,
@@ -163,6 +165,7 @@ impl<'sess> AttributeParser<'sess, Early> {
163165
inner_span: Span,
164166
attr_style: AttrStyle,
165167
attr_path: AttrPath,
168+
parsed_description: ParsedDescription,
166169
target_span: Span,
167170
target_node_id: NodeId,
168171
features: Option<&'sess Features>,
@@ -190,6 +193,7 @@ impl<'sess> AttributeParser<'sess, Early> {
190193
attr_span,
191194
inner_span,
192195
attr_style,
196+
parsed_description,
193197
template,
194198
attr_path,
195199
};
@@ -310,6 +314,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
310314
attr_span: lower_span(attr.span),
311315
inner_span: lower_span(attr.get_normal_item().span()),
312316
attr_style: attr.style,
317+
parsed_description: ParsedDescription::Attribute,
313318
template: &accept.template,
314319
attr_path: path.get_attribute_path(),
315320
};

compiler/rustc_attr_parsing/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,5 +113,6 @@ pub use attributes::util::{is_builtin_attr, is_doc_alias_attrs_contain_symbol, p
113113
pub use context::{Early, Late, OmitDoc, ShouldEmit};
114114
pub use interface::AttributeParser;
115115
pub use lints::emit_attribute_lint;
116+
pub use session_diagnostics::ParsedDescription;
116117

117118
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -610,20 +610,33 @@ pub(crate) enum AttributeParseErrorReason<'a> {
610610
ExpectedIdentifier,
611611
}
612612

613+
/// A description of a thing that can be parsed using an attribute parser.
614+
#[derive(Copy, Clone)]
615+
pub enum ParsedDescription {
616+
Attribute,
617+
Macro,
618+
}
619+
613620
pub(crate) struct AttributeParseError<'a> {
614621
pub(crate) span: Span,
615622
pub(crate) attr_span: Span,
616623
pub(crate) template: AttributeTemplate,
617-
pub(crate) attribute: AttrPath,
624+
pub(crate) path: AttrPath,
625+
pub(crate) description: ParsedDescription,
618626
pub(crate) reason: AttributeParseErrorReason<'a>,
619627
pub(crate) suggestions: Vec<String>,
620628
}
621629

622630
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
623631
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
624-
let name = self.attribute.to_string();
632+
let name = self.path.to_string();
633+
634+
let description = match self.description {
635+
ParsedDescription::Attribute => "attribute",
636+
ParsedDescription::Macro => "macro",
637+
};
625638

626-
let mut diag = Diag::new(dcx, level, format!("malformed `{name}` attribute input"));
639+
let mut diag = Diag::new(dcx, level, format!("malformed `{name}` {description} input"));
627640
diag.span(self.attr_span);
628641
diag.code(E0539);
629642
match self.reason {
@@ -724,12 +737,12 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
724737
diag.span_label(
725738
self.span,
726739
format!(
727-
"this attribute is only valid with {quote}{x}{quote} as an argument"
740+
"this {description} is only valid with {quote}{x}{quote} as an argument"
728741
),
729742
);
730743
}
731744
[first, second] => {
732-
diag.span_label(self.span, format!("this attribute is only valid with either {quote}{first}{quote} or {quote}{second}{quote} as an argument"));
745+
diag.span_label(self.span, format!("this {description} is only valid with either {quote}{first}{quote} or {quote}{second}{quote} as an argument"));
733746
}
734747
[first @ .., second_to_last, last] => {
735748
let mut res = String::new();
@@ -740,7 +753,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
740753
"{quote}{second_to_last}{quote} or {quote}{last}{quote}"
741754
));
742755

743-
diag.span_label(self.span, format!("this attribute is only valid with one of the following arguments: {res}"));
756+
diag.span_label(self.span, format!("this {description} is only valid with one of the following arguments: {res}"));
744757
}
745758
}
746759
}
@@ -756,9 +769,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
756769
diag.span_suggestions(
757770
self.attr_span,
758771
if self.suggestions.len() == 1 {
759-
"must be of the form"
772+
"must be of the form".to_string()
760773
} else {
761-
"try changing it to one of the following valid forms of the attribute"
774+
format!("try changing it to one of the following valid forms of the {description}")
762775
},
763776
self.suggestions,
764777
Applicability::HasPlaceholders,

compiler/rustc_builtin_macros/src/cfg.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use rustc_ast::tokenstream::TokenStream;
66
use rustc_ast::{AttrStyle, CRATE_NODE_ID, token};
77
use rustc_attr_parsing as attr;
88
use rustc_attr_parsing::parser::MetaItemOrLitParser;
9-
use rustc_attr_parsing::{AttributeParser, CFG_TEMPLATE, ShouldEmit, parse_cfg_entry};
9+
use rustc_attr_parsing::{
10+
AttributeParser, CFG_TEMPLATE, ParsedDescription, ShouldEmit, parse_cfg_entry,
11+
};
1012
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
1113
use rustc_hir::AttrPath;
1214
use rustc_hir::attrs::CfgEntry;
@@ -53,6 +55,7 @@ fn parse_cfg(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream) -> Result<CfgEntry,
5355
span,
5456
AttrStyle::Inner,
5557
AttrPath { segments: vec![Ident::from_str("cfg")].into_boxed_slice(), span },
58+
ParsedDescription::Macro,
5659
span,
5760
CRATE_NODE_ID,
5861
Some(cx.ecfg.features),

tests/ui/macros/cfg.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
fn main() {
22
cfg!(); //~ ERROR macro requires a cfg-pattern
3-
cfg!(123); //~ ERROR malformed `cfg` attribute input
4-
cfg!(foo = 123); //~ ERROR malformed `cfg` attribute input
3+
cfg!(123); //~ ERROR malformed `cfg` macro input
4+
cfg!(foo = 123); //~ ERROR malformed `cfg` macro input
55
cfg!(foo, bar); //~ ERROR expected 1 cfg-pattern
66
}

tests/ui/macros/cfg.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error: macro requires a cfg-pattern as an argument
44
LL | cfg!();
55
| ^^^^^^ cfg-pattern required
66

7-
error[E0539]: malformed `cfg` attribute input
7+
error[E0539]: malformed `cfg` macro input
88
--> $DIR/cfg.rs:3:5
99
|
1010
LL | cfg!(123);
@@ -15,7 +15,7 @@ LL | cfg!(123);
1515
|
1616
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
1717

18-
error[E0539]: malformed `cfg` attribute input
18+
error[E0539]: malformed `cfg` macro input
1919
--> $DIR/cfg.rs:4:5
2020
|
2121
LL | cfg!(foo = 123);

tests/ui/span/E0805.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0805]: malformed `cfg` attribute input
1+
error[E0805]: malformed `cfg` macro input
22
--> $DIR/E0805.rs:2:8
33
|
44
LL | if cfg!(not()) { }

0 commit comments

Comments
 (0)