From 1c829877824aeda82e78ed3a0ecb12a3cb0b2d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 21 Aug 2019 11:46:31 -0700 Subject: [PATCH 1/3] Fix typo in E0308 if/else label --- src/librustc/infer/error_reporting/mod.rs | 2 +- src/librustc/ty/error.rs | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 84687b8cab5c0..9be73cf3c6d16 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1650,7 +1650,7 @@ impl<'tcx> ObligationCause<'tcx> { hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types", _ => "match arms have compatible types", }, - IfExpression { .. } => "if and else have compatible types", + IfExpression { .. } => "if and else have incompatible types", IfExpressionWithNoElse => "if missing an else returns ()", MainFunctionType => "`main` function has the correct type", StartFunctionType => "`start` function has the correct type", diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index d6d17a67e01e9..6daecd7ae941a 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -247,13 +247,15 @@ impl<'tcx> ty::TyS<'tcx> { } impl<'tcx> TyCtxt<'tcx> { - pub fn note_and_explain_type_err(self, - db: &mut DiagnosticBuilder<'_>, - err: &TypeError<'tcx>, - sp: Span) { + pub fn note_and_explain_type_err( + self, + db: &mut DiagnosticBuilder<'_>, + err: &TypeError<'tcx>, + sp: Span, + ) { use self::TypeError::*; - match err.clone() { + match err { Sorts(values) => { let expected_str = values.expected.sort_string(self); let found_str = values.found.sort_string(self); @@ -261,6 +263,15 @@ impl<'tcx> TyCtxt<'tcx> { db.note("no two closures, even if identical, have the same type"); db.help("consider boxing your closure and/or using it as a trait object"); } + if expected_str == found_str && expected_str == "opaque type" { // Issue #63167 + db.note("distinct uses of `impl Trait` result in different opaque types"); + let e_str = values.expected.to_string(); + let f_str = values.found.to_string(); + if &e_str == &f_str && &e_str == "impl std::future::Future" { + db.help("if both futures resolve to the same type, consider `await`ing \ + on both of them"); + } + } if let (ty::Infer(ty::IntVar(_)), ty::Float(_)) = (&values.found.sty, &values.expected.sty) // Issue #53280 { From ba8e09415b00fdfcda8feeb1cf233f2f065ef6c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 21 Aug 2019 11:49:51 -0700 Subject: [PATCH 2/3] Add clarification on E0308 about opaque types --- src/librustc/ty/error.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 6daecd7ae941a..c1593799286ef 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -268,6 +268,7 @@ impl<'tcx> TyCtxt<'tcx> { let e_str = values.expected.to_string(); let f_str = values.found.to_string(); if &e_str == &f_str && &e_str == "impl std::future::Future" { + // FIXME: use non-string based check. db.help("if both futures resolve to the same type, consider `await`ing \ on both of them"); } From a710c610b2ea1550014e9f6bd20e5e4aed8a716c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 21 Aug 2019 15:35:38 -0700 Subject: [PATCH 3/3] review comments: reword and add test --- src/librustc/ty/error.rs | 4 ++-- src/test/ui/suggestions/opaque-type-error.rs | 24 +++++++++++++++++++ .../ui/suggestions/opaque-type-error.stderr | 20 ++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/suggestions/opaque-type-error.rs create mode 100644 src/test/ui/suggestions/opaque-type-error.stderr diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index c1593799286ef..c70006b68d69a 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -269,8 +269,8 @@ impl<'tcx> TyCtxt<'tcx> { let f_str = values.found.to_string(); if &e_str == &f_str && &e_str == "impl std::future::Future" { // FIXME: use non-string based check. - db.help("if both futures resolve to the same type, consider `await`ing \ - on both of them"); + db.help("if both `Future`s have the same `Output` type, consider \ + `.await`ing on both of them"); } } if let (ty::Infer(ty::IntVar(_)), ty::Float(_)) = diff --git a/src/test/ui/suggestions/opaque-type-error.rs b/src/test/ui/suggestions/opaque-type-error.rs new file mode 100644 index 0000000000000..979bb60d48c12 --- /dev/null +++ b/src/test/ui/suggestions/opaque-type-error.rs @@ -0,0 +1,24 @@ +// edition:2018 +use core::future::Future; + +async fn base_thing() -> Result<(), ()> { + Ok(()) +} + +fn thing_one() -> impl Future> { + base_thing() +} + +fn thing_two() -> impl Future> { + base_thing() +} + +async fn thing() -> Result<(), ()> { + if true { + thing_one() + } else { + thing_two() //~ ERROR if and else have incompatible types + }.await +} + +fn main() {} diff --git a/src/test/ui/suggestions/opaque-type-error.stderr b/src/test/ui/suggestions/opaque-type-error.stderr new file mode 100644 index 0000000000000..3c9ea05aeceb2 --- /dev/null +++ b/src/test/ui/suggestions/opaque-type-error.stderr @@ -0,0 +1,20 @@ +error[E0308]: if and else have incompatible types + --> $DIR/opaque-type-error.rs:20:9 + | +LL | / if true { +LL | | thing_one() + | | ----------- expected because of this +LL | | } else { +LL | | thing_two() + | | ^^^^^^^^^^^ expected opaque type, found a different opaque type +LL | | }.await + | |_____- if and else have incompatible types + | + = note: expected type `impl std::future::Future` (opaque type) + found type `impl std::future::Future` (opaque type) + = note: distinct uses of `impl Trait` result in different opaque types + = help: if both `Future`s have the same `Output` type, consider `.await`ing on both of them + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`.