Rollup merge of #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 #63167
This commit is contained in:
commit
aa9490bd7b
4 changed files with 62 additions and 6 deletions
|
@ -1650,7 +1650,7 @@ impl<'tcx> ObligationCause<'tcx> {
|
||||||
hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types",
|
hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types",
|
||||||
_ => "match 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 ()",
|
IfExpressionWithNoElse => "if missing an else returns ()",
|
||||||
MainFunctionType => "`main` function has the correct type",
|
MainFunctionType => "`main` function has the correct type",
|
||||||
StartFunctionType => "`start` function has the correct type",
|
StartFunctionType => "`start` function has the correct type",
|
||||||
|
|
|
@ -247,13 +247,15 @@ impl<'tcx> ty::TyS<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TyCtxt<'tcx> {
|
impl<'tcx> TyCtxt<'tcx> {
|
||||||
pub fn note_and_explain_type_err(self,
|
pub fn note_and_explain_type_err(
|
||||||
db: &mut DiagnosticBuilder<'_>,
|
self,
|
||||||
err: &TypeError<'tcx>,
|
db: &mut DiagnosticBuilder<'_>,
|
||||||
sp: Span) {
|
err: &TypeError<'tcx>,
|
||||||
|
sp: Span,
|
||||||
|
) {
|
||||||
use self::TypeError::*;
|
use self::TypeError::*;
|
||||||
|
|
||||||
match err.clone() {
|
match err {
|
||||||
Sorts(values) => {
|
Sorts(values) => {
|
||||||
let expected_str = values.expected.sort_string(self);
|
let expected_str = values.expected.sort_string(self);
|
||||||
let found_str = values.found.sort_string(self);
|
let found_str = values.found.sort_string(self);
|
||||||
|
@ -261,6 +263,16 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
db.note("no two closures, even if identical, have the same type");
|
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");
|
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(_)) =
|
if let (ty::Infer(ty::IntVar(_)), ty::Float(_)) =
|
||||||
(&values.found.sty, &values.expected.sty) // Issue #53280
|
(&values.found.sty, &values.expected.sty) // Issue #53280
|
||||||
{
|
{
|
||||||
|
|
24
src/test/ui/suggestions/opaque-type-error.rs
Normal file
24
src/test/ui/suggestions/opaque-type-error.rs
Normal file
|
@ -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
src/test/ui/suggestions/opaque-type-error.stderr
Normal file
20
src/test/ui/suggestions/opaque-type-error.stderr
Normal file
|
@ -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`.
|
Loading…
Add table
Add a link
Reference in a new issue