Skip to content

Commit f6a8294

Browse files
committed
Enable deducing future output for impl trait in trait
1 parent 25b706c commit f6a8294

File tree

3 files changed

+57
-9
lines changed

3 files changed

+57
-9
lines changed

compiler/rustc_hir_typeck/src/closure.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -760,16 +760,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
760760
get_future_output(obligation.predicate, obligation.cause.span)
761761
})?
762762
}
763-
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => self
764-
.tcx
765-
.explicit_item_bounds(def_id)
766-
.iter_instantiated_copied(self.tcx, args)
767-
.find_map(|(p, s)| get_future_output(p.as_predicate(), s))?,
763+
ty::Alias(kind, ty::AliasTy { def_id, args, .. }) => {
764+
match kind {
765+
ty::Projection => assert!(self.tcx.is_impl_trait_in_trait(def_id)),
766+
ty::Opaque => {}
767+
ty::Inherent | ty::Weak => span_bug!(
768+
closure_span,
769+
"invalid async fn coroutine return type: {ret_ty:?}"
770+
),
771+
}
772+
self.tcx
773+
.explicit_item_bounds(def_id)
774+
.iter_instantiated_copied(self.tcx, args)
775+
.find_map(|(p, s)| get_future_output(p.as_predicate(), s))?
776+
}
768777
ty::Error(_) => return Some(ret_ty),
769-
_ => span_bug!(
770-
closure_span,
771-
"async fn coroutine return type not an inference variable: {ret_ty}"
772-
),
778+
_ => {
779+
span_bug!(closure_span, "invalid async fn coroutine return type: {ret_ty:?}")
780+
}
773781
};
774782

775783
let output_ty = self.normalize(closure_span, output_ty);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//! This is a regression test for an ICE.
2+
// edition: 2021
3+
4+
trait Foo {
5+
async fn foo(self: &dyn Foo) {
6+
//~^ ERROR: `Foo` cannot be made into an object
7+
//~| ERROR invalid `self` parameter type: &dyn Foo
8+
todo!()
9+
}
10+
}
11+
12+
fn main() {}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
error[E0038]: the trait `Foo` cannot be made into an object
2+
--> $DIR/inference_var_self_argument.rs:5:5
3+
|
4+
LL | async fn foo(self: &dyn Foo) {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
6+
|
7+
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
8+
--> $DIR/inference_var_self_argument.rs:5:14
9+
|
10+
LL | trait Foo {
11+
| --- this trait cannot be made into an object...
12+
LL | async fn foo(self: &dyn Foo) {
13+
| ^^^ ...because method `foo` is `async`
14+
= help: consider moving `foo` to another trait
15+
16+
error[E0307]: invalid `self` parameter type: &dyn Foo
17+
--> $DIR/inference_var_self_argument.rs:5:24
18+
|
19+
LL | async fn foo(self: &dyn Foo) {
20+
| ^^^^^^^^
21+
|
22+
= note: type of `self` must be `Self` or a type that dereferences to it
23+
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
24+
25+
error: aborting due to 2 previous errors
26+
27+
Some errors have detailed explanations: E0038, E0307.
28+
For more information about an error, try `rustc --explain E0038`.

0 commit comments

Comments
 (0)