about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
authorXiretza <xiretza@xiretza.xyz>2022-09-04 10:14:00 +0200
committerXiretza <xiretza@xiretza.xyz>2022-09-27 20:29:19 +0200
commit7507ee29fcee3dea2819dc113434ba97d7716422 (patch)
tree30d3296dc6a862f16ee69166ab2a30695740cc44 /compiler/rustc_parse/src/parser
parent21b5194a3a0ff5179d4afb6886fc8816243574f0 (diff)
downloadrust-7507ee29fcee3dea2819dc113434ba97d7716422.tar.gz
rust-7507ee29fcee3dea2819dc113434ba97d7716422.zip
Migrate "expected identifier" diagnostics to diagnostic structs
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs54
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs48
2 files changed, 60 insertions, 42 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 326b2553eaf..8c2a925a231 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -4,8 +4,9 @@ use super::{
     TokenExpectType, TokenType,
 };
 use crate::errors::{
-    AmbiguousPlus, BadQPathStage2, BadTypePlus, BadTypePlusSub, InInTypo, IncorrectAwait,
-    IncorrectSemicolon, IncorrectUseOfAwait, UseEqInstead,
+    AmbiguousPlus, BadQPathStage2, BadTypePlus, BadTypePlusSub, ExpectedIdentifier, InInTypo,
+    IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, SuggEscapeToUseAsIdentifier,
+    SuggRemoveComma, UseEqInstead,
 };
 
 use crate::lexer::UnmatchedBrace;
@@ -23,7 +24,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{
     fluent, Applicability, DiagnosticBuilder, DiagnosticMessage, Handler, MultiSpan, PResult,
 };
-use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed};
+use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed, IntoDiagnostic};
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::{Span, SpanSnippetError, DUMMY_SP};
@@ -285,10 +286,6 @@ impl<'a> Parser<'a> {
     }
 
     pub(super) fn expected_ident_found(&self) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
-        let mut err = self.struct_span_err(
-            self.token.span,
-            &format!("expected identifier, found {}", super::token_descr(&self.token)),
-        );
         let valid_follow = &[
             TokenKind::Eq,
             TokenKind::Colon,
@@ -300,34 +297,33 @@ impl<'a> Parser<'a> {
             TokenKind::CloseDelim(Delimiter::Brace),
             TokenKind::CloseDelim(Delimiter::Parenthesis),
         ];
-        match self.token.ident() {
+        let suggest_raw = match self.token.ident() {
             Some((ident, false))
                 if ident.is_raw_guess()
                     && self.look_ahead(1, |t| valid_follow.contains(&t.kind)) =>
             {
-                err.span_suggestion_verbose(
-                    ident.span.shrink_to_lo(),
-                    &format!("escape `{}` to use it as an identifier", ident.name),
-                    "r#",
-                    Applicability::MaybeIncorrect,
-                );
+                Some(SuggEscapeToUseAsIdentifier {
+                    span: ident.span.shrink_to_lo(),
+                    ident_name: ident.name.to_string(),
+                })
             }
-            _ => {}
-        }
-        if let Some(token_descr) = super::token_descr_opt(&self.token) {
-            err.span_label(self.token.span, format!("expected identifier, found {}", token_descr));
-        } else {
-            err.span_label(self.token.span, "expected identifier");
+            _ => None,
+        };
+
+        let suggest_remove_comma =
             if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) {
-                err.span_suggestion(
-                    self.token.span,
-                    "remove this comma",
-                    "",
-                    Applicability::MachineApplicable,
-                );
-            }
-        }
-        err
+                Some(SuggRemoveComma { span: self.token.span })
+            } else {
+                None
+            };
+
+        let err = ExpectedIdentifier {
+            span: self.token.span,
+            token_descr: super::token_descr_struct(&self.token),
+            suggest_raw,
+            suggest_remove_comma,
+        };
+        err.into_diagnostic(&self.sess.span_diagnostic)
     }
 
     pub(super) fn expected_one_of_not_found(
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 07fa909e71b..a1a224e8524 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -410,22 +410,44 @@ pub enum FollowedByType {
     No,
 }
 
-fn token_descr_opt(token: &Token) -> Option<&'static str> {
-    Some(match token.kind {
-        _ if token.is_special_ident() => "reserved identifier",
-        _ if token.is_used_keyword() => "keyword",
-        _ if token.is_unused_keyword() => "reserved keyword",
-        token::DocComment(..) => "doc comment",
-        _ => return None,
-    })
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub enum TokenDescriptionKind {
+    ReservedIdentifier,
+    Keyword,
+    ReservedKeyword,
+    DocComment,
+}
+
+#[derive(Clone, PartialEq, Eq)]
+pub struct TokenDescription {
+    pub kind: Option<TokenDescriptionKind>,
+    pub name: String,
+}
+
+pub(super) fn token_descr_struct(token: &Token) -> TokenDescription {
+    let kind = match token.kind {
+        _ if token.is_special_ident() => Some(TokenDescriptionKind::ReservedIdentifier),
+        _ if token.is_used_keyword() => Some(TokenDescriptionKind::Keyword),
+        _ if token.is_unused_keyword() => Some(TokenDescriptionKind::ReservedKeyword),
+        token::DocComment(..) => Some(TokenDescriptionKind::DocComment),
+        _ => None,
+    };
+    let name = pprust::token_to_string(token).to_string();
+
+    TokenDescription { kind, name }
 }
 
 pub(super) fn token_descr(token: &Token) -> String {
-    let token_str = pprust::token_to_string(token);
-    match token_descr_opt(token) {
-        Some(prefix) => format!("{} `{}`", prefix, token_str),
-        _ => format!("`{}`", token_str),
-    }
+    let TokenDescription { kind, name } = token_descr_struct(token);
+
+    let kind = kind.map(|kind| match kind {
+        TokenDescriptionKind::ReservedIdentifier => "reserved identifier",
+        TokenDescriptionKind::Keyword => "keyword",
+        TokenDescriptionKind::ReservedKeyword => "reserved keyword",
+        TokenDescriptionKind::DocComment => "doc comment",
+    });
+
+    if let Some(kind) = kind { format!("{} `{}`", kind, name) } else { format!("`{}`", name) }
 }
 
 impl<'a> Parser<'a> {