Skip to content

Commit

Permalink
DST raw pointers - *-pointers are fat pointers
Browse files Browse the repository at this point in the history
  • Loading branch information
nrc committed Sep 1, 2014
1 parent 01364c4 commit 52d6d3b
Show file tree
Hide file tree
Showing 20 changed files with 363 additions and 69 deletions.
3 changes: 2 additions & 1 deletion src/librustc/diagnostics.rs
Expand Up @@ -170,5 +170,6 @@ register_diagnostics!(
E0156,
E0157,
E0158,
E0159
E0159,
E0160
)
25 changes: 21 additions & 4 deletions src/librustc/middle/astencode.rs
Expand Up @@ -1073,9 +1073,18 @@ impl<'a> rbml_writer_helpers for Encoder<'a> {
this.emit_enum_variant_arg(0, |this| Ok(this.emit_unsize_kind(ecx, uk)))
})
}
&ty::AutoUnsafe(m) => {
this.emit_enum_variant("AutoUnsafe", 3, 1, |this| {
this.emit_enum_variant_arg(0, |this| m.encode(this))
&ty::AutoUnsafe(m, None) => {
this.emit_enum_variant("AutoUnsafe", 3, 2, |this| {
this.emit_enum_variant_arg(0, |this| m.encode(this));
this.emit_enum_variant_arg(1,
|this| this.emit_option(|this| this.emit_option_none()))
})
}
&ty::AutoUnsafe(m, Some(box ref a)) => {
this.emit_enum_variant("AutoUnsafe", 3, 2, |this| {
this.emit_enum_variant_arg(0, |this| m.encode(this));
this.emit_enum_variant_arg(1, |this| this.emit_option(
|this| this.emit_option_some(|this| Ok(this.emit_autoref(ecx, a)))))
})
}
}
Expand Down Expand Up @@ -1635,8 +1644,16 @@ impl<'a> rbml_decoder_decoder_helpers for reader::Decoder<'a> {
3 => {
let m: ast::Mutability =
this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap();
let a: Option<Box<ty::AutoRef>> =
this.read_enum_variant_arg(1, |this| this.read_option(|this, b| {
if b {
Ok(Some(box this.read_autoref(xcx)))
} else {
Ok(None)
}
})).unwrap();

ty::AutoUnsafe(m)
ty::AutoUnsafe(m, a)
}
_ => fail!("bad enum variant for ty::AutoRef")
})
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/expr_use_visitor.rs
Expand Up @@ -762,7 +762,7 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
ty::BorrowKind::from_mutbl(m),
AutoRef);
}
ty::AutoUnsizeUniq(_) | ty::AutoUnsize(_) | ty::AutoUnsafe(_) => {}
ty::AutoUnsizeUniq(_) | ty::AutoUnsize(_) | ty::AutoUnsafe(..) => {}
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/librustc/middle/trans/adt.rs
Expand Up @@ -296,8 +296,9 @@ impl Case {

for (i, &ty) in self.tys.iter().enumerate() {
match ty::get(ty).sty {
// &T/&mut T could either be a thin or fat pointer depending on T
ty::ty_rptr(_, ty::mt { ty, .. }) => match ty::get(ty).sty {
// &T/&mut T/*T could either be a thin or fat pointer depending on T
ty::ty_rptr(_, ty::mt { ty, .. })
| ty::ty_ptr(ty::mt { ty, .. }) => match ty::get(ty).sty {
// &[T] and &str are a pointer and length pair
ty::ty_vec(_, None) | ty::ty_str => return Some(FatPointer(i, slice_elt_base)),

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/trans/base.rs
Expand Up @@ -566,8 +566,8 @@ pub fn compare_scalar_types<'a>(

match ty::get(t).sty {
ty::ty_nil => f(nil_type),
ty::ty_bool | ty::ty_ptr(_) |
ty::ty_uint(_) | ty::ty_char => f(unsigned_int),
ty::ty_bool | ty::ty_uint(_) | ty::ty_char => f(unsigned_int),
ty::ty_ptr(mt) if ty::type_is_sized(cx.tcx(), mt.ty) => f(unsigned_int),
ty::ty_int(_) => f(signed_int),
ty::ty_float(_) => f(floating_point),
// Should never get here, because t is scalar.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/consts.rs
Expand Up @@ -243,7 +243,7 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
}
Some(ref autoref) => {
match *autoref {
ty::AutoUnsafe(_) |
ty::AutoUnsafe(_, None) |
ty::AutoPtr(ty::ReStatic, _, None) => {
// Don't copy data to do a deref+ref
// (i.e., skip the last auto-deref).
Expand Down
9 changes: 2 additions & 7 deletions src/librustc/middle/trans/expr.rs
Expand Up @@ -254,11 +254,7 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
let mut datum = datum;

let datum = match autoref {
&AutoUnsafe(..) => {
debug!(" AutoUnsafe");
unpack_datum!(bcx, ref_ptr(bcx, expr, datum))
}
&AutoPtr(_, _, ref a) => {
&AutoPtr(_, _, ref a) | &AutoUnsafe(_, ref a) => {
debug!(" AutoPtr");
match a {
&Some(box ref a) => datum = unpack_datum!(bcx,
Expand Down Expand Up @@ -1847,8 +1843,7 @@ pub fn cast_type_kind(tcx: &ty::ctxt, t: ty::t) -> cast_kind {
match ty::get(t).sty {
ty::ty_char => cast_integral,
ty::ty_float(..) => cast_float,
ty::ty_ptr(..) => cast_pointer,
ty::ty_rptr(_, mt) => {
ty::ty_rptr(_, mt) | ty::ty_ptr(mt) => {
if ty::type_is_sized(tcx, mt.ty) {
cast_pointer
} else {
Expand Down
22 changes: 19 additions & 3 deletions src/librustc/middle/trans/reflect.rs
Expand Up @@ -154,7 +154,7 @@ impl<'a, 'b> Reflector<'a, 'b> {
// Unfortunately we can't do anything here because at runtime we
// pass around the value by pointer (*u8). But unsized pointers are
// fat and so we can't just cast them to *u8 and back. So we have
// to work with the pointer directly (see ty_rptr/ty_uniq).
// to work with the pointer directly (see ty_ptr/ty_rptr/ty_uniq).
fail!("Can't reflect unsized type")
}
// FIXME(15049) Reflection for unsized structs.
Expand All @@ -177,8 +177,24 @@ impl<'a, 'b> Reflector<'a, 'b> {
self.visit("box", extra.as_slice())
}
ty::ty_ptr(ref mt) => {
let extra = self.c_mt(mt);
self.visit("ptr", extra.as_slice())
match ty::get(mt.ty).sty {
ty::ty_vec(ty, None) => {
let extra = self.c_mt(&ty::mt{ty: ty, mutbl: mt.mutbl});
self.visit("evec_slice", extra.as_slice())
}
ty::ty_str => self.visit("estr_slice", &[]),
ty::ty_trait(..) => {
let extra = [
self.c_slice(token::intern_and_get_ident(
ty_to_string(tcx, t).as_slice()))
];
self.visit("trait", extra);
}
_ => {
let extra = self.c_mt(mt);
self.visit("ptr", extra.as_slice())
}
}
}
ty::ty_uniq(typ) => {
match ty::get(typ).sty {
Expand Down
8 changes: 3 additions & 5 deletions src/librustc/middle/trans/type_of.rs
Expand Up @@ -174,9 +174,8 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
ty::ty_uint(t) => Type::uint_from_ty(cx, t),
ty::ty_float(t) => Type::float_from_ty(cx, t),

ty::ty_box(..) |
ty::ty_ptr(..) => Type::i8p(cx),
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => {
ty::ty_box(..) => Type::i8p(cx),
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) | ty::ty_ptr(ty::mt{ty, ..}) => {
if ty::type_is_sized(cx.tcx(), ty) {
Type::i8p(cx)
} else {
Expand Down Expand Up @@ -303,9 +302,8 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
ty::ty_box(typ) => {
Type::at_box(cx, type_of(cx, typ)).ptr_to()
}
ty::ty_ptr(ref mt) => type_of(cx, mt.ty).ptr_to(),

ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => {
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) | ty::ty_ptr(ty::mt{ty, ..}) => {
match ty::get(ty).sty {
ty::ty_str => {
// This means we get a nicer name in the output (str is always
Expand Down
28 changes: 21 additions & 7 deletions src/librustc/middle/ty.rs
Expand Up @@ -298,7 +298,8 @@ pub enum AutoRef {

/// Convert from T to *T
/// Value to thin pointer
AutoUnsafe(ast::Mutability),
/// The second field allows us to wrap other AutoRef adjustments.
AutoUnsafe(ast::Mutability, Option<Box<AutoRef>>),
}

// Ugly little helper function. The first bool in the returned tuple is true if
Expand Down Expand Up @@ -326,6 +327,7 @@ fn autoref_object_region(autoref: &AutoRef) -> (bool, bool, Option<Region>) {
(b, u, Some(adj_r))
}
}
&AutoUnsafe(_, Some(box ref autoref)) => autoref_object_region(autoref),
_ => (false, false, None)
}
}
Expand Down Expand Up @@ -380,6 +382,12 @@ pub fn type_of_adjust(cx: &ctxt, adj: &AutoAdjustment) -> Option<t> {
None => None
}
}
&AutoUnsafe(m, Some(box ref autoref)) => {
match type_of_autoref(cx, autoref) {
Some(t) => Some(mk_ptr(cx, mt {mutbl: m, ty: t})),
None => None
}
}
_ => None
}
}
Expand Down Expand Up @@ -1898,7 +1906,7 @@ pub fn type_is_self(ty: t) -> bool {

fn type_is_slice(ty: t) -> bool {
match get(ty).sty {
ty_rptr(_, mt) => match get(mt.ty).sty {
ty_ptr(mt) | ty_rptr(_, mt) => match get(mt.ty).sty {
ty_vec(_, None) | ty_str => true,
_ => false,
},
Expand Down Expand Up @@ -1996,7 +2004,8 @@ pub fn type_is_unique(ty: t) -> bool {

pub fn type_is_fat_ptr(cx: &ctxt, ty: t) -> bool {
match get(ty).sty {
ty_rptr(_, mt{ty, ..}) | ty_uniq(ty) if !type_is_sized(cx, ty) => true,
ty_ptr(mt{ty, ..}) | ty_rptr(_, mt{ty, ..})
| ty_uniq(ty) if !type_is_sized(cx, ty) => true,
_ => false,
}
}
Expand Down Expand Up @@ -2896,7 +2905,7 @@ pub fn is_type_representable(cx: &ctxt, sp: Span, ty: t) -> Representability {

pub fn type_is_trait(ty: t) -> bool {
match get(ty).sty {
ty_uniq(ty) | ty_rptr(_, mt { ty, ..}) => match get(ty).sty {
ty_uniq(ty) | ty_rptr(_, mt { ty, ..}) | ty_ptr(mt { ty, ..}) => match get(ty).sty {
ty_trait(..) => true,
_ => false
},
Expand Down Expand Up @@ -3392,8 +3401,12 @@ pub fn adjust_ty(cx: &ctxt,
})
}

AutoUnsafe(m) => {
mk_ptr(cx, mt {ty: ty, mutbl: m})
AutoUnsafe(m, ref a) => {
let adjusted_ty = match a {
&Some(box ref a) => adjust_for_autoref(cx, span, ty, a),
&None => ty
};
mk_ptr(cx, mt {ty: adjusted_ty, mutbl: m})
}

AutoUnsize(ref k) => unsize_ty(cx, ty, k, span),
Expand Down Expand Up @@ -3444,7 +3457,8 @@ impl AutoRef {
ty::AutoPtr(r, m, Some(ref a)) => ty::AutoPtr(f(r), m, Some(box a.map_region(f))),
ty::AutoUnsize(ref k) => ty::AutoUnsize(k.clone()),
ty::AutoUnsizeUniq(ref k) => ty::AutoUnsizeUniq(k.clone()),
ty::AutoUnsafe(m) => ty::AutoUnsafe(m),
ty::AutoUnsafe(m, None) => ty::AutoUnsafe(m, None),
ty::AutoUnsafe(m, Some(ref a)) => ty::AutoUnsafe(m, Some(box a.map_region(f))),
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/librustc/middle/ty_fold.rs
Expand Up @@ -466,7 +466,10 @@ pub fn super_fold_autoref<T:TypeFolder>(this: &mut T,
ty::AutoPtr(r, m, Some(ref a)) => {
ty::AutoPtr(this.fold_region(r), m, Some(box super_fold_autoref(this, &**a)))
}
ty::AutoUnsafe(m) => ty::AutoUnsafe(m),
ty::AutoUnsafe(m, None) => ty::AutoUnsafe(m, None),
ty::AutoUnsafe(m, Some(ref a)) => {
ty::AutoUnsafe(m, Some(box super_fold_autoref(this, &**a)))
}
ty::AutoUnsize(ref k) => ty::AutoUnsize(k.fold_with(this)),
ty::AutoUnsizeUniq(ref k) => ty::AutoUnsizeUniq(k.fold_with(this)),
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/check/mod.rs
Expand Up @@ -3650,7 +3650,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
ast::ExprAddrOf(mutbl, ref oprnd) => {
let expected = expected.only_has_type();
let hint = expected.map(fcx, |sty| {
match *sty { ty::ty_rptr(_, ref mt) => ExpectHasType(mt.ty),
match *sty { ty::ty_rptr(_, ref mt) | ty::ty_ptr(ref mt) => ExpectHasType(mt.ty),
_ => NoExpectation }
});
let lvalue_pref = match mutbl {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/check/regionck.rs
Expand Up @@ -1363,7 +1363,7 @@ fn link_autoref(rcx: &Rcx,
ty::BorrowKind::from_mutbl(m), expr_cmt);
}

ty::AutoUnsafe(_) | ty::AutoUnsizeUniq(_) | ty::AutoUnsize(_) => {}
ty::AutoUnsafe(..) | ty::AutoUnsizeUniq(_) | ty::AutoUnsize(_) => {}
}
}

Expand Down
23 changes: 20 additions & 3 deletions src/librustc/middle/typeck/check/vtable.rs
Expand Up @@ -630,9 +630,13 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {

let cx = fcx.ccx;
let check_object_cast = |src_ty: ty::t, target_ty: ty::t| {
debug!("check_object_cast {} to {}",
fcx.infcx().ty_to_string(src_ty),
fcx.infcx().ty_to_string(target_ty));
// Check that a cast is of correct types.
match (&ty::get(target_ty).sty, &ty::get(src_ty).sty) {
(&ty::ty_rptr(_, ty::mt{ty, mutbl}), &ty::ty_rptr(_, mt))
| (&ty::ty_ptr(ty::mt{ty, mutbl}), &ty::ty_rptr(_, mt))
if !mutability_allowed(mt.mutbl, mutbl) => {
match ty::get(ty).sty {
ty::ty_trait(..) => {
Expand All @@ -641,7 +645,9 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
_ => {}
}
}
(&ty::ty_uniq(..), &ty::ty_uniq(..) ) => {}
(&ty::ty_uniq(..), &ty::ty_uniq(..) )
| (&ty::ty_ptr(..), &ty::ty_ptr(..) )
| (&ty::ty_ptr(..), &ty::ty_rptr(..)) => {}
(&ty::ty_rptr(r_t, _), &ty::ty_rptr(r_s, _)) => {
infer::mk_subr(fcx.infcx(),
infer::RelateObjectBound(ex.span),
Expand Down Expand Up @@ -669,6 +675,16 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
_ => {}
}
}
(&ty::ty_ptr(ty::mt{ty, ..}), _) => {
match ty::get(ty).sty {
ty::ty_trait(..) => {
span_err!(fcx.ccx.tcx.sess, ex.span, E0160,
"can only cast an *-pointer or &-pointer to an *-object, not a {}",
ty::ty_sort_string(fcx.tcx(), src_ty));
}
_ => {}
}
}
_ => {}
}
};
Expand Down Expand Up @@ -880,7 +896,8 @@ fn trait_cast_types(fcx: &FnCtxt,
match autoref {
&ty::AutoUnsize(ref k) |
&ty::AutoUnsizeUniq(ref k) => trait_cast_types_unsize(fcx, k, src_ty, sp),
&ty::AutoPtr(_, _, Some(box ref autoref)) => {
&ty::AutoPtr(_, _, Some(box ref autoref))
| &ty::AutoUnsafe(_, Some(box ref autoref))=> {
trait_cast_types_autoref(fcx, autoref, src_ty, sp)
}
_ => None
Expand All @@ -891,7 +908,7 @@ fn trait_cast_types(fcx: &FnCtxt,
&ty::AutoDerefRef(AutoDerefRef{autoref: Some(ref autoref), autoderefs}) => {
let mut derefed_type = src_ty;
for _ in range(0, autoderefs) {
derefed_type = ty::deref(derefed_type, false).unwrap().ty;
derefed_type = ty::deref(derefed_type, true).unwrap().ty;
derefed_type = structurally_resolved_type(fcx, sp, derefed_type)
}
trait_cast_types_autoref(fcx, autoref, derefed_type, sp)
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/typeck/coherence.rs
Expand Up @@ -157,7 +157,8 @@ fn get_base_type_def_id(inference_context: &InferCtxt,
ty_unboxed_closure(def_id, _) => {
Some(def_id)
}
ty_rptr(_, ty::mt {ty, ..}) | ty_uniq(ty) => match ty::get(ty).sty {
ty_ptr(ty::mt {ty, ..}) | ty_rptr(_, ty::mt {ty, ..}) | ty_uniq(ty)
=> match ty::get(ty).sty {
ty_trait(box ty::TyTrait { def_id, .. }) => {
Some(def_id)
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/collect.rs
Expand Up @@ -1401,7 +1401,7 @@ fn check_method_self_type<RS:RegionScope>(
ast::SelfExplicit(ref ast_type, _) => {
let typ = crate_context.to_ty(rs, &**ast_type);
let base_type = match ty::get(typ).sty {
ty::ty_rptr(_, tm) => tm.ty,
ty::ty_ptr(tm) | ty::ty_rptr(_, tm) => tm.ty,
ty::ty_uniq(typ) => typ,
_ => typ,
};
Expand Down

0 comments on commit 52d6d3b

Please sign in to comment.