about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/const_eval/mod.rs
diff options
context:
space:
mode:
authorb-naber <bn263@gmx.de>2022-04-14 21:56:27 +0200
committerb-naber <bn263@gmx.de>2022-04-14 22:01:40 +0200
commitd8205cd3fe3cda6ebbcff40c8d173f8e05a375be (patch)
tree35dbacaff5a28619d759b8186c14786068f1e91d /compiler/rustc_const_eval/src/const_eval/mod.rs
parent4b126b805bd51d2b7aa335cadd571a319ec0e224 (diff)
downloadrust-d8205cd3fe3cda6ebbcff40c8d173f8e05a375be.tar.gz
rust-d8205cd3fe3cda6ebbcff40c8d173f8e05a375be.zip
handle arrays and slices uniformly in valtree creation
Diffstat (limited to 'compiler/rustc_const_eval/src/const_eval/mod.rs')
-rw-r--r--compiler/rustc_const_eval/src/const_eval/mod.rs44
1 files changed, 13 insertions, 31 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs
index 541462a26d5..80270f82563 100644
--- a/compiler/rustc_const_eval/src/const_eval/mod.rs
+++ b/compiler/rustc_const_eval/src/const_eval/mod.rs
@@ -3,6 +3,7 @@
 use std::convert::TryFrom;
 
 use rustc_hir::Mutability;
+use rustc_middle::ty::layout::HasTyCtxt;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_middle::{
     mir::{self, interpret::ConstAlloc},
@@ -74,7 +75,7 @@ fn branches<'tcx>(
         let field = ecx.mplace_field(&place, i).unwrap();
         const_to_valtree_inner(ecx, &field)
     });
-    // For enums, we preped their variant index before the variant's fields so we can figure out
+    // For enums, we prepend their variant index before the variant's fields so we can figure out
     // the variant again when just seeing a valtree.
     let branches = variant.into_iter().chain(fields);
     Some(ty::ValTree::Branch(ecx.tcx.arena.alloc_from_iter(branches.collect::<Option<Vec<_>>>()?)))
@@ -83,17 +84,13 @@ fn branches<'tcx>(
 fn slice_branches<'tcx>(
     ecx: &CompileTimeEvalContext<'tcx, 'tcx>,
     place: &MPlaceTy<'tcx>,
-    n: u64,
 ) -> Option<ty::ValTree<'tcx>> {
-    let elems = (0..n).map(|i| {
+    let n = place.len(&ecx.tcx()).expect(&format!("expected to use len of place {:?}", place));
+    let branches = (0..n).map(|i| {
         let place_elem = ecx.mplace_index(place, i).unwrap();
         const_to_valtree_inner(ecx, &place_elem)
     });
 
-    // Need `len` for the ValTree -> ConstValue conversion
-    let len = Some(Some(ty::ValTree::Leaf(ScalarInt::from(n))));
-    let branches = len.into_iter().chain(elems);
-
     Some(ty::ValTree::Branch(ecx.tcx.arena.alloc_from_iter(branches.collect::<Option<Vec<_>>>()?)))
 }
 
@@ -116,33 +113,19 @@ fn const_to_valtree_inner<'tcx>(
         // agree with runtime equality tests.
         ty::FnPtr(_) | ty::RawPtr(_) => None,
 
-        ty::Ref(_, inner_ty, _)  => {
-            match inner_ty.kind() {
-                ty::Slice(_) | ty::Str => {
-                    let derefd = ecx.deref_operand(&place.into()).unwrap();
-                    debug!(?derefd);
-                    let len = derefd.len(&ecx.tcx.tcx).unwrap();
-                    let valtree = slice_branches(ecx, &derefd, len);
-                    debug!(?valtree);
-
-                    valtree
-                }
-                _ => {
-                    let derefd_place = ecx.deref_operand(&place.into()).unwrap_or_else(|e| bug!("couldn't deref {:?}, error: {:?}", place, e));
-                    debug!(?derefd_place);
+        ty::Ref(_, _, _)  => {
+            let derefd_place = ecx.deref_operand(&place.into()).unwrap_or_else(|e| bug!("couldn't deref {:?}, error: {:?}", place, e));
+            debug!(?derefd_place);
 
-                    const_to_valtree_inner(ecx, &derefd_place)
-                }
-            }
+            const_to_valtree_inner(ecx, &derefd_place)
         }
 
-        ty::Str => {
-            bug!("ty::Str should have been handled in ty::Ref branch that uses raw bytes");
-        }
-        ty::Slice(_) => {
-            bug!("should have been handled in the Ref arm");
-        }
+        ty::Str | ty::Slice(_) | ty::Array(_, _) => {
+            let valtree = slice_branches(ecx, place);
+            debug!(?valtree);
 
+            valtree
+        }
         // Trait objects are not allowed in type level constants, as we have no concept for
         // resolving their backing type, even if we can do that at const eval time. We may
         // hypothetically be able to allow `dyn StructuralEq` trait objects in the future,
@@ -150,7 +133,6 @@ fn const_to_valtree_inner<'tcx>(
         ty::Dynamic(..) => None,
 
         ty::Tuple(substs) => branches(ecx, place, substs.len(), None),
-        ty::Array(_, len) => branches(ecx, place, usize::try_from(len.eval_usize(ecx.tcx.tcx, ecx.param_env)).unwrap(), None),
 
         ty::Adt(def, _) => {
             if def.variants().is_empty() {