diff --git a/mk/dist.mk b/mk/dist.mk index 6d4e4401eaff7..aea263c961987 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -12,7 +12,7 @@ PKG_ICO = $(S)src/etc/pkg/rust-logo.ico PKG_EXE = $(PKG_DIR)-install.exe endif -PKG_GITMODULES := $(S)src/libuv $(S)src/llvm $(S)src/gyp +PKG_GITMODULES := $(S)src/libuv $(S)src/llvm $(S)src/gyp $(S)src/compiler-rt PKG_FILES := \ $(S)COPYRIGHT \ diff --git a/src/doc/guide-ffi.md b/src/doc/guide-ffi.md index e22f30871baa8..053a8612694ab 100644 --- a/src/doc/guide-ffi.md +++ b/src/doc/guide-ffi.md @@ -195,7 +195,7 @@ impl Unique { pub fn new(value: T) -> Unique { unsafe { let ptr = malloc(std::mem::size_of::() as size_t) as *mut T; - assert!(!ptr::is_null(ptr)); + assert!(!ptr.is_null()); // `*ptr` is uninitialized, and `*ptr = value` would attempt to destroy it // move_val_init moves a value into this memory without // attempting to drop the original value. diff --git a/src/doc/tutorial.md b/src/doc/tutorial.md index 91d5e490949a1..61eccb520552b 100644 --- a/src/doc/tutorial.md +++ b/src/doc/tutorial.md @@ -293,7 +293,7 @@ braced block gives the whole block the value of that last expression. Put another way, the semicolon in Rust *ignores the value of an expression*. Thus, if the branches of the `if` had looked like `{ 4; }`, the above example -would simply assign `()` (nil or void) to `price`. But without the semicolon, each +would simply assign `()` (unit or void) to `price`. But without the semicolon, each branch has a different value, and `price` gets the value of the branch that was taken. @@ -352,7 +352,7 @@ before the opening and after the closing quote, and can contain any sequence of characters except their closing delimiter. More on strings [later](#vectors-and-strings). -The nil type, written `()`, has a single value, also written `()`. +The unit type, written `()`, has a single value, also written `()`. ## Operators @@ -852,7 +852,7 @@ fn line(a: int, b: int, x: int) -> int { It's better Rust style to write a return value this way instead of writing an explicit `return`. The utility of `return` comes in when returning early from a function. Functions that do not return a value -are said to return nil, `()`, and both the return type and the return +are said to return unit, `()`, and both the return type and the return value may be omitted from the definition. The following two functions are equivalent. diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 6ba1c86fdf286..b41af9eb05430 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -34,7 +34,6 @@ use std::cast; use std::cell::{Cell, RefCell}; use std::mem; use std::num; -use std::ptr; use std::kinds::marker; use std::rc::Rc; use std::rt::global_heap; @@ -144,7 +143,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) { let fill = chunk.fill.get(); while idx < fill { - let tydesc_data: *uint = transmute(ptr::offset(buf, idx as int)); + let tydesc_data: *uint = transmute(buf.offset(idx as int)); let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data); let (size, align) = ((*tydesc).size, (*tydesc).align); @@ -155,7 +154,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) { //debug!("freeing object: idx = {}, size = {}, align = {}, done = {}", // start, size, align, is_done); if is_done { - ((*tydesc).drop_glue)(ptr::offset(buf, start as int) as *i8); + ((*tydesc).drop_glue)(buf.offset(start as int) as *i8); } // Find where the next tydesc lives @@ -261,7 +260,7 @@ impl Arena { // start, n_bytes, align, head.fill); let buf = self.head.as_ptr(); - return (ptr::offset(buf, tydesc_start as int), ptr::offset(buf, start as int)); + return (buf.offset(tydesc_start as int), buf.offset(start as int)); } } diff --git a/src/libextra/c_vec.rs b/src/libextra/c_vec.rs index 35a6ccaa7083c..fec5b105c4b18 100644 --- a/src/libextra/c_vec.rs +++ b/src/libextra/c_vec.rs @@ -119,7 +119,7 @@ impl CVec { pub fn get<'a>(&'a self, ofs: uint) -> &'a T { assert!(ofs < self.len); unsafe { - &*ptr::mut_offset(self.base, ofs as int) + &*self.base.offset(ofs as int) } } @@ -131,7 +131,7 @@ impl CVec { pub fn get_mut<'a>(&'a mut self, ofs: uint) -> &'a mut T { assert!(ofs < self.len); unsafe { - &mut *ptr::mut_offset(self.base, ofs as int) + &mut *self.base.offset(ofs as int) } } diff --git a/src/libextra/lib.rs b/src/libextra/lib.rs index 70a21da6816d8..e0200f48cfeca 100644 --- a/src/libextra/lib.rs +++ b/src/libextra/lib.rs @@ -59,11 +59,9 @@ pub mod url; pub mod json; pub mod tempfile; pub mod time; -pub mod base64; pub mod workcache; pub mod enum_set; pub mod stats; -pub mod hex; #[cfg(unicode)] mod unicode; diff --git a/src/libnum/bigint.rs b/src/libnum/bigint.rs index 56385c6f43b4d..8f632ae639dcc 100644 --- a/src/libnum/bigint.rs +++ b/src/libnum/bigint.rs @@ -784,11 +784,12 @@ impl BigUint { if n_bits == 0 || self.data.is_empty() { return (*self).clone(); } let mut borrow = 0; - let mut shifted = ~[]; + let mut shifted_rev = vec::with_capacity(self.data.len()); for elem in self.data.rev_iter() { - shifted = ~[(*elem >> n_bits) | borrow] + shifted; + shifted_rev.push((*elem >> n_bits) | borrow); borrow = *elem << (BigDigit::bits - n_bits); } + let shifted = { shifted_rev.reverse(); shifted_rev }; return BigUint::new(shifted); } @@ -2637,4 +2638,15 @@ mod bench { fib.to_str(); }); } + + #[bench] + fn shr(bh: &mut BenchHarness) { + let n = { let one : BigUint = One::one(); one << 1000 }; + bh.iter(|| { + let mut m = n.clone(); + for _ in range(0, 10) { + m = m >> 1; + } + }) + } } diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 72ae70565a750..957ca3b46c9d1 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -34,7 +34,7 @@ use std::run; use std::str; use std::io; use std::io::fs; -use extra::hex::ToHex; +use serialize::hex::ToHex; use extra::tempfile::TempDir; use syntax::abi; use syntax::ast; diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index abcd650ced131..70b93a9813535 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -30,7 +30,6 @@ use std::io; use std::num; use std::option; use std::os::consts::{macos, freebsd, linux, android, win32}; -use std::ptr; use std::str; use std::vec; use flate; @@ -340,7 +339,7 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Option { }); if !version_ok { return None; } - let cvbuf1 = ptr::offset(cvbuf, vlen as int); + let cvbuf1 = cvbuf.offset(vlen as int); debug!("inflating {} bytes of compressed metadata", csz - vlen); vec::raw::buf_as_slice(cvbuf1, csz-vlen, |bytes| { diff --git a/src/librustc/middle/trans/builder.rs b/src/librustc/middle/trans/builder.rs index e4eeaa5fded7f..b8d16f9bb8006 100644 --- a/src/librustc/middle/trans/builder.rs +++ b/src/librustc/middle/trans/builder.rs @@ -21,7 +21,6 @@ use std::cast; use std::hashmap::HashMap; use std::libc::{c_uint, c_ulonglong, c_char}; use syntax::codemap::Span; -use std::ptr::is_not_null; pub struct Builder<'a> { llbuilder: BuilderRef, @@ -492,7 +491,7 @@ impl<'a> Builder<'a> { debug!("Store {} -> {}", self.ccx.tn.val_to_str(val), self.ccx.tn.val_to_str(ptr)); - assert!(is_not_null(self.llbuilder)); + assert!(self.llbuilder.is_not_null()); self.count_insn("store"); unsafe { llvm::LLVMBuildStore(self.llbuilder, val, ptr); @@ -503,7 +502,7 @@ impl<'a> Builder<'a> { debug!("Store {} -> {}", self.ccx.tn.val_to_str(val), self.ccx.tn.val_to_str(ptr)); - assert!(is_not_null(self.llbuilder)); + assert!(self.llbuilder.is_not_null()); self.count_insn("store.volatile"); unsafe { let insn = llvm::LLVMBuildStore(self.llbuilder, val, ptr); diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 9eec804dd2e11..68511362f5ffc 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3035,6 +3035,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt, if type_is_c_like_enum(fcx, expr.span, t_e) && t_1_is_trivial { // casts from C-like enums are allowed } else if t_1_is_char { + let te = fcx.infcx().resolve_type_vars_if_possible(te); if ty::get(te).sty != ty::ty_uint(ast::TyU8) { fcx.type_error_message(expr.span, |actual| { format!("only `u8` can be cast as `char`, not `{}`", actual) diff --git a/src/librustc/util/sha2.rs b/src/librustc/util/sha2.rs index 116ec6bba2904..940cebf78471e 100644 --- a/src/librustc/util/sha2.rs +++ b/src/librustc/util/sha2.rs @@ -16,7 +16,7 @@ use std::iter::range_step; use std::num::Zero; use std::vec; use std::vec::bytes::{MutableByteVector, copy_memory}; -use extra::hex::ToHex; +use serialize::hex::ToHex; /// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian /// format. @@ -529,7 +529,7 @@ mod tests { use std::vec; use std::rand::isaac::IsaacRng; use std::rand::Rng; - use extra::hex::FromHex; + use serialize::hex::FromHex; // A normal addition - no overflow occurs #[test] diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs index ca7f502a2e82d..eb0b4597e3007 100644 --- a/src/librustdoc/clean.rs +++ b/src/librustdoc/clean.rs @@ -342,7 +342,9 @@ impl Clean for ast::Method { _ => self.decl.inputs.slice_from(1) }; let decl = FnDecl { - inputs: inputs.iter().map(|x| x.clean()).collect(), + inputs: Arguments { + values: inputs.iter().map(|x| x.clean()).collect(), + }, output: (self.decl.output.clean()), cf: self.decl.cf.clean(), attrs: ~[] @@ -378,7 +380,9 @@ impl Clean for ast::TypeMethod { _ => self.decl.inputs.slice_from(1) }; let decl = FnDecl { - inputs: inputs.iter().map(|x| x.clean()).collect(), + inputs: Arguments { + values: inputs.iter().map(|x| x.clean()).collect(), + }, output: (self.decl.output.clean()), cf: self.decl.cf.clean(), attrs: ~[] @@ -472,16 +476,23 @@ impl Clean for ast::ClosureTy { #[deriving(Clone, Encodable, Decodable)] pub struct FnDecl { - inputs: ~[Argument], + inputs: Arguments, output: Type, cf: RetStyle, attrs: ~[Attribute] } +#[deriving(Clone, Encodable, Decodable)] +pub struct Arguments { + values: ~[Argument], +} + impl Clean for ast::FnDecl { fn clean(&self) -> FnDecl { FnDecl { - inputs: self.inputs.iter().map(|x| x.clean()).collect(), + inputs: Arguments { + values: self.inputs.iter().map(|x| x.clean()).collect(), + }, output: (self.output.clean()), cf: self.cf.clean(), attrs: ~[] diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 024d010f0b927..3e5afc399b962 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -404,6 +404,19 @@ impl fmt::Show for clean::Type { } } +impl fmt::Show for clean::Arguments { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for (i, input) in self.values.iter().enumerate() { + if i > 0 { if_ok!(write!(f.buf, ", ")); } + if input.name.len() > 0 { + if_ok!(write!(f.buf, "{}: ", input.name)); + } + if_ok!(write!(f.buf, "{}", input.type_)); + } + Ok(()) + } +} + impl fmt::Show for clean::FnDecl { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f.buf, "({args}){arrow, select, yes{ -> {ret}} other{}}", @@ -413,20 +426,6 @@ impl fmt::Show for clean::FnDecl { } } -impl fmt::Show for ~[clean::Argument] { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut args = ~""; - for (i, input) in self.iter().enumerate() { - if i > 0 { args.push_str(", "); } - if input.name.len() > 0 { - args.push_str(format!("{}: ", input.name)); - } - args.push_str(format!("{}", input.type_)); - } - f.buf.write(args.as_bytes()) - } -} - impl<'a> fmt::Show for Method<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let Method(selfty, d) = *self; @@ -448,7 +447,7 @@ impl<'a> fmt::Show for Method<'a> { args.push_str("&self"); } } - for (i, input) in d.inputs.iter().enumerate() { + for (i, input) in d.inputs.values.iter().enumerate() { if i > 0 || args.len() > 0 { args.push_str(", "); } if input.name.len() > 0 { args.push_str(format!("{}: ", input.name)); diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs index b463bb7fd733d..b71dbe05ad2b6 100644 --- a/src/librustuv/lib.rs +++ b/src/librustuv/lib.rs @@ -426,7 +426,7 @@ mod test { unsafe { let base = transmute::<*u8, *mut u8>(buf.base); (*base) = 1; - (*ptr::mut_offset(base, 1)) = 2; + (*base.offset(1)) = 2; } assert!(slice[0] == 1); diff --git a/src/libextra/base64.rs b/src/libserialize/base64.rs similarity index 97% rename from src/libextra/base64.rs rename to src/libserialize/base64.rs index 556032af1ac84..c22eefdb33020 100644 --- a/src/libextra/base64.rs +++ b/src/libserialize/base64.rs @@ -63,8 +63,8 @@ impl<'a> ToBase64 for &'a [u8] { * # Example * * ```rust - * extern mod extra; - * use extra::base64::{ToBase64, STANDARD}; + * extern mod serialize; + * use serialize::base64::{ToBase64, STANDARD}; * * fn main () { * let str = [52,32].to_base64(STANDARD); @@ -189,8 +189,8 @@ impl<'a> FromBase64 for &'a str { * This converts a string literal to base64 and back. * * ```rust - * extern mod extra; - * use extra::base64::{ToBase64, FromBase64, STANDARD}; + * extern mod serialize; + * use serialize::base64::{ToBase64, FromBase64, STANDARD}; * use std::str; * * fn main () { @@ -261,8 +261,8 @@ impl<'a> FromBase64 for &'a str { #[cfg(test)] mod test { - use test::BenchHarness; - use base64::*; + use extra::test::BenchHarness; + use base64::{Config, FromBase64, ToBase64, STANDARD, URL_SAFE}; #[test] fn test_to_base64_basic() { diff --git a/src/libserialize/ebml.rs b/src/libserialize/ebml.rs index f08f943306fcf..3d57a32a830b2 100644 --- a/src/libserialize/ebml.rs +++ b/src/libserialize/ebml.rs @@ -131,7 +131,6 @@ pub mod reader { } pub fn vuint_at(data: &[u8], start: uint) -> Res { - use std::ptr::offset; use std::mem::from_be32; if data.len() - start < 4 { @@ -163,7 +162,7 @@ pub mod reader { unsafe { let (ptr, _): (*u8, uint) = transmute(data); - let ptr = offset(ptr, start as int); + let ptr = ptr.offset(start as int); let ptr: *i32 = transmute(ptr); let val = from_be32(*ptr) as u32; diff --git a/src/libextra/hex.rs b/src/libserialize/hex.rs similarity index 96% rename from src/libextra/hex.rs rename to src/libserialize/hex.rs index d4e1ae123378e..409bf4af80992 100644 --- a/src/libextra/hex.rs +++ b/src/libserialize/hex.rs @@ -28,7 +28,8 @@ impl<'a> ToHex for &'a [u8] { * # Example * * ```rust - * use extra::hex::ToHex; + * extern mod serialize; + * use serialize::hex::ToHex; * * fn main () { * let str = [52,32].to_hex(); @@ -88,7 +89,8 @@ impl<'a> FromHex for &'a str { * This converts a string literal to hexadecimal and back. * * ```rust - * use extra::hex::{FromHex, ToHex}; + * extern mod serialize; + * use serialize::hex::{FromHex, ToHex}; * use std::str; * * fn main () { @@ -137,8 +139,8 @@ impl<'a> FromHex for &'a str { #[cfg(test)] mod tests { - use test::BenchHarness; - use hex::*; + use extra::test::BenchHarness; + use hex::{FromHex, ToHex}; #[test] pub fn test_to_hex() { diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 5f473b253697c..3b71b2237b176 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -30,4 +30,8 @@ pub use self::serialize::{Decoder, Encoder, Decodable, Encodable, DecoderHelpers, EncoderHelpers}; mod serialize; + +pub mod base64; pub mod ebml; +pub mod hex; + diff --git a/src/libstd/any.rs b/src/libstd/any.rs index 24da59341ccdd..3f14db14882ec 100644 --- a/src/libstd/any.rs +++ b/src/libstd/any.rs @@ -21,6 +21,7 @@ //! extension traits (`*Ext`) for the full details. use cast::transmute; +use fmt; use option::{Option, Some, None}; use result::{Result, Ok, Err}; use to_str::ToStr; @@ -158,6 +159,18 @@ impl<'a> ToStr for &'a Any { fn to_str(&self) -> ~str { ~"&Any" } } +impl fmt::Show for ~Any { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad("~Any") + } +} + +impl<'a> fmt::Show for &'a Any { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad("&Any") + } +} + #[cfg(test)] mod tests { use prelude::*; @@ -377,4 +390,17 @@ mod tests { assert!(a.move::<~Test>().is_err()); assert!(b.move::<~uint>().is_err()); } + + #[test] + fn test_show() { + let a = ~8u as ~Any; + let b = ~Test as ~Any; + assert_eq!(format!("{}", a), ~"~Any"); + assert_eq!(format!("{}", b), ~"~Any"); + + let a = &8u as &Any; + let b = &Test as &Any; + assert_eq!(format!("{}", a), ~"&Any"); + assert_eq!(format!("{}", b), ~"&Any"); + } } diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 7965127007c1c..651d364dd1b97 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -17,6 +17,7 @@ use str::StrSlice; use str::OwnedStr; use container::Container; use cast; +use fmt; use iter::Iterator; use vec::{ImmutableVector, MutableVector, Vector}; use to_bytes::IterBytes; @@ -134,6 +135,12 @@ impl ToStr for Ascii { } } +impl<'a> fmt::Show for Ascii { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + (self.chr as char).fmt(f) + } +} + /// Trait for converting into an ascii type. pub trait AsciiCast { /// Convert to an ascii type, fail on non-ASCII input. @@ -698,5 +705,9 @@ mod tests { assert_eq!(s, ~"t"); } - + #[test] + fn test_show() { + let c = Ascii { chr: 't' as u8 }; + assert_eq!(format!("{}", c), ~"t"); + } } diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs index cc6cd7666d642..fe332a60efa44 100644 --- a/src/libstd/c_str.rs +++ b/src/libstd/c_str.rs @@ -310,7 +310,7 @@ impl<'a> ToCStr for &'a [u8] { let buf = malloc_raw(self_len + 1); ptr::copy_memory(buf, self.as_ptr(), self_len); - *ptr::mut_offset(buf, self_len as int) = 0; + *buf.offset(self_len as int) = 0; CString::new(buf as *libc::c_char, true) } @@ -368,7 +368,7 @@ impl<'a> Iterator for CChars<'a> { if ch == 0 { None } else { - self.ptr = unsafe { ptr::offset(self.ptr, 1) }; + self.ptr = unsafe { self.ptr.offset(1) }; Some(ch) } } @@ -429,18 +429,18 @@ mod tests { fn test_str_to_c_str() { "".to_c_str().with_ref(|buf| { unsafe { - assert_eq!(*ptr::offset(buf, 0), 0); + assert_eq!(*buf.offset(0), 0); } }); "hello".to_c_str().with_ref(|buf| { unsafe { - assert_eq!(*ptr::offset(buf, 0), 'h' as libc::c_char); - assert_eq!(*ptr::offset(buf, 1), 'e' as libc::c_char); - assert_eq!(*ptr::offset(buf, 2), 'l' as libc::c_char); - assert_eq!(*ptr::offset(buf, 3), 'l' as libc::c_char); - assert_eq!(*ptr::offset(buf, 4), 'o' as libc::c_char); - assert_eq!(*ptr::offset(buf, 5), 0); + assert_eq!(*buf.offset(0), 'h' as libc::c_char); + assert_eq!(*buf.offset(1), 'e' as libc::c_char); + assert_eq!(*buf.offset(2), 'l' as libc::c_char); + assert_eq!(*buf.offset(3), 'l' as libc::c_char); + assert_eq!(*buf.offset(4), 'o' as libc::c_char); + assert_eq!(*buf.offset(5), 0); } }) } @@ -450,28 +450,28 @@ mod tests { let b: &[u8] = []; b.to_c_str().with_ref(|buf| { unsafe { - assert_eq!(*ptr::offset(buf, 0), 0); + assert_eq!(*buf.offset(0), 0); } }); let _ = bytes!("hello").to_c_str().with_ref(|buf| { unsafe { - assert_eq!(*ptr::offset(buf, 0), 'h' as libc::c_char); - assert_eq!(*ptr::offset(buf, 1), 'e' as libc::c_char); - assert_eq!(*ptr::offset(buf, 2), 'l' as libc::c_char); - assert_eq!(*ptr::offset(buf, 3), 'l' as libc::c_char); - assert_eq!(*ptr::offset(buf, 4), 'o' as libc::c_char); - assert_eq!(*ptr::offset(buf, 5), 0); + assert_eq!(*buf.offset(0), 'h' as libc::c_char); + assert_eq!(*buf.offset(1), 'e' as libc::c_char); + assert_eq!(*buf.offset(2), 'l' as libc::c_char); + assert_eq!(*buf.offset(3), 'l' as libc::c_char); + assert_eq!(*buf.offset(4), 'o' as libc::c_char); + assert_eq!(*buf.offset(5), 0); } }); let _ = bytes!("foo", 0xff).to_c_str().with_ref(|buf| { unsafe { - assert_eq!(*ptr::offset(buf, 0), 'f' as libc::c_char); - assert_eq!(*ptr::offset(buf, 1), 'o' as libc::c_char); - assert_eq!(*ptr::offset(buf, 2), 'o' as libc::c_char); - assert_eq!(*ptr::offset(buf, 3), 0xff as i8); - assert_eq!(*ptr::offset(buf, 4), 0); + assert_eq!(*buf.offset(0), 'f' as libc::c_char); + assert_eq!(*buf.offset(1), 'o' as libc::c_char); + assert_eq!(*buf.offset(2), 'o' as libc::c_char); + assert_eq!(*buf.offset(3), 0xff as i8); + assert_eq!(*buf.offset(4), 0); } }); } @@ -634,7 +634,6 @@ mod bench { use extra::test::BenchHarness; use libc; use prelude::*; - use ptr; #[inline] fn check(s: &str, c_str: *libc::c_char) { @@ -642,8 +641,8 @@ mod bench { for i in range(0, s.len()) { unsafe { assert_eq!( - *ptr::offset(s_buf, i as int) as libc::c_char, - *ptr::offset(c_str, i as int)); + *s_buf.offset(i as int) as libc::c_char, + *c_str.offset(i as int)); } } } diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 953cc66a2cbcc..c49294a095f29 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -56,6 +56,7 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet}; use clone::Clone; use cmp::{Eq, Equiv}; use default::Default; +#[cfg(not(stage0))] use fmt; use hash::Hash; use iter; use iter::{Iterator, FromIterator, Extendable}; @@ -65,6 +66,7 @@ use num; use option::{None, Option, Some}; use rand::Rng; use rand; +#[cfg(not(stage0))] use result::{Ok, Err}; use vec::{ImmutableVector, MutableVector, OwnedVector, Items, MutItems}; use vec_ng; use vec_ng::Vec; @@ -595,6 +597,23 @@ impl Clone for HashMap { } } +#[cfg(not(stage0))] +impl fmt::Show for HashMap { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if_ok!(write!(f.buf, r"\{")) + let mut first = true; + for (key, value) in self.iter() { + if first { + first = false; + } else { + if_ok!(write!(f.buf, ", ")); + } + if_ok!(write!(f.buf, "{}: {}", *key, *value)); + } + write!(f.buf, r"\}") + } +} + /// HashMap iterator #[deriving(Clone)] pub struct Entries<'a, K, V> { @@ -857,6 +876,23 @@ impl Clone for HashSet { } } +#[cfg(not(stage0))] +impl fmt::Show for HashSet { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if_ok!(write!(f.buf, r"\{")) + let mut first = true; + for x in self.iter() { + if first { + first = false; + } else { + if_ok!(write!(f.buf, ", ")); + } + if_ok!(write!(f.buf, "{}", *x)); + } + write!(f.buf, r"\}") + } +} + impl FromIterator for HashSet { fn from_iterator>(iter: &mut T) -> HashSet { let (lower, _) = iter.size_hint(); @@ -890,6 +926,7 @@ pub type SetAlgebraItems<'a, T> = mod test_map { use prelude::*; use super::*; + use fmt; #[test] fn test_create_capacity_zero() { @@ -1121,6 +1158,30 @@ mod test_map { assert_eq!(map.find(&k), Some(&v)); } } + + struct ShowableStruct { + value: int, + } + + impl fmt::Show for ShowableStruct { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f.buf, r"s{}", self.value) + } + } + + #[test] + fn test_show() { + let mut table: HashMap = HashMap::new(); + let empty: HashMap = HashMap::new(); + + table.insert(3, ShowableStruct { value: 4 }); + table.insert(1, ShowableStruct { value: 2 }); + + let table_str = format!("{}", table); + + assert!(table_str == ~"{1: s2, 3: s4}" || table_str == ~"{3: s4, 1: s2}"); + assert_eq!(format!("{}", empty), ~"{}"); + } } #[cfg(test)] @@ -1346,4 +1407,18 @@ mod test_set { assert_eq!(s1, s2); } + + #[test] + fn test_show() { + let mut set: HashSet = HashSet::new(); + let empty: HashSet = HashSet::new(); + + set.insert(1); + set.insert(2); + + let set_str = format!("{}", set); + + assert!(set_str == ~"{1, 2}" || set_str == ~"{2, 1}"); + assert_eq!(format!("{}", empty), ~"{}"); + } } diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs index 240f4c65501dc..da4697d0e4880 100644 --- a/src/libstd/io/extensions.rs +++ b/src/libstd/io/extensions.rs @@ -18,6 +18,7 @@ use iter::Iterator; use option::Option; use io::Reader; use vec::{OwnedVector, ImmutableVector}; +use ptr::RawPtr; /// An iterator that reads a single byte on each iteration, /// until `.read_byte()` returns `None`. @@ -104,7 +105,7 @@ pub fn u64_from_be_bytes(data: &[u8], start: uint, size: uint) -> u64 { - use ptr::{copy_nonoverlapping_memory, offset, mut_offset}; + use ptr::{copy_nonoverlapping_memory}; use mem::from_be64; use vec::MutableVector; @@ -116,9 +117,9 @@ pub fn u64_from_be_bytes(data: &[u8], let mut buf = [0u8, ..8]; unsafe { - let ptr = offset(data.as_ptr(), start as int); + let ptr = data.as_ptr().offset(start as int); let out = buf.as_mut_ptr(); - copy_nonoverlapping_memory(mut_offset(out, (8 - size) as int), ptr, size); + copy_nonoverlapping_memory(out.offset((8 - size) as int), ptr, size); from_be64(*(out as *i64)) as u64 } } diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index 80439d6989921..2ba6f7d4fd64d 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -21,23 +21,6 @@ use unstable::intrinsics; #[cfg(not(test))] use cmp::{Eq, Ord}; -/// Calculate the offset from a pointer. -/// The `count` argument is in units of T; e.g. a `count` of 3 -/// represents a pointer offset of `3 * sizeof::()` bytes. -#[inline] -pub unsafe fn offset(ptr: *T, count: int) -> *T { - intrinsics::offset(ptr, count) -} - -/// Calculate the offset from a mut pointer. The count *must* be in bounds or -/// otherwise the loads of this address are undefined. -/// The `count` argument is in units of T; e.g. a `count` of 3 -/// represents a pointer offset of `3 * sizeof::()` bytes. -#[inline] -pub unsafe fn mut_offset(ptr: *mut T, count: int) -> *mut T { - intrinsics::offset(ptr as *T, count) as *mut T -} - /// Return the offset of the first null pointer in `buf`. #[inline] pub unsafe fn buf_len(buf: **T) -> uint { @@ -63,7 +46,7 @@ impl Clone for *mut T { pub unsafe fn position(buf: *T, f: |&T| -> bool) -> uint { let mut i = 0; loop { - if f(&(*offset(buf, i as int))) { return i; } + if f(&(*buf.offset(i as int))) { return i; } else { i += 1; } } } @@ -76,14 +59,6 @@ pub fn null() -> *T { 0 as *T } #[inline] pub fn mut_null() -> *mut T { 0 as *mut T } -/// Returns true if the pointer is equal to the null pointer. -#[inline] -pub fn is_null>(ptr: P) -> bool { ptr.is_null() } - -/// Returns true if the pointer is not equal to the null pointer. -#[inline] -pub fn is_not_null>(ptr: P) -> bool { ptr.is_not_null() } - /** * Copies data from one location to another. * @@ -206,7 +181,7 @@ pub unsafe fn array_each_with_len(arr: **T, len: uint, cb: |*T|) { } //let start_ptr = *arr; for e in range(0, len) { - let n = offset(arr, e as int); + let n = arr.offset(e as int); cb(*n); } debug!("array_each_with_len: after iterate"); @@ -278,7 +253,7 @@ impl RawPtr for *T { /// Calculates the offset from a pointer. The offset *must* be in-bounds of /// the object, or one-byte-past-the-end. #[inline] - unsafe fn offset(self, count: int) -> *T { offset(self, count) } + unsafe fn offset(self, count: int) -> *T { intrinsics::offset(self, count) } } /// Extension methods for mutable pointers @@ -323,7 +298,7 @@ impl RawPtr for *mut T { /// This method should be preferred over `offset` when the guarantee can be /// satisfied, to enable better optimization. #[inline] - unsafe fn offset(self, count: int) -> *mut T { mut_offset(self, count) } + unsafe fn offset(self, count: int) -> *mut T { intrinsics::offset(self as *T, count) as *mut T } } // Equality for pointers @@ -478,14 +453,14 @@ pub mod ptr_tests { let v0 = ~[32000u16, 32001u16, 32002u16]; let mut v1 = ~[0u16, 0u16, 0u16]; - copy_memory(mut_offset(v1.as_mut_ptr(), 1), - offset(v0.as_ptr(), 1), 1); + copy_memory(v1.as_mut_ptr().offset(1), + v0.as_ptr().offset(1), 1); assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16)); copy_memory(v1.as_mut_ptr(), - offset(v0.as_ptr(), 2), 1); + v0.as_ptr().offset(2), 1); assert!((v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16)); - copy_memory(mut_offset(v1.as_mut_ptr(), 2), + copy_memory(v1.as_mut_ptr().offset(2), v0.as_ptr(), 1u); assert!((v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16)); @@ -525,7 +500,7 @@ pub mod ptr_tests { assert!(p.is_null()); assert!(!p.is_not_null()); - let q = unsafe { offset(p, 1) }; + let q = unsafe { p.offset(1) }; assert!(!q.is_null()); assert!(q.is_not_null()); diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index 4ced74a92b7c0..dbd1ea8e989ec 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -23,6 +23,7 @@ use io; use iter::Iterator; use option::{Some, None, Option}; use ptr; +use ptr::RawPtr; use reflect; use reflect::{MovePtr, align}; use result::{Ok, Err}; @@ -221,7 +222,7 @@ impl<'a> ReprVisitor<'a> { if_ok!(self, self.writer.write(", ".as_bytes())); } self.visit_ptr_inner(p as *u8, inner); - p = align(unsafe { ptr::offset(p, sz as int) as uint }, al) as *u8; + p = align(unsafe { p.offset(sz as int) as uint }, al) as *u8; left -= dec; } if_ok!(self, self.writer.write([']' as u8])); diff --git a/src/libstd/str.rs b/src/libstd/str.rs index bc5991c6eebd0..0d263d94ccf0f 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -1242,7 +1242,7 @@ pub mod raw { let mut i = 0; while *curr != 0 { i += 1; - curr = ptr::offset(buf, i); + curr = buf.offset(i); } from_buf_len(buf as *u8, i as uint) } @@ -1272,7 +1272,7 @@ pub mod raw { let mut len = 0u; while *curr != 0u8 { len += 1u; - curr = ptr::offset(s, len as int); + curr = s.offset(len as int); } let v = Slice { data: s, len: len }; assert!(is_utf8(::cast::transmute(v))); @@ -2921,7 +2921,6 @@ impl Default for ~str { mod tests { use iter::AdditiveIterator; use prelude::*; - use ptr; use str::*; #[test] @@ -3549,11 +3548,11 @@ mod tests { fn test_as_ptr() { let buf = "hello".as_ptr(); unsafe { - assert_eq!(*ptr::offset(buf, 0), 'h' as u8); - assert_eq!(*ptr::offset(buf, 1), 'e' as u8); - assert_eq!(*ptr::offset(buf, 2), 'l' as u8); - assert_eq!(*ptr::offset(buf, 3), 'l' as u8); - assert_eq!(*ptr::offset(buf, 4), 'o' as u8); + assert_eq!(*buf.offset(0), 'h' as u8); + assert_eq!(*buf.offset(1), 'e' as u8); + assert_eq!(*buf.offset(2), 'l' as u8); + assert_eq!(*buf.offset(3), 'l' as u8); + assert_eq!(*buf.offset(4), 'o' as u8); } } @@ -4164,6 +4163,7 @@ mod tests { assert_eq!(s.len(), 5); assert_eq!(s.as_slice(), "abcde"); assert_eq!(s.to_str(), ~"abcde"); + assert_eq!(format!("{}", s), ~"abcde"); assert!(s.lt(&Owned(~"bcdef"))); assert_eq!(Slice(""), Default::default()); @@ -4171,6 +4171,7 @@ mod tests { assert_eq!(o.len(), 5); assert_eq!(o.as_slice(), "abcde"); assert_eq!(o.to_str(), ~"abcde"); + assert_eq!(format!("{}", o), ~"abcde"); assert!(o.lt(&Slice("bcdef"))); assert_eq!(Owned(~""), Default::default()); diff --git a/src/libstd/unit.rs b/src/libstd/unit.rs index 3aa3e020500ea..b23dafbca6970 100644 --- a/src/libstd/unit.rs +++ b/src/libstd/unit.rs @@ -14,6 +14,7 @@ use default::Default; #[cfg(not(test))] use cmp::{Eq, Equal, Ord, Ordering, TotalEq, TotalOrd}; +use fmt; #[cfg(not(test))] impl Eq for () { @@ -46,3 +47,9 @@ impl Default for () { #[inline] fn default() -> () { () } } + +impl fmt::Show for () { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad("()") + } +} diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 2acafecf95720..c67b19933d37f 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -108,6 +108,7 @@ use container::{Container, Mutable}; use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater}; use cmp; use default::Default; +#[cfg(not(stage0))] use fmt; use iter::*; use num::{Integer, CheckedAdd, Saturating, checked_next_power_of_two}; use option::{None, Option, Some}; @@ -115,6 +116,7 @@ use ptr::to_unsafe_ptr; use ptr; use ptr::RawPtr; use rt::global_heap::{malloc_raw, realloc_raw, exchange_free}; +#[cfg(not(stage0))] use result::{Ok, Err}; use mem; use mem::size_of; use kinds::marker; @@ -137,7 +139,7 @@ pub fn from_fn(n_elts: uint, op: |uint| -> T) -> ~[T] { &mut i, (), |i, ()| while *i < n_elts { mem::move_val_init( - &mut(*ptr::mut_offset(p, *i as int)), + &mut(*p.offset(*i as int)), op(*i)); *i += 1u; }, @@ -165,7 +167,7 @@ pub fn from_elem(n_elts: uint, t: T) -> ~[T] { &mut i, (), |i, ()| while *i < n_elts { mem::move_val_init( - &mut(*ptr::mut_offset(p, *i as int)), + &mut(*p.offset(*i as int)), t.clone()); *i += 1u; }, @@ -1495,7 +1497,7 @@ impl OwnedVector for ~[T] { let fill = (**repr).fill; (**repr).fill += mem::nonzero_size_of::(); let p = to_unsafe_ptr(&((**repr).data)); - let p = ptr::offset(p, fill as int) as *mut T; + let p = p.offset(fill as int) as *mut T; mem::move_val_init(&mut(*p), t); } } @@ -1509,7 +1511,7 @@ impl OwnedVector for ~[T] { unsafe { // Note: infallible. let self_p = self.as_mut_ptr(); let rhs_p = rhs.as_ptr(); - ptr::copy_memory(ptr::mut_offset(self_p, self_len as int), rhs_p, rhs_len); + ptr::copy_memory(self_p.offset(self_len as int), rhs_p, rhs_len); self.set_len(new_len); rhs.set_len(0); } @@ -1796,11 +1798,11 @@ impl OwnedEqVector for ~[T] { let mut w = 1; while r < ln { - let p_r = ptr::mut_offset(p, r as int); - let p_wm1 = ptr::mut_offset(p, (w - 1) as int); + let p_r = p.offset(r as int); + let p_wm1 = p.offset((w - 1) as int); if *p_r != *p_wm1 { if r != w { - let p_w = ptr::mut_offset(p_wm1, 1); + let p_w = p_wm1.offset(1); mem::swap(&mut *p_r, &mut *p_w); } w += 1; @@ -2383,7 +2385,7 @@ impl<'a,T> MutableVector<'a, T> for &'a mut [T] { #[inline] unsafe fn unsafe_mut_ref(self, index: uint) -> &'a mut T { - cast::transmute(ptr::mut_offset(self.repr().data as *mut T, index as int)) + cast::transmute((self.repr().data as *mut T).offset(index as int)) } #[inline] @@ -2484,6 +2486,7 @@ pub unsafe fn from_buf(ptr: *T, elts: uint) -> ~[T] { pub mod raw { use cast; use ptr; + use ptr::RawPtr; use vec::{with_capacity, MutableVector, OwnedVector}; use unstable::raw::Slice; @@ -2542,7 +2545,7 @@ pub mod raw { pub unsafe fn shift_ptr(slice: &mut Slice) -> *T { if slice.len == 0 { fail!("shift on empty slice"); } let head: *T = slice.data; - slice.data = ptr::offset(slice.data, 1); + slice.data = slice.data.offset(1); slice.len -= 1; head } @@ -2554,7 +2557,7 @@ pub mod raw { */ pub unsafe fn pop_ptr(slice: &mut Slice) -> *T { if slice.len == 0 { fail!("pop on empty slice"); } - let tail: *T = ptr::offset(slice.data, (slice.len - 1) as int); + let tail: *T = slice.data.offset((slice.len - 1) as int); slice.len -= 1; tail } @@ -2640,6 +2643,30 @@ impl DeepClone for ~[A] { } } +#[cfg(not(stage0))] +impl<'a, T: fmt::Show> fmt::Show for &'a [T] { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if_ok!(write!(f.buf, "[")); + let mut is_first = true; + for x in self.iter() { + if is_first { + is_first = false; + } else { + if_ok!(write!(f.buf, ", ")); + } + if_ok!(write!(f.buf, "{}", *x)) + } + write!(f.buf, "]") + } +} + +#[cfg(not(stage0))] +impl fmt::Show for ~[T] { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.as_slice().fmt(f) + } +} + // This works because every lifetime is a sub-lifetime of 'static impl<'a, A> Default for &'a [A] { fn default() -> &'a [A] { &'a [] } @@ -4049,6 +4076,22 @@ mod tests { assert_eq!(values, [1,4,3,2,5]); } + #[test] + fn test_show() { + macro_rules! test_show_vec( + ($x:expr, $x_str:expr) => ({ + let (x, x_str) = ($x, $x_str); + assert_eq!(format!("{}", x), x_str); + assert_eq!(format!("{}", x.as_slice()), x_str); + }) + ) + let empty: ~[int] = ~[]; + test_show_vec!(empty, ~"[]"); + test_show_vec!(~[1], ~"[1]"); + test_show_vec!(~[1, 2, 3], ~"[1, 2, 3]"); + test_show_vec!(~[~[], ~[1u], ~[1u, 1u]], ~"[[], [1], [1, 1]]"); + } + #[test] fn test_vec_default() { use default::Default; diff --git a/src/libstd/vec_ng.rs b/src/libstd/vec_ng.rs index 90bc583624012..25ba45021b3fa 100644 --- a/src/libstd/vec_ng.rs +++ b/src/libstd/vec_ng.rs @@ -22,7 +22,8 @@ use cast::{forget, transmute}; use rt::global_heap::{malloc_raw, realloc_raw}; use vec::{ImmutableVector, Items, MutableVector}; use unstable::raw::Slice; -use ptr::{offset, read_ptr}; +use ptr::read_ptr; +use ptr::RawPtr; use libc::{free, c_void}; pub struct Vec { @@ -135,7 +136,7 @@ impl Vec { } unsafe { - let end = offset(self.ptr as *T, self.len as int) as *mut T; + let end = (self.ptr as *T).offset(self.len as int) as *mut T; move_val_init(&mut *end, value); self.len += 1; } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index d22a1d697fcb4..02c3a1b985be3 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -20,7 +20,6 @@ use parse::token::{InternedString, intern, str_to_ident}; use util::small_vector::SmallVector; use std::hashmap::HashMap; -use std::unstable::dynamic_lib::DynamicLibrary; // new-style macro! tt code: // @@ -143,8 +142,6 @@ pub struct BlockInfo { macros_escape : bool, // what are the pending renames? pending_renames : RenameList, - // references for crates loaded in this scope - macro_crates: ~[DynamicLibrary], } impl BlockInfo { @@ -152,7 +149,6 @@ impl BlockInfo { BlockInfo { macros_escape: false, pending_renames: ~[], - macro_crates: ~[], } } } @@ -551,10 +547,6 @@ impl SyntaxEnv { self.find_escape_frame().map.insert(k, v); } - pub fn insert_macro_crate(&mut self, lib: DynamicLibrary) { - self.find_escape_frame().info.macro_crates.push(lib); - } - pub fn info<'a>(&'a mut self) -> &'a mut BlockInfo { &mut self.chain[self.chain.len()-1].info } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index d146cd4dae392..d79c4cbc96a9b 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -28,6 +28,7 @@ use visit; use visit::Visitor; use util::small_vector::SmallVector; +use std::cast; use std::vec; use std::unstable::dynamic_lib::DynamicLibrary; use std::os; @@ -469,9 +470,12 @@ fn load_extern_macros(crate: &ast::ViewItem, fld: &mut MacroExpander) { }; fld.extsbox.insert(name, extension); }); - } - fld.extsbox.insert_macro_crate(lib); + // Intentionally leak the dynamic library. We can't ever unload it + // since the library can do things that will outlive the expansion + // phase (e.g. make an @-box cycle or launch a task). + cast::forget(lib); + } } // expand a stmt diff --git a/src/test/auxiliary/macro_crate_outlive_expansion_phase.rs b/src/test/auxiliary/macro_crate_outlive_expansion_phase.rs new file mode 100644 index 0000000000000..eecbb325630d3 --- /dev/null +++ b/src/test/auxiliary/macro_crate_outlive_expansion_phase.rs @@ -0,0 +1,35 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// force-host + +#[feature(macro_registrar)]; + +extern mod syntax; + +use std::any::Any; +use std::local_data; +use syntax::ast::Name; +use syntax::ext::base::SyntaxExtension; + +struct Foo { + foo: int +} + +impl Drop for Foo { + fn drop(&mut self) {} +} + +#[macro_registrar] +pub fn registrar(_: |Name, SyntaxExtension|) { + local_data_key!(foo: ~Any); + local_data::set(foo, ~Foo { foo: 10 } as ~Any); +} + diff --git a/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs b/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs new file mode 100644 index 0000000000000..a71cc465e88dc --- /dev/null +++ b/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs @@ -0,0 +1,21 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:macro_crate_outlive_expansion_phase.rs +// ignore-stage1 +// ignore-fast +// ignore-android + +#[feature(phase)]; + +#[phase(syntax)] +extern mod macro_crate_outlive_expansion_phase; + +pub fn main() {} diff --git a/src/test/run-pass/issue-9918.rs b/src/test/run-pass/issue-9918.rs new file mode 100644 index 0000000000000..240a134221d34 --- /dev/null +++ b/src/test/run-pass/issue-9918.rs @@ -0,0 +1,13 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub fn main() { + assert_eq!((0 + 0u8) as char, '\0'); +}