1
Fork 0

Suggest a trailing comma if a 1-tuple is expected

This commit is contained in:
Fabian Wolff 2021-06-07 23:16:03 +02:00
parent e4a6032706
commit 6206247335
3 changed files with 108 additions and 1 deletions

View file

@ -64,6 +64,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_hir::{Item, ItemKind, Node}; use rustc_hir::{Item, ItemKind, Node};
use rustc_middle::dep_graph::DepContext;
use rustc_middle::ty::error::TypeError; use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, self,
@ -1965,7 +1966,33 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
struct_span_err!(self.tcx.sess, span, E0580, "{}", failure_str) struct_span_err!(self.tcx.sess, span, E0580, "{}", failure_str)
} }
FailureCode::Error0308(failure_str) => { FailureCode::Error0308(failure_str) => {
struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str) let mut err = struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str);
if let ValuePairs::Types(ty::error::ExpectedFound { expected, found }) =
trace.values
{
// 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)
match (expected.kind(), found.kind()) {
(ty::Tuple(_), ty::Tuple(_)) => {}
(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,
);
}
}
}
_ => {}
}
}
err
} }
FailureCode::Error0644(failure_str) => { FailureCode::Error0644(failure_str) => {
struct_span_err!(self.tcx.sess, span, E0644, "{}", failure_str) struct_span_err!(self.tcx.sess, span, E0644, "{}", failure_str)

View file

@ -0,0 +1,25 @@
// Tests that a suggestion is issued for type mismatch errors when a
// 1-tuple is expected and a parenthesized expression of non-tuple
// type is supplied.
fn foo<T>(_t: (T,)) {}
struct S { _s: (String,) }
fn main() {
let _x: (i32,) = (5);
//~^ ERROR: mismatched types [E0308]
//~| HELP: use a trailing comma to create a tuple with one element
foo((Some(3)));
//~^ ERROR: mismatched types [E0308]
//~| HELP: use a trailing comma to create a tuple with one element
let _s = S { _s: ("abc".to_string()) };
//~^ ERROR: mismatched types [E0308]
//~| HELP: use a trailing comma to create a tuple with one element
// Do not issue the suggestion if the found type is already a tuple.
let t = (1, 2);
let _x: (i32,) = (t);
//~^ ERROR: mismatched types [E0308]
}

View file

@ -0,0 +1,55 @@
error[E0308]: mismatched types
--> $DIR/issue-86100-tuple-paren-comma.rs:9:22
|
LL | let _x: (i32,) = (5);
| ------ ^^^ expected tuple, found integer
| |
| expected due to this
|
= note: expected tuple `(i32,)`
found type `{integer}`
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
|
LL | foo((Some(3)));
| ^^^^^^^^^ expected tuple, found enum `Option`
|
= note: expected tuple `(_,)`
found enum `Option<{integer}>`
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
|
LL | let _s = S { _s: ("abc".to_string()) };
| ^^^^^^^^^^^^^^^^^^^ expected tuple, found struct `String`
|
= note: expected tuple `(String,)`
found struct `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
|
LL | let _x: (i32,) = (t);
| ------ ^^^ expected a tuple with 1 element, found one with 2 elements
| |
| expected due to this
|
= note: expected tuple `(i32,)`
found tuple `({integer}, {integer})`
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0308`.