summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-10-05 18:51:36 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-10-05 18:53:04 -0700
commitb80b0688d5ccc276e1dd3b6dfeeaea5e6f2782de (patch)
tree283d012bdf0cf44a4ac38a5bea247cfe7b8392e2 /src/rustc
parent02c33f8d316cca760b380e5d9fc4762629a9f968 (diff)
downloadrust-b80b0688d5ccc276e1dd3b6dfeeaea5e6f2782de.tar.gz
rust-b80b0688d5ccc276e1dd3b6dfeeaea5e6f2782de.zip
rustc: Add a new method_self method call origin. Part of default methods.
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/middle/astencode.rs3
-rw-r--r--src/rustc/middle/privacy.rs7
-rw-r--r--src/rustc/middle/trans/base.rs15
-rw-r--r--src/rustc/middle/trans/meth.rs3
-rw-r--r--src/rustc/middle/trans/type_use.rs2
-rw-r--r--src/rustc/middle/ty.rs3
-rw-r--r--src/rustc/middle/typeck.rs5
-rw-r--r--src/rustc/middle/typeck/check/method.rs38
8 files changed, 61 insertions, 15 deletions
diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs
index f2ee3df6610..a364c1d75d4 100644
--- a/src/rustc/middle/astencode.rs
+++ b/src/rustc/middle/astencode.rs
@@ -493,6 +493,9 @@ impl method_origin: tr {
           typeck::method_trait(did, m, vstore) => {
             typeck::method_trait(did.tr(xcx), m, vstore)
           }
+          typeck::method_self(did, m) => {
+            typeck::method_self(did.tr(xcx), m)
+          }
         }
     }
 }
diff --git a/src/rustc/middle/privacy.rs b/src/rustc/middle/privacy.rs
index f15ace40d30..98260a0d081 100644
--- a/src/rustc/middle/privacy.rs
+++ b/src/rustc/middle/privacy.rs
@@ -8,8 +8,8 @@ use syntax::ast::{item_trait, local_crate, node_id, pat_struct, private};
 use syntax::ast::{provided, required};
 use syntax::ast_map::{node_item, node_method};
 use ty::ty_class;
-use typeck::{method_map, method_origin, method_param, method_static};
-use typeck::{method_trait};
+use typeck::{method_map, method_origin, method_param, method_self};
+use typeck::{method_static, method_trait};
 
 use core::util::ignore;
 use dvec::DVec;
@@ -81,7 +81,8 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) {
                 }
             }
             method_param({trait_id: trait_id, method_num: method_num, _}) |
-            method_trait(trait_id, method_num, _) => {
+            method_trait(trait_id, method_num, _) |
+            method_self(trait_id, method_num) => {
                 if trait_id.crate == local_crate {
                     match tcx.items.find(trait_id.node) {
                         Some(node_item(item, _)) => {
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 24774add4dc..afa008fdbb7 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -1847,7 +1847,7 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
             }
         }
       }
-      ast::item_impl(tps, trait_refs, _, ms) => {
+      ast::item_impl(tps, trait_refs, self_ast_ty, ms) => {
         meth::trans_impl(ccx, *path, item.ident, ms, tps, None);
 
         // Translate any methods that have provided implementations.
@@ -1860,13 +1860,22 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
                 loop;
             }
 
+            // Get the self type.
+            let self_ty;
+            match ccx.tcx.ast_ty_to_ty_cache.get(self_ast_ty) {
+                ty::atttce_resolved(self_type) => self_ty = self_type,
+                ty::atttce_unresolved => {
+                    ccx.tcx.sess.impossible_case(item.span,
+                                                 ~"didn't cache self ast ty");
+                }
+            }
+
             match ccx.tcx.items.get(trait_id.node) {
                 ast_map::node_item(trait_item, _) => {
                     match trait_item.node {
                         ast::item_trait(tps, _, trait_methods) => {
-                            // XXX: ty_self is wrong here. Get the real type.
                             trans_trait(ccx, tps, trait_methods, path,
-                                        item.ident, ty::mk_self(ccx.tcx));
+                                        item.ident, self_ty);
                         }
                         _ => {
                             ccx.tcx.sess.impossible_case(item.span,
diff --git a/src/rustc/middle/trans/meth.rs b/src/rustc/middle/trans/meth.rs
index 65605f0e466..b4a64abeed7 100644
--- a/src/rustc/middle/trans/meth.rs
+++ b/src/rustc/middle/trans/meth.rs
@@ -154,6 +154,9 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id,
         typeck::method_trait(_, off, vstore) => {
             trans_trait_callee(bcx, callee_id, off, self, vstore)
         }
+        typeck::method_self(_, off) => {
+            bcx.tcx().sess.span_bug(self.span, ~"self method call");
+        }
     }
 }
 
diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs
index 8bd5bd7afc7..8eabf26e217 100644
--- a/src/rustc/middle/trans/type_use.rs
+++ b/src/rustc/middle/trans/type_use.rs
@@ -247,7 +247,7 @@ fn mark_for_expr(cx: ctx, e: @expr) {
               typeck::method_param({param_num: param, _}) => {
                 cx.uses[param] |= use_tydesc;
               }
-              typeck::method_trait(*) => (),
+              typeck::method_trait(*) | typeck::method_self(*) => (),
             }
         }
       }
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index 78949ec5f79..f2f7b32b670 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -2826,7 +2826,8 @@ fn method_call_bounds(tcx: ctxt, method_map: typeck::method_map,
           }
           typeck::method_param({trait_id:trt_id,
                                 method_num:n_mth, _}) |
-          typeck::method_trait(trt_id, n_mth, _) => {
+          typeck::method_trait(trt_id, n_mth, _) |
+          typeck::method_self(trt_id, n_mth) => {
             // ...trait methods bounds, in contrast, include only the
             // method bounds, so we must preprend the tps from the
             // trait itself.  This ought to be harmonized.
diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs
index 6c461126853..514fc2cfbb3 100644
--- a/src/rustc/middle/typeck.rs
+++ b/src/rustc/middle/typeck.rs
@@ -73,7 +73,7 @@ export deserialize_method_map_entry;
 export vtable_map;
 export vtable_res;
 export vtable_origin;
-export method_static, method_param, method_trait;
+export method_static, method_param, method_trait, method_self;
 export vtable_static, vtable_param, vtable_trait;
 export provided_methods_map;
 
@@ -87,6 +87,9 @@ enum method_origin {
 
     // method invoked on a trait instance
     method_trait(ast::def_id, uint, ty::vstore),
+
+    // method invoked on "self" inside a default method
+    method_self(ast::def_id, uint),
 }
 
 // details for a method invoked with a receiver whose type is a type parameter
diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs
index d55f9facc62..f3b2c8f1b7e 100644
--- a/src/rustc/middle/typeck/check/method.rs
+++ b/src/rustc/middle/typeck/check/method.rs
@@ -232,9 +232,8 @@ impl LookupContext {
                     let self_did = self.fcx.self_impl_def_id.expect(
                         ~"unexpected `none` for self_impl_def_id");
                     let substs = {self_r: None, self_ty: None, tps: ~[]};
-                    self.push_inherent_candidates_from_trait(
-                        self_ty, self_did, &substs,
-                        ty::vstore_slice(ty::re_static));   // XXX: Wrong!
+                    self.push_inherent_candidates_from_self(
+                        self_ty, self_did, &substs);
                 }
                 ty_enum(did, _) | ty_class(did, _) => {
                     self.push_inherent_impl_candidates_for_type(did);
@@ -397,6 +396,33 @@ impl LookupContext {
         });
     }
 
+    fn push_inherent_candidates_from_self(&self,
+                                          self_ty: ty::t,
+                                          did: def_id,
+                                          substs: &ty::substs) {
+        let tcx = self.tcx();
+        let methods = ty::trait_methods(tcx, did);  // XXX: Inherited methods.
+        let index;
+        match vec::position(*methods, |m| m.ident == self.m_name) {
+            Some(i) => index = i,
+            None => return
+        }
+        let method = &methods[index];
+
+        let rcvr_substs = { self_ty: Some(self_ty), ..*substs };
+        let (rcvr_ty, rcvr_substs) =
+            self.create_rcvr_ty_and_substs_for_method(
+                method.self_ty, self_ty, move rcvr_substs);
+
+        self.inherent_candidates.push(Candidate {
+            rcvr_ty: rcvr_ty,
+            rcvr_substs: move rcvr_substs,
+            num_method_tps: method.tps.len(),
+            self_mode: get_mode_from_self_type(method.self_ty),
+            origin: method_self(did, index)
+        });
+    }
+
     fn push_inherent_impl_candidates_for_type(did: def_id)
     {
         let opt_impl_infos =
@@ -737,7 +763,7 @@ impl LookupContext {
          * vtable and hence cannot be monomorphized. */
 
         match candidate.origin {
-            method_static(*) | method_param(*) => {
+            method_static(*) | method_param(*) | method_self(*) => {
                 return; // not a call to a trait instance
             }
             method_trait(*) => {}
@@ -772,7 +798,7 @@ impl LookupContext {
             method_param(ref mp) => {
                 type_of_trait_method(self.tcx(), mp.trait_id, mp.method_num)
             }
-            method_trait(did, idx, _) => {
+            method_trait(did, idx, _) | method_self(did, idx) => {
                 type_of_trait_method(self.tcx(), did, idx)
             }
         };
@@ -793,7 +819,7 @@ impl LookupContext {
             method_param(mp) => {
                 self.report_param_candidate(idx, mp.trait_id)
             }
-            method_trait(trait_did, _, _) => {
+            method_trait(trait_did, _, _) | method_self(trait_did, _) => {
                 self.report_param_candidate(idx, trait_did)
             }
         }