From f6a829456c91dca637c66ba3ff6fa5f4d9184384 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 17 Jan 2024 14:52:38 +0000 Subject: [PATCH] Enable deducing future output for impl trait in trait --- compiler/rustc_hir_typeck/src/closure.rs | 26 +++++++++++------ .../inference_var_self_argument.rs | 12 ++++++++ .../inference_var_self_argument.stderr | 28 +++++++++++++++++++ 3 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 tests/ui/async-await/inference_var_self_argument.rs create mode 100644 tests/ui/async-await/inference_var_self_argument.stderr diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 57fdfa4ecb6ea..1c04e54e311ad 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -760,16 +760,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { get_future_output(obligation.predicate, obligation.cause.span) })? } - ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => self - .tcx - .explicit_item_bounds(def_id) - .iter_instantiated_copied(self.tcx, args) - .find_map(|(p, s)| get_future_output(p.as_predicate(), s))?, + ty::Alias(kind, ty::AliasTy { def_id, args, .. }) => { + match kind { + ty::Projection => assert!(self.tcx.is_impl_trait_in_trait(def_id)), + ty::Opaque => {} + ty::Inherent | ty::Weak => span_bug!( + closure_span, + "invalid async fn coroutine return type: {ret_ty:?}" + ), + } + self.tcx + .explicit_item_bounds(def_id) + .iter_instantiated_copied(self.tcx, args) + .find_map(|(p, s)| get_future_output(p.as_predicate(), s))? + } ty::Error(_) => return Some(ret_ty), - _ => span_bug!( - closure_span, - "async fn coroutine return type not an inference variable: {ret_ty}" - ), + _ => { + span_bug!(closure_span, "invalid async fn coroutine return type: {ret_ty:?}") + } }; let output_ty = self.normalize(closure_span, output_ty); diff --git a/tests/ui/async-await/inference_var_self_argument.rs b/tests/ui/async-await/inference_var_self_argument.rs new file mode 100644 index 0000000000000..fd8482f86b4fc --- /dev/null +++ b/tests/ui/async-await/inference_var_self_argument.rs @@ -0,0 +1,12 @@ +//! This is a regression test for an ICE. +// edition: 2021 + +trait Foo { + async fn foo(self: &dyn Foo) { + //~^ ERROR: `Foo` cannot be made into an object + //~| ERROR invalid `self` parameter type: &dyn Foo + todo!() + } +} + +fn main() {} diff --git a/tests/ui/async-await/inference_var_self_argument.stderr b/tests/ui/async-await/inference_var_self_argument.stderr new file mode 100644 index 0000000000000..8a8c1ea03f14a --- /dev/null +++ b/tests/ui/async-await/inference_var_self_argument.stderr @@ -0,0 +1,28 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/inference_var_self_argument.rs:5:5 + | +LL | async fn foo(self: &dyn Foo) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +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 + --> $DIR/inference_var_self_argument.rs:5:14 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | async fn foo(self: &dyn Foo) { + | ^^^ ...because method `foo` is `async` + = help: consider moving `foo` to another trait + +error[E0307]: invalid `self` parameter type: &dyn Foo + --> $DIR/inference_var_self_argument.rs:5:24 + | +LL | async fn foo(self: &dyn Foo) { + | ^^^^^^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0038, E0307. +For more information about an error, try `rustc --explain E0038`.