diff options
| author | ben <benlewisj@gmail.com> | 2019-09-28 14:35:04 +1200 |
|---|---|---|
| committer | ben <benlewisj@gmail.com> | 2019-09-28 14:35:04 +1200 |
| commit | c94fea092e0a8f38855e2ed9a57704cd4ca85a38 (patch) | |
| tree | f41554d10b5fc6242856c836307926c21fd8942e | |
| parent | 875fa72f9e8ff3c6fd955bc5ed0de0c9b72da400 (diff) | |
| download | rust-c94fea092e0a8f38855e2ed9a57704cd4ca85a38.tar.gz rust-c94fea092e0a8f38855e2ed9a57704cd4ca85a38.zip | |
Move `get_slice_bytes` to `rustc::mir::interpret` so it can be reused.
| -rw-r--r-- | src/librustc/mir/interpret/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc/mir/interpret/value.rs | 15 | ||||
| -rw-r--r-- | src/librustc/ty/relate.rs | 22 | ||||
| -rw-r--r-- | src/librustc_mir/hair/pattern/mod.rs | 29 |
4 files changed, 26 insertions, 42 deletions
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index cd58396d95c..e925d7429ff 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -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}; diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index b8bc7414197..32f45cd9d47 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -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"); + } +} diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 6d81e36e928..3bd61e34554 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -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, diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 4d2fee3d160..fcdf2719ab6 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -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); } _ => (), } |
