Suggest a trailing comma if a 1-tuple is expected
This commit is contained in:
parent
e4a6032706
commit
6206247335
3 changed files with 108 additions and 1 deletions
|
@ -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)
|
||||||
|
|
25
src/test/ui/suggestions/issue-86100-tuple-paren-comma.rs
Normal file
25
src/test/ui/suggestions/issue-86100-tuple-paren-comma.rs
Normal 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]
|
||||||
|
}
|
55
src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
Normal file
55
src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
Normal 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`.
|
Loading…
Add table
Add a link
Reference in a new issue