1
Fork 0

Move get_slice_bytes to rustc::mir::interpret so it can be reused.

This commit is contained in:
ben 2019-09-28 14:35:04 +12:00
parent 875fa72f9e
commit c94fea092e
4 changed files with 26 additions and 42 deletions

View file

@ -101,7 +101,7 @@ pub use self::error::{
InvalidProgramInfo, ResourceExhaustionInfo, UndefinedBehaviorInfo,
};
pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue};
pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue, get_slice_bytes};
pub use self::allocation::{Allocation, AllocationExtra, Relocations, UndefMask};

View file

@ -611,3 +611,18 @@ impl_stable_hash_for!(enum crate::mir::interpret::ScalarMaybeUndef {
Scalar(v),
Undef
});
/// Gets the bytes of a constant slice value.
pub fn get_slice_bytes<'tcx>(cx: &impl HasDataLayout, val: ConstValue<'tcx>) -> &'tcx [u8] {
if let ConstValue::Slice { data, start, end } = val {
let len = end - start;
data.get_bytes(
cx,
// invent a pointer, only the offset is relevant anyway
Pointer::new(AllocId(0), Size::from_bytes(start as u64)),
Size::from_bytes(len as u64),
).unwrap_or_else(|err| bug!("const slice is invalid: {:?}", err))
} else {
bug!("expected const slice, but found another const value");
}
}

View file

@ -6,9 +6,9 @@
use crate::hir::def_id::DefId;
use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
use crate::ty::{self, layout::Size, Ty, TyCtxt, TypeFoldable};
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
use crate::ty::error::{ExpectedFound, TypeError};
use crate::mir::interpret::{AllocId, ConstValue, Pointer, Scalar};
use crate::mir::interpret::{ConstValue, get_slice_bytes, Scalar};
use std::rc::Rc;
use std::iter;
use rustc_target::spec::abi;
@ -585,22 +585,8 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
// saying that we're not handling it intentionally.
(a_val @ ConstValue::Slice { .. }, b_val @ ConstValue::Slice { .. }) => {
fn get_slice_bytes<'tcx>(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>) -> &'tcx [u8] {
if let ConstValue::Slice { data, start, end } = val {
let len = end - start;
data.get_bytes(
&tcx,
// invent a pointer, only the offset is relevant anyway
Pointer::new(AllocId(0), Size::from_bytes(start as u64)),
Size::from_bytes(len as u64),
).unwrap_or_else(|err| bug!("const slice is invalid: {:?}", err))
} else {
unreachable!();
}
}
let a_bytes = get_slice_bytes(tcx, a_val);
let b_bytes = get_slice_bytes(tcx, b_val);
let a_bytes = get_slice_bytes(&tcx, a_val);
let b_bytes = get_slice_bytes(&tcx, b_val);
if a_bytes == b_bytes {
Ok(tcx.mk_const(ty::Const {
val: a_val,

View file

@ -13,12 +13,12 @@ use crate::hair::constant::*;
use rustc::lint;
use rustc::mir::{Field, BorrowKind, Mutability};
use rustc::mir::{UserTypeProjection};
use rustc::mir::interpret::{GlobalId, ConstValue, sign_extend, AllocId, Pointer};
use rustc::mir::interpret::{GlobalId, ConstValue, get_slice_bytes, sign_extend};
use rustc::traits::{ObligationCause, PredicateObligation};
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, UserType, DefIdTree};
use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations};
use rustc::ty::subst::{SubstsRef, GenericArg};
use rustc::ty::layout::{VariantIdx, Size};
use rustc::ty::layout::VariantIdx;
use rustc::hir::{self, RangeEnd};
use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
@ -1526,27 +1526,10 @@ pub fn compare_const_vals<'tcx>(
if let ty::Str = ty.kind {
match (a.val, b.val) {
(
ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a },
ConstValue::Slice { data: alloc_b, start: offset_b, end: end_b },
) => {
let len_a = end_a - offset_a;
let len_b = end_b - offset_b;
let a = alloc_a.get_bytes(
&tcx,
// invent a pointer, only the offset is relevant anyway
Pointer::new(AllocId(0), Size::from_bytes(offset_a as u64)),
Size::from_bytes(len_a as u64),
);
let b = alloc_b.get_bytes(
&tcx,
// invent a pointer, only the offset is relevant anyway
Pointer::new(AllocId(0), Size::from_bytes(offset_b as u64)),
Size::from_bytes(len_b as u64),
);
if let (Ok(a), Ok(b)) = (a, b) {
return from_bool(a == b);
}
(ConstValue::Slice { .. }, ConstValue::Slice { .. }) => {
let a_bytes = get_slice_bytes(&tcx, a.val);
let b_bytes = get_slice_bytes(&tcx, b.val);
return from_bool(a_bytes == b_bytes);
}
_ => (),
}