diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-08-14 15:27:06 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-08-15 16:20:31 -0700 |
| commit | fe9d07dda6e884df9873376c85941cc766dbd1dc (patch) | |
| tree | 426406223615438c3ea72db0fe7130dfb9ded1d8 | |
| parent | fd0f616ceb17ac283717322674e35b7589a27232 (diff) | |
| download | rust-fe9d07dda6e884df9873376c85941cc766dbd1dc.tar.gz rust-fe9d07dda6e884df9873376c85941cc766dbd1dc.zip | |
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".
27 files changed, 125 insertions, 83 deletions
diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs index 352831c86e6..c6dde67dd75 100644 --- a/src/fuzzer/fuzzer.rs +++ b/src/fuzzer/fuzzer.rs @@ -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, diff --git a/src/libsyntax/ext/tt/earley_parser.rs b/src/libsyntax/ext/tt/earley_parser.rs index b6dc1c05a2c..77ba941015b 100644 --- a/src/libsyntax/ext/tt/earley_parser.rs +++ b/src/libsyntax/ext/tt/earley_parser.rs @@ -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" => { diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 693b538ec6d..8acf0e8ec6d 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -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} { } } -} \ No newline at end of file +} diff --git a/src/libsyntax/parse.rs b/src/libsyntax/parse.rs index 6936eeed8f9..deaaaf69b1c 100644 --- a/src/libsyntax/parse.rs +++ b/src/libsyntax/parse.rs @@ -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}; } diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 2da34539321..701dd9301ca 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -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; } diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index 4038578d3f8..59dad16dc44 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -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 { diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 99768d558ab..aaafe958efb 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -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) == '>' { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f894f6fae82..642cdaa8fab 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index de1cd2c3df0..39bc18529c9 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -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 { ~"+" }); diff --git a/src/rustc/metadata/tydecode.rs b/src/rustc/metadata/tydecode.rs index 80c64430ec3..90be808b229 100644 --- a/src/rustc/metadata/tydecode.rs +++ b/src/rustc/metadata/tydecode.rs @@ -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); diff --git a/src/rustc/metadata/tyencode.rs b/src/rustc/metadata/tyencode.rs index f26ccff1806..5a24b9af8d9 100644 --- a/src/rustc/metadata/tyencode.rs +++ b/src/rustc/metadata/tyencode.rs @@ -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) => { diff --git a/src/rustc/middle/kind.rs b/src/rustc/middle/kind.rs index 9968318292c..e960e21c752 100644 --- a/src/rustc/middle/kind.rs +++ b/src/rustc/middle/kind.rs @@ -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 */ } }; diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 23f5c69caa1..83bdb941f46 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -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); diff --git a/src/rustc/middle/trans/reflect.rs b/src/rustc/middle/trans/reflect.rs index ccb3bf3429b..5829041a54a 100644 --- a/src/rustc/middle/trans/reflect.rs +++ b/src/rustc/middle/trans/reflect.rs @@ -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)]), diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs index 78eb527b785..5209b6f61f0 100644 --- a/src/rustc/middle/trans/shape.rs +++ b/src/rustc/middle/trans/shape.rs @@ -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; diff --git a/src/rustc/middle/trans/type_of.rs b/src/rustc/middle/trans/type_of.rs index d06862262f2..f48fa782683 100644 --- a/src/rustc/middle/trans/type_of.rs +++ b/src/rustc/middle/trans/type_of.rs @@ -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 = ~[]; diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs index d630653ef27..880c6c546f2 100644 --- a/src/rustc/middle/trans/type_use.rs +++ b/src/rustc/middle/trans/type_use.rs @@ -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); diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 2d85a0fd296..72cfbca1af0 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -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 } } diff --git a/src/rustc/middle/typeck/astconv.rs b/src/rustc/middle/typeck/astconv.rs index 9a1eba46f2e..64d4cdbd979 100644 --- a/src/rustc/middle/typeck/astconv.rs +++ b/src/rustc/middle/typeck/astconv.rs @@ -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); + } + _ => + {} + } + } _ => () } } diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs index 9de5aa98e5f..3bb0e566dc6 100644 --- a/src/rustc/middle/typeck/check/method.rs +++ b/src/rustc/middle/typeck/check/method.rs @@ -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) } } }; diff --git a/src/rustc/middle/typeck/check/regionck.rs b/src/rustc/middle/typeck/check/regionck.rs index 34a0bfc41a5..c4127eb2e48 100644 --- a/src/rustc/middle/typeck/check/regionck.rs +++ b/src/rustc/middle/typeck/check/regionck.rs @@ -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} diff --git a/src/rustc/middle/typeck/check/vtable.rs b/src/rustc/middle/typeck/check/vtable.rs index d509b26b841..a0218f3e9b5 100644 --- a/src/rustc/middle/typeck/check/vtable.rs +++ b/src/rustc/middle/typeck/check/vtable.rs @@ -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)); } diff --git a/src/rustc/middle/typeck/coherence.rs b/src/rustc/middle/typeck/coherence.rs index bc6342dbce1..24e80b13744 100644 --- a/src/rustc/middle/typeck/coherence.rs +++ b/src/rustc/middle/typeck/coherence.rs @@ -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); } _ => { diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs index 12d996777cb..0394813746d 100644 --- a/src/rustc/middle/typeck/collect.rs +++ b/src/rustc/middle/typeck/collect.rs @@ -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; diff --git a/src/rustc/middle/typeck/infer.rs b/src/rustc/middle/typeck/infer.rs index 36461b44b75..d2f799ff4f7 100644 --- a/src/rustc/middle/typeck/infer.rs +++ b/src/rustc/middle/typeck/infer.rs @@ -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)) + } } } diff --git a/src/rustc/util/ppaux.rs b/src/rustc/util/ppaux.rs index d471abbd4b6..a347fdddb79 100644 --- a/src/rustc/util/ppaux.rs +++ b/src/rustc/util/ppaux.rs @@ -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) diff --git a/src/test/run-pass/boxed-trait-with-vstore.rs b/src/test/run-pass/boxed-trait-with-vstore.rs new file mode 100644 index 00000000000..8e94d222746 --- /dev/null +++ b/src/test/run-pass/boxed-trait-with-vstore.rs @@ -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(); +} + |
