about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-09-14 07:40:05 +0200
committerRalf Jung <post@ralfj.de>2023-09-14 07:40:05 +0200
commit06947be1966f088a0dfb496e986bcc09bda0cb31 (patch)
tree9940fd4bee2c1c088cc7f39c1e504b41be631f6d
parent3aedb85a278b86b254a7c00de0be03864e678d72 (diff)
downloadrust-06947be1966f088a0dfb496e986bcc09bda0cb31.tar.gz
rust-06947be1966f088a0dfb496e986bcc09bda0cb31.zip
valtree_to_const_value: add fast-path for Scalar tuples/structs
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs17
1 files changed, 16 insertions, 1 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index 793a1d21c30..1675b824c52 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -7,7 +7,7 @@ use crate::interpret::{
     intern_const_alloc_recursive, ConstValue, ImmTy, Immediate, InternKind, MemPlaceMeta,
     MemoryKind, PlaceTy, Projectable, Scalar,
 };
-use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
+use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
 use rustc_span::source_map::DUMMY_SP;
 use rustc_target::abi::VariantIdx;
@@ -239,6 +239,21 @@ pub fn valtree_to_const_value<'tcx>(
                 // Fast path to avoid some allocations.
                 return ConstValue::ZeroSized;
             }
+            if layout.abi.is_scalar()
+                && (matches!(ty.kind(), ty::Tuple(_))
+                    || matches!(ty.kind(), ty::Adt(def, _) if def.is_struct()))
+            {
+                // A Scalar tuple/struct; we can avoid creating an allocation.
+                let branches = valtree.unwrap_branch();
+                // Find the non-ZST field. (There can be aligned ZST!)
+                for (i, &inner_valtree) in branches.iter().enumerate() {
+                    let field = layout.field(&LayoutCx { tcx, param_env }, i);
+                    if !field.is_zst() {
+                        return valtree_to_const_value(tcx, param_env.and(field.ty), inner_valtree);
+                    }
+                }
+                bug!("could not find non-ZST field during in {layout:#?}");
+            }
 
             let mut ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No);