From f9f3f13d5ad5f27ef5e3dfe1544318fb3efd461a Mon Sep 17 00:00:00 2001 From: Adwin White Date: Fri, 25 Apr 2025 12:56:41 +0800 Subject: [PATCH 1/2] fix accidental type inference in array coercion --- compiler/rustc_hir_typeck/src/expr.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index a75f6f4caac91..70ba4acf48954 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1760,7 +1760,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let coerce_to = expected .to_option(self) .and_then(|uty| match *self.try_structurally_resolve_type(expr.span, uty).kind() { - ty::Array(ty, _) | ty::Slice(ty) => Some(ty), + // Avoid using a type variable as the coerce_to type, as it may resolve + // during the first coercion instead of being based on the common type. + ty::Array(ty, _) | ty::Slice(ty) if !ty.is_ty_var() => Some(ty), _ => None, }) .unwrap_or_else(|| self.next_ty_var(expr.span)); From b31fa29e345858a1b62ea2ff9b9206e63b3efb0d Mon Sep 17 00:00:00 2001 From: Adwin White Date: Sat, 26 Apr 2025 11:21:04 +0800 Subject: [PATCH 2/2] add ui test --- tests/ui/coercion/coerce-many-with-ty-var.rs | 25 ++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tests/ui/coercion/coerce-many-with-ty-var.rs diff --git a/tests/ui/coercion/coerce-many-with-ty-var.rs b/tests/ui/coercion/coerce-many-with-ty-var.rs new file mode 100644 index 0000000000000..e759918c9e398 --- /dev/null +++ b/tests/ui/coercion/coerce-many-with-ty-var.rs @@ -0,0 +1,25 @@ +//@ run-pass +// Check that least upper bound coercions don't resolve type variable merely based on the first +// coercion. Check issue #136420. + +fn foo() {} +fn bar() {} + +fn infer(_: T) {} + +fn infer_array_element(_: [T; 2]) {} + +fn main() { + infer(if false { + foo + } else { + bar + }); + + infer(match false { + true => foo, + false => bar, + }); + + infer_array_element([foo, bar]); +}