Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 29c5a02

Browse files
committed
Auto merge of #99309 - RalfJung:no-large-copies, r=oli-obk
interpret: make some large types not Copy Also remove some unused trait impls (mostly HashStable). This didn't find any unnecessary copies that I managed to avoid, but it might still be better to require explicit clone for these types? Not sure. r? `@oli-obk`
2 parents a289cfc + 213a25d commit 29c5a02

File tree

9 files changed

+54
-82
lines changed

9 files changed

+54
-82
lines changed

‎compiler/rustc_const_eval/src/interpret/eval_context.rs‎

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ use std::cell::Cell;
22
use std::fmt;
33
use std::mem;
44

5-
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
65
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
76
use rustc_index::vec::IndexVec;
8-
use rustc_macros::HashStable;
97
use rustc_middle::mir;
108
use rustc_middle::mir::interpret::{InterpError, InvalidProgramInfo};
119
use rustc_middle::ty::layout::{
@@ -16,7 +14,6 @@ use rustc_middle::ty::{
1614
self, query::TyCtxtAt, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable,
1715
};
1816
use rustc_mir_dataflow::storage::always_storage_live_locals;
19-
use rustc_query_system::ich::StableHashingContext;
2017
use rustc_session::Limit;
2118
use rustc_span::{Pos, Span};
2219
use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayout};
@@ -142,7 +139,7 @@ pub struct FrameInfo<'tcx> {
142139
}
143140

144141
/// Unwind information.
145-
#[derive(Clone, Copy, Eq, PartialEq, Debug,HashStable)]
142+
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
146143
pub enum StackPopUnwind {
147144
/// The cleanup block.
148145
Cleanup(mir::BasicBlock),
@@ -152,7 +149,7 @@ pub enum StackPopUnwind {
152149
NotAllowed,
153150
}
154151

155-
#[derive(Clone, Copy, Eq, PartialEq, Debug,HashStable)] // Miri debug-prints these
152+
#[derive(Clone, Copy, Eq, PartialEq, Debug)] // Miri debug-prints these
156153
pub enum StackPopCleanup {
157154
/// Jump to the next block in the caller, or cause UB if None (that's a function
158155
/// that may never return). Also store layout of return place so
@@ -168,16 +165,15 @@ pub enum StackPopCleanup {
168165
}
169166

170167
/// State of a local variable including a memoized layout
171-
#[derive(Clone, Debug,PartialEq,Eq,HashStable)]
168+
#[derive(Clone, Debug)]
172169
pub struct LocalState<'tcx, Tag: Provenance = AllocId> {
173170
pub value: LocalValue<Tag>,
174171
/// Don't modify if `Some`, this is only used to prevent computing the layout twice
175-
#[stable_hasher(ignore)]
176172
pub layout: Cell<Option<TyAndLayout<'tcx>>>,
177173
}
178174

179175
/// Current value of a local variable
180-
#[derive(Copy, Clone, PartialEq,Eq,HashStable,Debug)] // Miri debug-prints these
176+
#[derive(Copy, Clone, Debug)] // Miri debug-prints these
181177
pub enum LocalValue<Tag: Provenance = AllocId> {
182178
/// This local is not currently alive, and cannot be used at all.
183179
Dead,
@@ -678,7 +674,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
678674
body,
679675
loc: Err(body.span), // Span used for errors caused during preamble.
680676
return_to_block,
681-
return_place: *return_place,
677+
return_place: return_place.clone(),
682678
// empty local array, we fill it in below, after we are inside the stack frame and
683679
// all methods actually know about the frame
684680
locals: IndexVec::new(),
@@ -799,7 +795,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
799795
let op = self
800796
.local_to_op(self.frame(), mir::RETURN_PLACE, None)
801797
.expect("return place should always be live");
802-
let dest = self.frame().return_place;
798+
let dest = self.frame().return_place.clone();
803799
let err = self.copy_op(&op, &dest, /*allow_transmute*/ true);
804800
trace!("return value: {:?}", self.dump_place(*dest));
805801
// We delay actually short-circuiting on this error until *after* the stack frame is
@@ -1021,31 +1017,3 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> std::fmt::Debug
10211017
}
10221018
}
10231019
}
1024-
1025-
impl<'ctx, 'mir, 'tcx, Tag: Provenance, Extra> HashStable<StableHashingContext<'ctx>>
1026-
for Frame<'mir, 'tcx, Tag, Extra>
1027-
where
1028-
Extra: HashStable<StableHashingContext<'ctx>>,
1029-
Tag: HashStable<StableHashingContext<'ctx>>,
1030-
{
1031-
fn hash_stable(&self, hcx: &mut StableHashingContext<'ctx>, hasher: &mut StableHasher) {
1032-
// Exhaustive match on fields to make sure we forget no field.
1033-
let Frame {
1034-
body,
1035-
instance,
1036-
return_to_block,
1037-
return_place,
1038-
locals,
1039-
loc,
1040-
extra,
1041-
tracing_span: _,
1042-
} = self;
1043-
body.hash_stable(hcx, hasher);
1044-
instance.hash_stable(hcx, hasher);
1045-
return_to_block.hash_stable(hcx, hasher);
1046-
return_place.hash_stable(hcx, hasher);
1047-
locals.hash_stable(hcx, hasher);
1048-
loc.hash_stable(hcx, hasher);
1049-
extra.hash_stable(hcx, hasher);
1050-
}
1051-
}

‎compiler/rustc_const_eval/src/interpret/intrinsics.rs‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,8 +455,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
455455

456456
for i in 0..dest_len {
457457
let place = self.mplace_index(&dest, i)?;
458-
let value =
459-
if i == index { *elem } else { self.mplace_index(&input, i)?.into() };
458+
let value = if i == index {
459+
elem.clone()
460+
} else {
461+
self.mplace_index(&input, i)?.into()
462+
};
460463
self.copy_op(&value, &place.into(), /*allow_transmute*/ false)?;
461464
}
462465
}

‎compiler/rustc_const_eval/src/interpret/operand.rs‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
use std::fmt::Write;
55

66
use rustc_hir::def::Namespace;
7-
use rustc_macros::HashStable;
87
use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout};
98
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer};
109
use rustc_middle::ty::{ConstInt, DelaySpanBugEmitted, Ty};
@@ -25,7 +24,7 @@ use super::{
2524
/// operations and wide pointers. This idea was taken from rustc's codegen.
2625
/// In particular, thanks to `ScalarPair`, arithmetic operations and casts can be entirely
2726
/// defined on `Immediate`, and do not have to work with a `Place`.
28-
#[derive(Copy, Clone, PartialEq,Eq,HashStable,Hash,Debug)]
27+
#[derive(Copy, Clone, Debug)]
2928
pub enum Immediate<Tag: Provenance = AllocId> {
3029
/// A single scalar value (must have *initialized* `Scalar` ABI).
3130
/// FIXME: we also currently often use this for ZST.
@@ -112,7 +111,7 @@ impl<'tcx, Tag: Provenance> Immediate<Tag> {
112111

113112
// ScalarPair needs a type to interpret, so we often have an immediate and a type together
114113
// as input for binary and cast operations.
115-
#[derive(Copy,Clone, Debug)]
114+
#[derive(Clone, Debug)]
116115
pub struct ImmTy<'tcx, Tag: Provenance = AllocId> {
117116
imm: Immediate<Tag>,
118117
pub layout: TyAndLayout<'tcx>,
@@ -182,13 +181,16 @@ impl<'tcx, Tag: Provenance> std::ops::Deref for ImmTy<'tcx, Tag> {
182181
/// An `Operand` is the result of computing a `mir::Operand`. It can be immediate,
183182
/// or still in memory. The latter is an optimization, to delay reading that chunk of
184183
/// memory and to avoid having to store arbitrary-sized data here.
185-
#[derive(Copy, Clone, PartialEq,Eq,HashStable,Hash,Debug)]
184+
#[derive(Copy, Clone, Debug)]
186185
pub enum Operand<Tag: Provenance = AllocId> {
187186
Immediate(Immediate<Tag>),
188187
Indirect(MemPlace<Tag>),
189188
}
190189

191-
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
190+
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
191+
rustc_data_structures::static_assert_size!(Operand, 64);
192+
193+
#[derive(Clone, Debug)]
192194
pub struct OpTy<'tcx, Tag: Provenance = AllocId> {
193195
op: Operand<Tag>, // Keep this private; it helps enforce invariants.
194196
pub layout: TyAndLayout<'tcx>,

‎compiler/rustc_const_eval/src/interpret/place.rs‎

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use std::hash::Hash;
66

77
use rustc_ast::Mutability;
8-
use rustc_macros::HashStable;
98
use rustc_middle::mir;
109
use rustc_middle::ty;
1110
use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout};
@@ -17,7 +16,7 @@ use super::{
1716
Pointer, Provenance, Scalar, ScalarMaybeUninit,
1817
};
1918

20-
#[derive(Copy, Clone, Hash, PartialEq, Eq, HashStable,Debug)]
19+
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
2120
/// Information required for the sound usage of a `MemPlace`.
2221
pub enum MemPlaceMeta<Tag: Provenance = AllocId> {
2322
/// The unsized payload (e.g. length for slices or vtable pointer for trait objects).
@@ -47,7 +46,7 @@ impl<Tag: Provenance> MemPlaceMeta<Tag> {
4746
}
4847
}
4948

50-
#[derive(Copy, Clone, Hash, PartialEq, Eq, HashStable,Debug)]
49+
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
5150
pub struct MemPlace<Tag: Provenance = AllocId> {
5251
/// The pointer can be a pure integer, with the `None` tag.
5352
pub ptr: Pointer<Option<Tag>>,
@@ -60,7 +59,22 @@ pub struct MemPlace<Tag: Provenance = AllocId> {
6059
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
6160
rustc_data_structures::static_assert_size!(MemPlace, 40);
6261

63-
#[derive(Copy, Clone, Hash, PartialEq, Eq, HashStable, Debug)]
62+
/// A MemPlace with its layout. Constructing it is only possible in this module.
63+
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
64+
pub struct MPlaceTy<'tcx, Tag: Provenance = AllocId> {
65+
mplace: MemPlace<Tag>,
66+
pub layout: TyAndLayout<'tcx>,
67+
/// rustc does not have a proper way to represent the type of a field of a `repr(packed)` struct:
68+
/// it needs to have a different alignment than the field type would usually have.
69+
/// So we represent this here with a separate field that "overwrites" `layout.align`.
70+
/// This means `layout.align` should never be used for a `MPlaceTy`!
71+
pub align: Align,
72+
}
73+
74+
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
75+
rustc_data_structures::static_assert_size!(MPlaceTy<'_>, 64);
76+
77+
#[derive(Copy, Clone, Debug)]
6478
pub enum Place<Tag: Provenance = AllocId> {
6579
/// A place referring to a value allocated in the `Memory` system.
6680
Ptr(MemPlace<Tag>),
@@ -73,7 +87,7 @@ pub enum Place<Tag: Provenance = AllocId> {
7387
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
7488
rustc_data_structures::static_assert_size!(Place, 48);
7589

76-
#[derive(Copy,Clone, Debug)]
90+
#[derive(Clone, Debug)]
7791
pub struct PlaceTy<'tcx, Tag: Provenance = AllocId> {
7892
place: Place<Tag>, // Keep this private; it helps enforce invariants.
7993
pub layout: TyAndLayout<'tcx>,
@@ -95,21 +109,6 @@ impl<'tcx, Tag: Provenance> std::ops::Deref for PlaceTy<'tcx, Tag> {
95109
}
96110
}
97111

98-
/// A MemPlace with its layout. Constructing it is only possible in this module.
99-
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
100-
pub struct MPlaceTy<'tcx, Tag: Provenance = AllocId> {
101-
mplace: MemPlace<Tag>,
102-
pub layout: TyAndLayout<'tcx>,
103-
/// rustc does not have a proper way to represent the type of a field of a `repr(packed)` struct:
104-
/// it needs to have a different alignment than the field type would usually have.
105-
/// So we represent this here with a separate field that "overwrites" `layout.align`.
106-
/// This means `layout.align` should never be used for a `MPlaceTy`!
107-
pub align: Align,
108-
}
109-
110-
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
111-
rustc_data_structures::static_assert_size!(MPlaceTy<'_>, 64);
112-
113112
impl<'tcx, Tag: Provenance> std::ops::Deref for MPlaceTy<'tcx, Tag> {
114113
type Target = MemPlace<Tag>;
115114
#[inline(always)]

‎compiler/rustc_const_eval/src/interpret/projection.rs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ where
157157
variant: VariantIdx,
158158
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
159159
// Downcast just changes the layout
160-
let mut base = *base;
160+
let mut base = base.clone();
161161
base.layout = base.layout.for_variant(self, variant);
162162
Ok(base)
163163
}
@@ -168,7 +168,7 @@ where
168168
variant: VariantIdx,
169169
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
170170
// Downcast just changes the layout
171-
let mut base = *base;
171+
let mut base = base.clone();
172172
base.layout = base.layout.for_variant(self, variant);
173173
Ok(base)
174174
}
@@ -350,7 +350,7 @@ where
350350
use rustc_middle::mir::ProjectionElem::*;
351351
Ok(match proj_elem {
352352
OpaqueCast(ty) => {
353-
let mut place = *base;
353+
let mut place = base.clone();
354354
place.layout = self.layout_of(ty)?;
355355
place
356356
}
@@ -379,7 +379,7 @@ where
379379
use rustc_middle::mir::ProjectionElem::*;
380380
Ok(match proj_elem {
381381
OpaqueCast(ty) => {
382-
let mut op = *base;
382+
let mut op = base.clone();
383383
op.layout = self.layout_of(ty)?;
384384
op
385385
}

‎compiler/rustc_const_eval/src/interpret/terminator.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
444444
trace!("eval_fn_call: Will pass last argument by untupling");
445445
Cow::from(
446446
args.iter()
447-
.map(|&a| Ok(a))
447+
.map(|a| Ok(a.clone()))
448448
.chain(
449449
(0..untuple_arg.layout.fields.count())
450450
.map(|i| self.operand_field(untuple_arg, i)),
@@ -525,7 +525,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
525525
// We have to implement all "object safe receivers". So we have to go search for a
526526
// pointer or `dyn Trait` type, but it could be wrapped in newtypes. So recursively
527527
// unwrap those newtypes until we are there.
528-
let mut receiver = args[0];
528+
let mut receiver = args[0].clone();
529529
let receiver_place = loop {
530530
match receiver.layout.ty.kind() {
531531
ty::Ref(..) | ty::RawPtr(..) => break self.deref_operand(&receiver)?,

‎compiler/rustc_const_eval/src/interpret/visitor.rs‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use super::{InterpCx, MPlaceTy, Machine, OpTy, PlaceTy};
1313
/// A thing that we can project into, and that has a layout.
1414
/// This wouldn't have to depend on `Machine` but with the current type inference,
1515
/// that's just more convenient to work with (avoids repeating all the `Machine` bounds).
16-
pub trait Value<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Copy {
16+
pub trait Value<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Sized {
1717
/// Gets this value's layout.
1818
fn layout(&self) -> TyAndLayout<'tcx>;
1919

@@ -54,7 +54,7 @@ pub trait Value<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Copy {
5454
/// A thing that we can project into given *mutable* access to `ecx`, and that has a layout.
5555
/// This wouldn't have to depend on `Machine` but with the current type inference,
5656
/// that's just more convenient to work with (avoids repeating all the `Machine` bounds).
57-
pub trait ValueMut<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Copy {
57+
pub trait ValueMut<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Sized {
5858
/// Gets this value's layout.
5959
fn layout(&self) -> TyAndLayout<'tcx>;
6060

@@ -106,12 +106,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for OpTy<'tc
106106
&self,
107107
_ecx: &InterpCx<'mir, 'tcx, M>,
108108
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
109-
Ok(*self)
109+
Ok(self.clone())
110110
}
111111

112112
#[inline(always)]
113113
fn from_op(op: &OpTy<'tcx, M::PointerTag>) -> Self {
114-
*op
114+
op.clone()
115115
}
116116

117117
#[inline(always)]
@@ -146,20 +146,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueMut<'mir, 'tcx, M>
146146
&self,
147147
_ecx: &InterpCx<'mir, 'tcx, M>,
148148
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
149-
Ok(*self)
149+
Ok(self.clone())
150150
}
151151

152152
#[inline(always)]
153153
fn to_op_for_proj(
154154
&self,
155155
_ecx: &mut InterpCx<'mir, 'tcx, M>,
156156
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
157-
Ok(*self)
157+
Ok(self.clone())
158158
}
159159

160160
#[inline(always)]
161161
fn from_op(op: &OpTy<'tcx, M::PointerTag>) -> Self {
162-
*op
162+
op.clone()
163163
}
164164

165165
#[inline(always)]

‎compiler/rustc_mir_transform/src/const_prop.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
516516
let l = self.use_ecx(|this| this.ecx.read_immediate(&this.ecx.eval_operand(left, None)?));
517517
// Check for exceeding shifts *even if* we cannot evaluate the LHS.
518518
if op == BinOp::Shr || op == BinOp::Shl {
519-
let r = r?;
519+
let r = r.clone()?;
520520
// We need the type of the LHS. We cannot use `place_layout` as that is the type
521521
// of the result, which for checked binops is not the same!
522522
let left_ty = left.ty(self.local_decls, self.tcx);

‎compiler/rustc_mir_transform/src/const_prop_lint.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
584584
});
585585
// Check for exceeding shifts *even if* we cannot evaluate the LHS.
586586
if op == BinOp::Shr || op == BinOp::Shl {
587-
let r = r?;
587+
let r = r.clone()?;
588588
// We need the type of the LHS. We cannot use `place_layout` as that is the type
589589
// of the result, which for checked binops is not the same!
590590
let left_ty = left.ty(self.local_decls, self.tcx);
@@ -616,10 +616,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
616616
}
617617
}
618618

619-
if let (Some(l), Some(r)) = (&l, &r) {
619+
if let (Some(l), Some(r)) = (l, r) {
620620
// The remaining operators are handled through `overflowing_binary_op`.
621621
if self.use_ecx(source_info, |this| {
622-
let (_res, overflow, _ty) = this.ecx.overflowing_binary_op(op, l, r)?;
622+
let (_res, overflow, _ty) = this.ecx.overflowing_binary_op(op, &l, &r)?;
623623
Ok(overflow)
624624
})? {
625625
self.report_assert_as_lint(

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /