Skip to content

Commit f1ef930

Browse files
committed
Don't ICE when deducing future output if other errors already occurred
1 parent 25b706c commit f1ef930

File tree

5 files changed

+82
-4
lines changed

5 files changed

+82
-4
lines changed

compiler/rustc_hir_typeck/src/closure.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -760,16 +760,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
760760
get_future_output(obligation.predicate, obligation.cause.span)
761761
})?
762762
}
763+
ty::Alias(ty::Projection, _) => {
764+
return Some(Ty::new_error_with_message(
765+
self.tcx,
766+
closure_span,
767+
"this projection should have been projected to an opaque type",
768+
));
769+
}
763770
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => self
764771
.tcx
765772
.explicit_item_bounds(def_id)
766773
.iter_instantiated_copied(self.tcx, args)
767774
.find_map(|(p, s)| get_future_output(p.as_predicate(), s))?,
768775
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-
),
776+
_ => {
777+
span_bug!(closure_span, "invalid async fn coroutine return type: {ret_ty:?}")
778+
}
773779
};
774780

775781
let output_ty = self.normalize(closure_span, output_ty);
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() {}
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`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
trait Foo {
2+
fn err(&self) -> MissingType;
3+
//~^ ERROR cannot find type `MissingType` in this scope
4+
}
5+
6+
impl Foo for i32 {
7+
fn err(&self) -> MissingType {
8+
//~^ ERROR cannot find type `MissingType` in this scope
9+
0
10+
}
11+
}
12+
13+
fn coerce(x: &i32) -> &dyn Foo {
14+
x
15+
}
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0412]: cannot find type `MissingType` in this scope
2+
--> $DIR/erroneous_signature.rs:2:22
3+
|
4+
LL | fn err(&self) -> MissingType;
5+
| ^^^^^^^^^^^ not found in this scope
6+
7+
error[E0412]: cannot find type `MissingType` in this scope
8+
--> $DIR/erroneous_signature.rs:7:22
9+
|
10+
LL | fn err(&self) -> MissingType {
11+
| ^^^^^^^^^^^ not found in this scope
12+
13+
error: aborting due to 2 previous errors
14+
15+
For more information about this error, try `rustc --explain E0412`.

0 commit comments

Comments
 (0)