Skip to content

Commit ad7c621

Browse files
committed
Add invisible open delimiters to TokenDescription.
Invisible delimiters pretty-print as empty strings, and changing that can break some proc macros. But error messages saying "expected identifer, found ``" are bad. So this commit adds support for invisible open delimiters in `TokenDescription` so they print as "invisible open delimiter" in error messages, instead of "``". It's not used meaningfully yet, but will be needed to get rid of interpolated tokens.
1 parent eb03a6d commit ad7c621

File tree

3 files changed

+47
-8
lines changed

3 files changed

+47
-8
lines changed

compiler/rustc_parse/messages.ftl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ parse_expected_identifier = expected identifier
204204
205205
parse_expected_identifier_found_doc_comment = expected identifier, found doc comment
206206
parse_expected_identifier_found_doc_comment_str = expected identifier, found doc comment `{$token}`
207+
parse_expected_identifier_found_invisible_open_delim = expected identifier, found invisible open delimiter
208+
# Deliberately doesn't print `$token`, which is empty.
209+
parse_expected_identifier_found_invisible_open_delim_str = expected identifier, found invisible open delimiter
207210
parse_expected_identifier_found_keyword = expected identifier, found keyword
208211
parse_expected_identifier_found_keyword_str = expected identifier, found keyword `{$token}`
209212
parse_expected_identifier_found_reserved_identifier = expected identifier, found reserved identifier
@@ -216,6 +219,8 @@ parse_expected_mut_or_const_in_raw_pointer_type = expected `mut` or `const` keyw
216219
.suggestion = add `mut` or `const` here
217220
218221
parse_expected_semi_found_doc_comment_str = expected `;`, found doc comment `{$token}`
222+
# Deliberately doesn't print `$token`, which is empty.
223+
parse_expected_semi_found_invisible_open_delim_str = expected `;`, found invisible open delimiter
219224
parse_expected_semi_found_keyword_str = expected `;`, found keyword `{$token}`
220225
parse_expected_semi_found_reserved_identifier_str = expected `;`, found reserved identifier `{$token}`
221226
parse_expected_semi_found_reserved_keyword_str = expected `;`, found reserved keyword `{$token}`
@@ -797,6 +802,8 @@ parse_unexpected_token_after_not_default = use `!` to perform logical negation o
797802
parse_unexpected_token_after_not_logical = use `!` to perform logical negation
798803
parse_unexpected_token_after_struct_name = expected `where`, `{"{"}`, `(`, or `;` after struct name
799804
parse_unexpected_token_after_struct_name_found_doc_comment = expected `where`, `{"{"}`, `(`, or `;` after struct name, found doc comment `{$token}`
805+
# Deliberately doesn't print `$token`, which is empty.
806+
parse_unexpected_token_after_struct_name_found_invisible_open_delim = expected `where`, `{"{"}`, `(`, or `;` after struct name, found invisible open delim
800807
parse_unexpected_token_after_struct_name_found_keyword = expected `where`, `{"{"}`, `(`, or `;` after struct name, found keyword `{$token}`
801808
parse_unexpected_token_after_struct_name_found_other = expected `where`, `{"{"}`, `(`, or `;` after struct name, found `{$token}`
802809

compiler/rustc_parse/src/errors.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,8 @@ pub(crate) enum ExpectedIdentifierFound {
948948
#[label(parse_expected_identifier_found_doc_comment)]
949949
DocComment(#[primary_span] Span),
950950
#[label(parse_expected_identifier)]
951+
InvisibleOpenDelim(#[primary_span] Span),
952+
#[label(parse_expected_identifier)]
951953
Other(#[primary_span] Span),
952954
}
953955

@@ -960,6 +962,9 @@ impl ExpectedIdentifierFound {
960962
Some(TokenDescription::Keyword) => ExpectedIdentifierFound::Keyword,
961963
Some(TokenDescription::ReservedKeyword) => ExpectedIdentifierFound::ReservedKeyword,
962964
Some(TokenDescription::DocComment) => ExpectedIdentifierFound::DocComment,
965+
Some(TokenDescription::InvisibleOpenDelim) => {
966+
ExpectedIdentifierFound::InvisibleOpenDelim
967+
}
963968
None => ExpectedIdentifierFound::Other,
964969
})(span)
965970
}
@@ -992,6 +997,9 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
992997
Some(TokenDescription::DocComment) => {
993998
fluent::parse_expected_identifier_found_doc_comment_str
994999
}
1000+
Some(TokenDescription::InvisibleOpenDelim) => {
1001+
fluent::parse_expected_identifier_found_invisible_open_delim_str
1002+
}
9951003
None => fluent::parse_expected_identifier_found_str,
9961004
});
9971005
diag.set_span(self.span);
@@ -1047,6 +1055,9 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi {
10471055
fluent::parse_expected_semi_found_reserved_keyword_str
10481056
}
10491057
Some(TokenDescription::DocComment) => fluent::parse_expected_semi_found_doc_comment_str,
1058+
Some(TokenDescription::InvisibleOpenDelim) => {
1059+
fluent::parse_expected_semi_found_invisible_open_delim_str
1060+
}
10501061
None => fluent::parse_expected_semi_found_str,
10511062
});
10521063
diag.set_span(self.span);
@@ -1671,6 +1682,13 @@ pub(crate) enum UnexpectedTokenAfterStructName {
16711682
span: Span,
16721683
token: Token,
16731684
},
1685+
#[diag(parse_unexpected_token_after_struct_name_found_invisible_open_delim)]
1686+
InvisibleOpenDelim {
1687+
#[primary_span]
1688+
#[label(parse_unexpected_token_after_struct_name)]
1689+
span: Span,
1690+
token: Token,
1691+
},
16741692
#[diag(parse_unexpected_token_after_struct_name_found_other)]
16751693
Other {
16761694
#[primary_span]
@@ -1687,6 +1705,7 @@ impl UnexpectedTokenAfterStructName {
16871705
Some(TokenDescription::Keyword) => Self::Keyword { span, token },
16881706
Some(TokenDescription::ReservedKeyword) => Self::ReservedKeyword { span, token },
16891707
Some(TokenDescription::DocComment) => Self::DocComment { span, token },
1708+
Some(TokenDescription::InvisibleOpenDelim) => Self::InvisibleOpenDelim { span, token },
16901709
None => Self::Other { span, token },
16911710
}
16921711
}

compiler/rustc_parse/src/parser/mod.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,15 @@ pub enum TokenDescription {
346346
Keyword,
347347
ReservedKeyword,
348348
DocComment,
349+
350+
// Invisible delimiters aren't pretty-printed. But in error messages we
351+
// want to print something, otherwise we get confusing things in messages
352+
// like "expected `(`, found ``". It's better to say "expected `(`, found
353+
// invisible open delimiter".
354+
//
355+
// There has been no need for an `InvisibleCloseDelim` entry yet, but one
356+
// could be added if necessary.
357+
InvisibleOpenDelim,
349358
}
350359

351360
impl TokenDescription {
@@ -355,22 +364,26 @@ impl TokenDescription {
355364
_ if token.is_used_keyword() => Some(TokenDescription::Keyword),
356365
_ if token.is_unused_keyword() => Some(TokenDescription::ReservedKeyword),
357366
token::DocComment(..) => Some(TokenDescription::DocComment),
367+
token::OpenDelim(Delimiter::Invisible(_)) => Some(TokenDescription::InvisibleOpenDelim),
358368
_ => None,
359369
}
360370
}
361371
}
362372

363373
pub(super) fn token_descr(token: &Token) -> String {
364-
let name = pprust::token_to_string(token).to_string();
374+
use TokenDescription::*;
365375

366-
let kind = TokenDescription::from_token(token).map(|kind| match kind {
367-
TokenDescription::ReservedIdentifier => "reserved identifier",
368-
TokenDescription::Keyword => "keyword",
369-
TokenDescription::ReservedKeyword => "reserved keyword",
370-
TokenDescription::DocComment => "doc comment",
371-
});
376+
let s = pprust::token_to_string(token).to_string();
372377

373-
if let Some(kind) = kind { format!("{kind} `{name}`") } else { format!("`{name}`") }
378+
match TokenDescription::from_token(token) {
379+
Some(ReservedIdentifier) => format!("reserved identifier `{s}`"),
380+
Some(Keyword) => format!("keyword `{s}`"),
381+
Some(ReservedKeyword) => format!("reserved keyword `{s}`"),
382+
Some(DocComment) => format!("doc comment `{s}`"),
383+
// Deliberately doesn't print `s`, which is empty.
384+
Some(InvisibleOpenDelim) => "invisible open delimiter".to_string(),
385+
None => format!("`{s}`"),
386+
}
374387
}
375388

376389
impl<'a> Parser<'a> {

0 commit comments

Comments
 (0)