From 2a8f08083f32ed64fb367282b4896ee792f0c4a8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 10 Oct 2024 00:20:37 -0400 Subject: [PATCH] Structurallyresolve adts and tuples expectations too --- compiler/rustc_hir_typeck/src/expr.rs | 4 +-- .../traits/next-solver/typeck/guide-ctors.rs | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 tests/ui/traits/next-solver/typeck/guide-ctors.rs diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 95ca3e66472..c5b7fc1eabd 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1783,7 +1783,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { let flds = expected.only_has_type(self).and_then(|ty| { - let ty = self.resolve_vars_with_obligations(ty); + let ty = self.try_structurally_resolve_type(expr.span, ty); match ty.kind() { ty::Tuple(flds) => Some(&flds[..]), _ => None, @@ -1861,7 +1861,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let tcx = self.tcx; - let adt_ty = self.resolve_vars_with_obligations(adt_ty); + let adt_ty = self.try_structurally_resolve_type(span, adt_ty); let adt_ty_hint = expected.only_has_type(self).and_then(|expected| { self.fudge_inference_if_ok(|| { let ocx = ObligationCtxt::new(self); diff --git a/tests/ui/traits/next-solver/typeck/guide-ctors.rs b/tests/ui/traits/next-solver/typeck/guide-ctors.rs new file mode 100644 index 00000000000..7432ea78a56 --- /dev/null +++ b/tests/ui/traits/next-solver/typeck/guide-ctors.rs @@ -0,0 +1,32 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +// Makes sure we structurally normalize before trying to use expectation to guide +// coercion in adt and tuples. + +use std::any::Any; + +trait Coerce { + type Assoc; +} + +struct TupleGuidance; +impl Coerce for TupleGuidance { + type Assoc = (&'static dyn Any,); +} + +struct AdtGuidance; +impl Coerce for AdtGuidance { + type Assoc = Adt<&'static dyn Any>; +} + +struct Adt { + f: T, +} + +fn foo<'a, T: Coerce>(_: T::Assoc) {} + +fn main() { + foo::((&0u32,)); + foo::(Adt { f: &0u32 }); +}