1
Fork 0

move required_consts check to general post-mono-check function

This commit is contained in:
Ralf Jung 2023-09-11 09:52:45 +02:00
parent ccf817b9bb
commit 89ac57db4d
40 changed files with 319 additions and 257 deletions

View file

@ -565,6 +565,37 @@ impl<'tcx> Body<'tcx> {
pub fn is_custom_mir(&self) -> bool {
self.injection_phase.is_some()
}
/// *Must* be called once the full substitution for this body is known, to ensure that the body
/// is indeed fit for code generation or consumption more generally.
///
/// Sadly there's no nice way to represent an "arbitrary normalizer", so we take one for
/// constants specifically. (`Option<GenericArgsRef>` could be used for that, but the fact
/// that `Instance::args_for_mir_body` is private and instead instance exposes normalization
/// functions makes it seem like exposing the generic args is not the intended strategy.)
///
/// Also sadly, CTFE doesn't even know whether it runs on MIR that is already polymorphic or still monomorphic,
/// so we cannot just immediately ICE on TooGeneric.
///
/// Returns Ok(()) if everything went fine, and `Err` if a problem occurred and got reported.
pub fn post_mono_checks(
&self,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
normalize_const: impl Fn(ConstantKind<'tcx>) -> Result<ConstantKind<'tcx>, ErrorHandled>,
) -> Result<(), ErrorHandled> {
// For now, the only thing we have to check is is to ensure that all the constants used in
// the body successfully evaluate.
for &const_ in &self.required_consts {
let c = normalize_const(const_.literal)?;
c.eval(tcx, param_env, Some(const_.span)).map_err(|e| {
// The query results don't always have the span we want.
e.with_span(const_.span)
})?;
}
Ok(())
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)]
@ -2397,10 +2428,10 @@ impl<'tcx> ConstantKind<'tcx> {
pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
match self.eval(tcx, param_env, None) {
Ok(val) => Self::Val(val, self.ty()),
Err(ErrorHandled::Reported(guar)) => {
Err(ErrorHandled::Reported(guar, _span)) => {
Self::Ty(ty::Const::new_error(tcx, guar.into(), self.ty()))
}
Err(ErrorHandled::TooGeneric) => self,
Err(ErrorHandled::TooGeneric(_span)) => self,
}
}