about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_mir_transform')
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs38
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs77
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs15
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs4
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs8
5 files changed, 40 insertions, 102 deletions
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index fe53de31f75..5c984984d3c 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -412,18 +412,6 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
         state: &mut State<FlatSet<Scalar>>,
     ) -> ValueOrPlace<FlatSet<Scalar>> {
         let val = match rvalue {
-            Rvalue::Len(place) => {
-                let place_ty = place.ty(self.local_decls, self.tcx);
-                if let ty::Array(_, len) = place_ty.ty.kind() {
-                    Const::Ty(self.tcx.types.usize, *len)
-                        .try_eval_scalar(self.tcx, self.typing_env)
-                        .map_or(FlatSet::Top, FlatSet::Elem)
-                } else if let [ProjectionElem::Deref] = place.projection[..] {
-                    state.get_len(place.local.into(), &self.map)
-                } else {
-                    FlatSet::Top
-                }
-            }
             Rvalue::Cast(CastKind::IntToInt | CastKind::IntToFloat, operand, ty) => {
                 let Ok(layout) = self.tcx.layout_of(self.typing_env.as_query_input(*ty)) else {
                     return ValueOrPlace::Value(FlatSet::Top);
@@ -465,15 +453,23 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
                 let (val, _overflow) = self.binary_op(state, *op, left, right);
                 val
             }
-            Rvalue::UnaryOp(op, operand) => match self.eval_operand(operand, state) {
-                FlatSet::Elem(value) => self
-                    .ecx
-                    .unary_op(*op, &value)
-                    .discard_err()
-                    .map_or(FlatSet::Top, |val| self.wrap_immediate(*val)),
-                FlatSet::Bottom => FlatSet::Bottom,
-                FlatSet::Top => FlatSet::Top,
-            },
+            Rvalue::UnaryOp(op, operand) => {
+                if let UnOp::PtrMetadata = op
+                    && let Some(place) = operand.place()
+                    && let Some(len) = self.map.find_len(place.as_ref())
+                {
+                    return ValueOrPlace::Place(len);
+                }
+                match self.eval_operand(operand, state) {
+                    FlatSet::Elem(value) => self
+                        .ecx
+                        .unary_op(*op, &value)
+                        .discard_err()
+                        .map_or(FlatSet::Top, |val| self.wrap_immediate(*val)),
+                    FlatSet::Bottom => FlatSet::Bottom,
+                    FlatSet::Top => FlatSet::Top,
+                }
+            }
             Rvalue::NullaryOp(null_op, ty) => {
                 let Ok(layout) = self.tcx.layout_of(self.typing_env.as_query_input(*ty)) else {
                     return ValueOrPlace::Value(FlatSet::Top);
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index bf6aa800d20..30e68a3f650 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -200,8 +200,6 @@ enum Value<'tcx> {
     Projection(VnIndex, ProjectionElem<VnIndex, ()>),
     /// Discriminant of the given value.
     Discriminant(VnIndex),
-    /// Length of an array or slice.
-    Len(VnIndex),
 
     // Operations.
     NullaryOp(NullOp<'tcx>, Ty<'tcx>),
@@ -477,11 +475,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                     self.ecx.discriminant_for_variant(base.layout.ty, variant).discard_err()?;
                 discr_value.into()
             }
-            Len(slice) => {
-                let slice = self.evaluated[slice].as_ref()?;
-                let len = slice.len(&self.ecx).discard_err()?;
-                ImmTy::from_uint(len, ty).into()
-            }
             NullaryOp(null_op, arg_ty) => {
                 let arg_layout = self.ecx.layout_of(arg_ty).ok()?;
                 if let NullOp::SizeOf | NullOp::AlignOf = null_op
@@ -841,7 +834,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             }
 
             // Operations.
-            Rvalue::Len(ref mut place) => return self.simplify_len(place, location),
             Rvalue::Cast(ref mut kind, ref mut value, to) => {
                 return self.simplify_cast(kind, value, to, location);
             }
@@ -1049,7 +1041,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         if op == UnOp::PtrMetadata {
             let mut was_updated = false;
             loop {
-                match self.get(arg_index) {
+                arg_index = match self.get(arg_index) {
                     // Pointer casts that preserve metadata, such as
                     // `*const [i32]` <-> `*mut [i32]` <-> `*mut [f32]`.
                     // It's critical that this not eliminate cases like
@@ -1061,9 +1053,19 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                     Value::Cast { kind: CastKind::PtrToPtr, value: inner }
                         if self.pointers_have_same_metadata(self.ty(*inner), arg_ty) =>
                     {
-                        arg_index = *inner;
-                        was_updated = true;
-                        continue;
+                        *inner
+                    }
+
+                    // We have an unsizing cast, which assigns the length to wide pointer metadata.
+                    Value::Cast {
+                        kind: CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _),
+                        value: from,
+                    } if let Some(from) = self.ty(*from).builtin_deref(true)
+                        && let ty::Array(_, len) = from.kind()
+                        && let Some(to) = self.ty(arg_index).builtin_deref(true)
+                        && let ty::Slice(..) = to.kind() =>
+                    {
+                        return Some(self.insert_constant(Const::Ty(self.tcx.types.usize, *len)));
                     }
 
                     // `&mut *p`, `&raw *p`, etc don't change metadata.
@@ -1072,18 +1074,16 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                             place.as_ref()
                             && let Some(local_index) = self.locals[local] =>
                     {
-                        arg_index = local_index;
-                        was_updated = true;
-                        continue;
+                        local_index
                     }
 
-                    _ => {
-                        if was_updated && let Some(op) = self.try_as_operand(arg_index, location) {
-                            *arg_op = op;
-                        }
-                        break;
-                    }
-                }
+                    _ => break,
+                };
+                was_updated = true;
+            }
+
+            if was_updated && let Some(op) = self.try_as_operand(arg_index, location) {
+                *arg_op = op;
             }
         }
 
@@ -1407,39 +1407,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         Some(self.insert(to, Value::Cast { kind, value }))
     }
 
-    fn simplify_len(&mut self, place: &mut Place<'tcx>, location: Location) -> Option<VnIndex> {
-        // Trivial case: we are fetching a statically known length.
-        let place_ty = place.ty(self.local_decls, self.tcx).ty;
-        if let ty::Array(_, len) = place_ty.kind() {
-            return Some(self.insert_constant(Const::Ty(self.tcx.types.usize, *len)));
-        }
-
-        let mut inner = self.simplify_place_value(place, location)?;
-
-        // The length information is stored in the wide pointer.
-        // Reborrowing copies length information from one pointer to the other.
-        while let Value::Address { place: borrowed, .. } = self.get(inner)
-            && let [PlaceElem::Deref] = borrowed.projection[..]
-            && let Some(borrowed) = self.locals[borrowed.local]
-        {
-            inner = borrowed;
-        }
-
-        // We have an unsizing cast, which assigns the length to wide pointer metadata.
-        if let Value::Cast { kind, value: from } = self.get(inner)
-            && let CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _) = kind
-            && let Some(from) = self.ty(*from).builtin_deref(true)
-            && let ty::Array(_, len) = from.kind()
-            && let Some(to) = self.ty(inner).builtin_deref(true)
-            && let ty::Slice(..) = to.kind()
-        {
-            return Some(self.insert_constant(Const::Ty(self.tcx.types.usize, *len)));
-        }
-
-        // Fallback: a symbolic `Len`.
-        Some(self.insert(self.tcx.types.usize, Value::Len(inner)))
-    }
-
     fn pointers_have_same_metadata(&self, left_ptr_ty: Ty<'tcx>, right_ptr_ty: Ty<'tcx>) -> bool {
         let left_meta_ty = left_ptr_ty.pointee_metadata_ty_or_projection(self.tcx);
         let right_meta_ty = right_ptr_ty.pointee_metadata_ty_or_projection(self.tcx);
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index 481c7941909..aaacc5866a2 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -441,7 +441,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             | Rvalue::Use(..)
             | Rvalue::CopyForDeref(..)
             | Rvalue::Repeat(..)
-            | Rvalue::Len(..)
             | Rvalue::Cast(..)
             | Rvalue::ShallowInitBox(..)
             | Rvalue::Discriminant(..)
@@ -604,20 +603,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 return None;
             }
 
-            Len(place) => {
-                let len = if let ty::Array(_, n) = place.ty(self.local_decls(), self.tcx).ty.kind()
-                {
-                    n.try_to_target_usize(self.tcx)?
-                } else {
-                    match self.get_const(place)? {
-                        Value::Immediate(src) => src.len(&self.ecx).discard_err()?,
-                        Value::Aggregate { fields, .. } => fields.len() as u64,
-                        Value::Uninit => return None,
-                    }
-                };
-                ImmTy::from_scalar(Scalar::from_target_usize(len, self), layout).into()
-            }
-
             Ref(..) | RawPtr(..) => return None,
 
             NullaryOp(ref null_op, ty) => {
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index 9ea2eb4f25d..a0b0c8c990f 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -437,9 +437,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                 self.validate_operand(op)?
             }
 
-            Rvalue::Discriminant(place) | Rvalue::Len(place) => {
-                self.validate_place(place.as_ref())?
-            }
+            Rvalue::Discriminant(place) => self.validate_place(place.as_ref())?,
 
             Rvalue::ThreadLocalRef(_) => return Err(Unpromotable),
 
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index 99e4782e470..c8a9a88dc3f 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -1064,14 +1064,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 }
             }
             Rvalue::Ref(..) => {}
-            Rvalue::Len(p) => {
-                let pty = p.ty(&self.body.local_decls, self.tcx).ty;
-                check_kinds!(
-                    pty,
-                    "Cannot compute length of non-array type {:?}",
-                    ty::Array(..) | ty::Slice(..)
-                );
-            }
             Rvalue::BinaryOp(op, vals) => {
                 use BinOp::*;
                 let a = vals.0.ty(&self.body.local_decls, self.tcx);