diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 3df4a2aefa5..f7e990b1025 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -678,31 +678,24 @@ type item = {ident: ident, attrs: ~[attribute], id: node_id, node: item_, vis: visibility, span: span}; -#[auto_serialize] -enum region_param { - rp_none, - rp_self -} - #[auto_serialize] enum item_ { item_const(@ty, @expr), item_fn(fn_decl, ~[ty_param], blk), item_mod(_mod), item_foreign_mod(foreign_mod), - item_ty(@ty, ~[ty_param], region_param), - item_enum(~[variant], ~[ty_param], region_param), + item_ty(@ty, ~[ty_param]), + item_enum(~[variant], ~[ty_param]), item_class(~[ty_param], /* ty params for class */ ~[@trait_ref], /* traits this class implements */ ~[@class_member], /* methods, etc. */ /* (not including ctor or dtor) */ class_ctor, /* dtor is optional */ - option, - region_param + option ), - item_trait(~[ty_param], region_param, ~[ty_method]), - item_impl(~[ty_param], region_param, option<@trait_ref> /* trait */, + item_trait(~[ty_param], ~[ty_method]), + item_impl(~[ty_param], option<@trait_ref> /* trait */, @ty /* self */, ~[@method]), item_mac(mac), } diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 79d6691caf1..129a03f71aa 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -188,14 +188,14 @@ fn map_item(i: @item, cx: ctx, v: vt) { let item_path = @/* FIXME (#2543) */ copy cx.path; cx.map.insert(i.id, node_item(i, item_path)); alt i.node { - item_impl(_, _, _, _, ms) { + item_impl(_, _, _, ms) { let impl_did = ast_util::local_def(i.id); for ms.each |m| { map_method(impl_did, extend(cx, i.ident), m, cx); } } - item_enum(vs, _, _) { + item_enum(vs, _) { for vs.each |v| { cx.map.insert(v.node.id, node_variant( /* FIXME (#2543) */ copy v, i, @@ -214,7 +214,7 @@ fn map_item(i: @item, cx: ctx, v: vt) { extend(cx, i.ident))); } } - item_class(tps, traits, items, ctor, dtor, _) { + item_class(tps, traits, items, ctor, dtor) { let (_, ms) = ast_util::split_class_items(items); // Map trait refs to their parent classes. This is // so we can find the self_ty diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 551c6817405..806f6c35ed0 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -155,7 +155,7 @@ fn is_exported(i: ident, m: _mod) -> bool { for m.items.each |it| { if it.ident == i { local = true; } alt it.node { - item_enum(variants, _, _) { + item_enum(variants, _) { for variants.each |v| { if v.node.name == i { local = true; @@ -428,7 +428,7 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> { visit_item: fn@(i: @item) { vfn(i.id); alt i.node { - item_enum(vs, _, _) { for vs.each |v| { vfn(v.node.id); } } + item_enum(vs, _) { for vs.each |v| { vfn(v.node.id); } } _ {} } }, @@ -519,6 +519,9 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> { } }, + visit_ty_method: fn@(_ty_m: ty_method) { + }, + visit_class_item: fn@(c: @class_member) { alt c.node { instance_var(_, _, _, id,_) { diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs index 64da3a7dcbd..6bbce757a92 100644 --- a/src/libsyntax/ext/auto_serialize.rs +++ b/src/libsyntax/ext/auto_serialize.rs @@ -102,12 +102,12 @@ fn expand(cx: ext_ctxt, do vec::flat_map(in_items) |in_item| { alt in_item.node { - ast::item_ty(ty, tps, _) { + ast::item_ty(ty, tps) { vec::append(~[filter_attrs(in_item)], ty_fns(cx, in_item.ident, ty, tps)) } - ast::item_enum(variants, tps, _) { + ast::item_enum(variants, tps) { vec::append(~[filter_attrs(in_item)], enum_fns(cx, in_item.ident, in_item.span, variants, tps)) diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index b23e707f4eb..ac0d507e61e 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -128,8 +128,7 @@ impl ast_builder for ext_ctxt { +ty_params: ~[ast::ty_param]) -> @ast::item { self.item(name, ast::item_enum(variants, - ty_params, - ast::rp_none)) + ty_params)) } fn item_enum(name: ident, @@ -167,12 +166,10 @@ impl ast_builder for ext_ctxt { fn item_ty_poly(name: ident, ty: @ast::ty, +params: ~[ast::ty_param]) -> @ast::item { - self.item(name, - ast::item_ty(ty, params, ast::rp_none)) + self.item(name, ast::item_ty(ty, params)) } - fn item_ty(name: ident, - ty: @ast::ty) -> @ast::item { + fn item_ty(name: ident, ty: @ast::ty) -> @ast::item { self.item_ty_poly(name, ty, ~[]) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 01298675688..a78148b37c6 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -244,15 +244,13 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { } item_mod(m) { item_mod(fld.fold_mod(m)) } item_foreign_mod(nm) { item_foreign_mod(fld.fold_foreign_mod(nm)) } - item_ty(t, typms, rp) { item_ty(fld.fold_ty(t), - fold_ty_params(typms, fld), - rp) } - item_enum(variants, typms, r) { + item_ty(t, typms) { item_ty(fld.fold_ty(t), + fold_ty_params(typms, fld)) } + item_enum(variants, typms) { item_enum(vec::map(variants, |x| fld.fold_variant(x)), - fold_ty_params(typms, fld), - r) + fold_ty_params(typms, fld)) } - item_class(typms, traits, items, ctor, m_dtor, rp) { + item_class(typms, traits, items, ctor, m_dtor) { let ctor_body = fld.fold_block(ctor.node.body); let ctor_decl = fold_fn_decl(ctor.node.dec, fld); let ctor_id = fld.new_id(ctor.node.id); @@ -269,18 +267,16 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { {node: {body: ctor_body, dec: ctor_decl, id: ctor_id with ctor.node} - with ctor}, dtor, rp) + with ctor}, dtor) } - item_impl(tps, rp, ifce, ty, methods) { + item_impl(tps, ifce, ty, methods) { item_impl(fold_ty_params(tps, fld), - rp, ifce.map(|p| fold_trait_ref(p, fld)), fld.fold_ty(ty), vec::map(methods, |x| fld.fold_method(x))) } - item_trait(tps, rp, methods) { + item_trait(tps, methods) { item_trait(fold_ty_params(tps, fld), - rp, /* FIXME (#2543) */ copy methods) } item_mac(m) { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1a60d46f5e5..f4681ba2619 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -41,8 +41,8 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute, pat_box, pat_enum, pat_ident, pat_lit, pat_range, pat_rec, pat_tup, pat_uniq, pat_wild, path, private, proto, proto_any, proto_bare, proto_block, proto_box, proto_uniq, public, pure_fn, - purity, re_anon, re_named, region, region_param, rem, ret_style, - return_val, rp_none, rp_self, shl, shr, stmt, stmt_decl, + purity, re_anon, re_named, region, rem, ret_style, + return_val, shl, shr, stmt, stmt_decl, stmt_expr, stmt_semi, subtract, token_tree, trait_ref, tt_delim, tt_dotdotdot, tt_flat, tt_interpolate, ty, ty_, ty_bot, ty_box, ty_constr, ty_constr_, ty_constr_arg, ty_field, ty_fn, ty_infer, @@ -2133,10 +2133,10 @@ class parser { fn parse_item_trait() -> item_info { let ident = self.parse_ident(); - let rp = self.parse_region_param(); + self.parse_region_param(); let tps = self.parse_ty_params(); let meths = self.parse_ty_methods(); - (ident, item_trait(tps, rp, meths), none) + (ident, item_trait(tps, meths), none) } // Parses three variants (with the region/type params always optional): @@ -2147,18 +2147,19 @@ class parser { fn wrap_path(p: parser, pt: @path) -> @ty { @{id: p.get_id(), node: ty_path(pt, p.get_id()), span: pt.span} } - let mut (ident, rp, tps) = { + let mut (ident, tps) = { if self.token == token::LT { - (none, rp_none, self.parse_ty_params()) + (none, self.parse_ty_params()) } else if self.token == token::BINOP(token::SLASH) { - (none, self.parse_region_param(), self.parse_ty_params()) + self.parse_region_param(); + (none, self.parse_ty_params()) } else if self.is_keyword("of") { - (none, rp_none, ~[]) + (none, ~[]) } else { let id = self.parse_ident(); - let rp = self.parse_region_param(); - (some(id), rp, self.parse_ty_params()) + self.parse_region_param(); + (some(id), self.parse_ty_params()) } }; let ifce = if self.eat_keyword("of") { @@ -2179,25 +2180,18 @@ class parser { while !self.eat(token::RBRACE) { vec::push(meths, self.parse_method(public)); } - (ident, item_impl(tps, rp, ifce, ty, meths), none) + (ident, item_impl(tps, ifce, ty, meths), none) } // Instantiates ident with references to as arguments. // Used to create a path that refers to a class which will be defined as // the return type of the ctor function. fn ident_to_path_tys(i: ident, - rp: region_param, typarams: ~[ty_param]) -> @path { let s = self.last_span; - // Hack. But then, this whole function is in service of a hack. - let a_r = alt rp { - rp_none { none } - rp_self { some(self.region_from_name(some(@"self"))) } - }; - @{span: s, global: false, idents: ~[i], - rp: a_r, + rp: none, types: vec::map(typarams, |tp| { @{id: self.get_id(), node: ty_path(ident_to_path(s, tp.ident), self.get_id()), @@ -2218,9 +2212,9 @@ class parser { fn parse_item_class() -> item_info { let class_name = self.parse_value_ident(); - let rp = self.parse_region_param(); + self.parse_region_param(); let ty_params = self.parse_ty_params(); - let class_path = self.ident_to_path_tys(class_name, rp, ty_params); + let class_path = self.ident_to_path_tys(class_name, ty_params); let traits : ~[@trait_ref] = if self.eat(token::COLON) { self.parse_trait_ref_list() } else { ~[] }; @@ -2255,7 +2249,7 @@ class parser { self_id: self.get_id(), dec: ct_d, body: ct_b}, - span: ct_s}, actual_dtor, rp), + span: ct_s}, actual_dtor), none) } /* @@ -2447,26 +2441,23 @@ class parser { fn parse_item_type() -> item_info { let t = self.parse_type_decl(); - let rp = self.parse_region_param(); + self.parse_region_param(); let tps = self.parse_ty_params(); self.expect(token::EQ); let ty = self.parse_ty(false); self.expect(token::SEMI); - (t.ident, item_ty(ty, tps, rp), none) + (t.ident, item_ty(ty, tps), none) } - fn parse_region_param() -> region_param { + fn parse_region_param() { if self.eat(token::BINOP(token::SLASH)) { self.expect(token::BINOP(token::AND)); - rp_self - } else { - rp_none } } fn parse_item_enum(default_vis: visibility) -> item_info { let id = self.parse_ident(); - let rp = self.parse_region_param(); + self.parse_region_param(); let ty_params = self.parse_ty_params(); let mut variants: ~[variant] = ~[]; // Newtype syntax @@ -2483,7 +2474,7 @@ class parser { id: self.get_id(), disr_expr: none, vis: public}); - ret (id, item_enum(~[variant], ty_params, rp), none); + ret (id, item_enum(~[variant], ty_params), none); } self.expect(token::LBRACE); @@ -2521,7 +2512,7 @@ class parser { self.fatal("discriminator values can only be used with a c-like \ enum"); } - (id, item_enum(variants, ty_params, rp), none) + (id, item_enum(variants, ty_params), none) } fn parse_fn_ty_proto() -> proto { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 5453c3cf5eb..7e7dff4de12 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -458,12 +458,11 @@ fn print_item(s: ps, &&item: @ast::item) { print_foreign_mod(s, nmod, item.attrs); bclose(s, item.span); } - ast::item_ty(ty, params, rp) { + ast::item_ty(ty, params) { ibox(s, indent_unit); ibox(s, 0u); word_nbsp(s, "type"); word(s.s, *item.ident); - print_region_param(s, rp); print_type_params(s, params); end(s); // end the inner ibox @@ -473,7 +472,7 @@ fn print_item(s: ps, &&item: @ast::item) { word(s.s, ";"); end(s); // end the outer ibox } - ast::item_enum(variants, params, rp) { + ast::item_enum(variants, params) { let newtype = vec::len(variants) == 1u && str::eq(*item.ident, *variants[0].node.name) && @@ -483,7 +482,6 @@ fn print_item(s: ps, &&item: @ast::item) { word_space(s, "enum"); } else { head(s, "enum"); } word(s.s, *item.ident); - print_region_param(s, rp); print_type_params(s, params); space(s.s); if newtype { @@ -506,10 +504,9 @@ fn print_item(s: ps, &&item: @ast::item) { bclose(s, item.span); } } - ast::item_class(tps, traits, items, ctor, m_dtor, rp) { + ast::item_class(tps, traits, items, ctor, m_dtor) { head(s, "class"); word_nbsp(s, *item.ident); - print_region_param(s, rp); print_type_params(s, tps); if vec::len(traits) != 0u { word_space(s, ":"); @@ -571,10 +568,9 @@ fn print_item(s: ps, &&item: @ast::item) { } bclose(s, item.span); } - ast::item_impl(tps, rp, ifce, ty, methods) { + ast::item_impl(tps, ifce, ty, methods) { head(s, "impl"); word(s.s, *item.ident); - print_region_param(s, rp); print_type_params(s, tps); space(s.s); option::iter(ifce, |p| { @@ -591,10 +587,9 @@ fn print_item(s: ps, &&item: @ast::item) { } bclose(s, item.span); } - ast::item_trait(tps, rp, methods) { + ast::item_trait(tps, methods) { head(s, "iface"); word(s.s, *item.ident); - print_region_param(s, rp); print_type_params(s, tps); word(s.s, " "); bopen(s); @@ -1406,13 +1401,6 @@ fn print_bounds(s: ps, bounds: @~[ast::ty_param_bound]) { } } -fn print_region_param(s: ps, rp: ast::region_param) { - alt rp { - ast::rp_self { word(s.s, "/&") } - ast::rp_none { } - } -} - fn print_type_params(s: ps, &¶ms: ~[ast::ty_param]) { if vec::len(params) > 0u { word(s.s, "<"); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 51fd2e47c86..5dc42fd4823 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -61,6 +61,7 @@ type visitor = visit_ty_params: fn@(~[ty_param], E, vt), visit_constr: fn@(@path, span, node_id, E, vt), visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id, E, vt), + visit_ty_method: fn@(ty_method, E, vt), visit_class_item: fn@(@class_member, E, vt)}; fn default_visitor() -> visitor { @@ -79,6 +80,7 @@ fn default_visitor() -> visitor { visit_ty_params: |a,b,c|visit_ty_params::(a, b, c), visit_constr: |a,b,c,d,e|visit_constr::(a, b, c, d, e), visit_fn: |a,b,c,d,e,f,g|visit_fn::(a, b, c, d, e, f, g), + visit_ty_method: |a,b,c|visit_ty_method::(a, b, c), visit_class_item: |a,b,c|visit_class_item::(a, b, c)}; } @@ -125,17 +127,17 @@ fn visit_item(i: @item, e: E, v: vt) { for nm.view_items.each |vi| { v.visit_view_item(vi, e, v); } for nm.items.each |ni| { v.visit_foreign_item(ni, e, v); } } - item_ty(t, tps, rp) { + item_ty(t, tps) { v.visit_ty(t, e, v); v.visit_ty_params(tps, e, v); } - item_enum(variants, tps, _) { + item_enum(variants, tps) { v.visit_ty_params(tps, e, v); for variants.each |vr| { for vr.node.args.each |va| { v.visit_ty(va.ty, e, v); } } } - item_impl(tps, _rp, ifce, ty, methods) { + item_impl(tps, ifce, ty, methods) { v.visit_ty_params(tps, e, v); option::iter(ifce, |p| visit_path(p.path, e, v)); v.visit_ty(ty, e, v); @@ -143,7 +145,7 @@ fn visit_item(i: @item, e: E, v: vt) { visit_method_helper(m, e, v) } } - item_class(tps, traits, members, ctor, m_dtor, _) { + item_class(tps, traits, members, ctor, m_dtor) { v.visit_ty_params(tps, e, v); for members.each |m| { v.visit_class_item(m, e, v); @@ -155,12 +157,10 @@ fn visit_item(i: @item, e: E, v: vt) { visit_class_dtor_helper(dtor, tps, ast_util::local_def(i.id), e, v)}; } - item_trait(tps, _rp, methods) { + item_trait(tps, methods) { v.visit_ty_params(tps, e, v); for methods.each |m| { - for m.decl.inputs.each |a| { v.visit_ty(a.ty, e, v); } - v.visit_ty_params(m.tps, e, v); - v.visit_ty(m.decl.output, e, v); + v.visit_ty_method(m, e, v); } } item_mac(m) { visit_mac(m, e, v) } @@ -311,6 +311,12 @@ fn visit_fn(fk: fn_kind, decl: fn_decl, body: blk, _sp: span, v.visit_block(body, e, v); } +fn visit_ty_method(m: ty_method, e: E, v: vt) { + for m.decl.inputs.each |a| { v.visit_ty(a.ty, e, v); } + v.visit_ty_params(m.tps, e, v); + v.visit_ty(m.decl.output, e, v); +} + fn visit_block(b: ast::blk, e: E, v: vt) { for b.node.view_items.each |vi| { v.visit_view_item(vi, e, v); } for b.node.stmts.each |s| { v.visit_stmt(s, e, v); } @@ -458,6 +464,7 @@ type simple_visitor = visit_ty_params: fn@(~[ty_param]), visit_constr: fn@(@path, span, node_id), visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id), + visit_ty_method: fn@(ty_method), visit_class_item: fn@(@class_member)}; fn simple_ignore_ty(_t: @ty) {} @@ -479,6 +486,7 @@ fn default_simple_visitor() -> simple_visitor { visit_constr: fn@(_p: @path, _sp: span, _id: node_id) { }, visit_fn: fn@(_fk: fn_kind, _d: fn_decl, _b: blk, _sp: span, _id: node_id) { }, + visit_ty_method: fn@(_m: ty_method) { }, visit_class_item: fn@(_c: @class_member) {} }; } @@ -534,6 +542,10 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> { f(ty); visit_ty(ty, e, v); } + fn v_ty_method(f: fn@(ty_method), ty: ty_method, &&e: (), v: vt<()>) { + f(ty); + visit_ty_method(ty, e, v); + } fn v_ty_params(f: fn@(~[ty_param]), ps: ~[ty_param], &&e: (), v: vt<()>) { @@ -582,6 +594,8 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> { v_constr(v.visit_constr, a, b, c, d, e), visit_fn: |a,b,c,d,e,f,g| v_fn(v.visit_fn, a, b, c, d, e, f, g), + visit_ty_method: |a,b,c| + v_ty_method(v.visit_ty_method, a, b, c), visit_class_item: |a,b,c| v_class_item(v.visit_class_item, a, b, c) }); diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs index 606bcd77e1a..cec72045bca 100644 --- a/src/rustc/driver/driver.rs +++ b/src/rustc/driver/driver.rs @@ -178,7 +178,11 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg, let region_map = time(time_passes, "region resolution", || middle::region::resolve_crate(sess, def_map, crate)); - let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars, region_map); + let rp_set = time(time_passes, "region paramerization inference", || + middle::region::determine_rp_in_crate(sess, ast_map, def_map, crate)); + + let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars, + region_map, rp_set); let (method_map, vtable_map) = time(time_passes, "typechecking", || typeck::check_crate(ty_cx, diff --git a/src/rustc/driver/session.rs b/src/rustc/driver/session.rs index cffec613e60..be21555a1d7 100644 --- a/src/rustc/driver/session.rs +++ b/src/rustc/driver/session.rs @@ -38,6 +38,7 @@ const no_rt: uint = 256u; const coherence: uint = 512u; const borrowck_stats: uint = 1024u; const borrowck_note_pure: uint = 2048; +const borrowck_note_loan: uint = 4096; fn debugging_opts_map() -> ~[(str, str, uint)] { ~[("ppregions", "prettyprint regions with \ @@ -46,7 +47,7 @@ fn debugging_opts_map() -> ~[(str, str, uint)] { ("count-llvm-insns", "count where LLVM \ instrs originate", count_llvm_insns), ("time-llvm-passes", "measure time of each LLVM pass", time_llvm_passes), - ("stats", "gather trans statistics", stats), + ("trans-stats", "gather trans statistics", trans_stats), ("no-asm-comments", "omit comments when using -S", no_asm_comments), ("no-verify", "skip LLVM verification", no_verify), ("trace", "emit trace logs", trace), @@ -54,7 +55,9 @@ fn debugging_opts_map() -> ~[(str, str, uint)] { ("coherence", "perform coherence checking", coherence), ("borrowck-stats", "gather borrowck statistics", borrowck_stats), ("borrowck-note-pure", "note where purity is req'd", - borrowck_note_pure) + borrowck_note_pure), + ("borrowck-note-loan", "note where loans are req'd", + borrowck_note_loan) ] } @@ -172,6 +175,7 @@ impl session for session { fn coherence() -> bool { self.debugging_opt(coherence) } fn borrowck_stats() -> bool { self.debugging_opt(borrowck_stats) } fn borrowck_note_pure() -> bool { self.debugging_opt(borrowck_note_pure) } + fn borrowck_note_loan() -> bool { self.debugging_opt(borrowck_note_loan) } } /// Some reasonable defaults diff --git a/src/rustc/metadata/csearch.rs b/src/rustc/metadata/csearch.rs index 03b3fdcba86..16b2481edd9 100644 --- a/src/rustc/metadata/csearch.rs +++ b/src/rustc/metadata/csearch.rs @@ -17,6 +17,7 @@ export get_class_fields; export get_class_method; export get_field_type; export get_type_param_count; +export get_region_param; export lookup_defs; export lookup_method_purity; export get_enum_variants; @@ -151,6 +152,12 @@ fn get_type(tcx: ty::ctxt, def: ast::def_id) -> ty::ty_param_bounds_and_ty { decoder::get_type(cdata, def.node, tcx) } +fn get_region_param(cstore: metadata::cstore::cstore, + def: ast::def_id) -> bool { + let cdata = cstore::get_crate_data(cstore, def.crate); + ret decoder::get_region_param(cdata, def.node); +} + fn get_field_type(tcx: ty::ctxt, class_id: ast::def_id, def: ast::def_id) -> ty::ty_param_bounds_and_ty { let cstore = tcx.cstore; @@ -168,7 +175,7 @@ fn get_field_type(tcx: ty::ctxt, class_id: ast::def_id, class_id, def) ); #debug("got field data %?", the_field); let ty = decoder::item_type(def, the_field, tcx, cdata); - ret {bounds: @~[], rp: ast::rp_none, ty: ty}; + ret {bounds: @~[], rp: false, ty: ty}; } // Given a def_id for an impl or class, return the trait it implements, diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs index b3e5660c4a8..fd2eb10d8d5 100644 --- a/src/rustc/metadata/decoder.rs +++ b/src/rustc/metadata/decoder.rs @@ -21,6 +21,7 @@ export get_class_fields; export get_symbol; export get_enum_variants; export get_type; +export get_region_param; export get_type_param_count; export get_impl_trait; export get_class_method; @@ -185,15 +186,10 @@ fn item_ty_param_bounds(item: ebml::doc, tcx: ty::ctxt, cdata: cmd) @bounds } -fn item_ty_region_param(item: ebml::doc) -> ast::region_param { +fn item_ty_region_param(item: ebml::doc) -> bool { alt ebml::maybe_get_doc(item, tag_region_param) { - some(rp_doc) { - let dsr = ebml::ebml_deserializer(rp_doc); - ast::deserialize_region_param(dsr) - } - none { // not all families of items have region params - ast::rp_none - } + some(_) { true } + none { false } } } @@ -325,6 +321,11 @@ fn get_type(cdata: cmd, id: ast::node_id, tcx: ty::ctxt) ret {bounds: tp_bounds, rp: rp, ty: t}; } +fn get_region_param(cdata: cmd, id: ast::node_id) -> bool { + let item = lookup_item(id, cdata.data); + ret item_ty_region_param(item); +} + fn get_type_param_count(data: @~[u8], id: ast::node_id) -> uint { item_ty_param_count(lookup_item(id, data)) } diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 972fa278453..7539d2be00b 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -86,10 +86,10 @@ fn encode_name_and_def_id(ebml_w: ebml::writer, nm: ident, encode_def_id(ebml_w, local_def(id)); } -fn encode_region_param(ebml_w: ebml::writer, rp: region_param) { - do ebml_w.wr_tag(tag_region_param) { - serialize_region_param(ebml_w, rp) - } +fn encode_region_param(ecx: @encode_ctxt, ebml_w: ebml::writer, + it: @ast::item) { + let rp = ecx.tcx.region_paramd_items.contains_key(it.id); + if rp { do ebml_w.wr_tag(tag_region_param) { } } } fn encode_named_def_id(ebml_w: ebml::writer, name: ident, id: def_id) { @@ -188,12 +188,12 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt, vec::append_one(path, it.ident), index); } } - item_ty(_, tps, _) { + item_ty(_, tps) { do ebml_w.wr_tag(tag_paths_data_item) { encode_name_and_def_id(ebml_w, it.ident, it.id); } } - item_class(_, _, items, ctor, m_dtor, _) { + item_class(_, _, items, ctor, m_dtor) { do ebml_w.wr_tag(tag_paths_data_item) { encode_name_and_def_id(ebml_w, it.ident, it.id); } @@ -208,7 +208,7 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt, index); } } - item_enum(variants, _, _) { + item_enum(variants, _) { do ebml_w.wr_tag(tag_paths_data_item) { encode_name_and_def_id(ebml_w, it.ident, it.id); } @@ -406,7 +406,7 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod, ref, we need to map it to its parent class */ ebml_w.wr_str(def_to_str(local_def(it.id))); } - some(ast_map::node_item(@{node: item_impl(_,_, + some(ast_map::node_item(@{node: item_impl(_, some(ifce),_,_),_},_)) { ebml_w.wr_str(def_to_str(did)); } @@ -550,7 +550,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, let tcx = ecx.tcx; let must_write = - alt item.node { item_enum(_, _, _) { true } _ { false } }; + alt item.node { item_enum(_, _) { true } _ { false } }; if !must_write && !reachable(ecx, item.id) { ret; } fn add_to_index_(item: @item, ebml_w: ebml::writer, @@ -598,7 +598,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_path(ebml_w, path, ast_map::path_name(item.ident)); ebml_w.end_tag(); } - item_ty(_, tps, rp) { + item_ty(_, tps) { add_to_index(); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); @@ -607,10 +607,10 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_name(ebml_w, item.ident); encode_path(ebml_w, path, ast_map::path_name(item.ident)); - encode_region_param(ebml_w, rp); + encode_region_param(ecx, ebml_w, item); ebml_w.end_tag(); } - item_enum(variants, tps, rp) { + item_enum(variants, tps) { add_to_index(); do ebml_w.wr_tag(tag_items_data_item) { encode_def_id(ebml_w, local_def(item.id)); @@ -623,12 +623,12 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, } ecx.encode_inlined_item(ecx, ebml_w, path, ii_item(item)); encode_path(ebml_w, path, ast_map::path_name(item.ident)); - encode_region_param(ebml_w, rp); + encode_region_param(ecx, ebml_w, item); } encode_enum_variant_info(ecx, ebml_w, item.id, variants, path, index, tps); } - item_class(tps, traits, items, ctor, m_dtor, rp) { + item_class(tps, traits, items, ctor, m_dtor) { /* First, encode the fields and methods These come first because we need to write them to make the index, and the index needs to be in the item for the @@ -655,7 +655,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_name(ebml_w, item.ident); encode_path(ebml_w, path, ast_map::path_name(item.ident)); - encode_region_param(ebml_w, rp); + encode_region_param(ecx, ebml_w, item); for traits.each |t| { encode_trait_ref(ebml_w, ecx, t); } @@ -704,12 +704,12 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_index(ebml_w, bkts, write_int); ebml_w.end_tag(); } - item_impl(tps, rp, ifce, _, methods) { + item_impl(tps, ifce, _, methods) { add_to_index(); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); encode_family(ebml_w, 'i'); - encode_region_param(ebml_w, rp); + encode_region_param(ecx, ebml_w, item); encode_type_param_bounds(ebml_w, ecx, tps); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_name(ebml_w, item.ident); @@ -733,12 +733,12 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, vec::append(tps, m.tps)); } } - item_trait(tps, rp, ms) { + item_trait(tps, ms) { add_to_index(); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); encode_family(ebml_w, 'I'); - encode_region_param(ebml_w, rp); + encode_region_param(ecx, ebml_w, item); encode_type_param_bounds(ebml_w, ecx, tps); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_name(ebml_w, item.ident); @@ -801,7 +801,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer, encode_info_for_item(ecx, ebml_w, i, index, *pt); /* encode ctor, then encode items */ alt i.node { - item_class(tps, _, _, ctor, m_dtor, _) { + item_class(tps, _, _, ctor, m_dtor) { #debug("encoding info for ctor %s %d", *i.ident, ctor.node.id); vec::push(*index, diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs index 88bb9e63933..a4810e77b56 100644 --- a/src/rustc/middle/astencode.rs +++ b/src/rustc/middle/astencode.rs @@ -554,11 +554,11 @@ impl helpers for ebml::writer { do self.emit_rec { do self.emit_rec_field("bounds", 0u) { do self.emit_from_vec(*tpbt.bounds) |bs| { - self.emit_bounds(ecx, bs) + self.emit_bounds(ecx, bs); } } do self.emit_rec_field("rp", 1u) { - ast::serialize_region_param(self, tpbt.rp) + self.emit_bool(tpbt.rp); } do self.emit_rec_field("ty", 2u) { self.emit_ty(ecx, tpbt.ty); @@ -759,7 +759,7 @@ impl decoder for ebml::ebml_deserializer { @self.read_to_vec(|| self.read_bounds(xcx) ) }), rp: self.read_rec_field("rp", 1u, || { - ast::deserialize_region_param(self) + self.read_bool() }), ty: self.read_rec_field("ty", 2u, || { self.read_ty(xcx) diff --git a/src/rustc/middle/borrowck/gather_loans.rs b/src/rustc/middle/borrowck/gather_loans.rs index 6a4aa98db0a..ddbd78b631c 100644 --- a/src/rustc/middle/borrowck/gather_loans.rs +++ b/src/rustc/middle/borrowck/gather_loans.rs @@ -199,6 +199,12 @@ impl methods for gather_loan_ctxt { if req_mutbl == m_imm && cmt.mutbl != m_imm { self.bccx.loaned_paths_imm += 1; + + if self.tcx().sess.borrowck_note_loan() { + self.bccx.span_note( + cmt.span, + #fmt["immutable loan required"]); + } } else { self.bccx.loaned_paths_same += 1; } diff --git a/src/rustc/middle/check_const.rs b/src/rustc/middle/check_const.rs index 16c714ac057..54b10d5566d 100644 --- a/src/rustc/middle/check_const.rs +++ b/src/rustc/middle/check_const.rs @@ -24,7 +24,7 @@ fn check_item(sess: session, ast_map: ast_map::map, def_map: resolve::def_map, v.visit_expr(ex, true, v); check_item_recursion(sess, ast_map, def_map, it); } - item_enum(vs, _, _) { + item_enum(vs, _) { for vs.each |var| { do option::iter(var.node.disr_expr) |ex| { v.visit_expr(ex, true, v); diff --git a/src/rustc/middle/region.rs b/src/rustc/middle/region.rs index 15faf3d2b7c..ff8377fa374 100644 --- a/src/rustc/middle/region.rs +++ b/src/rustc/middle/region.rs @@ -138,11 +138,13 @@ import syntax::{ast, visit}; import syntax::codemap::span; import syntax::print::pprust; import syntax::ast_util::new_def_hash; +import syntax::ast_map; +import dvec::{dvec, extensions}; +import metadata::csearch; import std::list; import std::list::list; -import std::map; -import std::map::hashmap; +import std::map::{hashmap, int_hash}; type parent = option; @@ -386,7 +388,7 @@ fn resolve_crate(sess: session, def_map: resolve::def_map, crate: @ast::crate) -> region_map { let cx: ctxt = {sess: sess, def_map: def_map, - region_map: map::int_hash(), + region_map: int_hash(), parent: none}; let visitor = visit::mk_vt(@{ visit_block: resolve_block, @@ -402,3 +404,208 @@ fn resolve_crate(sess: session, def_map: resolve::def_map, crate: @ast::crate) ret cx.region_map; } +// ___________________________________________________________________________ +// Determining region parameterization +// +// Infers which type defns must be region parameterized---this is done +// by scanning their contents to see whether they reference a region +// type, directly or indirectly. This is a fixed-point computation. +// +// We do it in two passes. First we walk the AST and construct a map +// from each type defn T1 to other defns which make use of it. For example, +// if we have a type like: +// +// type S = *int; +// type T = S; +// +// Then there would be a map entry from S to T. During the same walk, +// we also construct add any types that reference regions to a set and +// a worklist. We can then process the worklist, propagating indirect +// dependencies until a fixed point is reached. + +type region_paramd_items = hashmap; +type dep_map = hashmap>; + +type determine_rp_ctxt = @{ + sess: session, + ast_map: ast_map::map, + def_map: resolve::def_map, + region_paramd_items: region_paramd_items, + dep_map: dep_map, + worklist: dvec, + + mut item_id: ast::node_id, + mut anon_implies_rp: bool +}; + +impl methods for determine_rp_ctxt { + fn add_rp(id: ast::node_id) { + assert id != 0; + if self.region_paramd_items.insert(id, ()) { + #debug["add region-parameterized item: %d (%s)", + id, ast_map::node_id_to_str(self.ast_map, id)]; + self.worklist.push(id); + } else { + #debug["item %d already region-parameterized", id]; + } + } + + fn add_dep(from: ast::node_id, to: ast::node_id) { + #debug["add dependency from %d -> %d (%s -> %s)", + from, to, + ast_map::node_id_to_str(self.ast_map, from), + ast_map::node_id_to_str(self.ast_map, to)]; + let vec = alt self.dep_map.find(from) { + some(vec) => {vec} + none => { + let vec = @dvec(); + self.dep_map.insert(from, vec); + vec + } + }; + if !vec.contains(to) { vec.push(to); } + } + + fn region_is_relevant(r: @ast::region) -> bool { + alt r.node { + ast::re_anon {self.anon_implies_rp} + ast::re_named(@"self") {true} + ast::re_named(_) {false} + } + } + + fn with(item_id: ast::node_id, anon_implies_rp: bool, f: fn()) { + let old_item_id = self.item_id; + let old_anon_implies_rp = self.anon_implies_rp; + self.item_id = item_id; + self.anon_implies_rp = anon_implies_rp; + #debug["with_item_id(%d, %b)", item_id, anon_implies_rp]; + let _i = util::common::indenter(); + f(); + self.item_id = old_item_id; + self.anon_implies_rp = old_anon_implies_rp; + } +} + +fn determine_rp_in_item(item: @ast::item, + &&cx: determine_rp_ctxt, + visitor: visit::vt) { + do cx.with(item.id, true) { + visit::visit_item(item, cx, visitor); + } +} + +fn determine_rp_in_fn(fk: visit::fn_kind, + decl: ast::fn_decl, + body: ast::blk, + sp: span, + id: ast::node_id, + &&cx: determine_rp_ctxt, + visitor: visit::vt) { + do cx.with(cx.item_id, false) { + visit::visit_fn(fk, decl, body, sp, id, cx, visitor); + } +} + +fn determine_rp_in_ty_method(ty_m: ast::ty_method, + &&cx: determine_rp_ctxt, + visitor: visit::vt) { + do cx.with(cx.item_id, false) { + visit::visit_ty_method(ty_m, cx, visitor); + } +} + +fn determine_rp_in_ty(ty: @ast::ty, + &&cx: determine_rp_ctxt, + visitor: visit::vt) { + + // we are only interesting in types that will require an item to + // be region-parameterized. if cx.item_id is zero, then this type + // is not a member of a type defn nor is it a constitutent of an + // impl etc. So we can ignore it and its components. + if cx.item_id == 0 { ret; } + + // if this type directly references a region, either via a + // region pointer like &r.ty or a region-parameterized path + // like path/r, add to the worklist/set + alt ty.node { + ast::ty_rptr(r, _) | + ast::ty_path(@{rp: some(r), _}, _) | + ast::ty_vstore(_, ast::vstore_slice(r)) => { + #debug["referenced type with regions %s", pprust::ty_to_str(ty)]; + if cx.region_is_relevant(r) { + cx.add_rp(cx.item_id); + } + } + + _ => {} + } + + // if this references another named type, add the dependency + // to the dep_map. If the type is not defined in this crate, + // then check whether it is region-parameterized and consider + // that as a direct dependency. + alt ty.node { + ast::ty_path(_, id) { + alt cx.def_map.get(id) { + ast::def_ty(did) | ast::def_class(did) { + if did.crate == ast::local_crate { + cx.add_dep(did.node, cx.item_id); + } else { + let cstore = cx.sess.cstore; + if csearch::get_region_param(cstore, did) { + #debug["reference to external, rp'd type %s", + pprust::ty_to_str(ty)]; + cx.add_rp(cx.item_id); + } + } + } + _ {} + } + } + _ {} + } + + visit::visit_ty(ty, cx, visitor); +} + +fn determine_rp_in_crate(sess: session, + ast_map: ast_map::map, + def_map: resolve::def_map, + crate: @ast::crate) -> region_paramd_items { + let cx = @{sess: sess, + ast_map: ast_map, + def_map: def_map, + region_paramd_items: int_hash(), + dep_map: int_hash(), + worklist: dvec(), + mut item_id: 0, + mut anon_implies_rp: false}; + + // gather up the base set, worklist and dep_map: + let visitor = visit::mk_vt(@{ + visit_fn: determine_rp_in_fn, + visit_item: determine_rp_in_item, + visit_ty: determine_rp_in_ty, + visit_ty_method: determine_rp_in_ty_method, + with *visit::default_visitor() + }); + visit::visit_crate(*crate, cx, visitor); + + // propagate indirect dependencies + while cx.worklist.len() != 0 { + let id = cx.worklist.pop(); + #debug["popped %d from worklist", id]; + alt cx.dep_map.find(id) { + none {} + some(vec) { + for vec.each |to_id| { + cx.add_rp(to_id); + } + } + } + } + + // return final set + ret cx.region_paramd_items; +} \ No newline at end of file diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs index c0e72da6ece..f2eea665522 100644 --- a/src/rustc/middle/resolve.rs +++ b/src/rustc/middle/resolve.rs @@ -439,10 +439,10 @@ fn resolve_names(e: @env, c: @ast::crate) { /* At this point, the code knows what traits the trait refs refer to, so it's possible to resolve them. */ - ast::item_impl(_, _, ifce, _, _) { + ast::item_impl(_, ifce, _, _) { ifce.iter(|p| resolve_trait_ref(p, sc, e)) } - ast::item_class(_, traits, _, _, _, _) { + ast::item_class(_, traits, _, _, _) { for traits.each |p| { resolve_trait_ref(p, sc, e); } @@ -552,7 +552,7 @@ fn visit_item_with_scope(e: @env, i: @ast::item, let sc = @cons(scope_item(i), sc); alt i.node { - ast::item_impl(tps, _, ifce, sty, methods) { + ast::item_impl(tps, ifce, sty, methods) { v.visit_ty_params(tps, sc, v); option::iter(ifce, |p| visit::visit_path(p.path, sc, v)); v.visit_ty(sty, sc, v); @@ -564,7 +564,7 @@ fn visit_item_with_scope(e: @env, i: @ast::item, m.decl, m.body, m.span, m.id, msc, v); } } - ast::item_trait(tps, _, methods) { + ast::item_trait(tps, methods) { v.visit_ty_params(tps, sc, v); let isc = @cons(scope_method(i.id, tps), sc); for methods.each |m| { @@ -574,7 +574,7 @@ fn visit_item_with_scope(e: @env, i: @ast::item, v.visit_ty(m.decl.output, msc, v); } } - ast::item_class(tps, traits, members, ctor, m_dtor, _) { + ast::item_class(tps, traits, members, ctor, m_dtor) { v.visit_ty_params(tps, sc, v); let class_scope = @cons(scope_item(i), sc); /* visit the constructor... */ @@ -1042,13 +1042,13 @@ fn lookup_in_scope(e: env, &&sc: scopes, sp: span, name: ident, ns: namespace, } scope_item(it) { alt it.node { - ast::item_impl(tps, _, _, _, _) { + ast::item_impl(tps, _, _, _) { if ns == ns_type { ret lookup_in_ty_params(e, name, tps); } } - ast::item_enum(_, tps, _) | ast::item_ty(_, tps, _) { + ast::item_enum(_, tps) | ast::item_ty(_, tps) { if ns == ns_type { ret lookup_in_ty_params(e, name, tps); } } - ast::item_trait(tps, _, _) { + ast::item_trait(tps, _) { if ns == ns_type { if *name == "self" { ret some(def_self(it.id)); @@ -1062,7 +1062,7 @@ fn lookup_in_scope(e: env, &&sc: scopes, sp: span, name: ident, ns: namespace, ast::item_foreign_mod(m) { ret lookup_in_local_foreign_mod(e, it.id, sp, name, ns); } - ast::item_class(tps, _, members, ctor, _, _) { + ast::item_class(tps, _, members, ctor, _) { if ns == ns_type { ret lookup_in_ty_params(e, name, tps); } @@ -1234,7 +1234,7 @@ fn lookup_in_block(e: env, name: ident, sp: span, b: ast::blk_, pos: uint, } ast::decl_item(it) { alt it.node { - ast::item_enum(variants, _, _) { + ast::item_enum(variants, _) { if ns == ns_type { if str::eq(*it.ident, *name) { ret some(ast::def_ty(local_def(it.id))); @@ -1339,7 +1339,7 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option { ast::item_ty(*) | item_trait(*) | item_enum(*) { if ns == ns_type { ret some(ast::def_ty(local_def(i.id))); } } - ast::item_class(_, _, _members, ct, _, _) { + ast::item_class(_, _, _members, ct, _) { alt ns { ns_type { ret some(ast::def_class(local_def(i.id))); @@ -1641,11 +1641,11 @@ fn index_mod(md: ast::_mod) -> mod_index { for md.items.each |it| { alt it.node { ast::item_const(_, _) | ast::item_fn(_, _, _) | ast::item_mod(_) | - ast::item_foreign_mod(_) | ast::item_ty(_, _, _) | + ast::item_foreign_mod(_) | ast::item_ty(_, _) | ast::item_impl(*) | ast::item_trait(*) { add_to_index(index, it.ident, mie_item(it)); } - ast::item_enum(variants, _, _) { + ast::item_enum(variants, _) { add_to_index(index, it.ident, mie_item(it)); let mut variant_idx: uint = 0u; for variants.each |v| { @@ -1655,7 +1655,7 @@ fn index_mod(md: ast::_mod) -> mod_index { variant_idx += 1u; } } - ast::item_class(tps, _, items, ctor, _, _) { + ast::item_class(tps, _, items, ctor, _) { // add the class name itself add_to_index(index, it.ident, mie_item(it)); } @@ -1780,15 +1780,15 @@ fn check_item(e: @env, i: @ast::item, &&x: (), v: vt<()>) { ensure_unique(*e, i.span, ty_params, |tp| tp.ident, "type parameter"); } - ast::item_enum(_, ty_params, _) { + ast::item_enum(_, ty_params) { ensure_unique(*e, i.span, ty_params, |tp| tp.ident, "type parameter"); } - ast::item_trait(_, _, methods) { + ast::item_trait(_, methods) { ensure_unique(*e, i.span, methods, |m| m.ident, "method"); } - ast::item_impl(_, _, _, _, methods) { + ast::item_impl(_, _, _, methods) { ensure_unique(*e, i.span, methods, |m| m.ident, "method"); } @@ -1854,7 +1854,7 @@ fn check_block(e: @env, b: ast::blk, &&x: (), v: vt<()>) { } ast::decl_item(it) { alt it.node { - ast::item_enum(variants, _, _) { + ast::item_enum(variants, _) { add_name(types, it.span, it.ident); for variants.each |v| { add_name(values, v.span, v.node.name); @@ -2051,7 +2051,7 @@ fn check_exports(e: @env) { some(ms) { let maybe_id = do list_search(ms) |m| { alt m { - mie_item(@{node: item_enum(_, _, _), id, _}) { some(id) } + mie_item(@{node: item_enum(_, _), id, _}) { some(id) } _ { none } } }; @@ -2242,7 +2242,7 @@ fn find_impls_in_item(e: env, i: @ast::item, &impls: ~[@_impl], name: option, ck_exports: option<@indexed_mod>) { alt i.node { - ast::item_impl(_, _, ifce, _, mthds) { + ast::item_impl(_, ifce, _, mthds) { if alt name { some(n) { n == i.ident } _ { true } } && alt ck_exports { some(m) { is_exported(e, i.ident, m) } @@ -2257,7 +2257,7 @@ fn find_impls_in_item(e: env, i: @ast::item, &impls: ~[@_impl], })}); } } - ast::item_class(tps, ifces, items, _, _, _) { + ast::item_class(tps, ifces, items, _, _) { let (_, mthds) = ast_util::split_class_items(items); let n_tps = tps.len(); do vec::iter(ifces) |p| { diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs index d3502fb9644..9c129dd673b 100644 --- a/src/rustc/middle/resolve3.rs +++ b/src/rustc/middle/resolve3.rs @@ -847,7 +847,7 @@ class Resolver { } // These items live in both the type and value namespaces. - item_enum(variants, _, _) { + item_enum(variants, _) { (*name_bindings).define_type(def_ty(local_def(item.id))); for variants.each |variant| { @@ -857,7 +857,7 @@ class Resolver { visitor); } } - item_class(_, _, class_members, ctor, _, _) { + item_class(_, _, class_members, ctor, _) { (*name_bindings).define_type(def_ty(local_def(item.id))); let purity = ctor.node.dec.purity; @@ -899,7 +899,7 @@ class Resolver { visit_item(item, new_parent, visitor); } - item_impl(_, _, _, _, methods) { + item_impl(_, _, _, methods) { // Create the set of implementation information that the // implementation scopes (ImplScopes) need and write it into // the implementation definition list for this set of name @@ -2884,8 +2884,8 @@ class Resolver { } alt item.node { - item_enum(_, type_parameters, _) | - item_ty(_, type_parameters, _) { + item_enum(_, type_parameters) | + item_ty(_, type_parameters) { do self.with_type_parameter_rib (HasTypeParameters(&type_parameters, item.id, 0u, NormalRibKind)) @@ -2895,7 +2895,7 @@ class Resolver { } } - item_impl(type_parameters, _, interface_reference, self_type, + item_impl(type_parameters, interface_reference, self_type, methods) { self.resolve_implementation(item.id, item.span, @@ -2906,7 +2906,7 @@ class Resolver { visitor); } - item_trait(type_parameters, _, methods) { + item_trait(type_parameters, methods) { // Create a new rib for the self type. let self_type_rib = @Rib(NormalRibKind); (*self.type_ribs).push(self_type_rib); @@ -2948,7 +2948,7 @@ class Resolver { } item_class(ty_params, interfaces, class_members, constructor, - optional_destructor, _) { + optional_destructor) { self.resolve_class(item.id, @copy ty_params, diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 045f175bea1..b96186126f5 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -2291,7 +2291,7 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id) ccx.external.insert(parent_id, some(item.id)); let mut my_id = 0; alt check item.node { - ast::item_enum(_, _, _) { + ast::item_enum(_, _) { let vs_here = ty::enum_variants(ccx.tcx, local_def(item.id)); let vs_there = ty::enum_variants(ccx.tcx, parent_id); do vec::iter2(*vs_here, *vs_there) |here, there| { @@ -4886,13 +4886,13 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) { } } } - ast::item_impl(tps, _rp, _, _, ms) { + ast::item_impl(tps, _, _, ms) { impl::trans_impl(ccx, *path, item.ident, ms, tps); } ast::item_mod(m) { trans_mod(ccx, m); } - ast::item_enum(variants, tps, _) { + ast::item_enum(variants, tps) { if tps.len() == 0u { let degen = variants.len() == 1u; let vi = ty::enum_variants(ccx.tcx, local_def(item.id)); @@ -4916,7 +4916,7 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) { }; foreign::trans_foreign_mod(ccx, foreign_mod, abi); } - ast::item_class(tps, _traits, items, ctor, m_dtor, _) { + ast::item_class(tps, _traits, items, ctor, m_dtor) { if tps.len() == 0u { let psubsts = {tys: ty::ty_params_to_tys(ccx.tcx, tps), vtables: none, @@ -5199,7 +5199,7 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef { ~[path_name(enm.ident), path_name(v.node.name)]); let llfn = alt check enm.node { - ast::item_enum(_, _, _) { + ast::item_enum(_, _) { register_fn(ccx, v.span, pth, id) } }; @@ -5220,7 +5220,7 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef { fn trans_constant(ccx: @crate_ctxt, it: @ast::item) { let _icx = ccx.insn_ctxt("trans_constant"); alt it.node { - ast::item_enum(variants, _, _) { + ast::item_enum(variants, _) { let vi = ty::enum_variants(ccx.tcx, {crate: ast::local_crate, node: it.id}); let mut i = 0; diff --git a/src/rustc/middle/trans/impl.rs b/src/rustc/middle/trans/impl.rs index b95864f5132..2ebddb0038f 100644 --- a/src/rustc/middle/trans/impl.rs +++ b/src/rustc/middle/trans/impl.rs @@ -84,11 +84,11 @@ fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id, name: ast::ident) -> ast::def_id { if impl_id.crate == ast::local_crate { alt check ccx.tcx.items.get(impl_id.node) { - ast_map::node_item(@{node: ast::item_impl(_, _, _, _, ms), _}, _) { + ast_map::node_item(@{node: ast::item_impl(_, _, _, ms), _}, _) { method_from_methods(ms, name) } ast_map::node_item(@{node: - ast::item_class(_, _, items, _, _, _), _}, _) { + ast::item_class(_, _, items, _, _), _}, _) { let (_,ms) = split_class_items(items); method_from_methods(ms, name) } diff --git a/src/rustc/middle/trans/reachable.rs b/src/rustc/middle/trans/reachable.rs index f9b031f1a51..51dc20d1c87 100644 --- a/src/rustc/middle/trans/reachable.rs +++ b/src/rustc/middle/trans/reachable.rs @@ -112,7 +112,7 @@ fn traverse_public_item(cx: ctx, item: @item) { traverse_inline_body(cx, blk); } } - item_impl(tps, _, _, _, ms) { + item_impl(tps, _, _, ms) { for vec::each(ms) |m| { if tps.len() > 0u || m.tps.len() > 0u || attr::find_inline_attr(m.attrs) != attr::ia_none { @@ -121,7 +121,7 @@ fn traverse_public_item(cx: ctx, item: @item) { } } } - item_class(tps, _traits, items, ctor, m_dtor, _) { + item_class(tps, _traits, items, ctor, m_dtor) { cx.rmap.insert(ctor.node.id, ()); do option::iter(m_dtor) |dtor| { cx.rmap.insert(dtor.node.id, ()); @@ -143,7 +143,7 @@ fn traverse_public_item(cx: ctx, item: @item) { } } } - item_ty(t, _, _) { + item_ty(t, _) { traverse_ty(t, cx, mk_ty_visitor()); } item_const(*) | @@ -218,7 +218,7 @@ fn traverse_all_resources(cx: ctx, crate_mod: _mod) { visit_item: |i, cx, v| { visit::visit_item(i, cx, v); alt i.node { - item_class(_, _, _, _, some(_), _) { + item_class(_, _, _, _, some(_)) { traverse_public_item(cx, i); } _ {} diff --git a/src/rustc/middle/tstate/pre_post_conditions.rs b/src/rustc/middle/tstate/pre_post_conditions.rs index c2c8810ec1b..fe502e18476 100644 --- a/src/rustc/middle/tstate/pre_post_conditions.rs +++ b/src/rustc/middle/tstate/pre_post_conditions.rs @@ -52,7 +52,7 @@ fn find_pre_post_item(ccx: crate_ctxt, i: item) { item_class(*) { fail "find_pre_post_item: shouldn't be called on item_class"; } - item_impl(_, _, _, _, ms) { + item_impl(_, _, _, ms) { for ms.each |m| { find_pre_post_method(ccx, m); } } item_mac(*) { fail "item macros unimplemented" } diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index f4febfa0512..8aebe510966 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -233,7 +233,9 @@ type ctxt = cstore: metadata::cstore::cstore, sess: session::session, def_map: resolve::def_map, + region_map: middle::region::region_map, + region_paramd_items: middle::region::region_paramd_items, // Stores the types for various nodes in the AST. Note that this table // is not guaranteed to be populated until after typeck. See @@ -482,7 +484,7 @@ fn param_bounds_to_kind(bounds: param_bounds) -> kind { } type ty_param_bounds_and_ty = {bounds: @~[param_bounds], - rp: ast::region_param, + rp: bool, ty: t}; type type_cache = hashmap; @@ -505,9 +507,12 @@ fn new_ty_hash() -> map::hashmap { |&&a: t, &&b: t| type_id(a) == type_id(b)) } -fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map, +fn mk_ctxt(s: session::session, + dm: resolve::def_map, + amap: ast_map::map, freevars: freevars::freevar_map, - region_map: middle::region::region_map) -> ctxt { + region_map: middle::region::region_map, + region_paramd_items: middle::region::region_paramd_items) -> ctxt { let interner = map::hashmap(|&&k: intern_key| { hash_type_structure(k.struct) + option::map_default(k.o_def_id, 0u, ast_util::hash_def) @@ -523,6 +528,7 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map, sess: s, def_map: dm, region_map: region_map, + region_paramd_items: region_paramd_items, node_types: @smallintmap::mk(), node_type_substs: map::int_hash(), items: amap, @@ -2543,10 +2549,10 @@ fn impl_trait(cx: ctxt, id: ast::def_id) -> option { #debug("(impl_trait) searching for trait impl %?", id); alt cx.items.find(id.node) { some(ast_map::node_item(@{node: ast::item_impl( - _, _, some(@{id: id, _}), _, _), _}, _)) { + _, some(@{id: id, _}), _, _), _}, _)) { some(node_id_to_type(cx, id)) } - some(ast_map::node_item(@{node: ast::item_class(_, _, _, _, _, _), + some(ast_map::node_item(@{node: ast::item_class(*), _},_)) { alt cx.def_map.find(id.node) { some(def_ty(trait_id)) { @@ -2606,7 +2612,7 @@ fn ty_dtor(cx: ctxt, class_id: def_id) -> option { if is_local(class_id) { alt cx.items.find(class_id.node) { some(ast_map::node_item(@{node: ast::item_class(_, _, _, _, - some(dtor), _), _}, _)) + some(dtor)), _}, _)) { some(local_def(dtor.node.id)) } _ { none } } @@ -2687,7 +2693,7 @@ fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[variant_info] { expr, since check_enum_variants also updates the enum_var_cache */ alt cx.items.get(id.node) { - ast_map::node_item(@{node: ast::item_enum(variants, _, _), _}, _) { + ast_map::node_item(@{node: ast::item_enum(variants, _), _}, _) { let mut disr_val = -1; @vec::map(variants, |variant| { let ctor_ty = node_id_to_type(cx, variant.node.id); @@ -2780,7 +2786,7 @@ fn lookup_class_fields(cx: ctxt, did: ast::def_id) -> ~[field_ty] { alt cx.items.find(did.node) { some(ast_map::node_item(i,_)) { alt i.node { - ast::item_class(_, _, items, _, _, _) { + ast::item_class(_, _, items, _, _) { class_field_tys(items) } _ { cx.sess.bug("class ID bound to non-class"); } @@ -2822,7 +2828,7 @@ pure fn is_public(f: field_ty) -> bool { fn lookup_class_method_ids(cx: ctxt, did: ast::def_id) : is_local(did) -> ~[{name: ident, id: node_id, vis: visibility}] { alt cx.items.find(did.node) { - some(ast_map::node_item(@{node: item_class(_,_,items,_,_,_), _}, _)) { + some(ast_map::node_item(@{node: item_class(_,_,items,_,_), _}, _)) { let (_,ms) = split_class_items(items); vec::map(ms, |m| {name: m.ident, id: m.id, vis: m.vis}) diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index 6281aaed1ab..2f3fcb498be 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -185,7 +185,7 @@ fn lookup_def_ccx(ccx: @crate_ctxt, sp: span, id: ast::node_id) -> ast::def { } fn no_params(t: ty::t) -> ty::ty_param_bounds_and_ty { - {bounds: @~[], rp: ast::rp_none, ty: t} + {bounds: @~[], rp: false, ty: t} } fn require_same_types( diff --git a/src/rustc/middle/typeck/astconv.rs b/src/rustc/middle/typeck/astconv.rs index b171f9fc041..fe9a8b4aadf 100644 --- a/src/rustc/middle/typeck/astconv.rs +++ b/src/rustc/middle/typeck/astconv.rs @@ -87,14 +87,17 @@ fn ast_path_to_substs_and_ty( let {bounds: decl_bounds, rp: decl_rp, ty: decl_ty} = self.get_item_ty(did); + #debug["ast_path_to_substs_and_ty: did=%? decl_rp=%b", + did, decl_rp]; + // If the type is parameterized by the self region, then replace self // region with the current anon region binding (in other words, // whatever & would get replaced with). let self_r = alt (decl_rp, path.rp) { - (ast::rp_none, none) { + (false, none) { none } - (ast::rp_none, some(_)) { + (false, some(_)) { tcx.sess.span_err( path.span, #fmt["no region bound is permitted on %s, \ @@ -102,12 +105,12 @@ fn ast_path_to_substs_and_ty( ty::item_path_str(tcx, did)]); none } - (ast::rp_self, none) { + (true, none) { let res = rscope.anon_region(); let r = get_region_reporting_err(self.tcx(), path.span, res); some(r) } - (ast::rp_self, some(r)) { + (true, some(r)) { some(ast_region_to_region(self, rscope, path.span, r)) } }; diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index bd9230613d3..74aaca06a7c 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -66,7 +66,7 @@ type parameter). */ -import astconv::{ast_conv, ast_ty_to_ty}; +import astconv::{ast_conv, ast_ty_to_ty, ast_region_to_region}; import collect::{methods}; // ccx.to_ty() import middle::ty::{tv_vid, vid}; import regionmanip::{replace_bound_regions_in_fn_ty, region_of}; @@ -348,17 +348,20 @@ fn check_class_member(ccx: @crate_ctxt, class_t: ty::t, fn check_item(ccx: @crate_ctxt, it: @ast::item) { alt it.node { ast::item_const(_, e) { check_const(ccx, it.span, e, it.id); } - ast::item_enum(vs, _, _) { + ast::item_enum(vs, _) { check_enum_variants(ccx, it.span, vs, it.id); } ast::item_fn(decl, tps, body) { check_bare_fn(ccx, decl, body, it.id, none); } - ast::item_impl(tps, rp, _, ty, ms) { + ast::item_impl(tps, _, ty, ms) { + let rp = ccx.tcx.region_paramd_items.contains_key(it.id); + #debug["item_impl %s with id %d rp %b", + *it.ident, it.id, rp]; let self_ty = ccx.to_ty(rscope::type_rscope(rp), ty); for ms.each |m| { check_method(ccx, m, self_ty);} } - ast::item_class(tps, traits, members, ctor, m_dtor, rp) { + ast::item_class(tps, traits, members, ctor, m_dtor) { let tcx = ccx.tcx; let class_t = ty::node_id_to_type(tcx, it.id); // typecheck the ctor @@ -387,9 +390,9 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) { // Check that the class is instantiable check_instantiable(ccx.tcx, it.span, it.id); } - ast::item_ty(t, tps, rp) { + ast::item_ty(t, tps) { let tpt_ty = ty::node_id_to_type(ccx.tcx, it.id); - check_bounds_are_used(ccx, t.span, tps, rp, tpt_ty); + check_bounds_are_used(ccx, t.span, tps, tpt_ty); } ast::item_foreign_mod(m) { if syntax::attr::foreign_abi(it.attrs) == @@ -647,15 +650,16 @@ fn impl_self_ty(fcx: @fn_ctxt, did: ast::def_id) -> ty_param_substs_and_ty { let tcx = fcx.ccx.tcx; let {n_tps, rp, raw_ty} = if did.crate == ast::local_crate { + let rp = fcx.tcx().region_paramd_items.contains_key(did.node); alt check tcx.items.find(did.node) { - some(ast_map::node_item(@{node: ast::item_impl(ts, rp, _, st, _), + some(ast_map::node_item(@{node: ast::item_impl(ts, _, st, _), _}, _)) { {n_tps: ts.len(), rp: rp, raw_ty: fcx.ccx.to_ty(rscope::type_rscope(rp), st)} } some(ast_map::node_item(@{node: ast::item_class(ts, - _,_,_,_,rp), id: class_id, _},_)) { + _,_,_,_), id: class_id, _},_)) { /* If the impl is a class, the self ty is just the class ty (doing a no-op subst for the ty params; in the next step, we substitute in fresh vars for them) @@ -663,9 +667,8 @@ fn impl_self_ty(fcx: @fn_ctxt, did: ast::def_id) -> ty_param_substs_and_ty { {n_tps: ts.len(), rp: rp, raw_ty: ty::mk_class(tcx, local_def(class_id), - {self_r: alt rp { - ast::rp_self { some(fcx.infcx.next_region_var()) } - ast::rp_none { none }}, + {self_r: if rp {some(ty::re_bound(ty::br_self))} + else {none}, self_ty: none, tps: ty::ty_params_to_tys(tcx, ts)})} } @@ -679,10 +682,7 @@ fn impl_self_ty(fcx: @fn_ctxt, did: ast::def_id) -> ty_param_substs_and_ty { raw_ty: ity.ty} }; - let self_r = alt rp { - ast::rp_none { none } - ast::rp_self { some(fcx.infcx.next_region_var()) } - }; + let self_r = if rp {some(fcx.infcx.next_region_var())} else {none}; let tps = fcx.infcx.next_ty_vars(n_tps); let substs = {self_r: self_r, self_ty: none, tps: tps}; @@ -2053,7 +2053,7 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) -> // extern functions are just u8 pointers ret { bounds: @~[], - rp: ast::rp_none, + rp: false, ty: ty::mk_ptr( fcx.ccx.tcx, { @@ -2109,13 +2109,27 @@ fn instantiate_path(fcx: @fn_ctxt, let ty_param_count = vec::len(*tpt.bounds); let ty_substs_len = vec::len(pth.types); - // For now, there is no way to explicitly specify the region bound. - // This will have to change eventually. - let self_r = alt tpt.rp { - ast::rp_self { some(fcx.infcx.next_region_var()) } - ast::rp_none { none } + // determine the region bound, using the value given by the user + // (if any) and otherwise using a fresh region variable + let self_r = alt pth.rp { + some(r) if !tpt.rp => { + fcx.ccx.tcx.sess.span_err + (sp, "this item is not region-parameterized"); + none + } + some(r) => { + some(ast_region_to_region(fcx, fcx, sp, r)) + } + none if tpt.rp => { + some(fcx.infcx.next_region_var()) + } + none => { + none + } }; + // determine values for type parameters, using the values given by + // the user (if any) and otherwise using fresh type variables let tps = if ty_substs_len == 0u { fcx.infcx.next_ty_vars(ty_param_count) } else if ty_param_count == 0u { @@ -2203,24 +2217,14 @@ fn ast_expr_vstore_to_vstore(fcx: @fn_ctxt, e: @ast::expr, n: uint, fn check_bounds_are_used(ccx: @crate_ctxt, span: span, tps: ~[ast::ty_param], - rp: ast::region_param, ty: ty::t) { - let mut r_used = alt rp { - ast::rp_self { false } - ast::rp_none { true } - }; - - if tps.len() == 0u && r_used { ret; } + // make a vector of booleans initially false, set to true when used + if tps.len() == 0u { ret; } let tps_used = vec::to_mut(vec::from_elem(tps.len(), false)); ty::walk_regions_and_ty( ccx.tcx, ty, - |r| { - alt r { - ty::re_bound(_) { r_used = true; } - _ { } - } - }, + |_r| {}, |t| { alt ty::get(t).struct { ty::ty_param(idx, _) { tps_used[idx] = true; } @@ -2229,12 +2233,6 @@ fn check_bounds_are_used(ccx: @crate_ctxt, true }); - if !r_used { - ccx.tcx.sess.span_err( - span, "lifetime `self` unused inside \ - reference-parameterized type"); - } - for tps_used.eachi |i, b| { if !b { ccx.tcx.sess.span_err( diff --git a/src/rustc/middle/typeck/coherence.rs b/src/rustc/middle/typeck/coherence.rs index 07929d50ce1..ad121772bd7 100644 --- a/src/rustc/middle/typeck/coherence.rs +++ b/src/rustc/middle/typeck/coherence.rs @@ -15,7 +15,7 @@ import middle::typeck::infer::{infer_ctxt, mk_subty, new_infer_ctxt}; import syntax::ast::{crate, def_id, item, item_class, item_const, item_enum}; import syntax::ast::{item_fn, item_foreign_mod, item_impl, item_mac}; import syntax::ast::{item_mod, item_trait, item_ty, local_crate, method}; -import syntax::ast::{node_id, region_param, rp_none, rp_self, trait_ref}; +import syntax::ast::{node_id, trait_ref}; import syntax::ast_util::{def_id_of_def, new_def_hash}; import syntax::visit::{default_simple_visitor, default_visitor}; import syntax::visit::{mk_simple_visitor, mk_vt, visit_crate, visit_item}; @@ -76,7 +76,7 @@ class CoherenceChecker { visit_crate(*crate, (), mk_simple_visitor(@{ visit_item: |item| { alt item.node { - item_impl(_, _, associated_trait, self_type, _) { + item_impl(_, associated_trait, self_type, _) { self.check_implementation(item, associated_trait); } _ { @@ -239,15 +239,9 @@ class CoherenceChecker { // Converts a polytype to a monotype by replacing all parameters with // type variables. fn universally_quantify_polytype(polytype: ty_param_bounds_and_ty) -> t { - let self_region; - alt polytype.rp { - rp_none { - self_region = none; - } - rp_self { - self_region = some(self.inference_context.next_region_var()) - } - }; + let self_region = + if polytype.rp {none} + else {some(self.inference_context.next_region_var())}; let bounds_count = polytype.bounds.len(); let type_parameters = @@ -304,7 +298,7 @@ class CoherenceChecker { self.privileged_types.remove(privileged_type); } } - item_impl(_, _, optional_trait_ref, _, _) { + item_impl(_, optional_trait_ref, _, _) { alt self.base_type_def_ids.find(item.id) { none { // Nothing to do. diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs index b1d0f026957..fa5ffc61bae 100644 --- a/src/rustc/middle/typeck/collect.rs +++ b/src/rustc/middle/typeck/collect.rs @@ -39,13 +39,13 @@ fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) { alt intrinsic_item.node { - ast::item_trait(_, _, _) { + ast::item_trait(_, _) { let ty = ty::mk_trait(ccx.tcx, def_id, substs); ccx.tcx.intrinsic_defs.insert (intrinsic_item.ident, (def_id, ty)); } - ast::item_enum(_, _, _) { + ast::item_enum(_, _) { let ty = ty::mk_enum(ccx.tcx, def_id, substs); ccx.tcx.intrinsic_defs.insert (intrinsic_item.ident, (def_id, ty)); @@ -107,7 +107,7 @@ fn get_enum_variant_types(ccx: @crate_ctxt, enum_ty: ty::t, variants: ~[ast::variant], ty_params: ~[ast::ty_param], - rp: ast::region_param) { + rp: bool) { let tcx = ccx.tcx; // Create a set of parameter types shared among all the variants. @@ -144,13 +144,14 @@ fn ensure_trait_methods(ccx: @crate_ctxt, id: ast::node_id) { } let tcx = ccx.tcx; + let rp = tcx.region_paramd_items.contains_key(id); alt check tcx.items.get(id) { - ast_map::node_item(@{node: ast::item_trait(_, rp, ms), _}, _) { + ast_map::node_item(@{node: ast::item_trait(_, ms), _}, _) { store_methods::(ccx, id, ms, |m| { ty_of_ty_method(ccx, m, rp) }); } - ast_map::node_item(@{node: ast::item_class(_,_,its,_,_,rp), _}, _) { + ast_map::node_item(@{node: ast::item_class(_,_,its,_,_), _}, _) { let (_,ms) = split_class_items(its); // All methods need to be stored, since lookup_method // relies on the same method cache for self-calls @@ -234,7 +235,7 @@ fn compare_impl_method(tcx: ty::ctxt, sp: span, fn check_methods_against_trait(ccx: @crate_ctxt, tps: ~[ast::ty_param], - rp: ast::region_param, + rp: bool, selfty: ty::t, a_trait_ty: @ast::trait_ref, ms: ~[converted_method]) { @@ -267,7 +268,7 @@ fn check_methods_against_trait(ccx: @crate_ctxt, } // fn fn convert_class_item(ccx: @crate_ctxt, - rp: ast::region_param, + rp: bool, bounds: @~[ty::param_bounds], v: ast_util::ivar) { let tt = ccx.to_ty(type_rscope(rp), v.ty); @@ -280,7 +281,7 @@ type converted_method = {mty: ty::method, id: ast::node_id, span: span}; fn convert_methods(ccx: @crate_ctxt, ms: ~[@ast::method], - rp: ast::region_param, + rp: bool, rcvr_bounds: @~[ty::param_bounds], self_ty: ty::t) -> ~[converted_method] { @@ -303,16 +304,17 @@ fn convert_methods(ccx: @crate_ctxt, fn convert(ccx: @crate_ctxt, it: @ast::item) { let tcx = ccx.tcx; + let rp = tcx.region_paramd_items.contains_key(it.id); + #debug["convert: item %s with id %d rp %b", *it.ident, it.id, rp]; alt it.node { // These don't define types. ast::item_foreign_mod(_) | ast::item_mod(_) {} - ast::item_enum(variants, ty_params, rp) { + ast::item_enum(variants, ty_params) { let tpt = ty_of_item(ccx, it); write_ty_to_tcx(tcx, it.id, tpt.ty); - get_enum_variant_types(ccx, tpt.ty, variants, - ty_params, rp); + get_enum_variant_types(ccx, tpt.ty, variants, ty_params, rp); } - ast::item_impl(tps, rp, ifce, selfty, ms) { + ast::item_impl(tps, ifce, selfty, ms) { let i_bounds = ty_param_bounds(ccx, tps); let selfty = ccx.to_ty(type_rscope(rp), selfty); write_ty_to_tcx(tcx, it.id, selfty); @@ -333,7 +335,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) { write_ty_to_tcx(tcx, it.id, tpt.ty); ensure_trait_methods(ccx, it.id); } - ast::item_class(tps, traits, members, ctor, m_dtor, rp) { + ast::item_class(tps, traits, members, ctor, m_dtor) { // Write the class type let tpt = ty_of_item(ccx, it); write_ty_to_tcx(tcx, it.id, tpt.ty); @@ -341,20 +343,19 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) { // Write the ctor type let t_args = ctor.node.dec.inputs.map( |a| ty_of_arg(ccx, type_rscope(rp), a, none) ); - let t_res = ty::mk_class(tcx, local_def(it.id), - {self_r: alt rp { - ast::rp_none { none } - ast::rp_self { some(ty::re_bound(ty::br_self)) } - }, - self_ty: none, - tps: ty::ty_params_to_tys(tcx, tps)}); - let t_ctor = ty::mk_fn(tcx, {purity: ast::impure_fn, - proto: ast::proto_any, - inputs: t_args, - output: t_res, - ret_style: ast::return_val, - constraints: ~[]}); // FIXME (#2813): allow ctors to have - // constraints, or remove constraints from the language + let t_res = ty::mk_class( + tcx, local_def(it.id), + {self_r: if rp {some(ty::re_bound(ty::br_self))} else {none}, + self_ty: none, + tps: ty::ty_params_to_tys(tcx, tps)}); + let t_ctor = ty::mk_fn( + tcx, {purity: ast::impure_fn, + proto: ast::proto_any, + inputs: t_args, + output: t_res, + ret_style: ast::return_val, + constraints: ~[]}); // FIXME (#2813): allow ctors to have + // constraints, or remove constraints from the language write_ty_to_tcx(tcx, ctor.node.id, t_ctor); tcx.tcache.insert(local_def(ctor.node.id), {bounds: tpt.bounds, @@ -421,18 +422,18 @@ fn convert_foreign(ccx: @crate_ctxt, i: @ast::foreign_item) { fn ty_of_method(ccx: @crate_ctxt, m: @ast::method, - rp: ast::region_param) -> ty::method { + rp: bool) -> ty::method { {ident: m.ident, tps: ty_param_bounds(ccx, m.tps), fty: ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_bare, - m.decl, none), + m.decl, none), purity: m.decl.purity, vis: m.vis} } fn ty_of_ty_method(self: @crate_ctxt, m: ast::ty_method, - rp: ast::region_param) -> ty::method { + rp: bool) -> ty::method { {ident: m.ident, tps: ty_param_bounds(self, m.tps), fty: ty_of_fn_decl(self, type_rscope(rp), ast::proto_bare, @@ -446,8 +447,7 @@ fn ty_of_ty_method(self: @crate_ctxt, it's bound to a valid trait type. Returns the def_id for the defining trait. Fails if the type is a type other than an trait type. */ -fn instantiate_trait_ref(ccx: @crate_ctxt, t: @ast::trait_ref, - rp: ast::region_param) +fn instantiate_trait_ref(ccx: @crate_ctxt, t: @ast::trait_ref, rp: bool) -> (ast::def_id, ty_param_substs_and_ty) { let sp = t.path.span, err = "can only implement interface types", @@ -480,6 +480,7 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item) some(tpt) { ret tpt; } _ {} } + let rp = tcx.region_paramd_items.contains_key(it.id); alt it.node { ast::item_const(t, _) { let typ = ccx.to_ty(empty_rscope, t); @@ -492,19 +493,20 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item) let tofd = ty_of_fn_decl(ccx, empty_rscope, ast::proto_bare, decl, none); let tpt = {bounds: bounds, - rp: ast::rp_none, // functions do not have a self + rp: false, // functions do not have a self ty: ty::mk_fn(ccx.tcx, tofd)}; #debug["type of %s (id %d) is %s", *it.ident, it.id, ty_to_str(tcx, tpt.ty)]; ccx.tcx.tcache.insert(local_def(it.id), tpt); ret tpt; } - ast::item_ty(t, tps, rp) { + ast::item_ty(t, tps) { alt tcx.tcache.find(local_def(it.id)) { some(tpt) { ret tpt; } none { } } + let rp = tcx.region_paramd_items.contains_key(it.id); let tpt = { let ty = { let t0 = ccx.to_ty(type_rscope(rp), t); @@ -522,7 +524,7 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item) tcx.tcache.insert(local_def(it.id), tpt); ret tpt; } - ast::item_enum(_, tps, rp) { + ast::item_enum(_, tps) { // Create a new generic polytype. let {bounds, substs} = mk_substs(ccx, tps, rp); let t = ty::mk_enum(tcx, local_def(it.id), substs); @@ -530,14 +532,14 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item) tcx.tcache.insert(local_def(it.id), tpt); ret tpt; } - ast::item_trait(tps, rp, ms) { + 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 tpt = {bounds: bounds, rp: rp, ty: t}; tcx.tcache.insert(local_def(it.id), tpt); ret tpt; } - ast::item_class(tps, _, _, _, _, rp) { + ast::item_class(tps, _, _, _, _) { let {bounds,substs} = mk_substs(ccx, tps, rp); let t = ty::mk_class(tcx, local_def(it.id), substs); let tpt = {bounds: bounds, rp: rp, ty: t}; @@ -555,7 +557,7 @@ fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item) alt it.node { ast::foreign_item_fn(fn_decl, params) { ret ty_of_foreign_fn_decl(ccx, fn_decl, params, - local_def(it.id)); + local_def(it.id)); } } } @@ -615,7 +617,7 @@ fn ty_of_foreign_fn_decl(ccx: @crate_ctxt, output: output_ty, ret_style: ast::return_val, constraints: ~[]}); - let tpt = {bounds: bounds, rp: ast::rp_none, ty: t_fn}; + let tpt = {bounds: bounds, rp: false, ty: t_fn}; ccx.tcx.tcache.insert(def_id, tpt); ret tpt; } @@ -633,13 +635,10 @@ fn mk_ty_params(ccx: @crate_ctxt, atps: ~[ast::ty_param]) })} } -fn mk_substs(ccx: @crate_ctxt, atps: ~[ast::ty_param], rp: ast::region_param) +fn mk_substs(ccx: @crate_ctxt, atps: ~[ast::ty_param], rp: bool) -> {bounds: @~[ty::param_bounds], substs: ty::substs} { let {bounds, params} = mk_ty_params(ccx, atps); - let self_r = alt rp { - ast::rp_self { some(ty::re_bound(ty::br_self)) } - ast::rp_none { none } - }; + let self_r = if rp {some(ty::re_bound(ty::br_self))} else {none}; {bounds: bounds, substs: {self_r: self_r, self_ty: none, tps: params}} } diff --git a/src/rustc/middle/typeck/rscope.rs b/src/rustc/middle/typeck/rscope.rs index f9f467a90fa..ec0dbe7ea8e 100644 --- a/src/rustc/middle/typeck/rscope.rs +++ b/src/rustc/middle/typeck/rscope.rs @@ -16,15 +16,14 @@ impl of region_scope for empty_rscope { } } -enum type_rscope = ast::region_param; +enum type_rscope = bool; impl of region_scope for type_rscope { fn anon_region() -> result { - alt *self { - ast::rp_self { result::ok(ty::re_bound(ty::br_self)) } - ast::rp_none { + if *self { + result::ok(ty::re_bound(ty::br_self)) + } else { result::err("to use region types here, the containing type \ must be declared with a region bound") - } } } fn named_region(id: ast::ident) -> result { diff --git a/src/rustdoc/attr_pass.rs b/src/rustdoc/attr_pass.rs index 00124bcc2a4..cf2077bfb5e 100644 --- a/src/rustdoc/attr_pass.rs +++ b/src/rustdoc/attr_pass.rs @@ -147,7 +147,7 @@ fn fold_enum( let desc = do astsrv::exec(srv) |ctxt| { alt check ctxt.ast_map.get(doc_id) { ast_map::node_item(@{ - node: ast::item_enum(ast_variants, _, _), _ + node: ast::item_enum(ast_variants, _), _ }, _) { let ast_variant = option::get( vec::find(ast_variants, |v| { @@ -204,14 +204,14 @@ fn merge_method_attrs( let attrs: ~[(str, option)] = do astsrv::exec(srv) |ctxt| { alt ctxt.ast_map.get(item_id) { ast_map::node_item(@{ - node: ast::item_trait(_, _, methods), _ + node: ast::item_trait(_, methods), _ }, _) { par::seqmap(methods, |method| { (*method.ident, attr_parser::parse_desc(method.attrs)) }) } ast_map::node_item(@{ - node: ast::item_impl(_, _, _, _, methods), _ + node: ast::item_impl(_, _, _, methods), _ }, _) { par::seqmap(methods, |method| { (*method.ident, attr_parser::parse_desc(method.attrs)) diff --git a/src/rustdoc/extract.rs b/src/rustdoc/extract.rs index 60402288ecf..955c0976c23 100644 --- a/src/rustdoc/extract.rs +++ b/src/rustdoc/extract.rs @@ -78,22 +78,22 @@ fn moddoc_from_mod( constdoc_from_const(itemdoc) )) } - ast::item_enum(variants, _, _) { + ast::item_enum(variants, _) { some(doc::enumtag( enumdoc_from_enum(itemdoc, variants) )) } - ast::item_trait(_, _, methods) { + ast::item_trait(_, methods) { some(doc::traittag( traitdoc_from_trait(itemdoc, methods) )) } - ast::item_impl(_, _, _, _, methods) { + ast::item_impl(_, _, _, methods) { some(doc::impltag( impldoc_from_impl(itemdoc, methods) )) } - ast::item_ty(_, _, _) { + ast::item_ty(_, _) { some(doc::tytag( tydoc_from_ty(itemdoc) )) diff --git a/src/rustdoc/reexport_pass.rs b/src/rustdoc/reexport_pass.rs index 8351d6a3146..6a5d2b326b9 100644 --- a/src/rustdoc/reexport_pass.rs +++ b/src/rustdoc/reexport_pass.rs @@ -291,7 +291,7 @@ fn all_impls(m: ast::_mod) -> map::set { let all_impls = ast_util::new_def_hash(); for m.items.each |item| { alt item.node { - ast::item_impl(_, _, _, _, _) { + ast::item_impl(_, _, _, _) { all_impls.insert(ast_util::local_def(item.id), ()); } _ { } diff --git a/src/rustdoc/tystr_pass.rs b/src/rustdoc/tystr_pass.rs index cd4683a4356..ba5abf9f66d 100644 --- a/src/rustdoc/tystr_pass.rs +++ b/src/rustdoc/tystr_pass.rs @@ -110,7 +110,7 @@ fn fold_enum( let sig = do astsrv::exec(srv) |ctxt| { alt check ctxt.ast_map.get(doc_id) { ast_map::node_item(@{ - node: ast::item_enum(ast_variants, _, _), _ + node: ast::item_enum(ast_variants, _), _ }, _) { let ast_variant = option::get( do vec::find(ast_variants) |v| { @@ -168,7 +168,7 @@ fn get_method_sig( do astsrv::exec(srv) |ctxt| { alt check ctxt.ast_map.get(item_id) { ast_map::node_item(@{ - node: ast::item_trait(_, _, methods), _ + node: ast::item_trait(_, methods), _ }, _) { alt check vec::find(methods, |method| { *method.ident == method_name @@ -183,7 +183,7 @@ fn get_method_sig( } } ast_map::node_item(@{ - node: ast::item_impl(_, _, _, _, methods), _ + node: ast::item_impl(_, _, _, methods), _ }, _) { alt check vec::find(methods, |method| { *method.ident == method_name @@ -218,7 +218,7 @@ fn fold_impl( let (trait_ty, self_ty) = do astsrv::exec(srv) |ctxt| { alt ctxt.ast_map.get(doc.id()) { ast_map::node_item(@{ - node: ast::item_impl(_, _, trait_ty, self_ty, _), _ + node: ast::item_impl(_, trait_ty, self_ty, _), _ }, _) { let trait_ty = option::map(trait_ty, |p| { pprust::path_to_str(p.path) @@ -274,7 +274,7 @@ fn fold_type( alt ctxt.ast_map.get(doc.id()) { ast_map::node_item(@{ ident: ident, - node: ast::item_ty(ty, params, ast::rp_none), _ + node: ast::item_ty(ty, params), _ }, _) { some(#fmt( "type %s%s = %s", diff --git a/src/test/compile-fail/region-unused.rs b/src/test/compile-fail/region-unused.rs deleted file mode 100644 index bf48e3f0da2..00000000000 --- a/src/test/compile-fail/region-unused.rs +++ /dev/null @@ -1,3 +0,0 @@ -type foo/& = {f: int}; //~ ERROR lifetime `self` unused - -fn main() {} \ No newline at end of file diff --git a/src/test/compile-fail/regions-bounds.rs b/src/test/compile-fail/regions-bounds.rs index ae9f16ae714..d19a0c83905 100644 --- a/src/test/compile-fail/regions-bounds.rs +++ b/src/test/compile-fail/regions-bounds.rs @@ -2,9 +2,9 @@ // nominal types (but not on other types) and that they are type // checked. -enum an_enum/& { } -iface an_iface/& { } -class a_class/& { let x:int; new(x:int) { self.x = x; } } +enum an_enum = ∫ +iface an_iface { fn foo() -> &self.int; } +class a_class { let x:&self.int; new(x:&self.int) { self.x = x; } } fn a_fn1(e: an_enum/&a) -> an_enum/&b { ret e; //~ ERROR mismatched types: expected `an_enum/&b` but found `an_enum/&a` diff --git a/src/test/compile-fail/regions-creating-enums.rs b/src/test/compile-fail/regions-creating-enums.rs index 3873dcb6d0a..16d0bd6afde 100644 --- a/src/test/compile-fail/regions-creating-enums.rs +++ b/src/test/compile-fail/regions-creating-enums.rs @@ -1,4 +1,4 @@ -enum ast/& { +enum ast { num(uint), add(&ast, &ast) } diff --git a/src/test/compile-fail/regions-iface-1.rs b/src/test/compile-fail/regions-iface-1.rs index f6d4d5885f9..3478742c2ec 100644 --- a/src/test/compile-fail/regions-iface-1.rs +++ b/src/test/compile-fail/regions-iface-1.rs @@ -1,13 +1,13 @@ type ctxt = { v: uint }; -iface get_ctxt/& { +iface get_ctxt { // Here the `&` is bound in the method definition: fn get_ctxt() -> &ctxt; } -type has_ctxt/& = { c: &ctxt }; +type has_ctxt = { c: &ctxt }; -impl/& of get_ctxt for has_ctxt { +impl of get_ctxt for has_ctxt { // Here an error occurs because we used `&self` but // the definition used `&`: diff --git a/src/test/compile-fail/regions-iface-2.rs b/src/test/compile-fail/regions-iface-2.rs index 3ebba4e2d2f..413e17c354f 100644 --- a/src/test/compile-fail/regions-iface-2.rs +++ b/src/test/compile-fail/regions-iface-2.rs @@ -1,12 +1,12 @@ type ctxt = { v: uint }; -iface get_ctxt/& { +iface get_ctxt { fn get_ctxt() -> &self.ctxt; } -type has_ctxt/& = { c: &ctxt }; +type has_ctxt = { c: &ctxt }; -impl/& of get_ctxt for has_ctxt { +impl of get_ctxt for has_ctxt { fn get_ctxt() -> &self.ctxt { self.c } } diff --git a/src/test/compile-fail/regions-iface-3.rs b/src/test/compile-fail/regions-iface-3.rs index efd15583ab6..6268846c3ec 100644 --- a/src/test/compile-fail/regions-iface-3.rs +++ b/src/test/compile-fail/regions-iface-3.rs @@ -1,4 +1,4 @@ -iface get_ctxt/& { +iface get_ctxt { fn get_ctxt() -> &self.uint; } diff --git a/src/test/compile-fail/regions-in-enums.rs b/src/test/compile-fail/regions-in-enums.rs index d7b1ddf1e18..3a9f34892f6 100644 --- a/src/test/compile-fail/regions-in-enums.rs +++ b/src/test/compile-fail/regions-in-enums.rs @@ -1,24 +1,12 @@ -enum no0 { - x0(&uint) //~ ERROR to use region types here, the containing type must be declared with a region bound -} - -enum no1 { - x1(&self.uint) //~ ERROR to use region types here, the containing type must be declared with a region bound -} - -enum no2 { - x2(&foo.uint) //~ ERROR named regions other than `self` are not allowed as part of a type declaration -} - -enum yes0/& { +enum yes0 { x3(&uint) } -enum yes1/& { +enum yes1 { x4(&self.uint) } -enum yes2/& { +enum yes2 { x5(&foo.uint) //~ ERROR named regions other than `self` are not allowed as part of a type declaration } diff --git a/src/test/compile-fail/regions-in-rsrcs.rs b/src/test/compile-fail/regions-in-rsrcs.rs index 55990fb0568..297ff98ad4e 100644 --- a/src/test/compile-fail/regions-in-rsrcs.rs +++ b/src/test/compile-fail/regions-in-rsrcs.rs @@ -1,34 +1,16 @@ -class no0 { - let x: &uint; //~ ERROR to use region types here, the containing type must be declared with a region bound - new(x: &uint) { self.x = x; } //~ ERROR to use region types here, the containing type must be declared with a region bound - drop {} -} - -class no1 { - let x: &self.uint; //~ ERROR to use region types here, the containing type must be declared with a region bound - new(x: &self.uint) { self.x = x; } //~ ERROR to use region types here, the containing type must be declared with a region bound - drop {} -} - -class no2 { - let x: &foo.uint; //~ ERROR named regions other than `self` are not allowed as part of a type declaration - new(x: &foo.uint) { self.x = x; } //~ ERROR named regions other than `self` are not allowed as part of a type declaration - drop {} -} - -class yes0/& { +class yes0 { let x: &uint; new(x: &uint) { self.x = x; } drop {} } -class yes1/& { +class yes1 { let x: &self.uint; new(x: &self.uint) { self.x = x; } drop {} } -class yes2/& { +class yes2 { let x: &foo.uint; //~ ERROR named regions other than `self` are not allowed as part of a type declaration new(x: &foo.uint) { self.x = x; } //~ ERROR named regions other than `self` are not allowed as part of a type declaration drop {} diff --git a/src/test/compile-fail/regions-in-type-items.rs b/src/test/compile-fail/regions-in-type-items.rs index bbc5da2004d..3ccae788651 100644 --- a/src/test/compile-fail/regions-in-type-items.rs +++ b/src/test/compile-fail/regions-in-type-items.rs @@ -1,24 +1,12 @@ -type item_ty_no0 = { - x: &uint //~ ERROR to use region types here, the containing type must be declared with a region bound -}; - -type item_ty_no1 = { - x: &self.uint //~ ERROR to use region types here, the containing type must be declared with a region bound -}; - -type item_ty_no2 = { - x: &foo.uint //~ ERROR named regions other than `self` are not allowed as part of a type declaration -}; - -type item_ty_yes0/& = { +type item_ty_yes0 = { x: &uint }; -type item_ty_yes1/& = { +type item_ty_yes1 = { x: &self.uint }; -type item_ty_yes2/& = { //~ ERROR lifetime `self` unused inside reference-parameterized type +type item_ty_yes2 = { x: &foo.uint //~ ERROR named regions other than `self` are not allowed as part of a type declaration }; diff --git a/src/test/compile-fail/regions-infer-paramd-indirect.rs b/src/test/compile-fail/regions-infer-paramd-indirect.rs new file mode 100644 index 00000000000..907f8e5e69d --- /dev/null +++ b/src/test/compile-fail/regions-infer-paramd-indirect.rs @@ -0,0 +1,18 @@ +// Check that we correctly infer that b and c must be region +// parameterized because they reference a which requires a region. + +type a = ∫ +type b = @a; +type c = {f: @b}; + +impl methods for c { + fn set_f_ok(b: @b/&self) { + self.f = b; + } + + fn set_f_bad(b: @b) { + self.f = b; //~ ERROR mismatched types: expected `@@&self.int` but found `@@&int` + } +} + +fn main() {} \ No newline at end of file diff --git a/src/test/compile-fail/regions-infer-paramd-method.rs b/src/test/compile-fail/regions-infer-paramd-method.rs new file mode 100644 index 00000000000..bea901071a2 --- /dev/null +++ b/src/test/compile-fail/regions-infer-paramd-method.rs @@ -0,0 +1,32 @@ +// Here: foo is parameterized because it contains a method that +// refers to self. + +iface foo { + fn self_int() -> &self.int; + + fn any_int() -> ∫ +} + +type with_foo = {mut f: foo}; + +impl methods for with_foo { + fn set_foo(f: foo) { + self.f = f; //~ ERROR mismatched types: expected `foo/&self` but found `foo/&` + } +} + +// Bar is not region parameterized. + +iface bar { + fn any_int() -> ∫ +} + +type with_bar = {mut f: bar}; + +impl methods for with_bar { + fn set_foo(f: bar) { + self.f = f; + } +} + +fn main() {} \ No newline at end of file diff --git a/src/test/run-pass/assignability-iface.rs b/src/test/run-pass/assignability-iface.rs index 47cf7535a6e..f65b06fcfe0 100644 --- a/src/test/run-pass/assignability-iface.rs +++ b/src/test/run-pass/assignability-iface.rs @@ -6,7 +6,7 @@ iface iterable { fn iterate(blk: fn(A) -> bool); } -impl vec/& of iterable for &[const A] { +impl vec of iterable for &[const A] { fn iterate(f: fn(A) -> bool) { vec::each(self, f); } diff --git a/src/test/run-pass/issue-2502.rs b/src/test/run-pass/issue-2502.rs index 359467dbe62..5df083a9402 100644 --- a/src/test/run-pass/issue-2502.rs +++ b/src/test/run-pass/issue-2502.rs @@ -1,4 +1,4 @@ -class font/& { +class font { let fontbuf: &self.~[u8]; new(fontbuf: &self.~[u8]) { diff --git a/src/test/run-pass/issue-2748-a.rs b/src/test/run-pass/issue-2748-a.rs index 7f1d4a45b61..bf027bdd060 100644 --- a/src/test/run-pass/issue-2748-a.rs +++ b/src/test/run-pass/issue-2748-a.rs @@ -1,7 +1,7 @@ -class CMap/& { - let buf: [u8]/&; +class CMap { + let buf: &[u8]; - new(buf: [u8]/&) { + new(buf: &self.[u8]) { self.buf = buf; } } diff --git a/src/test/run-pass/rcvr-borrowed-to-region.rs b/src/test/run-pass/rcvr-borrowed-to-region.rs index cae6462ceb2..ddf7081060d 100644 --- a/src/test/run-pass/rcvr-borrowed-to-region.rs +++ b/src/test/run-pass/rcvr-borrowed-to-region.rs @@ -1,5 +1,5 @@ // Note: impl on a slice -impl foo/& for &int { +impl foo for &int { fn get() -> int { ret *self; } diff --git a/src/test/run-pass/rcvr-borrowed-to-slice.rs b/src/test/run-pass/rcvr-borrowed-to-slice.rs index f03defbd6fc..09de19cae45 100644 --- a/src/test/run-pass/rcvr-borrowed-to-slice.rs +++ b/src/test/run-pass/rcvr-borrowed-to-slice.rs @@ -1,5 +1,5 @@ // Note: impl on a slice -impl foo/& for &[int] { +impl foo for &[int] { fn sum() -> int { let mut sum = 0; for vec::each(self) |e| { sum += e; } diff --git a/src/test/run-pass/regions-creating-enums2.rs b/src/test/run-pass/regions-creating-enums2.rs index 27559ea8942..b03205e1596 100644 --- a/src/test/run-pass/regions-creating-enums2.rs +++ b/src/test/run-pass/regions-creating-enums2.rs @@ -1,4 +1,4 @@ -enum ast/& { +enum ast { num(uint), add(&ast, &ast) } diff --git a/src/test/run-pass/regions-creating-enums5.rs b/src/test/run-pass/regions-creating-enums5.rs index a7982cb9374..0ca55e99e12 100644 --- a/src/test/run-pass/regions-creating-enums5.rs +++ b/src/test/run-pass/regions-creating-enums5.rs @@ -1,4 +1,4 @@ -enum ast/& { +enum ast { num(uint), add(&ast, &ast) } diff --git a/src/test/run-pass/regions-iface.rs b/src/test/run-pass/regions-iface.rs index 6bc8f172f98..3f8301cd26c 100644 --- a/src/test/run-pass/regions-iface.rs +++ b/src/test/run-pass/regions-iface.rs @@ -1,12 +1,12 @@ type ctxt = { v: uint }; -iface get_ctxt/& { +iface get_ctxt { fn get_ctxt() -> &self.ctxt; } -type has_ctxt/& = { c: &ctxt }; +type has_ctxt = { c: &ctxt }; -impl/& of get_ctxt for has_ctxt { +impl of get_ctxt for has_ctxt { fn get_ctxt() -> &self.ctxt { self.c } diff --git a/src/test/run-pass/regions-mock-trans-impls.rs b/src/test/run-pass/regions-mock-trans-impls.rs index 077ca3d51ed..b579d1e578c 100644 --- a/src/test/run-pass/regions-mock-trans-impls.rs +++ b/src/test/run-pass/regions-mock-trans-impls.rs @@ -2,11 +2,11 @@ import libc, sys, unsafe; enum arena = (); -type bcx/& = { +type bcx = { fcx: &fcx }; -type fcx/& = { +type fcx = { arena: &arena, ccx: &ccx }; diff --git a/src/test/run-pass/regions-mock-trans.rs b/src/test/run-pass/regions-mock-trans.rs index 646456301d5..a82fa6eead6 100644 --- a/src/test/run-pass/regions-mock-trans.rs +++ b/src/test/run-pass/regions-mock-trans.rs @@ -2,11 +2,11 @@ import libc, sys, unsafe; enum arena = (); -type bcx/& = { +type bcx = { fcx: &fcx }; -type fcx/& = { +type fcx = { arena: &arena, ccx: &ccx }; diff --git a/src/test/run-pass/regions-nullary-variant.rs b/src/test/run-pass/regions-nullary-variant.rs index ad08ec1f67b..6d6d7b65a3f 100644 --- a/src/test/run-pass/regions-nullary-variant.rs +++ b/src/test/run-pass/regions-nullary-variant.rs @@ -1,4 +1,4 @@ -enum roption/& { +enum roption { a, b(&uint) } diff --git a/src/test/run-pass/regions-self-impls.rs b/src/test/run-pass/regions-self-impls.rs index e29d88cc78d..4e0cd5b1aee 100644 --- a/src/test/run-pass/regions-self-impls.rs +++ b/src/test/run-pass/regions-self-impls.rs @@ -1,6 +1,6 @@ -type clam/& = { chowder: &int }; +type clam = { chowder: &int }; -impl clam/& for clam { +impl clam for clam { fn get_chowder() -> &self.int { ret self.chowder; } } diff --git a/src/test/run-pass/regions-self-in-enums.rs b/src/test/run-pass/regions-self-in-enums.rs index ced26c8c7db..ef7a8ae1ed7 100644 --- a/src/test/run-pass/regions-self-in-enums.rs +++ b/src/test/run-pass/regions-self-in-enums.rs @@ -1,4 +1,4 @@ -enum int_wrapper/& { +enum int_wrapper { int_wrapper_ctor(&int) }