From f7146136d79a4fb78c482797e50724bb4483a337 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 9 Mar 2023 20:52:06 +0000 Subject: [PATCH] Bail in combine if consts have different types --- compiler/rustc_infer/src/infer/combine.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 33292e871b1..adbd91f436c 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -34,7 +34,6 @@ use rustc_middle::infer::canonical::OriginalQueryValues; use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; @@ -161,9 +160,9 @@ pub fn super_combine_consts( // // This probe is probably not strictly necessary but it seems better to be safe and not accidentally find // ourselves with a check to find bugs being required for code to compile because it made inference progress. - self.probe(|_| { + let compatible_types = self.probe(|_| { if a.ty() == b.ty() { - return; + return Ok(()); } // We don't have access to trait solving machinery in `rustc_infer` so the logic for determining if the @@ -173,15 +172,24 @@ pub fn super_combine_consts( (relation.param_env(), a.ty(), b.ty()), &mut OriginalQueryValues::default(), ); - - if let Err(NoSolution) = self.tcx.check_tys_might_be_eq(canonical) { + self.tcx.check_tys_might_be_eq(canonical).map_err(|_| { self.tcx.sess.delay_span_bug( DUMMY_SP, &format!("cannot relate consts of different types (a={:?}, b={:?})", a, b,), - ); - } + ) + }) }); + // If the consts have differing types, just bail with a const error with + // the expected const's type. Specifically, we don't want const infer vars + // to do any type shapeshifting before and after resolution. + if let Err(guar) = compatible_types { + return Ok(self.tcx.const_error_with_guaranteed( + if relation.a_is_expected() { a.ty() } else { b.ty() }, + guar, + )); + } + match (a.kind(), b.kind()) { ( ty::ConstKind::Infer(InferConst::Var(a_vid)),