about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamelid <camelidcamel@gmail.com>2020-12-18 19:51:39 -0800
committerCamelid <camelidcamel@gmail.com>2021-01-12 19:25:50 -0800
commitf3d9df54ee682d0b76909d27938b30c51ca5ec70 (patch)
tree495a604937423119d89d260d64ee29b28b91eae3
parent5fe61a79cc5d26a0843b7169d1c95fbb3cbda0ba (diff)
downloadrust-f3d9df54ee682d0b76909d27938b30c51ca5ec70.tar.gz
rust-f3d9df54ee682d0b76909d27938b30c51ca5ec70.zip
Suggest `Variant(..)` if all of the mentioned fields are `_`
-rw-r--r--compiler/rustc_typeck/src/check/pat.rs33
-rw-r--r--src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr8
-rw-r--r--src/test/ui/match/match-pattern-field-mismatch.stderr4
-rw-r--r--src/test/ui/pattern/pat-tuple-underfield.stderr8
4 files changed, 34 insertions, 19 deletions
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index db2f4eca0c9..474aed39eb2 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -20,7 +20,6 @@ use rustc_trait_selection::traits::{ObligationCause, Pattern};
 
 use std::cmp;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
-use std::iter;
 
 use super::report_unexpected_variant_res;
 
@@ -1048,26 +1047,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             } else {
                 pat_span.with_hi(pat_span.hi() - BytePos(1)).shrink_to_hi()
             };
+            let all_fields_span = match subpats {
+                [] => after_fields_span,
+                [field] => field.span,
+                [first, .., last] => first.span.to(last.span),
+            };
+
+            // Check if all the fields in the pattern are wildcards.
+            let all_wildcards = subpats.iter().all(|pat| matches!(pat.kind, PatKind::Wild));
 
             let mut wildcard_sugg = vec!["_"; fields.len() - subpats.len()].join(", ");
             if !subpats.is_empty() {
                 wildcard_sugg = String::from(", ") + &wildcard_sugg;
             }
 
-            let rest_sugg = if subpats.is_empty() { "..".to_owned() } else { ", ..".to_owned() };
-
             err.span_suggestion(
                 after_fields_span,
                 "use `_` to explicitly ignore each field",
                 wildcard_sugg,
                 Applicability::MaybeIncorrect,
             );
-            err.span_suggestion(
-                after_fields_span,
-                "use `..` to ignore all unmentioned fields",
-                rest_sugg,
-                Applicability::MaybeIncorrect,
-            );
+
+            if subpats.is_empty() || all_wildcards {
+                err.span_suggestion(
+                    all_fields_span,
+                    "use `..` to ignore all unmentioned fields",
+                    String::from(".."),
+                    Applicability::MaybeIncorrect,
+                );
+            } else {
+                err.span_suggestion(
+                    after_fields_span,
+                    "use `..` to ignore all unmentioned fields",
+                    String::from(", .."),
+                    Applicability::MaybeIncorrect,
+                );
+            }
         }
 
         err.emit();
diff --git a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
index 623e1d674d7..dd1fbbbd3bb 100644
--- a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
+++ b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
@@ -38,8 +38,8 @@ LL |     TupleStruct(_, _) = TupleStruct(1, 2);
    |                  ^^^
 help: use `..` to ignore all unmentioned fields
    |
-LL |     TupleStruct(_, ..) = TupleStruct(1, 2);
-   |                  ^^^^
+LL |     TupleStruct(..) = TupleStruct(1, 2);
+   |                 ^^
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
   --> $DIR/tuple_struct_destructure_fail.rs:34:5
@@ -65,8 +65,8 @@ LL |     Enum::SingleVariant(_, _) = Enum::SingleVariant(1, 2);
    |                          ^^^
 help: use `..` to ignore all unmentioned fields
    |
-LL |     Enum::SingleVariant(_, ..) = Enum::SingleVariant(1, 2);
-   |                          ^^^^
+LL |     Enum::SingleVariant(..) = Enum::SingleVariant(1, 2);
+   |                         ^^
 
 error[E0070]: invalid left-hand side of assignment
   --> $DIR/tuple_struct_destructure_fail.rs:40:12
diff --git a/src/test/ui/match/match-pattern-field-mismatch.stderr b/src/test/ui/match/match-pattern-field-mismatch.stderr
index 299b2d216db..1ee45ca1b1e 100644
--- a/src/test/ui/match/match-pattern-field-mismatch.stderr
+++ b/src/test/ui/match/match-pattern-field-mismatch.stderr
@@ -13,8 +13,8 @@ LL |           Color::Rgb(_, _, _) => { }
    |                          ^^^
 help: use `..` to ignore all unmentioned fields
    |
-LL |           Color::Rgb(_, _, ..) => { }
-   |                          ^^^^
+LL |           Color::Rgb(..) => { }
+   |                      ^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/pat-tuple-underfield.stderr b/src/test/ui/pattern/pat-tuple-underfield.stderr
index 5364053b8e5..b7a54026639 100644
--- a/src/test/ui/pattern/pat-tuple-underfield.stderr
+++ b/src/test/ui/pattern/pat-tuple-underfield.stderr
@@ -40,8 +40,8 @@ LL |         S(_, _) => {}
    |            ^^^
 help: use `..` to ignore all unmentioned fields
    |
-LL |         S(_, ..) => {}
-   |            ^^^^
+LL |         S(..) => {}
+   |           ^^
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 2 fields
   --> $DIR/pat-tuple-underfield.rs:20:9
@@ -94,8 +94,8 @@ LL |         E::S(_, _) => {}
    |               ^^^
 help: use `..` to ignore all unmentioned fields
    |
-LL |         E::S(_, ..) => {}
-   |               ^^^^
+LL |         E::S(..) => {}
+   |              ^^
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 2 fields
   --> $DIR/pat-tuple-underfield.rs:39:9