rustc: "as Trait" can now be written "as @Trait".

There is also code for ~Trait and &Trait, but these are currently (incorrectly)
synonyms for "as @Trait" and "as &Trait".
This commit is contained in:
Patrick Walton
2012-08-14 15:27:06 -07:00
parent fd0f616ceb
commit fe9d07dda6
27 changed files with 125 additions and 83 deletions

View File

@@ -212,8 +212,9 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
assert next(st) == '[';
let def = parse_def(st, conv);
let substs = parse_substs(st, conv);
let vstore = parse_vstore(st);
assert next(st) == ']';
return ty::mk_trait(st.tcx, def, substs);
return ty::mk_trait(st.tcx, def, substs, vstore);
}
'p' => {
let did = parse_def(st, conv);

View File

@@ -227,11 +227,12 @@ fn enc_sty(w: io::Writer, cx: @ctxt, st: ty::sty) {
enc_substs(w, cx, substs);
w.write_char(']');
}
ty::ty_trait(def, substs) => {
ty::ty_trait(def, substs, vstore) => {
w.write_str(&"x[");
w.write_str(cx.ds(def));
w.write_char('|');
enc_substs(w, cx, substs);
enc_vstore(w, cx, vstore);
w.write_char(']');
}
ty::ty_tup(ts) => {

View File

@@ -498,7 +498,7 @@ fn check_cast_for_escaping_regions(
// worries.
let target_ty = ty::expr_ty(cx.tcx, target);
let target_substs = match ty::get(target_ty).struct {
ty::ty_trait(_, substs) => {substs}
ty::ty_trait(_, substs, _) => {substs}
_ => { return; /* not a cast to a trait */ }
};

View File

@@ -668,7 +668,7 @@ fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) {
ty::ty_fn(_) => {
closure::make_fn_glue(bcx, v, t, take_ty)
}
ty::ty_trait(_, _) => {
ty::ty_trait(_, _, _) => {
let llbox = Load(bcx, GEPi(bcx, v, ~[0u, 1u]));
incr_refcnt_of_boxed(bcx, llbox);
bcx
@@ -819,7 +819,7 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
ty::ty_fn(_) => {
closure::make_fn_glue(bcx, v0, t, drop_ty)
}
ty::ty_trait(_, _) => {
ty::ty_trait(_, _, _) => {
let llbox = Load(bcx, GEPi(bcx, v0, ~[0u, 1u]));
decr_refcnt_maybe_free(bcx, llbox, ty::mk_opaque_box(ccx.tcx))
}
@@ -2041,7 +2041,7 @@ fn normalize_for_monomorphization(tcx: ty::ctxt, ty: ty::t) -> option<ty::t> {
output: ty::mk_nil(tcx),
ret_style: ast::return_val}))
}
ty::ty_trait(_, _) => {
ty::ty_trait(_, _, _) => {
some(ty::mk_fn(tcx, {purity: ast::impure_fn,
proto: ty::proto_vstore(ty::vstore_box),
bounds: @~[],
@@ -2819,7 +2819,7 @@ fn trans_cast(cx: block, e: @ast::expr, id: ast::node_id,
let ccx = cx.ccx();
let t_out = node_id_type(cx, id);
match ty::get(t_out).struct {
ty::ty_trait(_, _) => return impl::trans_cast(cx, e, id, dest),
ty::ty_trait(_, _, _) => return impl::trans_cast(cx, e, id, dest),
_ => ()
}
let e_res = trans_temp_expr(cx, e);

View File

@@ -268,7 +268,7 @@ impl reflector {
}
// Miscallaneous extra types
ty::ty_trait(_, _) => self.leaf(~"trait"),
ty::ty_trait(_, _, _) => self.leaf(~"trait"),
ty::ty_var(_) => self.leaf(~"var"),
ty::ty_var_integral(_) => self.leaf(~"var_integral"),
ty::ty_param(p) => self.visit(~"param", ~[self.c_uint(p.idx)]),

View File

@@ -323,7 +323,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> ~[u8] {
add_substr(s, sub);
s
}
ty::ty_trait(_, _) => ~[shape_box_fn],
ty::ty_trait(_, _, _) => ~[shape_box_fn],
ty::ty_class(did, ref substs) => {
// same as records, unless there's a dtor
let tps = substs.tps;

View File

@@ -147,7 +147,7 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
T_struct(tys)
}
ty::ty_fn(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)),
ty::ty_trait(_, _) => T_opaque_trait(cx),
ty::ty_trait(_, _, _) => T_opaque_trait(cx),
ty::ty_type => T_ptr(cx.tydesc_type),
ty::ty_tup(elts) => {
let mut tys = ~[];

View File

@@ -134,7 +134,7 @@ fn type_needs_inner(cx: ctx, use: uint, ty: ty::t,
right tydesc into the result)
*/
ty::ty_fn(_) | ty::ty_ptr(_) | ty::ty_rptr(_, _)
| ty::ty_trait(_, _) => false,
| ty::ty_trait(_, _, _) => false,
ty::ty_enum(did, substs) => {
if option::is_none(list::find(enums_seen, |id| id == did)) {
let seen = @cons(did, enums_seen);

View File

@@ -172,7 +172,7 @@ export terr_regions_does_not_outlive, terr_mutability, terr_purity_mismatch;
export terr_regions_not_same, terr_regions_no_overlap;
export terr_proto_mismatch;
export terr_ret_style_mismatch;
export terr_fn;
export terr_fn, terr_trait;
export purity_to_str;
export param_tys_in_type;
export eval_repeat_count;
@@ -434,7 +434,7 @@ enum sty {
ty_rptr(region, mt),
ty_rec(~[field]),
ty_fn(fn_ty),
ty_trait(def_id, substs),
ty_trait(def_id, substs, vstore),
ty_class(def_id, substs),
ty_tup(~[t]),
@@ -452,7 +452,7 @@ enum sty {
}
enum terr_vstore_kind {
terr_vec, terr_str, terr_fn
terr_vec, terr_str, terr_fn, terr_trait
}
// Data structures used in type unification
@@ -670,7 +670,7 @@ fn mk_t_with_id(cx: ctxt, +st: sty, o_def_id: option<ast::def_id>) -> t {
ty_var(_) | ty_var_integral(_) => flags |= needs_infer as uint,
ty_self => flags |= has_self as uint,
ty_enum(_, ref substs) | ty_class(_, ref substs)
| ty_trait(_, ref substs) => {
| ty_trait(_, ref substs, _) => {
flags |= sflags(substs);
}
ty_box(m) | ty_uniq(m) | ty_evec(m, _) |
@@ -787,9 +787,10 @@ fn mk_tup(cx: ctxt, ts: ~[t]) -> t { mk_t(cx, ty_tup(ts)) }
// take a copy because we want to own the various vectors inside
fn mk_fn(cx: ctxt, +fty: fn_ty) -> t { mk_t(cx, ty_fn(fty)) }
fn mk_trait(cx: ctxt, did: ast::def_id, +substs: substs) -> t {
fn mk_trait(cx: ctxt, did: ast::def_id, +substs: substs, vstore: vstore)
-> t {
// take a copy of substs so that we own the vectors inside
mk_t(cx, ty_trait(did, substs))
mk_t(cx, ty_trait(did, substs, vstore))
}
fn mk_class(cx: ctxt, class_id: ast::def_id, +substs: substs) -> t {
@@ -862,7 +863,7 @@ fn maybe_walk_ty(ty: t, f: fn(t) -> bool) {
maybe_walk_ty(tm.ty, f);
}
ty_enum(_, substs) | ty_class(_, substs) |
ty_trait(_, substs) => {
ty_trait(_, substs, _) => {
for substs.tps.each |subty| { maybe_walk_ty(subty, f); }
}
ty_rec(fields) => {
@@ -907,8 +908,8 @@ fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty {
ty_enum(tid, ref substs) => {
ty_enum(tid, fold_substs(substs, fldop))
}
ty_trait(did, ref substs) => {
ty_trait(did, fold_substs(substs, fldop))
ty_trait(did, ref substs, vst) => {
ty_trait(did, fold_substs(substs, fldop), vst)
}
ty_rec(fields) => {
let new_fields = do vec::map(fields) |fl| {
@@ -1005,8 +1006,8 @@ fn fold_regions_and_ty(
ty_class(def_id, ref substs) => {
ty::mk_class(cx, def_id, fold_substs(substs, fldr, fldt))
}
ty_trait(def_id, ref substs) => {
ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt))
ty_trait(def_id, ref substs, vst) => {
ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), vst)
}
ref sty @ ty_fn(f) => {
let new_proto;
@@ -1664,7 +1665,7 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
}
// Trait instances are (for now) like shared boxes, basically
ty_trait(_, _) => kind_safe_for_default_mode() | kind_owned(),
ty_trait(_, _, _) => kind_safe_for_default_mode() | kind_owned(),
// Region pointers are copyable but NOT owned nor sendable
ty_rptr(_, _) => kind_safe_for_default_mode(),
@@ -1911,7 +1912,7 @@ fn is_instantiable(cx: ctxt, r_ty: t) -> bool {
}
}
ty_trait(_, _) => {
ty_trait(_, _, _) => {
false
}
@@ -2053,7 +2054,7 @@ fn type_is_pod(cx: ctxt, ty: t) -> bool {
ty_box(_) | ty_uniq(_) | ty_fn(_) |
ty_estr(vstore_uniq) | ty_estr(vstore_box) |
ty_evec(_, vstore_uniq) | ty_evec(_, vstore_box) |
ty_trait(_, _) | ty_rptr(_,_) | ty_opaque_box => result = false,
ty_trait(_, _, _) | ty_rptr(_,_) | ty_opaque_box => result = false,
// Structural types
ty_enum(did, ref substs) => {
let variants = enum_variants(cx, did);
@@ -2273,7 +2274,7 @@ pure fn hash_type_structure(st: &sty) -> uint {
ty_bot => 34u,
ty_ptr(mt) => hash_subty(35u, mt.ty),
ty_uniq(mt) => hash_subty(37u, mt.ty),
ty_trait(did, ref substs) => {
ty_trait(did, ref substs, _) => {
let mut h = hash_def(40u, did);
hash_substs(h, substs)
}
@@ -2590,7 +2591,7 @@ fn ty_sort_str(cx: ctxt, t: t) -> ~str {
ty_rptr(_, _) => ~"&-ptr",
ty_rec(_) => ~"record",
ty_fn(_) => ~"fn",
ty_trait(id, _) => fmt!{"trait %s", item_path_str(cx, id)},
ty_trait(id, _, _) => fmt!{"trait %s", item_path_str(cx, id)},
ty_class(id, _) => fmt!{"class %s", item_path_str(cx, id)},
ty_tup(_) => ~"tuple",
ty_var(_) => ~"variable",
@@ -2605,7 +2606,8 @@ fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str {
match k {
terr_vec => ~"[]",
terr_str => ~"str",
terr_fn => ~"fn"
terr_fn => ~"fn",
terr_trait => ~"trait"
}
}
@@ -2769,7 +2771,7 @@ fn impl_traits(cx: ctxt, id: ast::def_id) -> ~[t] {
fn ty_to_def_id(ty: t) -> option<ast::def_id> {
match get(ty).struct {
ty_trait(id, _) | ty_class(id, _) | ty_enum(id, _) => some(id),
ty_trait(id, _, _) | ty_class(id, _) | ty_enum(id, _) => some(id),
_ => none
}
}

View File

@@ -162,7 +162,7 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope copy owned>(
// Handle @, ~, and & being able to mean estrs and evecs.
// If a_seq_ty is a str or a vec, make it an estr/evec.
// Also handle function sigils.
// Also handle function sigils and first-class trait types.
fn mk_maybe_vstore<AC: ast_conv, RS: region_scope copy owned>(
self: AC, rscope: RS, a_seq_ty: ast::mt, vst: ty::vstore,
span: span, constr: fn(ty::mt) -> ty::t) -> ty::t {
@@ -181,6 +181,23 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope copy owned>(
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
return ty::mk_estr(tcx, vst);
}
some(ast::def_ty(type_def_id)) => {
let result = ast_path_to_substs_and_ty(self, rscope,
type_def_id, path);
match ty::get(result.ty).struct {
ty::ty_trait(trait_def_id, substs, _) => {
if vst != ty::vstore_box {
tcx.sess.span_unimpl(path.span,
~"`~trait` and `&trait` are \
unimplemented; use \
`@trait` instead for now");
}
return ty::mk_trait(tcx, trait_def_id, substs, vst);
}
_ =>
{}
}
}
_ => ()
}
}

View File

@@ -126,7 +126,7 @@ class lookup {
self.add_candidates_from_param(p.idx, p.def_id);
}
ty::ty_trait(did, substs) => {
ty::ty_trait(did, substs, _) => {
self.add_candidates_from_trait(did, substs);
}
ty::ty_class(did, substs) => {
@@ -238,7 +238,7 @@ class lookup {
}
ty::bound_trait(bound_t) => {
match check ty::get(bound_t).struct {
ty::ty_trait(i, substs) => (i, substs)
ty::ty_trait(i, substs, _) => (i, substs)
}
}
};

View File

@@ -158,7 +158,7 @@ fn visit_expr(e: @ast::expr, &&rcx: @rcx, v: rvt) {
result::err(_) => { return; /* typeck will fail anyhow */ }
result::ok(target_ty) => {
match ty::get(target_ty).struct {
ty::ty_trait(_, substs) => {
ty::ty_trait(_, substs, _) => {
let trait_region = match substs.self_r {
some(r) => {r}
none => {ty::re_static}

View File

@@ -37,10 +37,10 @@ fn fixup_substs(fcx: @fn_ctxt, sp: span,
id: ast::def_id, substs: ty::substs) -> ty::substs {
let tcx = fcx.ccx.tcx;
// use a dummy type just to package up the substs that need fixing up
let t = ty::mk_trait(tcx, id, substs);
let t = ty::mk_trait(tcx, id, substs, ty::vstore_slice(ty::re_static));
let t_f = fixup_ty(fcx, sp, t);
match check ty::get(t_f).struct {
ty::ty_trait(_, substs_f) => substs_f,
ty::ty_trait(_, substs_f, _) => substs_f,
}
}
@@ -63,7 +63,7 @@ fn lookup_vtable(fcx: @fn_ctxt, sp: span, ty: ty::t, trait_ty: ty::t,
let tcx = fcx.ccx.tcx;
let (trait_id, trait_substs) = match check ty::get(trait_ty).struct {
ty::ty_trait(did, substs) => (did, substs)
ty::ty_trait(did, substs, _) => (did, substs)
};
let ty = fixup_ty(fcx, sp, ty);
match ty::get(ty).struct {
@@ -77,7 +77,7 @@ fn lookup_vtable(fcx: @fn_ctxt, sp: span, ty: ty::t, trait_ty: ty::t,
}
ty::bound_trait(ity) => {
match check ty::get(ity).struct {
ty::ty_trait(idid, substs) => {
ty::ty_trait(idid, substs, _) => {
if trait_id == idid {
debug!{"(checking vtable) @0 relating ty to trait ty
with did %?", idid};
@@ -92,7 +92,7 @@ fn lookup_vtable(fcx: @fn_ctxt, sp: span, ty: ty::t, trait_ty: ty::t,
}
}
ty::ty_trait(did, substs) if trait_id == did => {
ty::ty_trait(did, substs, _) if trait_id == did => {
debug!{"(checking vtable) @1 relating ty to trait ty with did %?",
did};
@@ -139,7 +139,7 @@ fn lookup_vtable(fcx: @fn_ctxt, sp: span, ty: ty::t, trait_ty: ty::t,
for vec::each(ty::impl_traits(tcx, im.did)) |of_ty| {
// it must have the same id as the expected one
match ty::get(of_ty).struct {
ty::ty_trait(id, _) if id != trait_id => again,
ty::ty_trait(id, _, _) if id != trait_id => again,
_ => { /* ok */ }
}
@@ -219,7 +219,7 @@ fn connect_trait_tps(fcx: @fn_ctxt, sp: span, impl_tys: ~[ty::t],
debug!{"(connect trait tps) trait type is %?, impl did is %?",
ty::get(trait_ty).struct, impl_did};
match check ty::get(trait_ty).struct {
ty::ty_trait(_, substs) => {
ty::ty_trait(_, substs, _) => {
vec::iter2(substs.tps, trait_tys,
|a, b| demand::suptype(fcx, sp, a, b));
}

View File

@@ -96,7 +96,7 @@ fn get_base_type_def_id(inference_context: infer_ctxt,
match get(base_type).struct {
ty_enum(def_id, _) |
ty_class(def_id, _) |
ty_trait(def_id, _) => {
ty_trait(def_id, _, _) => {
return some(def_id);
}
_ => {
@@ -735,7 +735,7 @@ class CoherenceChecker {
// Record all the trait methods.
for associated_traits.each |trait_type| {
match get(trait_type).struct {
ty_trait(trait_id, _) => {
ty_trait(trait_id, _, _) => {
self.add_trait_method(trait_id, implementation);
}
_ => {

View File

@@ -40,7 +40,8 @@ fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) {
match intrinsic_item.node {
ast::item_trait(*) => {
let ty = ty::mk_trait(ccx.tcx, def_id, substs);
let ty = ty::mk_trait(ccx.tcx, def_id, substs,
ty::vstore_box);
ccx.tcx.intrinsic_defs.insert
(intrinsic_item.ident, (def_id, ty));
}
@@ -648,7 +649,7 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item)
}
ast::item_trait(tps, _, ms) => {
let {bounds, substs} = mk_substs(ccx, tps, rp);
let t = ty::mk_trait(tcx, local_def(it.id), substs);
let t = ty::mk_trait(tcx, local_def(it.id), substs, ty::vstore_box);
let tpt = {bounds: bounds, rp: rp, ty: t};
tcx.tcache.insert(local_def(it.id), tpt);
return tpt;

View File

@@ -1902,10 +1902,14 @@ fn super_tys<C:combine>(
}
}
(ty::ty_trait(a_id, ref a_substs), ty::ty_trait(b_id, ref b_substs))
(ty::ty_trait(a_id, ref a_substs, a_vstore),
ty::ty_trait(b_id, ref b_substs, b_vstore))
if a_id == b_id => {
do self.substs(a_substs, b_substs).chain |substs| {
ok(ty::mk_trait(tcx, a_id, substs))
do self.vstores(ty::terr_trait, a_vstore,
b_vstore).chain |vstores| {
ok(ty::mk_trait(tcx, a_id, substs, vstores))
}
}
}

View File

@@ -314,10 +314,11 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str {
let base = ast_map::path_to_str(path);
parameterized(cx, base, substs.self_r, substs.tps)
}
ty_trait(did, substs) => {
ty_trait(did, substs, vs) => {
let path = ty::item_path(cx, did);
let base = ast_map::path_to_str(path);
parameterized(cx, base, substs.self_r, substs.tps)
let result = parameterized(cx, base, substs.self_r, substs.tps);
vstore_ty_to_str(cx, result, vs)
}
ty_evec(mt, vs) => {
vstore_ty_to_str(cx, fmt!{"[%s]", mt_to_str(cx, mt)}, vs)