Skip to content

Implement special-cased projection error message for some common traits #98863

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 2 commits into from
Aug 8, 2022
Merged
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
62 changes: 49 additions & 13 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
@@ -1315,6 +1315,13 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
error: &MismatchedProjectionTypes<'tcx>,
);

fn maybe_detailed_projection_msg(
&self,
pred: ty::ProjectionPredicate<'tcx>,
normalized_ty: ty::Term<'tcx>,
expected_ty: ty::Term<'tcx>,
) -> Option<String>;

fn fuzzy_match_tys(
&self,
a: Ty<'tcx>,
@@ -1542,23 +1549,19 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
normalized_ty,
data.term,
) {
values = Some(infer::ValuePairs::Terms(ExpectedFound::new(
is_normalized_ty_expected,
normalized_ty,
data.term,
)));
values = Some((data, is_normalized_ty_expected, normalized_ty, data.term));
err_buf = error;
err = &err_buf;
}
}

let mut diag = struct_span_err!(
self.tcx.sess,
obligation.cause.span,
E0271,
"type mismatch resolving `{}`",
predicate
);
let msg = values
.and_then(|(predicate, _, normalized_ty, expected_ty)| {
self.maybe_detailed_projection_msg(predicate, normalized_ty, expected_ty)
})
.unwrap_or_else(|| format!("type mismatch resolving `{}`", predicate));
let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}");

let secondary_span = match predicate.kind().skip_binder() {
ty::PredicateKind::Projection(proj) => self
.tcx
@@ -1596,7 +1599,13 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
&mut diag,
&obligation.cause,
secondary_span,
values,
values.map(|(_, is_normalized_ty_expected, normalized_ty, term)| {
infer::ValuePairs::Terms(ExpectedFound::new(
is_normalized_ty_expected,
normalized_ty,
term,
))
}),
err,
true,
false,
@@ -1606,6 +1615,33 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
});
}

fn maybe_detailed_projection_msg(
&self,
pred: ty::ProjectionPredicate<'tcx>,
normalized_ty: ty::Term<'tcx>,
expected_ty: ty::Term<'tcx>,
) -> Option<String> {
let trait_def_id = pred.projection_ty.trait_def_id(self.tcx);
let self_ty = pred.projection_ty.self_ty();

if Some(pred.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output() {
Some(format!(
"expected `{self_ty}` to be a {fn_kind} that returns `{expected_ty}`, but it returns `{normalized_ty}`",
fn_kind = self_ty.prefix_string(self.tcx)
))
} else if Some(trait_def_id) == self.tcx.lang_items().future_trait() {
Some(format!(
"expected `{self_ty}` to be a future that resolves to `{expected_ty}`, but it resolves to `{normalized_ty}`"
))
} else if Some(trait_def_id) == self.tcx.get_diagnostic_item(sym::Iterator) {
Some(format!(
"expected `{self_ty}` to be an iterator that yields `{expected_ty}`, but it yields `{normalized_ty}`"
))
} else {
None
}
}

fn fuzzy_match_tys(
&self,
mut a: Ty<'tcx>,
Original file line number Diff line number Diff line change
@@ -4,5 +4,5 @@ trait I32Iterator = Iterator<Item = i32>;

fn main() {
let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
//~^ ERROR type mismatch
//~^ ERROR expected `std::vec::IntoIter<u32>` to be an iterator that yields `i32`, but it yields `u32`
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == i32`
error[E0271]: expected `std::vec::IntoIter<u32>` to be an iterator that yields `i32`, but it yields `u32`
--> $DIR/associated-types-overridden-binding-2.rs:6:43
|
LL | let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ fn return_targets_async_block_not_fn() -> u8 {
return 0u8;
};
let _: &dyn Future<Output = ()> = &block;
//~^ ERROR type mismatch
//~^ ERROR expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
}

async fn return_targets_async_block_not_async_fn() -> u8 {
@@ -24,7 +24,7 @@ async fn return_targets_async_block_not_async_fn() -> u8 {
return 0u8;
};
let _: &dyn Future<Output = ()> = &block;
//~^ ERROR type mismatch resolving `<impl Future<Output = u8> as Future>::Output == ()`
//~^ ERROR expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
}

fn no_break_in_async_block() {
@@ -42,7 +42,9 @@ fn no_break_in_async_block_even_with_outer_loop() {
}

struct MyErr;
fn err() -> Result<u8, MyErr> { Err(MyErr) }
fn err() -> Result<u8, MyErr> {
Err(MyErr)
}

fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
//~^ ERROR mismatched types
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ LL | |
LL | | }
| |_^ expected `u8`, found `()`

error[E0271]: type mismatch resolving `<impl Future<Output = u8> as Future>::Output == ()`
error[E0271]: expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
--> $DIR/async-block-control-flow-static-semantics.rs:26:39
|
LL | let _: &dyn Future<Output = ()> = &block;
@@ -47,7 +47,7 @@ LL | fn return_targets_async_block_not_fn() -> u8 {
| |
| implicitly returns `()` as its body has no tail or `return` expression

error[E0271]: type mismatch resolving `<impl Future<Output = u8> as Future>::Output == ()`
error[E0271]: expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
--> $DIR/async-block-control-flow-static-semantics.rs:17:39
|
LL | let _: &dyn Future<Output = ()> = &block;
@@ -56,7 +56,7 @@ LL | let _: &dyn Future<Output = ()> = &block;
= note: required for the cast from `impl Future<Output = u8>` to the object type `dyn Future<Output = ()>`

error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:47:44
--> $DIR/async-block-control-flow-static-semantics.rs:49:44
|
LL | fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
| ---------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `Result`, found `()`
@@ -67,7 +67,7 @@ LL | fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
found unit type `()`

error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:56:50
--> $DIR/async-block-control-flow-static-semantics.rs:58:50
|
LL | fn rethrow_targets_async_block_not_async_fn() -> Result<u8, MyErr> {
| ---------------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `Result`, found `()`
10 changes: 7 additions & 3 deletions src/test/ui/hrtb/issue-62203-hrtb-ice.rs
Original file line number Diff line number Diff line change
@@ -38,9 +38,13 @@ fn main() {
let v = Unit2.m(
//~^ ERROR type mismatch
L {
//~^ ERROR type mismatch
f : |x| { drop(x); Unit4 }
});
//~^ ERROR to be a closure that returns `Unit3`, but it returns `Unit4`
f: |x| {
drop(x);
Unit4
},
},
);
}

impl<'a> Ty<'a> for Unit2 {
15 changes: 9 additions & 6 deletions src/test/ui/hrtb/issue-62203-hrtb-ice.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0271]: type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:20]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
error[E0271]: type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
--> $DIR/issue-62203-hrtb-ice.rs:38:19
|
LL | let v = Unit2.m(
| ^ type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:20]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
| ^ type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
|
note: expected this to be `<_ as Ty<'_>>::V`
--> $DIR/issue-62203-hrtb-ice.rs:21:14
@@ -22,19 +22,22 @@ LL | where
LL | F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m`

error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:20] as FnOnce<((&'r u8,),)>>::Output == Unit3`
error[E0271]: expected `[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]` to be a closure that returns `Unit3`, but it returns `Unit4`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for this PR: I would love to instead say "expected the closure to return Unit3..." and have a span label pointing at the closure, but we need to improve that in general.

--> $DIR/issue-62203-hrtb-ice.rs:40:9
|
LL | let v = Unit2.m(
| - required by a bound introduced by this call
LL |
LL | / L {
LL | |
LL | | f : |x| { drop(x); Unit4 }
LL | | });
LL | | f: |x| {
LL | | drop(x);
LL | | Unit4
LL | | },
LL | | },
| |_________^ expected struct `Unit3`, found struct `Unit4`
|
note: required because of the requirements on the impl of `for<'r> T0<'r, (&'r u8,)>` for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:20]>`
note: required because of the requirements on the impl of `for<'r> T0<'r, (&'r u8,)>` for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]>`
--> $DIR/issue-62203-hrtb-ice.rs:17:16
|
LL | impl<'a, A, T> T0<'a, A> for L<T>
2 changes: 1 addition & 1 deletion src/test/ui/impl-trait/issues/issue-78722.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ type F = impl core::future::Future<Output = u8>;
struct Bug {
V1: [(); {
fn concrete_use() -> F {
//~^ ERROR type mismatch
//~^ ERROR expected `impl Future<Output = ()>` to be a future that resolves to `u8`, but it resolves to `()`
async {}
}
let f: F = async { 1 };
2 changes: 1 addition & 1 deletion src/test/ui/impl-trait/issues/issue-78722.stderr
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ LL | let f: F = async { 1 };
LL | }],
| - value is dropped here

error[E0271]: type mismatch resolving `<impl Future<Output = ()> as Future>::Output == u8`
error[E0271]: expected `impl Future<Output = ()>` to be a future that resolves to `u8`, but it resolves to `()`
--> $DIR/issue-78722.rs:9:30
|
LL | fn concrete_use() -> F {
2 changes: 1 addition & 1 deletion src/test/ui/intrinsics/const-eval-select-bad.rs
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ fn baz(n: bool) -> i32 {

const fn return_ty_mismatch() {
const_eval_select((1,), foo, bar);
//~^ ERROR type mismatch
//~^ ERROR expected `fn(i32) -> bool {bar}` to be a fn item that returns `i32`, but it returns `bool`
}

const fn args_ty_mismatch() {
2 changes: 1 addition & 1 deletion src/test/ui/intrinsics/const-eval-select-bad.stderr
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ note: required by a bound in `const_eval_select`
LL | G: FnOnce<ARG, Output = RET> + ~const Destruct,
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`

error[E0271]: type mismatch resolving `<fn(i32) -> bool {bar} as FnOnce<(i32,)>>::Output == i32`
error[E0271]: expected `fn(i32) -> bool {bar}` to be a fn item that returns `i32`, but it returns `bool`
--> $DIR/const-eval-select-bad.rs:29:5
|
LL | const_eval_select((1,), foo, bar);
11 changes: 6 additions & 5 deletions src/test/ui/issues/issue-31173.rs
Original file line number Diff line number Diff line change
@@ -3,12 +3,13 @@ use std::vec::IntoIter;
pub fn get_tok(it: &mut IntoIter<u8>) {
let mut found_e = false;

let temp: Vec<u8> = it.take_while(|&x| {
found_e = true;
false
})
let temp: Vec<u8> = it
.take_while(|&x| {
found_e = true;
false
})
.cloned()
//~^ ERROR type mismatch resolving
//~^ ERROR to be an iterator that yields `&_`, but it yields `u8`
.collect(); //~ ERROR the method
}

18 changes: 9 additions & 9 deletions src/test/ui/issues/issue-31173.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0271]: type mismatch resolving `<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]> as Iterator>::Item == &_`
--> $DIR/issue-31173.rs:10:10
error[E0271]: expected `TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>` to be an iterator that yields `&_`, but it yields `u8`
--> $DIR/issue-31173.rs:11:10
|
LL | .cloned()
| ^^^^^^ expected reference, found `u8`
@@ -12,11 +12,11 @@ note: required by a bound in `cloned`
LL | Self: Sized + Iterator<Item = &'a T>,
| ^^^^^^^^^^^^ required by this bound in `cloned`

error[E0599]: the method `collect` exists for struct `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]>>`, but its trait bounds were not satisfied
--> $DIR/issue-31173.rs:12:10
error[E0599]: the method `collect` exists for struct `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>`, but its trait bounds were not satisfied
--> $DIR/issue-31173.rs:13:10
|
LL | .collect();
| ^^^^^^^ method cannot be called on `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]>>` due to unsatisfied trait bounds
| ^^^^^^^ method cannot be called on `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>` due to unsatisfied trait bounds
|
::: $SRC_DIR/core/src/iter/adapters/cloned.rs:LL:COL
|
@@ -29,10 +29,10 @@ LL | pub struct TakeWhile<I, P> {
| -------------------------- doesn't satisfy `<_ as Iterator>::Item = &_`
|
= note: the following trait bounds were not satisfied:
`<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]> as Iterator>::Item = &_`
which is required by `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]>>: Iterator`
`Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]>>: Iterator`
which is required by `&mut Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]>>: Iterator`
`<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]> as Iterator>::Item = &_`
which is required by `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
`Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
which is required by `&mut Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`

error: aborting due to 2 previous errors

6 changes: 3 additions & 3 deletions src/test/ui/issues/issue-33941.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
use std::collections::HashMap;

fn main() {
for _ in HashMap::new().iter().cloned() {} //~ ERROR type mismatch
//~^ ERROR type mismatch
//~| ERROR type mismatch
for _ in HashMap::new().iter().cloned() {} //~ ERROR expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
//~^ ERROR expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
//~| ERROR expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
}
6 changes: 3 additions & 3 deletions src/test/ui/issues/issue-33941.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as Iterator>::Item == &_`
error[E0271]: expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
--> $DIR/issue-33941.rs:6:36
|
LL | for _ in HashMap::new().iter().cloned() {}
@@ -12,7 +12,7 @@ note: required by a bound in `cloned`
LL | Self: Sized + Iterator<Item = &'a T>,
| ^^^^^^^^^^^^ required by this bound in `cloned`

error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as Iterator>::Item == &_`
error[E0271]: expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
--> $DIR/issue-33941.rs:6:14
|
LL | for _ in HashMap::new().iter().cloned() {}
@@ -23,7 +23,7 @@ LL | for _ in HashMap::new().iter().cloned() {}
= note: required because of the requirements on the impl of `Iterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
= note: required because of the requirements on the impl of `IntoIterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`

error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as Iterator>::Item == &_`
error[E0271]: expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
--> $DIR/issue-33941.rs:6:14
|
LL | for _ in HashMap::new().iter().cloned() {}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0271]: type mismatch resolving `<[closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47] as FnOnce<()>>::Output == ()`
error[E0271]: expected `[closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47]` to be a closure that returns `()`, but it returns `!`
--> $DIR/fallback-closure-wrap.rs:18:31
|
LL | let error = Closure::wrap(Box::new(move || {
2 changes: 1 addition & 1 deletion src/test/ui/never_type/fallback-closure-wrap.rs
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ use std::marker::PhantomData;

fn main() {
let error = Closure::wrap(Box::new(move || {
//[fallback]~^ ERROR type mismatch resolving
//[fallback]~^ to be a closure that returns `()`, but it returns `!`
panic!("Can't connect to server.");
}) as Box<dyn FnMut()>);
}
8 changes: 4 additions & 4 deletions src/test/ui/traits/assoc-type-in-superbad.rs
Original file line number Diff line number Diff line change
@@ -4,13 +4,13 @@

use std::vec::IntoIter;

pub trait Foo: Iterator<Item=<Self as Foo>::Key> {
pub trait Foo: Iterator<Item = <Self as Foo>::Key> {
type Key;
}

impl Foo for IntoIter<i32> {
type Key = u32; //~ ERROR type mismatch
type Key = u32;
//~^ ERROR expected `std::vec::IntoIter<i32>` to be an iterator that yields `u32`, but it yields `i32`
}

fn main() {
}
fn main() {}
6 changes: 3 additions & 3 deletions src/test/ui/traits/assoc-type-in-superbad.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0271]: type mismatch resolving `<std::vec::IntoIter<i32> as Iterator>::Item == u32`
error[E0271]: expected `std::vec::IntoIter<i32>` to be an iterator that yields `u32`, but it yields `i32`
--> $DIR/assoc-type-in-superbad.rs:12:16
|
LL | type Key = u32;
@@ -7,8 +7,8 @@ LL | type Key = u32;
note: required by a bound in `Foo`
--> $DIR/assoc-type-in-superbad.rs:7:25
|
LL | pub trait Foo: Iterator<Item=<Self as Foo>::Key> {
| ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo`
LL | pub trait Foo: Iterator<Item = <Self as Foo>::Key> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo`

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/test/ui/type-alias-impl-trait/issue-57961.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ trait Foo {

impl Foo for () {
type Bar = std::vec::IntoIter<u32>;
//~^ ERROR type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == X
//~^ ERROR expected `std::vec::IntoIter<u32>` to be an iterator that yields `X`, but it yields `u32`
}

fn incoherent() {
2 changes: 1 addition & 1 deletion src/test/ui/type-alias-impl-trait/issue-57961.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == X`
error[E0271]: expected `std::vec::IntoIter<u32>` to be an iterator that yields `X`, but it yields `u32`
--> $DIR/issue-57961.rs:10:16
|
LL | type X = impl Sized;
6 changes: 2 additions & 4 deletions src/test/ui/type-alias-impl-trait/issue-98604.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
// edition:2018

type AsyncFnPtr = Box<
dyn Fn() -> std::pin::Pin<Box<dyn std::future::Future<Output = ()>>>,
>;
type AsyncFnPtr = Box<dyn Fn() -> std::pin::Pin<Box<dyn std::future::Future<Output = ()>>>>;

async fn test() {}

#[allow(unused_must_use)]
fn main() {
Box::new(test) as AsyncFnPtr;
//~^ ERROR type mismatch
//~^ ERROR expected `fn() -> impl Future<Output = ()> {test}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
}
6 changes: 3 additions & 3 deletions src/test/ui/type-alias-impl-trait/issue-98604.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0271]: type mismatch resolving `<fn() -> impl Future<Output = ()> {test} as FnOnce<()>>::Output == Pin<Box<(dyn Future<Output = ()> + 'static)>>`
--> $DIR/issue-98604.rs:11:5
error[E0271]: expected `fn() -> impl Future<Output = ()> {test}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
--> $DIR/issue-98604.rs:9:5
|
LL | Box::new(test) as AsyncFnPtr;
| ^^^^^^^^^^^^^^ expected struct `Pin`, found opaque type
|
note: while checking the return type of the `async fn`
--> $DIR/issue-98604.rs:7:17
--> $DIR/issue-98604.rs:5:17
|
LL | async fn test() {}
| ^ checked the `Output` of this `async fn`, found opaque type
6 changes: 4 additions & 2 deletions src/test/ui/type-alias-impl-trait/issue-98608.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
fn hi() -> impl Sized { std::ptr::null::<u8>() }
fn hi() -> impl Sized {
std::ptr::null::<u8>()
}

fn main() {
let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi);
//~^ ERROR type mismatch resolving `<fn() -> impl Sized {hi} as FnOnce<()>>::Output == Box<u8>`
//~^ ERROR expected `fn() -> impl Sized {hi}` to be a fn item that returns `Box<u8>`, but it returns `impl Sized`
let boxed = b();
let null = *boxed;
println!("{null:?}");
6 changes: 3 additions & 3 deletions src/test/ui/type-alias-impl-trait/issue-98608.stderr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
error[E0271]: type mismatch resolving `<fn() -> impl Sized {hi} as FnOnce<()>>::Output == Box<u8>`
--> $DIR/issue-98608.rs:4:39
error[E0271]: expected `fn() -> impl Sized {hi}` to be a fn item that returns `Box<u8>`, but it returns `impl Sized`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here, we could refer to the function by name

expected `hi` to return `Box<u8>`, but it returns `impl Sized`

--> $DIR/issue-98608.rs:6:39
|
LL | fn hi() -> impl Sized { std::ptr::null::<u8>() }
LL | fn hi() -> impl Sized {
| ---------- the found opaque type
...
LL | let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi);