Rollup merge of #109938 - oli-obk:try_norm, r=compiler-errors
Move a const-prop-lint specific hack from mir interpret to const-prop-lint and make it fallible fixes #109743 This hack didn't need to live in the mir interpreter. For const-prop-lint it is entirely correct to avoid doing any const prop if normalization fails at this stage. Most likely we couldn't const propagate anything anyway, and if revealing was needed (so opaque types were involved), we wouldn't want to be too smart and leak the hidden type anyway.
This commit is contained in:
commit
b0483e8004
4 changed files with 64 additions and 12 deletions
|
@ -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)?;
|
||||
|
|
|
@ -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`.
|
||||
|
|
51
tests/ui/mir/issue-109743.rs
Normal file
51
tests/ui/mir/issue-109743.rs
Normal 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())
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue