Remove ty_open and treat Unsized lvalues as *Unsized.
This commit is contained in:
parent
2890508d97
commit
7a8a5172a5
@ -153,9 +153,6 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t
|
||||
ty::ty_err => {
|
||||
mywrite!(w, "e");
|
||||
}
|
||||
ty::ty_open(_) => {
|
||||
cx.diag.handler().bug("unexpected type in enc_sty (ty_open)");
|
||||
}
|
||||
}
|
||||
|
||||
let end = w.tell().unwrap();
|
||||
|
@ -93,7 +93,7 @@ pub fn simplify_type(tcx: &ty::ctxt,
|
||||
None
|
||||
}
|
||||
}
|
||||
ty::ty_open(_) | ty::ty_infer(_) | ty::ty_err => None,
|
||||
ty::ty_infer(_) | ty::ty_err => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||
t
|
||||
}
|
||||
|
||||
ty::ty_open(..) |
|
||||
ty::ty_bool |
|
||||
ty::ty_char |
|
||||
ty::ty_int(..) |
|
||||
|
@ -194,7 +194,6 @@ fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
|
||||
ty::ty_closure(..) |
|
||||
ty::ty_infer(..) |
|
||||
ty::ty_open(..) |
|
||||
ty::ty_err => {
|
||||
tcx.sess.bug(
|
||||
&format!("ty_is_local invoked on unexpected type: {}",
|
||||
|
@ -1626,25 +1626,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
Ok(AmbiguousBuiltin)
|
||||
}
|
||||
|
||||
ty::ty_open(ty) => {
|
||||
// these only crop up in trans, and represent an
|
||||
// "opened" unsized/existential type (one that has
|
||||
// been dereferenced)
|
||||
match bound {
|
||||
ty::BoundCopy => {
|
||||
Ok(If(vec!(ty)))
|
||||
}
|
||||
|
||||
ty::BoundSized => {
|
||||
Err(Unimplemented)
|
||||
}
|
||||
|
||||
ty::BoundSync |
|
||||
ty::BoundSend => {
|
||||
self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()");
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::ty_err => {
|
||||
Ok(If(Vec::new()))
|
||||
}
|
||||
|
@ -930,7 +930,7 @@ impl<'tcx> ctxt<'tcx> {
|
||||
sty_debug_print!(
|
||||
self,
|
||||
ty_enum, ty_uniq, ty_vec, ty_ptr, ty_rptr, ty_bare_fn, ty_trait,
|
||||
ty_struct, ty_closure, ty_tup, ty_param, ty_open, ty_infer, ty_projection);
|
||||
ty_struct, ty_closure, ty_tup, ty_param, ty_infer, ty_projection);
|
||||
|
||||
println!("Substs interner: #{}", self.substs_interner.borrow().len());
|
||||
println!("BareFnTy interner: #{}", self.bare_fn_interner.borrow().len());
|
||||
@ -1374,12 +1374,6 @@ pub enum sty<'tcx> {
|
||||
ty_projection(ProjectionTy<'tcx>),
|
||||
ty_param(ParamTy), // type parameter
|
||||
|
||||
ty_open(Ty<'tcx>), // A deref'ed fat pointer, i.e., a dynamically sized value
|
||||
// and its size. Only ever used in trans. It is not necessary
|
||||
// earlier since we don't need to distinguish a DST with its
|
||||
// size (e.g., in a deref) vs a DST with the size elsewhere (
|
||||
// e.g., in a field).
|
||||
|
||||
ty_infer(InferTy), // something used only during inference/typeck
|
||||
ty_err, // Also only used during inference/typeck, to represent
|
||||
// the type of an erroneous expression (helps cut down
|
||||
@ -2689,7 +2683,7 @@ impl FlagComputation {
|
||||
self.add_bounds(bounds);
|
||||
}
|
||||
|
||||
&ty_uniq(tt) | &ty_vec(tt, _) | &ty_open(tt) => {
|
||||
&ty_uniq(tt) | &ty_vec(tt, _) => {
|
||||
self.add_ty(tt)
|
||||
}
|
||||
|
||||
@ -2964,8 +2958,6 @@ pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'t
|
||||
mk_param(cx, def.space, def.index, def.name)
|
||||
}
|
||||
|
||||
pub fn mk_open<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, ty_open(ty)) }
|
||||
|
||||
impl<'tcx> TyS<'tcx> {
|
||||
/// Iterator that walks `self` and any types reachable from
|
||||
/// `self`, in depth-first order. Note that just walks the types
|
||||
@ -3164,7 +3156,6 @@ pub fn sequence_element_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match ty.sty {
|
||||
ty_vec(ty, _) => ty,
|
||||
ty_str => mk_mach_uint(cx, ast::TyU8),
|
||||
ty_open(ty) => sequence_element_type(cx, ty),
|
||||
_ => cx.sess.bug(&format!("sequence_element_type called on non-sequence value: {}",
|
||||
ty_to_string(cx, ty))),
|
||||
}
|
||||
@ -3583,12 +3574,6 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
|
||||
TC::All
|
||||
}
|
||||
|
||||
ty_open(ty) => {
|
||||
let result = tc_ty(cx, ty, cache);
|
||||
assert!(!result.is_sized(cx));
|
||||
result.unsafe_pointer() | TC::Nonsized
|
||||
}
|
||||
|
||||
ty_infer(_) |
|
||||
ty_err => {
|
||||
cx.sess.bug("asked to compute contents of error type");
|
||||
@ -3747,7 +3732,7 @@ pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool {
|
||||
ty_vec(_, None) => {
|
||||
false
|
||||
}
|
||||
ty_uniq(typ) | ty_open(typ) => {
|
||||
ty_uniq(typ) => {
|
||||
type_requires(cx, seen, r_ty, typ)
|
||||
}
|
||||
ty_rptr(_, ref mt) => {
|
||||
@ -4106,14 +4091,6 @@ pub fn deref<'tcx>(ty: Ty<'tcx>, explicit: bool) -> Option<mt<'tcx>> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn close_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match ty.sty {
|
||||
ty_open(ty) => mk_rptr(cx, cx.mk_region(ReStatic), mt {ty: ty, mutbl:ast::MutImmutable}),
|
||||
_ => cx.sess.bug(&format!("Trying to close a non-open type {}",
|
||||
ty_to_string(cx, ty)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_content<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match ty.sty {
|
||||
ty_uniq(ty) => ty,
|
||||
@ -4122,14 +4099,6 @@ pub fn type_content<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the unsized type in an open type (or just return ty if it is not open).
|
||||
pub fn unopen_type<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match ty.sty {
|
||||
ty_open(ty) => ty,
|
||||
_ => ty
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the type of ty[i]
|
||||
pub fn index<'tcx>(ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
|
||||
match ty.sty {
|
||||
@ -4802,7 +4771,6 @@ pub fn ty_sort_string<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> String {
|
||||
}
|
||||
}
|
||||
ty_err => "type error".to_string(),
|
||||
ty_open(_) => "opened DST".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -6328,16 +6296,15 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
|
||||
hash!(p.idx);
|
||||
hash!(token::get_name(p.name));
|
||||
}
|
||||
ty_open(_) => byte!(22),
|
||||
ty_infer(_) => unreachable!(),
|
||||
ty_err => byte!(23),
|
||||
ty_err => byte!(21),
|
||||
ty_closure(d, r, _) => {
|
||||
byte!(24);
|
||||
byte!(22);
|
||||
did(state, d);
|
||||
region(state, *r);
|
||||
}
|
||||
ty_projection(ref data) => {
|
||||
byte!(25);
|
||||
byte!(23);
|
||||
did(state, data.trait_ref.def_id);
|
||||
hash!(token::get_name(data.item_name));
|
||||
}
|
||||
@ -6666,7 +6633,6 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
|
||||
ty_projection(_) |
|
||||
ty_param(_) |
|
||||
ty_infer(_) |
|
||||
ty_open(_) |
|
||||
ty_err => {
|
||||
}
|
||||
}
|
||||
|
@ -626,9 +626,6 @@ pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
|
||||
ty::ty_vec(typ, sz) => {
|
||||
ty::ty_vec(typ.fold_with(this), sz)
|
||||
}
|
||||
ty::ty_open(typ) => {
|
||||
ty::ty_open(typ.fold_with(this))
|
||||
}
|
||||
ty::ty_enum(tid, ref substs) => {
|
||||
let substs = substs.fold_with(this);
|
||||
ty::ty_enum(tid, this.tcx().mk_substs(substs))
|
||||
|
@ -28,7 +28,7 @@ impl<'tcx> TypeWalker<'tcx> {
|
||||
ty::ty_bool | ty::ty_char | ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
|
||||
ty::ty_str | ty::ty_infer(_) | ty::ty_param(_) | ty::ty_err => {
|
||||
}
|
||||
ty::ty_uniq(ty) | ty::ty_vec(ty, _) | ty::ty_open(ty) => {
|
||||
ty::ty_uniq(ty) | ty::ty_vec(ty, _) => {
|
||||
self.stack.push(ty);
|
||||
}
|
||||
ty::ty_ptr(ref mt) | ty::ty_rptr(_, ref mt) => {
|
||||
|
@ -20,7 +20,7 @@ use middle::ty::{ReSkolemized, ReVar, BrEnv};
|
||||
use middle::ty::{mt, Ty, ParamTy};
|
||||
use middle::ty::{ty_bool, ty_char, ty_struct, ty_enum};
|
||||
use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn};
|
||||
use middle::ty::{ty_param, ty_ptr, ty_rptr, ty_tup, ty_open};
|
||||
use middle::ty::{ty_param, ty_ptr, ty_rptr, ty_tup};
|
||||
use middle::ty::{ty_closure};
|
||||
use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
|
||||
use middle::ty;
|
||||
@ -369,8 +369,6 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
|
||||
buf.push_str(&mt_to_string(cx, tm));
|
||||
buf
|
||||
}
|
||||
ty_open(typ) =>
|
||||
format!("opened<{}>", ty_to_string(cx, typ)),
|
||||
ty_tup(ref elems) => {
|
||||
let strs = elems
|
||||
.iter()
|
||||
|
@ -678,7 +678,7 @@ fn bind_subslice_pat(bcx: Block,
|
||||
}
|
||||
|
||||
fn extract_vec_elems<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
left_ty: Ty,
|
||||
left_ty: Ty<'tcx>,
|
||||
before: uint,
|
||||
after: uint,
|
||||
val: ValueRef)
|
||||
|
@ -699,7 +699,7 @@ fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, st: &Struct<'tcx>,
|
||||
st.fields.iter().filter(|&ty| !dst || type_is_sized(cx.tcx(), *ty))
|
||||
.map(|&ty| type_of::sizing_type_of(cx, ty)).collect()
|
||||
} else {
|
||||
st.fields.iter().map(|&ty| type_of::type_of(cx, ty)).collect()
|
||||
st.fields.iter().map(|&ty| type_of::in_memory_type_of(cx, ty)).collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -676,8 +676,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
|
||||
let val = if common::type_is_sized(cx.tcx(), field_ty) {
|
||||
llfld_a
|
||||
} else {
|
||||
let boxed_ty = ty::mk_open(cx.tcx(), field_ty);
|
||||
let scratch = datum::rvalue_scratch_datum(cx, boxed_ty, "__fat_ptr_iter");
|
||||
let scratch = datum::rvalue_scratch_datum(cx, field_ty, "__fat_ptr_iter");
|
||||
Store(cx, llfld_a, GEPi(cx, scratch.val, &[0, abi::FAT_PTR_ADDR]));
|
||||
Store(cx, info.unwrap(), GEPi(cx, scratch.val, &[0, abi::FAT_PTR_EXTRA]));
|
||||
scratch.val
|
||||
|
@ -123,13 +123,6 @@ pub fn type_is_sized<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
ty::type_is_sized(¶m_env, DUMMY_SP, ty)
|
||||
}
|
||||
|
||||
pub fn lltype_is_sized<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
match ty.sty {
|
||||
ty::ty_open(_) => true,
|
||||
_ => type_is_sized(cx, ty),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_is_fat_ptr<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
match ty.sty {
|
||||
ty::ty_ptr(ty::mt{ty, ..}) |
|
||||
@ -211,10 +204,15 @@ pub fn type_needs_unwind_cleanup<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_needs_drop<'tcx>(cx: &ty::ctxt<'tcx>,
|
||||
ty: Ty<'tcx>)
|
||||
-> bool {
|
||||
ty::type_contents(cx, ty).needs_drop(cx)
|
||||
pub fn type_needs_drop<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
// Unsized types cannot be dropped automatically - these are lvalues pointing
|
||||
// to alloca's containing the actual data pointer (and the unsizing info),
|
||||
// which only be obtained by dereferencing a pointer from which moves are
|
||||
// not allowed. Datum & friends could possibly be adjusted to avoid getting
|
||||
// this far - maybe the (*data, info) aggregate could be an SSA value?
|
||||
// Lvalues don't have to be pointers, just behave like a pointer, but there
|
||||
// is no telling what other implicit assumptions are lurking around.
|
||||
ty::type_contents(cx, ty).needs_drop(cx) && type_is_sized(cx, ty)
|
||||
}
|
||||
|
||||
fn type_is_newtype_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
|
@ -146,8 +146,8 @@ fn const_deref<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
(const_deref_ptr(cx, v), mt.ty)
|
||||
} else {
|
||||
// Derefing a fat pointer does not change the representation,
|
||||
// just the type to ty_open.
|
||||
(v, ty::mk_open(cx.tcx(), mt.ty))
|
||||
// just the type to the unsized contents.
|
||||
(v, mt.ty)
|
||||
}
|
||||
}
|
||||
None => {
|
||||
@ -290,15 +290,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
// an optimisation, it is necessary for mutable vectors to
|
||||
// work properly.
|
||||
ty = match ty::deref(ty, true) {
|
||||
Some(mt) => {
|
||||
if type_is_sized(cx.tcx(), mt.ty) {
|
||||
mt.ty
|
||||
} else {
|
||||
// Derefing a fat pointer does not change the representation,
|
||||
// just the type to ty_open.
|
||||
ty::mk_open(cx.tcx(), mt.ty)
|
||||
}
|
||||
}
|
||||
Some(mt) => mt.ty,
|
||||
None => {
|
||||
cx.sess().bug(&format!("unexpected dereferenceable type {}",
|
||||
ty_to_string(cx.tcx(), ty)))
|
||||
@ -319,11 +311,12 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
llconst = addr_of(cx, llconst, "autoref", e.id);
|
||||
}
|
||||
Some(box ty::AutoUnsize(ref k)) => {
|
||||
let unsized_ty = ty::unsize_ty(cx.tcx(), ty, k, e.span);
|
||||
let info = expr::unsized_info(cx, k, e.id, ty, param_substs,
|
||||
|t| ty::mk_imm_rptr(cx.tcx(), cx.tcx().mk_region(ty::ReStatic), t));
|
||||
|
||||
let base = ptrcast(llconst, type_of::type_of(cx, unsized_ty).ptr_to());
|
||||
let unsized_ty = ty::unsize_ty(cx.tcx(), ty, k, e.span);
|
||||
let ptr_ty = type_of::in_memory_type_of(cx, unsized_ty).ptr_to();
|
||||
let base = ptrcast(llconst, ptr_ty);
|
||||
let prev_const = cx.const_unsized().borrow_mut()
|
||||
.insert(base, llconst);
|
||||
assert!(prev_const.is_none() || prev_const == Some(llconst));
|
||||
@ -477,16 +470,10 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
};
|
||||
let (arr, len) = match bt.sty {
|
||||
ty::ty_vec(_, Some(u)) => (bv, C_uint(cx, u)),
|
||||
ty::ty_open(ty) => match ty.sty {
|
||||
ty::ty_vec(_, None) | ty::ty_str => {
|
||||
let e1 = const_get_elt(cx, bv, &[0]);
|
||||
(const_deref_ptr(cx, e1), const_get_elt(cx, bv, &[1]))
|
||||
},
|
||||
_ => cx.sess().span_bug(base.span,
|
||||
&format!("index-expr base must be a vector \
|
||||
or string type, found {}",
|
||||
ty_to_string(cx.tcx(), bt)))
|
||||
},
|
||||
ty::ty_vec(_, None) | ty::ty_str => {
|
||||
let e1 = const_get_elt(cx, bv, &[0]);
|
||||
(const_deref_ptr(cx, e1), const_get_elt(cx, bv, &[1]))
|
||||
}
|
||||
ty::ty_rptr(_, mt) => match mt.ty.sty {
|
||||
ty::ty_vec(_, Some(u)) => {
|
||||
(const_deref_ptr(cx, bv), C_uint(cx, u))
|
||||
|
@ -492,8 +492,6 @@ impl<'tcx> Datum<'tcx, Expr> {
|
||||
-> DatumBlock<'blk, 'tcx, Lvalue> {
|
||||
debug!("to_lvalue_datum self: {}", self.to_string(bcx.ccx()));
|
||||
|
||||
assert!(lltype_is_sized(bcx.tcx(), self.ty),
|
||||
"Trying to convert unsized value to lval");
|
||||
self.match_kind(
|
||||
|l| DatumBlock::new(bcx, l),
|
||||
|r| {
|
||||
@ -549,15 +547,10 @@ impl<'tcx> Datum<'tcx, Lvalue> {
|
||||
-> Datum<'tcx, Lvalue> where
|
||||
F: FnOnce(ValueRef) -> ValueRef,
|
||||
{
|
||||
let val = match self.ty.sty {
|
||||
_ if type_is_sized(bcx.tcx(), self.ty) => gep(self.val),
|
||||
ty::ty_open(_) => {
|
||||
let base = Load(bcx, expr::get_dataptr(bcx, self.val));
|
||||
gep(base)
|
||||
}
|
||||
_ => bcx.tcx().sess.bug(
|
||||
&format!("Unexpected unsized type in get_element: {}",
|
||||
bcx.ty_to_string(self.ty)))
|
||||
let val = if type_is_sized(bcx.tcx(), self.ty) {
|
||||
gep(self.val)
|
||||
} else {
|
||||
gep(Load(bcx, expr::get_dataptr(bcx, self.val)))
|
||||
};
|
||||
Datum {
|
||||
val: val,
|
||||
@ -566,7 +559,8 @@ impl<'tcx> Datum<'tcx, Lvalue> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_vec_base_and_len(&self, bcx: Block) -> (ValueRef, ValueRef) {
|
||||
pub fn get_vec_base_and_len<'blk>(&self, bcx: Block<'blk, 'tcx>)
|
||||
-> (ValueRef, ValueRef) {
|
||||
//! Converts a vector into the slice pair.
|
||||
|
||||
tvec::get_base_and_len(bcx, self.val, self.ty)
|
||||
|
@ -3828,7 +3828,6 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
}
|
||||
ty::ty_err |
|
||||
ty::ty_infer(_) |
|
||||
ty::ty_open(_) |
|
||||
ty::ty_projection(..) |
|
||||
ty::ty_param(_) => {
|
||||
cx.sess().bug(&format!("debuginfo: Trying to create type name for \
|
||||
|
@ -451,8 +451,6 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let datum_ty = datum.ty;
|
||||
let unsized_ty = ty::unsize_ty(tcx, datum_ty, k, expr.span);
|
||||
debug!("unsized_ty={}", unsized_ty.repr(bcx.tcx()));
|
||||
let dest_ty = ty::mk_open(tcx, unsized_ty);
|
||||
debug!("dest_ty={}", unsized_ty.repr(bcx.tcx()));
|
||||
|
||||
let info = unsized_info(bcx.ccx(), k, expr.id, datum_ty, bcx.fcx.param_substs,
|
||||
|t| ty::mk_imm_rptr(tcx, tcx.mk_region(ty::ReStatic), t));
|
||||
@ -462,16 +460,10 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
datum.to_lvalue_datum(bcx, "into_fat_ptr", expr.id));
|
||||
// Compute the base pointer. This doesn't change the pointer value,
|
||||
// but merely its type.
|
||||
let base = match *k {
|
||||
ty::UnsizeStruct(..) | ty::UnsizeVtable(..) => {
|
||||
PointerCast(bcx, lval.val, type_of::type_of(bcx.ccx(), unsized_ty).ptr_to())
|
||||
}
|
||||
ty::UnsizeLength(..) => {
|
||||
GEPi(bcx, lval.val, &[0, 0])
|
||||
}
|
||||
};
|
||||
let ptr_ty = type_of::in_memory_type_of(bcx.ccx(), unsized_ty).ptr_to();
|
||||
let base = PointerCast(bcx, lval.val, ptr_ty);
|
||||
|
||||
let scratch = rvalue_scratch_datum(bcx, dest_ty, "__fat_ptr");
|
||||
let scratch = rvalue_scratch_datum(bcx, unsized_ty, "__fat_ptr");
|
||||
Store(bcx, base, get_dataptr(bcx, scratch.val));
|
||||
Store(bcx, info, get_len(bcx, scratch.val));
|
||||
|
||||
@ -711,7 +703,7 @@ fn trans_field<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||
let _icx = push_ctxt("trans_rec_field");
|
||||
|
||||
let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, base, "field"));
|
||||
let bare_ty = ty::unopen_type(base_datum.ty);
|
||||
let bare_ty = base_datum.ty;
|
||||
let repr = adt::represent_type(bcx.ccx(), bare_ty);
|
||||
with_field_tys(bcx.tcx(), bare_ty, None, move |discr, field_tys| {
|
||||
let ix = get_idx(bcx.tcx(), field_tys);
|
||||
@ -723,7 +715,7 @@ fn trans_field<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||
if type_is_sized(bcx.tcx(), d.ty) {
|
||||
DatumBlock { datum: d.to_expr_datum(), bcx: bcx }
|
||||
} else {
|
||||
let scratch = rvalue_scratch_datum(bcx, ty::mk_open(bcx.tcx(), d.ty), "");
|
||||
let scratch = rvalue_scratch_datum(bcx, d.ty, "");
|
||||
Store(bcx, d.val, get_dataptr(bcx, scratch.val));
|
||||
let info = Load(bcx, get_len(bcx, base_datum.val));
|
||||
Store(bcx, info, get_len(bcx, scratch.val));
|
||||
@ -809,7 +801,7 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
if type_is_sized(bcx.tcx(), elt_ty) {
|
||||
Datum::new(datum.to_llscalarish(bcx), elt_ty, LvalueExpr)
|
||||
} else {
|
||||
Datum::new(datum.val, ty::mk_open(bcx.tcx(), elt_ty), LvalueExpr)
|
||||
Datum::new(datum.val, elt_ty, LvalueExpr)
|
||||
}
|
||||
}
|
||||
None => {
|
||||
@ -1671,7 +1663,7 @@ fn trans_uniq_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
fn ref_fat_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
lval: Datum<'tcx, Lvalue>)
|
||||
-> DatumBlock<'blk, 'tcx, Expr> {
|
||||
let dest_ty = ty::close_type(bcx.tcx(), lval.ty);
|
||||
let dest_ty = ty::mk_imm_rptr(bcx.tcx(), bcx.tcx().mk_region(ty::ReStatic), lval.ty);
|
||||
let scratch = rvalue_scratch_datum(bcx, dest_ty, "__fat_ptr");
|
||||
memcpy_ty(bcx, scratch.val, lval.val, scratch.ty);
|
||||
|
||||
@ -1685,16 +1677,13 @@ fn trans_addr_of<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let _icx = push_ctxt("trans_addr_of");
|
||||
let mut bcx = bcx;
|
||||
let sub_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, subexpr, "addr_of"));
|
||||
match sub_datum.ty.sty {
|
||||
ty::ty_open(_) => {
|
||||
// Opened DST value, close to a fat pointer
|
||||
ref_fat_ptr(bcx, sub_datum)
|
||||
}
|
||||
_ => {
|
||||
// Sized value, ref to a thin pointer
|
||||
let ty = expr_ty(bcx, expr);
|
||||
immediate_rvalue_bcx(bcx, sub_datum.val, ty).to_expr_datumblock()
|
||||
}
|
||||
if !type_is_sized(bcx.tcx(), sub_datum.ty) {
|
||||
// DST lvalue, close to a fat pointer
|
||||
ref_fat_ptr(bcx, sub_datum)
|
||||
} else {
|
||||
// Sized value, ref to a thin pointer
|
||||
let ty = expr_ty(bcx, expr);
|
||||
immediate_rvalue_bcx(bcx, sub_datum.val, ty).to_expr_datumblock()
|
||||
}
|
||||
}
|
||||
|
||||
@ -2234,16 +2223,15 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
if type_is_sized(bcx.tcx(), content_ty) {
|
||||
deref_owned_pointer(bcx, expr, datum, content_ty)
|
||||
} else {
|
||||
// A fat pointer and an opened DST value have the same
|
||||
// representation just different types. Since there is no
|
||||
// temporary for `*e` here (because it is unsized), we cannot
|
||||
// emulate the sized object code path for running drop glue and
|
||||
// free. Instead, we schedule cleanup for `e`, turning it into
|
||||
// an lvalue.
|
||||
// A fat pointer and a DST lvalue have the same representation
|
||||
// just different types. Since there is no temporary for `*e`
|
||||
// here (because it is unsized), we cannot emulate the sized
|
||||
// object code path for running drop glue and free. Instead,
|
||||
// we schedule cleanup for `e`, turning it into an lvalue.
|
||||
let datum = unpack_datum!(
|
||||
bcx, datum.to_lvalue_datum(bcx, "deref", expr.id));
|
||||
|
||||
let datum = Datum::new(datum.val, ty::mk_open(bcx.tcx(), content_ty), LvalueExpr);
|
||||
let datum = Datum::new(datum.val, content_ty, LvalueExpr);
|
||||
DatumBlock::new(bcx, datum)
|
||||
}
|
||||
}
|
||||
@ -2260,11 +2248,9 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
// owner (or, in the case of *T, by the user).
|
||||
DatumBlock::new(bcx, Datum::new(ptr, content_ty, LvalueExpr))
|
||||
} else {
|
||||
// A fat pointer and an opened DST value have the same representation
|
||||
// A fat pointer and a DST lvalue have the same representation
|
||||
// just different types.
|
||||
DatumBlock::new(bcx, Datum::new(datum.val,
|
||||
ty::mk_open(bcx.tcx(), content_ty),
|
||||
LvalueExpr))
|
||||
DatumBlock::new(bcx, Datum::new(datum.val, content_ty, LvalueExpr))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ use trans::expr;
|
||||
use trans::machine::*;
|
||||
use trans::tvec;
|
||||
use trans::type_::Type;
|
||||
use trans::type_of::{type_of, sizing_type_of, align_of};
|
||||
use trans::type_of::{self, type_of, sizing_type_of, align_of};
|
||||
use middle::ty::{self, Ty};
|
||||
use util::ppaux::{ty_to_short_str, Repr};
|
||||
use util::ppaux;
|
||||
@ -265,8 +265,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
assert_eq!(params.len(), 1);
|
||||
let self_arg = if type_is_fat_ptr(bcx.tcx(), self_ty) {
|
||||
// The dtor expects a fat pointer, so make one, even if we have to fake it.
|
||||
let boxed_ty = ty::mk_open(bcx.tcx(), t);
|
||||
let scratch = datum::rvalue_scratch_datum(bcx, boxed_ty, "__fat_ptr_drop_self");
|
||||
let scratch = datum::rvalue_scratch_datum(bcx, t, "__fat_ptr_drop_self");
|
||||
Store(bcx, value, GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_ADDR]));
|
||||
Store(bcx,
|
||||
// If we just had a thin pointer, make a fat pointer by sticking
|
||||
@ -284,20 +283,18 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
// Add all the fields as a value which needs to be cleaned at the end of
|
||||
// this scope. Iterate in reverse order so a Drop impl doesn't reverse
|
||||
// the order in which fields get dropped.
|
||||
for (i, ty) in st.fields.iter().enumerate().rev() {
|
||||
for (i, &ty) in st.fields.iter().enumerate().rev() {
|
||||
let llfld_a = adt::struct_field_ptr(variant_cx, &*st, value, i, false);
|
||||
|
||||
let val = if type_is_sized(bcx.tcx(), *ty) {
|
||||
let val = if type_is_sized(bcx.tcx(), ty) {
|
||||
llfld_a
|
||||
} else {
|
||||
let boxed_ty = ty::mk_open(bcx.tcx(), *ty);
|
||||
let scratch = datum::rvalue_scratch_datum(bcx, boxed_ty, "__fat_ptr_drop_field");
|
||||
let scratch = datum::rvalue_scratch_datum(bcx, ty, "__fat_ptr_drop_field");
|
||||
Store(bcx, llfld_a, GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_ADDR]));
|
||||
Store(bcx, info.unwrap(), GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_EXTRA]));
|
||||
scratch.val
|
||||
};
|
||||
variant_cx.fcx.schedule_drop_mem(cleanup::CustomScope(field_scope),
|
||||
val, *ty);
|
||||
variant_cx.fcx.schedule_drop_mem(cleanup::CustomScope(field_scope), val, ty);
|
||||
}
|
||||
|
||||
let dtor_ty = ty::mk_ctor_fn(bcx.tcx(),
|
||||
@ -502,7 +499,10 @@ pub fn declare_tydesc<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
|
||||
// tydescs.
|
||||
assert!(!ccx.finished_tydescs().get());
|
||||
|
||||
let llty = type_of(ccx, t);
|
||||
// This really shouldn't be like this, size/align will be wrong for
|
||||
// unsized types (i.e. [T] will have the size/align of T).
|
||||
// But we need it until we split this out into a "type name" intrinsic.
|
||||
let llty = type_of::in_memory_type_of(ccx, t);
|
||||
|
||||
if ccx.sess().count_type_sizes() {
|
||||
println!("{}\t{}", llsize_of_real(ccx, llty),
|
||||
|
@ -372,38 +372,31 @@ pub fn get_fixed_base_and_len(bcx: Block,
|
||||
(base, len)
|
||||
}
|
||||
|
||||
fn get_slice_base_and_len(bcx: Block,
|
||||
llval: ValueRef)
|
||||
-> (ValueRef, ValueRef) {
|
||||
let base = Load(bcx, GEPi(bcx, llval, &[0, abi::FAT_PTR_ADDR]));
|
||||
let len = Load(bcx, GEPi(bcx, llval, &[0, abi::FAT_PTR_EXTRA]));
|
||||
(base, len)
|
||||
}
|
||||
|
||||
/// Converts a vector into the slice pair. The vector should be stored in `llval` which should be
|
||||
/// by-reference. If you have a datum, you would probably prefer to call
|
||||
/// `Datum::get_base_and_len()` which will handle any conversions for you.
|
||||
pub fn get_base_and_len(bcx: Block,
|
||||
llval: ValueRef,
|
||||
vec_ty: Ty)
|
||||
-> (ValueRef, ValueRef) {
|
||||
pub fn get_base_and_len<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
llval: ValueRef,
|
||||
vec_ty: Ty<'tcx>)
|
||||
-> (ValueRef, ValueRef) {
|
||||
let ccx = bcx.ccx();
|
||||
|
||||
match vec_ty.sty {
|
||||
ty::ty_vec(_, Some(n)) => get_fixed_base_and_len(bcx, llval, n),
|
||||
ty::ty_open(ty) => match ty.sty {
|
||||
ty::ty_vec(_, None) | ty::ty_str => get_slice_base_and_len(bcx, llval),
|
||||
_ => ccx.sess().bug("unexpected type in get_base_and_len")
|
||||
},
|
||||
ty::ty_vec(_, None) | ty::ty_str => {
|
||||
let base = Load(bcx, expr::get_dataptr(bcx, llval));
|
||||
let len = Load(bcx, expr::get_len(bcx, llval));
|
||||
(base, len)
|
||||
}
|
||||
|
||||
// Only used for pattern matching.
|
||||
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty.sty {
|
||||
ty::ty_vec(_, None) | ty::ty_str => get_slice_base_and_len(bcx, llval),
|
||||
ty::ty_vec(_, Some(n)) => {
|
||||
let base = GEPi(bcx, Load(bcx, llval), &[0, 0]);
|
||||
(base, C_uint(ccx, n))
|
||||
}
|
||||
_ => ccx.sess().bug("unexpected type in get_base_and_len"),
|
||||
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => {
|
||||
let inner = if type_is_sized(bcx.tcx(), ty) {
|
||||
Load(bcx, llval)
|
||||
} else {
|
||||
llval
|
||||
};
|
||||
get_base_and_len(bcx, inner, ty)
|
||||
},
|
||||
_ => ccx.sess().bug("unexpected type in get_base_and_len"),
|
||||
}
|
||||
|
@ -232,14 +232,6 @@ impl Type {
|
||||
Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to().ptr_to()
|
||||
}
|
||||
|
||||
pub fn opaque_trait(ccx: &CrateContext) -> Type {
|
||||
Type::struct_(ccx, &[Type::opaque_trait_data(ccx).ptr_to(), Type::vtable_ptr(ccx)], false)
|
||||
}
|
||||
|
||||
pub fn opaque_trait_data(ccx: &CrateContext) -> Type {
|
||||
Type::i8(ccx)
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> TypeKind {
|
||||
unsafe {
|
||||
llvm::LLVMGetTypeKind(self.to_ref())
|
||||
|
@ -10,8 +10,6 @@
|
||||
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
pub use self::named_ty::*;
|
||||
|
||||
use middle::subst;
|
||||
use trans::adt;
|
||||
use trans::common::*;
|
||||
@ -183,9 +181,8 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
|
||||
}
|
||||
|
||||
let llsizingty = match t.sty {
|
||||
_ if !lltype_is_sized(cx.tcx(), t) => {
|
||||
cx.sess().bug(&format!("trying to take the sizing type of {}, an unsized type",
|
||||
ppaux::ty_to_string(cx.tcx(), t)))
|
||||
_ if !type_is_sized(cx.tcx(), t) => {
|
||||
Type::struct_(cx, &[Type::i8p(cx), Type::i8p(cx)], false)
|
||||
}
|
||||
|
||||
ty::ty_bool => Type::bool(cx),
|
||||
@ -232,15 +229,11 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
|
||||
}
|
||||
}
|
||||
|
||||
ty::ty_open(_) => {
|
||||
Type::struct_(cx, &[Type::i8p(cx), Type::i8p(cx)], false)
|
||||
}
|
||||
|
||||
ty::ty_projection(..) | ty::ty_infer(..) | ty::ty_param(..) | ty::ty_err(..) => {
|
||||
cx.sess().bug(&format!("fictitious type {} in sizing_type_of()",
|
||||
ppaux::ty_to_string(cx.tcx(), t)))
|
||||
}
|
||||
ty::ty_vec(_, None) | ty::ty_trait(..) | ty::ty_str => panic!("unreachable")
|
||||
ty::ty_vec(_, None) | ty::ty_trait(..) | ty::ty_str => unreachable!()
|
||||
};
|
||||
|
||||
cx.llsizingtypes().borrow_mut().insert(t, llsizingty);
|
||||
@ -270,25 +263,37 @@ pub fn arg_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
|
||||
}
|
||||
}
|
||||
|
||||
// NB: If you update this, be sure to update `sizing_type_of()` as well.
|
||||
pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
|
||||
fn type_of_unsize_info<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
|
||||
// It is possible to end up here with a sized type. This happens with a
|
||||
// struct which might be unsized, but is monomorphised to a sized type.
|
||||
// In this case we'll fake a fat pointer with no unsize info (we use 0).
|
||||
// However, its still a fat pointer, so we need some type use.
|
||||
if type_is_sized(cx.tcx(), t) {
|
||||
return Type::i8p(cx);
|
||||
}
|
||||
|
||||
match unsized_part_of_type(cx.tcx(), t).sty {
|
||||
ty::ty_str | ty::ty_vec(..) => Type::uint_from_ty(cx, ast::TyUs(false)),
|
||||
ty::ty_trait(_) => Type::vtable_ptr(cx),
|
||||
_ => panic!("Unexpected type returned from unsized_part_of_type : {}",
|
||||
t.repr(cx.tcx()))
|
||||
}
|
||||
}
|
||||
/// Get the LLVM type corresponding to a Rust type, i.e. `middle::ty::Ty`.
|
||||
/// This is the right LLVM type for an alloca containg a value of that type,
|
||||
/// and the pointee of an Lvalue Datum (which is always a LLVM pointer).
|
||||
/// For unsized types, the returned type is a fat pointer, thus the resulting
|
||||
/// LLVM type for a `Trait` Lvalue is `{ i8*, void(i8*)** }*`, which is a double
|
||||
/// indirection to the actual data, unlike a `i8` Lvalue, which is just `i8*`.
|
||||
/// This is needed due to the treatment of immediate values, as a fat pointer
|
||||
/// is too large for it to be placed in SSA value (by our rules).
|
||||
/// For the raw type without far pointer indirection, see `in_memory_type_of`.
|
||||
pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> Type {
|
||||
let ty = if !type_is_sized(cx.tcx(), ty) {
|
||||
ty::mk_imm_ptr(cx.tcx(), ty)
|
||||
} else {
|
||||
ty
|
||||
};
|
||||
in_memory_type_of(cx, ty)
|
||||
}
|
||||
|
||||
/// Get the LLVM type corresponding to a Rust type, i.e. `middle::ty::Ty`.
|
||||
/// This is the right LLVM type for a field/array element of that type,
|
||||
/// and is the same as `type_of` for all Sized types.
|
||||
/// Unsized types, however, are represented by a "minimal unit", e.g.
|
||||
/// `[T]` becomes `T`, while `str` and `Trait` turn into `i8` - this
|
||||
/// is useful for indexing slices, as `&[T]`'s data pointer is `T*`.
|
||||
/// If the type is an unsized struct, the regular layout is generated,
|
||||
/// with the inner-most trailing unsized field using the "minimal unit"
|
||||
/// of that field's type - this is useful for taking the address of
|
||||
/// that field and ensuring the struct has the right alignment.
|
||||
/// For the LLVM type of a value as a whole, see `type_of`.
|
||||
/// NB: If you update this, be sure to update `sizing_type_of()` as well.
|
||||
pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
|
||||
// Check the cache.
|
||||
match cx.lltypes().borrow().get(&t) {
|
||||
Some(&llty) => return llty,
|
||||
@ -307,7 +312,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
|
||||
let t_norm = erase_regions(cx.tcx(), &t);
|
||||
|
||||
if t != t_norm {
|
||||
let llty = type_of(cx, t_norm);
|
||||
let llty = in_memory_type_of(cx, t_norm);
|
||||
debug!("--> normalized {} {:?} to {} {:?} llty={}",
|
||||
t.repr(cx.tcx()),
|
||||
t,
|
||||
@ -331,10 +336,10 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
|
||||
// of the enum's variants refers to the enum itself.
|
||||
let repr = adt::represent_type(cx, t);
|
||||
let tps = substs.types.get_slice(subst::TypeSpace);
|
||||
let name = llvm_type_name(cx, an_enum, did, tps);
|
||||
let name = llvm_type_name(cx, did, tps);
|
||||
adt::incomplete_type_of(cx, &*repr, &name[..])
|
||||
}
|
||||
ty::ty_closure(did, _, ref substs) => {
|
||||
ty::ty_closure(..) => {
|
||||
// Only create the named struct, but don't fill it in. We
|
||||
// fill it in *after* placing it into the type cache.
|
||||
let repr = adt::represent_type(cx, t);
|
||||
@ -342,41 +347,47 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
|
||||
// inherited from their environment, so we use entire
|
||||
// contents of the VecPerParamSpace to to construct the llvm
|
||||
// name
|
||||
let name = llvm_type_name(cx, a_closure, did, substs.types.as_slice());
|
||||
adt::incomplete_type_of(cx, &*repr, &name[..])
|
||||
adt::incomplete_type_of(cx, &*repr, "closure")
|
||||
}
|
||||
|
||||
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) | ty::ty_ptr(ty::mt{ty, ..}) => {
|
||||
match ty.sty {
|
||||
ty::ty_str => {
|
||||
if !type_is_sized(cx.tcx(), ty) {
|
||||
if let ty::ty_str = ty.sty {
|
||||
// This means we get a nicer name in the output (str is always
|
||||
// unsized).
|
||||
cx.tn().find_type("str_slice").unwrap()
|
||||
} else {
|
||||
let ptr_ty = in_memory_type_of(cx, ty).ptr_to();
|
||||
let unsized_part = unsized_part_of_type(cx.tcx(), ty);
|
||||
let info_ty = match unsized_part.sty {
|
||||
ty::ty_str | ty::ty_vec(..) => {
|
||||
Type::uint_from_ty(cx, ast::TyUs(false))
|
||||
}
|
||||
ty::ty_trait(_) => Type::vtable_ptr(cx),
|
||||
_ => panic!("Unexpected type returned from \
|
||||
unsized_part_of_type: {} for ty={}",
|
||||
unsized_part.repr(cx.tcx()), ty.repr(cx.tcx()))
|
||||
};
|
||||
Type::struct_(cx, &[ptr_ty, info_ty], false)
|
||||
}
|
||||
ty::ty_trait(..) => Type::opaque_trait(cx),
|
||||
_ if !type_is_sized(cx.tcx(), ty) => {
|
||||
let p_ty = type_of(cx, ty).ptr_to();
|
||||
Type::struct_(cx, &[p_ty, type_of_unsize_info(cx, ty)], false)
|
||||
}
|
||||
_ => type_of(cx, ty).ptr_to(),
|
||||
} else {
|
||||
in_memory_type_of(cx, ty).ptr_to()
|
||||
}
|
||||
}
|
||||
|
||||
ty::ty_vec(ty, Some(size)) => {
|
||||
let size = size as u64;
|
||||
let llty = type_of(cx, ty);
|
||||
let llty = in_memory_type_of(cx, ty);
|
||||
ensure_array_fits_in_address_space(cx, llty, size, t);
|
||||
Type::array(&llty, size)
|
||||
}
|
||||
ty::ty_vec(ty, None) => {
|
||||
type_of(cx, ty)
|
||||
}
|
||||
|
||||
ty::ty_trait(..) => {
|
||||
Type::opaque_trait_data(cx)
|
||||
}
|
||||
|
||||
ty::ty_str => Type::i8(cx),
|
||||
// Unsized slice types (and str) have the type of their element, and
|
||||
// traits have the type of u8. This is so that the data pointer inside
|
||||
// fat pointers is of the right type (e.g. for array accesses), even
|
||||
// when taking the address of an unsized field in a struct.
|
||||
ty::ty_vec(ty, None) => in_memory_type_of(cx, ty),
|
||||
ty::ty_str | ty::ty_trait(..) => Type::i8(cx),
|
||||
|
||||
ty::ty_bare_fn(..) => {
|
||||
type_of_fn_from_ty(cx, t).ptr_to()
|
||||
@ -388,7 +399,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
|
||||
}
|
||||
ty::ty_struct(did, ref substs) => {
|
||||
if ty::type_is_simd(cx.tcx(), t) {
|
||||
let llet = type_of(cx, ty::simd_type(cx.tcx(), t));
|
||||
let llet = in_memory_type_of(cx, ty::simd_type(cx.tcx(), t));
|
||||
let n = ty::simd_size(cx.tcx(), t) as u64;
|
||||
ensure_array_fits_in_address_space(cx, llet, n, t);
|
||||
Type::vector(&llet, n)
|
||||
@ -398,29 +409,11 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
|
||||
// infinite recursion with recursive struct types.
|
||||
let repr = adt::represent_type(cx, t);
|
||||
let tps = substs.types.get_slice(subst::TypeSpace);
|
||||
let name = llvm_type_name(cx, a_struct, did, tps);
|
||||
let name = llvm_type_name(cx, did, tps);
|
||||
adt::incomplete_type_of(cx, &*repr, &name[..])
|
||||
}
|
||||
}
|
||||
|
||||
ty::ty_open(t) => match t.sty {
|
||||
ty::ty_struct(..) => {
|
||||
let p_ty = type_of(cx, t).ptr_to();
|
||||
Type::struct_(cx, &[p_ty, type_of_unsize_info(cx, t)], false)
|
||||
}
|
||||
ty::ty_vec(ty, None) => {
|
||||
let p_ty = type_of(cx, ty).ptr_to();
|
||||
Type::struct_(cx, &[p_ty, type_of_unsize_info(cx, t)], false)
|
||||
}
|
||||
ty::ty_str => {
|
||||
let p_ty = Type::i8p(cx);
|
||||
Type::struct_(cx, &[p_ty, type_of_unsize_info(cx, t)], false)
|
||||
}
|
||||
ty::ty_trait(..) => Type::opaque_trait(cx),
|
||||
_ => cx.sess().bug(&format!("ty_open with sized type: {}",
|
||||
ppaux::ty_to_string(cx.tcx(), t)))
|
||||
},
|
||||
|
||||
ty::ty_infer(..) => cx.sess().bug("type_of with ty_infer"),
|
||||
ty::ty_projection(..) => cx.sess().bug("type_of with ty_projection"),
|
||||
ty::ty_param(..) => cx.sess().bug("type_of with ty_param"),
|
||||
@ -444,7 +437,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
|
||||
_ => ()
|
||||
}
|
||||
|
||||
return llty;
|
||||
llty
|
||||
}
|
||||
|
||||
pub fn align_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
|
||||
@ -453,37 +446,22 @@ pub fn align_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
|
||||
machine::llalign_of_min(cx, llty)
|
||||
}
|
||||
|
||||
// Want refinements! (Or case classes, I guess
|
||||
#[derive(Copy)]
|
||||
pub enum named_ty {
|
||||
a_struct,
|
||||
an_enum,
|
||||
a_closure,
|
||||
}
|
||||
|
||||
pub fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
what: named_ty,
|
||||
did: ast::DefId,
|
||||
tps: &[Ty<'tcx>])
|
||||
-> String {
|
||||
let name = match what {
|
||||
a_struct => "struct",
|
||||
an_enum => "enum",
|
||||
a_closure => return "closure".to_string(),
|
||||
};
|
||||
|
||||
fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
did: ast::DefId,
|
||||
tps: &[Ty<'tcx>])
|
||||
-> String {
|
||||
let base = ty::item_path_str(cx.tcx(), did);
|
||||
let strings: Vec<String> = tps.iter().map(|t| t.repr(cx.tcx())).collect();
|
||||
let tstr = if strings.is_empty() {
|
||||
base
|
||||
} else {
|
||||
format!("{}<{:?}>", base, strings)
|
||||
format!("{}<{}>", base, strings.connect(", "))
|
||||
};
|
||||
|
||||
if did.krate == 0 {
|
||||
format!("{}.{}", name, tstr)
|
||||
tstr
|
||||
} else {
|
||||
format!("{}.{}[{}{}]", name, tstr, "#", did.krate)
|
||||
format!("{}.{}", did.krate, tstr)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,12 +161,6 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
|
||||
// entering the fn check. We should do this after
|
||||
// the fn check, then we can call this case a bug().
|
||||
}
|
||||
|
||||
ty::ty_open(_) => {
|
||||
self.tcx().sess.bug(
|
||||
&format!("Unexpected type encountered while doing wf check: {}",
|
||||
ty.repr(self.tcx())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ use middle::ty::{ParameterEnvironment, TypeTraitItemId, lookup_item_type};
|
||||
use middle::ty::{Ty, ty_bool, ty_char, ty_enum, ty_err};
|
||||
use middle::ty::{ty_param, TypeScheme, ty_ptr};
|
||||
use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup};
|
||||
use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open};
|
||||
use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int};
|
||||
use middle::ty::{ty_uint, ty_closure, ty_uniq, ty_bare_fn};
|
||||
use middle::ty::{ty_projection};
|
||||
use middle::ty;
|
||||
@ -75,7 +75,7 @@ fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
|
||||
|
||||
ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) |
|
||||
ty_str(..) | ty_vec(..) | ty_bare_fn(..) | ty_tup(..) |
|
||||
ty_param(..) | ty_err | ty_open(..) |
|
||||
ty_param(..) | ty_err |
|
||||
ty_ptr(_) | ty_rptr(_, _) | ty_projection(..) => {
|
||||
None
|
||||
}
|
||||
|
@ -849,7 +849,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
self.add_constraints_from_mt(generics, mt, variance);
|
||||
}
|
||||
|
||||
ty::ty_uniq(typ) | ty::ty_vec(typ, _) | ty::ty_open(typ) => {
|
||||
ty::ty_uniq(typ) | ty::ty_vec(typ, _) => {
|
||||
self.add_constraints_from_ty(generics, typ, variance);
|
||||
}
|
||||
|
||||
|
@ -1619,7 +1619,6 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
||||
ty::ty_closure(..) => Tuple(vec![]), // FIXME(pcwalton)
|
||||
|
||||
ty::ty_infer(..) => panic!("ty_infer"),
|
||||
ty::ty_open(..) => panic!("ty_open"),
|
||||
ty::ty_err => panic!("ty_err"),
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user