diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index b798862583952..22dee3e3ad9e3 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -76,6 +76,7 @@ impl<'tcx> MirPass<'tcx> for Validator { /// /// The point of this function is to approximate "equal up to subtyping". However, /// the approximation is incorrect as variance is ignored. +#[tracing::instrument(level = "trace", skip(tcx))] pub fn equal_up_to_regions<'tcx>( tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, @@ -170,6 +171,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { /// Check if src can be assigned into dest. /// This is not precise, it will accept some incorrect assignments. + #[tracing::instrument(level = "trace", skip(self))] fn mir_assign_valid_types(&self, src: Ty<'tcx>, dest: Ty<'tcx>) -> bool { // Fast path before we normalize. if src == dest { @@ -182,22 +184,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return true; } - // Normalize projections and things like that. - // Type-changing assignments can happen when subtyping is used. While - // all normal lifetimes are erased, higher-ranked types with their - // late-bound lifetimes are still around and can lead to type - // differences. So we compare ignoring lifetimes. + let try_equal_with_param_env = |param_env| { + let src = self.tcx.normalize_erasing_regions(param_env, src); + let dest = self.tcx.normalize_erasing_regions(param_env, dest); + // Type-changing assignments can happen when subtyping is used. While + // all normal lifetimes are erased, higher-ranked types with their + // late-bound lifetimes are still around and can lead to type + // differences. So we compare ignoring lifetimes. + equal_up_to_regions(self.tcx, param_env, src, dest) + }; + // Normalize projections and things like that. // First, try with reveal_all. This might not work in some cases, as the predicates // can be cleared in reveal_all mode. We try the reveal first anyways as it is used // by some other passes like inlining as well. let param_env = self.param_env.with_reveal_all_normalized(self.tcx); - if equal_up_to_regions(self.tcx, param_env, src, dest) { - return true; + if try_equal_with_param_env(param_env) { + true + } else { + // If this fails, we can try it without the reveal. + try_equal_with_param_env(self.param_env) } - - // If this fails, we can try it without the reveal. - equal_up_to_regions(self.tcx, self.param_env, src, dest) } }