Skip to content

Commit 122a55b

Browse files
committed
Revert "Auto merge of rust-lang#133734 - scottmcm:lower-indexing-to-ptrmetadata, r=davidtwco,RalfJung"
This reverts commit b57d93d, reversing changes made to 0aeaa5e.
1 parent 0bb4880 commit 122a55b

File tree

100 files changed

+1663
-1451
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+1663
-1451
lines changed

compiler/rustc_const_eval/src/check_consts/check.rs

+5-20
Original file line numberDiff line numberDiff line change
@@ -580,27 +580,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
580580
) => {}
581581
Rvalue::ShallowInitBox(_, _) => {}
582582

583-
Rvalue::UnaryOp(op, operand) => {
583+
Rvalue::UnaryOp(_, operand) => {
584584
let ty = operand.ty(self.body, self.tcx);
585-
match op {
586-
UnOp::Not | UnOp::Neg => {
587-
if is_int_bool_float_or_char(ty) {
588-
// Int, bool, float, and char operations are fine.
589-
} else {
590-
span_bug!(
591-
self.span,
592-
"non-primitive type in `Rvalue::UnaryOp{op:?}`: {ty:?}",
593-
);
594-
}
595-
}
596-
UnOp::PtrMetadata => {
597-
if !ty.is_ref() && !ty.is_unsafe_ptr() {
598-
span_bug!(
599-
self.span,
600-
"non-pointer type in `Rvalue::UnaryOp({op:?})`: {ty:?}",
601-
);
602-
}
603-
}
585+
if is_int_bool_float_or_char(ty) {
586+
// Int, bool, float, and char operations are fine.
587+
} else {
588+
span_bug!(self.span, "non-primitive type in `Rvalue::UnaryOp`: {:?}", ty);
604589
}
605590
}
606591

compiler/rustc_const_eval/src/interpret/step.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use rustc_middle::ty::layout::FnAbiOf;
99
use rustc_middle::ty::{self, Instance, Ty};
1010
use rustc_middle::{bug, mir, span_bug};
1111
use rustc_span::source_map::Spanned;
12-
use rustc_span::{DesugaringKind, Span};
1312
use rustc_target::callconv::FnAbi;
1413
use tracing::{info, instrument, trace};
1514

@@ -81,9 +80,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
8180
use rustc_middle::mir::StatementKind::*;
8281

8382
match &stmt.kind {
84-
Assign(box (place, rvalue)) => {
85-
self.eval_rvalue_into_place(rvalue, *place, stmt.source_info.span)?
86-
}
83+
Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?,
8784

8885
SetDiscriminant { place, variant_index } => {
8986
let dest = self.eval_place(**place)?;
@@ -162,7 +159,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
162159
&mut self,
163160
rvalue: &mir::Rvalue<'tcx>,
164161
place: mir::Place<'tcx>,
165-
span: Span,
166162
) -> InterpResult<'tcx> {
167163
let dest = self.eval_place(place)?;
168164
// FIXME: ensure some kind of non-aliasing between LHS and RHS?
@@ -254,13 +250,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
254250
let src = self.eval_place(place)?;
255251
let place = self.force_allocation(&src)?;
256252
let mut val = ImmTy::from_immediate(place.to_ref(self), dest.layout);
257-
if !place_base_raw
258-
&& span.desugaring_kind() != Some(DesugaringKind::IndexBoundsCheckReborrow)
259-
{
253+
if !place_base_raw {
260254
// If this was not already raw, it needs retagging.
261-
// As a special hack, we exclude the desugared `PtrMetadata(&raw const *_n)`
262-
// from indexing. (Really we should not do any retag on `&raw` but that does not
263-
// currently work with Stacked Borrows.)
264255
val = M::retag_ptr_value(self, mir::RetagKind::Raw, &val)?;
265256
}
266257
self.write_immediate(*val, &dest)?;

compiler/rustc_middle/src/mir/consts.rs

-3
Original file line numberDiff line numberDiff line change
@@ -467,9 +467,6 @@ impl<'tcx> Const<'tcx> {
467467
let const_val = tcx.valtree_to_const_val((ty, valtree));
468468
Self::Val(const_val, ty)
469469
}
470-
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => {
471-
Self::Unevaluated(UnevaluatedConst { def, args, promoted: None }, ty)
472-
}
473470
_ => Self::Ty(ty, c),
474471
}
475472
}

compiler/rustc_mir_build/src/builder/expr/as_place.rs

+9-83
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::mir::*;
1111
use rustc_middle::thir::*;
1212
use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance};
1313
use rustc_middle::{bug, span_bug};
14-
use rustc_span::{DesugaringKind, Span};
14+
use rustc_span::Span;
1515
use tracing::{debug, instrument, trace};
1616

1717
use crate::builder::ForGuard::{OutsideGuard, RefWithinGuard};
@@ -630,80 +630,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
630630
block.and(base_place.index(idx))
631631
}
632632

633-
/// Given a place that's either an array or a slice, returns an operand
634-
/// with the length of the array/slice.
635-
///
636-
/// For arrays it'll be `Operand::Constant` with the actual length;
637-
/// For slices it'll be `Operand::Move` of a local using `PtrMetadata`.
638-
fn len_of_slice_or_array(
639-
&mut self,
640-
block: BasicBlock,
641-
place: Place<'tcx>,
642-
span: Span,
643-
source_info: SourceInfo,
644-
) -> Operand<'tcx> {
645-
let place_ty = place.ty(&self.local_decls, self.tcx).ty;
646-
let usize_ty = self.tcx.types.usize;
647-
648-
match place_ty.kind() {
649-
ty::Array(_elem_ty, len_const) => {
650-
// We know how long an array is, so just use that as a constant
651-
// directly -- no locals needed. We do need one statement so
652-
// that borrow- and initialization-checking consider it used,
653-
// though. FIXME: Do we really *need* to count this as a use?
654-
// Could partial array tracking work off something else instead?
655-
self.cfg.push_fake_read(block, source_info, FakeReadCause::ForIndex, place);
656-
let const_ = Const::from_ty_const(*len_const, usize_ty, self.tcx);
657-
Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ }))
658-
}
659-
ty::Slice(_elem_ty) => {
660-
let ptr_or_ref = if let [PlaceElem::Deref] = place.projection[..]
661-
&& let local_ty = self.local_decls[place.local].ty
662-
&& local_ty.is_trivially_pure_clone_copy()
663-
{
664-
// It's extremely common that we have something that can be
665-
// directly passed to `PtrMetadata`, so avoid an unnecessary
666-
// temporary and statement in those cases. Note that we can
667-
// only do that for `Copy` types -- not `&mut [_]` -- because
668-
// the MIR we're building here needs to pass NLL later.
669-
Operand::Copy(Place::from(place.local))
670-
} else {
671-
let len_span = self.tcx.with_stable_hashing_context(|hcx| {
672-
let span = source_info.span;
673-
span.mark_with_reason(
674-
None,
675-
DesugaringKind::IndexBoundsCheckReborrow,
676-
span.edition(),
677-
hcx,
678-
)
679-
});
680-
let ptr_ty = Ty::new_imm_ptr(self.tcx, place_ty);
681-
let slice_ptr = self.temp(ptr_ty, span);
682-
self.cfg.push_assign(
683-
block,
684-
SourceInfo { span: len_span, ..source_info },
685-
slice_ptr,
686-
Rvalue::RawPtr(Mutability::Not, place),
687-
);
688-
Operand::Move(slice_ptr)
689-
};
690-
691-
let len = self.temp(usize_ty, span);
692-
self.cfg.push_assign(
693-
block,
694-
source_info,
695-
len,
696-
Rvalue::UnaryOp(UnOp::PtrMetadata, ptr_or_ref),
697-
);
698-
699-
Operand::Move(len)
700-
}
701-
_ => {
702-
span_bug!(span, "len called on place of type {place_ty:?}")
703-
}
704-
}
705-
}
706-
707633
fn bounds_check(
708634
&mut self,
709635
block: BasicBlock,
@@ -712,25 +638,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
712638
expr_span: Span,
713639
source_info: SourceInfo,
714640
) -> BasicBlock {
715-
let slice = slice.to_place(self);
641+
let usize_ty = self.tcx.types.usize;
642+
let bool_ty = self.tcx.types.bool;
643+
// bounds check:
644+
let len = self.temp(usize_ty, expr_span);
645+
let lt = self.temp(bool_ty, expr_span);
716646

717647
// len = len(slice)
718-
let len = self.len_of_slice_or_array(block, slice, expr_span, source_info);
719-
648+
self.cfg.push_assign(block, source_info, len, Rvalue::Len(slice.to_place(self)));
720649
// lt = idx < len
721-
let bool_ty = self.tcx.types.bool;
722-
let lt = self.temp(bool_ty, expr_span);
723650
self.cfg.push_assign(
724651
block,
725652
source_info,
726653
lt,
727654
Rvalue::BinaryOp(
728655
BinOp::Lt,
729-
Box::new((Operand::Copy(Place::from(index)), len.to_copy())),
656+
Box::new((Operand::Copy(Place::from(index)), Operand::Copy(len))),
730657
),
731658
);
732-
let msg = BoundsCheck { len, index: Operand::Copy(Place::from(index)) };
733-
659+
let msg = BoundsCheck { len: Operand::Move(len), index: Operand::Copy(Place::from(index)) };
734660
// assert!(lt, "...")
735661
self.assert(block, Operand::Move(lt), true, msg, expr_span)
736662
}

compiler/rustc_mir_transform/src/instsimplify.rs

+13
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
4646
}
4747
ctx.simplify_bool_cmp(rvalue);
4848
ctx.simplify_ref_deref(rvalue);
49+
ctx.simplify_len(rvalue);
4950
ctx.simplify_ptr_aggregate(rvalue);
5051
ctx.simplify_cast(rvalue);
5152
ctx.simplify_repeated_aggregate(rvalue);
@@ -161,6 +162,18 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
161162
}
162163
}
163164

165+
/// Transform `Len([_; N])` ==> `N`.
166+
fn simplify_len(&self, rvalue: &mut Rvalue<'tcx>) {
167+
if let Rvalue::Len(ref place) = *rvalue {
168+
let place_ty = place.ty(self.local_decls, self.tcx).ty;
169+
if let ty::Array(_, len) = *place_ty.kind() {
170+
let const_ = Const::from_ty_const(len, self.tcx.types.usize, self.tcx);
171+
let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None };
172+
*rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
173+
}
174+
}
175+
}
176+
164177
/// Transform `Aggregate(RawPtr, [p, ()])` ==> `Cast(PtrToPtr, p)`.
165178
fn simplify_ptr_aggregate(&self, rvalue: &mut Rvalue<'tcx>) {
166179
if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue

compiler/rustc_mir_transform/src/validate.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1124,6 +1124,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
11241124
);
11251125
}
11261126
UnOp::PtrMetadata => {
1127+
if !matches!(self.body.phase, MirPhase::Runtime(_)) {
1128+
// It would probably be fine to support this in earlier phases, but at
1129+
// the time of writing it's only ever introduced from intrinsic
1130+
// lowering or other runtime-phase optimization passes, so earlier
1131+
// things can just `bug!` on it.
1132+
self.fail(location, "PtrMetadata should be in runtime MIR only");
1133+
}
1134+
11271135
check_kinds!(
11281136
a,
11291137
"Cannot PtrMetadata non-pointer non-reference type {:?}",

compiler/rustc_span/src/hygiene.rs

-4
Original file line numberDiff line numberDiff line change
@@ -1163,9 +1163,6 @@ pub enum DesugaringKind {
11631163
WhileLoop,
11641164
/// `async Fn()` bound modifier
11651165
BoundModifier,
1166-
/// Marks a `&raw const *_1` needed as part of getting the length of a mutable
1167-
/// slice for the bounds check, so that MIRI's retag handling can recognize it.
1168-
IndexBoundsCheckReborrow,
11691166
}
11701167

11711168
impl DesugaringKind {
@@ -1182,7 +1179,6 @@ impl DesugaringKind {
11821179
DesugaringKind::ForLoop => "`for` loop",
11831180
DesugaringKind::WhileLoop => "`while` loop",
11841181
DesugaringKind::BoundModifier => "trait bound modifier",
1185-
DesugaringKind::IndexBoundsCheckReborrow => "slice indexing",
11861182
}
11871183
}
11881184
}

tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir

+5-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ fn main() -> () {
77
let mut _5: u32;
88
let mut _6: *mut usize;
99
let _7: usize;
10-
let mut _8: bool;
10+
let mut _8: usize;
11+
let mut _9: bool;
1112
scope 1 {
1213
debug x => _1;
1314
let mut _2: usize;
@@ -40,8 +41,9 @@ fn main() -> () {
4041
StorageDead(_6);
4142
StorageLive(_7);
4243
_7 = copy _2;
43-
_8 = Lt(copy _7, const 3_usize);
44-
assert(move _8, "index out of bounds: the length is {} but the index is {}", const 3_usize, copy _7) -> [success: bb2, unwind unreachable];
44+
_8 = Len(_1);
45+
_9 = Lt(copy _7, copy _8);
46+
assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable];
4547
}
4648

4749
bb2: {

tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir

+5-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ fn main() -> () {
77
let mut _5: u32;
88
let mut _6: *mut usize;
99
let _7: usize;
10-
let mut _8: bool;
10+
let mut _8: usize;
11+
let mut _9: bool;
1112
scope 1 {
1213
debug x => _1;
1314
let mut _2: usize;
@@ -40,8 +41,9 @@ fn main() -> () {
4041
StorageDead(_6);
4142
StorageLive(_7);
4243
_7 = copy _2;
43-
_8 = Lt(copy _7, const 3_usize);
44-
assert(move _8, "index out of bounds: the length is {} but the index is {}", const 3_usize, copy _7) -> [success: bb2, unwind continue];
44+
_8 = Len(_1);
45+
_9 = Lt(copy _7, copy _8);
46+
assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue];
4547
}
4648

4749
bb2: {

tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir

-31
This file was deleted.

tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir

-31
This file was deleted.

0 commit comments

Comments
 (0)