Skip to content

Commit

Permalink
Merge pull request rust-lang#147 from oli-obk/rustup
Browse files Browse the repository at this point in the history
rustup to rustc 1.17.0-nightly (60a0edc 2017-02-26)
  • Loading branch information
solson committed Mar 14, 2017
2 parents ed0feee + 80be25e commit 6ee8595
Show file tree
Hide file tree
Showing 12 changed files with 357 additions and 176 deletions.
9 changes: 4 additions & 5 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use std::error::Error;
use std::fmt;
use rustc::mir;
use rustc::ty::{BareFnTy, Ty, FnSig, layout};
use syntax::abi::Abi;
use rustc::ty::{FnSig, Ty, layout};
use memory::{Pointer, Function};
use rustc_const_math::ConstMathErr;
use syntax::codemap::Span;

#[derive(Clone, Debug)]
pub enum EvalError<'tcx> {
FunctionPointerTyMismatch(Abi, &'tcx FnSig<'tcx>, &'tcx BareFnTy<'tcx>),
FunctionPointerTyMismatch(FnSig<'tcx>, FnSig<'tcx>),
NoMirFor(String),
UnterminatedCString(Pointer),
DanglingPointerDeref,
Expand Down Expand Up @@ -151,8 +150,8 @@ impl<'tcx> fmt::Display for EvalError<'tcx> {
ptr.offset, ptr.offset + size, ptr.alloc_id, allocation_size)
},
EvalError::NoMirFor(ref func) => write!(f, "no mir for `{}`", func),
EvalError::FunctionPointerTyMismatch(abi, sig, got) =>
write!(f, "tried to call a function with abi {:?} and sig {:?} through a function pointer of type {:?}", abi, sig, got),
EvalError::FunctionPointerTyMismatch(sig, got) =>
write!(f, "tried to call a function with sig {} through a function pointer of type {}", sig, got),
EvalError::ArrayIndexOutOfBounds(span, len, index) =>
write!(f, "index out of bounds: the len is {} but the index is {} at {:?}", len, index, span),
EvalError::Math(span, ref err) =>
Expand Down
47 changes: 31 additions & 16 deletions src/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc::mir;
use rustc::traits::Reveal;
use rustc::ty::layout::{self, Layout, Size};
use rustc::ty::subst::{self, Subst, Substs};
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable, Binder};
use rustc_data_structures::indexed_vec::Idx;
use syntax::codemap::{self, DUMMY_SP};

Expand Down Expand Up @@ -181,8 +181,6 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {

Float(ConstFloat::F32(f)) => PrimVal::from_f32(f),
Float(ConstFloat::F64(f)) => PrimVal::from_f64(f),
Float(ConstFloat::FInfer { .. }) =>
bug!("uninferred constants only exist before typeck"),

Bool(b) => PrimVal::from_bool(b),
Char(c) => PrimVal::from_char(c),
Expand All @@ -196,7 +194,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {

Struct(_) => unimplemented!(),
Tuple(_) => unimplemented!(),
Function(_) => unimplemented!(),
Function(_, _) => unimplemented!(),
Array(_) => unimplemented!(),
Repeat(_, _) => unimplemented!(),
};
Expand Down Expand Up @@ -227,6 +225,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
self.tcx.normalize_associated_type(&substituted)
}

pub fn erase_lifetimes<T>(&self, value: &Binder<T>) -> T
where T : TypeFoldable<'tcx>
{
let value = self.tcx.erase_late_bound_regions(value);
self.tcx.erase_regions(&value)
}

pub(super) fn type_size(&self, ty: Ty<'tcx>) -> EvalResult<'tcx, Option<u64>> {
self.type_size_with_substs(ty, self.substs())
}
Expand Down Expand Up @@ -457,7 +462,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {

General { discr, ref variants, .. } => {
if let mir::AggregateKind::Adt(adt_def, variant, _, _) = *kind {
let discr_val = adt_def.variants[variant].disr_val;
let discr_val = adt_def.discriminants(self.tcx)
.nth(variant)
.expect("broken mir: Adt variant id invalid")
.to_u128_unchecked();
let discr_size = discr.size().bytes();
if variants[variant].packed {
let ptr = self.force_allocation(dest)?.to_ptr_and_extra().0;
Expand Down Expand Up @@ -530,7 +538,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
CEnum { .. } => {
assert_eq!(operands.len(), 0);
if let mir::AggregateKind::Adt(adt_def, variant, _, _) = *kind {
let n = adt_def.variants[variant].disr_val;
let n = adt_def.discriminants(self.tcx)
.nth(variant)
.expect("broken mir: Adt variant index invalid")
.to_u128_unchecked();
self.write_primval(dest, PrimVal::Bytes(n), dest_ty)?;
} else {
bug!("tried to assign {:?} to Layout::CEnum", kind);
Expand Down Expand Up @@ -640,25 +651,29 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
}

ReifyFnPointer => match self.operand_ty(operand).sty {
ty::TyFnDef(def_id, substs, fn_ty) => {
let fn_ty = self.tcx.erase_regions(&fn_ty);
let fn_ptr = self.memory.create_fn_ptr(self.tcx,def_id, substs, fn_ty);
ty::TyFnDef(def_id, substs, sig) => {
let fn_ptr = self.memory.create_fn_ptr(def_id, substs, sig);
self.write_value(Value::ByVal(PrimVal::Ptr(fn_ptr)), dest, dest_ty)?;
},
ref other => bug!("reify fn pointer on {:?}", other),
},

UnsafeFnPointer => match dest_ty.sty {
ty::TyFnPtr(unsafe_fn_ty) => {
ty::TyFnPtr(_) => {
let src = self.eval_operand(operand)?;
let ptr = src.read_ptr(&self.memory)?;
let fn_def = self.memory.get_fn(ptr.alloc_id)?.expect_concrete()?;
let unsafe_fn_ty = self.tcx.erase_regions(&unsafe_fn_ty);
let fn_ptr = self.memory.create_fn_ptr(self.tcx, fn_def.def_id, fn_def.substs, unsafe_fn_ty);
self.write_value(Value::ByVal(PrimVal::Ptr(fn_ptr)), dest, dest_ty)?;
self.write_value(src, dest, dest_ty)?;
},
ref other => bug!("fn to unsafe fn cast on {:?}", other),
},

ClosureFnPointer => match self.operand_ty(operand).sty {
ty::TyClosure(def_id, substs) => {
let fn_ty = self.tcx.closure_type(def_id);
let fn_ptr = self.memory.create_fn_ptr_from_noncapture_closure(def_id, substs, fn_ty);
self.write_value(Value::ByVal(PrimVal::Ptr(fn_ptr)), dest, dest_ty)?;
},
ref other => bug!("reify fn pointer on {:?}", other),
},
}
}

Expand All @@ -668,7 +683,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let ptr = self.force_allocation(lval)?.to_ptr();
let discr_val = self.read_discriminant_value(ptr, ty)?;
if let ty::TyAdt(adt_def, _) = ty.sty {
if adt_def.variants.iter().all(|v| discr_val != v.disr_val) {
if adt_def.discriminants(self.tcx).all(|v| discr_val != v.to_u128_unchecked()) {
return Err(EvalError::InvalidDiscriminant);
}
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/lvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
Local(mir::RETURN_POINTER) => self.frame().return_lvalue,
Local(local) => Lvalue::Local { frame: self.stack.len() - 1, local, field: None },

Static(def_id) => {
Static(ref static_) => {
let substs = self.tcx.intern_substs(&[]);
Lvalue::Global(GlobalId { def_id, substs, promoted: None })
Lvalue::Global(GlobalId { def_id: static_.def_id, substs, promoted: None })
}

Projection(ref proj) => return self.eval_lvalue_projection(proj),
Expand Down
67 changes: 26 additions & 41 deletions src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ use std::collections::{btree_map, BTreeMap, HashMap, HashSet, VecDeque, BTreeSet
use std::{fmt, iter, ptr, mem, io};

use rustc::hir::def_id::DefId;
use rustc::ty::{self, BareFnTy, ClosureTy, ClosureSubsts, TyCtxt};
use rustc::ty::{self, PolyFnSig, ClosureSubsts};
use rustc::ty::subst::Substs;
use rustc::ty::layout::{self, TargetDataLayout};

use syntax::abi::Abi;

use error::{EvalError, EvalResult};
use value::PrimVal;

Expand Down Expand Up @@ -109,8 +107,7 @@ impl Pointer {
pub struct FunctionDefinition<'tcx> {
pub def_id: DefId,
pub substs: &'tcx Substs<'tcx>,
pub abi: Abi,
pub sig: &'tcx ty::FnSig<'tcx>,
pub sig: PolyFnSig<'tcx>,
}

/// Either a concrete function, or a glue function
Expand All @@ -127,18 +124,14 @@ pub enum Function<'tcx> {
DropGlue(ty::Ty<'tcx>),
/// Glue required to treat the ptr part of a fat pointer
/// as a function pointer
FnPtrAsTraitObject(&'tcx ty::FnSig<'tcx>),
FnPtrAsTraitObject(PolyFnSig<'tcx>),
/// Glue for Closures
Closure(FunctionDefinition<'tcx>),
/// Glue for noncapturing closures casted to function pointers
NonCaptureClosureAsFnPtr(FunctionDefinition<'tcx>),
}

impl<'tcx> Function<'tcx> {
pub fn expect_concrete(self) -> EvalResult<'tcx, FunctionDefinition<'tcx>> {
match self {
Function::Concrete(fn_def) => Ok(fn_def),
other => Err(EvalError::ExpectedConcreteFunction(other)),
}
}
pub fn expect_drop_glue_real_ty(self) -> EvalResult<'tcx, ty::Ty<'tcx>> {
match self {
Function::DropGlue(real_ty) => Ok(real_ty),
Expand Down Expand Up @@ -221,50 +214,43 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
self.alloc_map.iter()
}

pub fn create_closure_ptr(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, substs: ClosureSubsts<'tcx>, fn_ty: ClosureTy<'tcx>) -> Pointer {
// FIXME: this is a hack
let fn_ty = tcx.mk_bare_fn(ty::BareFnTy {
unsafety: fn_ty.unsafety,
abi: fn_ty.abi,
sig: fn_ty.sig,
});
pub fn create_closure_ptr(&mut self, def_id: DefId, substs: ClosureSubsts<'tcx>, sig: PolyFnSig<'tcx>) -> Pointer {
self.create_fn_alloc(Function::Closure(FunctionDefinition {
def_id,
substs: substs.substs,
abi: fn_ty.abi,
// FIXME: why doesn't this compile?
//sig: tcx.erase_late_bound_regions(&fn_ty.sig),
sig: fn_ty.sig.skip_binder(),
sig,
}))
}

pub fn create_fn_ptr_from_noncapture_closure(&mut self, def_id: DefId, substs: ClosureSubsts<'tcx>, sig: PolyFnSig<'tcx>) -> Pointer {
self.create_fn_alloc(Function::NonCaptureClosureAsFnPtr(FunctionDefinition {
def_id,
substs: substs.substs,
sig,
}))
}

pub fn create_fn_as_trait_glue(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, substs: &'tcx Substs<'tcx>, fn_ty: &'tcx BareFnTy<'tcx>) -> Pointer {
pub fn create_fn_as_trait_glue(&mut self, def_id: DefId, substs: &'tcx Substs, sig: PolyFnSig<'tcx>) -> Pointer {
self.create_fn_alloc(Function::FnDefAsTraitObject(FunctionDefinition {
def_id,
substs,
abi: fn_ty.abi,
// FIXME: why doesn't this compile?
//sig: tcx.erase_late_bound_regions(&fn_ty.sig),
sig: fn_ty.sig.skip_binder(),
sig,
}))
}

pub fn create_fn_ptr_as_trait_glue(&mut self, fn_ty: &'tcx BareFnTy<'tcx>) -> Pointer {
self.create_fn_alloc(Function::FnPtrAsTraitObject(fn_ty.sig.skip_binder()))
pub fn create_fn_ptr_as_trait_glue(&mut self, sig: PolyFnSig<'tcx>) -> Pointer {
self.create_fn_alloc(Function::FnPtrAsTraitObject(sig))
}

pub fn create_drop_glue(&mut self, ty: ty::Ty<'tcx>) -> Pointer {
self.create_fn_alloc(Function::DropGlue(ty))
}

pub fn create_fn_ptr(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, substs: &'tcx Substs<'tcx>, fn_ty: &'tcx BareFnTy<'tcx>) -> Pointer {
pub fn create_fn_ptr(&mut self, def_id: DefId, substs: &'tcx Substs, sig: PolyFnSig<'tcx>) -> Pointer {
self.create_fn_alloc(Function::Concrete(FunctionDefinition {
def_id,
substs,
abi: fn_ty.abi,
// FIXME: why doesn't this compile?
//sig: tcx.erase_late_bound_regions(&fn_ty.sig),
sig: fn_ty.sig.skip_binder(),
sig,
}))
}

Expand Down Expand Up @@ -535,6 +521,10 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
trace!("{} closure glue for {}", msg, dump_fn_def(fn_def));
continue;
},
(None, Some(&Function::NonCaptureClosureAsFnPtr(fn_def))) => {
trace!("{} non-capture closure as fn ptr glue for {}", msg, dump_fn_def(fn_def));
continue;
},
(None, None) => {
trace!("{} (deallocated)", msg);
continue;
Expand Down Expand Up @@ -606,12 +596,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {

fn dump_fn_def<'tcx>(fn_def: FunctionDefinition<'tcx>) -> String {
let name = ty::tls::with(|tcx| tcx.item_path_str(fn_def.def_id));
let abi = if fn_def.abi == Abi::Rust {
format!("")
} else {
format!("extern {} ", fn_def.abi)
};
format!("function pointer: {}: {}{}", name, abi, fn_def.sig)
format!("function pointer: {}: {}", name, fn_def.sig.skip_binder())
}

/// Byte accessors
Expand Down
3 changes: 2 additions & 1 deletion src/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,8 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ConstantExtractor<'a, 'b, 'tcx> {
location: mir::Location
) {
self.super_lvalue(lvalue, context, location);
if let mir::Lvalue::Static(def_id) = *lvalue {
if let mir::Lvalue::Static(ref static_) = *lvalue {
let def_id = static_.def_id;
let substs = self.ecx.tcx.intern_substs(&[]);
let span = self.span;
if let Some(node_item) = self.ecx.tcx.hir.get_if_local(def_id) {
Expand Down
6 changes: 3 additions & 3 deletions src/terminator/drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let (adt_ptr, extra) = lval.to_ptr_and_extra();

// run drop impl before the fields' drop impls
if let Some(drop_def_id) = adt_def.destructor() {
if let Some(destructor) = adt_def.destructor(self.tcx) {
let trait_ref = ty::Binder(ty::TraitRef {
def_id: self.tcx.lang_items.drop_trait().unwrap(),
substs: self.tcx.mk_substs_trait(ty, &[]),
Expand All @@ -112,7 +112,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
LvalueExtra::Length(n) => Value::ByValPair(PrimVal::Ptr(adt_ptr), PrimVal::from_u128(n as u128)),
LvalueExtra::Vtable(vtable) => Value::ByValPair(PrimVal::Ptr(adt_ptr), PrimVal::Ptr(vtable)),
};
drop.push((drop_def_id, val, vtable.substs));
drop.push((destructor.did, val, vtable.substs));
}

let layout = self.type_layout(ty)?;
Expand All @@ -121,7 +121,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
Layout::General { .. } => {
let discr_val = self.read_discriminant_value(adt_ptr, ty)? as u128;
let ptr = self.force_allocation(lval)?.to_ptr();
match adt_def.variants.iter().position(|v| discr_val == v.disr_val) {
match adt_def.discriminants(self.tcx).position(|v| discr_val == v.to_u128_unchecked()) {
Some(i) => {
lval = Lvalue::Ptr {
ptr,
Expand Down
Loading

0 comments on commit 6ee8595

Please sign in to comment.