about summary refs log tree commit diff
path: root/src/rustc/middle/astencode.rs
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-09-11 21:25:01 -0700
committerNiko Matsakis <niko@alum.mit.edu>2012-09-11 21:25:01 -0700
commit8a8f200d102294cf1bd90cdacad995abccda7934 (patch)
tree31e99a460697349c403fc5cf4809427303e14804 /src/rustc/middle/astencode.rs
parent02b41097e42082a306ca6dbbd79ee9a1d7d35348 (diff)
downloadrust-8a8f200d102294cf1bd90cdacad995abccda7934.tar.gz
rust-8a8f200d102294cf1bd90cdacad995abccda7934.zip
Introduce auto adjustment table to subsume autoderef/autoref/borrowings.
Fixes #3261
Fixes #3443
Diffstat (limited to 'src/rustc/middle/astencode.rs')
-rw-r--r--src/rustc/middle/astencode.rs142
1 files changed, 109 insertions, 33 deletions
diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs
index 85e4a5f2e18..3172704c971 100644
--- a/src/rustc/middle/astencode.rs
+++ b/src/rustc/middle/astencode.rs
@@ -18,10 +18,8 @@ use std::serialization::DeserializerHelpers;
 use std::prettyprint::Serializer;
 use middle::{ty, typeck};
 use middle::typeck::{method_origin, method_map_entry,
-                        serialize_method_map_entry,
-                        deserialize_method_map_entry,
-                        vtable_res,
-                        vtable_origin};
+                     vtable_res,
+                     vtable_origin};
 use driver::session::session;
 use middle::freevars::{freevar_entry,
                           serialize_freevar_entry,
@@ -386,6 +384,45 @@ impl ast::def: tr {
 }
 
 // ______________________________________________________________________
+// Encoding and decoding of adjustment information
+
+impl ty::AutoAdjustment: tr {
+    fn tr(xcx: extended_decode_ctxt) -> ty::AutoAdjustment {
+        {autoderefs: self.autoderefs,
+         autoref: self.autoref.map(|ar| ar.tr(xcx))}
+    }
+}
+
+impl ty::AutoRef: tr {
+    fn tr(xcx: extended_decode_ctxt) -> ty::AutoRef {
+        {kind: self.kind,
+         region: self.region.tr(xcx),
+         mutbl: self.mutbl}
+    }
+}
+
+impl ty::region: tr {
+    fn tr(xcx: extended_decode_ctxt) -> ty::region {
+        match self {
+            ty::re_bound(br) => ty::re_bound(br.tr(xcx)),
+            ty::re_free(id, br) => ty::re_free(xcx.tr_id(id), br.tr(xcx)),
+            ty::re_scope(id) => ty::re_scope(xcx.tr_id(id)),
+            ty::re_static | ty::re_var(*) => self,
+        }
+    }
+}
+
+impl ty::bound_region: tr {
+    fn tr(xcx: extended_decode_ctxt) -> ty::bound_region {
+        match self {
+            ty::br_anon(_) | ty::br_named(_) | ty::br_self => self,
+            ty::br_cap_avoid(id, br) => ty::br_cap_avoid(xcx.tr_id(id),
+                                                         @br.tr(xcx))
+        }
+    }
+}
+
+// ______________________________________________________________________
 // Encoding and decoding of freevar information
 
 fn encode_freevar_entry(ebml_w: ebml::Writer, fv: freevar_entry) {
@@ -416,12 +453,31 @@ trait read_method_map_entry_helper {
     fn read_method_map_entry(xcx: extended_decode_ctxt) -> method_map_entry;
 }
 
+fn serialize_method_map_entry(ecx: @e::encode_ctxt,
+                              ebml_w: ebml::Writer,
+                              mme: method_map_entry) {
+    do ebml_w.emit_rec {
+        do ebml_w.emit_rec_field(~"self_arg", 0u) {
+            ebml_w.emit_arg(ecx, mme.self_arg);
+        }
+        do ebml_w.emit_rec_field(~"origin", 1u) {
+            typeck::serialize_method_origin(ebml_w, mme.origin);
+        }
+    }
+}
+
 impl ebml::EbmlDeserializer: read_method_map_entry_helper {
     fn read_method_map_entry(xcx: extended_decode_ctxt) -> method_map_entry {
-        let mme = deserialize_method_map_entry(self);
-        {derefs: mme.derefs,
-         self_mode: mme.self_mode,
-         origin: mme.origin.tr(xcx)}
+        do self.read_rec {
+            {self_arg:
+                 self.read_rec_field(~"self_arg", 0u, || {
+                     self.read_arg(xcx)
+                 }),
+             origin:
+                 self.read_rec_field(~"origin", 1u, || {
+                     typeck::deserialize_method_origin(self).tr(xcx)
+                 })}
+        }
     }
 }
 
@@ -445,8 +501,8 @@ impl method_origin: tr {
 // Encoding and decoding vtable_res
 
 fn encode_vtable_res(ecx: @e::encode_ctxt,
-                   ebml_w: ebml::Writer,
-                   dr: typeck::vtable_res) {
+                     ebml_w: ebml::Writer,
+                     dr: typeck::vtable_res) {
     // can't autogenerate this code because automatic serialization of
     // ty::t doesn't work, and there is no way (atm) to have
     // hand-written serialization routines combine with auto-generated
@@ -573,6 +629,7 @@ impl @e::encode_ctxt: get_ty_str_ctxt {
 }
 
 trait ebml_writer_helpers {
+    fn emit_arg(ecx: @e::encode_ctxt, arg: ty::arg);
     fn emit_ty(ecx: @e::encode_ctxt, ty: ty::t);
     fn emit_tys(ecx: @e::encode_ctxt, tys: ~[ty::t]);
     fn emit_bounds(ecx: @e::encode_ctxt, bs: ty::param_bounds);
@@ -581,17 +638,27 @@ trait ebml_writer_helpers {
 
 impl ebml::Writer: ebml_writer_helpers {
     fn emit_ty(ecx: @e::encode_ctxt, ty: ty::t) {
-        e::write_type(ecx, self, ty)
+        do self.emit_opaque {
+            e::write_type(ecx, self, ty)
+        }
+    }
+
+    fn emit_arg(ecx: @e::encode_ctxt, arg: ty::arg) {
+        do self.emit_opaque {
+            tyencode::enc_arg(self.writer, ecx.ty_str_ctxt(), arg);
+        }
     }
 
     fn emit_tys(ecx: @e::encode_ctxt, tys: ~[ty::t]) {
         do self.emit_from_vec(tys) |ty| {
-            e::write_type(ecx, self, ty)
+            self.emit_ty(ecx, ty)
         }
     }
 
     fn emit_bounds(ecx: @e::encode_ctxt, bs: ty::param_bounds) {
-        tyencode::enc_bounds(self.writer, ecx.ty_str_ctxt(), bs)
+        do self.emit_opaque {
+            tyencode::enc_bounds(self.writer, ecx.ty_str_ctxt(), bs)
+        }
     }
 
     fn emit_tpbt(ecx: @e::encode_ctxt, tpbt: ty::ty_param_bounds_and_ty) {
@@ -664,7 +731,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
         do ebml_w.tag(c::tag_table_node_type) {
             ebml_w.id(id);
             do ebml_w.tag(c::tag_table_val) {
-                e::write_type(ecx, ebml_w, ty)
+                ebml_w.emit_ty(ecx, ty);
             }
         }
     }
@@ -743,7 +810,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
         do ebml_w.tag(c::tag_table_method_map) {
             ebml_w.id(id);
             do ebml_w.tag(c::tag_table_val) {
-                serialize_method_map_entry(ebml_w, mme)
+                serialize_method_map_entry(ecx, ebml_w, mme)
             }
         }
     }
@@ -757,13 +824,11 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
         }
     }
 
-    do option::iter(tcx.borrowings.find(id)) |_borrow| {
-        do ebml_w.tag(c::tag_table_borrowings) {
+    do option::iter(tcx.adjustments.find(id)) |adj| {
+        do ebml_w.tag(c::tag_table_adjustments) {
             ebml_w.id(id);
             do ebml_w.tag(c::tag_table_val) {
-                // N.B. We don't actually serialize borrows as, in
-                // trans, we only care whether a value is borrowed or
-                // not.
+                ty::serialize_AutoAdjustment(ebml_w, *adj)
             }
         }
     }
@@ -782,6 +847,7 @@ impl ebml::Doc: doc_decoder_helpers {
 }
 
 trait ebml_deserializer_decoder_helpers {
+    fn read_arg(xcx: extended_decode_ctxt) -> ty::arg;
     fn read_ty(xcx: extended_decode_ctxt) -> ty::t;
     fn read_tys(xcx: extended_decode_ctxt) -> ~[ty::t];
     fn read_bounds(xcx: extended_decode_ctxt) -> @~[ty::param_bound];
@@ -791,15 +857,25 @@ trait ebml_deserializer_decoder_helpers {
 
 impl ebml::EbmlDeserializer: ebml_deserializer_decoder_helpers {
 
+    fn read_arg(xcx: extended_decode_ctxt) -> ty::arg {
+        do self.read_opaque |doc| {
+            tydecode::parse_arg_data(
+                doc.data, xcx.dcx.cdata.cnum, doc.start, xcx.dcx.tcx,
+                |a| xcx.tr_def_id(a))
+        }
+    }
+
     fn read_ty(xcx: extended_decode_ctxt) -> ty::t {
         // Note: regions types embed local node ids.  In principle, we
         // should translate these node ids into the new decode
         // context.  However, we do not bother, because region types
         // are not used during trans.
 
-        tydecode::parse_ty_data(
-            self.parent.data, xcx.dcx.cdata.cnum, self.pos, xcx.dcx.tcx,
-            |a| xcx.tr_def_id(a) )
+        do self.read_opaque |doc| {
+            tydecode::parse_ty_data(
+                doc.data, xcx.dcx.cdata.cnum, doc.start, xcx.dcx.tcx,
+                |a| xcx.tr_def_id(a))
+        }
     }
 
     fn read_tys(xcx: extended_decode_ctxt) -> ~[ty::t] {
@@ -807,13 +883,16 @@ impl ebml::EbmlDeserializer: ebml_deserializer_decoder_helpers {
     }
 
     fn read_bounds(xcx: extended_decode_ctxt) -> @~[ty::param_bound] {
-        tydecode::parse_bounds_data(
-            self.parent.data, self.pos, xcx.dcx.cdata.cnum, xcx.dcx.tcx,
-            |a| xcx.tr_def_id(a) )
+        do self.read_opaque |doc| {
+            tydecode::parse_bounds_data(
+                doc.data, doc.start, xcx.dcx.cdata.cnum, xcx.dcx.tcx,
+                |a| xcx.tr_def_id(a))
+        }
     }
 
     fn read_ty_param_bounds_and_ty(xcx: extended_decode_ctxt)
-        -> ty::ty_param_bounds_and_ty {
+        -> ty::ty_param_bounds_and_ty
+    {
         do self.read_rec {
             {
                 bounds: self.read_rec_field(~"bounds", 0u, || {
@@ -881,12 +960,9 @@ fn decode_side_tables(xcx: extended_decode_ctxt,
             } else if tag == (c::tag_table_vtable_map as uint) {
                 dcx.maps.vtable_map.insert(id,
                                            val_dsr.read_vtable_res(xcx));
-            } else if tag == (c::tag_table_borrowings as uint) {
-                // N.B.: we don't actually *serialize* borrows because, in
-                // trans, the only thing we care about is whether a value was
-                // borrowed or not.
-                let borrow = {region: ty::re_static, mutbl: ast::m_imm};
-                dcx.tcx.borrowings.insert(id, borrow);
+            } else if tag == (c::tag_table_adjustments as uint) {
+                let adj = @ty::deserialize_AutoAdjustment(val_dsr).tr(xcx);
+                dcx.tcx.adjustments.insert(id, adj);
             } else {
                 xcx.dcx.tcx.sess.bug(
                     fmt!("unknown tag found in side tables: %x", tag));