Skip to content

Commit c38da2e

Browse files
committed
Introduce Rvalue::ShallowInitBox
1 parent 308dffd commit c38da2e

File tree

19 files changed

+68
-11
lines changed

19 files changed

+68
-11
lines changed

compiler/rustc_borrowck/src/invalidation.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
316316
Rvalue::Use(ref operand)
317317
| Rvalue::Repeat(ref operand, _)
318318
| Rvalue::UnaryOp(_ /*un_op*/, ref operand)
319-
| Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/) => {
319+
| Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/)
320+
| Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => {
320321
self.consume_operand(location, operand)
321322
}
322323

compiler/rustc_borrowck/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1361,7 +1361,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
13611361
Rvalue::Use(ref operand)
13621362
| Rvalue::Repeat(ref operand, _)
13631363
| Rvalue::UnaryOp(_ /*un_op*/, ref operand)
1364-
| Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/) => {
1364+
| Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/)
1365+
| Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => {
13651366
self.consume_operand(location, (operand, span), flow_state)
13661367
}
13671368

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2018,13 +2018,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20182018
}
20192019
}
20202020

2021-
Rvalue::NullaryOp(_, ty) => {
2022-
// Even with unsized locals cannot box an unsized value.
2023-
if self.unsized_feature_enabled() {
2024-
let span = body.source_info(location).span;
2025-
self.ensure_place_sized(ty, span);
2026-
}
2027-
2021+
Rvalue::NullaryOp(_, ty) | Rvalue::ShallowInitBox(_, ty) => {
20282022
let trait_ref = ty::TraitRef {
20292023
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
20302024
substs: tcx.mk_substs_trait(ty, &[]),
@@ -2357,6 +2351,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
23572351
| Rvalue::AddressOf(..)
23582352
| Rvalue::Len(..)
23592353
| Rvalue::Cast(..)
2354+
| Rvalue::ShallowInitBox(..)
23602355
| Rvalue::BinaryOp(..)
23612356
| Rvalue::CheckedBinaryOp(..)
23622357
| Rvalue::NullaryOp(..)

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,13 @@ fn codegen_stmt<'tcx>(
701701
let len = codegen_array_len(fx, place);
702702
lval.write_cvalue(fx, CValue::by_val(len, usize_layout));
703703
}
704+
Rvalue::ShallowInitBox(ref operand, content_ty) => {
705+
let content_ty = fx.monomorphize(content_ty);
706+
let box_layout = fx.layout_of(fx.tcx.mk_box(content_ty));
707+
let operand = codegen_operand(fx, operand);
708+
let operand = operand.load_scalar(fx);
709+
lval.write_cvalue(fx, CValue::by_val(operand, box_layout));
710+
}
704711
Rvalue::NullaryOp(NullOp::Box, content_ty) => {
705712
let usize_type = fx.clif_type(fx.tcx.types.usize).unwrap();
706713
let content_ty = fx.monomorphize(content_ty);

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
550550
OperandRef::new_zst(&mut bx, self.cx.layout_of(self.monomorphize(ty)));
551551
(bx, operand)
552552
}
553+
mir::Rvalue::ShallowInitBox(ref operand, content_ty) => {
554+
let operand = self.codegen_operand(&mut bx, operand);
555+
let lloperand = operand.immediate();
556+
557+
let content_ty = self.monomorphize(content_ty);
558+
let box_layout = bx.cx().layout_of(bx.tcx().mk_box(content_ty));
559+
let llty_ptr = bx.cx().backend_type(box_layout);
560+
561+
let val = bx.pointercast(lloperand, llty_ptr);
562+
let operand = OperandRef { val: OperandValue::Immediate(val), layout: box_layout };
563+
(bx, operand)
564+
}
553565
}
554566
}
555567

@@ -763,6 +775,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
763775
mir::Rvalue::AddressOf(..) |
764776
mir::Rvalue::Len(..) |
765777
mir::Rvalue::Cast(..) | // (*)
778+
mir::Rvalue::ShallowInitBox(..) | // (*)
766779
mir::Rvalue::BinaryOp(..) |
767780
mir::Rvalue::CheckedBinaryOp(..) |
768781
mir::Rvalue::UnaryOp(..) |

compiler/rustc_const_eval/src/interpret/step.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
289289
self.write_scalar(Scalar::from_machine_usize(val, self), &dest)?;
290290
}
291291

292+
ShallowInitBox(ref operand, _) => {
293+
let src = self.eval_operand(operand, None)?;
294+
let v = self.read_immediate(&src)?;
295+
self.write_immediate(*v, &dest)?;
296+
}
297+
292298
Cast(cast_kind, ref operand, cast_ty) => {
293299
let src = self.eval_operand(operand, None)?;
294300
let cast_ty = self.subst_from_current_frame_and_normalize_erasing_regions(cast_ty);

compiler/rustc_const_eval/src/transform/check_consts/check.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
650650

651651
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {}
652652
Rvalue::NullaryOp(NullOp::Box, _) => self.check_op(ops::HeapAllocation),
653+
Rvalue::ShallowInitBox(_, _) => {}
653654

654655
Rvalue::UnaryOp(_, ref operand) => {
655656
let ty = operand.ty(self.body, self.tcx);

compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,8 @@ where
206206
Rvalue::Use(operand)
207207
| Rvalue::Repeat(operand, _)
208208
| Rvalue::UnaryOp(_, operand)
209-
| Rvalue::Cast(_, operand, _) => in_operand::<Q, _>(cx, in_local, operand),
209+
| Rvalue::Cast(_, operand, _)
210+
| Rvalue::ShallowInitBox(operand, _) => in_operand::<Q, _>(cx, in_local, operand),
210211

211212
Rvalue::BinaryOp(_, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(_, box (lhs, rhs)) => {
212213
in_operand::<Q, _>(cx, in_local, lhs) || in_operand::<Q, _>(cx, in_local, rhs)

compiler/rustc_const_eval/src/transform/promote_consts.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,8 @@ impl<'tcx> Validator<'_, 'tcx> {
523523
NullOp::AlignOf => {}
524524
},
525525

526+
Rvalue::ShallowInitBox(_, _) => return Err(Unpromotable),
527+
526528
Rvalue::UnaryOp(op, operand) => {
527529
match op {
528530
// These operations can never fail.

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2200,6 +2200,12 @@ pub enum Rvalue<'tcx> {
22002200
/// that `Foo` has a destructor. These rvalues can be optimized
22012201
/// away after type-checking and before lowering.
22022202
Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
2203+
2204+
/// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
2205+
///
2206+
/// This is different a normal transmute because dataflow analysis will treat the box
2207+
/// as initialized but its content as uninitialized.
2208+
ShallowInitBox(Operand<'tcx>, Ty<'tcx>),
22032209
}
22042210

22052211
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
@@ -2450,6 +2456,10 @@ impl<'tcx> Debug for Rvalue<'tcx> {
24502456
}),
24512457
}
24522458
}
2459+
2460+
ShallowInitBox(ref place, ref ty) => {
2461+
write!(fmt, "ShallowInitBox({:?}, {:?})", place, ty)
2462+
}
24532463
}
24542464
}
24552465
}

compiler/rustc_middle/src/mir/tcx.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ impl<'tcx> Rvalue<'tcx> {
206206
tcx.mk_generator(did, substs, movability)
207207
}
208208
},
209+
Rvalue::ShallowInitBox(_, ty) => tcx.mk_box(ty),
209210
}
210211
}
211212

@@ -214,7 +215,9 @@ impl<'tcx> Rvalue<'tcx> {
214215
/// whether its only shallowly initialized (`Rvalue::Box`).
215216
pub fn initialization_state(&self) -> RvalueInitializationState {
216217
match *self {
217-
Rvalue::NullaryOp(NullOp::Box, _) => RvalueInitializationState::Shallow,
218+
Rvalue::NullaryOp(NullOp::Box, _) | Rvalue::ShallowInitBox(_, _) => {
219+
RvalueInitializationState::Shallow
220+
}
218221
_ => RvalueInitializationState::Deep,
219222
}
220223
}

compiler/rustc_middle/src/mir/type_foldable.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
210210
});
211211
Aggregate(kind, fields.fold_with(folder))
212212
}
213+
ShallowInitBox(op, ty) => ShallowInitBox(op.fold_with(folder), ty.fold_with(folder)),
213214
}
214215
}
215216

@@ -255,6 +256,10 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
255256
}
256257
fields.visit_with(visitor)
257258
}
259+
ShallowInitBox(ref op, ty) => {
260+
op.visit_with(visitor)?;
261+
ty.visit_with(visitor)
262+
}
258263
}
259264
}
260265
}

compiler/rustc_middle/src/mir/visit.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,11 @@ macro_rules! make_mir_visitor {
753753
self.visit_operand(operand, location);
754754
}
755755
}
756+
757+
Rvalue::ShallowInitBox(operand, ty) => {
758+
self.visit_operand(operand, location);
759+
self.visit_ty(ty, TyContext::Location(location));
760+
}
756761
}
757762
}
758763

compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ where
169169
}
170170

171171
mir::Rvalue::Cast(..)
172+
| mir::Rvalue::ShallowInitBox(..)
172173
| mir::Rvalue::Use(..)
173174
| mir::Rvalue::ThreadLocalRef(..)
174175
| mir::Rvalue::Repeat(..)

compiler/rustc_mir_dataflow/src/move_paths/builder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
327327
Rvalue::Use(ref operand)
328328
| Rvalue::Repeat(ref operand, _)
329329
| Rvalue::Cast(_, ref operand, _)
330+
| Rvalue::ShallowInitBox(ref operand, _)
330331
| Rvalue::UnaryOp(_, ref operand) => self.gather_operand(operand),
331332
Rvalue::BinaryOp(ref _binop, box (ref lhs, ref rhs))
332333
| Rvalue::CheckedBinaryOp(ref _binop, box (ref lhs, ref rhs)) => {

compiler/rustc_mir_transform/src/const_prop.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
723723
| Rvalue::Repeat(..)
724724
| Rvalue::Len(..)
725725
| Rvalue::Cast(..)
726+
| Rvalue::ShallowInitBox(..)
726727
| Rvalue::Discriminant(..)
727728
| Rvalue::NullaryOp(..) => {}
728729
}

compiler/rustc_mir_transform/src/dest_prop.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,7 @@ impl<'tcx> Visitor<'tcx> for BorrowCollector {
967967
}
968968

969969
Rvalue::Cast(..)
970+
| Rvalue::ShallowInitBox(..)
970971
| Rvalue::Use(..)
971972
| Rvalue::Repeat(..)
972973
| Rvalue::Len(..)

compiler/rustc_mir_transform/src/separate_const_switch.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ fn is_likely_const<'tcx>(mut tracked_place: Place<'tcx>, block: &BasicBlockData<
204204
| Rvalue::AddressOf(_, _)
205205
| Rvalue::Cast(_, Operand::Constant(_), _)
206206
| Rvalue::NullaryOp(_, _)
207+
| Rvalue::ShallowInitBox(_, _)
207208
| Rvalue::UnaryOp(_, Operand::Constant(_)) => return true,
208209

209210
// These rvalues make things ambiguous
@@ -301,6 +302,7 @@ fn find_determining_place<'tcx>(
301302
| Rvalue::ThreadLocalRef(_)
302303
| Rvalue::AddressOf(_, _)
303304
| Rvalue::NullaryOp(_, _)
305+
| Rvalue::ShallowInitBox(_, _)
304306
| Rvalue::UnaryOp(_, Operand::Constant(_))
305307
| Rvalue::Cast(_, Operand::Constant(_), _)
306308
=> return None,

src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ fn check_rvalue(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId, rvalue: &Rv
194194
},
195195
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => Ok(()),
196196
Rvalue::NullaryOp(NullOp::Box, _) => Err((span, "heap allocations are not allowed in const fn".into())),
197+
Rvalue::ShallowInitBox(_, _) => Ok(()),
197198
Rvalue::UnaryOp(_, operand) => {
198199
let ty = operand.ty(body, tcx);
199200
if ty.is_integral() || ty.is_bool() {

0 commit comments

Comments
 (0)