summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2023-04-04 10:39:26 +0000
committerPietro Albini <pietro@pietroalbini.org>2023-04-16 16:26:46 +0200
commit7894a9033183b814ce0ca0cf67f6e0d38e2e951d (patch)
treec4cb9f76d1630353bf6276171c296371b7a111a3
parent6ed03e8924a27c176cb6b61fdba72eca5d7926d2 (diff)
downloadrust-7894a9033183b814ce0ca0cf67f6e0d38e2e951d.tar.gz
Move a const-prop-lint specific hack from mir interpret to const-prop-lint and make it fallible
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs9
-rw-r--r--compiler/rustc_middle/src/ty/normalize_erasing_regions.rs6
-rw-r--r--compiler/rustc_mir_transform/src/const_prop_lint.rs10
-rw-r--r--tests/ui/mir/issue-109743.rs51
4 files changed, 64 insertions, 12 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 8d5192bca67..5310ef0bb3e 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -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)?;
diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
index 578cd82aa4c..7c59879a187 100644
--- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
+++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
@@ -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
+ ))
}
}
diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs
index 6c1980ff3ad..fd9475748ce 100644
--- a/compiler/rustc_mir_transform/src/const_prop_lint.rs
+++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs
@@ -298,7 +298,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`.
diff --git a/tests/ui/mir/issue-109743.rs b/tests/ui/mir/issue-109743.rs
new file mode 100644
index 00000000000..73f3405e3ad
--- /dev/null
+++ b/tests/ui/mir/issue-109743.rs
@@ -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())
+ }
+}