Skip to content

Commit 3fe4557

Browse files
authored
Merge pull request rust-lang#110 from oli-obk/rename_map_hir
rustup
2 parents 2ba883c + 0e77dd9 commit 3fe4557

File tree

3 files changed

+95
-73
lines changed

3 files changed

+95
-73
lines changed

src/eval_context.rs

Lines changed: 90 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -668,9 +668,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
668668

669669
fn type_is_fat_ptr(&self, ty: Ty<'tcx>) -> bool {
670670
match ty.sty {
671-
ty::TyRawPtr(ty::TypeAndMut{ty, ..}) |
672-
ty::TyRef(_, ty::TypeAndMut{ty, ..}) |
673-
ty::TyBox(ty) => !self.type_is_sized(ty),
671+
ty::TyRawPtr(ref tam) |
672+
ty::TyRef(_, ref tam) => !self.type_is_sized(tam.ty),
673+
ty::TyAdt(def, _) if def.is_box() => !self.type_is_sized(ty.boxed_ty()),
674674
_ => false,
675675
}
676676
}
@@ -714,26 +714,27 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
714714

715715
Ok((offset, ty))
716716
}
717+
fn get_fat_field(&self, pointee_ty: Ty<'tcx>, field_index: usize) -> EvalResult<'tcx, Ty<'tcx>> {
718+
match (field_index, &self.tcx.struct_tail(pointee_ty).sty) {
719+
(1, &ty::TyStr) |
720+
(1, &ty::TySlice(_)) => Ok(self.tcx.types.usize),
721+
(1, &ty::TyDynamic(..)) |
722+
(0, _) => Ok(self.tcx.mk_imm_ptr(self.tcx.types.u8)),
723+
_ => bug!("invalid fat pointee type: {}", pointee_ty),
724+
}
725+
}
717726

718727
pub fn get_field_ty(&self, ty: Ty<'tcx>, field_index: usize) -> EvalResult<'tcx, Ty<'tcx>> {
719728
match ty.sty {
729+
ty::TyAdt(adt_def, _) if adt_def.is_box() => self.get_fat_field(ty.boxed_ty(), field_index),
720730
ty::TyAdt(adt_def, substs) => {
721731
Ok(adt_def.struct_variant().fields[field_index].ty(self.tcx, substs))
722732
}
723733

724734
ty::TyTuple(fields) => Ok(fields[field_index]),
725735

726-
ty::TyRef(_, ty::TypeAndMut { ty, .. }) |
727-
ty::TyRawPtr(ty::TypeAndMut { ty, .. }) |
728-
ty::TyBox(ty) => {
729-
match (field_index, &self.tcx.struct_tail(ty).sty) {
730-
(1, &ty::TyStr) |
731-
(1, &ty::TySlice(_)) => Ok(self.tcx.types.usize),
732-
(1, &ty::TyDynamic(..)) |
733-
(0, _) => Ok(self.tcx.mk_imm_ptr(self.tcx.types.u8)),
734-
_ => bug!("invalid fat pointee type: {}", ty),
735-
}
736-
}
736+
ty::TyRef(_, ref tam) |
737+
ty::TyRawPtr(ref tam) => self.get_fat_field(tam.ty, field_index),
737738
_ => Err(EvalError::Unimplemented(format!("can't handle type: {:?}, {:?}", ty, ty.sty))),
738739
}
739740
}
@@ -1076,9 +1077,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
10761077

10771078
ty::TyFnPtr(_) => PrimValKind::FnPtr,
10781079

1079-
ty::TyBox(ty) |
1080-
ty::TyRef(_, ty::TypeAndMut { ty, .. }) |
1081-
ty::TyRawPtr(ty::TypeAndMut { ty, .. }) if self.type_is_sized(ty) => PrimValKind::Ptr,
1080+
ty::TyRef(_, ref tam) |
1081+
ty::TyRawPtr(ref tam) if self.type_is_sized(tam.ty) => PrimValKind::Ptr,
1082+
1083+
ty::TyAdt(ref def, _) if def.is_box() => PrimValKind::Ptr,
10821084

10831085
ty::TyAdt(..) => {
10841086
use rustc::ty::layout::Layout::*;
@@ -1132,6 +1134,23 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
11321134
}
11331135
}
11341136

1137+
fn read_ptr(&mut self, ptr: Pointer, pointee_ty: Ty<'tcx>) -> EvalResult<'tcx, Value> {
1138+
let p = self.memory.read_ptr(ptr)?;
1139+
if self.type_is_sized(pointee_ty) {
1140+
Ok(Value::ByVal(PrimVal::Ptr(p)))
1141+
} else {
1142+
trace!("reading fat pointer extra of type {}", pointee_ty);
1143+
let extra = ptr.offset(self.memory.pointer_size());
1144+
let extra = match self.tcx.struct_tail(pointee_ty).sty {
1145+
ty::TyDynamic(..) => PrimVal::Ptr(self.memory.read_ptr(extra)?),
1146+
ty::TySlice(..) |
1147+
ty::TyStr => PrimVal::from_u128(self.memory.read_usize(extra)? as u128),
1148+
_ => bug!("unsized primval ptr read from {:?}", pointee_ty),
1149+
};
1150+
Ok(Value::ByValPair(PrimVal::Ptr(p), extra))
1151+
}
1152+
}
1153+
11351154
fn try_read_value(&mut self, ptr: Pointer, ty: Ty<'tcx>) -> EvalResult<'tcx, Option<Value>> {
11361155
use syntax::ast::FloatTy;
11371156

@@ -1175,26 +1194,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
11751194
ty::TyFloat(FloatTy::F64) => PrimVal::from_f64(self.memory.read_f64(ptr)?),
11761195

11771196
ty::TyFnPtr(_) => self.memory.read_ptr(ptr).map(PrimVal::Ptr)?,
1178-
ty::TyBox(ty) |
1179-
ty::TyRef(_, ty::TypeAndMut { ty, .. }) |
1180-
ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => {
1181-
let p = self.memory.read_ptr(ptr)?;
1182-
if self.type_is_sized(ty) {
1183-
PrimVal::Ptr(p)
1184-
} else {
1185-
trace!("reading fat pointer extra of type {}", ty);
1186-
let extra = ptr.offset(self.memory.pointer_size());
1187-
let extra = match self.tcx.struct_tail(ty).sty {
1188-
ty::TyDynamic(..) => PrimVal::Ptr(self.memory.read_ptr(extra)?),
1189-
ty::TySlice(..) |
1190-
ty::TyStr => PrimVal::from_u128(self.memory.read_usize(extra)? as u128),
1191-
_ => bug!("unsized primval ptr read from {:?}", ty),
1192-
};
1193-
return Ok(Some(Value::ByValPair(PrimVal::Ptr(p), extra)));
1194-
}
1195-
}
1197+
ty::TyRef(_, ref tam) |
1198+
ty::TyRawPtr(ref tam) => return self.read_ptr(ptr, tam.ty).map(Some),
11961199

1197-
ty::TyAdt(..) => {
1200+
ty::TyAdt(def, _) => {
1201+
if def.is_box() {
1202+
return self.read_ptr(ptr, ty.boxed_ty()).map(Some);
1203+
}
11981204
use rustc::ty::layout::Layout::*;
11991205
if let CEnum { discr, signed, .. } = *self.type_layout(ty)? {
12001206
let size = discr.size().bytes();
@@ -1230,6 +1236,45 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
12301236
self.frame().substs
12311237
}
12321238

1239+
fn unsize_into_ptr(
1240+
&mut self,
1241+
src: Value,
1242+
src_ty: Ty<'tcx>,
1243+
dest: Lvalue<'tcx>,
1244+
dest_ty: Ty<'tcx>,
1245+
sty: Ty<'tcx>,
1246+
dty: Ty<'tcx>,
1247+
) -> EvalResult<'tcx, ()> {
1248+
// A<Struct> -> A<Trait> conversion
1249+
let (src_pointee_ty, dest_pointee_ty) = self.tcx.struct_lockstep_tails(sty, dty);
1250+
1251+
match (&src_pointee_ty.sty, &dest_pointee_ty.sty) {
1252+
(&ty::TyArray(_, length), &ty::TySlice(_)) => {
1253+
let ptr = src.read_ptr(&self.memory)?;
1254+
let len = PrimVal::from_u128(length as u128);
1255+
let ptr = PrimVal::Ptr(ptr);
1256+
self.write_value(Value::ByValPair(ptr, len), dest, dest_ty)
1257+
}
1258+
(&ty::TyDynamic(..), &ty::TyDynamic(..)) => {
1259+
// For now, upcasts are limited to changes in marker
1260+
// traits, and hence never actually require an actual
1261+
// change to the vtable.
1262+
self.write_value(src, dest, dest_ty)
1263+
},
1264+
(_, &ty::TyDynamic(ref data, _)) => {
1265+
let trait_ref = data.principal().unwrap().with_self_ty(self.tcx, src_pointee_ty);
1266+
let trait_ref = self.tcx.erase_regions(&trait_ref);
1267+
let vtable = self.get_vtable(trait_ref)?;
1268+
let ptr = src.read_ptr(&self.memory)?;
1269+
let ptr = PrimVal::Ptr(ptr);
1270+
let extra = PrimVal::Ptr(vtable);
1271+
self.write_value(Value::ByValPair(ptr, extra), dest, dest_ty)
1272+
},
1273+
1274+
_ => bug!("invalid unsizing {:?} -> {:?}", src_ty, dest_ty),
1275+
}
1276+
}
1277+
12331278
fn unsize_into(
12341279
&mut self,
12351280
src: Value,
@@ -1238,40 +1283,16 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
12381283
dest_ty: Ty<'tcx>,
12391284
) -> EvalResult<'tcx, ()> {
12401285
match (&src_ty.sty, &dest_ty.sty) {
1241-
(&ty::TyBox(sty), &ty::TyBox(dty)) |
1242-
(&ty::TyRef(_, ty::TypeAndMut { ty: sty, .. }), &ty::TyRef(_, ty::TypeAndMut { ty: dty, .. })) |
1243-
(&ty::TyRef(_, ty::TypeAndMut { ty: sty, .. }), &ty::TyRawPtr(ty::TypeAndMut { ty: dty, .. })) |
1244-
(&ty::TyRawPtr(ty::TypeAndMut { ty: sty, .. }), &ty::TyRawPtr(ty::TypeAndMut { ty: dty, .. })) => {
1245-
// A<Struct> -> A<Trait> conversion
1246-
let (src_pointee_ty, dest_pointee_ty) = self.tcx.struct_lockstep_tails(sty, dty);
1247-
1248-
match (&src_pointee_ty.sty, &dest_pointee_ty.sty) {
1249-
(&ty::TyArray(_, length), &ty::TySlice(_)) => {
1250-
let ptr = src.read_ptr(&self.memory)?;
1251-
let len = PrimVal::from_u128(length as u128);
1252-
let ptr = PrimVal::Ptr(ptr);
1253-
self.write_value(Value::ByValPair(ptr, len), dest, dest_ty)?;
1286+
(&ty::TyRef(_, ref s), &ty::TyRef(_, ref d)) |
1287+
(&ty::TyRef(_, ref s), &ty::TyRawPtr(ref d)) |
1288+
(&ty::TyRawPtr(ref s), &ty::TyRawPtr(ref d)) => self.unsize_into_ptr(src, src_ty, dest, dest_ty, s.ty, d.ty),
1289+
(&ty::TyAdt(def_a, substs_a), &ty::TyAdt(def_b, substs_b)) => {
1290+
if def_a.is_box() || def_b.is_box() {
1291+
if !def_a.is_box() || !def_b.is_box() {
1292+
panic!("invalid unsizing between {:?} -> {:?}", src_ty, dest_ty);
12541293
}
1255-
(&ty::TyDynamic(..), &ty::TyDynamic(..)) => {
1256-
// For now, upcasts are limited to changes in marker
1257-
// traits, and hence never actually require an actual
1258-
// change to the vtable.
1259-
self.write_value(src, dest, dest_ty)?;
1260-
},
1261-
(_, &ty::TyDynamic(ref data, _)) => {
1262-
let trait_ref = data.principal().unwrap().with_self_ty(self.tcx, src_pointee_ty);
1263-
let trait_ref = self.tcx.erase_regions(&trait_ref);
1264-
let vtable = self.get_vtable(trait_ref)?;
1265-
let ptr = src.read_ptr(&self.memory)?;
1266-
let ptr = PrimVal::Ptr(ptr);
1267-
let extra = PrimVal::Ptr(vtable);
1268-
self.write_value(Value::ByValPair(ptr, extra), dest, dest_ty)?;
1269-
},
1270-
1271-
_ => bug!("invalid unsizing {:?} -> {:?}", src_ty, dest_ty),
1294+
return self.unsize_into_ptr(src, src_ty, dest, dest_ty, src_ty.boxed_ty(), dest_ty.boxed_ty());
12721295
}
1273-
}
1274-
(&ty::TyAdt(def_a, substs_a), &ty::TyAdt(def_b, substs_b)) => {
12751296
// FIXME(solson)
12761297
let dest = self.force_allocation(dest)?.to_ptr();
12771298
// unsizing of generic struct with pointer fields
@@ -1307,10 +1328,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
13071328
self.unsize_into(Value::ByRef(src_f_ptr), src_fty, Lvalue::from_ptr(dst_f_ptr), dst_fty)?;
13081329
}
13091330
}
1331+
Ok(())
13101332
}
13111333
_ => bug!("unsize_into: invalid conversion: {:?} -> {:?}", src_ty, dest_ty),
13121334
}
1313-
Ok(())
13141335
}
13151336

13161337
pub(super) fn dump_local(&self, lvalue: Lvalue<'tcx>) {

src/lvalue.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
241241
let val = self.eval_and_read_lvalue(&proj.base)?;
242242

243243
let pointee_type = match base_ty.sty {
244-
ty::TyRawPtr(ty::TypeAndMut{ty, ..}) |
245-
ty::TyRef(_, ty::TypeAndMut{ty, ..}) |
246-
ty::TyBox(ty) => ty,
244+
ty::TyRawPtr(ref tam) |
245+
ty::TyRef(_, ref tam) => tam.ty,
246+
ty::TyAdt(ref def, _) if def.is_box() => base_ty.boxed_ty(),
247247
_ => bug!("can only deref pointer types"),
248248
};
249249

src/terminator/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
658658

659659
match ty.sty {
660660
// special case `Box` to deallocate the inner allocation
661-
ty::TyBox(contents_ty) => {
661+
ty::TyAdt(ref def, _) if def.is_box() => {
662+
let contents_ty = ty.boxed_ty();
662663
let val = self.read_lvalue(lval);
663664
// we are going through the read_value path, because that already does all the
664665
// checks for the trait object types. We'd only be repeating ourselves here.

0 commit comments

Comments
 (0)