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
{
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
{
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
}
fun:tlv_finalize
fun:_pthread_tsd_cleanup
fun:_pthread_exit
- fun:_pthread_body
+ ...
fun:_pthread_start
fun:thread_start
}
fun:tlv_finalize
fun:_pthread_tsd_cleanup
fun:_pthread_exit
- fun:_pthread_body
+ ...
fun:_pthread_start
fun:thread_start
}
fun:tlv_finalize
fun:_pthread_tsd_cleanup
fun:_pthread_exit
- fun:_pthread_body
+ ...
fun:_pthread_start
fun:thread_start
}
fun:tlv_finalize
fun:_pthread_tsd_cleanup
fun:_pthread_exit
- fun:_pthread_body
+ ...
fun:_pthread_start
fun:thread_start
}
--- /dev/null
+// 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());
+}
#![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::*;
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,
}
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)
}
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,
}
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()
}
}
--- /dev/null
+// 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())]);
+ }
+}
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:
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
/// 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};
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.
/// 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
/// 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)
})
}
}
/// 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;
}
/// 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
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)
})
}
}
/// 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)
})
}
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();
}
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()
}
// ______________________________________________________________________
// ______________________________________________________________________
// 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>);
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>]) {
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))
});
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)));
}
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>,
-> 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.
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 {
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()
}
{
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,
};
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,
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()
}
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();
}
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();
}
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();
}
{
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();
}
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();
}
}
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);
}
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();
}
{
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,
// 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,
// 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);
}
}
&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(),
// 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(),
let end_position = ty_decoder.position();
- rbml_r.advance(end_position - starting_position);
+ decoder.advance(end_position - starting_position);
substs
}
use middle::ty::{self, ToPredicate, Ty, HasTypeFlags};
use rbml;
+use rbml::leb128;
use std::str;
use syntax::abi;
use syntax::ast;
}
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 {
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,
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.
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 {
// 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
}
}
-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);
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);
}
-> 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));
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;
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();
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;
}
}
-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())
// 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};
-> 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) {
}
}
+ /// 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>)
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};
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl Deref for CString {
+impl ops::Deref for CString {
type Target = CStr;
fn deref(&self) -> &CStr {
}
}
+#[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::*;
/// 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),
/// 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),
/// 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()) }
/// 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;
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))
}
}
// 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};
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
(CEnum::A, CEnum::B)
}
+#[rustc_mir]
+fn t24() -> fn(u8) -> S {
+ C4
+}
+
fn main(){
unsafe {
assert_eq!(t1()(), regular());
assert_eq!(t21(), Unit);
assert_eq!(t22(), None);
assert_eq!(t23(), (CEnum::A, CEnum::B));
+ assert_eq!(t24(), C4);
}
}