]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #30663 - apasel422:ll, r=bluss
authorbors <bors@rust-lang.org>
Fri, 1 Jan 2016 13:51:38 +0000 (13:51 +0000)
committerbors <bors@rust-lang.org>
Fri, 1 Jan 2016 13:51:38 +0000 (13:51 +0000)
CC #30642

r? @Gankro

25 files changed:
mk/platform.mk
src/etc/apple-darwin.supp
src/etc/x86.supp
src/librbml/leb128.rs [new file with mode: 0644]
src/librbml/lib.rs
src/librbml/opaque.rs [new file with mode: 0644]
src/librustc/diagnostics.rs
src/librustc/middle/cstore.rs
src/librustc_metadata/astencode.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/tls_context.rs
src/librustc_metadata/tydecode.rs
src/librustc_metadata/tyencode.rs
src/librustc_mir/build/mod.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/consts.rs
src/librustc_trans/trans/mir/constant.rs
src/libstd/ffi/c_str.rs
src/libstd/io/mod.rs
src/libstd/io/stdio.rs
src/libstd/sys/unix/ext/io.rs
src/libsyntax/codemap.rs
src/test/run-pass-valgrind/exit-flushes.rs
src/test/run-pass/mir_refs_correct.rs

index 04cab379de3c73e0f56062584b45a76384ced1c1..5239086a6552ca26739e280736c4e0e3b37f6cd1 100644 (file)
@@ -64,14 +64,18 @@ define DEF_GOOD_VALGRIND
   ifeq ($(OSTYPE_$(1)),unknown-linux-gnu)
     GOOD_VALGRIND_$(1) = 1
   endif
-  ifneq (,$(filter $(OSTYPE_$(1)),darwin freebsd))
-    ifeq (HOST_$(1),x86_64)
+  ifneq (,$(filter $(OSTYPE_$(1)),apple-darwin freebsd))
+    ifeq ($(HOST_$(1)),x86_64)
       GOOD_VALGRIND_$(1) = 1
     endif
   endif
+  ifdef GOOD_VALGRIND_$(t)
+    $$(info cfg: have good valgrind for $(t))
+  else
+    $$(info cfg: no good valgrind for $(t))
+  endif
 endef
 $(foreach t,$(CFG_TARGET),$(eval $(call DEF_GOOD_VALGRIND,$(t))))
-$(foreach t,$(CFG_TARGET),$(info cfg: good valgrind for $(t) is $(GOOD_VALGRIND_$(t))))
 
 ifneq ($(findstring linux,$(CFG_OSTYPE)),)
   ifdef CFG_PERF
index 866578930a3d8dca0f83d6ce285bc32e0913914d..50e30caa2b34b0fa58700b81091da0fe28185b93 100644 (file)
@@ -1,17 +1,11 @@
 {
    osx-frameworks.rs-fails-otherwise-1
    Memcheck:Leak
-   match-leak-kinds: possible
+   match-leak-kinds: definite,possible
    fun:malloc
    ...
    fun:__CFInitialize
-   fun:_ZN16ImageLoaderMachO11doImageInitERKN11ImageLoader11LinkContextE
-   fun:_ZN16ImageLoaderMachO16doInitializationERKN11ImageLoader11LinkContextE
-   fun:_ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE
-   fun:_ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE
-   fun:_ZN11ImageLoader19processInitializersERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE
-   fun:_ZN11ImageLoader15runInitializersERKNS_11LinkContextERNS_21InitializerTimingListE
-   fun:_ZN4dyld24initializeMainExecutableEv
+   ...
 }
 
 {
    ...
    fun:__CFInitialize
    fun:_ZN16ImageLoaderMachO11doImageInitERKN11ImageLoader11LinkContextE
-   fun:_ZN16ImageLoaderMachO16doInitializationERKN11ImageLoader11LinkContextE
-   fun:_ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE
-   fun:_ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE
-   fun:_ZN11ImageLoader19processInitializersERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE
 }
 
 {
    Memcheck:Leak
    match-leak-kinds: possible
    fun:realloc
-   fun:_ZL12realizeClassP10objc_class
-   fun:_ZL12realizeClassP10objc_class
-   fun:_ZN13list_array_ttIm15protocol_list_tE11attachListsEPKPS0_j
+   ...
    fun:_read_images
    fun:map_images_nolock
-   fun:map_2_images
+   ...
    fun:_ZN4dyldL18notifyBatchPartialE17dyld_image_statesbPFPKcS0_jPK15dyld_image_infoE
    fun:_ZN4dyld36registerImageStateBatchChangeHandlerE17dyld_image_statesPFPKcS0_jPK15dyld_image_infoE
    fun:dyld_register_image_state_change_handler
@@ -49,7 +37,7 @@
 {
    osx-frameworks.rs-fails-otherwise-4
    Memcheck:Leak
-   match-leak-kinds: possible
+   match-leak-kinds: definite,possible
    fun:calloc
    ...
    fun:__CFInitialize
 {
    osx-frameworks.rs-fails-otherwise-5
    Memcheck:Leak
-   match-leak-kinds: definite
-   fun:calloc
+   match-leak-kinds: definite,possible
+   fun:malloc_zone_malloc
    ...
    fun:__CFInitialize
-   fun:_ZN16ImageLoaderMachO11doImageInitERKN11ImageLoader11LinkContextE
-   fun:_ZN16ImageLoaderMachO16doInitializationERKN11ImageLoader11LinkContextE
-   fun:_ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE
-}
-
-{
-   osx-frameworks.rs-fails-otherwise-6
-   Memcheck:Leak
-   match-leak-kinds: definite
-   fun:malloc
-   fun:strdup
-   fun:_CFProcessPath
-   fun:__CFInitialize
-   fun:_ZN16ImageLoaderMachO11doImageInitERKN11ImageLoader11LinkContextE
-   fun:_ZN16ImageLoaderMachO16doInitializationERKN11ImageLoader11LinkContextE
-   fun:_ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE
-   fun:_ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE
-   fun:_ZN11ImageLoader19processInitializersERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE
-   fun:_ZN11ImageLoader15runInitializersERKNS_11LinkContextERNS_21InitializerTimingListE
-   fun:_ZN4dyld24initializeMainExecutableEv
-   fun:_ZN4dyld5_mainEPK12macho_headermiPPKcS5_S5_Pm
+   ...
 }
 
 {
-   osx-frameworks.rs-fails-otherwise-7
+   fails-since-xcode-7.2
    Memcheck:Leak
-   match-leak-kinds: definite
+   match-leak-kinds: possible
    fun:malloc_zone_malloc
-   ...
-   fun:__CFInitialize
-   fun:_ZN16ImageLoaderMachO11doImageInitERKN11ImageLoader11LinkContextE
-   fun:_ZN16ImageLoaderMachO16doInitializationERKN11ImageLoader11LinkContextE
-   fun:_ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE
-   fun:_ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE
-   fun:_ZN11ImageLoader19processInitializersERKNS_11LinkContextEjRNS_21InitializerTimingListERNS_15UninitedUpwardsE
-   fun:_ZN11ImageLoader15runInitializersERKNS_11LinkContextERNS_21InitializerTimingListE
-   fun:_ZN4dyld24initializeMainExecutableEv
+   fun:_objc_copyClassNamesForImage
+   fun:_ZL9protocolsv
+   fun:_Z9readClassP10objc_classbb
+   fun:gc_init
+   fun:_ZL33objc_initializeClassPair_internalP10objc_classPKcS0_S0_
+   fun:layout_string_create
+   fun:_ZL12realizeClassP10objc_class
+   fun:_ZL22copySwiftV1MangledNamePKcb
+   fun:_ZL22copySwiftV1MangledNamePKcb
+   fun:_ZL22copySwiftV1MangledNamePKcb
+   fun:_ZL22copySwiftV1MangledNamePKcb
 }
index e4368da90331f3ab3732d7e0253eb6d0c79d1151..6e409af79aecfe48f4c49bcd8cc97ae1dbb110b6 100644 (file)
@@ -12,7 +12,7 @@
    fun:tlv_finalize
    fun:_pthread_tsd_cleanup
    fun:_pthread_exit
-   fun:_pthread_body
+   ...
    fun:_pthread_start
    fun:thread_start
 }
@@ -24,7 +24,7 @@
    fun:tlv_finalize
    fun:_pthread_tsd_cleanup
    fun:_pthread_exit
-   fun:_pthread_body
+   ...
    fun:_pthread_start
    fun:thread_start
 }
@@ -36,7 +36,7 @@
    fun:tlv_finalize
    fun:_pthread_tsd_cleanup
    fun:_pthread_exit
-   fun:_pthread_body
+   ...
    fun:_pthread_start
    fun:thread_start
 }
@@ -48,7 +48,7 @@
    fun:tlv_finalize
    fun:_pthread_tsd_cleanup
    fun:_pthread_exit
-   fun:_pthread_body
+   ...
    fun:_pthread_start
    fun:thread_start
 }
diff --git a/src/librbml/leb128.rs b/src/librbml/leb128.rs
new file mode 100644 (file)
index 0000000..a5e8522
--- /dev/null
@@ -0,0 +1,162 @@
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[inline]
+pub fn write_to_vec(vec: &mut Vec<u8>, position: &mut usize, byte: u8)
+{
+    if *position == vec.len() {
+        vec.push(byte);
+    } else {
+        vec[*position] = byte;
+    }
+
+    *position += 1;
+}
+
+pub fn write_unsigned_leb128(out: &mut Vec<u8>,
+                             start_position: usize,
+                             mut value: u64)
+                             -> usize {
+    let mut position = start_position;
+    loop
+    {
+        let mut byte = (value & 0x7F) as u8;
+        value >>= 7;
+        if value != 0 {
+            byte |= 0x80;
+        }
+
+        write_to_vec(out, &mut position, byte);
+
+        if value == 0 {
+            break;
+        }
+    }
+
+    return position - start_position;
+}
+
+pub fn read_unsigned_leb128(data: &[u8],
+                            start_position: usize)
+                            -> (u64, usize) {
+    let mut result = 0;
+    let mut shift = 0;
+    let mut position = start_position;
+    loop {
+        let byte = data[position];
+        position += 1;
+        result |= ((byte & 0x7F) as u64) << shift;
+        if (byte & 0x80) == 0 {
+            break;
+        }
+        shift += 7;
+    }
+
+    (result, position - start_position)
+}
+
+
+pub fn write_signed_leb128(out: &mut Vec<u8>,
+                           start_position: usize,
+                           mut value: i64) -> usize {
+    let mut position = start_position;
+
+    loop {
+        let mut byte = (value as u8) & 0x7f;
+        value >>= 7;
+        let more = !((((value == 0 ) && ((byte & 0x40) == 0)) ||
+                      ((value == -1) && ((byte & 0x40) != 0))));
+        if more {
+            byte |= 0x80; // Mark this byte to show that more bytes will follow.
+        }
+
+        write_to_vec(out, &mut position, byte);
+
+        if !more {
+            break;
+        }
+    }
+
+    return position - start_position;
+}
+
+pub fn read_signed_leb128(data: &[u8],
+                          start_position: usize)
+                          -> (i64, usize) {
+    let mut result = 0;
+    let mut shift = 0;
+    let mut position = start_position;
+    let mut byte;
+
+    loop {
+        byte = data[position];
+        position += 1;
+        result |= ((byte & 0x7F) as i64) << shift;
+        shift += 7;
+
+        if (byte & 0x80) == 0 {
+            break;
+        }
+    }
+
+    if (shift < 64) && ((byte & 0x40) != 0) {
+        /* sign extend */
+        result |= -(1i64 << shift);
+    }
+
+    (result, position - start_position)
+}
+
+#[test]
+fn test_unsigned_leb128() {
+    let mut stream = Vec::with_capacity(10000);
+
+    for x in 0..62 {
+        let pos = stream.len();
+        let bytes_written = write_unsigned_leb128(&mut stream, pos, 3 << x);
+        assert_eq!(stream.len(), pos + bytes_written);
+    }
+
+    let mut position = 0;
+    for x in 0..62 {
+        let expected = 3 << x;
+        let (actual, bytes_read) = read_unsigned_leb128(&stream, position);
+        assert_eq!(expected, actual);
+        position += bytes_read;
+    }
+    assert_eq!(stream.len(), position);
+}
+
+#[test]
+fn test_signed_leb128() {
+    let mut values = Vec::new();
+
+    let mut i = -500;
+    while i < 500 {
+        values.push(i * 123457i64);
+        i += 1;
+    }
+
+    let mut stream = Vec::new();
+
+    for &x in &values {
+        let pos = stream.len();
+        let bytes_written = write_signed_leb128(&mut stream, pos, x);
+        assert_eq!(stream.len(), pos + bytes_written);
+    }
+
+    let mut pos = 0;
+    for &x in &values {
+        let (value, bytes_read) = read_signed_leb128(&mut stream, pos);
+        pos += bytes_read;
+        assert_eq!(x, value);
+    }
+    assert_eq!(pos, stream.len());
+}
index d8d6ea93f7569f1b2ff1112072f191602ed203c2..f3a1bbd7e26b832bd73e9aa8c9a0febaa5f44e07 100644 (file)
 #![cfg_attr(test, feature(test))]
 
 extern crate serialize;
+
+#[cfg(test)]
+extern crate serialize as rustc_serialize; // Used by RustcEncodable
+
 #[macro_use] extern crate log;
 
 #[cfg(test)] extern crate test;
 
+pub mod opaque;
+pub mod leb128;
+
 pub use self::EbmlEncoderTag::*;
 pub use self::Error::*;
 
@@ -241,6 +248,7 @@ pub mod reader {
 
     use serialize;
 
+    use super::opaque;
     use super::{ ApplicationError, EsVec, EsMap, EsEnum, EsSub8, EsSub32,
         EsVecElt, EsMapKey, EsU64, EsU32, EsU16, EsU8, EsI64,
         EsI32, EsI16, EsI8, EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
@@ -621,18 +629,16 @@ fn _next_int(&mut self,
         }
 
         pub fn read_opaque<R, F>(&mut self, op: F) -> DecodeResult<R> where
-            F: FnOnce(&mut Decoder, Doc) -> DecodeResult<R>,
+            F: FnOnce(&mut opaque::Decoder, Doc) -> DecodeResult<R>,
         {
             let doc = try!(self.next_doc(EsOpaque));
 
-            let (old_parent, old_pos) = (self.parent, self.pos);
-            self.parent = doc;
-            self.pos = doc.start;
-
-            let result = try!(op(self, doc));
+            let result = {
+                let mut opaque_decoder = opaque::Decoder::new(doc.data,
+                                                              doc.start);
+                try!(op(&mut opaque_decoder, doc))
+            };
 
-            self.parent = old_parent;
-            self.pos = old_pos;
             Ok(result)
         }
 
@@ -877,6 +883,7 @@ pub mod writer {
     use std::io::prelude::*;
     use std::io::{self, SeekFrom, Cursor};
 
+    use super::opaque;
     use super::{ EsVec, EsMap, EsEnum, EsSub8, EsSub32, EsVecElt, EsMapKey,
         EsU64, EsU32, EsU16, EsU8, EsI64, EsI32, EsI16, EsI8,
         EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
@@ -1120,10 +1127,16 @@ fn _emit_tagged_sub(&mut self, v: usize) -> EncodeResult {
         }
 
         pub fn emit_opaque<F>(&mut self, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder) -> EncodeResult,
+            F: FnOnce(&mut opaque::Encoder) -> EncodeResult,
         {
             try!(self.start_tag(EsOpaque as usize));
-            try!(f(self));
+
+            {
+                let mut opaque_encoder = opaque::Encoder::new(self.writer);
+                try!(f(&mut opaque_encoder));
+            }
+
+            self.mark_stable_position();
             self.end_tag()
         }
     }
diff --git a/src/librbml/opaque.rs b/src/librbml/opaque.rs
new file mode 100644 (file)
index 0000000..6475609
--- /dev/null
@@ -0,0 +1,811 @@
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use Error as DecodeError;
+use writer::EncodeResult;
+use leb128::{read_signed_leb128, read_unsigned_leb128, write_signed_leb128,
+             write_unsigned_leb128};
+use std::io::{self, Write};
+use serialize;
+
+//=-----------------------------------------------------------------------------
+// Encoder
+//=-----------------------------------------------------------------------------
+
+pub struct Encoder<'a> {
+    pub cursor: &'a mut io::Cursor<Vec<u8>>,
+}
+
+impl<'a> Encoder<'a> {
+    pub fn new(cursor: &'a mut io::Cursor<Vec<u8>>) -> Encoder<'a> {
+        Encoder {
+            cursor: cursor
+        }
+    }
+}
+
+
+macro_rules! write_uleb128 {
+    ($enc:expr, $value:expr) => {{
+        let pos = $enc.cursor.position() as usize;
+        let bytes_written = write_unsigned_leb128($enc.cursor.get_mut(), pos, $value as u64);
+        $enc.cursor.set_position((pos + bytes_written) as u64);
+        Ok(())
+    }}
+}
+
+macro_rules! write_sleb128 {
+    ($enc:expr, $value:expr) => {{
+        let pos = $enc.cursor.position() as usize;
+        let bytes_written = write_signed_leb128($enc.cursor.get_mut(), pos, $value as i64);
+        $enc.cursor.set_position((pos + bytes_written) as u64);
+        Ok(())
+    }}
+}
+
+impl<'a> serialize::Encoder for Encoder<'a> {
+    type Error = io::Error;
+
+    fn emit_nil(&mut self) -> EncodeResult {
+        Ok(())
+    }
+
+    fn emit_uint(&mut self, v: usize) -> EncodeResult {
+        write_uleb128!(self, v)
+    }
+
+    fn emit_u64(&mut self, v: u64) -> EncodeResult {
+        write_uleb128!(self, v)
+    }
+
+    fn emit_u32(&mut self, v: u32) -> EncodeResult {
+        write_uleb128!(self, v)
+    }
+
+    fn emit_u16(&mut self, v: u16) -> EncodeResult {
+        write_uleb128!(self, v)
+    }
+
+    fn emit_u8(&mut self, v: u8) -> EncodeResult {
+        let _ = self.cursor.write_all(&[v]);
+        Ok(())
+    }
+
+    fn emit_int(&mut self, v: isize) -> EncodeResult {
+        write_sleb128!(self, v)
+    }
+
+    fn emit_i64(&mut self, v: i64) -> EncodeResult {
+        write_sleb128!(self, v)
+    }
+
+    fn emit_i32(&mut self, v: i32) -> EncodeResult {
+        write_sleb128!(self, v)
+    }
+
+    fn emit_i16(&mut self, v: i16) -> EncodeResult {
+        write_sleb128!(self, v)
+    }
+
+    fn emit_i8(&mut self, v: i8) -> EncodeResult {
+        let as_u8: u8 = unsafe { ::std::mem::transmute(v) };
+        let _ = self.cursor.write_all(&[as_u8]);
+        Ok(())
+    }
+
+    fn emit_bool(&mut self, v: bool) -> EncodeResult {
+        self.emit_u8(if v { 1 } else { 0 })
+    }
+
+    fn emit_f64(&mut self, v: f64) -> EncodeResult {
+        let as_u64: u64 = unsafe { ::std::mem::transmute(v) };
+        self.emit_u64(as_u64)
+    }
+
+    fn emit_f32(&mut self, v: f32) -> EncodeResult {
+        let as_u32: u32 = unsafe { ::std::mem::transmute(v) };
+        self.emit_u32(as_u32)
+    }
+
+    fn emit_char(&mut self, v: char) -> EncodeResult {
+        self.emit_u32(v as u32)
+    }
+
+    fn emit_str(&mut self, v: &str) -> EncodeResult {
+        try!(self.emit_uint(v.len()));
+        let _ = self.cursor.write_all(v.as_bytes());
+        Ok(())
+    }
+
+    fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult
+        where F: FnOnce(&mut Self) -> EncodeResult {
+        f(self)
+    }
+
+    fn emit_enum_variant<F>(&mut self,
+                            _v_name: &str,
+                            v_id: usize,
+                            _len: usize,
+                            f: F) -> EncodeResult
+        where F: FnOnce(&mut Self) -> EncodeResult
+    {
+        try!(self.emit_uint(v_id));
+        f(self)
+    }
+
+    fn emit_enum_variant_arg<F>(&mut self, _: usize, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        f(self)
+    }
+
+    fn emit_enum_struct_variant<F>(&mut self,
+                                       v_name: &str,
+                                       v_id: usize,
+                                       cnt: usize,
+                                       f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        self.emit_enum_variant(v_name, v_id, cnt, f)
+    }
+
+    fn emit_enum_struct_variant_field<F>(&mut self,
+                                         _: &str,
+                                         idx: usize,
+                                         f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        self.emit_enum_variant_arg(idx, f)
+    }
+
+    fn emit_struct<F>(&mut self, _: &str, _len: usize, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        f(self)
+    }
+
+    fn emit_struct_field<F>(&mut self, _name: &str, _: usize, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        f(self)
+    }
+
+    fn emit_tuple<F>(&mut self, len: usize, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        self.emit_seq(len, f)
+    }
+
+    fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        self.emit_seq_elt(idx, f)
+    }
+
+    fn emit_tuple_struct<F>(&mut self, _: &str, len: usize, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        self.emit_seq(len, f)
+    }
+
+    fn emit_tuple_struct_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        self.emit_seq_elt(idx, f)
+    }
+
+    fn emit_option<F>(&mut self, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        self.emit_enum("Option", f)
+    }
+
+    fn emit_option_none(&mut self) -> EncodeResult {
+        self.emit_enum_variant("None", 0, 0, |_| Ok(()))
+    }
+
+    fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        self.emit_enum_variant("Some", 1, 1, f)
+    }
+
+    fn emit_seq<F>(&mut self, len: usize, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        try!(self.emit_uint(len));
+        f(self)
+    }
+
+    fn emit_seq_elt<F>(&mut self, _idx: usize, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        f(self)
+    }
+
+    fn emit_map<F>(&mut self, len: usize, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        try!(self.emit_uint(len));
+        f(self)
+    }
+
+    fn emit_map_elt_key<F>(&mut self, _idx: usize, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        f(self)
+    }
+
+    fn emit_map_elt_val<F>(&mut self, _idx: usize, f: F) -> EncodeResult where
+        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
+    {
+        f(self)
+    }
+}
+
+impl<'a> Encoder<'a> {
+    pub fn position(&self) -> usize {
+        self.cursor.position() as usize
+    }
+
+    pub fn from_rbml<'b: 'c, 'c>(rbml: &'c mut ::writer::Encoder<'b>) -> Encoder<'c> {
+        Encoder {
+            cursor: rbml.writer
+        }
+    }
+}
+
+//=-----------------------------------------------------------------------------
+// Decoder
+//=-----------------------------------------------------------------------------
+
+pub struct Decoder<'a> {
+    pub data: &'a [u8],
+    position: usize,
+}
+
+impl<'a> Decoder<'a> {
+    pub fn new(data: &'a [u8], position: usize) -> Decoder<'a> {
+        Decoder {
+            data: data,
+            position: position
+        }
+    }
+
+    pub fn position(&self) -> usize {
+        self.position
+    }
+
+    pub fn advance(&mut self, bytes: usize) {
+        self.position += bytes;
+    }
+}
+
+macro_rules! read_uleb128 {
+    ($dec:expr, $t:ty) => ({
+        let (value, bytes_read) = read_unsigned_leb128($dec.data, $dec.position);
+        $dec.position += bytes_read;
+        Ok(value as $t)
+    })
+}
+
+macro_rules! read_sleb128 {
+    ($dec:expr, $t:ty) => ({
+        let (value, bytes_read) = read_signed_leb128($dec.data, $dec.position);
+        $dec.position += bytes_read;
+        Ok(value as $t)
+    })
+}
+
+
+impl<'a> serialize::Decoder for Decoder<'a> {
+    type Error = DecodeError;
+
+    fn read_nil(&mut self) -> Result<(), Self::Error> {
+        Ok(())
+    }
+
+    fn read_u64(&mut self) -> Result<u64, Self::Error> {
+        read_uleb128!(self, u64)
+    }
+
+    fn read_u32(&mut self) -> Result<u32, Self::Error> {
+        read_uleb128!(self, u32)
+    }
+
+    fn read_u16(&mut self) -> Result<u16, Self::Error> {
+        read_uleb128!(self, u16)
+    }
+
+    fn read_u8(&mut self) -> Result<u8, Self::Error> {
+        let value = self.data[self.position];
+        self.position += 1;
+        Ok(value)
+    }
+
+    fn read_uint(&mut self) -> Result<usize, Self::Error> {
+        read_uleb128!(self, usize)
+    }
+
+    fn read_i64(&mut self) -> Result<i64, Self::Error> {
+        read_sleb128!(self, i64)
+    }
+
+    fn read_i32(&mut self) -> Result<i32, Self::Error> {
+        read_sleb128!(self, i32)
+    }
+
+    fn read_i16(&mut self) -> Result<i16, Self::Error> {
+        read_sleb128!(self, i16)
+    }
+
+    fn read_i8(&mut self) -> Result<i8, Self::Error> {
+        let as_u8 = self.data[self.position];
+        self.position += 1;
+        unsafe {
+            Ok(::std::mem::transmute(as_u8))
+        }
+    }
+
+    fn read_int(&mut self) -> Result<isize, Self::Error> {
+        read_sleb128!(self, isize)
+    }
+
+    fn read_bool(&mut self) -> Result<bool, Self::Error> {
+        let value = try!(self.read_u8());
+        Ok(value != 0)
+    }
+
+    fn read_f64(&mut self) -> Result<f64, Self::Error> {
+        let bits = try!(self.read_u64());
+        Ok(unsafe { ::std::mem::transmute(bits) })
+    }
+
+    fn read_f32(&mut self) -> Result<f32, Self::Error> {
+        let bits = try!(self.read_u32());
+        Ok(unsafe { ::std::mem::transmute(bits) })
+    }
+
+    fn read_char(&mut self) -> Result<char, Self::Error> {
+        let bits = try!(self.read_u32());
+        Ok(::std::char::from_u32(bits).unwrap())
+    }
+
+    fn read_str(&mut self) -> Result<String, Self::Error> {
+        let len = try!(self.read_uint());
+        let s = ::std::str::from_utf8(&self.data[self.position .. self.position + len]).unwrap();
+        self.position += len;
+        Ok(s.to_string())
+    }
+
+    fn read_enum<T, F>(&mut self, _name: &str, f: F) -> Result<T, Self::Error> where
+        F: FnOnce(&mut Decoder<'a>) -> Result<T, Self::Error>,
+    {
+        f(self)
+    }
+
+    fn read_enum_variant<T, F>(&mut self,
+                               _: &[&str],
+                               mut f: F)
+                               -> Result<T, Self::Error>
+        where F: FnMut(&mut Decoder<'a>, usize) -> Result<T, Self::Error>,
+    {
+        let disr = try!(self.read_uint());
+        f(self, disr)
+    }
+
+    fn read_enum_variant_arg<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Self::Error> where
+        F: FnOnce(&mut Decoder<'a>) -> Result<T, Self::Error>,
+    {
+        f(self)
+    }
+
+    fn read_enum_struct_variant<T, F>(&mut self,
+                                      _: &[&str],
+                                      mut f: F) -> Result<T, Self::Error>
+        where F: FnMut(&mut Decoder<'a>, usize) -> Result<T, Self::Error>,
+    {
+        let disr = try!(self.read_uint());
+        f(self, disr)
+    }
+
+    fn read_enum_struct_variant_field<T, F>(&mut self,
+                                            _name: &str,
+                                            _idx: usize,
+                                            f: F)
+                                            -> Result<T, Self::Error> where
+        F: FnOnce(&mut Decoder<'a>) -> Result<T, Self::Error>,
+    {
+        f(self)
+    }
+
+    fn read_struct<T, F>(&mut self, _name: &str, _: usize, f: F) -> Result<T, Self::Error> where
+        F: FnOnce(&mut Decoder<'a>) -> Result<T, Self::Error>,
+    {
+        f(self)
+    }
+
+    fn read_struct_field<T, F>(&mut self,
+                               _name: &str,
+                               _idx: usize, f: F)
+                               -> Result<T, Self::Error> where
+        F: FnOnce(&mut Decoder<'a>) -> Result<T, Self::Error>,
+    {
+        f(self)
+    }
+
+    fn read_tuple<T, F>(&mut self, tuple_len: usize, f: F) -> Result<T, Self::Error> where
+        F: FnOnce(&mut Decoder<'a>) -> Result<T, Self::Error>,
+    {
+        self.read_seq(move |d, len| {
+            if len == tuple_len {
+                f(d)
+            } else {
+                let err = format!("Invalid tuple length. Expected {}, found {}",
+                                   tuple_len,
+                                   len);
+                Err(DecodeError::Expected(err))
+            }
+        })
+    }
+
+    fn read_tuple_arg<T, F>(&mut self, idx: usize, f: F) -> Result<T, Self::Error> where
+        F: FnOnce(&mut Decoder<'a>) -> Result<T, Self::Error>,
+    {
+        self.read_seq_elt(idx, f)
+    }
+
+    fn read_tuple_struct<T, F>(&mut self,
+                               _name: &str,
+                               len: usize, f: F)
+                               -> Result<T, Self::Error> where
+        F: FnOnce(&mut Decoder<'a>) -> Result<T, Self::Error>,
+    {
+        self.read_tuple(len, f)
+    }
+
+    fn read_tuple_struct_arg<T, F>(&mut self,
+                                   idx: usize,
+                                   f: F)
+                                   -> Result<T, Self::Error> where
+        F: FnOnce(&mut Decoder<'a>) -> Result<T, Self::Error>,
+    {
+        self.read_tuple_arg(idx, f)
+    }
+
+    fn read_option<T, F>(&mut self, mut f: F) -> Result<T, Self::Error> where
+        F: FnMut(&mut Decoder<'a>, bool) -> Result<T, Self::Error>,
+    {
+        self.read_enum("Option", move |this| {
+            this.read_enum_variant(&["None", "Some"], move |this, idx| {
+                match idx {
+                    0 => f(this, false),
+                    1 => f(this, true),
+                    _ => {
+                        let msg = format!("Invalid Option index: {}", idx);
+                        Err(DecodeError::Expected(msg))
+                    }
+                }
+            })
+        })
+    }
+
+    fn read_seq<T, F>(&mut self, f: F) -> Result<T, Self::Error> where
+        F: FnOnce(&mut Decoder<'a>, usize) -> Result<T, Self::Error>,
+    {
+        let len = try!(self.read_uint());
+        f(self, len)
+    }
+
+    fn read_seq_elt<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Self::Error> where
+        F: FnOnce(&mut Decoder<'a>) -> Result<T, Self::Error>,
+    {
+        f(self)
+    }
+
+    fn read_map<T, F>(&mut self, f: F) -> Result<T, Self::Error> where
+        F: FnOnce(&mut Decoder<'a>, usize) -> Result<T, Self::Error>,
+    {
+        let len = try!(self.read_uint());
+        f(self, len)
+    }
+
+    fn read_map_elt_key<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Self::Error> where
+        F: FnOnce(&mut Decoder<'a>) -> Result<T, Self::Error>,
+    {
+        f(self)
+    }
+
+    fn read_map_elt_val<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Self::Error> where
+        F: FnOnce(&mut Decoder<'a>) -> Result<T, Self::Error>,
+    {
+        f(self)
+    }
+
+    fn error(&mut self, err: &str) -> Self::Error {
+        DecodeError::ApplicationError(err.to_string())
+    }
+}
+
+
+#[cfg(test)]
+mod tests {
+    use serialize::{Encodable, Decodable};
+    use std::io::{Cursor};
+    use std::fmt::Debug;
+    use super::{Encoder, Decoder};
+
+    #[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
+    struct Struct {
+        a: (),
+        b: u8,
+        c: u16,
+        d: u32,
+        e: u64,
+        f: usize,
+
+        g: i8,
+        h: i16,
+        i: i32,
+        j: i64,
+        k: isize,
+
+        l: char,
+        m: String,
+        n: f32,
+        o: f64,
+        p: bool,
+        q: Option<u32>,
+    }
+
+
+    fn check_round_trip<T: Encodable+Decodable+PartialEq+Debug>(values: Vec<T>) {
+        let mut cursor = Cursor::new(Vec::new());
+
+        for value in &values {
+            let mut encoder = Encoder::new(&mut cursor);
+            Encodable::encode(&value, &mut encoder).unwrap();
+        }
+
+        let data = cursor.into_inner();
+        let mut decoder = Decoder::new(&data[..], 0);
+
+        for value in values {
+            let decoded = Decodable::decode(&mut decoder).unwrap();
+            assert_eq!(value, decoded);
+        }
+    }
+
+    #[test]
+    fn test_unit() {
+        check_round_trip(vec![(), (), (), ()]);
+    }
+
+    #[test]
+    fn test_u8() {
+        let mut vec = vec![];
+        for i in ::std::u8::MIN .. ::std::u8::MAX {
+            vec.push(i);
+        }
+        check_round_trip(vec);
+    }
+
+    #[test]
+    fn test_u16() {
+        for i in ::std::u16::MIN .. ::std::u16::MAX {
+            check_round_trip(vec![1, 2, 3, i, i, i]);
+        }
+    }
+
+    #[test]
+    fn test_u32() {
+        check_round_trip(vec![1, 2, 3, ::std::u32::MIN, 0, 1, ::std::u32::MAX, 2, 1]);
+    }
+
+    #[test]
+    fn test_u64() {
+        check_round_trip(vec![1, 2, 3, ::std::u64::MIN, 0, 1, ::std::u64::MAX, 2, 1]);
+    }
+
+    #[test]
+    fn test_usize() {
+        check_round_trip(vec![1, 2, 3, ::std::usize::MIN, 0, 1, ::std::usize::MAX, 2, 1]);
+    }
+
+    #[test]
+    fn test_i8() {
+        let mut vec = vec![];
+        for i in ::std::i8::MIN .. ::std::i8::MAX {
+            vec.push(i);
+        }
+        check_round_trip(vec);
+    }
+
+    #[test]
+    fn test_i16() {
+        for i in ::std::i16::MIN .. ::std::i16::MAX {
+            check_round_trip(vec![-1, 2, -3, i, i, i, 2]);
+        }
+    }
+
+    #[test]
+    fn test_i32() {
+        check_round_trip(vec![-1, 2, -3, ::std::i32::MIN, 0, 1, ::std::i32::MAX, 2, 1]);
+    }
+
+    #[test]
+    fn test_i64() {
+        check_round_trip(vec![-1, 2, -3, ::std::i64::MIN, 0, 1, ::std::i64::MAX, 2, 1]);
+    }
+
+    #[test]
+    fn test_isize() {
+        check_round_trip(vec![-1, 2, -3, ::std::isize::MIN, 0, 1, ::std::isize::MAX, 2, 1]);
+    }
+
+    #[test]
+    fn test_bool() {
+        check_round_trip(vec![false, true, true, false, false]);
+    }
+
+    #[test]
+    fn test_f32() {
+        let mut vec = vec![];
+        for i in -100 .. 100 {
+            vec.push( (i as f32) / 3.0 );
+        }
+        check_round_trip(vec);
+    }
+
+    #[test]
+    fn test_f64() {
+        let mut vec = vec![];
+        for i in -100 .. 100 {
+            vec.push( (i as f64) / 3.0 );
+        }
+        check_round_trip(vec);
+    }
+
+    #[test]
+    fn test_char() {
+        let vec = vec!['a', 'b', 'c', 'd', 'A', 'X', ' ', '#', 'Ö', 'Ä', 'µ', '€'];
+        check_round_trip(vec);
+    }
+
+    #[test]
+    fn test_string() {
+        let vec = vec![
+            "abcbuÖeiovÄnameÃœavmpßvmea€µsbpnvapeapmaebn".to_string(),
+            "abcbuÖganeiovÄnameÃœavmpßvmea€µsbpnvapeapmaebn".to_string(),
+            "abcbuÖganeiovÄnameÃœavmpßvmea€µsbpapmaebn".to_string(),
+            "abcbuÖganeiovÄnameÃœavmpßvmeabpnvapeapmaebn".to_string(),
+            "abcbuÖganeiÄnameÃœavmpßvmea€µsbpnvapeapmaebn".to_string(),
+            "abcbuÖganeiovÄnameÃœavmpßvmea€µsbpmaebn".to_string(),
+            "abcbuÖganeiovÄnameÃœavmpßvmea€µnvapeapmaebn".to_string()];
+
+        check_round_trip(vec);
+    }
+
+    #[test]
+    fn test_option() {
+        check_round_trip(vec![Some(-1i8)]);
+        check_round_trip(vec![Some(-2i16)]);
+        check_round_trip(vec![Some(-3i32)]);
+        check_round_trip(vec![Some(-4i64)]);
+        check_round_trip(vec![Some(-5isize)]);
+
+        let none_i8: Option<i8> = None;
+        check_round_trip(vec![none_i8]);
+
+        let none_i16: Option<i16> = None;
+        check_round_trip(vec![none_i16]);
+
+        let none_i32: Option<i32> = None;
+        check_round_trip(vec![none_i32]);
+
+        let none_i64: Option<i64> = None;
+        check_round_trip(vec![none_i64]);
+
+        let none_isize: Option<isize> = None;
+        check_round_trip(vec![none_isize]);
+    }
+
+    #[test]
+    fn test_struct() {
+        check_round_trip(vec![Struct {
+            a: (),
+            b: 10,
+            c: 11,
+            d: 12,
+            e: 13,
+            f: 14,
+
+            g: 15,
+            h: 16,
+            i: 17,
+            j: 18,
+            k: 19,
+
+            l: 'x',
+            m: "abc".to_string(),
+            n: 20.5,
+            o: 21.5,
+            p: false,
+            q: None,
+        }]);
+
+        check_round_trip(vec![Struct {
+            a: (),
+            b: 101,
+            c: 111,
+            d: 121,
+            e: 131,
+            f: 141,
+
+            g: -15,
+            h: -16,
+            i: -17,
+            j: -18,
+            k: -19,
+
+            l: 'y',
+            m: "def".to_string(),
+            n: -20.5,
+            o: -21.5,
+            p: true,
+            q: Some(1234567),
+        }]);
+    }
+
+    #[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
+    enum Enum {
+        Variant1,
+        Variant2(usize, f32),
+        Variant3 { a: i32, b: char, c: bool }
+    }
+
+    #[test]
+    fn test_enum() {
+        check_round_trip(vec![Enum::Variant1,
+                              Enum::Variant2(1, 2.5),
+                              Enum::Variant3 { a: 3, b: 'b', c: false },
+                              Enum::Variant3 { a: -4, b: 'f', c: true }]);
+    }
+
+    #[test]
+    fn test_sequence() {
+        let mut vec = vec![];
+        for i in -100i64 .. 100i64 {
+            vec.push(i*100000);
+        }
+
+        check_round_trip(vec![vec]);
+    }
+
+    #[test]
+    fn test_hash_map() {
+        use std::collections::HashMap;
+        let mut map = HashMap::new();
+        for i in -100i64 .. 100i64 {
+            map.insert(i*100000, i*10000);
+        }
+
+        check_round_trip(vec![map]);
+    }
+
+    #[test]
+    fn test_tuples() {
+        check_round_trip(vec![('x', (), false, 0.5f32)]);
+        check_round_trip(vec![(9i8, 10u16, 1.5f64)]);
+        check_round_trip(vec![(-12i16, 11u8, 12usize)]);
+        check_round_trip(vec![(1234567isize, 100000000000000u64, 99999999999999i64)]);
+        check_round_trip(vec![(String::new(), "some string".to_string())]);
+    }
+}
index 6a5910074d91592c5aa5c38d05b786a069dda96e..715850154f64eb1b8e5047eea63a4e3aa6dee54b 100644 (file)
@@ -1657,6 +1657,46 @@ fn baz() {
 call `bar` on. Change `Foo::bar()` to `Foo::<T>::bar()` to resolve the error.
 "##,
 
+E0283: r##"
+This error occurs when the compiler doesn't have enough information
+to unambiguously choose an implementation.
+
+For example:
+
+```
+trait Generator {
+    fn create() -> u32;
+}
+
+struct Impl;
+impl Generator for Impl {
+    fn create() -> u32 { 1 }
+}
+
+struct AnotherImpl;
+impl Generator for AnotherImpl {
+    fn create() -> u32 { 2 }
+}
+
+fn main() {
+    let cont: u32 = Generator::create();
+    // error, impossible to choose one of Generator trait implementation
+    // Impl or AnotherImpl? Maybe anything else?
+}
+```
+
+To resolve this error use the concrete type:
+
+```
+fn main() {
+    let gen1 = AnotherImpl::create();
+
+    // if there are multiple methods with same name (different traits)
+    let gen2 = <AnotherImpl as Generator>::create();
+}
+```
+"##,
+
 E0296: r##"
 This error indicates that the given recursion limit could not be parsed. Ensure
 that the value provided is a positive integer between quotes, like so:
@@ -2279,7 +2319,6 @@ impl Foo {
     E0278, // requirement is not satisfied
     E0279, // requirement is not satisfied
     E0280, // requirement is not satisfied
-    E0283, // cannot resolve type
     E0284, // cannot resolve type
     E0285, // overflow evaluation builtin bounds
     E0298, // mismatched types between arms
index 2c3b89bf2fbb2ffa31e77b6ae6c2fc9403c47b72..380f543f969f06b4c2a77dde7c27233957032325 100644 (file)
@@ -432,8 +432,8 @@ fn metadata_encoding_version(&self) -> &[u8] { unimplemented!() }
 /// Note, however, that this only works for RBML-based encoding and decoding at
 /// the moment.
 pub mod tls {
-    use rbml::writer::Encoder as RbmlEncoder;
-    use rbml::reader::Decoder as RbmlDecoder;
+    use rbml::opaque::Encoder as OpaqueEncoder;
+    use rbml::opaque::Decoder as OpaqueDecoder;
     use serialize;
     use std::mem;
     use middle::ty::{self, Ty};
@@ -442,8 +442,8 @@ pub mod tls {
 
     pub trait EncodingContext<'tcx> {
         fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
-        fn encode_ty(&self, rbml_w: &mut RbmlEncoder, t: Ty<'tcx>);
-        fn encode_substs(&self, rbml_w: &mut RbmlEncoder, substs: &Substs<'tcx>);
+        fn encode_ty(&self, encoder: &mut OpaqueEncoder, t: Ty<'tcx>);
+        fn encode_substs(&self, encoder: &mut OpaqueEncoder, substs: &Substs<'tcx>);
     }
 
     /// Marker type used for the scoped TLS slot.
@@ -455,13 +455,13 @@ pub trait EncodingContext<'tcx> {
 
     /// Execute f after pushing the given EncodingContext onto the TLS stack.
     pub fn enter_encoding_context<'tcx, F, R>(ecx: &EncodingContext<'tcx>,
-                                              rbml_w: &mut RbmlEncoder,
+                                              encoder: &mut OpaqueEncoder,
                                               f: F) -> R
-        where F: FnOnce(&EncodingContext<'tcx>, &mut RbmlEncoder) -> R
+        where F: FnOnce(&EncodingContext<'tcx>, &mut OpaqueEncoder) -> R
     {
-        let tls_payload = (ecx as *const _, rbml_w as *mut _);
+        let tls_payload = (ecx as *const _, encoder as *mut _);
         let tls_ptr = &tls_payload as *const _ as *const TlsPayload;
-        TLS_ENCODING.set(unsafe { &*tls_ptr }, || f(ecx, rbml_w))
+        TLS_ENCODING.set(unsafe { &*tls_ptr }, || f(ecx, encoder))
     }
 
     /// Execute f with access to the thread-local encoding context and
@@ -473,16 +473,16 @@ pub fn enter_encoding_context<'tcx, F, R>(ecx: &EncodingContext<'tcx>,
     /// possible to construct cases where the EncodingContext is exchanged
     /// while the same encoder is used, thus working with a wrong context.
     pub fn with_encoding_context<'tcx, E, F, R>(encoder: &mut E, f: F) -> R
-        where F: FnOnce(&EncodingContext<'tcx>, &mut RbmlEncoder) -> R,
+        where F: FnOnce(&EncodingContext<'tcx>, &mut OpaqueEncoder) -> R,
               E: serialize::Encoder
     {
         unsafe {
-            unsafe_with_encoding_context(|ecx, rbml_w| {
-                assert!(encoder as *mut _ as usize == rbml_w as *mut _ as usize);
+            unsafe_with_encoding_context(|ecx, tls_encoder| {
+                assert!(encoder as *mut _ as usize == tls_encoder as *mut _ as usize);
 
                 let ecx: &EncodingContext<'tcx> = mem::transmute(ecx);
 
-                f(ecx, rbml_w)
+                f(ecx, tls_encoder)
             })
         }
     }
@@ -490,19 +490,19 @@ pub fn with_encoding_context<'tcx, E, F, R>(encoder: &mut E, f: F) -> R
     /// Execute f with access to the thread-local encoding context and
     /// rbml encoder.
     pub unsafe fn unsafe_with_encoding_context<F, R>(f: F) -> R
-        where F: FnOnce(&EncodingContext, &mut RbmlEncoder) -> R
+        where F: FnOnce(&EncodingContext, &mut OpaqueEncoder) -> R
     {
         TLS_ENCODING.with(|tls| {
             let tls_payload = (tls as *const TlsPayload)
-                                   as *mut (&EncodingContext, &mut RbmlEncoder);
+                                   as *mut (&EncodingContext, &mut OpaqueEncoder);
             f((*tls_payload).0, (*tls_payload).1)
         })
     }
 
     pub trait DecodingContext<'tcx> {
         fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
-        fn decode_ty(&self, rbml_r: &mut RbmlDecoder) -> ty::Ty<'tcx>;
-        fn decode_substs(&self, rbml_r: &mut RbmlDecoder) -> Substs<'tcx>;
+        fn decode_ty(&self, decoder: &mut OpaqueDecoder) -> ty::Ty<'tcx>;
+        fn decode_substs(&self, decoder: &mut OpaqueDecoder) -> Substs<'tcx>;
         fn translate_def_id(&self, def_id: DefId) -> DefId;
     }
 
@@ -510,13 +510,13 @@ pub trait DecodingContext<'tcx> {
 
     /// Execute f after pushing the given DecodingContext onto the TLS stack.
     pub fn enter_decoding_context<'tcx, F, R>(dcx: &DecodingContext<'tcx>,
-                                              rbml_r: &mut RbmlDecoder,
+                                              decoder: &mut OpaqueDecoder,
                                               f: F) -> R
-        where F: FnOnce(&DecodingContext<'tcx>, &mut RbmlDecoder) -> R
+        where F: FnOnce(&DecodingContext<'tcx>, &mut OpaqueDecoder) -> R
     {
-        let tls_payload = (dcx as *const _, rbml_r as *mut _);
+        let tls_payload = (dcx as *const _, decoder as *mut _);
         let tls_ptr = &tls_payload as *const _ as *const TlsPayload;
-        TLS_DECODING.set(unsafe { &*tls_ptr }, || f(dcx, rbml_r))
+        TLS_DECODING.set(unsafe { &*tls_ptr }, || f(dcx, decoder))
     }
 
     /// Execute f with access to the thread-local decoding context and
@@ -530,16 +530,16 @@ pub fn enter_decoding_context<'tcx, F, R>(dcx: &DecodingContext<'tcx>,
     pub fn with_decoding_context<'decoder, 'tcx, D, F, R>(d: &'decoder mut D, f: F) -> R
         where D: serialize::Decoder,
               F: FnOnce(&DecodingContext<'tcx>,
-                        &mut RbmlDecoder) -> R,
+                        &mut OpaqueDecoder) -> R,
               'tcx: 'decoder
     {
         unsafe {
-            unsafe_with_decoding_context(|dcx, rbml_r| {
-                assert!((d as *mut _ as usize) == (rbml_r as *mut _ as usize));
+            unsafe_with_decoding_context(|dcx, decoder| {
+                assert!((d as *mut _ as usize) == (decoder as *mut _ as usize));
 
                 let dcx: &DecodingContext<'tcx> = mem::transmute(dcx);
 
-                f(dcx, rbml_r)
+                f(dcx, decoder)
             })
         }
     }
@@ -547,11 +547,11 @@ pub fn with_decoding_context<'decoder, 'tcx, D, F, R>(d: &'decoder mut D, f: F)
     /// Execute f with access to the thread-local decoding context and
     /// rbml decoder.
     pub unsafe fn unsafe_with_decoding_context<F, R>(f: F) -> R
-        where F: FnOnce(&DecodingContext, &mut RbmlDecoder) -> R
+        where F: FnOnce(&DecodingContext, &mut OpaqueDecoder) -> R
     {
         TLS_DECODING.with(|tls| {
             let tls_payload = (tls as *const TlsPayload)
-                                   as *mut (&DecodingContext, &mut RbmlDecoder);
+                                   as *mut (&DecodingContext, &mut OpaqueDecoder);
             f((*tls_payload).0, (*tls_payload).1)
         })
     }
index 8f74acd9ebdf6f8da88694d89f608ee60df1d5c8..8c3bd3c4f8a5352851b919077ad90224bc70c425 100644 (file)
@@ -292,7 +292,7 @@ fn read_def_id_nodcx(&mut self,
 
 fn encode_ast(rbml_w: &mut Encoder, item: &InlinedItem) {
     rbml_w.start_tag(c::tag_tree as usize);
-    item.encode(rbml_w);
+    rbml_w.emit_opaque(|this| item.encode(this));
     rbml_w.end_tag();
 }
 
@@ -361,8 +361,8 @@ fn simplify_ast(ii: InlinedItemRef) -> InlinedItem {
 
 fn decode_ast(par_doc: rbml::Doc) -> InlinedItem {
     let chi_doc = par_doc.get(c::tag_tree as usize);
-    let mut d = reader::Decoder::new(chi_doc);
-    Decodable::decode(&mut d).unwrap()
+    let mut rbml_r = reader::Decoder::new(chi_doc);
+    rbml_r.read_opaque(|decoder, _| Decodable::decode(decoder)).unwrap()
 }
 
 // ______________________________________________________________________
@@ -509,21 +509,6 @@ pub fn encode_cast_kind(ebml_w: &mut Encoder, kind: cast::CastKind) {
 // ______________________________________________________________________
 // Encoding and decoding the side tables
 
-trait get_ty_str_ctxt<'tcx> {
-    fn ty_str_ctxt<'a>(&'a self) -> tyencode::ctxt<'a, 'tcx>;
-}
-
-impl<'a, 'tcx> get_ty_str_ctxt<'tcx> for e::EncodeContext<'a, 'tcx> {
-    fn ty_str_ctxt<'b>(&'b self) -> tyencode::ctxt<'b, 'tcx> {
-        tyencode::ctxt {
-            diag: self.tcx.sess.diagnostic(),
-            ds: e::def_to_string,
-            tcx: self.tcx,
-            abbrevs: &self.type_abbrevs
-        }
-    }
-}
-
 trait rbml_writer_helpers<'tcx> {
     fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region);
     fn emit_ty<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: Ty<'tcx>);
@@ -548,11 +533,15 @@ fn emit_auto_deref_ref<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
 
 impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
     fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region) {
-        self.emit_opaque(|this| Ok(e::write_region(ecx, this, r)));
+        self.emit_opaque(|this| Ok(tyencode::enc_region(&mut this.cursor,
+                                                        &ecx.ty_str_ctxt(),
+                                                        r)));
     }
 
     fn emit_ty<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, ty: Ty<'tcx>) {
-        self.emit_opaque(|this| Ok(e::write_type(ecx, this, ty)));
+        self.emit_opaque(|this| Ok(tyencode::enc_ty(&mut this.cursor,
+                                                    &ecx.ty_str_ctxt(),
+                                                    ty)));
     }
 
     fn emit_tys<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, tys: &[Ty<'tcx>]) {
@@ -561,13 +550,15 @@ fn emit_tys<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, tys: &[Ty<'tcx>]) {
 
     fn emit_trait_ref<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
                           trait_ref: &ty::TraitRef<'tcx>) {
-        self.emit_opaque(|this| Ok(e::write_trait_ref(ecx, this, trait_ref)));
+        self.emit_opaque(|this| Ok(tyencode::enc_trait_ref(&mut this.cursor,
+                                                           &ecx.ty_str_ctxt(),
+                                                           *trait_ref)));
     }
 
     fn emit_predicate<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
                           predicate: &ty::Predicate<'tcx>) {
         self.emit_opaque(|this| {
-            Ok(tyencode::enc_predicate(this,
+            Ok(tyencode::enc_predicate(&mut this.cursor,
                                        &ecx.ty_str_ctxt(),
                                        predicate))
         });
@@ -575,13 +566,13 @@ fn emit_predicate<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
 
     fn emit_existential_bounds<'b>(&mut self, ecx: &e::EncodeContext<'b,'tcx>,
                                    bounds: &ty::ExistentialBounds<'tcx>) {
-        self.emit_opaque(|this| Ok(tyencode::enc_existential_bounds(this,
+        self.emit_opaque(|this| Ok(tyencode::enc_existential_bounds(&mut this.cursor,
                                                                     &ecx.ty_str_ctxt(),
                                                                     bounds)));
     }
 
     fn emit_builtin_bounds(&mut self, ecx: &e::EncodeContext, bounds: &ty::BuiltinBounds) {
-        self.emit_opaque(|this| Ok(tyencode::enc_builtin_bounds(this,
+        self.emit_opaque(|this| Ok(tyencode::enc_builtin_bounds(&mut this.cursor,
                                                                 &ecx.ty_str_ctxt(),
                                                                 bounds)));
     }
@@ -608,9 +599,9 @@ fn emit_upvar_capture(&mut self, ecx: &e::EncodeContext, capture: &ty::UpvarCapt
 
     fn emit_substs<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
                        substs: &subst::Substs<'tcx>) {
-        self.emit_opaque(|this| Ok(tyencode::enc_substs(this,
-                                                           &ecx.ty_str_ctxt(),
-                                                           substs)));
+        self.emit_opaque(|this| Ok(tyencode::enc_substs(&mut this.cursor,
+                                                        &ecx.ty_str_ctxt(),
+                                                        substs)));
     }
 
     fn emit_auto_adjustment<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
@@ -878,10 +869,6 @@ fn read_auto_deref_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
                                    -> adjustment::AutoDerefRef<'tcx>;
     fn read_autoref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
                             -> adjustment::AutoRef<'tcx>;
-    fn convert_def_id(&mut self,
-                      dcx: &DecodeContext,
-                      did: DefId)
-                      -> DefId;
 
     // Versions of the type reading functions that don't need the full
     // DecodeContext.
@@ -933,12 +920,12 @@ fn read_substs_nodcx(&mut self,
     fn read_ty_encoded<'b, 'c, F, R>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>, op: F) -> R
         where F: for<'x> FnOnce(&mut tydecode::TyDecoder<'x,'tcx>) -> R
     {
-        return self.read_opaque(|this, doc| {
+        return self.read_opaque(|_, doc| {
             debug!("read_ty_encoded({})", type_string(doc));
             Ok(op(
                 &mut tydecode::TyDecoder::with_doc(
                     dcx.tcx, dcx.cdata.cnum, doc,
-                    &mut |a| this.convert_def_id(dcx, a))))
+                    &mut |d| convert_def_id(dcx, d))))
         }).unwrap();
 
         fn type_string(doc: rbml::Doc) -> String {
@@ -989,9 +976,9 @@ fn read_existential_bounds<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
 
     fn read_substs<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
                            -> subst::Substs<'tcx> {
-        self.read_opaque(|this, doc| {
+        self.read_opaque(|_, doc| {
             Ok(tydecode::TyDecoder::with_doc(dcx.tcx, dcx.cdata.cnum, doc,
-                                             &mut |a| this.convert_def_id(dcx, a))
+                                             &mut |d| convert_def_id(dcx, d))
                .parse_substs())
         }).unwrap()
     }
@@ -1097,47 +1084,46 @@ fn read_cast_kind<'b, 'c>(&mut self, _dcx: &DecodeContext<'b, 'c, 'tcx>)
     {
         Decodable::decode(self).unwrap()
     }
+}
 
-    /// Converts a def-id that appears in a type.  The correct
-    /// translation will depend on what kind of def-id this is.
-    /// This is a subtle point: type definitions are not
-    /// inlined into the current crate, so if the def-id names
-    /// a nominal type or type alias, then it should be
-    /// translated to refer to the source crate.
-    ///
-    /// However, *type parameters* are cloned along with the function
-    /// they are attached to.  So we should translate those def-ids
-    /// to refer to the new, cloned copy of the type parameter.
-    /// We only see references to free type parameters in the body of
-    /// an inlined function. In such cases, we need the def-id to
-    /// be a local id so that the TypeContents code is able to lookup
-    /// the relevant info in the ty_param_defs table.
-    ///
-    /// *Region parameters*, unfortunately, are another kettle of fish.
-    /// In such cases, def_id's can appear in types to distinguish
-    /// shadowed bound regions and so forth. It doesn't actually
-    /// matter so much what we do to these, since regions are erased
-    /// at trans time, but it's good to keep them consistent just in
-    /// case. We translate them with `tr_def_id()` which will map
-    /// the crate numbers back to the original source crate.
-    ///
-    /// Scopes will end up as being totally bogus. This can actually
-    /// be fixed though.
-    ///
-    /// Unboxed closures are cloned along with the function being
-    /// inlined, and all side tables use interned node IDs, so we
-    /// translate their def IDs accordingly.
-    ///
-    /// It'd be really nice to refactor the type repr to not include
-    /// def-ids so that all these distinctions were unnecessary.
-    fn convert_def_id(&mut self,
-                      dcx: &DecodeContext,
-                      did: DefId)
-                      -> DefId {
-        let r = dcx.tr_def_id(did);
-        debug!("convert_def_id(did={:?})={:?}", did, r);
-        return r;
-    }
+// Converts a def-id that appears in a type.  The correct
+// translation will depend on what kind of def-id this is.
+// This is a subtle point: type definitions are not
+// inlined into the current crate, so if the def-id names
+// a nominal type or type alias, then it should be
+// translated to refer to the source crate.
+//
+// However, *type parameters* are cloned along with the function
+// they are attached to.  So we should translate those def-ids
+// to refer to the new, cloned copy of the type parameter.
+// We only see references to free type parameters in the body of
+// an inlined function. In such cases, we need the def-id to
+// be a local id so that the TypeContents code is able to lookup
+// the relevant info in the ty_param_defs table.
+//
+// *Region parameters*, unfortunately, are another kettle of fish.
+// In such cases, def_id's can appear in types to distinguish
+// shadowed bound regions and so forth. It doesn't actually
+// matter so much what we do to these, since regions are erased
+// at trans time, but it's good to keep them consistent just in
+// case. We translate them with `tr_def_id()` which will map
+// the crate numbers back to the original source crate.
+//
+// Scopes will end up as being totally bogus. This can actually
+// be fixed though.
+//
+// Unboxed closures are cloned along with the function being
+// inlined, and all side tables use interned node IDs, so we
+// translate their def IDs accordingly.
+//
+// It'd be really nice to refactor the type repr to not include
+// def-ids so that all these distinctions were unnecessary.
+fn convert_def_id(dcx: &DecodeContext,
+                  did: DefId)
+                  -> DefId {
+    let r = dcx.tr_def_id(did);
+    debug!("convert_def_id(did={:?})={:?}", did, r);
+    return r;
 }
 
 fn decode_side_tables(dcx: &DecodeContext,
index 29fe9bc759ddece4164284ffe37daea4c7e9519b..54cccf087ebb61a0ec0c417317b784b2d9b25bf9 100644 (file)
@@ -833,9 +833,11 @@ pub fn maybe_get_item_mir<'tcx>(cdata: Cmd,
         };
         let mut decoder = reader::Decoder::new(mir_doc);
 
-        let mut mir = tls::enter_decoding_context(&dcx, &mut decoder, |_, decoder| {
-            Decodable::decode(decoder).unwrap()
-        });
+        let mut mir = decoder.read_opaque(|opaque_decoder, _| {
+            tls::enter_decoding_context(&dcx, opaque_decoder, |_, opaque_decoder| {
+                Decodable::decode(opaque_decoder)
+            })
+        }).unwrap();
 
         let mut def_id_and_span_translator = MirDefIdAndSpanTranslator {
             crate_metadata: cdata,
@@ -1643,7 +1645,9 @@ pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> {
 
     reader::tagged_docs(cm_doc, tag_codemap_filemap).map(|filemap_doc| {
         let mut decoder = reader::Decoder::new(filemap_doc);
-        Decodable::decode(&mut decoder).unwrap()
+        decoder.read_opaque(|opaque_decoder, _| {
+            Decodable::decode(opaque_decoder)
+        }).unwrap()
     }).collect()
 }
 
index f1c5d47df8889789f64535efc03960c156d6d980..26f32e207647fd0d4c948e285fb32fedbea49357 100644 (file)
@@ -140,15 +140,9 @@ fn encode_trait_ref<'a, 'tcx>(rbml_w: &mut Encoder,
                               ecx: &EncodeContext<'a, 'tcx>,
                               trait_ref: ty::TraitRef<'tcx>,
                               tag: usize) {
-    let ty_str_ctxt = &tyencode::ctxt {
-        diag: ecx.diag,
-        ds: def_to_string,
-        tcx: ecx.tcx,
-        abbrevs: &ecx.type_abbrevs
-    };
-
     rbml_w.start_tag(tag);
-    tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, trait_ref);
+    tyencode::enc_trait_ref(rbml_w.writer, &ecx.ty_str_ctxt(), trait_ref);
+    rbml_w.mark_stable_position();
     rbml_w.end_tag();
 }
 
@@ -202,59 +196,19 @@ fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) {
     rbml_w.wr_tagged_u64(tag_mod_child, id);
 }
 
-pub fn write_closure_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
-                                    rbml_w: &mut Encoder,
-                                    closure_type: &ty::ClosureTy<'tcx>) {
-    let ty_str_ctxt = &tyencode::ctxt {
-        diag: ecx.diag,
-        ds: def_to_string,
-        tcx: ecx.tcx,
-        abbrevs: &ecx.type_abbrevs
-    };
-    tyencode::enc_closure_ty(rbml_w, ty_str_ctxt, closure_type);
-}
-
-pub fn write_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
+fn write_closure_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                             rbml_w: &mut Encoder,
-                            typ: Ty<'tcx>) {
-    let ty_str_ctxt = &tyencode::ctxt {
-        diag: ecx.diag,
-        ds: def_to_string,
-        tcx: ecx.tcx,
-        abbrevs: &ecx.type_abbrevs
-    };
-    tyencode::enc_ty(rbml_w, ty_str_ctxt, typ);
-}
-
-pub fn write_trait_ref<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
-                                 rbml_w: &mut Encoder,
-                                trait_ref: &ty::TraitRef<'tcx>) {
-    let ty_str_ctxt = &tyencode::ctxt {
-        diag: ecx.diag,
-        ds: def_to_string,
-        tcx: ecx.tcx,
-        abbrevs: &ecx.type_abbrevs
-    };
-    tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, *trait_ref);
-}
-
-pub fn write_region(ecx: &EncodeContext,
-                    rbml_w: &mut Encoder,
-                    r: ty::Region) {
-    let ty_str_ctxt = &tyencode::ctxt {
-        diag: ecx.diag,
-        ds: def_to_string,
-        tcx: ecx.tcx,
-        abbrevs: &ecx.type_abbrevs
-    };
-    tyencode::enc_region(rbml_w, ty_str_ctxt, r);
+                            closure_type: &ty::ClosureTy<'tcx>) {
+    tyencode::enc_closure_ty(rbml_w.writer, &ecx.ty_str_ctxt(), closure_type);
+    rbml_w.mark_stable_position();
 }
 
 fn encode_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                          rbml_w: &mut Encoder,
                          typ: Ty<'tcx>) {
     rbml_w.start_tag(tag_items_data_item_type);
-    write_type(ecx, rbml_w, typ);
+    tyencode::enc_ty(rbml_w.writer, &ecx.ty_str_ctxt(), typ);
+    rbml_w.mark_stable_position();
     rbml_w.end_tag();
 }
 
@@ -262,7 +216,8 @@ fn encode_region(ecx: &EncodeContext,
                  rbml_w: &mut Encoder,
                  r: ty::Region) {
     rbml_w.start_tag(tag_items_data_region);
-    write_region(ecx, rbml_w, r);
+    tyencode::enc_region(rbml_w.writer, &ecx.ty_str_ctxt(), r);
+    rbml_w.mark_stable_position();
     rbml_w.end_tag();
 }
 
@@ -592,17 +547,10 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
 {
     rbml_w.start_tag(tag);
 
-    // Type parameters
-    let ty_str_ctxt = &tyencode::ctxt {
-        diag: ecx.diag,
-        ds: def_to_string,
-        tcx: ecx.tcx,
-        abbrevs: &ecx.type_abbrevs
-    };
-
     for param in &generics.types {
         rbml_w.start_tag(tag_type_param_def);
-        tyencode::enc_type_param_def(rbml_w, ty_str_ctxt, param);
+        tyencode::enc_type_param_def(rbml_w.writer, &ecx.ty_str_ctxt(), param);
+        rbml_w.mark_stable_position();
         rbml_w.end_tag();
     }
 
@@ -871,7 +819,11 @@ fn encode_mir(ecx: &EncodeContext, rbml_w: &mut Encoder, ii: InlinedItemRef) {
 
     if let Some(mir) = ecx.mir_map.get(&id) {
         rbml_w.start_tag(tag_mir as usize);
-        Encodable::encode(mir, rbml_w).unwrap();
+        rbml_w.emit_opaque(|opaque_encoder| {
+            tls::enter_encoding_context(ecx, opaque_encoder, |_, opaque_encoder| {
+                Encodable::encode(mir, opaque_encoder)
+            })
+        }).unwrap();
         rbml_w.end_tag();
     }
 }
@@ -916,23 +868,17 @@ fn encode_xrefs<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                           rbml_w: &mut Encoder,
                           xrefs: FnvHashMap<XRef<'tcx>, u32>)
 {
-    let ty_str_ctxt = &tyencode::ctxt {
-        diag: ecx.diag,
-        ds: def_to_string,
-        tcx: ecx.tcx,
-        abbrevs: &ecx.type_abbrevs
-    };
-
     let mut xref_positions = vec![0; xrefs.len()];
     rbml_w.start_tag(tag_xref_data);
     for (xref, id) in xrefs.into_iter() {
         xref_positions[id as usize] = rbml_w.mark_stable_position() as u32;
         match xref {
             XRef::Predicate(p) => {
-                tyencode::enc_predicate(rbml_w, ty_str_ctxt, &p)
+                tyencode::enc_predicate(rbml_w.writer, &ecx.ty_str_ctxt(), &p)
             }
         }
     }
+    rbml_w.mark_stable_position();
     rbml_w.end_tag();
 
     rbml_w.start_tag(tag_xref_index);
@@ -1750,7 +1696,9 @@ fn encode_codemap(ecx: &EncodeContext, rbml_w: &mut Encoder) {
         }
 
         rbml_w.start_tag(tag_codemap_filemap);
-        filemap.encode(rbml_w);
+        rbml_w.emit_opaque(|opaque_encoder| {
+            filemap.encode(opaque_encoder)
+        }).unwrap();
         rbml_w.end_tag();
     }
 
@@ -1961,9 +1909,7 @@ pub fn encode_metadata(parms: EncodeParams, krate: &hir::Crate) -> Vec<u8> {
 
     {
         let mut rbml_w = Encoder::new(&mut wr);
-        tls::enter_encoding_context(&ecx, &mut rbml_w, |_, rbml_w| {
-            encode_metadata_inner(rbml_w, &ecx, krate)
-        });
+        encode_metadata_inner(&mut rbml_w, &ecx, krate)
     }
 
     // RBML compacts the encoded bytes whenever appropriate,
@@ -2132,7 +2078,7 @@ struct Stats {
 // Get the encoded string for a type
 pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> Vec<u8> {
     let mut wr = Cursor::new(Vec::new());
-    tyencode::enc_ty(&mut Encoder::new(&mut wr), &tyencode::ctxt {
+    tyencode::enc_ty(&mut wr, &tyencode::ctxt {
         diag: tcx.sess.diagnostic(),
         ds: def_to_string,
         tcx: tcx,
index eb82d2df94d15d94f79c427470926dc072c10ef5..37e661c21e15a1383f12fe24b60fd93c3649b4bd 100644 (file)
@@ -11,8 +11,8 @@
 // This module provides implementations for the thread-local encoding and
 // decoding context traits in rustc::middle::cstore::tls.
 
-use rbml::writer::Encoder as RbmlEncoder;
-use rbml::reader::Decoder as RbmlDecoder;
+use rbml::opaque::Encoder as OpaqueEncoder;
+use rbml::opaque::Decoder as OpaqueDecoder;
 use rustc::middle::cstore::tls;
 use rustc::middle::def_id::DefId;
 use rustc::middle::subst::Substs;
 use tydecode::TyDecoder;
 use tyencode;
 
-
 impl<'a, 'tcx: 'a> tls::EncodingContext<'tcx> for encoder::EncodeContext<'a, 'tcx> {
 
     fn tcx<'s>(&'s self) -> &'s ty::ctxt<'tcx> {
         &self.tcx
     }
 
-    fn encode_ty(&self, rbml_w: &mut RbmlEncoder, t: ty::Ty<'tcx>) {
-        encoder::write_type(self, rbml_w, t);
+    fn encode_ty(&self, encoder: &mut OpaqueEncoder, t: ty::Ty<'tcx>) {
+        tyencode::enc_ty(encoder.cursor, &self.ty_str_ctxt(), t);
     }
 
-    fn encode_substs(&self, rbml_w: &mut RbmlEncoder, substs: &Substs<'tcx>) {
-        let ty_str_ctxt = &tyencode::ctxt {
-            diag: self.diag,
-            ds: encoder::def_to_string,
-            tcx: self.tcx,
-            abbrevs: &self.type_abbrevs
-        };
-        tyencode::enc_substs(rbml_w, ty_str_ctxt, substs);
+    fn encode_substs(&self, encoder: &mut OpaqueEncoder, substs: &Substs<'tcx>) {
+        tyencode::enc_substs(encoder.cursor, &self.ty_str_ctxt(), substs);
     }
 }
 
@@ -56,12 +49,12 @@ fn tcx<'s>(&'s self) -> &'s ty::ctxt<'tcx> {
         &self.tcx
     }
 
-    fn decode_ty(&self, rbml_r: &mut RbmlDecoder) -> ty::Ty<'tcx> {
+    fn decode_ty(&self, decoder: &mut OpaqueDecoder) -> ty::Ty<'tcx> {
         let def_id_convert = &mut |did| {
             decoder::translate_def_id(self.crate_metadata, did)
         };
 
-        let starting_position = rbml_r.position();
+        let starting_position = decoder.position();
 
         let mut ty_decoder = TyDecoder::new(
             self.crate_metadata.data.as_slice(),
@@ -77,16 +70,16 @@ fn decode_ty(&self, rbml_r: &mut RbmlDecoder) -> ty::Ty<'tcx> {
         // We can just reuse the tydecode implementation for parsing types, but
         // we have to make sure to leave the rbml reader at the position just
         // after the type.
-        rbml_r.advance(end_position - starting_position);
+        decoder.advance(end_position - starting_position);
         ty
     }
 
-    fn decode_substs(&self, rbml_r: &mut RbmlDecoder) -> Substs<'tcx> {
+    fn decode_substs(&self, decoder: &mut OpaqueDecoder) -> Substs<'tcx> {
         let def_id_convert = &mut |did| {
             decoder::translate_def_id(self.crate_metadata, did)
         };
 
-        let starting_position = rbml_r.position();
+        let starting_position = decoder.position();
 
         let mut ty_decoder = TyDecoder::new(
             self.crate_metadata.data.as_slice(),
@@ -99,7 +92,7 @@ fn decode_substs(&self, rbml_r: &mut RbmlDecoder) -> Substs<'tcx> {
 
         let end_position = ty_decoder.position();
 
-        rbml_r.advance(end_position - starting_position);
+        decoder.advance(end_position - starting_position);
         substs
     }
 
index b99431d265618a4c02438b6417615927415dbd42..c7a5faed35cd01bbf5cce863536a2d773142f422 100644 (file)
@@ -25,6 +25,7 @@
 use middle::ty::{self, ToPredicate, Ty, HasTypeFlags};
 
 use rbml;
+use rbml::leb128;
 use std::str;
 use syntax::abi;
 use syntax::ast;
@@ -103,9 +104,10 @@ fn scan<F>(&mut self, mut is_last: F) -> &'a [u8]
     }
 
     fn parse_vuint(&mut self) -> usize {
-        let res = rbml::reader::vuint_at(self.data, self.pos).unwrap();
-        self.pos = res.next;
-        res.val
+        let (value, bytes_read) = leb128::read_unsigned_leb128(self.data,
+                                                               self.pos);
+        self.pos += bytes_read;
+        value as usize
     }
 
     fn parse_name(&mut self, last: char) -> ast::Name {
index 6d42871201b8e792610a568fcdf57e3fa451c7e4..f03c25d698feb927020b084d3af9f2a737b9198a 100644 (file)
@@ -31,9 +31,8 @@
 use syntax::ast;
 use syntax::errors::Handler;
 
-use rbml::writer::{self, Encoder};
-
-macro_rules! mywrite { ($w:expr, $($arg:tt)*) => ({ write!($w.writer, $($arg)*); }) }
+use rbml::leb128;
+use encoder;
 
 pub struct ctxt<'a, 'tcx: 'a> {
     pub diag: &'a Handler,
@@ -44,6 +43,17 @@ pub struct ctxt<'a, 'tcx: 'a> {
     pub abbrevs: &'a abbrev_map<'tcx>
 }
 
+impl<'a, 'tcx> encoder::EncodeContext<'a, 'tcx> {
+    pub fn ty_str_ctxt<'b>(&'b self) -> ctxt<'b, 'tcx> {
+        ctxt {
+            diag: self.tcx.sess.diagnostic(),
+            ds: encoder::def_to_string,
+            tcx: self.tcx,
+            abbrevs: &self.type_abbrevs
+        }
+    }
+}
+
 // Compact string representation for Ty values. API TyStr & parse_from_str.
 // Extra parameters are for converting to/from def_ids in the string rep.
 // Whatever format you choose should not contain pipe characters.
@@ -53,125 +63,129 @@ pub struct ty_abbrev {
 
 pub type abbrev_map<'tcx> = RefCell<FnvHashMap<Ty<'tcx>, ty_abbrev>>;
 
-pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
+pub fn enc_ty<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
     match cx.abbrevs.borrow_mut().get(&t) {
-        Some(a) => { w.writer.write_all(&a.s); return; }
+        Some(a) => { w.write_all(&a.s); return; }
         None => {}
     }
 
-    // type abbreviations needs a stable position
-    let pos = w.mark_stable_position();
+    let pos = w.position();
 
     match t.sty {
-        ty::TyBool => mywrite!(w, "b"),
-        ty::TyChar => mywrite!(w, "c"),
+        ty::TyBool => { write!(w, "b"); }
+        ty::TyChar => { write!(w, "c"); }
         ty::TyInt(t) => {
             match t {
-                ast::TyIs => mywrite!(w, "is"),
-                ast::TyI8 => mywrite!(w, "MB"),
-                ast::TyI16 => mywrite!(w, "MW"),
-                ast::TyI32 => mywrite!(w, "ML"),
-                ast::TyI64 => mywrite!(w, "MD")
-            }
+                ast::TyIs => write!(w, "is"),
+                ast::TyI8 => write!(w, "MB"),
+                ast::TyI16 => write!(w, "MW"),
+                ast::TyI32 => write!(w, "ML"),
+                ast::TyI64 => write!(w, "MD")
+            };
         }
         ty::TyUint(t) => {
             match t {
-                ast::TyUs => mywrite!(w, "us"),
-                ast::TyU8 => mywrite!(w, "Mb"),
-                ast::TyU16 => mywrite!(w, "Mw"),
-                ast::TyU32 => mywrite!(w, "Ml"),
-                ast::TyU64 => mywrite!(w, "Md")
-            }
+                ast::TyUs => write!(w, "us"),
+                ast::TyU8 => write!(w, "Mb"),
+                ast::TyU16 => write!(w, "Mw"),
+                ast::TyU32 => write!(w, "Ml"),
+                ast::TyU64 => write!(w, "Md")
+            };
         }
         ty::TyFloat(t) => {
             match t {
-                ast::TyF32 => mywrite!(w, "Mf"),
-                ast::TyF64 => mywrite!(w, "MF"),
-            }
+                ast::TyF32 => write!(w, "Mf"),
+                ast::TyF64 => write!(w, "MF"),
+            };
         }
         ty::TyEnum(def, substs) => {
-            mywrite!(w, "t[{}|", (cx.ds)(def.did));
+            write!(w, "t[{}|", (cx.ds)(def.did));
             enc_substs(w, cx, substs);
-            mywrite!(w, "]");
+            write!(w, "]");
         }
         ty::TyTrait(box ty::TraitTy { ref principal,
                                        ref bounds }) => {
-            mywrite!(w, "x[");
+            write!(w, "x[");
             enc_trait_ref(w, cx, principal.0);
             enc_existential_bounds(w, cx, bounds);
-            mywrite!(w, "]");
+            write!(w, "]");
         }
         ty::TyTuple(ref ts) => {
-            mywrite!(w, "T[");
+            write!(w, "T[");
             for t in ts { enc_ty(w, cx, *t); }
-            mywrite!(w, "]");
+            write!(w, "]");
         }
-        ty::TyBox(typ) => { mywrite!(w, "~"); enc_ty(w, cx, typ); }
-        ty::TyRawPtr(mt) => { mywrite!(w, "*"); enc_mt(w, cx, mt); }
+        ty::TyBox(typ) => { write!(w, "~"); enc_ty(w, cx, typ); }
+        ty::TyRawPtr(mt) => { write!(w, "*"); enc_mt(w, cx, mt); }
         ty::TyRef(r, mt) => {
-            mywrite!(w, "&");
+            write!(w, "&");
             enc_region(w, cx, *r);
             enc_mt(w, cx, mt);
         }
         ty::TyArray(t, sz) => {
-            mywrite!(w, "V");
+            write!(w, "V");
             enc_ty(w, cx, t);
-            mywrite!(w, "/{}|", sz);
+            write!(w, "/{}|", sz);
         }
         ty::TySlice(t) => {
-            mywrite!(w, "V");
+            write!(w, "V");
             enc_ty(w, cx, t);
-            mywrite!(w, "/|");
+            write!(w, "/|");
         }
         ty::TyStr => {
-            mywrite!(w, "v");
+            write!(w, "v");
         }
         ty::TyBareFn(Some(def_id), f) => {
-            mywrite!(w, "F");
-            mywrite!(w, "{}|", (cx.ds)(def_id));
+            write!(w, "F");
+            write!(w, "{}|", (cx.ds)(def_id));
             enc_bare_fn_ty(w, cx, f);
         }
         ty::TyBareFn(None, f) => {
-            mywrite!(w, "G");
+            write!(w, "G");
             enc_bare_fn_ty(w, cx, f);
         }
         ty::TyInfer(_) => {
             cx.diag.bug("cannot encode inference variable types");
         }
         ty::TyParam(ParamTy {space, idx, name}) => {
-            mywrite!(w, "p[{}|{}|{}]", idx, space.to_uint(), name)
+            write!(w, "p[{}|{}|{}]", idx, space.to_uint(), name);
         }
         ty::TyStruct(def, substs) => {
-            mywrite!(w, "a[{}|", (cx.ds)(def.did));
+            write!(w, "a[{}|", (cx.ds)(def.did));
             enc_substs(w, cx, substs);
-            mywrite!(w, "]");
+            write!(w, "]");
         }
         ty::TyClosure(def, ref substs) => {
-            mywrite!(w, "k[{}|", (cx.ds)(def));
+            write!(w, "k[{}|", (cx.ds)(def));
             enc_substs(w, cx, &substs.func_substs);
             for ty in &substs.upvar_tys {
                 enc_ty(w, cx, ty);
             }
-            mywrite!(w, ".");
-            mywrite!(w, "]");
+            write!(w, ".");
+            write!(w, "]");
         }
         ty::TyProjection(ref data) => {
-            mywrite!(w, "P[");
+            write!(w, "P[");
             enc_trait_ref(w, cx, data.trait_ref);
-            mywrite!(w, "{}]", data.item_name);
+            write!(w, "{}]", data.item_name);
         }
         ty::TyError => {
-            mywrite!(w, "e");
+            write!(w, "e");
         }
     }
 
-    let end = w.mark_stable_position();
+    let end = w.position();
     let len = end - pos;
 
-    let buf: &mut [u8] = &mut [0; 16]; // vuint < 15 bytes
-    let mut abbrev = Cursor::new(buf);
+    let mut abbrev = Cursor::new(Vec::with_capacity(16));
     abbrev.write_all(b"#");
-    writer::write_vuint(&mut abbrev, pos as usize);
+    {
+        let start_position = abbrev.position() as usize;
+        let bytes_written = leb128::write_unsigned_leb128(abbrev.get_mut(),
+                                                          start_position,
+                                                          pos);
+        abbrev.set_position((start_position + bytes_written) as u64);
+    }
 
     cx.abbrevs.borrow_mut().insert(t, ty_abbrev {
         s: if abbrev.position() < len {
@@ -180,101 +194,105 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
             // if the abbreviation is longer than the real type,
             // don't use #-notation. However, insert it here so
             // other won't have to `mark_stable_position`
-            w.writer.get_ref()[pos as usize..end as usize].to_owned()
+            w.get_ref()[pos as usize .. end as usize].to_owned()
         }
     });
 }
 
-fn enc_mutability(w: &mut Encoder, mt: hir::Mutability) {
+fn enc_mutability(w: &mut Cursor<Vec<u8>>, mt: hir::Mutability) {
     match mt {
         hir::MutImmutable => (),
-        hir::MutMutable => mywrite!(w, "m"),
-    }
+        hir::MutMutable => {
+            write!(w, "m");
+        }
+    };
 }
 
-fn enc_mt<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
+fn enc_mt<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
                     mt: ty::TypeAndMut<'tcx>) {
     enc_mutability(w, mt.mutbl);
     enc_ty(w, cx, mt.ty);
 }
 
-fn enc_opt<T, F>(w: &mut Encoder, t: Option<T>, enc_f: F) where
-    F: FnOnce(&mut Encoder, T),
+fn enc_opt<T, F>(w: &mut Cursor<Vec<u8>>, t: Option<T>, enc_f: F) where
+    F: FnOnce(&mut Cursor<Vec<u8>>, T),
 {
     match t {
-        None => mywrite!(w, "n"),
+        None => {
+            write!(w, "n");
+        }
         Some(v) => {
-            mywrite!(w, "s");
+            write!(w, "s");
             enc_f(w, v);
         }
     }
 }
 
-fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut Encoder,
+fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut Cursor<Vec<u8>>,
                                            cx: &ctxt<'a, 'tcx>,
                                            v: &VecPerParamSpace<T>,
                                            mut op: F) where
-    F: FnMut(&mut Encoder, &ctxt<'a, 'tcx>, &T),
+    F: FnMut(&mut Cursor<Vec<u8>>, &ctxt<'a, 'tcx>, &T),
 {
     for &space in &subst::ParamSpace::all() {
-        mywrite!(w, "[");
+        write!(w, "[");
         for t in v.get_slice(space) {
             op(w, cx, t);
         }
-        mywrite!(w, "]");
+        write!(w, "]");
     }
 }
 
-pub fn enc_substs<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
+pub fn enc_substs<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
                             substs: &subst::Substs<'tcx>) {
     enc_region_substs(w, cx, &substs.regions);
     enc_vec_per_param_space(w, cx, &substs.types,
                             |w, cx, &ty| enc_ty(w, cx, ty));
 }
 
-fn enc_region_substs(w: &mut Encoder, cx: &ctxt, substs: &subst::RegionSubsts) {
+fn enc_region_substs(w: &mut Cursor<Vec<u8>>, cx: &ctxt, substs: &subst::RegionSubsts) {
     match *substs {
         subst::ErasedRegions => {
-            mywrite!(w, "e");
+            write!(w, "e");
         }
         subst::NonerasedRegions(ref regions) => {
-            mywrite!(w, "n");
+            write!(w, "n");
             enc_vec_per_param_space(w, cx, regions,
                                     |w, cx, &r| enc_region(w, cx, r));
         }
     }
 }
 
-pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
+pub fn enc_region(w: &mut Cursor<Vec<u8>>, cx: &ctxt, r: ty::Region) {
     match r {
         ty::ReLateBound(id, br) => {
-            mywrite!(w, "b[{}|", id.depth);
+            write!(w, "b[{}|", id.depth);
             enc_bound_region(w, cx, br);
-            mywrite!(w, "]");
+            write!(w, "]");
         }
         ty::ReEarlyBound(ref data) => {
-            mywrite!(w, "B[{}|{}|{}]",
-                     data.space.to_uint(),
-                     data.index,
-                     data.name);
+            write!(w, "B[{}|{}|{}]",
+                   data.space.to_uint(),
+                   data.index,
+                   data.name);
         }
         ty::ReFree(ref fr) => {
-            mywrite!(w, "f[");
+            write!(w, "f[");
             enc_scope(w, cx, fr.scope);
-            mywrite!(w, "|");
+            write!(w, "|");
             enc_bound_region(w, cx, fr.bound_region);
-            mywrite!(w, "]");
+            write!(w, "]");
         }
         ty::ReScope(scope) => {
-            mywrite!(w, "s");
+            write!(w, "s");
             enc_scope(w, cx, scope);
-            mywrite!(w, "|");
+            write!(w, "|");
         }
         ty::ReStatic => {
-            mywrite!(w, "t");
+            write!(w, "t");
         }
         ty::ReEmpty => {
-            mywrite!(w, "e");
+            write!(w, "e");
         }
         ty::ReVar(_) | ty::ReSkolemized(..) => {
             // these should not crop up after typeck
@@ -283,107 +301,107 @@ pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
     }
 }
 
-fn enc_scope(w: &mut Encoder, cx: &ctxt, scope: region::CodeExtent) {
+fn enc_scope(w: &mut Cursor<Vec<u8>>, cx: &ctxt, scope: region::CodeExtent) {
     match cx.tcx.region_maps.code_extent_data(scope) {
         region::CodeExtentData::CallSiteScope {
-            fn_id, body_id } => mywrite!(w, "C[{}|{}]", fn_id, body_id),
+            fn_id, body_id } => write!(w, "C[{}|{}]", fn_id, body_id),
         region::CodeExtentData::ParameterScope {
-            fn_id, body_id } => mywrite!(w, "P[{}|{}]", fn_id, body_id),
-        region::CodeExtentData::Misc(node_id) => mywrite!(w, "M{}", node_id),
+            fn_id, body_id } => write!(w, "P[{}|{}]", fn_id, body_id),
+        region::CodeExtentData::Misc(node_id) => write!(w, "M{}", node_id),
         region::CodeExtentData::Remainder(region::BlockRemainder {
-            block: b, first_statement_index: i }) => mywrite!(w, "B[{}|{}]", b, i),
-        region::CodeExtentData::DestructionScope(node_id) => mywrite!(w, "D{}", node_id),
-    }
+            block: b, first_statement_index: i }) => write!(w, "B[{}|{}]", b, i),
+        region::CodeExtentData::DestructionScope(node_id) => write!(w, "D{}", node_id),
+    };
 }
 
-fn enc_bound_region(w: &mut Encoder, cx: &ctxt, br: ty::BoundRegion) {
+fn enc_bound_region(w: &mut Cursor<Vec<u8>>, cx: &ctxt, br: ty::BoundRegion) {
     match br {
         ty::BrAnon(idx) => {
-            mywrite!(w, "a{}|", idx);
+            write!(w, "a{}|", idx);
         }
         ty::BrNamed(d, name) => {
-            mywrite!(w, "[{}|{}]",
+            write!(w, "[{}|{}]",
                      (cx.ds)(d),
                      name);
         }
         ty::BrFresh(id) => {
-            mywrite!(w, "f{}|", id);
+            write!(w, "f{}|", id);
         }
         ty::BrEnv => {
-            mywrite!(w, "e|");
+            write!(w, "e|");
         }
     }
 }
 
-pub fn enc_trait_ref<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
+pub fn enc_trait_ref<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
                                s: ty::TraitRef<'tcx>) {
-    mywrite!(w, "{}|", (cx.ds)(s.def_id));
+    write!(w, "{}|", (cx.ds)(s.def_id));
     enc_substs(w, cx, s.substs);
 }
 
-fn enc_unsafety(w: &mut Encoder, p: hir::Unsafety) {
+fn enc_unsafety(w: &mut Cursor<Vec<u8>>, p: hir::Unsafety) {
     match p {
-        hir::Unsafety::Normal => mywrite!(w, "n"),
-        hir::Unsafety::Unsafe => mywrite!(w, "u"),
-    }
+        hir::Unsafety::Normal => write!(w, "n"),
+        hir::Unsafety::Unsafe => write!(w, "u"),
+    };
 }
 
-fn enc_abi(w: &mut Encoder, abi: Abi) {
-    mywrite!(w, "[");
-    mywrite!(w, "{}", abi.name());
-    mywrite!(w, "]")
+fn enc_abi(w: &mut Cursor<Vec<u8>>, abi: Abi) {
+    write!(w, "[");
+    write!(w, "{}", abi.name());
+    write!(w, "]");
 }
 
-pub fn enc_bare_fn_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
+pub fn enc_bare_fn_ty<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
                                 ft: &ty::BareFnTy<'tcx>) {
     enc_unsafety(w, ft.unsafety);
     enc_abi(w, ft.abi);
     enc_fn_sig(w, cx, &ft.sig);
 }
 
-pub fn enc_closure_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
+pub fn enc_closure_ty<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
                                 ft: &ty::ClosureTy<'tcx>) {
     enc_unsafety(w, ft.unsafety);
     enc_fn_sig(w, cx, &ft.sig);
     enc_abi(w, ft.abi);
 }
 
-fn enc_fn_sig<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
+fn enc_fn_sig<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
                         fsig: &ty::PolyFnSig<'tcx>) {
-    mywrite!(w, "[");
+    write!(w, "[");
     for ty in &fsig.0.inputs {
         enc_ty(w, cx, *ty);
     }
-    mywrite!(w, "]");
+    write!(w, "]");
     if fsig.0.variadic {
-        mywrite!(w, "V");
+        write!(w, "V");
     } else {
-        mywrite!(w, "N");
+        write!(w, "N");
     }
     match fsig.0.output {
         ty::FnConverging(result_type) => {
             enc_ty(w, cx, result_type);
         }
         ty::FnDiverging => {
-            mywrite!(w, "z");
+            write!(w, "z");
         }
     }
 }
 
-pub fn enc_builtin_bounds(w: &mut Encoder, _cx: &ctxt, bs: &ty::BuiltinBounds) {
+pub fn enc_builtin_bounds(w: &mut Cursor<Vec<u8>>, _cx: &ctxt, bs: &ty::BuiltinBounds) {
     for bound in bs {
         match bound {
-            ty::BoundSend => mywrite!(w, "S"),
-            ty::BoundSized => mywrite!(w, "Z"),
-            ty::BoundCopy => mywrite!(w, "P"),
-            ty::BoundSync => mywrite!(w, "T"),
-        }
+            ty::BoundSend => write!(w, "S"),
+            ty::BoundSized => write!(w, "Z"),
+            ty::BoundCopy => write!(w, "P"),
+            ty::BoundSync => write!(w, "T"),
+        };
     }
 
-    mywrite!(w, ".");
+    write!(w, ".");
 }
 
-pub fn enc_existential_bounds<'a,'tcx>(w: &mut Encoder,
+pub fn enc_existential_bounds<'a,'tcx>(w: &mut Cursor<Vec<u8>>,
                                        cx: &ctxt<'a,'tcx>,
                                        bs: &ty::ExistentialBounds<'tcx>) {
     enc_builtin_bounds(w, cx, &bs.builtin_bounds);
@@ -391,90 +409,94 @@ pub fn enc_existential_bounds<'a,'tcx>(w: &mut Encoder,
     enc_region(w, cx, bs.region_bound);
 
     for tp in &bs.projection_bounds {
-        mywrite!(w, "P");
+        write!(w, "P");
         enc_projection_predicate(w, cx, &tp.0);
     }
 
-    mywrite!(w, ".");
+    write!(w, ".");
 }
 
-pub fn enc_type_param_def<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
+pub fn enc_type_param_def<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
                                     v: &ty::TypeParameterDef<'tcx>) {
-    mywrite!(w, "{}:{}|{}|{}|{}|",
+    write!(w, "{}:{}|{}|{}|{}|",
              v.name, (cx.ds)(v.def_id),
              v.space.to_uint(), v.index, (cx.ds)(v.default_def_id));
     enc_opt(w, v.default, |w, t| enc_ty(w, cx, t));
     enc_object_lifetime_default(w, cx, v.object_lifetime_default);
 }
 
-pub fn enc_region_param_def(w: &mut Encoder, cx: &ctxt,
+pub fn enc_region_param_def(w: &mut Cursor<Vec<u8>>, cx: &ctxt,
                             v: &ty::RegionParameterDef) {
-    mywrite!(w, "{}:{}|{}|{}|",
+    write!(w, "{}:{}|{}|{}|",
              v.name, (cx.ds)(v.def_id),
              v.space.to_uint(), v.index);
     for &r in &v.bounds {
-        mywrite!(w, "R");
+        write!(w, "R");
         enc_region(w, cx, r);
     }
-    mywrite!(w, ".");
+    write!(w, ".");
 }
 
-fn enc_object_lifetime_default<'a, 'tcx>(w: &mut Encoder,
+fn enc_object_lifetime_default<'a, 'tcx>(w: &mut Cursor<Vec<u8>>,
                                          cx: &ctxt<'a, 'tcx>,
                                          default: ty::ObjectLifetimeDefault)
 {
     match default {
-        ty::ObjectLifetimeDefault::Ambiguous => mywrite!(w, "a"),
-        ty::ObjectLifetimeDefault::BaseDefault => mywrite!(w, "b"),
+        ty::ObjectLifetimeDefault::Ambiguous => {
+            write!(w, "a");
+        }
+        ty::ObjectLifetimeDefault::BaseDefault => {
+            write!(w, "b");
+        }
         ty::ObjectLifetimeDefault::Specific(r) => {
-            mywrite!(w, "s");
+            write!(w, "s");
             enc_region(w, cx, r);
         }
     }
 }
 
-pub fn enc_predicate<'a, 'tcx>(w: &mut Encoder,
+pub fn enc_predicate<'a, 'tcx>(w: &mut Cursor<Vec<u8>>,
                                cx: &ctxt<'a, 'tcx>,
                                p: &ty::Predicate<'tcx>)
 {
     match *p {
         ty::Predicate::Trait(ref trait_ref) => {
-            mywrite!(w, "t");
+            write!(w, "t");
             enc_trait_ref(w, cx, trait_ref.0.trait_ref);
         }
         ty::Predicate::Equate(ty::Binder(ty::EquatePredicate(a, b))) => {
-            mywrite!(w, "e");
+            write!(w, "e");
             enc_ty(w, cx, a);
             enc_ty(w, cx, b);
         }
         ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(a, b))) => {
-            mywrite!(w, "r");
+            write!(w, "r");
             enc_region(w, cx, a);
             enc_region(w, cx, b);
         }
         ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(a, b))) => {
-            mywrite!(w, "o");
+            write!(w, "o");
             enc_ty(w, cx, a);
             enc_region(w, cx, b);
         }
         ty::Predicate::Projection(ty::Binder(ref data)) => {
-            mywrite!(w, "p");
-            enc_projection_predicate(w, cx, data)
+            write!(w, "p");
+            enc_projection_predicate(w, cx, data);
         }
         ty::Predicate::WellFormed(data) => {
-            mywrite!(w, "w");
+            write!(w, "w");
             enc_ty(w, cx, data);
         }
         ty::Predicate::ObjectSafe(trait_def_id) => {
-            mywrite!(w, "O{}|", (cx.ds)(trait_def_id));
+            write!(w, "O{}|", (cx.ds)(trait_def_id));
         }
     }
 }
 
-fn enc_projection_predicate<'a, 'tcx>(w: &mut Encoder,
+fn enc_projection_predicate<'a, 'tcx>(w: &mut Cursor<Vec<u8>>,
                                       cx: &ctxt<'a, 'tcx>,
                                       data: &ty::ProjectionPredicate<'tcx>) {
     enc_trait_ref(w, cx, data.projection_ty.trait_ref);
-    mywrite!(w, "{}|", data.projection_ty.item_name);
+    write!(w, "{}|", data.projection_ty.item_name);
     enc_ty(w, cx, data.ty);
 }
index bd94f4e5bf2577e411fe73793a0f2e6b6deeb38d..8347a03cda6f72318b879e8daae6dab3c2567c0c 100644 (file)
@@ -138,28 +138,25 @@ fn args_and_body(&mut self,
                      -> BlockAnd<Vec<ArgDecl<'tcx>>>
     {
         self.in_scope(argument_extent, block, |this| {
-            let arg_decls = {
-                let implicit_arg_decls = implicit_arguments.into_iter()
-                                                           .map(|ty| ArgDecl { ty: ty });
-
-                // to start, translate the argument patterns and collect the
-                // argument types.
-                let explicit_arg_decls =
-                    explicit_arguments
-                    .into_iter()
-                    .enumerate()
-                    .map(|(index, (ty, pattern))| {
+            // to start, translate the argument patterns and collect the argument types.
+            let implicits = implicit_arguments.into_iter().map(|ty| (ty, None));
+            let explicits = explicit_arguments.into_iter().map(|(ty, pat)| (ty, Some(pat)));
+            let arg_decls =
+                implicits
+                .chain(explicits)
+                .enumerate()
+                .map(|(index, (ty, pattern))| {
+                    if let Some(pattern) = pattern {
                         let lvalue = Lvalue::Arg(index as u32);
                         let pattern = this.hir.irrefutable_pat(pattern);
                         unpack!(block = this.lvalue_into_pattern(block,
                                                                  argument_extent,
                                                                  pattern,
                                                                  &lvalue));
-                        ArgDecl { ty: ty }
-                    });
-
-                implicit_arg_decls.chain(explicit_arg_decls).collect()
-            };
+                    }
+                    ArgDecl { ty: ty }
+                })
+                .collect();
 
             // start the first basic block and translate the body
             unpack!(block = this.ast_block(&Lvalue::ReturnPointer, block, ast_block));
index 996e72bdad3250e55adc87a102e26125c5c13f9f..4197f80cb5ea31282c959e17d89b09727b68b5be 100644 (file)
@@ -44,6 +44,7 @@
 use middle::subst::Substs;
 use middle::ty::{self, Ty, HasTypeFlags};
 use rustc::front::map as hir_map;
+use rustc::util::common::time;
 use rustc_mir::mir_map::MirMap;
 use session::config::{self, NoDebugInfo, FullDebugInfo};
 use session::Session;
@@ -3057,7 +3058,9 @@ pub fn trans_crate<'tcx>(tcx: &ty::ctxt<'tcx>,
     let reachable_symbol_ids = filter_reachable_ids(&shared_ccx);
 
     // Translate the metadata.
-    let metadata = write_metadata(&shared_ccx, krate, &reachable_symbol_ids, mir_map);
+    let metadata = time(tcx.sess.time_passes(), "write metadata", || {
+        write_metadata(&shared_ccx, krate, &reachable_symbol_ids, mir_map)
+    });
 
     if shared_ccx.sess().trans_stats() {
         let stats = shared_ccx.stats();
index 0fafe08178a273a725b3752e5982baacc519adba..fe7d29297a9608574f42e54babfc43fbdcf2ff37 100644 (file)
@@ -31,7 +31,6 @@
 use trans::base::{self, push_ctxt};
 use trans::common::{self, type_is_sized, ExprOrMethodCall, node_id_substs, C_nil, const_get_elt};
 use trans::common::{CrateContext, C_integral, C_floating, C_bool, C_str_slice, C_bytes, val_ty};
-use trans::common::C_floating_f64;
 use trans::common::{C_struct, C_undef, const_to_opt_int, const_to_opt_uint, VariantInfo, C_uint};
 use trans::common::{type_is_fat_ptr, Field, C_vector, C_array, C_null, ExprId, MethodCallKey};
 use trans::declare;
@@ -108,38 +107,6 @@ pub fn const_lit(cx: &CrateContext, e: &hir::Expr, lit: &ast::Lit)
     }
 }
 
-pub fn trans_constval<'blk, 'tcx>(bcx: common::Block<'blk, 'tcx>,
-                                cv: &ConstVal,
-                                ty: Ty<'tcx>,
-                                param_substs: &'tcx Substs<'tcx>)
-                                -> ValueRef
-{
-    let ccx = bcx.ccx();
-    let llty = type_of::type_of(ccx, ty);
-    match *cv {
-        ConstVal::Float(v) => C_floating_f64(v, llty),
-        ConstVal::Bool(v) => C_bool(ccx, v),
-        ConstVal::Int(v) => C_integral(llty, v as u64, true),
-        ConstVal::Uint(v) => C_integral(llty, v, false),
-        ConstVal::Str(ref v) => C_str_slice(ccx, v.clone()),
-        ConstVal::ByteStr(ref v) => addr_of(ccx, C_bytes(ccx, v), 1, "byte_str"),
-        ConstVal::Struct(id) | ConstVal::Tuple(id) => {
-            let expr = bcx.tcx().map.expect_expr(id);
-            match const_expr(ccx, expr, param_substs, None, TrueConst::Yes) {
-                Ok((val, _)) => val,
-                Err(e) => panic!("const eval failure: {}", e.description()),
-            }
-        },
-        ConstVal::Array(id, _) | ConstVal::Repeat(id, _) => {
-            let expr = bcx.tcx().map.expect_expr(id);
-            expr::trans(bcx, expr).datum.val
-        },
-        ConstVal::Function(_) => {
-            unimplemented!()
-        },
-    }
-}
-
 pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef {
     unsafe {
         llvm::LLVMConstPointerCast(val, ty.to_ref())
index 70a56990efd0341989e67e91737796df813cee95..12839df87b159d4ce86e55535ada1679986caa67 100644 (file)
@@ -9,11 +9,14 @@
 // except according to those terms.
 
 use back::abi;
+use llvm::ValueRef;
+use middle::subst::Substs;
 use middle::ty::{Ty, HasTypeFlags};
 use rustc::middle::const_eval::ConstVal;
 use rustc::mir::repr as mir;
-use trans::consts;
-use trans::common::{self, Block};
+use trans::common::{self, Block, C_bool, C_bytes, C_floating_f64, C_integral, C_str_slice};
+use trans::consts::{self, TrueConst};
+use trans::{type_of, expr};
 
 
 use super::operand::{OperandRef, OperandValue};
@@ -27,7 +30,7 @@ pub fn trans_constval(&mut self,
                           -> OperandRef<'tcx>
     {
         let ccx = bcx.ccx();
-        let val = consts::trans_constval(bcx, cv, ty, bcx.fcx.param_substs);
+        let val = self.trans_constval_inner(bcx, cv, ty, bcx.fcx.param_substs);
         let val = if common::type_is_immediate(ccx, ty) {
             OperandValue::Immediate(val)
         } else if common::type_is_fat_ptr(bcx.tcx(), ty) {
@@ -46,6 +49,39 @@ pub fn trans_constval(&mut self,
         }
     }
 
+    /// Translate ConstVal into a bare LLVM ValueRef.
+    fn trans_constval_inner(&mut self,
+                            bcx: common::Block<'bcx, 'tcx>,
+                            cv: &ConstVal,
+                            ty: Ty<'tcx>,
+                            param_substs: &'tcx Substs<'tcx>)
+                            -> ValueRef
+    {
+        let ccx = bcx.ccx();
+        let llty = type_of::type_of(ccx, ty);
+        match *cv {
+            ConstVal::Float(v) => C_floating_f64(v, llty),
+            ConstVal::Bool(v) => C_bool(ccx, v),
+            ConstVal::Int(v) => C_integral(llty, v as u64, true),
+            ConstVal::Uint(v) => C_integral(llty, v, false),
+            ConstVal::Str(ref v) => C_str_slice(ccx, v.clone()),
+            ConstVal::ByteStr(ref v) => consts::addr_of(ccx, C_bytes(ccx, v), 1, "byte_str"),
+            ConstVal::Struct(id) | ConstVal::Tuple(id) => {
+                let expr = bcx.tcx().map.expect_expr(id);
+                match consts::const_expr(ccx, expr, param_substs, None, TrueConst::Yes) {
+                    Ok((val, _)) => val,
+                    Err(e) => panic!("const eval failure: {}", e.description()),
+                }
+            },
+            ConstVal::Array(id, _) | ConstVal::Repeat(id, _) => {
+                let expr = bcx.tcx().map.expect_expr(id);
+                expr::trans(bcx, expr).datum.val
+            },
+            ConstVal::Function(did) =>
+                self.trans_fn_ref(bcx, ty, param_substs, did).immediate()
+        }
+    }
+
     pub fn trans_constant(&mut self,
                           bcx: Block<'bcx, 'tcx>,
                           constant: &mir::Constant<'tcx>)
index 3f3913471b8958193c7a2543e408350412d508c9..9a41272299e94a10e91ed875e69ca017ccd43bbd 100644 (file)
@@ -20,7 +20,7 @@
 use libc;
 use mem;
 use memchr;
-use ops::Deref;
+use ops;
 use option::Option::{self, Some, None};
 use os::raw::c_char;
 use result::Result::{self, Ok, Err};
@@ -282,7 +282,7 @@ pub fn as_bytes_with_nul(&self) -> &[u8] {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Deref for CString {
+impl ops::Deref for CString {
     type Target = CStr;
 
     fn deref(&self) -> &CStr {
@@ -522,6 +522,37 @@ fn to_owned(&self) -> CString {
     }
 }
 
+#[stable(feature = "cstring_asref", since = "1.7.0")]
+impl<'a> From<&'a CStr> for CString {
+    fn from(s: &'a CStr) -> CString {
+        s.to_owned()
+    }
+}
+
+#[stable(feature = "cstring_asref", since = "1.7.0")]
+impl ops::Index<ops::RangeFull> for CString {
+    type Output = CStr;
+
+    #[inline]
+    fn index(&self, _index: ops::RangeFull) -> &CStr {
+        self
+    }
+}
+
+#[stable(feature = "cstring_asref", since = "1.7.0")]
+impl AsRef<CStr> for CStr {
+    fn as_ref(&self) -> &CStr {
+        self
+    }
+}
+
+#[stable(feature = "cstring_asref", since = "1.7.0")]
+impl AsRef<CStr> for CString {
+    fn as_ref(&self) -> &CStr {
+        self
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use prelude::v1::*;
index 2ad45e80dd153e68e82cf9769bcba032b4e2d130..8ac46bf51f1bf9de9b5beecb908fac56e5b74d47 100644 (file)
@@ -1171,7 +1171,7 @@ pub enum SeekFrom {
     /// Set the offset to the size of this object plus the specified number of
     /// bytes.
     ///
-    /// It is possible to seek beyond the end of an object, but is an error to
+    /// It is possible to seek beyond the end of an object, but it's an error to
     /// seek before byte 0.
     #[stable(feature = "rust1", since = "1.0.0")]
     End(i64),
@@ -1179,7 +1179,7 @@ pub enum SeekFrom {
     /// Set the offset to the current position plus the specified number of
     /// bytes.
     ///
-    /// It is possible to seek beyond the end of an object, but is an error to
+    /// It is possible to seek beyond the end of an object, but it's an error to
     /// seek before byte 0.
     #[stable(feature = "rust1", since = "1.0.0")]
     Current(i64),
index 863e84be093d2d011fdcb717c9896c382f615a38..79091fd3d6b9d07bd227f935d4d541d2dec67e25 100644 (file)
@@ -231,8 +231,8 @@ impl Stdin {
     /// returned guard also implements the [`Read`] and [`BufRead`] traits for
     /// accessing the underlying data.
     ///
-    /// [Read]: trait.Read.html
-    /// [BufRead]: trait.BufRead.html
+    /// [`Read`]: trait.Read.html
+    /// [`BufRead`]: trait.BufRead.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StdinLock {
         StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
index 52ac37c6e334da4194ebbe0e3c1a1bb41110c0f8..4163ede46afedbd4cb3a150a85465dddd056aba4 100644 (file)
@@ -33,7 +33,7 @@ pub trait AsRawFd {
     /// Extracts the raw file descriptor.
     ///
     /// This method does **not** pass ownership of the raw file descriptor
-    /// to the caller. The descriptor is only guarantee to be valid while
+    /// to the caller. The descriptor is only guaranteed to be valid while
     /// the original object has not yet been destroyed.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn as_raw_fd(&self) -> RawFd;
index 18659cb2e78f18359f3a387c78130d0470060e46..19236f2cd98a80302e463ffd5d9112ac111f42c4 100644 (file)
@@ -164,18 +164,15 @@ impl Eq for Span {}
 
 impl Encodable for Span {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        // Encode spans as a single u64 in order to cut down on tagging overhead
-        // added by the RBML metadata encoding. The should be solved differently
-        // altogether some time (FIXME #21482)
-        s.emit_u64( (self.lo.0 as u64) | ((self.hi.0 as u64) << 32) )
+        try!(s.emit_u32(self.lo.0));
+        s.emit_u32(self.hi.0)
     }
 }
 
 impl Decodable for Span {
     fn decode<D: Decoder>(d: &mut D) -> Result<Span, D::Error> {
-        let lo_hi: u64 = try! { d.read_u64() };
-        let lo = BytePos(lo_hi as u32);
-        let hi = BytePos((lo_hi >> 32) as u32);
+        let lo = BytePos(try! { d.read_u32() });
+        let hi = BytePos(try! { d.read_u32() });
         Ok(mk_sp(lo, hi))
     }
 }
index 76ecbfd2f223d2945f3c0ca41ebc2b564dbbe624..632693dd728c33a8400f8b7e5c15ac605049c3aa 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-macos this needs valgrind 3.11 or higher; see
+// https://github.com/rust-lang/rust/pull/30365#issuecomment-165763679
+
 use std::env;
 use std::process::{exit, Command};
 
index b46ec0d8764d9c35ae9f516ea0b6539aba9b2800..93953e3f58ae0f2f4d477f4948bf64d5f931afd2 100644 (file)
@@ -68,6 +68,7 @@ enum CEnum {
 const C: u8 = 84;
 const C2: [u8; 5] = [42; 5];
 const C3: [u8; 3] = [42, 41, 40];
+const C4: fn(u8) -> S = S;
 
 fn regular() -> u8 {
     21
@@ -198,6 +199,11 @@ fn t23() -> (CEnum, CEnum) {
     (CEnum::A, CEnum::B)
 }
 
+#[rustc_mir]
+fn t24() -> fn(u8) -> S {
+    C4
+}
+
 fn main(){
     unsafe {
         assert_eq!(t1()(), regular());
@@ -240,5 +246,6 @@ fn main(){
         assert_eq!(t21(), Unit);
         assert_eq!(t22(), None);
         assert_eq!(t23(), (CEnum::A, CEnum::B));
+        assert_eq!(t24(), C4);
     }
 }