From 966f27977a888b332ff007f615c45e509e70576e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 4 Oct 2023 23:55:52 +0000 Subject: [PATCH 1/2] Structurally normalize async fn return type in deduce_future_output_from_obligations --- compiler/rustc_hir_typeck/src/closure.rs | 16 ++++++++++------ .../normalize-async-closure-in-trait.rs | 11 +++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 tests/ui/traits/new-solver/normalize-async-closure-in-trait.rs diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index e426b937542ea..d4d62a40328da 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -688,8 +688,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span_bug!(self.tcx.def_span(expr_def_id), "async fn generator outside of a fn") }); + let closure_span = self.tcx.def_span(expr_def_id); let ret_ty = ret_coercion.borrow().expected_ty(); - let ret_ty = self.inh.infcx.shallow_resolve(ret_ty); + let ret_ty = self.try_structurally_resolve_type(closure_span, ret_ty); let get_future_output = |predicate: ty::Predicate<'tcx>, span| { // Search for a pending obligation like @@ -711,8 +712,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - let span = self.tcx.def_span(expr_def_id); - let output_ty = match *ret_ty.kind() { ty::Infer(ty::TyVar(ret_vid)) => { self.obligations_for_self_ty(ret_vid).find_map(|obligation| { @@ -726,17 +725,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .find_map(|(p, s)| get_future_output(p.as_predicate(), s))?, ty::Error(_) => return None, _ => span_bug!( - span, + closure_span, "async fn generator return type not an inference variable: {ret_ty}" ), }; - let output_ty = self.normalize(span, output_ty); + let output_ty = self.normalize(closure_span, output_ty); // async fn that have opaque types in their return type need to redo the conversion to inference variables // as they fetch the still opaque version from the signature. let InferOk { value: output_ty, obligations } = self - .replace_opaque_types_with_inference_vars(output_ty, body_def_id, span, self.param_env); + .replace_opaque_types_with_inference_vars( + output_ty, + body_def_id, + closure_span, + self.param_env, + ); self.register_predicates(obligations); Some(output_ty) diff --git a/tests/ui/traits/new-solver/normalize-async-closure-in-trait.rs b/tests/ui/traits/new-solver/normalize-async-closure-in-trait.rs new file mode 100644 index 0000000000000..b6200096a8921 --- /dev/null +++ b/tests/ui/traits/new-solver/normalize-async-closure-in-trait.rs @@ -0,0 +1,11 @@ +// compile-flags: -Ztrait-solver=next +// check-pass +// edition:2021 + +#![feature(async_fn_in_trait)] + +trait Foo { + async fn bar() {} +} + +fn main() {} From dfbb1bfc892d442cd9456f52ebc99a95c7dfbdcd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 5 Oct 2023 00:05:04 +0000 Subject: [PATCH 2/2] Also closures --- compiler/rustc_hir_typeck/src/closure.rs | 4 +++- .../deduce-closure-signature-after-normalization.rs | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 tests/ui/traits/new-solver/deduce-closure-signature-after-normalization.rs diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index d4d62a40328da..e506c150f7d39 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -56,7 +56,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // closure sooner rather than later, so first examine the expected // type, and see if can glean a closure kind from there. let (expected_sig, expected_kind) = match expected.to_option(self) { - Some(ty) => self.deduce_closure_signature(ty), + Some(ty) => { + self.deduce_closure_signature(self.try_structurally_resolve_type(expr_span, ty)) + } None => (None, None), }; let body = self.tcx.hir().body(closure.body); diff --git a/tests/ui/traits/new-solver/deduce-closure-signature-after-normalization.rs b/tests/ui/traits/new-solver/deduce-closure-signature-after-normalization.rs new file mode 100644 index 0000000000000..d67fc65032ca7 --- /dev/null +++ b/tests/ui/traits/new-solver/deduce-closure-signature-after-normalization.rs @@ -0,0 +1,12 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +#![feature(return_position_impl_trait_in_trait)] + +trait Foo { + fn test() -> impl Fn(u32) -> u32 { + |x| x.count_ones() + } +} + +fn main() {}