Skip to content

Commit aa9490b

Browse files
authored
Rollup merge of rust-lang#63796 - estebank:opaque_future, r=Centril
Tweak E0308 on opaque types ``` error[E0308]: if and else have incompatible types --> file.rs:21:9 | 18 | / if true { 19 | | thing_one() | | ----------- expected because of this 20 | | } else { 21 | | thing_two() | | ^^^^^^^^^^^ expected opaque type, found a different opaque type 22 | | }.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 futures resolve to the same type, consider `await`ing on both of them ``` r? @Centril CC rust-lang#63167
2 parents 6c1cdb7 + a710c61 commit aa9490b

File tree

4 files changed

+62
-6
lines changed

4 files changed

+62
-6
lines changed

src/librustc/infer/error_reporting/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1650,7 +1650,7 @@ impl<'tcx> ObligationCause<'tcx> {
16501650
hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types",
16511651
_ => "match arms have compatible types",
16521652
},
1653-
IfExpression { .. } => "if and else have compatible types",
1653+
IfExpression { .. } => "if and else have incompatible types",
16541654
IfExpressionWithNoElse => "if missing an else returns ()",
16551655
MainFunctionType => "`main` function has the correct type",
16561656
StartFunctionType => "`start` function has the correct type",

src/librustc/ty/error.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -247,20 +247,32 @@ impl<'tcx> ty::TyS<'tcx> {
247247
}
248248

249249
impl<'tcx> TyCtxt<'tcx> {
250-
pub fn note_and_explain_type_err(self,
251-
db: &mut DiagnosticBuilder<'_>,
252-
err: &TypeError<'tcx>,
253-
sp: Span) {
250+
pub fn note_and_explain_type_err(
251+
self,
252+
db: &mut DiagnosticBuilder<'_>,
253+
err: &TypeError<'tcx>,
254+
sp: Span,
255+
) {
254256
use self::TypeError::*;
255257

256-
match err.clone() {
258+
match err {
257259
Sorts(values) => {
258260
let expected_str = values.expected.sort_string(self);
259261
let found_str = values.found.sort_string(self);
260262
if expected_str == found_str && expected_str == "closure" {
261263
db.note("no two closures, even if identical, have the same type");
262264
db.help("consider boxing your closure and/or using it as a trait object");
263265
}
266+
if expected_str == found_str && expected_str == "opaque type" { // Issue #63167
267+
db.note("distinct uses of `impl Trait` result in different opaque types");
268+
let e_str = values.expected.to_string();
269+
let f_str = values.found.to_string();
270+
if &e_str == &f_str && &e_str == "impl std::future::Future" {
271+
// FIXME: use non-string based check.
272+
db.help("if both `Future`s have the same `Output` type, consider \
273+
`.await`ing on both of them");
274+
}
275+
}
264276
if let (ty::Infer(ty::IntVar(_)), ty::Float(_)) =
265277
(&values.found.sty, &values.expected.sty) // Issue #53280
266278
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// edition:2018
2+
use core::future::Future;
3+
4+
async fn base_thing() -> Result<(), ()> {
5+
Ok(())
6+
}
7+
8+
fn thing_one() -> impl Future<Output = Result<(), ()>> {
9+
base_thing()
10+
}
11+
12+
fn thing_two() -> impl Future<Output = Result<(), ()>> {
13+
base_thing()
14+
}
15+
16+
async fn thing() -> Result<(), ()> {
17+
if true {
18+
thing_one()
19+
} else {
20+
thing_two() //~ ERROR if and else have incompatible types
21+
}.await
22+
}
23+
24+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0308]: if and else have incompatible types
2+
--> $DIR/opaque-type-error.rs:20:9
3+
|
4+
LL | / if true {
5+
LL | | thing_one()
6+
| | ----------- expected because of this
7+
LL | | } else {
8+
LL | | thing_two()
9+
| | ^^^^^^^^^^^ expected opaque type, found a different opaque type
10+
LL | | }.await
11+
| |_____- if and else have incompatible types
12+
|
13+
= note: expected type `impl std::future::Future` (opaque type)
14+
found type `impl std::future::Future` (opaque type)
15+
= note: distinct uses of `impl Trait` result in different opaque types
16+
= help: if both `Future`s have the same `Output` type, consider `.await`ing on both of them
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)