Skip to content

DST raw pointers - *-pointers are fat pointers #16805

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 2, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
20 changes: 12 additions & 8 deletions src/librustc/middle/typeck/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,19 @@ 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_trait(box ty::TyTrait { def_id, .. }) => {
Some(def_id)
}
_ => {
fail!("get_base_type() returned a type that wasn't an \
enum, struct, or trait");
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)
}
_ => {
fail!("get_base_type() returned a type that wasn't an \
enum, struct, or trait");
}
}
},
}
ty_trait(box ty::TyTrait { def_id, .. }) => {
Some(def_id)
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/collect.rs
Original file line number Diff line number Diff line change
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
Loading