about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2012-03-07 12:54:00 +0100
committerMarijn Haverbeke <marijnh@gmail.com>2012-03-08 21:17:32 +0100
commitc71306b0dbdec6c8d6aaec06cb6770d5b0a2a7cc (patch)
tree4b3a69f7b3e8af17f7049e4f3b48b1dbfa327579
parentfd465f91a89450b7daebecdde9c280a923bbe394 (diff)
Explicitly store self_ids use for self locals in methods
This makes it possible to move them between crates without confusion,
and to instantiate them at a point where the monomorphizing
substitutions are known.

Issue #1944
-rw-r--r--src/rustc/metadata/astencode.rs5
-rw-r--r--src/rustc/metadata/astencode_gen.rs18
-rw-r--r--src/rustc/metadata/encoder.rs6
-rw-r--r--src/rustc/middle/ast_map.rs2
-rw-r--r--src/rustc/middle/resolve.rs6
-rw-r--r--src/rustc/middle/trans/base.rs6
-rw-r--r--src/rustc/middle/trans/impl.rs5
-rw-r--r--src/rustc/middle/ty.rs9
-rw-r--r--src/rustc/middle/typeck.rs29
-rw-r--r--src/rustc/syntax/ast.rs2
-rw-r--r--src/rustc/syntax/ast_util.rs2
-rw-r--r--src/rustc/syntax/fold.rs3
-rw-r--r--src/rustc/syntax/parse/parser.rs3
-rw-r--r--src/rustc/syntax/visit.rs8
14 files changed, 62 insertions, 42 deletions
diff --git a/src/rustc/metadata/astencode.rs b/src/rustc/metadata/astencode.rs
index 8e6d7a0a526..88b70a67fbd 100644
--- a/src/rustc/metadata/astencode.rs
+++ b/src/rustc/metadata/astencode.rs
@@ -191,10 +191,13 @@ fn visit_ids(item: ast::inlined_item, vfn: fn@(ast::node_id)) {
 
             alt fk {
               visit::fk_item_fn(_, tps) |
-              visit::fk_method(_, tps) |
               visit::fk_res(_, tps) {
                 vec::iter(tps) {|tp| vfn(tp.id)}
               }
+              visit::fk_method(_, tps, m) {
+                vfn(m.self_id);
+                vec::iter(tps) {|tp| vfn(tp.id)}
+              }
               visit::fk_anon(_) |
               visit::fk_fn_block {
               }
diff --git a/src/rustc/metadata/astencode_gen.rs b/src/rustc/metadata/astencode_gen.rs
index 1d4c20098cb..9cd3fb06229 100644
--- a/src/rustc/metadata/astencode_gen.rs
+++ b/src/rustc/metadata/astencode_gen.rs
@@ -3938,7 +3938,7 @@ fn serialize_163<S: std::serialization::serializer>(s: S,
     s.emit_rec(/*syntax::ast::ident*//*[syntax::ast::attribute]*/
                /*[syntax::ast::ty_param]*//*syntax::ast::fn_decl*/
                /*syntax::ast::blk*//*syntax::ast::node_id*/
-               /*syntax::codemap::span*/
+               /*syntax::codemap::span*//*syntax::ast::node_id*/
                {||
                    {
                        s.emit_rec_field("ident", 0u,
@@ -3954,7 +3954,9 @@ fn serialize_163<S: std::serialization::serializer>(s: S,
                        s.emit_rec_field("id", 5u,
                                         {|| serialize_27(s, v.id) });
                        s.emit_rec_field("span", 6u,
-                                        {|| serialize_19(s, v.span) })
+                                        {|| serialize_19(s, v.span) });
+                       s.emit_rec_field("self_id", 7u,
+                                        {|| serialize_27(s, v.self_id) })
                    }
                });
 }
@@ -7845,6 +7847,8 @@ fn deserialize_163<S: std::serialization::deserializer>(s: S) ->
 
                /*syntax::codemap::span*/
 
+               /*syntax::ast::node_id*/
+
                {||
                    {ident:
                         s.read_rec_field("ident", 0u, {|| deserialize_1(s) }),
@@ -7858,8 +7862,10 @@ fn deserialize_163<S: std::serialization::deserializer>(s: S) ->
                         s.read_rec_field("body", 4u, {|| deserialize_82(s) }),
                     id: s.read_rec_field("id", 5u, {|| deserialize_27(s) }),
                     span:
-                        s.read_rec_field("span", 6u,
-                                         {|| deserialize_19(s) }),}
+                        s.read_rec_field("span", 6u, {|| deserialize_19(s) }),
+                    self_id:
+                        s.read_rec_field("self_id", 7u,
+                                         {|| deserialize_27(s) }),}
                })
 
 }
@@ -8165,7 +8171,7 @@ fn serialize_164<S: std::serialization::serializer>(s: S,
 
     s.emit_enum("syntax::ast::def",
                 /*syntax::ast::def_id*//*syntax::ast::purity*/
-                /*syntax::ast::node_id*/
+                /*syntax::ast::def_id*/
                 /*syntax::ast::def_id*/
                 /*syntax::ast::def_id*/
                 /*syntax::ast::def_id*/
@@ -8528,7 +8534,7 @@ fn deserialize_164<S: std::serialization::deserializer>(s: S) ->
     s.read_enum("syntax::ast::def",
                 /*syntax::ast::def_id*//*syntax::ast::purity*/
 
-                /*syntax::ast::node_id*/
+                /*syntax::ast::def_id*/
 
                 /*syntax::ast::def_id*/
 
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index 0b24b3325d9..8ea337bde1f 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -442,9 +442,11 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
             ebml_w.end_tag();
         }
         alt ifce {
-          some(_) {
+          some(t) {
             encode_symbol(ecx, ebml_w, item.id);
-            let i_ty = ty::lookup_item_type(tcx, local_def(item.id)).ty;
+            let i_ty = alt check t.node {
+              ty_path(_, id) { ty::node_id_to_type(tcx, id) }
+            };
             ebml_w.start_tag(tag_impl_iface);
             write_type(ecx, ebml_w, i_ty);
             ebml_w.end_tag();
diff --git a/src/rustc/middle/ast_map.rs b/src/rustc/middle/ast_map.rs
index 4240c0e5092..d1c80090e8c 100644
--- a/src/rustc/middle/ast_map.rs
+++ b/src/rustc/middle/ast_map.rs
@@ -132,6 +132,8 @@ fn map_arm(arm: arm, cx: ctx, v: vt) {
 fn map_method(impl_did: def_id, impl_path: @path,
               m: @method, cx: ctx) {
     cx.map.insert(m.id, node_method(m, impl_did, impl_path));
+    cx.map.insert(m.self_id, node_local(cx.local_id));
+    cx.local_id += 1u;
 }
 
 fn map_item(i: @item, cx: ctx, v: vt) {
diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs
index af71d57dded..c440574334e 100644
--- a/src/rustc/middle/resolve.rs
+++ b/src/rustc/middle/resolve.rs
@@ -530,8 +530,8 @@ fn visit_item_with_scope(e: @env, i: @ast::item, sc: scopes, v: vt<scopes>) {
         v.visit_ty(sty, sc, v);
         for m in methods {
             v.visit_ty_params(m.tps, sc, v);
-            let msc = cons(scope_method(i.id, tps + m.tps), @sc);
-            v.visit_fn(visit::fk_method(m.ident, []),
+            let msc = cons(scope_method(m.self_id, tps + m.tps), @sc);
+            v.visit_fn(visit::fk_method(m.ident, [], m),
                        m.decl, m.body, m.span, m.id, msc, v);
         }
       }
@@ -590,7 +590,7 @@ fn visit_fn_with_scope(e: @env, fk: visit::fn_kind, decl: ast::fn_decl,
     for c: @ast::constr in decl.constraints { resolve_constr(e, c, sc, v); }
     let scope = alt fk {
       visit::fk_item_fn(_, tps) | visit::fk_res(_, tps) |
-      visit::fk_method(_, tps) { scope_bare_fn(decl, id, tps) }
+      visit::fk_method(_, tps, _) { scope_bare_fn(decl, id, tps) }
       visit::fk_anon(ast::proto_bare) { scope_bare_fn(decl, id, []) }
       visit::fk_anon(_) | visit::fk_fn_block { scope_fn_expr(decl, id, []) }
     };
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 6f53c56e32c..95597bac309 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -2136,7 +2136,7 @@ fn monomorphic_fn(ccx: crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
                            (*tvs).len() == 1u, [], psubsts, lldecl);
       }
       ast_map::node_method(mth, impl_def_id, _) {
-        let selfty = ty::lookup_item_type(ccx.tcx, impl_def_id).ty;
+        let selfty = ty::node_id_to_type(ccx.tcx, mth.self_id);
         let selfty = ty::substitute_type_params(ccx.tcx, substs, selfty);
         trans_fn(ccx, pt, mth.decl, mth.body, lldecl,
                  impl_self(selfty), [], psubsts, fn_id.node, none);
@@ -2315,7 +2315,7 @@ fn trans_local_var(cx: block, def: ast::def) -> local_var_result {
         assert (cx.fcx.lllocals.contains_key(nid));
         ret take_local(cx.fcx.lllocals, nid);
       }
-      ast::def_self(nid) {
+      ast::def_self(_) {
         let slf = option::get(cx.fcx.llself);
         let ptr = PointerCast(cx, slf.v,
                               T_ptr(type_of_or_i8(cx.ccx(), slf.t)));
@@ -4343,7 +4343,7 @@ fn trans_item(ccx: crate_ctxt, item: ast::item) {
         }
       }
       ast::item_impl(tps, _, _, ms) {
-        impl::trans_impl(ccx, *path, item.ident, ms, item.id, tps);
+        impl::trans_impl(ccx, *path, item.ident, ms, tps);
       }
       ast::item_res(decl, tps, body, dtor_id, ctor_id) {
         let llctor_decl = get_item_val(ccx, ctor_id);
diff --git a/src/rustc/middle/trans/impl.rs b/src/rustc/middle/trans/impl.rs
index 16cc55a6f94..1af4a13331b 100644
--- a/src/rustc/middle/trans/impl.rs
+++ b/src/rustc/middle/trans/impl.rs
@@ -44,14 +44,13 @@ import std::map::hashmap;
 // are referenced (ccx.method_map and ccx.dict_map).
 
 fn trans_impl(ccx: crate_ctxt, path: path, name: ast::ident,
-              methods: [@ast::method], id: ast::node_id,
-              tps: [ast::ty_param]) {
+              methods: [@ast::method], tps: [ast::ty_param]) {
     let sub_path = path + [path_name(name)];
     for m in methods {
         let llfn = get_item_val(ccx, m.id);
         let m_bounds = param_bounds(ccx, tps + m.tps);
         trans_fn(ccx, sub_path + [path_name(m.ident)], m.decl, m.body,
-                 llfn, impl_self(ty::node_id_to_type(ccx.tcx, id)),
+                 llfn, impl_self(ty::node_id_to_type(ccx.tcx, m.self_id)),
                  m_bounds, none, m.id, none);
     }
 }
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index fa4e254d934..9d4dbec782c 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -2157,8 +2157,13 @@ fn iface_methods(cx: ctxt, id: ast::def_id) -> @[method] {
 
 fn impl_iface(cx: ctxt, id: ast::def_id) -> option<t> {
     if id.crate == ast::local_crate {
-        let t = cx.tcache.get(id).ty;
-        if get(t).struct == ty_nil { none } else { some(t) }
+        alt cx.items.get(id.node) {
+          ast_map::node_item(@{node: ast::item_impl(
+              _, some(@{node: ast::ty_path(_, id), _}), _, _), _}, _) {
+            some(node_id_to_type(cx, id))
+          }
+          _ { none }
+        }
     } else {
         csearch::get_impl_iface(cx, id)
     }
diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs
index 998ffa654d4..275bb862b84 100644
--- a/src/rustc/middle/typeck.rs
+++ b/src/rustc/middle/typeck.rs
@@ -106,7 +106,7 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) ->
         let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, nid));
         ret {bounds: @[], ty: typ};
       }
-      ast::def_self(id) {
+      ast::def_self(_) {
         alt get_self_info(fcx.ccx) {
           some(self_impl(impl_t)) {
             ret {bounds: @[], ty: impl_t};
@@ -362,8 +362,8 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
             }
             ty::mk_param(tcx, n, id)
           }
-          ast::def_self(iface_id) {
-            alt check tcx.items.get(iface_id) {
+          ast::def_self(self_id) {
+            alt check tcx.items.get(self_id) {
               ast_map::node_item(@{node: ast::item_iface(tps, _), _}, _) {
                 if vec::len(tps) != vec::len(path.node.types) {
                     tcx.sess.span_err(ast_ty.span, "incorrect number of type \
@@ -850,7 +850,12 @@ mod collect {
           ast::item_impl(tps, ifce, selfty, ms) {
             let i_bounds = ty_param_bounds(tcx, m_collect, tps);
             let my_methods = [];
+            let selfty = ast_ty_to_ty(tcx, m_collect, selfty);
+            write_ty(tcx, it.id, selfty);
+            tcx.tcache.insert(local_def(it.id), {bounds: i_bounds,
+                                                 ty: selfty});
             for m in ms {
+                write_ty(tcx, m.self_id, selfty);
                 let bounds = ty_param_bounds(tcx, m_collect, m.tps);
                 let mty = ty_of_method(tcx, m_collect, m);
                 my_methods += [{mty: mty, id: m.id, span: m.span}];
@@ -860,15 +865,15 @@ mod collect {
                                       ty: fty});
                 write_ty(tcx, m.id, fty);
             }
-            let selfty = ast_ty_to_ty(tcx, m_collect, selfty);
-            write_ty(tcx, it.id, selfty);
             alt ifce {
               some(t) {
                 let iface_ty = ast_ty_to_ty(tcx, m_collect, t);
-                tcx.tcache.insert(local_def(it.id),
-                                     {bounds: i_bounds, ty: iface_ty});
                 alt ty::get(iface_ty).struct {
                   ty::ty_iface(did, tys) {
+                    // Store the iface type in the type node
+                    alt check t.node {
+                      ast::ty_path(_, t_id) { write_ty(tcx, t_id, iface_ty); }
+                    }
                     if did.crate == ast::local_crate {
                         ensure_iface_methods(tcx, did.node);
                     }
@@ -906,11 +911,7 @@ mod collect {
                   }
                 }
               }
-              _ {
-                // Store the bounds with a nil type.
-                tcx.tcache.insert(local_def(it.id), {bounds: i_bounds,
-                                                     ty: ty::mk_nil(tcx)});
-              }
+              _ {}
             }
           }
           ast::item_res(decl, tps, _, dtor_id, ctor_id) {
@@ -1665,8 +1666,8 @@ fn impl_self_ty(tcx: ty::ctxt, did: ast::def_id) -> {n_tps: uint, ty: ty::t} {
           }
         }
     } else {
-        let tpt = csearch::get_type(tcx, did);
-        {n_tps: vec::len(*tpt.bounds), ty: tpt.ty}
+        let ity = ty::lookup_item_type(tcx, did);
+        {n_tps: vec::len(*ity.bounds), ty: ity.ty}
     }
 }
 
diff --git a/src/rustc/syntax/ast.rs b/src/rustc/syntax/ast.rs
index b9102ff4b22..e29b80f8d46 100644
--- a/src/rustc/syntax/ast.rs
+++ b/src/rustc/syntax/ast.rs
@@ -424,7 +424,7 @@ enum ret_style {
 
 type method = {ident: ident, attrs: [attribute],
                tps: [ty_param], decl: fn_decl, body: blk,
-               id: node_id, span: span};
+               id: node_id, span: span, self_id: node_id};
 
 type _mod = {view_items: [@view_item], items: [@item]};
 
diff --git a/src/rustc/syntax/ast_util.rs b/src/rustc/syntax/ast_util.rs
index dc0939cc2e4..98f87008a60 100644
--- a/src/rustc/syntax/ast_util.rs
+++ b/src/rustc/syntax/ast_util.rs
@@ -41,7 +41,7 @@ fn def_id_of_def(d: def) -> def_id {
       def_use(id) |
       def_class(id) | def_class_field(_, id) | def_class_method(_, id) { id }
 
-      def_self(id) | def_arg(id, _) | def_local(id, _) |
+      def_arg(id, _) | def_local(id, _) | def_self(id) |
       def_upvar(id, _, _) | def_binding(id) {
         local_def(id)
       }
diff --git a/src/rustc/syntax/fold.rs b/src/rustc/syntax/fold.rs
index bc9b4b79048..25e6219161f 100644
--- a/src/rustc/syntax/fold.rs
+++ b/src/rustc/syntax/fold.rs
@@ -301,7 +301,8 @@ fn noop_fold_method(&&m: @method, fld: ast_fold) -> @method {
           decl: fold_fn_decl(m.decl, fld),
           body: fld.fold_block(m.body),
           id: fld.new_id(m.id),
-          span: fld.new_span(m.span)};
+          span: fld.new_span(m.span),
+          self_id: fld.new_id(m.self_id)};
 }
 
 
diff --git a/src/rustc/syntax/parse/parser.rs b/src/rustc/syntax/parse/parser.rs
index ec7b63926c9..69c28c3c904 100644
--- a/src/rustc/syntax/parse/parser.rs
+++ b/src/rustc/syntax/parse/parser.rs
@@ -1931,7 +1931,8 @@ fn parse_method(p: parser) -> @ast::method {
     let (inner_attrs, body) = parse_inner_attrs_and_block(p, true);
     let attrs = attrs + inner_attrs;
     @{ident: ident, attrs: attrs, tps: tps, decl: decl, body: body,
-      id: p.get_id(), span: ast_util::mk_sp(lo, body.span.hi)}
+      id: p.get_id(), span: ast_util::mk_sp(lo, body.span.hi),
+      self_id: p.get_id()}
 }
 
 fn parse_item_iface(p: parser, attrs: [ast::attribute]) -> @ast::item {
diff --git a/src/rustc/syntax/visit.rs b/src/rustc/syntax/visit.rs
index dd1a53942fa..dd39028aab3 100644
--- a/src/rustc/syntax/visit.rs
+++ b/src/rustc/syntax/visit.rs
@@ -14,7 +14,7 @@ enum vt<E> { mk_vt(visitor<E>), }
 
 enum fn_kind {
     fk_item_fn(ident, [ty_param]), //< an item declared with fn()
-    fk_method(ident, [ty_param]),
+    fk_method(ident, [ty_param], @method),
     fk_res(ident, [ty_param]),
     fk_anon(proto),  //< an anonymous function like fn@(...)
     fk_fn_block,     //< a block {||...}
@@ -22,14 +22,14 @@ enum fn_kind {
 
 fn name_of_fn(fk: fn_kind) -> ident {
     alt fk {
-      fk_item_fn(name, _) | fk_method(name, _) | fk_res(name, _) { name }
+      fk_item_fn(name, _) | fk_method(name, _, _) | fk_res(name, _) { name }
       fk_anon(_) | fk_fn_block { "anon" }
     }
 }
 
 fn tps_of_fn(fk: fn_kind) -> [ty_param] {
     alt fk {
-      fk_item_fn(_, tps) | fk_method(_, tps) | fk_res(_, tps) { tps }
+      fk_item_fn(_, tps) | fk_method(_, tps, _) | fk_res(_, tps) { tps }
       fk_anon(_) | fk_fn_block { [] }
     }
 }
@@ -256,7 +256,7 @@ fn visit_fn_decl<E>(fd: fn_decl, e: E, v: vt<E>) {
 // because it is not a default impl of any method, though I doubt that really
 // clarifies anything. - Niko
 fn visit_method_helper<E>(m: @method, e: E, v: vt<E>) {
-    v.visit_fn(fk_method(m.ident, m.tps), m.decl, m.body, m.span,
+    v.visit_fn(fk_method(m.ident, m.tps, m), m.decl, m.body, m.span,
                m.id, e, v);
 }