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

@ -264,7 +264,7 @@ fn check_variants_T<T: copy>(
@as_str(|a|pprust::print_crate(
codemap,
// Assuming we're not generating any token_trees
@syntax::util::interner::mk::<@~str>(
syntax::util::interner::mk::<@~str>(
|x| str::hash(*x), |x,y| str::eq(*x,*y)),
diagnostic::mk_span_handler(handler, codemap),
crate2,
@ -427,7 +427,7 @@ fn parse_and_print(code: @~str) -> ~str {
pprust::print_crate(
sess.cm,
// Assuming there are no token_trees
@syntax::util::interner::mk::<@~str>(
syntax::util::interner::mk::<@~str>(
|x| str::hash(*x), |x,y| str::eq(*x,*y)),
sess.span_diagnostic,
crate,
@ -576,7 +576,7 @@ fn check_variants(files: ~[~str], cx: context) {
as_str(|a| pprust::print_crate(
sess.cm,
// Assuming no token_trees
@syntax::util::interner::mk::<@~str>(
syntax::util::interner::mk::<@~str>(
|x| str::hash(*x), |x,y| str::eq(*x,*y)),
sess.span_diagnostic,
crate,

View file

@ -284,7 +284,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
nts, next_eis.len()});
} else if (bb_eis.len() == 0u && next_eis.len() == 0u) {
return failure(sp, ~"No rules expected the token "
+ to_str(*rdr.interner(), tok));
+ to_str(rdr.interner(), tok));
} else if (next_eis.len() > 0u) {
/* Now process the next token */
while(next_eis.len() > 0u) {
@ -334,7 +334,7 @@ fn parse_nt(p: parser, name: ~str) -> nonterminal {
~"ident" => match copy p.token {
token::IDENT(sn,b) => { p.bump(); token::nt_ident(sn,b) }
_ => p.fatal(~"expected ident, found "
+ token::to_str(*p.reader.interner(), copy p.token))
+ token::to_str(p.reader.interner(), copy p.token))
},
~"path" => token::nt_path(p.parse_path_with_tps(false)),
~"tt" => {

View file

@ -25,7 +25,7 @@ type tt_frame = @{
type tt_reader = @{
sp_diag: span_handler,
interner: @interner<@~str>,
interner: interner<@~str>,
mut cur: tt_frame,
/* for MBE-style macro transcription */
interpolations: std::map::hashmap<ident, @named_match>,
@ -39,7 +39,7 @@ type tt_reader = @{
/** This can do Macro-By-Example transcription. On the other hand, if
* `src` contains no `tt_seq`s and `tt_nonterminal`s, `interp` can (and
* should) be none. */
fn new_tt_reader(sp_diag: span_handler, itr: @interner<@~str>,
fn new_tt_reader(sp_diag: span_handler, itr: interner<@~str>,
interp: option<std::map::hashmap<ident,@named_match>>,
src: ~[ast::token_tree])
-> tt_reader {
@ -237,4 +237,4 @@ fn tt_next_token(&&r: tt_reader) -> {tok: token, sp: span} {
}
}
}
}

View file

@ -24,7 +24,7 @@ type parse_sess = @{
cm: codemap::codemap,
mut next_id: node_id,
span_diagnostic: span_handler,
interner: @interner::interner<@~str>,
interner: interner::interner<@~str>,
// these two must be kept up to date
mut chpos: uint,
mut byte_pos: uint
@ -35,7 +35,7 @@ fn new_parse_sess(demitter: option<emitter>) -> parse_sess {
return @{cm: cm,
mut next_id: 1,
span_diagnostic: mk_span_handler(mk_handler(demitter), cm),
interner: @interner::mk::<@~str>(|x| str::hash(*x),
interner: interner::mk::<@~str>(|x| str::hash(*x),
|x,y| str::eq(*x, *y)),
mut chpos: 0u, mut byte_pos: 0u};
}
@ -45,7 +45,7 @@ fn new_parse_sess_special_handler(sh: span_handler, cm: codemap::codemap)
return @{cm: cm,
mut next_id: 1,
span_diagnostic: sh,
interner: @interner::mk::<@~str>(|x| str::hash(*x),
interner: interner::mk::<@~str>(|x| str::hash(*x),
|x,y| str::eq(*x, *y)),
mut chpos: 0u, mut byte_pos: 0u};
}

View file

@ -276,7 +276,7 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
srdr: io::Reader) ->
{cmnts: ~[cmnt], lits: ~[lit]} {
let src = @str::from_bytes(srdr.read_whole_stream());
let itr = @interner::mk::<@~str>(
let itr = interner::mk::<@~str>(
|x| str::hash(*x),
|x,y| str::eq(*x, *y)
);
@ -311,7 +311,7 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
vec::push(literals, {lit: s, pos: sp.lo});
log(debug, ~"tok lit: " + s);
} else {
log(debug, ~"tok: " + token::to_str(*rdr.interner, tok));
log(debug, ~"tok: " + token::to_str(rdr.interner, tok));
}
first_read = false;
}

View file

@ -19,7 +19,7 @@ fn seq_sep_none() -> seq_sep {
}
fn token_to_str(reader: reader, ++token: token::token) -> ~str {
token::to_str(*reader.interner(), token)
token::to_str(reader.interner(), token)
}
trait parser_common {

View file

@ -14,7 +14,7 @@ trait reader {
fn next_token() -> {tok: token::token, sp: span};
fn fatal(~str) -> !;
fn span_diag() -> span_handler;
pure fn interner() -> @interner<@~str>;
pure fn interner() -> interner<@~str>;
fn peek() -> {tok: token::token, sp: span};
fn dup() -> reader;
}
@ -27,7 +27,7 @@ type string_reader = @{
mut curr: char,
mut chpos: uint,
filemap: codemap::filemap,
interner: @interner<@~str>,
interner: interner<@~str>,
/* cached: */
mut peek_tok: token::token,
mut peek_span: span
@ -35,7 +35,7 @@ type string_reader = @{
fn new_string_reader(span_diagnostic: span_handler,
filemap: codemap::filemap,
itr: @interner<@~str>) -> string_reader {
itr: interner<@~str>) -> string_reader {
let r = new_low_level_string_reader(span_diagnostic, filemap, itr);
string_advance_token(r); /* fill in peek_* */
return r;
@ -44,7 +44,7 @@ fn new_string_reader(span_diagnostic: span_handler,
/* For comments.rs, which hackily pokes into 'pos' and 'curr' */
fn new_low_level_string_reader(span_diagnostic: span_handler,
filemap: codemap::filemap,
itr: @interner<@~str>)
itr: interner<@~str>)
-> string_reader {
let r = @{span_diagnostic: span_diagnostic, src: filemap.src,
mut col: 0u, mut pos: 0u, mut curr: -1 as char,
@ -79,7 +79,7 @@ impl string_reader: reader {
self.span_diagnostic.span_fatal(copy self.peek_span, m)
}
fn span_diag() -> span_handler { self.span_diagnostic }
pure fn interner() -> @interner<@~str> { self.interner }
pure fn interner() -> interner<@~str> { self.interner }
fn peek() -> {tok: token::token, sp: span} {
{tok: self.peek_tok, sp: self.peek_span}
}
@ -101,7 +101,7 @@ impl tt_reader: reader {
self.sp_diag.span_fatal(copy self.cur_span, m);
}
fn span_diag() -> span_handler { self.sp_diag }
pure fn interner() -> @interner<@~str> { self.interner }
pure fn interner() -> interner<@~str> { self.interner }
fn peek() -> {tok: token::token, sp: span} {
{ tok: self.cur_tok, sp: self.cur_span }
}
@ -219,7 +219,7 @@ fn consume_any_line_comment(rdr: string_reader)
bump(rdr);
}
return some({
tok: token::DOC_COMMENT((*rdr.interner).intern(@acc)),
tok: token::DOC_COMMENT(rdr.interner.intern(@acc)),
sp: ast_util::mk_sp(start_chpos, rdr.chpos)
});
} else {
@ -264,7 +264,7 @@ fn consume_block_comment(rdr: string_reader)
bump(rdr);
bump(rdr);
return some({
tok: token::DOC_COMMENT((*rdr.interner).intern(@acc)),
tok: token::DOC_COMMENT(rdr.interner.intern(@acc)),
sp: ast_util::mk_sp(start_chpos, rdr.chpos)
});
}
@ -398,12 +398,12 @@ fn scan_number(c: char, rdr: string_reader) -> token::token {
if c == '3' && n == '2' {
bump(rdr);
bump(rdr);
return token::LIT_FLOAT((*rdr.interner).intern(@num_str),
return token::LIT_FLOAT(rdr.interner.intern(@num_str),
ast::ty_f32);
} else if c == '6' && n == '4' {
bump(rdr);
bump(rdr);
return token::LIT_FLOAT((*rdr.interner).intern(@num_str),
return token::LIT_FLOAT(rdr.interner.intern(@num_str),
ast::ty_f64);
/* FIXME (#2252): if this is out of range for either a
32-bit or 64-bit float, it won't be noticed till the
@ -413,7 +413,7 @@ fn scan_number(c: char, rdr: string_reader) -> token::token {
}
}
if is_float {
return token::LIT_FLOAT((*rdr.interner).intern(@num_str), ast::ty_f);
return token::LIT_FLOAT(rdr.interner.intern(@num_str), ast::ty_f);
} else {
if str::len(num_str) == 0u {
rdr.fatal(~"no valid digits found for number");
@ -461,7 +461,7 @@ fn next_token_inner(rdr: string_reader) -> token::token {
let is_mod_name = c == ':' && nextch(rdr) == ':';
// FIXME: perform NFKC normalization here. (Issue #2253)
return token::IDENT((*rdr.interner).intern(@accum_str), is_mod_name);
return token::IDENT(rdr.interner.intern(@accum_str), is_mod_name);
}
if is_dec_digit(c) {
return scan_number(c, rdr);
@ -630,7 +630,7 @@ fn next_token_inner(rdr: string_reader) -> token::token {
}
}
bump(rdr);
return token::LIT_STR((*rdr.interner).intern(@accum_str));
return token::LIT_STR(rdr.interner.intern(@accum_str));
}
'-' => {
if nextch(rdr) == '>' {

View file

@ -263,7 +263,7 @@ class parser {
self.sess.span_diagnostic.span_warn(copy self.span, m)
}
pure fn get_str(i: token::str_num) -> @~str {
(*self.reader.interner()).get(i)
self.reader.interner().get(i)
}
fn get_id() -> node_id { next_node_id(self.sess) }

View file

@ -11,7 +11,7 @@ import dvec::{DVec, dvec};
import parse::classify::*;
import util::interner;
type ident_interner = @interner::interner<@~str>;
type ident_interner = interner::interner<@~str>;
// The ps is stored here to prevent recursive type.
enum ann_node {
@ -30,7 +30,7 @@ fn no_ann() -> pp_ann {
type ps =
@{s: pp::printer,
cm: option<codemap>,
intr: @interner::interner<@~str>,
intr: interner::interner<@~str>,
comments: option<~[comments::cmnt]>,
literals: option<~[comments::lit]>,
mut cur_cmnt: uint,
@ -51,8 +51,8 @@ fn end(s: ps) {
fn rust_printer(writer: io::Writer) -> ps {
return @{s: pp::mk_printer(writer, default_columns),
cm: none::<codemap>,
intr: @interner::mk::<@~str>(|x| str::hash(*x),
|x,y| str::eq(*x, *y)),
intr: interner::mk::<@~str>(|x| str::hash(*x),
|x,y| str::eq(*x, *y)),
comments: none::<~[comments::cmnt]>,
literals: none::<~[comments::lit]>,
mut cur_cmnt: 0u,
@ -81,7 +81,7 @@ const default_columns: uint = 78u;
// Requires you to pass an input filename and reader so that
// it can scan the input text for comments and literals to
// copy forward.
fn print_crate(cm: codemap, intr: @interner::interner<@~str>,
fn print_crate(cm: codemap, intr: interner::interner<@~str>,
span_diagnostic: diagnostic::span_handler,
crate: @ast::crate, filename: ~str, in: io::Reader,
out: io::Writer, ann: pp_ann, is_expanded: bool) {
@ -690,14 +690,14 @@ fn print_tt(s: ps, tt: ast::token_tree) {
}
_ => { s.s.token_tree_last_was_ident = false; }
}
word(s.s, parse::token::to_str(*s.intr, tk));
word(s.s, parse::token::to_str(s.intr, tk));
}
ast::tt_seq(_, tts, sep, zerok) => {
word(s.s, ~"$(");
for tts.each() |tt_elt| { print_tt(s, tt_elt); }
word(s.s, ~")");
match sep {
some(tk) => word(s.s, parse::token::to_str(*s.intr, tk)),
some(tk) => word(s.s, parse::token::to_str(s.intr, tk)),
none => ()
}
word(s.s, if zerok { ~"*" } else { ~"+" });

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)

View file

@ -0,0 +1,15 @@
trait Foo {
fn foo() {}
}
impl int : Foo {
fn foo() {
io::println("Hello world!");
}
}
fn main() {
let x = 3 as @Foo;
x.foo();
}