about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2021-03-17 09:49:46 +0900
committerYuki Okushi <huyuumi.dev@gmail.com>2021-03-17 09:57:58 +0900
commit2d99e68940087c7696a5d4919ba1456d6415fb9b (patch)
treeb2e3f753ad423017c7e43e19108a210f99e39f65 /compiler/rustc_parse/src/parser
parent8240f1a3d3f0ff3e36c19836ea4d783f29752b0b (diff)
downloadrust-2d99e68940087c7696a5d4919ba1456d6415fb9b.tar.gz
rust-2d99e68940087c7696a5d4919ba1456d6415fb9b.zip
Emit more pretty diagnostics for qualified paths
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs35
1 files changed, 21 insertions, 14 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 975b9cc15bd..77e85c06ff5 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -640,7 +640,7 @@ impl<'a> Parser<'a> {
                     }
                 }
                 Err(mut err) => {
-                    // We could't parse generic parameters, unlikely to be a turbofish. Rely on
+                    // We couldn't parse generic parameters, unlikely to be a turbofish. Rely on
                     // generic parse error instead.
                     err.cancel();
                     *self = snapshot;
@@ -1242,7 +1242,7 @@ impl<'a> Parser<'a> {
         let is_question = self.eat(&token::Question); // Handle `await? <expr>`.
         let expr = if self.token == token::OpenDelim(token::Brace) {
             // Handle `await { <expr> }`.
-            // This needs to be handled separatedly from the next arm to avoid
+            // This needs to be handled separately from the next arm to avoid
             // interpreting `await { <expr> }?` as `<expr>?.await`.
             self.parse_block_expr(None, self.token.span, BlockCheckMode::Default, AttrVec::new())
         } else {
@@ -1618,6 +1618,8 @@ impl<'a> Parser<'a> {
                 || self.token == token::Lt
                 || self.token == token::CloseDelim(token::Paren))
         {
+            let rfc_note = "anonymous parameters are removed in the 2018 edition (see RFC 1685)";
+
             let (ident, self_sugg, param_sugg, type_sugg) = match pat.kind {
                 PatKind::Ident(_, ident, _) => (
                     ident,
@@ -1626,7 +1628,9 @@ impl<'a> Parser<'a> {
                     format!("_: {}", ident),
                 ),
                 // Also catches `fn foo(&a)`.
-                PatKind::Ref(ref pat, mutab) => {
+                PatKind::Ref(ref pat, mutab)
+                    if matches!(pat.clone().into_inner().kind, PatKind::Ident(..)) =>
+                {
                     match pat.clone().into_inner().kind {
                         PatKind::Ident(_, ident, _) => {
                             let mutab = mutab.prefix_str();
@@ -1637,20 +1641,23 @@ impl<'a> Parser<'a> {
                                 format!("_: &{}{}", mutab, ident),
                             )
                         }
-                        PatKind::Path(..) => {
-                            err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
-                            return None;
-                        }
-                        _ => return None,
+                        _ => unreachable!(),
                     }
                 }
-                // Also catches `fn foo(<Bar as T>::Baz)`
-                PatKind::Path(..) => {
-                    err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
+                _ => {
+                    // Otherwise, try to get a type and emit a suggestion.
+                    if let Some(ty) = pat.to_ty() {
+                        err.span_suggestion_verbose(
+                            pat.span,
+                            "explicitly ignore the parameter name",
+                            format!("_: {}", pprust::ty_to_string(&ty)),
+                            Applicability::MachineApplicable,
+                        );
+                        err.note(rfc_note);
+                    }
+
                     return None;
                 }
-                // Ignore other `PatKind`.
-                _ => return None,
             };
 
             // `fn foo(a, b) {}`, `fn foo(a<x>, b<y>) {}` or `fn foo(usize, usize) {}`
@@ -1678,7 +1685,7 @@ impl<'a> Parser<'a> {
                 type_sugg,
                 Applicability::MachineApplicable,
             );
-            err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
+            err.note(rfc_note);
 
             // Don't attempt to recover by using the `X` in `X<Y>` as the parameter name.
             return if self.token == token::Lt { None } else { Some(ident) };