Skip to content

Commit 3b690f4

Browse files
Rollup merge of rust-lang#155757 - mejrs:ident_help, r=Kivooeo
macro_metavar_expr_concat: explain why idents are invalid Recently I've been playing around with `macro_metavar_expr_concat` and in the process wasted more time than I'd have liked on debugging my dodgy idents. This should make that experience much nicer going forward.
2 parents 68ffae4 + b6c6dd1 commit 3b690f4

6 files changed

Lines changed: 139 additions & 52 deletions

File tree

compiler/rustc_expand/src/errors.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,49 @@ mod metavar_exprs {
545545
pub span: Span,
546546
pub key: MacroRulesNormalizedIdent,
547547
}
548+
549+
#[derive(Diagnostic)]
550+
#[diag(r#"`${"{"}concat(..){"}"}` is not generating a valid identifier"#)]
551+
pub(crate) struct ConcatInvalidIdent {
552+
#[primary_span]
553+
pub span: Span,
554+
#[subdiagnostic]
555+
pub reason: InvalidIdentReason,
556+
}
557+
558+
#[derive(Subdiagnostic)]
559+
pub(crate) enum InvalidIdentReason {
560+
#[note(r#"this `${"{"}concat(..){"}"}` invocation generated an empty ident"#)]
561+
Empty,
562+
#[note(r#"this `${"{"}concat(..){"}"}` invocation generated `{$symbol}`, but {$start} is neither '_' nor XID_Start"#)]
563+
#[note(
564+
"see <https://doc.rust-lang.org/reference/identifiers.html> for the definition of valid identifiers"
565+
)]
566+
InvalidStart { symbol: Symbol, start: char },
567+
#[note(r#"this `${"{"}concat(..){"}"}` invocation generated `{$symbol}`, but {$not_continue} is not XID_Continue"#)]
568+
#[note(
569+
"see <https://doc.rust-lang.org/reference/identifiers.html> for the definition of valid identifiers"
570+
)]
571+
InvalidContinue { symbol: Symbol, not_continue: char },
572+
}
573+
574+
impl InvalidIdentReason {
575+
pub(crate) fn new(symbol: Symbol) -> Self {
576+
let mut chars = symbol.as_str().chars();
577+
if let Some(start) = chars.next() {
578+
if rustc_lexer::is_id_start(start) {
579+
let not_continue = chars
580+
.find(|c| !rustc_lexer::is_id_continue(*c))
581+
.expect("InvalidIdentReason: cannot find invalid ident reason");
582+
InvalidIdentReason::InvalidContinue { symbol, not_continue }
583+
} else {
584+
InvalidIdentReason::InvalidStart { symbol, start }
585+
}
586+
} else {
587+
InvalidIdentReason::Empty
588+
}
589+
}
590+
}
548591
}
549592

550593
#[derive(Diagnostic)]

compiler/rustc_expand/src/mbe/transcribe.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ use rustc_span::{
1818
use smallvec::{SmallVec, smallvec};
1919

2020
use crate::errors::{
21-
CountRepetitionMisplaced, MacroVarStillRepeating, MetaVarsDifSeqMatchers, MustRepeatOnce,
22-
MveUnrecognizedVar, NoRepeatableVar, NoSyntaxVarsExprRepeat, VarNoTypo,
23-
VarTypoSuggestionRepeatable, VarTypoSuggestionUnrepeatable, VarTypoSuggestionUnrepeatableLabel,
21+
ConcatInvalidIdent, CountRepetitionMisplaced, InvalidIdentReason, MacroVarStillRepeating,
22+
MetaVarsDifSeqMatchers, MustRepeatOnce, MveUnrecognizedVar, NoRepeatableVar,
23+
NoSyntaxVarsExprRepeat, VarNoTypo, VarTypoSuggestionRepeatable, VarTypoSuggestionUnrepeatable,
24+
VarTypoSuggestionUnrepeatableLabel,
2425
};
2526
use crate::mbe::macro_parser::NamedMatch;
2627
use crate::mbe::macro_parser::NamedMatch::*;
@@ -656,10 +657,10 @@ fn metavar_expr_concat<'tx>(
656657
let symbol = nfc_normalize(&concatenated);
657658
let concatenated_span = tscx.visited_dspan(dspan);
658659
if !rustc_lexer::is_ident(symbol.as_str()) {
659-
return Err(dcx.struct_span_err(
660-
concatenated_span,
661-
"`${concat(..)}` is not generating a valid identifier",
662-
));
660+
return Err(dcx.create_err(ConcatInvalidIdent {
661+
span: concatenated_span,
662+
reason: InvalidIdentReason::new(symbol),
663+
}));
663664
}
664665
tscx.psess.symbol_gallery.insert(symbol, concatenated_span);
665666

tests/ui/macros/metavar-expressions/concat-trace-errors.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,28 @@ macro_rules! post_expansion {
1616
($a:literal) => {
1717
const _: () = ${concat("hi", $a, "bye")};
1818
//~^ ERROR is not generating a valid identifier
19+
//~| NOTE this `${concat(..)}` invocation generated `hi!bye`, but '!' is not XID_Continue
20+
//~| NOTE see <https://doc.rust-lang.org/reference/identifiers.html> for the definition of valid identifiers
1921
}
2022
}
2123

2224
post_expansion!("!");
25+
//~^ NOTE in this expansion of post_expansion!
26+
//~| NOTE in this expansion of post_expansion!
27+
//~| NOTE in this expansion of post_expansion!
2328

2429
macro_rules! post_expansion_many {
2530
($a:ident, $b:ident, $c:ident, $d:literal, $e:ident) => {
2631
const _: () = ${concat($a, $b, $c, $d, $e)};
2732
//~^ ERROR is not generating a valid identifier
33+
//~| NOTE this `${concat(..)}` invocation generated `abc.de`, but '.' is not XID_Continue
34+
//~| NOTE see <https://doc.rust-lang.org/reference/identifiers.html> for the definition of valid identifiers
2835
}
2936
}
3037

3138
post_expansion_many!(a, b, c, ".d", e);
39+
//~^ NOTE in this expansion of post_expansion_many!
40+
//~| NOTE in this expansion of post_expansion_many!
41+
//~| NOTE in this expansion of post_expansion_many!
3242

3343
fn main() {}

tests/ui/macros/metavar-expressions/concat-trace-errors.stderr

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,21 @@ LL | const _: () = ${concat("hi", $a, "bye")};
77
LL | post_expansion!("!");
88
| -------------------- in this macro invocation
99
|
10+
= note: this `${concat(..)}` invocation generated `hi!bye`, but '!' is not XID_Continue
11+
= note: see <https://doc.rust-lang.org/reference/identifiers.html> for the definition of valid identifiers
1012
= note: this error originates in the macro `post_expansion` (in Nightly builds, run with -Z macro-backtrace for more info)
1113

1214
error: `${concat(..)}` is not generating a valid identifier
13-
--> $DIR/concat-trace-errors.rs:26:24
15+
--> $DIR/concat-trace-errors.rs:31:24
1416
|
1517
LL | const _: () = ${concat($a, $b, $c, $d, $e)};
1618
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1719
...
1820
LL | post_expansion_many!(a, b, c, ".d", e);
1921
| -------------------------------------- in this macro invocation
2022
|
23+
= note: this `${concat(..)}` invocation generated `abc.de`, but '.' is not XID_Continue
24+
= note: see <https://doc.rust-lang.org/reference/identifiers.html> for the definition of valid identifiers
2125
= note: this error originates in the macro `post_expansion_many` (in Nightly builds, run with -Z macro-backtrace for more info)
2226

2327
error: aborting due to 2 previous errors

tests/ui/macros/metavar-expressions/concat-usage-errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//@ edition: 2021
2+
//@ dont-require-annotations: NOTE
23

34
#![feature(macro_metavar_expr_concat)]
45

@@ -43,6 +44,7 @@ macro_rules! starting_number {
4344
($ident:ident) => {{
4445
let ${concat("1", $ident)}: () = ();
4546
//~^ ERROR `${concat(..)}` is not generating a valid identifier
47+
//~| NOTE this `${concat(..)}` invocation generated `1_abc`, but '1' is neither '_' nor XID_Start
4648
}};
4749
}
4850

@@ -56,6 +58,8 @@ macro_rules! starting_invalid_unicode {
5658
($ident:ident) => {{
5759
let ${concat("\u{00BD}", $ident)}: () = ();
5860
//~^ ERROR `${concat(..)}` is not generating a valid identifier
61+
//~| NOTE this `${concat(..)}` invocation generated `\u{00BD}_abc`, but '\' is neither '_' nor XID_Start
62+
//~| NOTE see <https://doc.rust-lang.org/reference/identifiers.html> for the definition of valid identifiers
5963
}};
6064
}
6165

@@ -75,13 +79,15 @@ macro_rules! ending_invalid_unicode {
7579
($ident:ident) => {{
7680
let ${concat($ident, "\u{00BD}")}: () = ();
7781
//~^ ERROR `${concat(..)}` is not generating a valid identifier
82+
//~| NOTE this `${concat(..)}` invocation generated `_abc\u{00BD}`, but '\' is not XID_Continue
7883
}};
7984
}
8085

8186
macro_rules! empty {
8287
() => {{
8388
let ${concat("", "")}: () = ();
8489
//~^ ERROR `${concat(..)}` is not generating a valid identifier
90+
//~| NOTE this `${concat(..)}` invocation generated an empty ident
8591
}};
8692
}
8793

@@ -130,6 +136,8 @@ macro_rules! bad_literal_string {
130136
//~| ERROR `${concat(..)}` is not generating a valid identifier
131137
//~| ERROR `${concat(..)}` is not generating a valid identifier
132138
//~| ERROR `${concat(..)}` is not generating a valid identifier
139+
//~| NOTE this `${concat(..)}` invocation generated `_foo🤷`, but '🤷' is not XID_Continue
140+
//~| NOTE this `${concat(..)}` invocation generated `_foo-1`, but '-' is not XID_Continue
133141
}
134142
}
135143

0 commit comments

Comments
 (0)