Skip to content

Commit e0ba421

Browse files
committed
ConstValue::ScalarPair only needs to represent slices
1 parent b8139a7 commit e0ba421

File tree

12 files changed

+53
-81
lines changed

12 files changed

+53
-81
lines changed

src/librustc/ich/impls_ty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ impl_stable_hash_for!(struct ty::FieldDef {
302302
impl_stable_hash_for!(
303303
impl<'tcx> for enum mir::interpret::ConstValue<'tcx> [ mir::interpret::ConstValue ] {
304304
Scalar(val),
305-
ScalarPair(a, b),
305+
Slice(a, b),
306306
ByRef(id, alloc, offset),
307307
}
308308
);

src/librustc/mir/interpret/value.rs

+5-16
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,23 @@ pub enum ConstValue<'tcx> {
2222
/// Not using the enum `Value` to encode that this must not be `Undef`
2323
Scalar(Scalar),
2424

25-
/// Used only for *fat pointers* with layout::abi::ScalarPair
26-
///
27-
/// Needed for pattern matching code related to slices and strings.
28-
ScalarPair(Scalar, Scalar),
25+
/// Used only for slices and strings (`&[T]`, `&str`, `*const [T]`, `*mut str`, `Box<str>`, ...)
26+
Slice(Scalar, u64),
2927

3028
/// An allocation + offset into the allocation.
3129
/// Invariant: The AllocId matches the allocation.
3230
ByRef(AllocId, &'tcx Allocation, Size),
3331
}
3432

3533
#[cfg(target_arch = "x86_64")]
36-
static_assert!(CONST_SIZE: ::std::mem::size_of::<ConstValue<'static>>() == 56);
34+
static_assert!(CONST_SIZE: ::std::mem::size_of::<ConstValue<'static>>() == 40);
3735

3836
impl<'tcx> ConstValue<'tcx> {
3937
#[inline]
4038
pub fn try_to_scalar(&self) -> Option<Scalar> {
4139
match *self {
4240
ConstValue::ByRef(..) |
43-
ConstValue::ScalarPair(..) => None,
41+
ConstValue::Slice(..) => None,
4442
ConstValue::Scalar(val) => Some(val),
4543
}
4644
}
@@ -59,17 +57,8 @@ impl<'tcx> ConstValue<'tcx> {
5957
pub fn new_slice(
6058
val: Scalar,
6159
len: u64,
62-
cx: &impl HasDataLayout
6360
) -> Self {
64-
ConstValue::ScalarPair(val, Scalar::Bits {
65-
bits: len as u128,
66-
size: cx.data_layout().pointer_size.bytes() as u8,
67-
})
68-
}
69-
70-
#[inline]
71-
pub fn new_dyn_trait(val: Scalar, vtable: Pointer) -> Self {
72-
ConstValue::ScalarPair(val, Scalar::Ptr(vtable))
61+
ConstValue::Slice(val, len)
7362
}
7463
}
7564

src/librustc/mir/mod.rs

+14-16
Original file line numberDiff line numberDiff line change
@@ -2702,23 +2702,21 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Resul
27022702
return write!(f, "{}", item_path_str(did));
27032703
}
27042704
// print string literals
2705-
if let ConstValue::ScalarPair(ptr, len) = value {
2705+
if let ConstValue::Slice(ptr, len) = value {
27062706
if let Scalar::Ptr(ptr) = ptr {
2707-
if let Scalar::Bits { bits: len, .. } = len {
2708-
if let Ref(_, &ty::TyS { sty: Str, .. }, _) = ty.sty {
2709-
return ty::tls::with(|tcx| {
2710-
let alloc = tcx.alloc_map.lock().get(ptr.alloc_id);
2711-
if let Some(interpret::AllocKind::Memory(alloc)) = alloc {
2712-
assert_eq!(len as usize as u128, len);
2713-
let slice =
2714-
&alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
2715-
let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri");
2716-
write!(f, "{:?}", s)
2717-
} else {
2718-
write!(f, "pointer to erroneous constant {:?}, {:?}", ptr, len)
2719-
}
2720-
});
2721-
}
2707+
if let Ref(_, &ty::TyS { sty: Str, .. }, _) = ty.sty {
2708+
return ty::tls::with(|tcx| {
2709+
let alloc = tcx.alloc_map.lock().get(ptr.alloc_id);
2710+
if let Some(interpret::AllocKind::Memory(alloc)) = alloc {
2711+
assert_eq!(len as usize as u64, len);
2712+
let slice =
2713+
&alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
2714+
let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri");
2715+
write!(f, "{:?}", s)
2716+
} else {
2717+
write!(f, "pointer to erroneous constant {:?}, {:?}", ptr, len)
2718+
}
2719+
});
27222720
}
27232721
}
27242722
}

src/librustc/ty/structural_impls.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ impl<'a, 'tcx> Lift<'tcx> for ConstValue<'a> {
498498
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
499499
match *self {
500500
ConstValue::Scalar(x) => Some(ConstValue::Scalar(x)),
501-
ConstValue::ScalarPair(x, y) => Some(ConstValue::ScalarPair(x, y)),
501+
ConstValue::Slice(x, y) => Some(ConstValue::Slice(x, y)),
502502
ConstValue::ByRef(x, alloc, z) => Some(ConstValue::ByRef(
503503
x, alloc.lift_to_tcx(tcx)?, z,
504504
)),

src/librustc/ty/sty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2064,7 +2064,7 @@ pub enum LazyConst<'tcx> {
20642064
}
20652065

20662066
#[cfg(target_arch = "x86_64")]
2067-
static_assert!(LAZY_CONST_SIZE: ::std::mem::size_of::<LazyConst<'static>>() == 72);
2067+
static_assert!(LAZY_CONST_SIZE: ::std::mem::size_of::<LazyConst<'static>>() == 56);
20682068

20692069
impl<'tcx> LazyConst<'tcx> {
20702070
pub fn map_evaluated<R>(self, f: impl FnOnce(Const<'tcx>) -> Option<R>) -> Option<R> {
@@ -2093,7 +2093,7 @@ pub struct Const<'tcx> {
20932093
}
20942094

20952095
#[cfg(target_arch = "x86_64")]
2096-
static_assert!(CONST_SIZE: ::std::mem::size_of::<Const<'static>>() == 64);
2096+
static_assert!(CONST_SIZE: ::std::mem::size_of::<Const<'static>>() == 48);
20972097

20982098
impl<'tcx> Const<'tcx> {
20992099
#[inline]

src/librustc_codegen_ssa/mir/operand.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -88,21 +88,17 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> {
8888
);
8989
OperandValue::Immediate(llval)
9090
},
91-
ConstValue::ScalarPair(a, b) => {
92-
let (a_scalar, b_scalar) = match layout.abi {
93-
layout::Abi::ScalarPair(ref a, ref b) => (a, b),
91+
ConstValue::Slice(a, b) => {
92+
let a_scalar = match layout.abi {
93+
layout::Abi::ScalarPair(ref a, _) => a,
9494
_ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout)
9595
};
9696
let a_llval = bx.cx().scalar_to_backend(
9797
a,
9898
a_scalar,
9999
bx.cx().scalar_pair_element_backend_type(layout, 0, true),
100100
);
101-
let b_llval = bx.cx().scalar_to_backend(
102-
b,
103-
b_scalar,
104-
bx.cx().scalar_pair_element_backend_type(layout, 1, true),
105-
);
101+
let b_llval = bx.cx().const_usize(b);
106102
OperandValue::Pair(a_llval, b_llval)
107103
},
108104
ConstValue::ByRef(_, alloc, offset) => {

src/librustc_mir/const_eval.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,7 @@ pub fn op_to_const<'tcx>(
100100
let normalize = may_normalize
101101
&& match op.layout.abi {
102102
layout::Abi::Scalar(..) => true,
103-
layout::Abi::ScalarPair(..) => {
104-
// Must be a fat pointer
105-
op.layout.ty.builtin_deref(true).is_some()
106-
},
103+
layout::Abi::ScalarPair(..) => op.layout.ty.is_slice(),
107104
_ => false,
108105
};
109106
let normalized_op = if normalize {
@@ -132,7 +129,7 @@ pub fn op_to_const<'tcx>(
132129
Ok(Immediate::Scalar(x)) =>
133130
ConstValue::Scalar(x.not_undef()?),
134131
Ok(Immediate::ScalarPair(a, b)) =>
135-
ConstValue::ScalarPair(a.not_undef()?, b.not_undef()?),
132+
ConstValue::Slice(a.not_undef()?, b.to_usize(ecx)?),
136133
};
137134
Ok(ty::Const { val, ty: op.layout.ty })
138135
}

src/librustc_mir/hair/constant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>(
3535
LitKind::Str(ref s, _) => {
3636
let s = s.as_str();
3737
let id = tcx.allocate_bytes(s.as_bytes());
38-
ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx)
38+
ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64)
3939
},
4040
LitKind::ByteStr(ref data) => {
4141
let id = tcx.allocate_bytes(data);

src/librustc_mir/hair/pattern/_match.rs

+12-11
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,16 @@ impl<'a, 'tcx> LiteralExpander<'a, 'tcx> {
221221
// unsize array to slice if pattern is array but match value or other patterns are slice
222222
(ConstValue::Scalar(Scalar::Ptr(p)), ty::Array(t, n), ty::Slice(u)) => {
223223
assert_eq!(t, u);
224-
ConstValue::ScalarPair(
224+
ConstValue::Slice(
225225
Scalar::Ptr(p),
226-
n.map_evaluated(|val| val.val.try_to_scalar()).unwrap(),
226+
n.map_evaluated(|val| val.val.try_to_scalar())
227+
.unwrap()
228+
.to_usize(&self.tcx)
229+
.unwrap(),
227230
)
228231
},
229232
// fat pointers stay the same
230-
(ConstValue::ScalarPair(..), _, _) => val,
233+
(ConstValue::Slice(..), _, _) => val,
231234
// FIXME(oli-obk): this is reachable for `const FOO: &&&u32 = &&&42;` being used
232235
_ => bug!("cannot deref {:#?}, {} -> {}", val, crty, rty),
233236
}
@@ -777,9 +780,9 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>(
777780
max_fixed_len,
778781
n.unwrap_usize(cx.tcx),
779782
),
780-
(ConstValue::ScalarPair(_, n), ty::Slice(_)) => max_fixed_len = cmp::max(
783+
(ConstValue::Slice(_, n), ty::Slice(_)) => max_fixed_len = cmp::max(
781784
max_fixed_len,
782-
n.to_usize(&cx.tcx).unwrap(),
785+
n,
783786
),
784787
_ => {},
785788
}
@@ -1414,27 +1417,25 @@ fn slice_pat_covered_by_const<'tcx>(
14141417
alloc.get_bytes(&tcx, ptr, Size::from_bytes(n)).unwrap()
14151418
},
14161419
// a slice fat pointer to a zero length slice
1417-
(ConstValue::ScalarPair(Scalar::Bits { .. }, n), ty::Slice(t)) => {
1420+
(ConstValue::Slice(Scalar::Bits { .. }, 0), ty::Slice(t)) => {
14181421
if *t != tcx.types.u8 {
14191422
// FIXME(oli-obk): can't mix const patterns with slice patterns and get
14201423
// any sort of exhaustiveness/unreachable check yet
14211424
// This solely means that we don't lint about unreachable patterns, even if some
14221425
// are definitely unreachable.
14231426
return Ok(false);
14241427
}
1425-
assert_eq!(n.to_usize(&tcx).unwrap(), 0);
14261428
&[]
14271429
},
14281430
//
1429-
(ConstValue::ScalarPair(Scalar::Ptr(ptr), n), ty::Slice(t)) => {
1431+
(ConstValue::Slice(Scalar::Ptr(ptr), n), ty::Slice(t)) => {
14301432
if *t != tcx.types.u8 {
14311433
// FIXME(oli-obk): can't mix const patterns with slice patterns and get
14321434
// any sort of exhaustiveness/unreachable check yet
14331435
// This solely means that we don't lint about unreachable patterns, even if some
14341436
// are definitely unreachable.
14351437
return Ok(false);
14361438
}
1437-
let n = n.to_usize(&tcx).unwrap();
14381439
tcx.alloc_map
14391440
.lock()
14401441
.unwrap_memory(ptr.alloc_id)
@@ -1766,12 +1767,12 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
17661767
},
17671768
ty::TyKind::Slice(t) => {
17681769
match value.val {
1769-
ConstValue::ScalarPair(ptr, n) => (
1770+
ConstValue::Slice(ptr, n) => (
17701771
ptr.to_ptr().ok().map(|ptr| (
17711772
ptr,
17721773
cx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id),
17731774
)),
1774-
n.to_bits(cx.tcx.data_layout.pointer_size).unwrap() as u64,
1775+
n,
17751776
t,
17761777
),
17771778
_ => span_bug!(

src/librustc_mir/hair/pattern/mod.rs

+8-12
Original file line numberDiff line numberDiff line change
@@ -1218,25 +1218,21 @@ pub fn compare_const_vals<'a, 'gcx, 'tcx>(
12181218
if let ty::Str = ty.value.sty {
12191219
match (a.val, b.val) {
12201220
(
1221-
ConstValue::ScalarPair(
1221+
ConstValue::Slice(
12221222
Scalar::Ptr(ptr_a),
12231223
len_a,
12241224
),
1225-
ConstValue::ScalarPair(
1225+
ConstValue::Slice(
12261226
Scalar::Ptr(ptr_b),
12271227
len_b,
12281228
),
12291229
) if ptr_a.offset.bytes() == 0 && ptr_b.offset.bytes() == 0 => {
1230-
if let Ok(len_a) = len_a.to_bits(tcx.data_layout.pointer_size) {
1231-
if let Ok(len_b) = len_b.to_bits(tcx.data_layout.pointer_size) {
1232-
if len_a == len_b {
1233-
let map = tcx.alloc_map.lock();
1234-
let alloc_a = map.unwrap_memory(ptr_a.alloc_id);
1235-
let alloc_b = map.unwrap_memory(ptr_b.alloc_id);
1236-
if alloc_a.bytes.len() as u128 == len_a {
1237-
return from_bool(alloc_a == alloc_b);
1238-
}
1239-
}
1230+
if len_a == len_b {
1231+
let map = tcx.alloc_map.lock();
1232+
let alloc_a = map.unwrap_memory(ptr_a.alloc_id);
1233+
let alloc_b = map.unwrap_memory(ptr_b.alloc_id);
1234+
if alloc_a.bytes.len() as u64 == len_a {
1235+
return from_bool(alloc_a == alloc_b);
12401236
}
12411237
}
12421238
}

src/librustc_mir/interpret/operand.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -561,10 +561,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
561561
MemPlace::from_ptr(Pointer::new(id, offset), alloc.align)
562562
).with_default_tag())
563563
},
564-
ConstValue::ScalarPair(a, b) =>
564+
ConstValue::Slice(a, b) =>
565565
Ok(Operand::Immediate(Immediate::ScalarPair(
566566
a.into(),
567-
b.into(),
567+
Scalar::from_uint(b, self.tcx.data_layout.pointer_size).into(),
568568
)).with_default_tag()),
569569
ConstValue::Scalar(x) =>
570570
Ok(Operand::Immediate(Immediate::Scalar(x.into())).with_default_tag()),

src/librustc_mir/monomorphize/collector.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -1261,12 +1261,7 @@ fn collect_const<'a, 'tcx>(
12611261
debug!("visiting const {:?}", constant);
12621262

12631263
match constant.val {
1264-
ConstValue::ScalarPair(Scalar::Ptr(a), Scalar::Ptr(b)) => {
1265-
collect_miri(tcx, a.alloc_id, output);
1266-
collect_miri(tcx, b.alloc_id, output);
1267-
}
1268-
ConstValue::ScalarPair(_, Scalar::Ptr(ptr)) |
1269-
ConstValue::ScalarPair(Scalar::Ptr(ptr), _) |
1264+
ConstValue::Slice(Scalar::Ptr(ptr), _) |
12701265
ConstValue::Scalar(Scalar::Ptr(ptr)) =>
12711266
collect_miri(tcx, ptr.alloc_id, output),
12721267
ConstValue::ByRef(_id, alloc, _offset) => {

0 commit comments

Comments
 (0)