Skip to content

Commit 3f85e19

Browse files
committed
Merge branch 'gvn-borrowed'
2 parents de7b889 + 9999848 commit 3f85e19

File tree

106 files changed

+3178
-1316
lines changed

Some content is hidden

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

106 files changed

+3178
-1316
lines changed

compiler/rustc_const_eval/src/interpret/cast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
416416
}
417417
}
418418

419-
fn unsize_into(
419+
pub fn unsize_into(
420420
&mut self,
421421
src: &OpTy<'tcx, M::Provenance>,
422422
cast_ty: TyAndLayout<'tcx>,

compiler/rustc_mir_transform/src/copy_prop.rs

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
112112

113113
fn visit_local(&mut self, local: &mut Local, ctxt: PlaceContext, _: Location) {
114114
let new_local = self.copy_classes[*local];
115+
if self.borrowed_locals.contains(*local) {
116+
return;
117+
}
115118
match ctxt {
116119
// Do not modify the local in storage statements.
117120
PlaceContext::NonUse(NonUseContext::StorageLive | NonUseContext::StorageDead) => {}
@@ -122,32 +125,16 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
122125
}
123126
}
124127

125-
fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) {
128+
fn visit_place(&mut self, place: &mut Place<'tcx>, _: PlaceContext, loc: Location) {
126129
if let Some(new_projection) = self.process_projection(place.projection, loc) {
127130
place.projection = self.tcx().mk_place_elems(&new_projection);
128131
}
129132

130-
let observes_address = match ctxt {
131-
PlaceContext::NonMutatingUse(
132-
NonMutatingUseContext::SharedBorrow
133-
| NonMutatingUseContext::FakeBorrow
134-
| NonMutatingUseContext::AddressOf,
135-
) => true,
136-
// For debuginfo, merging locals is ok.
137-
PlaceContext::NonUse(NonUseContext::VarDebugInfo) => {
138-
self.borrowed_locals.contains(place.local)
139-
}
140-
_ => false,
141-
};
142-
if observes_address && !place.is_indirect() {
143-
// We observe the address of `place.local`. Do not replace it.
144-
} else {
145-
self.visit_local(
146-
&mut place.local,
147-
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
148-
loc,
149-
)
150-
}
133+
self.visit_local(
134+
&mut place.local,
135+
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
136+
loc,
137+
)
151138
}
152139

153140
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {

compiler/rustc_mir_transform/src/dataflow_const_prop.rs

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
//!
33
//! Currently, this pass only propagates scalar values.
44
5-
use rustc_const_eval::interpret::{ImmTy, Immediate, InterpCx, OpTy, PlaceTy, Projectable};
5+
use rustc_const_eval::interpret::{
6+
ImmTy, Immediate, InterpCx, OpTy, PlaceTy, Pointer, PointerArithmetic, Projectable,
7+
};
68
use rustc_data_structures::fx::FxHashMap;
79
use rustc_hir::def::DefKind;
810
use rustc_middle::mir::interpret::{AllocId, ConstAllocation, InterpResult, Scalar};
@@ -935,12 +937,64 @@ impl<'mir, 'tcx: 'mir> rustc_const_eval::interpret::Machine<'mir, 'tcx> for Dumm
935937
}
936938

937939
fn binary_ptr_op(
938-
_ecx: &InterpCx<'mir, 'tcx, Self>,
939-
_bin_op: BinOp,
940-
_left: &rustc_const_eval::interpret::ImmTy<'tcx, Self::Provenance>,
941-
_right: &rustc_const_eval::interpret::ImmTy<'tcx, Self::Provenance>,
940+
ecx: &InterpCx<'mir, 'tcx, Self>,
941+
bin_op: BinOp,
942+
left: &rustc_const_eval::interpret::ImmTy<'tcx, Self::Provenance>,
943+
right: &rustc_const_eval::interpret::ImmTy<'tcx, Self::Provenance>,
942944
) -> interpret::InterpResult<'tcx, (ImmTy<'tcx, Self::Provenance>, bool)> {
943-
throw_machine_stop_str!("can't do pointer arithmetic");
945+
use rustc_middle::mir::BinOp::*;
946+
Ok(match bin_op {
947+
Eq | Ne | Lt | Le | Gt | Ge => {
948+
assert_eq!(left.layout.abi, right.layout.abi); // types an differ, e.g. fn ptrs with different `for`
949+
let size = ecx.pointer_size();
950+
// Just compare the bits. ScalarPairs are compared lexicographically.
951+
// We thus always compare pairs and simply fill scalars up with 0.
952+
let left = match **left {
953+
Immediate::Scalar(l) => (l.to_bits(size)?, 0),
954+
Immediate::ScalarPair(l1, l2) => (l1.to_bits(size)?, l2.to_bits(size)?),
955+
Immediate::Uninit => panic!("we should never see uninit data here"),
956+
};
957+
let right = match **right {
958+
Immediate::Scalar(r) => (r.to_bits(size)?, 0),
959+
Immediate::ScalarPair(r1, r2) => (r1.to_bits(size)?, r2.to_bits(size)?),
960+
Immediate::Uninit => panic!("we should never see uninit data here"),
961+
};
962+
let res = match bin_op {
963+
Eq => left == right,
964+
Ne => left != right,
965+
Lt => left < right,
966+
Le => left <= right,
967+
Gt => left > right,
968+
Ge => left >= right,
969+
_ => bug!(),
970+
};
971+
(ImmTy::from_bool(res, *ecx.tcx), false)
972+
}
973+
974+
// Some more operations are possible with atomics.
975+
// The return value always has the provenance of the *left* operand.
976+
Add | Sub | BitOr | BitAnd | BitXor => {
977+
assert!(left.layout.ty.is_unsafe_ptr());
978+
assert!(right.layout.ty.is_unsafe_ptr());
979+
let ptr = left.to_scalar().to_pointer(ecx)?;
980+
// We do the actual operation with usize-typed scalars.
981+
let usize_layout = ecx.layout_of(ecx.tcx.types.usize).unwrap();
982+
let left = ImmTy::from_uint(ptr.addr().bytes(), usize_layout);
983+
let right = ImmTy::from_uint(right.to_scalar().to_target_usize(ecx)?, usize_layout);
984+
let (result, overflowing) = ecx.overflowing_binary_op(bin_op, &left, &right)?;
985+
// Construct a new pointer with the provenance of `ptr` (the LHS).
986+
let result_ptr = Pointer::new(
987+
ptr.provenance,
988+
Size::from_bytes(result.to_scalar().to_target_usize(ecx)?),
989+
);
990+
(
991+
ImmTy::from_scalar(Scalar::from_maybe_pointer(result_ptr, ecx), left.layout),
992+
overflowing,
993+
)
994+
}
995+
996+
_ => span_bug!(ecx.cur_span(), "Invalid operator on pointers: {:?}", bin_op),
997+
})
944998
}
945999

9461000
fn expose_ptr(

0 commit comments

Comments
 (0)