about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-11-01 21:40:06 +0100
committerGitHub <noreply@github.com>2023-11-01 21:40:06 +0100
commit4e437be0441cb5d26f7fa6c2bfc40f3b2aee30a6 (patch)
treee7a76d03f22b4b19ca46d3258298ca1dc20fbfb5 /compiler/rustc_const_eval/src
parent3087b63d1f305690b2146ba5f0d7295630e60ca9 (diff)
parentf512f91258a8df420598c968b604a922d277ea99 (diff)
downloadrust-4e437be0441cb5d26f7fa6c2bfc40f3b2aee30a6.tar.gz
rust-4e437be0441cb5d26f7fa6c2bfc40f3b2aee30a6.zip
Rollup merge of #117441 - cjgillot:diag-noassert, r=oli-obk,RalfJung
Do not assert in op_to_const.

`op_to_const` is used in `try_destructure_mir_constant_for_diagnostics`, which may encounter invalid constants created by optimizations and debugging.

r? ``@oli-obk``

Fixes https://github.com/rust-lang/rust/issues/117368
Diffstat (limited to 'compiler/rustc_const_eval/src')
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs16
-rw-r--r--compiler/rustc_const_eval/src/const_eval/mod.rs4
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs4
-rw-r--r--compiler/rustc_const_eval/src/lib.rs4
4 files changed, 20 insertions, 8 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 669838308a5..7782cb8fd38 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -106,10 +106,16 @@ pub(crate) fn mk_eval_cx<'mir, 'tcx>(
 }
 
 /// This function converts an interpreter value into a MIR constant.
+///
+/// The `for_diagnostics` flag turns the usual rules for returning `ConstValue::Scalar` into a
+/// best-effort attempt. This is not okay for use in const-eval sine it breaks invariants rustc
+/// relies on, but it is okay for diagnostics which will just give up gracefully when they
+/// encounter an `Indirect` they cannot handle.
 #[instrument(skip(ecx), level = "debug")]
 pub(super) fn op_to_const<'tcx>(
     ecx: &CompileTimeEvalContext<'_, 'tcx>,
     op: &OpTy<'tcx>,
+    for_diagnostics: bool,
 ) -> ConstValue<'tcx> {
     // Handle ZST consistently and early.
     if op.layout.is_zst() {
@@ -133,7 +139,13 @@ pub(super) fn op_to_const<'tcx>(
         _ => false,
     };
     let immediate = if force_as_immediate {
-        Right(ecx.read_immediate(op).expect("normalization works on validated constants"))
+        match ecx.read_immediate(op) {
+            Ok(imm) => Right(imm),
+            Err(err) if !for_diagnostics => {
+                panic!("normalization works on validated constants: {err:?}")
+            }
+            _ => op.as_mplace_or_imm(),
+        }
     } else {
         op.as_mplace_or_imm()
     };
@@ -205,7 +217,7 @@ pub(crate) fn turn_into_const_value<'tcx>(
     );
 
     // Turn this into a proper constant.
-    op_to_const(&ecx, &mplace.into())
+    op_to_const(&ecx, &mplace.into(), /* for diagnostics */ false)
 }
 
 #[instrument(skip(tcx), level = "debug")]
diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs
index d6ee6975cdd..e53282ffaeb 100644
--- a/compiler/rustc_const_eval/src/const_eval/mod.rs
+++ b/compiler/rustc_const_eval/src/const_eval/mod.rs
@@ -72,7 +72,7 @@ pub(crate) fn eval_to_valtree<'tcx>(
 }
 
 #[instrument(skip(tcx), level = "debug")]
-pub(crate) fn try_destructure_mir_constant_for_diagnostics<'tcx>(
+pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>(
     tcx: TyCtxtAt<'tcx>,
     val: mir::ConstValue<'tcx>,
     ty: Ty<'tcx>,
@@ -99,7 +99,7 @@ pub(crate) fn try_destructure_mir_constant_for_diagnostics<'tcx>(
     let fields_iter = (0..field_count)
         .map(|i| {
             let field_op = ecx.project_field(&down, i).ok()?;
-            let val = op_to_const(&ecx, &field_op);
+            let val = op_to_const(&ecx, &field_op, /* for diagnostics */ true);
             Some((val, field_op.layout.ty))
         })
         .collect::<Option<Vec<_>>>()?;
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index d6dc1a62f4d..3aaaf08c856 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -232,7 +232,7 @@ pub fn valtree_to_const_value<'tcx>(
             let mut ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No);
             let imm = valtree_to_ref(&mut ecx, valtree, *inner_ty);
             let imm = ImmTy::from_immediate(imm, tcx.layout_of(param_env_ty).unwrap());
-            op_to_const(&ecx, &imm.into())
+            op_to_const(&ecx, &imm.into(), /* for diagnostics */ false)
         }
         ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => {
             let layout = tcx.layout_of(param_env_ty).unwrap();
@@ -265,7 +265,7 @@ pub fn valtree_to_const_value<'tcx>(
             dump_place(&ecx, &place);
             intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap();
 
-            op_to_const(&ecx, &place.into())
+            op_to_const(&ecx, &place.into(), /* for diagnostics */ false)
         }
         ty::Never
         | ty::Error(_)
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 7d36e2eaefe..1e21c494070 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -54,8 +54,8 @@ pub fn provide(providers: &mut Providers) {
         let (param_env, raw) = param_env_and_value.into_parts();
         const_eval::eval_to_valtree(tcx, param_env, raw)
     };
-    providers.hooks.try_destructure_mir_constant_for_diagnostics =
-        const_eval::try_destructure_mir_constant_for_diagnostics;
+    providers.hooks.try_destructure_mir_constant_for_user_output =
+        const_eval::try_destructure_mir_constant_for_user_output;
     providers.valtree_to_const_val = |tcx, (ty, valtree)| {
         const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree)
     };