1
Fork 0

Move a const-prop-lint specific hack from mir interpret to const-prop-lint and make it fallible

This commit is contained in:
Oli Scherer 2023-04-04 10:39:26 +00:00
parent 35d06f9c74
commit b5d96d5ec5
4 changed files with 64 additions and 12 deletions

View file

@ -612,14 +612,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
span: Option<Span>,
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
// FIXME(const_prop): normalization needed b/c const prop lint in
// `mir_drops_elaborated_and_const_checked`, which happens before
// optimized MIR. Only after optimizing the MIR can we guarantee
// that the `RevealAll` pass has happened and that the body's consts
// are normalized, so any call to resolve before that needs to be
// manually normalized.
let val = self.tcx.normalize_erasing_regions(self.param_env, *val);
match val {
match *val {
mir::ConstantKind::Ty(ct) => {
let ty = ct.ty();
let valtree = self.eval_ty_constant(ct, span)?;

View file

@ -193,9 +193,9 @@ impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> {
let arg = self.param_env.and(arg);
self.tcx.try_normalize_generic_arg_after_erasing_regions(arg).unwrap_or_else(|_| bug!(
"Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead",
arg.value
))
"Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead",
arg.value
))
}
}

View file

@ -284,7 +284,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
return None;
}
self.use_ecx(source_info, |this| this.ecx.eval_mir_constant(&c.literal, Some(c.span), None))
// Normalization needed b/c const prop lint runs in
// `mir_drops_elaborated_and_const_checked`, which happens before
// optimized MIR. Only after optimizing the MIR can we guarantee
// that the `RevealAll` pass has happened and that the body's consts
// are normalized, so any call to resolve before that needs to be
// manually normalized.
let val = self.tcx.try_normalize_erasing_regions(self.param_env, c.literal).ok()?;
self.use_ecx(source_info, |this| this.ecx.eval_mir_constant(&val, Some(c.span), None))
}
/// Returns the value, if any, of evaluating `place`.

View file

@ -0,0 +1,51 @@
// build-pass
// compile-flags: --crate-type=lib
use std::marker::PhantomData;
pub trait StreamOnce {
type Token;
}
impl StreamOnce for &str {
type Token = ();
}
pub trait Parser<Input: StreamOnce> {
type PartialState: Default;
fn parse_mode(&self, _state: &Self::PartialState) {}
fn parse_mode_impl() {}
}
pub fn parse_bool<'a>() -> impl Parser<&'a str> {
pub struct TokensCmp<C, Input>
where
Input: StreamOnce,
{
_cmp: C,
_marker: PhantomData<Input>,
}
impl<Input, C> Parser<Input> for TokensCmp<C, Input>
where
C: FnMut(Input::Token),
Input: StreamOnce,
{
type PartialState = ();
}
TokensCmp { _cmp: |_| (), _marker: PhantomData }
}
pub struct ParseBool;
impl<'a> Parser<&'a str> for ParseBool
where
&'a str: StreamOnce,
{
type PartialState = ();
fn parse_mode_impl() {
parse_bool().parse_mode(&Default::default())
}
}