about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2013-03-29 16:02:55 -0400
committerNiko Matsakis <niko@alum.mit.edu>2013-04-05 05:36:02 -0400
commit3333b0f1177fd758cfd95d992aed18972ed26dfb (patch)
tree7e813be45397c5a4fc06e15d44aa0a60ea70d531 /src
parent0a0525e3664dfb659aae06c146a4336a878e2b05 (diff)
downloadrust-3333b0f1177fd758cfd95d992aed18972ed26dfb.tar.gz
rust-3333b0f1177fd758cfd95d992aed18972ed26dfb.zip
Add a (currently unused) "transformed self type" pointer into ty::method
Diffstat (limited to 'src')
-rw-r--r--src/librustc/metadata/common.rs1
-rw-r--r--src/librustc/metadata/decoder.rs19
-rw-r--r--src/librustc/metadata/encoder.rs12
-rw-r--r--src/librustc/middle/ty.rs1
-rw-r--r--src/librustc/middle/typeck/astconv.rs87
-rw-r--r--src/librustc/middle/typeck/collect.rs53
-rw-r--r--src/test/run-pass/regions-expl-self.rs2
7 files changed, 144 insertions, 31 deletions
diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs
index d3b06009d72..5df7b037334 100644
--- a/src/librustc/metadata/common.rs
+++ b/src/librustc/metadata/common.rs
@@ -162,6 +162,7 @@ pub static tag_link_args_arg: uint = 0x7a;
 
 pub static tag_item_method_tps: uint = 0x7b;
 pub static tag_item_method_fty: uint = 0x7c;
+pub static tag_item_method_transformed_self_ty: uint = 0x7d;
 
 pub struct LinkMeta {
     name: @str,
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 598539609e9..32a912d0101 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -236,6 +236,16 @@ fn doc_method_fty(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::BareFnTy {
                           |_, did| translate_def_id(cdata, did))
 }
 
+fn doc_transformed_self_ty(doc: ebml::Doc,
+                           tcx: ty::ctxt,
+                           cdata: cmd) -> Option<ty::t>
+{
+    do reader::maybe_get_doc(doc, tag_item_method_transformed_self_ty).map |tp| {
+        parse_ty_data(tp.data, cdata.cnum, tp.start, tcx,
+                      |_, did| translate_def_id(cdata, did))
+    }
+}
+
 pub fn item_type(item_id: ast::def_id, item: ebml::Doc,
                  tcx: ty::ctxt, cdata: cmd) -> ty::t {
     let t = doc_type(item, tcx, cdata);
@@ -716,14 +726,17 @@ pub fn get_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
     let method_doc = lookup_item(id, cdata.data);
     let def_id = item_def_id(method_doc, cdata);
     let name = item_name(intr, method_doc);
-    let bounds = item_ty_param_bounds(method_doc, tcx, cdata,
-                                      tag_item_method_tps);
+    let bounds =
+        item_ty_param_bounds(method_doc, tcx, cdata,
+                             tag_item_method_tps);
+    let transformed_self_ty = doc_transformed_self_ty(method_doc, tcx, cdata);
     let fty = doc_method_fty(method_doc, tcx, cdata);
     let vis = item_visibility(method_doc);
     let self_ty = get_self_ty(method_doc);
     ty::method {
         ident: name,
         tps: bounds,
+        transformed_self_ty: transformed_self_ty,
         fty: fty,
         self_ty: self_ty,
         vis: vis,
@@ -767,10 +780,12 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd,
             }
         };
 
+        let transformed_self_ty = doc_transformed_self_ty(mth, tcx, cdata);
         let self_ty = get_self_ty(mth);
         let ty_method = ty::method {
             ident: name,
             tps: bounds,
+            transformed_self_ty: transformed_self_ty,
             fty: fty,
             self_ty: self_ty,
             vis: ast::public,
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 2e3008a0cdc..e8fc4c44fea 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -230,6 +230,17 @@ fn encode_type(ecx: @EncodeContext, ebml_w: writer::Encoder, typ: ty::t) {
     ebml_w.end_tag();
 }
 
+fn encode_transformed_self_ty(ecx: @EncodeContext,
+                              ebml_w: writer::Encoder,
+                              opt_typ: Option<ty::t>)
+{
+    for opt_typ.each |&typ| {
+        ebml_w.start_tag(tag_item_method_transformed_self_ty);
+        write_type(ecx, ebml_w, typ);
+        ebml_w.end_tag();
+    }
+}
+
 fn encode_method_fty(ecx: @EncodeContext,
                      ebml_w: writer::Encoder,
                      typ: &ty::BareFnTy)
@@ -570,6 +581,7 @@ fn encode_method_ty_fields(ecx: @EncodeContext,
     encode_name(ecx, ebml_w, method_ty.ident);
     encode_ty_type_param_bounds(ebml_w, ecx, method_ty.tps,
                                 tag_item_method_tps);
+    encode_transformed_self_ty(ecx, ebml_w, method_ty.transformed_self_ty);
     encode_method_fty(ecx, ebml_w, &method_ty.fty);
     encode_visibility(ebml_w, method_ty.vis);
     encode_self_type(ebml_w, method_ty.self_ty);
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index fcdd5a650af..eb9eec25c04 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -71,6 +71,7 @@ pub type param_bounds = @~[param_bound];
 pub struct method {
     ident: ast::ident,
     tps: @~[param_bounds],
+    transformed_self_ty: Option<ty::t>,
     fty: BareFnTy,
     self_ty: ast::self_ty_,
     vis: ast::visibility,
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index c54e76b9c05..05a5e926f27 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -544,6 +544,29 @@ pub fn bound_lifetimes<AC:AstConv>(
     bound_lifetime_names
 }
 
+struct SelfInfo {
+    untransformed_self_ty: ty::t,
+    self_transform: ast::self_ty
+}
+
+pub fn ty_of_method<AC:AstConv,RS:region_scope + Copy + Durable>(
+    self: &AC,
+    rscope: &RS,
+    purity: ast::purity,
+    lifetimes: &OptVec<ast::Lifetime>,
+    untransformed_self_ty: ty::t,
+    self_transform: ast::self_ty,
+    decl: &ast::fn_decl) -> (Option<ty::t>, ty::BareFnTy)
+{
+    let self_info = SelfInfo {
+        untransformed_self_ty: untransformed_self_ty,
+        self_transform: self_transform
+    };
+    let (a, b) = ty_of_method_or_bare_fn(
+        self, rscope, purity, AbiSet::Rust(), lifetimes, Some(&self_info), decl);
+    (a.get(), b)
+}
+
 pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
     self: &AC,
     rscope: &RS,
@@ -552,6 +575,20 @@ pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
     lifetimes: &OptVec<ast::Lifetime>,
     decl: &ast::fn_decl) -> ty::BareFnTy
 {
+    let (_, b) = ty_of_method_or_bare_fn(
+        self, rscope, purity, abi, lifetimes, None, decl);
+    b
+}
+
+fn ty_of_method_or_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
+    self: &AC,
+    rscope: &RS,
+    purity: ast::purity,
+    abi: AbiSet,
+    lifetimes: &OptVec<ast::Lifetime>,
+    opt_self_info: Option<&SelfInfo>,
+    decl: &ast::fn_decl) -> (Option<Option<ty::t>>, ty::BareFnTy)
+{
     debug!("ty_of_bare_fn");
 
     // new region names that appear inside of the fn decl are bound to
@@ -559,18 +596,56 @@ pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
     let bound_lifetime_names = bound_lifetimes(self, lifetimes);
     let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
 
+    let opt_transformed_self_ty = opt_self_info.map(|&self_info| {
+        transform_self_ty(self, &rb, self_info)
+    });
+
     let input_tys = decl.inputs.map(|a| ty_of_arg(self, &rb, *a, None));
+
     let output_ty = match decl.output.node {
         ast::ty_infer => self.ty_infer(decl.output.span),
         _ => ast_ty_to_ty(self, &rb, decl.output)
     };
 
-    ty::BareFnTy {
-        purity: purity,
-        abis: abi,
-        sig: ty::FnSig {bound_lifetime_names: bound_lifetime_names,
-                        inputs: input_tys,
-                        output: output_ty}
+    return (opt_transformed_self_ty,
+            ty::BareFnTy {
+                purity: purity,
+                abis: abi,
+                sig: ty::FnSig {bound_lifetime_names: bound_lifetime_names,
+                                inputs: input_tys,
+                                output: output_ty}
+            });
+
+    fn transform_self_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
+        self: &AC,
+        rscope: &RS,
+        self_info: &SelfInfo) -> Option<ty::t>
+    {
+        match self_info.self_transform.node {
+            ast::sty_static => None,
+            ast::sty_value => {
+                Some(self_info.untransformed_self_ty)
+            }
+            ast::sty_region(lifetime, mutability) => {
+                let region =
+                    ast_region_to_region(self, rscope,
+                                         self_info.self_transform.span,
+                                         lifetime);
+                Some(ty::mk_rptr(self.tcx(), region,
+                                 ty::mt {ty: self_info.untransformed_self_ty,
+                                         mutbl: mutability}))
+            }
+            ast::sty_box(mutability) => {
+                Some(ty::mk_box(self.tcx(),
+                                ty::mt {ty: self_info.untransformed_self_ty,
+                                        mutbl: mutability}))
+            }
+            ast::sty_uniq(mutability) => {
+                Some(ty::mk_uniq(self.tcx(),
+                                 ty::mt {ty: self_info.untransformed_self_ty,
+                                         mutbl: mutability}))
+            }
+        }
     }
 }
 
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 3ac3766e89d..81acae1d3a9 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -237,15 +237,17 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
             for ms.each |m| {
                 let ty_method = @match m {
                     &ast::required(ref m) => {
-                        ty_method_of_trait_method(ccx, region_paramd, generics,
-                                                  &m.id, &m.ident, &m.self_ty,
-                                                  &m.generics, &m.purity, &m.decl)
+                        ty_method_of_trait_method(
+                            ccx, trait_id, region_paramd, generics,
+                            &m.id, &m.ident, &m.self_ty,
+                            &m.generics, &m.purity, &m.decl)
                     }
 
                     &ast::provided(ref m) => {
-                        ty_method_of_trait_method(ccx, region_paramd, generics,
-                                                  &m.id, &m.ident, &m.self_ty,
-                                                  &m.generics, &m.purity, &m.decl)
+                        ty_method_of_trait_method(
+                            ccx, trait_id, region_paramd, generics,
+                            &m.id, &m.ident, &m.self_ty,
+                            &m.generics, &m.purity, &m.decl)
                     }
                 };
 
@@ -316,6 +318,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
     }
 
     fn ty_method_of_trait_method(self: &CrateCtxt,
+                                 trait_id: ast::node_id,
                                  trait_rp: Option<ty::region_variance>,
                                  trait_generics: &ast::Generics,
                                  m_id: &ast::node_id,
@@ -325,16 +328,16 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
                                  m_purity: &ast::purity,
                                  m_decl: &ast::fn_decl) -> ty::method
     {
+        let trait_self_ty = ty::mk_self(self.tcx, local_def(trait_id));
         let rscope = MethodRscope::new(m_self_ty.node, trait_rp, trait_generics);
+        let (transformed_self_ty, fty) =
+            astconv::ty_of_method(self, &rscope, *m_purity, &m_generics.lifetimes,
+                                  trait_self_ty, *m_self_ty, m_decl);
         ty::method {
             ident: *m_ident,
             tps: ty_param_bounds(self, m_generics),
-            fty: astconv::ty_of_bare_fn(self,
-                                        &rscope,
-                                        *m_purity,
-                                        AbiSet::Rust(),
-                                        &m_generics.lifetimes,
-                                        m_decl),
+            transformed_self_ty: transformed_self_ty,
+            fty: fty,
             self_ty: m_self_ty.node,
             // assume public, because this is only invoked on trait methods
             vis: ast::public,
@@ -607,6 +610,7 @@ pub struct ConvertedMethod {
 pub fn convert_methods(ccx: &CrateCtxt,
                        ms: &[@ast::method],
                        rp: Option<ty::region_variance>,
+                       untransformed_rcvr_ty: ty::t,
                        rcvr_bounds: @~[ty::param_bounds],
                        rcvr_generics: &ast::Generics,
                        rcvr_visibility: ast::visibility)
@@ -615,8 +619,9 @@ pub fn convert_methods(ccx: &CrateCtxt,
     let tcx = ccx.tcx;
     return vec::map(ms, |m| {
         let bounds = ty_param_bounds(ccx, &m.generics);
-        let mty = @ty_of_method(ccx, *m, rp, rcvr_generics,
-                                rcvr_visibility, &m.generics);
+        let mty = @ty_of_method(
+            ccx, *m, rp, untransformed_rcvr_ty,
+            rcvr_generics, rcvr_visibility, &m.generics);
         let fty = ty::mk_bare_fn(tcx, copy mty.fty);
         tcx.tcache.insert(
             local_def(m.id),
@@ -637,6 +642,7 @@ pub fn convert_methods(ccx: &CrateCtxt,
     fn ty_of_method(ccx: &CrateCtxt,
                     m: @ast::method,
                     rp: Option<ty::region_variance>,
+                    untransformed_rcvr_ty: ty::t,
                     rcvr_generics: &ast::Generics,
                     rcvr_visibility: ast::visibility,
                     method_generics: &ast::Generics) -> ty::method
@@ -644,15 +650,16 @@ pub fn convert_methods(ccx: &CrateCtxt,
         let rscope = MethodRscope::new(m.self_ty.node,
                                        rp,
                                        rcvr_generics);
+        let (transformed_self_ty, fty) =
+            astconv::ty_of_method(ccx, &rscope, m.purity,
+                                  &method_generics.lifetimes,
+                                  untransformed_rcvr_ty,
+                                  m.self_ty, &m.decl);
         ty::method {
             ident: m.ident,
             tps: ty_param_bounds(ccx, &m.generics),
-            fty: astconv::ty_of_bare_fn(ccx,
-                                        &rscope,
-                                        m.purity,
-                                        ast::RustAbi,
-                                        &method_generics.lifetimes,
-                                        &m.decl),
+            transformed_self_ty: transformed_self_ty,
+            fty: fty,
             self_ty: m.self_ty.node,
             vis: m.vis.inherit_from(rcvr_visibility),
             def_id: local_def(m.id)
@@ -715,7 +722,7 @@ pub fn convert(ccx: &CrateCtxt, it: @ast::item) {
             it.vis
         };
 
-        let cms = convert_methods(ccx, *ms, rp, i_bounds, generics,
+        let cms = convert_methods(ccx, *ms, rp, selfty, i_bounds, generics,
                                   parent_visibility);
         for opt_trait_ref.each |t| {
             check_methods_against_trait(ccx, generics, rp, selfty, *t, cms);
@@ -732,7 +739,9 @@ pub fn convert(ccx: &CrateCtxt, it: @ast::item) {
         let (_, provided_methods) =
             split_trait_methods(*trait_methods);
         let (bounds, _) = mk_substs(ccx, generics, rp);
-        let _ = convert_methods(ccx, provided_methods, rp, bounds, generics,
+        let untransformed_rcvr_ty = ty::mk_self(tcx, local_def(it.id));
+        let _ = convert_methods(ccx, provided_methods, rp,
+                                untransformed_rcvr_ty, bounds, generics,
                                 it.vis);
       }
       ast::item_struct(struct_def, ref generics) => {
diff --git a/src/test/run-pass/regions-expl-self.rs b/src/test/run-pass/regions-expl-self.rs
index 05f0994c765..174b9a206cc 100644
--- a/src/test/run-pass/regions-expl-self.rs
+++ b/src/test/run-pass/regions-expl-self.rs
@@ -15,7 +15,7 @@ struct Foo {
 }
 
 pub impl Foo {
-    fn foo(&'a self) {}
+    fn foo<'a>(&'a self) {}
 }
 
 pub fn main() {}
\ No newline at end of file