about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs50
-rw-r--r--src/test/ui/consts/const-tup-index-span.stderr4
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple-errors.rs6
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple-errors.stderr25
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple.fixed6
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple.rs6
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple.stderr43
-rw-r--r--src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr6
8 files changed, 119 insertions, 27 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 1eb8190bd7d..c5da9977db7 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2044,19 +2044,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                         // If a tuple of length one was expected and the found expression has
                         // parentheses around it, perhaps the user meant to write `(expr,)` to
                         // build a tuple (issue #86100)
-                        (ty::Tuple(_), _) if expected.tuple_fields().count() == 1 => {
-                            if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) {
-                                if let Some(code) =
-                                    code.strip_prefix('(').and_then(|s| s.strip_suffix(')'))
-                                {
-                                    err.span_suggestion(
-                                        span,
-                                        "use a trailing comma to create a tuple with one element",
-                                        format!("({},)", code),
-                                        Applicability::MaybeIncorrect,
-                                    );
-                                }
-                            }
+                        (ty::Tuple(_), _) => {
+                            self.emit_tuple_wrap_err(&mut err, span, found, expected)
                         }
                         // If a character was expected and the found expression is a string literal
                         // containing a single character, perhaps the user meant to write `'c'` to
@@ -2119,6 +2108,41 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         diag
     }
 
+    fn emit_tuple_wrap_err(
+        &self,
+        err: &mut DiagnosticBuilder<'tcx>,
+        span: Span,
+        found: Ty<'tcx>,
+        expected: Ty<'tcx>,
+    ) {
+        let [expected_tup_elem] = &expected.tuple_fields().collect::<Vec<_>>()[..]
+            else { return };
+
+        if !same_type_modulo_infer(expected_tup_elem, found) {
+            return;
+        }
+
+        let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
+            else { return };
+
+        let msg = "use a trailing comma to create a tuple with one element";
+        if code.starts_with('(') && code.ends_with(')') {
+            let before_close = span.hi() - BytePos::from_u32(1);
+            err.span_suggestion(
+                span.with_hi(before_close).shrink_to_hi(),
+                msg,
+                ",".into(),
+                Applicability::MachineApplicable,
+            );
+        } else {
+            err.multipart_suggestion(
+                msg,
+                vec![(span.shrink_to_lo(), "(".into()), (span.shrink_to_hi(), ",)".into())],
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+
     fn values_str(
         &self,
         values: ValuePairs<'tcx>,
diff --git a/src/test/ui/consts/const-tup-index-span.stderr b/src/test/ui/consts/const-tup-index-span.stderr
index 6724984d8d7..d301f8c4054 100644
--- a/src/test/ui/consts/const-tup-index-span.stderr
+++ b/src/test/ui/consts/const-tup-index-span.stderr
@@ -6,6 +6,10 @@ LL | const TUP: (usize,) = 5usize << 64;
    |
    = note: expected tuple `(usize,)`
                found type `usize`
+help: use a trailing comma to create a tuple with one element
+   |
+LL | const TUP: (usize,) = (5usize << 64,);
+   |                       +            ++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/args-instead-of-tuple-errors.rs b/src/test/ui/suggestions/args-instead-of-tuple-errors.rs
index 2c3ee5fcb80..5403b8d6d28 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple-errors.rs
+++ b/src/test/ui/suggestions/args-instead-of-tuple-errors.rs
@@ -10,6 +10,12 @@ fn main() {
 
     let _: Option<(i8,)> = Some();
     //~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
+
+    let _: Option<(i32,)> = Some(5_usize);
+    //~^ ERROR mismatched types
+
+    let _: Option<(i32,)> = Some((5_usize));
+    //~^ ERROR mismatched types
 }
 
 fn int_bool(_: (i32, bool)) {
diff --git a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
index a2ad602dbd4..ddcdfb1c3b3 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
+++ b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
@@ -15,7 +15,7 @@ LL |     int_bool(1, 2);
    |     expected 1 argument
    |
 note: function defined here
-  --> $DIR/args-instead-of-tuple-errors.rs:15:4
+  --> $DIR/args-instead-of-tuple-errors.rs:21:4
    |
 LL | fn int_bool(_: (i32, bool)) {
    |    ^^^^^^^^ --------------
@@ -28,6 +28,25 @@ LL |     let _: Option<(i8,)> = Some();
    |                            |
    |                            expected 1 argument
 
-error: aborting due to 3 previous errors
+error[E0308]: mismatched types
+  --> $DIR/args-instead-of-tuple-errors.rs:14:34
+   |
+LL |     let _: Option<(i32,)> = Some(5_usize);
+   |                                  ^^^^^^^ expected tuple, found `usize`
+   |
+   = note: expected tuple `(i32,)`
+               found type `usize`
+
+error[E0308]: mismatched types
+  --> $DIR/args-instead-of-tuple-errors.rs:17:34
+   |
+LL |     let _: Option<(i32,)> = Some((5_usize));
+   |                                  ^^^^^^^^^ expected tuple, found `usize`
+   |
+   = note: expected tuple `(i32,)`
+               found type `usize`
+
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0061`.
+Some errors have detailed explanations: E0061, E0308.
+For more information about an error, try `rustc --explain E0061`.
diff --git a/src/test/ui/suggestions/args-instead-of-tuple.fixed b/src/test/ui/suggestions/args-instead-of-tuple.fixed
index c9b8a41d469..66e53f9ce2c 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple.fixed
+++ b/src/test/ui/suggestions/args-instead-of-tuple.fixed
@@ -11,6 +11,12 @@ fn main() {
     let _: Option<()> = Some(());
     //~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
 
+    let _: Option<(i32,)> = Some((3,));
+    //~^ ERROR mismatched types
+
+    let _: Option<(i32,)> = Some((3,));
+    //~^ ERROR mismatched types
+
     two_ints((1, 2)); //~ ERROR this function takes 1 argument
 
     with_generic((3, 4)); //~ ERROR this function takes 1 argument
diff --git a/src/test/ui/suggestions/args-instead-of-tuple.rs b/src/test/ui/suggestions/args-instead-of-tuple.rs
index d4cc3024dd0..a15bff07ebf 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple.rs
+++ b/src/test/ui/suggestions/args-instead-of-tuple.rs
@@ -11,6 +11,12 @@ fn main() {
     let _: Option<()> = Some();
     //~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
 
+    let _: Option<(i32,)> = Some(3);
+    //~^ ERROR mismatched types
+
+    let _: Option<(i32,)> = Some((3));
+    //~^ ERROR mismatched types
+
     two_ints(1, 2); //~ ERROR this function takes 1 argument
 
     with_generic(3, 4); //~ ERROR this function takes 1 argument
diff --git a/src/test/ui/suggestions/args-instead-of-tuple.stderr b/src/test/ui/suggestions/args-instead-of-tuple.stderr
index 172db7ee3df..6a7602c9d0f 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple.stderr
+++ b/src/test/ui/suggestions/args-instead-of-tuple.stderr
@@ -31,14 +31,40 @@ help: expected the unit value `()`; create it with empty parentheses
 LL |     let _: Option<()> = Some(());
    |                              ++
 
+error[E0308]: mismatched types
+  --> $DIR/args-instead-of-tuple.rs:14:34
+   |
+LL |     let _: Option<(i32,)> = Some(3);
+   |                                  ^ expected tuple, found integer
+   |
+   = note: expected tuple `(i32,)`
+               found type `{integer}`
+help: use a trailing comma to create a tuple with one element
+   |
+LL |     let _: Option<(i32,)> = Some((3,));
+   |                                  + ++
+
+error[E0308]: mismatched types
+  --> $DIR/args-instead-of-tuple.rs:17:34
+   |
+LL |     let _: Option<(i32,)> = Some((3));
+   |                                  ^^^ expected tuple, found integer
+   |
+   = note: expected tuple `(i32,)`
+               found type `{integer}`
+help: use a trailing comma to create a tuple with one element
+   |
+LL |     let _: Option<(i32,)> = Some((3,));
+   |                                    +
+
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
-  --> $DIR/args-instead-of-tuple.rs:14:5
+  --> $DIR/args-instead-of-tuple.rs:20:5
    |
 LL |     two_ints(1, 2);
    |     ^^^^^^^^ -  - supplied 2 arguments
    |
 note: function defined here
-  --> $DIR/args-instead-of-tuple.rs:19:4
+  --> $DIR/args-instead-of-tuple.rs:25:4
    |
 LL | fn two_ints(_: (i32, i32)) {
    |    ^^^^^^^^ -------------
@@ -48,13 +74,13 @@ LL |     two_ints((1, 2));
    |              +    +
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
-  --> $DIR/args-instead-of-tuple.rs:16:5
+  --> $DIR/args-instead-of-tuple.rs:22:5
    |
 LL |     with_generic(3, 4);
    |     ^^^^^^^^^^^^ -  - supplied 2 arguments
    |
 note: function defined here
-  --> $DIR/args-instead-of-tuple.rs:22:4
+  --> $DIR/args-instead-of-tuple.rs:28:4
    |
 LL | fn with_generic<T: Copy + Send>((a, b): (i32, T)) {
    |    ^^^^^^^^^^^^                 ----------------
@@ -64,13 +90,13 @@ LL |     with_generic((3, 4));
    |                  +    +
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
-  --> $DIR/args-instead-of-tuple.rs:25:9
+  --> $DIR/args-instead-of-tuple.rs:31:9
    |
 LL |         with_generic(a, b);
    |         ^^^^^^^^^^^^ -  - supplied 2 arguments
    |
 note: function defined here
-  --> $DIR/args-instead-of-tuple.rs:22:4
+  --> $DIR/args-instead-of-tuple.rs:28:4
    |
 LL | fn with_generic<T: Copy + Send>((a, b): (i32, T)) {
    |    ^^^^^^^^^^^^                 ----------------
@@ -79,6 +105,7 @@ help: use parentheses to construct a tuple
 LL |         with_generic((a, b));
    |                      +    +
 
-error: aborting due to 6 previous errors
+error: aborting due to 8 previous errors
 
-For more information about this error, try `rustc --explain E0061`.
+Some errors have detailed explanations: E0061, E0308.
+For more information about an error, try `rustc --explain E0061`.
diff --git a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
index 9c8356a5284..0016f192842 100644
--- a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
+++ b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
@@ -11,7 +11,7 @@ LL |     let _x: (i32,) = (5);
 help: use a trailing comma to create a tuple with one element
    |
 LL |     let _x: (i32,) = (5,);
-   |                      ~~~~
+   |                        +
 
 error[E0308]: mismatched types
   --> $DIR/issue-86100-tuple-paren-comma.rs:13:9
@@ -24,7 +24,7 @@ LL |     foo((Some(3)));
 help: use a trailing comma to create a tuple with one element
    |
 LL |     foo((Some(3),));
-   |         ~~~~~~~~~~
+   |                 +
 
 error[E0308]: mismatched types
   --> $DIR/issue-86100-tuple-paren-comma.rs:17:22
@@ -37,7 +37,7 @@ LL |     let _s = S { _s: ("abc".to_string()) };
 help: use a trailing comma to create a tuple with one element
    |
 LL |     let _s = S { _s: ("abc".to_string(),) };
-   |                      ~~~~~~~~~~~~~~~~~~~~
+   |                                        +
 
 error[E0308]: mismatched types
   --> $DIR/issue-86100-tuple-paren-comma.rs:23:22