Skip to content

Tweak E0308 on opaque types #63796

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
22 changes: 17 additions & 5 deletions src/librustc/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,20 +247,32 @@ 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);
if expected_str == found_str && expected_str == "closure" {
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" {
// FIXME: use non-string based check.
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(_)) =
(&values.found.sty, &values.expected.sty) // Issue #53280
{
Expand Down
24 changes: 24 additions & 0 deletions src/test/ui/suggestions/opaque-type-error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// edition:2018
use core::future::Future;

async fn base_thing() -> Result<(), ()> {
Ok(())
}

fn thing_one() -> impl Future<Output = Result<(), ()>> {
base_thing()
}

fn thing_two() -> impl Future<Output = Result<(), ()>> {
base_thing()
}

async fn thing() -> Result<(), ()> {
if true {
thing_one()
} else {
thing_two() //~ ERROR if and else have incompatible types
}.await
}

fn main() {}
20 changes: 20 additions & 0 deletions src/test/ui/suggestions/opaque-type-error.stderr
Original file line number Diff line number Diff line change
@@ -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`.