about summary refs log tree commit diff
path: root/src/rustc/middle
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-07-31 16:32:37 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-07-31 16:35:11 -0700
commit2cfe8fb357f8ad7e99dc03b09e0ec5fa1c2c9029 (patch)
tree56af8b2f6feb43d3393caf47bcebaa8399712257 /src/rustc/middle
parent567f881fdf4053d4890929eb4cd46c67c4a011ee (diff)
rustc: Check self types in method lookup; allow required trait methods to have self types; write self types into metadata
Diffstat (limited to 'src/rustc/middle')
-rw-r--r--src/rustc/middle/resolve3.rs31
-rw-r--r--src/rustc/middle/ty.rs1
-rw-r--r--src/rustc/middle/typeck/check/method.rs34
-rw-r--r--src/rustc/middle/typeck/coherence.rs6
-rw-r--r--src/rustc/middle/typeck/collect.rs2
5 files changed, 59 insertions, 15 deletions
diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs
index 13019f19a8a..7a7f80bf9dc 100644
--- a/src/rustc/middle/resolve3.rs
+++ b/src/rustc/middle/resolve3.rs
@@ -28,13 +28,13 @@ import syntax::ast::{item_mod, item_trait, item_ty, le, local, local_crate};
 import syntax::ast::{lt, method, mul, ne, neg, node_id, pat, pat_enum};
 import syntax::ast::{pat_ident, path, prim_ty, pat_box, pat_uniq, pat_lit};
 import syntax::ast::{pat_range, pat_rec, pat_tup, pat_wild, provided};
-import syntax::ast::{required, rem, shl, stmt_decl, subtract, ty, ty_bool};
-import syntax::ast::{ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i, ty_i16};
-import syntax::ast::{ty_i32, ty_i64, ty_i8, ty_int, ty_param, ty_path};
-import syntax::ast::{ty_str, ty_u, ty_u16, ty_u32, ty_u64, ty_u8, ty_uint};
-import syntax::ast::{variant, view_item, view_item_export, view_item_import};
-import syntax::ast::{view_item_use, view_path_glob, view_path_list};
-import syntax::ast::{view_path_simple};
+import syntax::ast::{required, rem, self_ty_, shl, stmt_decl, subtract, ty};
+import syntax::ast::{ty_bool, ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i};
+import syntax::ast::{ty_i16, ty_i32, ty_i64, ty_i8, ty_int, ty_param};
+import syntax::ast::{ty_path, ty_str, ty_u, ty_u16, ty_u32, ty_u64, ty_u8};
+import syntax::ast::{ty_uint, variant, view_item, view_item_export};
+import syntax::ast::{view_item_import, view_item_use, view_path_glob};
+import syntax::ast::{view_path_list, view_path_simple};
 import syntax::ast_util::{def_id_of_def, dummy_sp, local_def, new_def_hash};
 import syntax::ast_util::{walk_pat};
 import syntax::attr::{attr_metas, contains_name};
@@ -59,7 +59,16 @@ import str_eq = str::eq;
 type DefMap = hashmap<node_id,def>;
 
 // Implementation resolution
-type MethodInfo = { did: def_id, n_tps: uint, ident: ident };
+
+// XXX: This kind of duplicates information kept in ty::method. Maybe it
+// should go away.
+type MethodInfo = {
+    did: def_id,
+    n_tps: uint,
+    ident: ident,
+    self_type: self_ty_
+};
+
 type Impl = { did: def_id, ident: ident, methods: ~[@MethodInfo] };
 type ImplScope = @~[@Impl];
 type ImplScopes = @list<ImplScope>;
@@ -925,7 +934,8 @@ class Resolver {
                                 @{
                                     did: local_def(method.id),
                                     n_tps: method.tps.len(),
-                                    ident: method.ident
+                                    ident: method.ident,
+                                    self_type: method.self_ty.node
                                 }
                             ];
                         }
@@ -962,7 +972,8 @@ class Resolver {
                         @{
                             did: local_def(method.id),
                             n_tps: method.tps.len(),
-                            ident: method.ident
+                            ident: method.ident,
+                            self_type: method.self_ty.node
                         }
                     ];
                 }
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index f2903232400..71e0fedef61 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -183,6 +183,7 @@ type param_bounds = @~[param_bound];
 type method = {ident: ast::ident,
                tps: @~[param_bounds],
                fty: fn_ty,
+               self_ty: ast::self_ty_,
                purity: ast::purity,
                vis: ast::visibility};
 
diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs
index ac18b8ccad6..08f36bdb256 100644
--- a/src/rustc/middle/typeck/check/method.rs
+++ b/src/rustc/middle/typeck/check/method.rs
@@ -1,12 +1,14 @@
 /* Code to handle method lookups (which can be quite complex) */
 
 import coherence::get_base_type_def_id;
-import middle::resolve3::Impl;
+import middle::resolve3::{Impl, MethodInfo};
+import middle::ty::{mk_box, mk_rptr, mk_uniq};
 import middle::typeck::infer::methods; // next_ty_vars
-import syntax::ast::def_id;
+import syntax::ast::{def_id, sty_box, sty_by_ref, sty_region, sty_uniq};
+import syntax::ast::{sty_value};
 import syntax::ast_map;
 import syntax::ast_map::node_id_to_str;
-import syntax::ast_util::new_def_hash;
+import syntax::ast_util::{dummy_sp, new_def_hash};
 import dvec::{dvec, extensions};
 
 type candidate = {
@@ -18,6 +20,28 @@ type candidate = {
     entry: method_map_entry
 };
 
+fn transform_self_type_for_method(fcx: @fn_ctxt,
+                                  impl_ty: ty::t,
+                                  method_info: MethodInfo)
+                               -> ty::t {
+    alt method_info.self_type {
+        sty_by_ref | sty_value => {
+            impl_ty
+        }
+        sty_region(r, mutability) => {
+            // XXX: dummy_sp is unfortunate here.
+            let region = ast_region_to_region(fcx, fcx, dummy_sp(), r);
+            mk_rptr(fcx.ccx.tcx, region, { ty: impl_ty, mutbl: mutability })
+        }
+        sty_box(mutability) => {
+            mk_box(fcx.ccx.tcx, { ty: impl_ty, mutbl: mutability })
+        }
+        sty_uniq(mutability) => {
+            mk_uniq(fcx.ccx.tcx, { ty: impl_ty, mutbl: mutability })
+        }
+    }
+}
+
 class lookup {
     let fcx: @fn_ctxt;
     let expr: @ast::expr;
@@ -370,6 +394,10 @@ class lookup {
             let {substs: impl_substs, ty: impl_ty} =
                 impl_self_ty(self.fcx, im.did);
 
+            let impl_ty = transform_self_type_for_method(self.fcx,
+                                                         impl_ty,
+                                                         *m);
+
             // Depending on our argument, we find potential
             // matches either by checking subtypability or
             // type assignability. Collect the matches.
diff --git a/src/rustc/middle/typeck/coherence.rs b/src/rustc/middle/typeck/coherence.rs
index e3fdd0424b7..091980ceb39 100644
--- a/src/rustc/middle/typeck/coherence.rs
+++ b/src/rustc/middle/typeck/coherence.rs
@@ -492,7 +492,8 @@ class CoherenceChecker {
                     push(methods, @{
                         did: local_def(ast_method.id),
                         n_tps: ast_method.tps.len(),
-                        ident: ast_method.ident
+                        ident: ast_method.ident,
+                        self_type: ast_method.self_ty.node
                     });
                 }
 
@@ -513,7 +514,8 @@ class CoherenceChecker {
                             push(methods, @{
                                 did: local_def(ast_method.id),
                                 n_tps: ast_method.tps.len(),
-                                ident: ast_method.ident
+                                ident: ast_method.ident,
+                                self_type: ast_method.self_ty.node
                             });
                         }
                     }
diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs
index 22063051dce..0c16fc16933 100644
--- a/src/rustc/middle/typeck/collect.rs
+++ b/src/rustc/middle/typeck/collect.rs
@@ -432,6 +432,7 @@ fn ty_of_method(ccx: @crate_ctxt,
      tps: ty_param_bounds(ccx, m.tps),
      fty: ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_bare,
                         m.decl, none),
+     self_ty: m.self_ty.node,
      purity: m.decl.purity,
      vis: m.vis}
 }
@@ -444,6 +445,7 @@ fn ty_of_ty_method(self: @crate_ctxt,
      fty: ty_of_fn_decl(self, type_rscope(rp), ast::proto_bare,
                                  m.decl, none),
      // assume public, because this is only invoked on trait methods
+     self_ty: m.self_ty.node,
      purity: m.decl.purity, vis: ast::public}
 }