From b248647ef0aed88dc8f3be29bec0b98d8be64c3c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 26 Jul 2022 00:43:29 +0000 Subject: [PATCH] Address nits, move substs replacement to separate function --- compiler/rustc_infer/src/infer/mod.rs | 68 ++++++++++++++++----------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 4595cf6e270..ffbcedf4629 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1701,33 +1701,7 @@ pub fn const_eval_resolve( } Ok(Some(ct)) => { if ct.unify_failure_kind(self.tcx) == FailureKind::Concrete { - substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(idx, arg)| { - let needs_replacement = - arg.has_param_types_or_consts() || arg.has_infer_types_or_consts(); - match arg.unpack() { - GenericArgKind::Type(_) if needs_replacement => self - .tcx - .mk_ty(ty::Placeholder(ty::PlaceholderType { - universe: ty::UniverseIndex::ROOT, - name: ty::BoundVar::from_usize(idx), - })) - .into(), - GenericArgKind::Const(ct) if needs_replacement => self - .tcx - .mk_const(ty::ConstS { - ty: ct.ty(), - kind: ty::ConstKind::Placeholder(ty::PlaceholderConst { - universe: ty::UniverseIndex::ROOT, - name: ty::BoundConst { - var: ty::BoundVar::from_usize(idx), - ty: ct.ty(), - }, - }), - }) - .into(), - _ => arg, - } - })); + substs = replace_param_and_infer_substs_with_placeholder(self.tcx, substs); } else { return Err(ErrorHandled::TooGeneric); } @@ -2052,3 +2026,43 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ) } } + +/// Replaces substs that reference param or infer variables with suitable +/// placeholders. This function is meant to remove these param and infer +/// substs when they're not actually needed to evaluate a constant. +fn replace_param_and_infer_substs_with_placeholder<'tcx>( + tcx: TyCtxt<'tcx>, + substs: SubstsRef<'tcx>, +) -> SubstsRef<'tcx> { + tcx.mk_substs(substs.iter().enumerate().map(|(idx, arg)| { + match arg.unpack() { + GenericArgKind::Type(_) + if arg.has_param_types_or_consts() || arg.has_infer_types_or_consts() => + { + tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { + universe: ty::UniverseIndex::ROOT, + name: ty::BoundVar::from_usize(idx), + })) + .into() + } + GenericArgKind::Const(ct) + if ct.has_infer_types_or_consts() || ct.has_param_types_or_consts() => + { + let ty = ct.ty(); + // If the type references param or infer, replace that too... + if ty.has_param_types_or_consts() || ty.has_infer_types_or_consts() { + bug!("const `{ct}`'s type should not reference params or types"); + } + tcx.mk_const(ty::ConstS { + ty, + kind: ty::ConstKind::Placeholder(ty::PlaceholderConst { + universe: ty::UniverseIndex::ROOT, + name: ty::BoundConst { ty, var: ty::BoundVar::from_usize(idx) }, + }), + }) + .into() + } + _ => arg, + } + })) +}