Skip to content

Commit a628e71

Browse files
Add ParsedDescription to the attribute parsers
Signed-off-by: Jonathan Brouwer <[email protected]>
1 parent b78800f commit a628e71

File tree

9 files changed

+75
-29
lines changed

9 files changed

+75
-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
@@ -71,7 +71,9 @@ use crate::attributes::traits::{
7171
use crate::attributes::transparency::TransparencyParser;
7272
use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
7373
use crate::parser::{ArgParser, PathParser};
74-
use crate::session_diagnostics::{AttributeParseError, AttributeParseErrorReason, UnknownMetaItem};
74+
use crate::session_diagnostics::{
75+
AttributeParseError, AttributeParseErrorReason, ParsedDescription, UnknownMetaItem,
76+
};
7577
use crate::target_checking::AllowedTargets;
7678

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

358+
/// A description of the thing we are parsing using this attribute parser
359+
/// We are not only using these parsers for attributes, but also for macros such as the `cfg!()` macro.
360+
pub(crate) parsed_description: ParsedDescription,
361+
356362
/// The expected structure of the attribute.
357363
///
358364
/// Used in reporting errors to give a hint to users what the attribute *should* look like.
@@ -431,7 +437,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
431437
span,
432438
attr_span: self.attr_span,
433439
template: self.template.clone(),
434-
attribute: self.attr_path.clone(),
440+
path: self.attr_path.clone(),
441+
description: self.parsed_description,
435442
reason: AttributeParseErrorReason::ExpectedStringLiteral {
436443
byte_string: actual_literal.and_then(|i| {
437444
i.kind.is_bytestr().then(|| self.sess().source_map().start_point(i.span))
@@ -446,7 +453,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
446453
span,
447454
attr_span: self.attr_span,
448455
template: self.template.clone(),
449-
attribute: self.attr_path.clone(),
456+
path: self.attr_path.clone(),
457+
description: self.parsed_description,
450458
reason: AttributeParseErrorReason::ExpectedIntegerLiteral,
451459
suggestions: self.suggestions(),
452460
})
@@ -457,7 +465,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
457465
span,
458466
attr_span: self.attr_span,
459467
template: self.template.clone(),
460-
attribute: self.attr_path.clone(),
468+
path: self.attr_path.clone(),
469+
description: self.parsed_description,
461470
reason: AttributeParseErrorReason::ExpectedList,
462471
suggestions: self.suggestions(),
463472
})
@@ -468,7 +477,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
468477
span: args_span,
469478
attr_span: self.attr_span,
470479
template: self.template.clone(),
471-
attribute: self.attr_path.clone(),
480+
path: self.attr_path.clone(),
481+
description: self.parsed_description,
472482
reason: AttributeParseErrorReason::ExpectedNoArgs,
473483
suggestions: self.suggestions(),
474484
})
@@ -480,7 +490,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
480490
span,
481491
attr_span: self.attr_span,
482492
template: self.template.clone(),
483-
attribute: self.attr_path.clone(),
493+
path: self.attr_path.clone(),
494+
description: self.parsed_description,
484495
reason: AttributeParseErrorReason::ExpectedIdentifier,
485496
suggestions: self.suggestions(),
486497
})
@@ -493,7 +504,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
493504
span,
494505
attr_span: self.attr_span,
495506
template: self.template.clone(),
496-
attribute: self.attr_path.clone(),
507+
path: self.attr_path.clone(),
508+
description: self.parsed_description,
497509
reason: AttributeParseErrorReason::ExpectedNameValue(name),
498510
suggestions: self.suggestions(),
499511
})
@@ -505,7 +517,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
505517
span,
506518
attr_span: self.attr_span,
507519
template: self.template.clone(),
508-
attribute: self.attr_path.clone(),
520+
path: self.attr_path.clone(),
521+
description: self.parsed_description,
509522
reason: AttributeParseErrorReason::DuplicateKey(key),
510523
suggestions: self.suggestions(),
511524
})
@@ -518,7 +531,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
518531
span,
519532
attr_span: self.attr_span,
520533
template: self.template.clone(),
521-
attribute: self.attr_path.clone(),
534+
path: self.attr_path.clone(),
535+
description: self.parsed_description,
522536
reason: AttributeParseErrorReason::UnexpectedLiteral,
523537
suggestions: self.suggestions(),
524538
})
@@ -529,7 +543,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
529543
span,
530544
attr_span: self.attr_span,
531545
template: self.template.clone(),
532-
attribute: self.attr_path.clone(),
546+
path: self.attr_path.clone(),
547+
description: self.parsed_description,
533548
reason: AttributeParseErrorReason::ExpectedSingleArgument,
534549
suggestions: self.suggestions(),
535550
})
@@ -540,7 +555,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
540555
span,
541556
attr_span: self.attr_span,
542557
template: self.template.clone(),
543-
attribute: self.attr_path.clone(),
558+
path: self.attr_path.clone(),
559+
description: self.parsed_description,
544560
reason: AttributeParseErrorReason::ExpectedAtLeastOneArgument,
545561
suggestions: self.suggestions(),
546562
})
@@ -556,7 +572,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
556572
span,
557573
attr_span: self.attr_span,
558574
template: self.template.clone(),
559-
attribute: self.attr_path.clone(),
575+
path: self.attr_path.clone(),
576+
description: self.parsed_description,
560577
reason: AttributeParseErrorReason::ExpectedSpecificArgument {
561578
possibilities,
562579
strings: false,
@@ -577,7 +594,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
577594
span,
578595
attr_span: self.attr_span,
579596
template: self.template.clone(),
580-
attribute: self.attr_path.clone(),
597+
path: self.attr_path.clone(),
598+
description: self.parsed_description,
581599
reason: AttributeParseErrorReason::ExpectedSpecificArgument {
582600
possibilities,
583601
strings: false,
@@ -597,7 +615,8 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
597615
span,
598616
attr_span: self.attr_span,
599617
template: self.template.clone(),
600-
attribute: self.attr_path.clone(),
618+
path: self.attr_path.clone(),
619+
description: self.parsed_description,
601620
reason: AttributeParseErrorReason::ExpectedSpecificArgument {
602621
possibilities,
603622
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: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -610,20 +610,35 @@ 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+
/// Used when parsing attributes.
617+
Attribute,
618+
/// Used when parsing some macros, such as the `cfg!()` macro.
619+
Macro,
620+
}
621+
613622
pub(crate) struct AttributeParseError<'a> {
614623
pub(crate) span: Span,
615624
pub(crate) attr_span: Span,
616625
pub(crate) template: AttributeTemplate,
617-
pub(crate) attribute: AttrPath,
626+
pub(crate) path: AttrPath,
627+
pub(crate) description: ParsedDescription,
618628
pub(crate) reason: AttributeParseErrorReason<'a>,
619629
pub(crate) suggestions: Vec<String>,
620630
}
621631

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

626-
let mut diag = Diag::new(dcx, level, format!("malformed `{name}` attribute input"));
641+
let mut diag = Diag::new(dcx, level, format!("malformed `{name}` {description} input"));
627642
diag.span(self.attr_span);
628643
diag.code(E0539);
629644
match self.reason {
@@ -724,12 +739,12 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
724739
diag.span_label(
725740
self.span,
726741
format!(
727-
"this attribute is only valid with {quote}{x}{quote} as an argument"
742+
"this {description} is only valid with {quote}{x}{quote} as an argument"
728743
),
729744
);
730745
}
731746
[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"));
747+
diag.span_label(self.span, format!("this {description} is only valid with either {quote}{first}{quote} or {quote}{second}{quote} as an argument"));
733748
}
734749
[first @ .., second_to_last, last] => {
735750
let mut res = String::new();
@@ -740,7 +755,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
740755
"{quote}{second_to_last}{quote} or {quote}{last}{quote}"
741756
));
742757

743-
diag.span_label(self.span, format!("this attribute is only valid with one of the following arguments: {res}"));
758+
diag.span_label(self.span, format!("this {description} is only valid with one of the following arguments: {res}"));
744759
}
745760
}
746761
}
@@ -756,9 +771,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
756771
diag.span_suggestions(
757772
self.attr_span,
758773
if self.suggestions.len() == 1 {
759-
"must be of the form"
774+
"must be of the form".to_string()
760775
} else {
761-
"try changing it to one of the following valid forms of the attribute"
776+
format!("try changing it to one of the following valid forms of the {description}")
762777
},
763778
self.suggestions,
764779
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)