Skip to content

Commit fa17654

Browse files
committed
Make ConstValue::Slice solely take [u8] and str
1 parent af6ac1f commit fa17654

File tree

14 files changed

+157
-162
lines changed

14 files changed

+157
-162
lines changed

src/librustc/infer/freshen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
260260

261261
ConstValue::Param(_) |
262262
ConstValue::Scalar(_) |
263-
ConstValue::Slice(..) |
263+
ConstValue::Slice { .. } |
264264
ConstValue::ByRef(..) |
265265
ConstValue::Unevaluated(..) => {}
266266
}

src/librustc/mir/interpret/value.rs

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,12 @@ pub enum ConstValue<'tcx> {
3535
/// Not using the enum `Value` to encode that this must not be `Undef`.
3636
Scalar(Scalar),
3737

38-
/// Used only for slices and strings (`&[T]`, `&str`, `*const [T]`, `*mut str`, `Box<str>`,
39-
/// etc.).
40-
///
41-
/// Empty slices don't necessarily have an address backed by an `AllocId`, thus we also need to
42-
/// enable integer pointers. The `Scalar` type covers exactly those two cases. While we could
43-
/// create dummy-`AllocId`s, the additional code effort for the conversions doesn't seem worth
44-
/// it.
45-
Slice(Scalar, u64),
38+
/// Used only for `&[u8]` and `&str`
39+
Slice {
40+
data: &'tcx Allocation,
41+
start: usize,
42+
end: usize,
43+
},
4644

4745
/// An allocation together with a pointer into the allocation.
4846
/// Invariant: the pointer's `AllocId` resolves to the allocation.
@@ -54,7 +52,7 @@ pub enum ConstValue<'tcx> {
5452
}
5553

5654
#[cfg(target_arch = "x86_64")]
57-
static_assert_size!(ConstValue<'_>, 40);
55+
static_assert_size!(ConstValue<'_>, 32);
5856

5957
impl<'tcx> ConstValue<'tcx> {
6058
#[inline]
@@ -65,7 +63,7 @@ impl<'tcx> ConstValue<'tcx> {
6563
ConstValue::Placeholder(_) |
6664
ConstValue::ByRef(..) |
6765
ConstValue::Unevaluated(..) |
68-
ConstValue::Slice(..) => None,
66+
ConstValue::Slice { .. } => None,
6967
ConstValue::Scalar(val) => Some(val),
7068
}
7169
}
@@ -79,14 +77,6 @@ impl<'tcx> ConstValue<'tcx> {
7977
pub fn try_to_ptr(&self) -> Option<Pointer> {
8078
self.try_to_scalar()?.to_ptr().ok()
8179
}
82-
83-
#[inline]
84-
pub fn new_slice(
85-
val: Scalar,
86-
len: u64,
87-
) -> Self {
88-
ConstValue::Slice(val, len)
89-
}
9080
}
9181

9282
/// A `Scalar` represents an immediate, primitive value existing outside of a

src/librustc/ty/print/pretty.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,21 +1567,27 @@ define_print_and_forward_display! {
15671567
=> p!(write("{:?}", ::std::char::from_u32(bits as u32).unwrap())),
15681568
(_, ty::FnDef(did, _)) => p!(write("{}", cx.tcx().def_path_str(*did))),
15691569
(
1570-
ConstValue::Slice(place, len),
1571-
ty::Ref(_, &ty::TyS { sty: ty::Str, .. }, _),
1570+
ConstValue::Slice { data, start, end },
1571+
ty::Ref(_, slice_ty, _),
15721572
) => {
1573-
match (place, len) {
1574-
(_, 0) => "",
1575-
(Scalar::Ptr(ptr), len) => {
1576-
let alloc = cx.tcx().alloc_map.lock().unwrap_memory(ptr.alloc_id);
1577-
assert_eq!(len as usize as u64, len);
1578-
let slice =
1579-
&alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
1580-
let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri");
1573+
let slice = &data.bytes[start..end];
1574+
match slice_ty.sty {
1575+
ty::Str => {
1576+
let s = ::std::str::from_utf8(slice)
1577+
.expect("non utf8 str from miri");
15811578
p!(write("{:?}", s))
15821579
},
1580+
ty::Slice(elem) if elem == cx.tcx().types.u8 => {
1581+
p!(write("b\""));
1582+
for &c in slice {
1583+
for e in std::ascii::escape_default(c) {
1584+
p!(write("{}", e));
1585+
}
1586+
}
1587+
p!(write("\""));
1588+
},
15831589
_ => bug!("invalid slice: {:#?}", self),
1584-
};
1590+
}
15851591
},
15861592
_ => p!(write("{:?} : ", self.val), print(self.ty)),
15871593
}

src/librustc/ty/structural_impls.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,7 +1345,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
13451345
ConstValue::Param(p) => ConstValue::Param(p.fold_with(folder)),
13461346
ConstValue::Placeholder(p) => ConstValue::Placeholder(p),
13471347
ConstValue::Scalar(a) => ConstValue::Scalar(a),
1348-
ConstValue::Slice(a, b) => ConstValue::Slice(a, b),
1348+
ConstValue::Slice { data, start, end } => ConstValue::Slice { data, start, end },
13491349
ConstValue::Unevaluated(did, substs)
13501350
=> ConstValue::Unevaluated(did, substs.fold_with(folder)),
13511351
}
@@ -1358,7 +1358,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
13581358
ConstValue::Param(p) => p.visit_with(visitor),
13591359
ConstValue::Placeholder(_) => false,
13601360
ConstValue::Scalar(_) => false,
1361-
ConstValue::Slice(..) => false,
1361+
ConstValue::Slice { .. } => false,
13621362
ConstValue::Unevaluated(_, substs) => substs.visit_with(visitor),
13631363
}
13641364
}

src/librustc/ty/sty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2207,7 +2207,7 @@ pub struct Const<'tcx> {
22072207
}
22082208

22092209
#[cfg(target_arch = "x86_64")]
2210-
static_assert_size!(Const<'_>, 48);
2210+
static_assert_size!(Const<'_>, 40);
22112211

22122212
impl<'tcx> Const<'tcx> {
22132213
#[inline]

src/librustc_codegen_ssa/mir/operand.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use rustc::mir::interpret::{ConstValue, ErrorHandled};
1+
use rustc::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar};
22
use rustc::mir;
33
use rustc::ty;
4-
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
4+
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout, Size};
55

66
use crate::base;
77
use crate::MemFlags;
@@ -92,17 +92,21 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> {
9292
);
9393
OperandValue::Immediate(llval)
9494
},
95-
ConstValue::Slice(a, b) => {
95+
ConstValue::Slice { data, start, end } => {
9696
let a_scalar = match layout.abi {
9797
layout::Abi::ScalarPair(ref a, _) => a,
9898
_ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout)
9999
};
100+
let a = Scalar::from(Pointer::new(
101+
bx.tcx().alloc_map.lock().allocate(data),
102+
Size::from_bytes(start as u64),
103+
)).into();
100104
let a_llval = bx.scalar_to_backend(
101105
a,
102106
a_scalar,
103107
bx.scalar_pair_element_backend_type(layout, 0, true),
104108
);
105-
let b_llval = bx.const_usize(b);
109+
let b_llval = bx.const_usize((end - start) as u64);
106110
OperandValue::Pair(a_llval, b_llval)
107111
},
108112
ConstValue::ByRef(ptr, alloc) => {

src/librustc_mir/const_eval.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::error::Error;
55
use std::borrow::{Borrow, Cow};
66
use std::hash::Hash;
77
use std::collections::hash_map::Entry;
8+
use std::convert::TryInto;
89

910
use rustc::hir::def::DefKind;
1011
use rustc::hir::def_id::DefId;
@@ -89,7 +90,14 @@ fn op_to_const<'tcx>(
8990
// We do not normalize just any data. Only non-union scalars and slices.
9091
let normalize = match op.layout.abi {
9192
layout::Abi::Scalar(..) => op.layout.ty.ty_adt_def().map_or(true, |adt| !adt.is_union()),
92-
layout::Abi::ScalarPair(..) => op.layout.ty.is_slice(),
93+
layout::Abi::ScalarPair(..) => match op.layout.ty.sty {
94+
ty::Ref(_, inner, _) => match inner.sty {
95+
ty::Slice(elem) => elem == ecx.tcx.types.u8,
96+
ty::Str => true,
97+
_ => false,
98+
},
99+
_ => false,
100+
},
93101
_ => false,
94102
};
95103
let normalized_op = if normalize {
@@ -101,8 +109,26 @@ fn op_to_const<'tcx>(
101109
Ok(mplace) => return mplace_to_const(ecx, mplace),
102110
Err(Immediate::Scalar(x)) =>
103111
ConstValue::Scalar(x.not_undef().unwrap()),
104-
Err(Immediate::ScalarPair(a, b)) =>
105-
ConstValue::Slice(a.not_undef().unwrap(), b.to_usize(ecx).unwrap()),
112+
Err(Immediate::ScalarPair(a, b)) => {
113+
let (data, start) = match a.not_undef().unwrap() {
114+
Scalar::Ptr(ptr) => (
115+
ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id),
116+
ptr.offset.bytes(),
117+
),
118+
Scalar::Bits { .. } => (
119+
ecx.tcx.intern_const_alloc(Allocation::from_byte_aligned_bytes(b"", ())),
120+
0,
121+
),
122+
};
123+
let len = b.to_usize(&ecx.tcx.tcx).unwrap();
124+
let start = start.try_into().unwrap();
125+
let len: usize = len.try_into().unwrap();
126+
ConstValue::Slice {
127+
data,
128+
start,
129+
end: start + len,
130+
}
131+
},
106132
};
107133
ecx.tcx.mk_const(ty::Const { val, ty: op.layout.ty })
108134
}

src/librustc_mir/hair/constant.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,16 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>(
3333
let lit = match *lit {
3434
LitKind::Str(ref s, _) => {
3535
let s = s.as_str();
36-
let id = tcx.allocate_bytes(s.as_bytes());
37-
ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64)
36+
let allocation = Allocation::from_byte_aligned_bytes(s.as_bytes(), ());
37+
let allocation = tcx.intern_const_alloc(allocation);
38+
ConstValue::Slice { data: allocation, start: 0, end: s.len() }
3839
},
3940
LitKind::Err(ref s) => {
4041
let s = s.as_str();
41-
let id = tcx.allocate_bytes(s.as_bytes());
42+
let allocation = Allocation::from_byte_aligned_bytes(s.as_bytes(), ());
43+
let allocation = tcx.intern_const_alloc(allocation);
4244
return Ok(tcx.mk_const(ty::Const {
43-
val: ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64),
45+
val: ConstValue::Slice{ data: allocation, start: 0, end: s.len() },
4446
ty: tcx.types.err,
4547
}));
4648
},

0 commit comments

Comments
 (0)