Skip to content

Commit b0483e8

Browse files
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.
2 parents d984671 + b5d96d5 commit b0483e8

File tree

4 files changed

+64
-12
lines changed

4 files changed

+64
-12
lines changed

compiler/rustc_const_eval/src/interpret/operand.rs

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

compiler/rustc_middle/src/ty/normalize_erasing_regions.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,9 @@ impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> {
193193
let arg = self.param_env.and(arg);
194194

195195
self.tcx.try_normalize_generic_arg_after_erasing_regions(arg).unwrap_or_else(|_| bug!(
196-
"Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead",
197-
arg.value
198-
))
196+
"Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead",
197+
arg.value
198+
))
199199
}
200200
}
201201

compiler/rustc_mir_transform/src/const_prop_lint.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
284284
return None;
285285
}
286286

287-
self.use_ecx(source_info, |this| this.ecx.eval_mir_constant(&c.literal, Some(c.span), None))
287+
// Normalization needed b/c const prop lint runs in
288+
// `mir_drops_elaborated_and_const_checked`, which happens before
289+
// optimized MIR. Only after optimizing the MIR can we guarantee
290+
// that the `RevealAll` pass has happened and that the body's consts
291+
// are normalized, so any call to resolve before that needs to be
292+
// manually normalized.
293+
let val = self.tcx.try_normalize_erasing_regions(self.param_env, c.literal).ok()?;
294+
295+
self.use_ecx(source_info, |this| this.ecx.eval_mir_constant(&val, Some(c.span), None))
288296
}
289297

290298
/// Returns the value, if any, of evaluating `place`.

tests/ui/mir/issue-109743.rs

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// build-pass
2+
// compile-flags: --crate-type=lib
3+
4+
use std::marker::PhantomData;
5+
6+
pub trait StreamOnce {
7+
type Token;
8+
}
9+
10+
impl StreamOnce for &str {
11+
type Token = ();
12+
}
13+
14+
pub trait Parser<Input: StreamOnce> {
15+
type PartialState: Default;
16+
fn parse_mode(&self, _state: &Self::PartialState) {}
17+
fn parse_mode_impl() {}
18+
}
19+
20+
pub fn parse_bool<'a>() -> impl Parser<&'a str> {
21+
pub struct TokensCmp<C, Input>
22+
where
23+
Input: StreamOnce,
24+
{
25+
_cmp: C,
26+
_marker: PhantomData<Input>,
27+
}
28+
29+
impl<Input, C> Parser<Input> for TokensCmp<C, Input>
30+
where
31+
C: FnMut(Input::Token),
32+
Input: StreamOnce,
33+
{
34+
type PartialState = ();
35+
}
36+
37+
TokensCmp { _cmp: |_| (), _marker: PhantomData }
38+
}
39+
40+
pub struct ParseBool;
41+
42+
impl<'a> Parser<&'a str> for ParseBool
43+
where
44+
&'a str: StreamOnce,
45+
{
46+
type PartialState = ();
47+
48+
fn parse_mode_impl() {
49+
parse_bool().parse_mode(&Default::default())
50+
}
51+
}

0 commit comments

Comments
 (0)