about summary refs log tree commit diff
path: root/compiler/rustc_mir_build
diff options
context:
space:
mode:
authorDing Xiang Fei <dingxiangfei2009@protonmail.ch>2025-08-12 06:39:50 +0800
committerXiangfei Ding <dingxiangfei2009@protonmail.ch>2025-09-25 01:54:23 +0800
commita86f14072714fb817a6f60fa20be5a4e875d049f (patch)
tree9f42ebd49c3ced094501b1bb444a33fd0c404edc /compiler/rustc_mir_build
parent15283f6fe95e5b604273d13a428bab5fc0788f5a (diff)
downloadrust-a86f14072714fb817a6f60fa20be5a4e875d049f.tar.gz
rust-a86f14072714fb817a6f60fa20be5a4e875d049f.zip
do not materialise X in [X; 0] when X is unsizing a const
Diffstat (limited to 'compiler/rustc_mir_build')
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs21
1 files changed, 20 insertions, 1 deletions
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
index a4ef6e92739..d6dc12e5955 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
@@ -8,6 +8,7 @@ use rustc_middle::middle::region;
 use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::mir::*;
 use rustc_middle::thir::*;
+use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::cast::{CastTy, mir_cast_kind};
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::{self, Ty, UpvarArgs};
@@ -656,6 +657,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         block.and(rvalue)
     }
 
+    /// Recursively inspect a THIR expression and probe through unsizing
+    /// operations that can be const-folded today.
+    fn check_constness(&self, mut kind: &'a ExprKind<'tcx>) -> bool {
+        loop {
+            match kind {
+                &ExprKind::PointerCoercion {
+                    cast: PointerCoercion::Unsize,
+                    source: eid,
+                    is_from_as_cast: _,
+                }
+                | &ExprKind::Scope { region_scope: _, lint_level: _, value: eid } => {
+                    kind = &self.thir[eid].kind
+                }
+                _ => return matches!(Category::of(&kind), Some(Category::Constant)),
+            }
+        }
+    }
+
     fn build_zero_repeat(
         &mut self,
         mut block: BasicBlock,
@@ -666,7 +685,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let this = self;
         let value_expr = &this.thir[value];
         let elem_ty = value_expr.ty;
-        if let Some(Category::Constant) = Category::of(&value_expr.kind) {
+        if this.check_constness(&value_expr.kind) {
             // Repeating a const does nothing
         } else {
             // For a non-const, we may need to generate an appropriate `Drop`