diff --git a/configure b/configure index a5699cc56c9a6..1a2a79cb36bd3 100755 --- a/configure +++ b/configure @@ -453,12 +453,12 @@ valopt datadir "${CFG_PREFIX}/share" "install data" valopt infodir "${CFG_PREFIX}/share/info" "install additional info" valopt mandir "${CFG_PREFIX}/share/man" "install man pages in PATH" -valopt release-channel "source" "the name of the release channel to build" +valopt release-channel "dev" "the name of the release channel to build" # On windows we just store the libraries in the bin directory because # there's no rpath. This is where the build system itself puts libraries; # --libdir is used to configure the installation directory. -# FIXME: Thise needs to parameterized over target triples. Do it in platform.mk +# FIXME: This needs to parameterized over target triples. Do it in platform.mk CFG_LIBDIR_RELATIVE=lib if [ "$CFG_OSTYPE" = "pc-mingw32" ] || [ "$CFG_OSTYPE" = "w64-mingw32" ] then @@ -479,10 +479,10 @@ validate_opt # Validate the release channel case "$CFG_RELEASE_CHANNEL" in - (source | nightly | beta | stable) + (dev | nightly | beta | stable) ;; (*) - err "release channel must be 'source', 'nightly', 'beta' or 'stable'" + err "release channel must be 'dev', 'nightly', 'beta' or 'stable'" ;; esac diff --git a/mk/crates.mk b/mk/crates.mk index ed3fce775f31e..9f01ff23c7fc9 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -71,7 +71,7 @@ DEPS_graphviz := std DEPS_green := std native:context_switch DEPS_rustuv := std native:uv native:uv_support DEPS_native := std -DEPS_syntax := std term serialize log fmt_macros debug arena +DEPS_syntax := std term serialize log fmt_macros debug arena libc DEPS_rustc := syntax flate arena serialize getopts rbml \ time log graphviz debug rustc_llvm rustc_back DEPS_rustc_llvm := native:rustllvm libc std diff --git a/mk/main.mk b/mk/main.mk index 6667a29d4f956..a4bac74aace04 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -35,9 +35,9 @@ ifeq ($(CFG_RELEASE_CHANNEL),nightly) CFG_RELEASE=$(CFG_RELEASE_NUM)-nightly CFG_PACKAGE_VERS=nightly endif -ifeq ($(CFG_RELEASE_CHANNEL),source) -CFG_RELEASE=$(CFG_RELEASE_NUM)-pre -CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-pre +ifeq ($(CFG_RELEASE_CHANNEL),dev) +CFG_RELEASE=$(CFG_RELEASE_NUM)-dev +CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-dev endif # The name of the package to use for creating tarballs, installers etc. diff --git a/src/doc/guide.md b/src/doc/guide.md index cab31fc5a9ac1..0474e5a31ce1d 100644 --- a/src/doc/guide.md +++ b/src/doc/guide.md @@ -4325,8 +4325,6 @@ and so we tell it that we want a vector of integers. is one: ```{rust} -let one_to_one_hundred = range(0i, 100i); - let greater_than_forty_two = range(0i, 100i) .find(|x| *x >= 42); diff --git a/src/etc/pkg/rust.iss b/src/etc/pkg/rust.iss index 08c28c4399bdd..fe2107943c576 100644 --- a/src/etc/pkg/rust.iss +++ b/src/etc/pkg/rust.iss @@ -8,7 +8,7 @@ SetupIconFile=rust-logo.ico AppName=Rust AppVersion={#CFG_RELEASE} -AppCopyright=Copyright (C) 2006-2013 Mozilla Foundation, MIT license +AppCopyright=Copyright (C) 2006-2014 Mozilla Foundation, MIT license AppPublisher=Mozilla Foundation AppPublisherURL=http://www.rust-lang.org VersionInfoVersion={#CFG_VERSION_WIN} @@ -43,7 +43,7 @@ Source: "tmp/dist/win/*.*" ; DestDir: "{app}"; Flags: ignoreversion recursesubdi [Code] const ModPathName = 'modifypath'; - ModPathType = 'user'; + ModPathType = 'system'; function ModPathDir(): TArrayOfString; begin diff --git a/src/grammar/RustLexer.g4 b/src/grammar/RustLexer.g4 index f2705e5421b9b..e8165dabce5cd 100644 --- a/src/grammar/RustLexer.g4 +++ b/src/grammar/RustLexer.g4 @@ -120,10 +120,9 @@ LIT_INTEGER | '0x' [0-9a-fA-F][0-9a-fA-F_]* INT_SUFFIX? ; -FLOAT_SUFFIX +fragment FLOAT_SUFFIX : 'f32' | 'f64' - | 'f128' ; LIT_FLOAT diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 13d4a0a1f0a08..168d0daeb3845 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -96,12 +96,6 @@ pub trait BoxAny { /// `Err(Self)` if it isn't. #[unstable = "naming conventions around accessing innards may change"] fn downcast(self) -> Result, Self>; - - /// Deprecated; this method has been renamed to `downcast`. - #[deprecated = "use downcast instead"] - fn move(self) -> Result, Self> { - self.downcast::() - } } #[stable] diff --git a/src/liballoc/util.rs b/src/liballoc/util.rs index 7e35af79eab1c..d5f0d25fb01f9 100644 --- a/src/liballoc/util.rs +++ b/src/liballoc/util.rs @@ -16,7 +16,7 @@ use core::raw; #[inline] #[deprecated] pub fn get_box_size(body_size: uint, body_align: uint) -> uint { - let header_size = mem::size_of::>(); + let header_size = mem::size_of::>(); let total_size = align_to(header_size, body_align) + body_size; total_size } diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 02396dc13d134..f282549f6f9a4 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -16,7 +16,7 @@ use core::prelude::*; use core::fmt; -#[deriving(Clone, PartialEq, Eq, Hash)] +#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] /// A specialized `Set` implementation to use enum types. pub struct EnumSet { // We must maintain the invariant that no bits are set diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 6843996a9e145..a856642c9361b 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -18,6 +18,7 @@ use core::default::Default; use core::fmt; use core::mem; use core::ptr; +use core::ops; // FIXME: ICE's abound if you import the `Slice` type while importing `Slice` trait use core::raw::Slice as RawSlice; @@ -530,7 +531,7 @@ impl String { /// assert_eq!(s.as_slice(), "abc123"); /// ``` #[inline] - #[stable = "function just renamed from push"] + #[stable = "function just renamed from push_char"] pub fn push(&mut self, ch: char) { let cur_len = self.len(); // This may use up to 4 bytes. @@ -926,6 +927,28 @@ impl Add for String { } } +impl ops::Slice for String { + #[inline] + fn as_slice_<'a>(&'a self) -> &'a str { + self.as_slice() + } + + #[inline] + fn slice_from_<'a>(&'a self, from: &uint) -> &'a str { + self[][*from..] + } + + #[inline] + fn slice_to_<'a>(&'a self, to: &uint) -> &'a str { + self[][..*to] + } + + #[inline] + fn slice_<'a>(&'a self, from: &uint, to: &uint) -> &'a str { + self[][*from..*to] + } +} + /// Unsafe operations #[unstable = "waiting on raw module conventions"] pub mod raw { @@ -1290,6 +1313,15 @@ mod tests { #[test] #[should_fail] fn insert_bad1() { "".to_string().insert(1, 't'); } #[test] #[should_fail] fn insert_bad2() { "ệ".to_string().insert(1, 't'); } + #[test] + fn test_slicing() { + let s = "foobar".to_string(); + assert_eq!("foobar", s[]); + assert_eq!("foo", s[..3]); + assert_eq!("bar", s[3..]); + assert_eq!("oob", s[1..4]); + } + #[bench] fn bench_with_capacity(b: &mut Bencher) { b.iter(|| { diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 479a4c3045a6a..8bccda37c246d 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -2393,8 +2393,6 @@ mod tests { let _ = vec[3]; } - // NOTE uncomment after snapshot - /* #[test] #[should_fail] fn test_slice_out_of_bounds_1() { @@ -2429,7 +2427,6 @@ mod tests { let x: Vec = vec![1, 2, 3, 4, 5]; x[3..2]; } - */ #[test] fn test_swap_remove_empty() { diff --git a/src/libcore/failure.rs b/src/libcore/failure.rs index f5f45b2f72e2a..9b63d325bc89a 100644 --- a/src/libcore/failure.rs +++ b/src/libcore/failure.rs @@ -33,24 +33,9 @@ use fmt; use intrinsics; -// NOTE: remove after next snapshot -#[cfg(stage0)] -#[cold] #[inline(never)] // this is the slow path, always -#[lang="fail_"] -fn fail_(expr_file_line: &(&'static str, &'static str, uint)) -> ! { - let (expr, file, line) = *expr_file_line; - let ref file_line = (file, line); - format_args!(|args| -> () { - fail_fmt(args, file_line); - }, "{}", expr); - - unsafe { intrinsics::abort() } -} - -#[cfg(not(stage0))] #[cold] #[inline(never)] // this is the slow path, always #[lang="fail"] -fn fail(expr_file_line: &(&'static str, &'static str, uint)) -> ! { +pub fn fail(expr_file_line: &(&'static str, &'static str, uint)) -> ! { let (expr, file, line) = *expr_file_line; let ref file_line = (file, line); format_args!(|args| -> () { @@ -70,23 +55,10 @@ fn fail_bounds_check(file_line: &(&'static str, uint), unsafe { intrinsics::abort() } } -#[cold] #[inline(never)] -pub fn fail_str(msg: &str, file: &(&'static str, uint)) -> ! { - format_args!(|fmt| fail_fmt(fmt, file), "{}", msg) -} - #[cold] #[inline(never)] pub fn fail_fmt(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! { #[allow(ctypes)] extern { - - // NOTE: remove after next snapshot - #[cfg(stage0)] - #[lang = "begin_unwind"] - fn fail_impl(fmt: &fmt::Arguments, file: &'static str, - line: uint) -> !; - - #[cfg(not(stage0))] #[lang = "fail_fmt"] fn fail_impl(fmt: &fmt::Arguments, file: &'static str, line: uint) -> !; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index f78c8c2aa0ed2..9799e9d398055 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -366,7 +366,7 @@ pub trait Iterator { /// let mut sum = 0; /// for x in it { /// if x > 5 { - /// continue; + /// break; /// } /// sum += x; /// } @@ -377,6 +377,8 @@ pub trait Iterator { /// sum /// } /// let x = vec![1i,2,3,7,8,9]; + /// assert_eq!(process(x.into_iter()), 6); + /// let x = vec![1i,2,3]; /// assert_eq!(process(x.into_iter()), 1006); /// ``` #[inline] diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 0f972a6702916..17fcf0254575d 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -17,8 +17,8 @@ macro_rules! fail( fail!("{}", "explicit failure") ); ($msg:expr) => ({ - static _FILE_LINE: (&'static str, uint) = (file!(), line!()); - ::core::failure::fail_str($msg, &_FILE_LINE) + static _MSG_FILE_LINE: (&'static str, &'static str, uint) = ($msg, file!(), line!()); + ::core::failure::fail(&_MSG_FILE_LINE) }); ($fmt:expr, $($arg:tt)*) => ({ // a closure can't have return type !, so we need a full diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 718d311999552..ad0f128a02e78 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -764,13 +764,13 @@ pub trait Slice for Sized? { // FIXME(#17273) remove the postscript _s #[lang="slice_mut"] pub trait SliceMut for Sized? { - /// The method for the slicing operation foo[] + /// The method for the slicing operation foo[mut] fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Result; - /// The method for the slicing operation foo[from..] + /// The method for the slicing operation foo[mut from..] fn slice_from_mut_<'a>(&'a mut self, from: &Idx) -> &'a mut Result; - /// The method for the slicing operation foo[..to] + /// The method for the slicing operation foo[mut ..to] fn slice_to_mut_<'a>(&'a mut self, to: &Idx) -> &'a mut Result; - /// The method for the slicing operation foo[from..to] + /// The method for the slicing operation foo[mut from..to] fn slice_mut_<'a>(&'a mut self, from: &Idx, to: &Idx) -> &'a mut Result; } /** diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 77fe55aadee48..1e353708730f2 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -312,7 +312,7 @@ impl Option { pub fn expect(self, msg: &str) -> T { match self { Some(val) => val, - None => fail!(msg), + None => fail!("{}", msg), } } diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index 188ef2a3b8879..86b96ff15f156 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -20,12 +20,12 @@ use mem; -/// The representation of a Rust managed box -pub struct Box { +/// The representation of `std::gc::Gc`. +pub struct GcBox { pub ref_count: uint, pub drop_glue: fn(ptr: *mut u8), - pub prev: *mut Box, - pub next: *mut Box, + pub prev: *mut GcBox, + pub next: *mut GcBox, pub data: T, } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 7e399902a4b5e..343b8e0b64b0f 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -1123,6 +1123,7 @@ pub mod traits { use collections::Collection; use iter::Iterator; use option::{Option, Some}; + use ops; use str::{Str, StrSlice, eq_slice}; impl<'a> Ord for &'a str { @@ -1162,6 +1163,28 @@ pub mod traits { #[inline] fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) } } + + impl ops::Slice for str { + #[inline] + fn as_slice_<'a>(&'a self) -> &'a str { + self + } + + #[inline] + fn slice_from_<'a>(&'a self, from: &uint) -> &'a str { + self.slice_from(*from) + } + + #[inline] + fn slice_to_<'a>(&'a self, to: &uint) -> &'a str { + self.slice_to(*to) + } + + #[inline] + fn slice_<'a>(&'a self, from: &uint, to: &uint) -> &'a str { + self.slice(*from, *to) + } + } } /// Any string that can be represented as a slice diff --git a/src/libdebug/repr.rs b/src/libdebug/repr.rs index e1eb281495169..64dc87908824b 100644 --- a/src/libdebug/repr.rs +++ b/src/libdebug/repr.rs @@ -277,7 +277,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> { fn visit_box(&mut self, mtbl: uint, inner: *const TyDesc) -> bool { try!(self, self.writer.write("box(GC) ".as_bytes())); self.write_mut_qualifier(mtbl); - self.get::<&raw::Box<()>>(|this, b| { + self.get::<&raw::GcBox<()>>(|this, b| { let p = &b.data as *const () as *const u8; this.visit_ptr_inner(p, inner) }) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 633248562a553..b793096b30a4f 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -1319,6 +1319,18 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, sess.abort_if_errors(); } } + // Fix up permissions of the copy, as fs::copy() preserves + // permissions, but the original file may have been installed + // by a package manager and may be read-only. + match fs::chmod(&dst, io::UserRead | io::UserWrite) { + Ok(..) => {} + Err(e) => { + sess.err(format!("failed to chmod {} when preparing \ + for LTO: {}", dst.display(), + e).as_slice()); + sess.abort_if_errors(); + } + } let handler = &sess.diagnostic().handler; let config = ArchiveConfig { handler: handler, diff --git a/src/librustc/back/write.rs b/src/librustc/back/write.rs index 7242c12ae0c7a..7b4d1780ccd69 100644 --- a/src/librustc/back/write.rs +++ b/src/librustc/back/write.rs @@ -16,6 +16,7 @@ use driver::session::Session; use driver::config; use llvm; use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, ContextRef}; +use llvm::SMDiagnosticRef; use util::common::time; use syntax::abi; use syntax::codemap; @@ -326,14 +327,40 @@ impl<'a> CodegenContext<'a> { } } -struct DiagHandlerFreeVars<'a> { +struct HandlerFreeVars<'a> { llcx: ContextRef, cgcx: &'a CodegenContext<'a>, } +unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef, + user: *const c_void, + cookie: c_uint) { + use syntax::codemap::ExpnId; + + let HandlerFreeVars { cgcx, .. } + = *mem::transmute::<_, *const HandlerFreeVars>(user); + + let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s)) + .expect("non-UTF8 SMDiagnostic"); + + match cgcx.lto_ctxt { + Some((sess, _)) => { + sess.codemap().with_expn_info(ExpnId::from_llvm_cookie(cookie), |info| match info { + Some(ei) => sess.span_err(ei.call_site, msg.as_slice()), + None => sess.err(msg.as_slice()), + }); + } + + None => { + cgcx.handler.err(msg.as_slice()); + cgcx.handler.note("build without -C codegen-units for more exact errors"); + } + } +} + unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) { - let DiagHandlerFreeVars { llcx, cgcx } - = *mem::transmute::<_, *const DiagHandlerFreeVars>(user); + let HandlerFreeVars { llcx, cgcx } + = *mem::transmute::<_, *const HandlerFreeVars>(user); match llvm::diagnostic::Diagnostic::unpack(info) { llvm::diagnostic::Optimization(opt) => { @@ -368,14 +395,16 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, let tm = config.tm; // llcx doesn't outlive this function, so we can put this on the stack. - let fv = DiagHandlerFreeVars { + let fv = HandlerFreeVars { llcx: llcx, cgcx: cgcx, }; + let fv = &fv as *const HandlerFreeVars as *mut c_void; + + llvm::LLVMSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, fv); + if !cgcx.remark.is_empty() { - llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, - &fv as *const DiagHandlerFreeVars - as *mut c_void); + llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, fv); } if config.emit_no_opt_bc { diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 80e507b7a791a..be0c9bb0ba356 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -288,8 +288,9 @@ pub fn phase_2_configure_and_expand(sess: &Session, os::setenv("PATH", os::join_paths(new_path.as_slice()).unwrap()); } let cfg = syntax::ext::expand::ExpansionConfig { - deriving_hash_type_parameter: sess.features.borrow().default_type_params, crate_name: crate_name.to_string(), + deriving_hash_type_parameter: sess.features.borrow().default_type_params, + enable_quotes: sess.features.borrow().quote, }; let ret = syntax::ext::expand::expand_crate(&sess.parse_sess, cfg, @@ -556,6 +557,8 @@ pub fn phase_5_run_llvm_passes(sess: &Session, sess.opts.output_types.as_slice(), outputs)); } + + sess.abort_if_errors(); } /// Run the linker on any artifacts that resulted from the LLVM run. diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index c67f673879e69..be3867eaba2fa 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -32,7 +32,6 @@ This API is completely unstable and subject to change. #![feature(macro_rules, globs, struct_variant, quote)] #![feature(default_type_params, phase, unsafe_destructor)] -#![allow(unknown_features)] // NOTE: Remove after next snapshot #![feature(rustc_diagnostic_macros)] #![feature(import_shadowing)] diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index e9be87758f95c..26eca0938b189 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -652,12 +652,12 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { debug!("check_if_path_is_moved(id={:?}, use_kind={:?}, lp={})", id, use_kind, lp.repr(self.bccx.tcx)); let base_lp = owned_ptr_base_path_rc(lp); - self.move_data.each_move_of(id, &base_lp, |move, moved_lp| { + self.move_data.each_move_of(id, &base_lp, |the_move, moved_lp| { self.bccx.report_use_of_moved_value( span, use_kind, &**lp, - move, + the_move, moved_lp); false }); diff --git a/src/librustc/middle/borrowck/graphviz.rs b/src/librustc/middle/borrowck/graphviz.rs index c789db5be0c01..63d49dcd3036e 100644 --- a/src/librustc/middle/borrowck/graphviz.rs +++ b/src/librustc/middle/borrowck/graphviz.rs @@ -108,8 +108,8 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> { let move_index_to_path = |move_index| { let move_data = &self.analysis_data.move_data.move_data; let moves = move_data.moves.borrow(); - let move = moves.get(move_index); - move_data.path_loan_path(move.path) + let the_move = moves.get(move_index); + move_data.path_loan_path(the_move.path) }; self.build_set(e, cfgidx, dfcx, move_index_to_path) } diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index d3d6e7508f077..d4d6fae53e3a3 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -409,14 +409,14 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { use_span: Span, use_kind: MovedValueUseKind, lp: &LoanPath, - move: &move_data::Move, + the_move: &move_data::Move, moved_lp: &LoanPath) { let verb = match use_kind { MovedInUse => "use", MovedInCapture => "capture", }; - match move.kind { + match the_move.kind { move_data::Declared => { self.tcx.sess.span_err( use_span, @@ -435,18 +435,20 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } } - match move.kind { + match the_move.kind { move_data::Declared => {} move_data::MoveExpr => { - let (expr_ty, expr_span) = match self.tcx.map.find(move.id) { + let (expr_ty, expr_span) = match self.tcx + .map + .find(the_move.id) { Some(ast_map::NodeExpr(expr)) => { (ty::expr_ty_adjusted(self.tcx, &*expr), expr.span) } r => { self.tcx.sess.bug(format!("MoveExpr({:?}) maps to \ {:?}, not Expr", - move.id, + the_move.id, r).as_slice()) } }; @@ -461,8 +463,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } move_data::MovePat => { - let pat_ty = ty::node_id_to_type(self.tcx, move.id); - self.tcx.sess.span_note(self.tcx.map.span(move.id), + let pat_ty = ty::node_id_to_type(self.tcx, the_move.id); + self.tcx.sess.span_note(self.tcx.map.span(the_move.id), format!("`{}` moved here because it has type `{}`, \ which is moved by default (use `ref` to \ override)", @@ -471,14 +473,16 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } move_data::Captured => { - let (expr_ty, expr_span) = match self.tcx.map.find(move.id) { + let (expr_ty, expr_span) = match self.tcx + .map + .find(the_move.id) { Some(ast_map::NodeExpr(expr)) => { (ty::expr_ty_adjusted(self.tcx, &*expr), expr.span) } r => { self.tcx.sess.bug(format!("Captured({:?}) maps to \ {:?}, not Expr", - move.id, + the_move.id, r).as_slice()) } }; diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index d8597c08b454c..5cc58eb264e07 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -413,8 +413,8 @@ impl MoveData { * killed by scoping. See `doc.rs` for more details. */ - for (i, move) in self.moves.borrow().iter().enumerate() { - dfcx_moves.add_gen(move.id, i); + for (i, the_move) in self.moves.borrow().iter().enumerate() { + dfcx_moves.add_gen(the_move.id, i); } for (i, assignment) in self.var_assignments.borrow().iter().enumerate() { @@ -577,10 +577,10 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> { let mut ret = None; for loan_path_index in self.move_data.path_map.borrow().find(&*loan_path).iter() { self.dfcx_moves.each_gen_bit(id, |move_index| { - let move = self.move_data.moves.borrow(); - let move = move.get(move_index); - if move.path == **loan_path_index { - ret = Some(move.kind); + let the_move = self.move_data.moves.borrow(); + let the_move = the_move.get(move_index); + if the_move.path == **loan_path_index { + ret = Some(the_move.kind); false } else { true @@ -622,13 +622,13 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> { let mut ret = true; self.dfcx_moves.each_bit_on_entry(id, |index| { - let move = self.move_data.moves.borrow(); - let move = move.get(index); - let moved_path = move.path; + let the_move = self.move_data.moves.borrow(); + let the_move = the_move.get(index); + let moved_path = the_move.path; if base_indices.iter().any(|x| x == &moved_path) { // Scenario 1 or 2: `loan_path` or some base path of // `loan_path` was moved. - if !f(move, &*self.move_data.path_loan_path(moved_path)) { + if !f(the_move, &*self.move_data.path_loan_path(moved_path)) { ret = false; } } else { @@ -637,7 +637,8 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> { if p == loan_path_index { // Scenario 3: some extension of `loan_path` // was moved - f(move, &*self.move_data.path_loan_path(moved_path)) + f(the_move, + &*self.move_data.path_loan_path(moved_path)) } else { true } diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index a5e6d606d7bc1..c51e242026241 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -25,6 +25,7 @@ use middle::trans::type_::Type; use std::c_str::ToCStr; use std::string::String; use syntax::ast; +use libc::{c_uint, c_char}; // Take an inline assembly expression and splat it out via LLVM pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) @@ -141,6 +142,19 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) } } + // Store expn_id in a metadata node so we can map LLVM errors + // back to source locations. See #17552. + unsafe { + let key = "srcloc"; + let kind = llvm::LLVMGetMDKindIDInContext(bcx.ccx().llcx(), + key.as_ptr() as *const c_char, key.len() as c_uint); + + let val: llvm::ValueRef = C_i32(bcx.ccx(), ia.expn_id.to_llvm_cookie()); + + llvm::LLVMSetMetadata(r, kind, + llvm::LLVMMDNodeInContext(bcx.ccx().llcx(), &val, 1)); + } + return bcx; } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index c7be2430cc98d..d4c38d48a8c56 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1405,6 +1405,37 @@ fn check_cast(fcx: &FnCtxt, return } + if !ty::type_is_sized(fcx.tcx(), t_1) { + let tstr = fcx.infcx().ty_to_string(t_1); + fcx.type_error_message(span, |actual| { + format!("cast to unsized type: `{}` as `{}`", actual, tstr) + }, t_e, None); + match ty::get(t_e).sty { + ty::ty_rptr(_, ty::mt { mutbl: mt, .. }) => { + let mtstr = match mt { + ast::MutMutable => "mut ", + ast::MutImmutable => "" + }; + if ty::type_is_trait(t_1) { + span_note!(fcx.tcx().sess, t.span, "did you mean `&{}{}`?", mtstr, tstr); + } else { + span_note!(fcx.tcx().sess, span, + "consider using an implicit coercion to `&{}{}` instead", + mtstr, tstr); + } + } + ty::ty_uniq(..) => { + span_note!(fcx.tcx().sess, t.span, "did you mean `Box<{}>`?", tstr); + } + _ => { + span_note!(fcx.tcx().sess, e.span, + "consider using a box or reference as appropriate"); + } + } + fcx.write_error(id); + return + } + if ty::type_is_trait(t_1) { // This will be looked up later on. vtable2::check_object_cast(fcx, cast_expr, e, t_1); diff --git a/src/librustc/middle/typeck/coherence/overlap.rs b/src/librustc/middle/typeck/coherence/overlap.rs index 48f71d95c429a..88e09c3060060 100644 --- a/src/librustc/middle/typeck/coherence/overlap.rs +++ b/src/librustc/middle/typeck/coherence/overlap.rs @@ -49,8 +49,8 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> { // FIXME -- it seems like this method actually pushes // duplicate impls onto the list - ty::populate_implementations_for_type_if_necessary(self.tcx, - trait_def_id); + ty::populate_implementations_for_trait_if_necessary(self.tcx, + trait_def_id); let mut impls = Vec::new(); self.push_impls_of_trait(trait_def_id, &mut impls); diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index c25ef2ca63a0b..401933d705849 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -424,8 +424,11 @@ pub enum DiagnosticInfo_opaque {} pub type DiagnosticInfoRef = *mut DiagnosticInfo_opaque; pub enum DebugLoc_opaque {} pub type DebugLocRef = *mut DebugLoc_opaque; +pub enum SMDiagnostic_opaque {} +pub type SMDiagnosticRef = *mut SMDiagnostic_opaque; pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void); +pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_void, c_uint); pub mod debuginfo { use super::{ValueRef}; @@ -1967,6 +1970,12 @@ extern { pub fn LLVMGetDiagInfoKind(DI: DiagnosticInfoRef) -> DiagnosticKind; pub fn LLVMWriteDebugLocToString(C: ContextRef, DL: DebugLocRef, s: RustStringRef); + + pub fn LLVMSetInlineAsmDiagnosticHandler(C: ContextRef, + H: InlineAsmDiagHandler, + CX: *mut c_void); + + pub fn LLVMWriteSMDiagnosticToString(d: SMDiagnosticRef, s: RustStringRef); } pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5ac7baaa6d10a..666be2debdaab 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -641,11 +641,27 @@ impl Clean> for ty::Region { } } +#[deriving(Clone, Encodable, Decodable, PartialEq)] +pub struct WherePredicate { + pub name: String, + pub bounds: Vec +} + +impl Clean for ast::WherePredicate { + fn clean(&self, cx: &DocContext) -> WherePredicate { + WherePredicate { + name: self.ident.clean(cx), + bounds: self.bounds.clean(cx) + } + } +} + // maybe use a Generic enum and use ~[Generic]? #[deriving(Clone, Encodable, Decodable, PartialEq)] pub struct Generics { pub lifetimes: Vec, pub type_params: Vec, + pub where_predicates: Vec } impl Clean for ast::Generics { @@ -653,6 +669,7 @@ impl Clean for ast::Generics { Generics { lifetimes: self.lifetimes.clean(cx), type_params: self.ty_params.clean(cx), + where_predicates: self.where_clause.predicates.clean(cx) } } } @@ -663,6 +680,7 @@ impl<'a> Clean for (&'a ty::Generics, subst::ParamSpace) { Generics { type_params: me.types.get_slice(space).to_vec().clean(cx), lifetimes: me.regions.get_slice(space).to_vec().clean(cx), + where_predicates: vec![] } } } @@ -1260,7 +1278,9 @@ impl Clean for ty::t { ty::ty_bare_fn(ref fty) => BareFunction(box BareFunctionDecl { fn_style: fty.fn_style, generics: Generics { - lifetimes: Vec::new(), type_params: Vec::new() + lifetimes: Vec::new(), + type_params: Vec::new(), + where_predicates: Vec::new() }, decl: (ast_util::local_def(0), &fty.sig).clean(cx), abi: fty.abi.to_string(), @@ -1670,6 +1690,7 @@ impl Clean for ast::BareFnTy { generics: Generics { lifetimes: self.lifetimes.clean(cx), type_params: Vec::new(), + where_predicates: Vec::new() }, decl: self.decl.clean(cx), abi: self.abi.to_string(), @@ -2172,6 +2193,7 @@ impl Clean for ast::Typedef { generics: Generics { lifetimes: Vec::new(), type_params: Vec::new(), + where_predicates: Vec::new() }, }), visibility: None, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index c807c180e640e..947d9f05ae2bb 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -44,6 +44,11 @@ pub struct RawMutableSpace(pub clean::Mutability); pub struct Stability<'a>(pub &'a Option); /// Wrapper struct for emitting the stability level concisely. pub struct ConciseStability<'a>(pub &'a Option); +/// Wrapper struct for emitting a where clause from Generics. +pub struct WhereClause<'a>(pub &'a clean::Generics); + +/// Wrapper struct for emitting type parameter bounds. +struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]); impl VisSpace { pub fn get(&self) -> Option { @@ -57,6 +62,19 @@ impl FnStyleSpace { } } +impl<'a> fmt::Show for TyParamBounds<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let &TyParamBounds(bounds) = self; + for (i, bound) in bounds.iter().enumerate() { + if i > 0 { + try!(f.write(" + ".as_bytes())); + } + try!(write!(f, "{}", *bound)); + } + Ok(()) + } +} + impl fmt::Show for clean::Generics { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.lifetimes.len() == 0 && self.type_params.len() == 0 { return Ok(()) } @@ -73,7 +91,6 @@ impl fmt::Show for clean::Generics { if self.lifetimes.len() > 0 { try!(f.write(", ".as_bytes())); } - for (i, tp) in self.type_params.iter().enumerate() { if i > 0 { try!(f.write(", ".as_bytes())) @@ -81,13 +98,7 @@ impl fmt::Show for clean::Generics { try!(f.write(tp.name.as_bytes())); if tp.bounds.len() > 0 { - try!(f.write(": ".as_bytes())); - for (i, bound) in tp.bounds.iter().enumerate() { - if i > 0 { - try!(f.write(" + ".as_bytes())); - } - try!(write!(f, "{}", *bound)); - } + try!(write!(f, ": {}", TyParamBounds(tp.bounds.as_slice()))); } match tp.default { @@ -101,6 +112,24 @@ impl fmt::Show for clean::Generics { } } +impl<'a> fmt::Show for WhereClause<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let &WhereClause(gens) = self; + if gens.where_predicates.len() == 0 { + return Ok(()); + } + try!(f.write(" where ".as_bytes())); + for (i, pred) in gens.where_predicates.iter().enumerate() { + if i > 0 { + try!(f.write(", ".as_bytes())); + } + let bounds = pred.bounds.as_slice(); + try!(write!(f, "{}: {}", pred.name, TyParamBounds(bounds))); + } + Ok(()) + } +} + impl fmt::Show for clean::Lifetime { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(f.write(self.get_ref().as_bytes())); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 3cd3fe3053a37..8668e684c2d64 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -56,7 +56,7 @@ use clean; use doctree; use fold::DocFolder; use html::format::{VisSpace, Method, FnStyleSpace, MutableSpace, Stability}; -use html::format::{ConciseStability}; +use html::format::{ConciseStability, WhereClause}; use html::highlight; use html::item_type::{ItemType, shortty}; use html::item_type; @@ -1610,11 +1610,12 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, fn item_function(w: &mut fmt::Formatter, it: &clean::Item, f: &clean::Function) -> fmt::Result { try!(write!(w, "
{vis}{fn_style}fn \
-                    {name}{generics}{decl}
", + {name}{generics}{decl}{where_clause}", vis = VisSpace(it.visibility), fn_style = FnStyleSpace(f.fn_style), name = it.name.get_ref().as_slice(), generics = f.generics, + where_clause = WhereClause(&f.generics), decl = f.decl)); document(w, it) } @@ -1631,11 +1632,12 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, } // Output the trait definition - try!(write!(w, "
{}trait {}{}{} ",
+    try!(write!(w, "
{}trait {}{}{}{} ",
                   VisSpace(it.visibility),
                   it.name.get_ref().as_slice(),
                   t.generics,
-                  bounds));
+                  bounds,
+                  WhereClause(&t.generics)));
     let required = t.items.iter()
                           .filter(|m| {
                               match **m {
@@ -1719,9 +1721,9 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
     match cache.implementors.find(&it.def_id) {
         Some(implementors) => {
             for i in implementors.iter() {
-                try!(writeln!(w, "
  • {}impl{} {} for {}
  • ", + try!(writeln!(w, "
  • {}impl{} {} for {}{}
  • ", ConciseStability(&i.stability), - i.generics, i.trait_, i.for_)); + i.generics, i.trait_, i.for_, WhereClause(&i.generics))); } } None => {} @@ -1747,7 +1749,7 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result { g: &clean::Generics, selfty: &clean::SelfTy, d: &clean::FnDecl) -> fmt::Result { write!(w, "{}fn
    {name}\ - {generics}{decl}", + {generics}{decl}{where_clause}", match fn_style { ast::UnsafeFn => "unsafe ", _ => "", @@ -1755,7 +1757,8 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result { ty = shortty(it), name = it.name.get_ref().as_slice(), generics = *g, - decl = Method(selfty, d)) + decl = Method(selfty, d), + where_clause = WhereClause(g)) } match meth.inner { clean::TyMethodItem(ref m) => { @@ -1810,10 +1813,11 @@ fn item_struct(w: &mut fmt::Formatter, it: &clean::Item, fn item_enum(w: &mut fmt::Formatter, it: &clean::Item, e: &clean::Enum) -> fmt::Result { - try!(write!(w, "
    {}enum {}{}",
    +    try!(write!(w, "
    {}enum {}{}{}",
                       VisSpace(it.visibility),
                       it.name.get_ref().as_slice(),
    -                  e.generics));
    +                  e.generics,
    +                  WhereClause(&e.generics)));
         if e.variants.len() == 0 && !e.variants_stripped {
             try!(write!(w, " {{}}"));
         } else {
    @@ -1917,7 +1921,7 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
                       if structhead {"struct "} else {""},
                       it.name.get_ref().as_slice()));
         match g {
    -        Some(g) => try!(write!(w, "{}", *g)),
    +        Some(g) => try!(write!(w, "{}{}", *g, WhereClause(g))),
             None => {}
         }
         match ty {
    @@ -2009,7 +2013,7 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
             Some(ref ty) => try!(write!(w, "{} for ", *ty)),
             None => {}
         }
    -    try!(write!(w, "{}", i.impl_.for_));
    +    try!(write!(w, "{}{}", i.impl_.for_, WhereClause(&i.impl_.generics)));
         match i.dox {
             Some(ref dox) => {
                 try!(write!(w, "
    {}
    ", diff --git a/src/librustrt/local_heap.rs b/src/librustrt/local_heap.rs index fe377d9e75b87..0e84e9c0097f5 100644 --- a/src/librustrt/local_heap.rs +++ b/src/librustrt/local_heap.rs @@ -24,7 +24,7 @@ use task::Task; static RC_IMMORTAL : uint = 0x77777777; -pub type Box = raw::Box<()>; +pub type Box = raw::GcBox<()>; pub struct MemoryRegion { live_allocations: uint, @@ -32,7 +32,7 @@ pub struct MemoryRegion { pub struct LocalHeap { memory_region: MemoryRegion, - live_allocs: *mut raw::Box<()>, + live_allocs: *mut raw::GcBox<()>, } impl LocalHeap { @@ -161,7 +161,7 @@ impl LocalHeap { } unsafe fn each_live_alloc(&mut self, read_next_before: bool, - f: |&mut LocalHeap, alloc: *mut raw::Box<()>|) { + f: |&mut LocalHeap, alloc: *mut raw::GcBox<()>|) { //! Walks the internal list of allocations let mut alloc = self.live_allocs; diff --git a/src/librustrt/unwind.rs b/src/librustrt/unwind.rs index 034ed470c9752..d3ab0f27c1328 100644 --- a/src/librustrt/unwind.rs +++ b/src/librustrt/unwind.rs @@ -37,11 +37,11 @@ //! In the cleanup phase, personality routines invoke cleanup code associated //! with their stack frames (i.e. destructors). Once stack has been unwound down //! to the handler frame level, unwinding stops and the last personality routine -//! transfers control to its' catch block. +//! transfers control to its catch block. //! //! ## Frame unwind info registration //! -//! Each module has its' own frame unwind info section (usually ".eh_frame"), and +//! Each module has its own frame unwind info section (usually ".eh_frame"), and //! unwinder needs to know about all of them in order for unwinding to be able to //! cross module boundaries. //! @@ -488,22 +488,13 @@ pub mod eabi { } // Entry point of failure from the libcore crate -#[cfg(not(test), not(stage0))] +#[cfg(not(test))] #[lang = "fail_fmt"] pub extern fn rust_begin_unwind(msg: &fmt::Arguments, file: &'static str, line: uint) -> ! { begin_unwind_fmt(msg, &(file, line)) } -// -// Entry point of failure from the libcore crate -#[cfg(stage0, not(test))] -#[lang = "begin_unwind"] -pub extern fn rust_begin_unwind(msg: &fmt::Arguments, - file: &'static str, line: uint) -> ! { - begin_unwind_fmt(msg, &(file, line)) -} - /// The entry point for unwinding with a formatted message. /// /// This is designed to reduce the amount of code required at the call diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index b936dde6fe4be..ed95fa341b39d 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -668,16 +668,23 @@ impl<'a> ::Encoder for PrettyEncoder<'a> { if cnt == 0 { escape_str(self.writer, name) } else { + try!(write!(self.writer, "{{\n")); self.curr_indent += self.indent; - try!(write!(self.writer, "[\n")); try!(spaces(self.writer, self.curr_indent)); + try!(write!(self.writer, "\"variant\": ")); try!(escape_str(self.writer, name)); try!(write!(self.writer, ",\n")); + try!(spaces(self.writer, self.curr_indent)); + try!(write!(self.writer, "\"fields\": [\n")); + self.curr_indent += self.indent; try!(f(self)); self.curr_indent -= self.indent; try!(write!(self.writer, "\n")); try!(spaces(self.writer, self.curr_indent)); - write!(self.writer, "]") + self.curr_indent -= self.indent; + try!(write!(self.writer, "]\n")); + try!(spaces(self.writer, self.curr_indent)); + write!(self.writer, "}}") } } @@ -2651,12 +2658,13 @@ mod tests { let mut encoder = PrettyEncoder::new(writer); animal.encode(&mut encoder).unwrap(); }), - "\ - [\n \ - \"Frog\",\n \ - \"Henry\",\n \ - 349\n\ - ]".to_string() + "{\n \ + \"variant\": \"Frog\",\n \ + \"fields\": [\n \ + \"Henry\",\n \ + 349\n \ + ]\n\ + }".to_string() ); } diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs index 7855748fc6489..1d479b852480c 100644 --- a/src/libstd/bitflags.rs +++ b/src/libstd/bitflags.rs @@ -93,6 +93,7 @@ /// /// - `BitOr`: union /// - `BitAnd`: intersection +/// - `BitXor`: toggle /// - `Sub`: set difference /// - `Not`: set complement /// @@ -109,6 +110,8 @@ /// - `contains`: `true` all of the flags in `other` are contained within `self` /// - `insert`: inserts the specified flags in-place /// - `remove`: removes the specified flags in-place +/// - `toggle`: the specified flags will be inserted if not present, and removed +/// if they are. #[macro_export] macro_rules! bitflags { ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty { @@ -184,6 +187,11 @@ macro_rules! bitflags { pub fn remove(&mut self, other: $BitFlags) { self.bits &= !other.bits; } + + /// Toggles the specified flags in-place. + pub fn toggle(&mut self, other: $BitFlags) { + self.bits ^= other.bits; + } } impl BitOr<$BitFlags, $BitFlags> for $BitFlags { @@ -194,6 +202,14 @@ macro_rules! bitflags { } } + impl BitXor<$BitFlags, $BitFlags> for $BitFlags { + /// Returns the left flags, but with all the right flags toggled. + #[inline] + fn bitxor(&self, other: &$BitFlags) -> $BitFlags { + $BitFlags { bits: self.bits ^ other.bits } + } + } + impl BitAnd<$BitFlags, $BitFlags> for $BitFlags { /// Returns the intersection between the two sets of flags. #[inline] @@ -234,7 +250,7 @@ macro_rules! bitflags { mod tests { use hash; use option::{Some, None}; - use ops::{BitOr, BitAnd, Sub, Not}; + use ops::{BitOr, BitAnd, BitXor, Sub, Not}; bitflags! { #[doc = "> The first principle is that you must not fool yourself — and"] @@ -358,10 +374,14 @@ mod tests { fn test_operators() { let e1 = FlagA | FlagC; let e2 = FlagB | FlagC; - assert!((e1 | e2) == FlagABC); // union - assert!((e1 & e2) == FlagC); // intersection - assert!((e1 - e2) == FlagA); // set difference - assert!(!e2 == FlagA); // set complement + assert!((e1 | e2) == FlagABC); // union + assert!((e1 & e2) == FlagC); // intersection + assert!((e1 - e2) == FlagA); // set difference + assert!(!e2 == FlagA); // set complement + assert!(e1 ^ e2 == FlagA | FlagB); // toggle + let mut e3 = e1; + e3.toggle(e2); + assert!(e3 == FlagA | FlagB); } #[test] diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs index 47b7426633c7b..ecef8e9ed9022 100644 --- a/src/libstd/gc.rs +++ b/src/libstd/gc.rs @@ -89,7 +89,7 @@ impl Default for Gc { } } -impl raw::Repr<*const raw::Box> for Gc {} +impl raw::Repr<*const raw::GcBox> for Gc {} impl + 'static> hash::Hash for Gc { fn hash(&self, s: &mut S) { diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 81e05648567b2..444372e3c4f04 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -229,7 +229,7 @@ use int; use iter::Iterator; use libc; use mem::transmute; -use ops::{BitOr, BitAnd, Sub, Not}; +use ops::{BitOr, BitXor, BitAnd, Sub, Not}; use option::{Option, Some, None}; use os; use boxed::Box; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 38d8136c1a13c..0fee3ff321850 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -10,7 +10,7 @@ // The Rust abstract syntax tree. -use codemap::{Span, Spanned, DUMMY_SP}; +use codemap::{Span, Spanned, DUMMY_SP, ExpnId}; use abi::Abi; use ast_util; use owned_slice::OwnedSlice; @@ -983,7 +983,8 @@ pub struct InlineAsm { pub clobbers: InternedString, pub volatile: bool, pub alignstack: bool, - pub dialect: AsmDialect + pub dialect: AsmDialect, + pub expn_id: ExpnId, } /// represents an argument in a function header diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 9072889463cd6..e9b2556c53e25 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -26,6 +26,7 @@ source code snippets, etc. use serialize::{Encodable, Decodable, Encoder, Decoder}; use std::cell::RefCell; use std::rc::Rc; +use libc::c_uint; pub trait Pos { fn from_uint(n: uint) -> Self; @@ -223,11 +224,22 @@ pub struct ExpnInfo { pub callee: NameAndSpan } -#[deriving(PartialEq, Eq, Clone, Show, Hash)] +#[deriving(PartialEq, Eq, Clone, Show, Hash, Encodable, Decodable)] pub struct ExpnId(u32); pub static NO_EXPANSION: ExpnId = ExpnId(-1); +impl ExpnId { + pub fn from_llvm_cookie(cookie: c_uint) -> ExpnId { + ExpnId(cookie as u32) + } + + pub fn to_llvm_cookie(self) -> i32 { + let ExpnId(cookie) = self; + cookie as i32 + } +} + pub type FileName = String; pub struct FileLines { diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index 4b8c3376cad2e..702be0c0eeede 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -13,6 +13,7 @@ */ use ast; +use codemap; use codemap::Span; use ext::base; use ext::base::*; @@ -198,6 +199,15 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } } + let expn_id = cx.codemap().record_expansion(codemap::ExpnInfo { + call_site: sp, + callee: codemap::NameAndSpan { + name: "asm".to_string(), + format: codemap::MacroBang, + span: None, + }, + }); + MacExpr::new(P(ast::Expr { id: ast::DUMMY_NODE_ID, node: ast::ExprInlineAsm(ast::InlineAsm { @@ -208,7 +218,8 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) clobbers: token::intern_and_get_ident(cons.as_slice()), volatile: volatile, alignstack: alignstack, - dialect: dialect + dialect: dialect, + expn_id: expn_id, }), span: sp })) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 8bf13e20fedf7..212cd33e16e61 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -344,7 +344,7 @@ impl BlockInfo { /// The base map of methods for expanding syntax extension /// AST nodes into full ASTs -fn initial_syntax_expander_table() -> SyntaxEnv { +fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv { // utility function to simplify creating NormalTT syntax extensions fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension { NormalTT(box f, None) @@ -383,31 +383,33 @@ fn initial_syntax_expander_table() -> SyntaxEnv { syntax_expanders.insert(intern("deriving"), Decorator(box ext::deriving::expand_meta_deriving)); - // Quasi-quoting expanders - syntax_expanders.insert(intern("quote_tokens"), - builtin_normal_expander( - ext::quote::expand_quote_tokens)); - syntax_expanders.insert(intern("quote_expr"), - builtin_normal_expander( - ext::quote::expand_quote_expr)); - syntax_expanders.insert(intern("quote_ty"), - builtin_normal_expander( - ext::quote::expand_quote_ty)); - syntax_expanders.insert(intern("quote_method"), - builtin_normal_expander( - ext::quote::expand_quote_method)); - syntax_expanders.insert(intern("quote_item"), - builtin_normal_expander( - ext::quote::expand_quote_item)); - syntax_expanders.insert(intern("quote_pat"), - builtin_normal_expander( - ext::quote::expand_quote_pat)); - syntax_expanders.insert(intern("quote_arm"), - builtin_normal_expander( - ext::quote::expand_quote_arm)); - syntax_expanders.insert(intern("quote_stmt"), - builtin_normal_expander( - ext::quote::expand_quote_stmt)); + if ecfg.enable_quotes { + // Quasi-quoting expanders + syntax_expanders.insert(intern("quote_tokens"), + builtin_normal_expander( + ext::quote::expand_quote_tokens)); + syntax_expanders.insert(intern("quote_expr"), + builtin_normal_expander( + ext::quote::expand_quote_expr)); + syntax_expanders.insert(intern("quote_ty"), + builtin_normal_expander( + ext::quote::expand_quote_ty)); + syntax_expanders.insert(intern("quote_method"), + builtin_normal_expander( + ext::quote::expand_quote_method)); + syntax_expanders.insert(intern("quote_item"), + builtin_normal_expander( + ext::quote::expand_quote_item)); + syntax_expanders.insert(intern("quote_pat"), + builtin_normal_expander( + ext::quote::expand_quote_pat)); + syntax_expanders.insert(intern("quote_arm"), + builtin_normal_expander( + ext::quote::expand_quote_arm)); + syntax_expanders.insert(intern("quote_stmt"), + builtin_normal_expander( + ext::quote::expand_quote_stmt)); + } syntax_expanders.insert(intern("line"), builtin_normal_expander( @@ -466,6 +468,7 @@ pub struct ExtCtxt<'a> { impl<'a> ExtCtxt<'a> { pub fn new<'a>(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig, ecfg: expand::ExpansionConfig) -> ExtCtxt<'a> { + let env = initial_syntax_expander_table(&ecfg); ExtCtxt { parse_sess: parse_sess, cfg: cfg, @@ -474,7 +477,7 @@ impl<'a> ExtCtxt<'a> { ecfg: ecfg, trace_mac: false, exported_macros: Vec::new(), - syntax_env: initial_syntax_expander_table(), + syntax_env: env, } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 70cf41d5e171d..9f3df1a762398 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -975,8 +975,19 @@ fn new_span(cx: &ExtCtxt, sp: Span) -> Span { } pub struct ExpansionConfig { - pub deriving_hash_type_parameter: bool, pub crate_name: String, + pub deriving_hash_type_parameter: bool, + pub enable_quotes: bool, +} + +impl ExpansionConfig { + pub fn default(crate_name: String) -> ExpansionConfig { + ExpansionConfig { + crate_name: crate_name, + deriving_hash_type_parameter: false, + enable_quotes: false, + } + } } pub struct ExportedMacros { @@ -1106,7 +1117,7 @@ impl<'a, 'v> Visitor<'v> for MacroExterminator<'a> { #[cfg(test)] mod test { use super::{pattern_bindings, expand_crate, contains_macro_escape}; - use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer}; + use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer, ExpansionConfig}; use ast; use ast::{Attribute_, AttrOuter, MetaWord, Name}; use attr; @@ -1171,6 +1182,10 @@ mod test { // these following tests are quite fragile, in that they don't test what // *kind* of failure occurs. + fn test_ecfg() -> ExpansionConfig { + ExpansionConfig::default("test".to_string()) + } + // make sure that macros can't escape fns #[should_fail] #[test] fn macros_cant_escape_fns_test () { @@ -1182,11 +1197,7 @@ mod test { src, Vec::new(), &sess); // should fail: - let cfg = ::syntax::ext::expand::ExpansionConfig { - deriving_hash_type_parameter: false, - crate_name: "test".to_string(), - }; - expand_crate(&sess,cfg,vec!(),vec!(),crate_ast); + expand_crate(&sess,test_ecfg(),vec!(),vec!(),crate_ast); } // make sure that macros can't escape modules @@ -1199,11 +1210,7 @@ mod test { "".to_string(), src, Vec::new(), &sess); - let cfg = ::syntax::ext::expand::ExpansionConfig { - deriving_hash_type_parameter: false, - crate_name: "test".to_string(), - }; - expand_crate(&sess,cfg,vec!(),vec!(),crate_ast); + expand_crate(&sess,test_ecfg(),vec!(),vec!(),crate_ast); } // macro_escape modules should allow macros to escape @@ -1215,11 +1222,7 @@ mod test { "".to_string(), src, Vec::new(), &sess); - let cfg = ::syntax::ext::expand::ExpansionConfig { - deriving_hash_type_parameter: false, - crate_name: "test".to_string(), - }; - expand_crate(&sess, cfg, vec!(), vec!(), crate_ast); + expand_crate(&sess, test_ecfg(), vec!(), vec!(), crate_ast); } #[test] fn test_contains_flatten (){ @@ -1252,11 +1255,7 @@ mod test { let ps = parse::new_parse_sess(); let crate_ast = string_to_parser(&ps, crate_str).parse_crate_mod(); // the cfg argument actually does matter, here... - let cfg = ::syntax::ext::expand::ExpansionConfig { - deriving_hash_type_parameter: false, - crate_name: "test".to_string(), - }; - expand_crate(&ps,cfg,vec!(),vec!(),crate_ast) + expand_crate(&ps,test_ecfg(),vec!(),vec!(),crate_ast) } // find the pat_ident paths in a crate diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index cd0fa184a09dc..1c6ee8acc94a5 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -102,6 +102,7 @@ pub struct Features { pub rustc_diagnostic_macros: bool, pub import_shadowing: bool, pub visible_private_types: bool, + pub quote: bool, } impl Features { @@ -112,6 +113,7 @@ impl Features { rustc_diagnostic_macros: false, import_shadowing: false, visible_private_types: false, + quote: false, } } } @@ -282,10 +284,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { fn visit_mac(&mut self, macro: &ast::Mac) { let ast::MacInvocTT(ref path, _, _) = macro.node; let id = path.segments.last().unwrap().identifier; - let quotes = ["quote_tokens", "quote_expr", "quote_ty", - "quote_item", "quote_pat", "quote_stmt"]; - let msg = " is not stable enough for use and are subject to change"; - if id == token::str_to_ident("macro_rules") { self.gate_feature("macro_rules", path.span, "macro definitions are \ @@ -311,16 +309,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { self.gate_feature("concat_idents", path.span, "`concat_idents` is not \ stable enough for use and is subject to change"); } - - else { - for "e in quotes.iter() { - if id == token::str_to_ident(quote) { - self.gate_feature("quote", - path.span, - format!("{}{}", quote, msg).as_slice()); - } - } - } } fn visit_foreign_item(&mut self, i: &ast::ForeignItem) { @@ -483,6 +471,7 @@ pub fn check_crate(span_handler: &SpanHandler, krate: &ast::Crate) -> (Features, rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"), import_shadowing: cx.has_feature("import_shadowing"), visible_private_types: cx.has_feature("visible_private_types"), + quote: cx.has_feature("quote"), }, unknown_features) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 91a339a73f7af..53be7f2c20c4e 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1279,7 +1279,8 @@ pub fn noop_fold_expr(Expr {id, node, span}: Expr, folder: &mut T) -> clobbers, volatile, alignstack, - dialect + dialect, + expn_id, }) => ExprInlineAsm(InlineAsm { inputs: inputs.move_map(|(c, input)| { (c, folder.fold_expr(input)) @@ -1292,7 +1293,8 @@ pub fn noop_fold_expr(Expr {id, node, span}: Expr, folder: &mut T) -> clobbers: clobbers, volatile: volatile, alignstack: alignstack, - dialect: dialect + dialect: dialect, + expn_id: expn_id, }), ExprMac(mac) => ExprMac(folder.fold_mac(mac)), ExprStruct(path, fields, maybe_expr) => { diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 7a504d22c1e9e..a427154414654 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -33,6 +33,7 @@ extern crate debug; #[phase(plugin, link)] extern crate log; extern crate serialize; extern crate term; +extern crate libc; pub mod util { pub mod interner; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cbc710821f937..415ff6a4097ac 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2084,7 +2084,7 @@ impl<'a> Parser<'a> { ExprBlock(blk)); }, token::BINOP(token::OR) | token::OROR => { - return self.parse_lambda_expr(CaptureByValue); + return self.parse_lambda_expr(CaptureByRef); }, // FIXME #13626: Should be able to stick in // token::SELF_KEYWORD_NAME @@ -2135,8 +2135,8 @@ impl<'a> Parser<'a> { hi = self.last_span.hi; } _ => { - if self.eat_keyword(keywords::Ref) { - return self.parse_lambda_expr(CaptureByRef); + if self.eat_keyword(keywords::Move) { + return self.parse_lambda_expr(CaptureByValue); } if self.eat_keyword(keywords::Proc) { let decl = self.parse_proc_decl(); diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index f71190da43011..a486ac40a97a1 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -482,40 +482,41 @@ declare_special_idents_and_keywords! { (25, Loop, "loop"); (26, Match, "match"); (27, Mod, "mod"); - (28, Mut, "mut"); - (29, Once, "once"); - (30, Pub, "pub"); - (31, Ref, "ref"); - (32, Return, "return"); + (28, Move, "move"); + (29, Mut, "mut"); + (30, Once, "once"); + (31, Pub, "pub"); + (32, Ref, "ref"); + (33, Return, "return"); // Static and Self are also special idents (prefill de-dupes) (super::STATIC_KEYWORD_NAME_NUM, Static, "static"); (super::SELF_KEYWORD_NAME_NUM, Self, "self"); - (33, Struct, "struct"); + (34, Struct, "struct"); (super::SUPER_KEYWORD_NAME_NUM, Super, "super"); - (34, True, "true"); - (35, Trait, "trait"); - (36, Type, "type"); - (37, Unsafe, "unsafe"); - (38, Use, "use"); - (39, Virtual, "virtual"); - (40, While, "while"); - (41, Continue, "continue"); - (42, Proc, "proc"); - (43, Box, "box"); - (44, Const, "const"); - (45, Where, "where"); + (35, True, "true"); + (36, Trait, "trait"); + (37, Type, "type"); + (38, Unsafe, "unsafe"); + (39, Use, "use"); + (40, Virtual, "virtual"); + (41, While, "while"); + (42, Continue, "continue"); + (43, Proc, "proc"); + (44, Box, "box"); + (45, Const, "const"); + (46, Where, "where"); 'reserved: - (46, Alignof, "alignof"); - (47, Be, "be"); - (48, Offsetof, "offsetof"); - (49, Priv, "priv"); - (50, Pure, "pure"); - (51, Sizeof, "sizeof"); - (52, Typeof, "typeof"); - (53, Unsized, "unsized"); - (54, Yield, "yield"); - (55, Do, "do"); + (47, Alignof, "alignof"); + (48, Be, "be"); + (49, Offsetof, "offsetof"); + (50, Priv, "priv"); + (51, Pure, "pure"); + (52, Sizeof, "sizeof"); + (53, Typeof, "typeof"); + (54, Unsized, "unsized"); + (55, Yield, "yield"); + (56, Do, "do"); } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 1fbd4af8627a9..ae4ba611bab53 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2176,8 +2176,8 @@ impl<'a> State<'a> { pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureClause) -> IoResult<()> { match capture_clause { - ast::CaptureByValue => Ok(()), - ast::CaptureByRef => self.word_space("ref"), + ast::CaptureByValue => self.word_space("move"), + ast::CaptureByRef => Ok(()), } } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 091b0ce8ed949..828a6124aa09f 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -235,10 +235,7 @@ fn generate_test_harness(sess: &ParseSess, sess: sess, span_diagnostic: sd, ext_cx: ExtCtxt::new(sess, cfg.clone(), - ExpansionConfig { - deriving_hash_type_parameter: false, - crate_name: "test".to_string(), - }), + ExpansionConfig::default("test".to_string())), path: Vec::new(), testfns: Vec::new(), reexport_test_harness_main: reexport_test_harness_main, diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 7896ce2ba761a..1fdaa548ebe6e 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -871,3 +871,18 @@ extern "C" void LLVMWriteDebugLocToString( raw_rust_string_ostream os(str); unwrap(dl)->print(*unwrap(C), os); } + +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef) + +extern "C" void LLVMSetInlineAsmDiagnosticHandler( + LLVMContextRef C, + LLVMContext::InlineAsmDiagHandlerTy H, + void *CX) +{ + unwrap(C)->setInlineAsmDiagnosticHandler(H, CX); +} + +extern "C" void LLVMWriteSMDiagnosticToString(LLVMSMDiagnosticRef d, RustStringRef str) { + raw_rust_string_ostream os(str); + unwrap(d)->print("", os); +} diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index 54b0c2506c76b..5469531c54188 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -73,6 +73,7 @@ void LLVMRustSetLastError(const char*); typedef struct OpaqueRustString *RustStringRef; typedef struct LLVMOpaqueTwine *LLVMTwineRef; typedef struct LLVMOpaqueDebugLoc *LLVMDebugLocRef; +typedef struct LLVMOpaqueSMDiagnostic *LLVMSMDiagnosticRef; extern "C" void rust_llvm_string_write_impl(RustStringRef str, const char *ptr, size_t size); diff --git a/src/snapshots.txt b/src/snapshots.txt index b779b56bff58e..154191bb488d1 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,3 +1,12 @@ +S 2014-09-28 7eb9337 + freebsd-x86_64 d45e0edd44f40a976ea0affaadd98732684cfca0 + linux-i386 3acb35755aa62b7ff78f76007d9a70696fce7aa7 + linux-x86_64 2615b67b700ae8f7d8d87c043207a1a6e2339389 + macos-i386 5eb4552dc66a14e1eff6e806a8ba27f4a73bb02a + macos-x86_64 c6052632443f638f5024ae38f33ae2c80d8b18bd + winnt-i386 269f46347b5766bff6f888c4307d50c475d3fe0f + winnt-x86_64 06f89825cecda7f2e36a4660ffe6d2d4a0430ab4 + S 2014-09-22 437179e freebsd-x86_64 f693c0441de3dbb2d471dde5a5045ac8a48807d8 linux-i386 5c2132b65f45c21b43d28de6a9460978b1a7b08a diff --git a/src/test/compile-fail/asm-src-loc-codegen-units.rs b/src/test/compile-fail/asm-src-loc-codegen-units.rs new file mode 100644 index 0000000000000..1b8fb32a808dc --- /dev/null +++ b/src/test/compile-fail/asm-src-loc-codegen-units.rs @@ -0,0 +1,20 @@ +// 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. +// +// compile-flags: -C codegen-units=2 +// error-pattern: build without -C codegen-units for more exact errors + +#![feature(asm)] + +fn main() { + unsafe { + asm!("nowayisthisavalidinstruction"); + } +} diff --git a/src/test/compile-fail/asm-src-loc.rs b/src/test/compile-fail/asm-src-loc.rs new file mode 100644 index 0000000000000..b4ebe07776a4d --- /dev/null +++ b/src/test/compile-fail/asm-src-loc.rs @@ -0,0 +1,17 @@ +// 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. + +#![feature(asm)] + +fn main() { + unsafe { + asm!("nowayisthisavalidinstruction"); //~ ERROR invalid instruction + } +} diff --git a/src/test/compile-fail/conflicting-implementations-aux.rs b/src/test/compile-fail/conflicting-implementations-aux.rs index c1aa6ccd9bde6..99446be43acaa 100644 --- a/src/test/compile-fail/conflicting-implementations-aux.rs +++ b/src/test/compile-fail/conflicting-implementations-aux.rs @@ -15,7 +15,9 @@ extern crate trait_impl_conflict; use trait_impl_conflict::Foo; -impl Foo for A { //~ ERROR E0117 +impl Foo for A { + //~^ ERROR E0117 + //~^^ ERROR E0119 } fn main() { diff --git a/src/test/compile-fail/issue-16465.rs b/src/test/compile-fail/issue-16465.rs new file mode 100644 index 0000000000000..280f19cfe9cc7 --- /dev/null +++ b/src/test/compile-fail/issue-16465.rs @@ -0,0 +1,24 @@ +// 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. + +// Used to cause an ICE + +struct Foo{ + x : T +} + +type FooInt = Foo; + +impl Drop for FooInt { +//~^ ERROR cannot implement a destructor on a structure with type parameters + fn drop(&mut self){} +} + +fn main() {} diff --git a/src/test/compile-fail/issue-17441.rs b/src/test/compile-fail/issue-17441.rs new file mode 100644 index 0000000000000..da548ca5ffe3e --- /dev/null +++ b/src/test/compile-fail/issue-17441.rs @@ -0,0 +1,24 @@ +// 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. + +fn main() { + let _foo = &[1u, 2] as [uint]; + //~^ ERROR cast to unsized type: `&[uint, .. 2]` as `[uint]` + //~^^ NOTE consider using an implicit coercion to `&[uint]` instead + let _bar = box 1u as std::fmt::Show; + //~^ ERROR cast to unsized type: `Box` as `core::fmt::Show` + //~^^ NOTE did you mean `Box`? + let _baz = 1u as std::fmt::Show; + //~^ ERROR cast to unsized type: `uint` as `core::fmt::Show` + //~^^ NOTE consider using a box or reference as appropriate + let _quux = [1u, 2] as [uint]; + //~^ ERROR cast to unsized type: `[uint, .. 2]` as `[uint]` + //~^^ NOTE consider using a box or reference as appropriate +} diff --git a/src/test/compile-fail/pat-range-bad-dots.rs b/src/test/compile-fail/pat-range-bad-dots.rs new file mode 100644 index 0000000000000..b3c436f6d2b67 --- /dev/null +++ b/src/test/compile-fail/pat-range-bad-dots.rs @@ -0,0 +1,18 @@ +// 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. + +// ignore-test + +pub fn main() { + match 22i { + 0 .. 3 => {} //~ ERROR expected `=>`, found `..` + _ => {} + } +} diff --git a/src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs b/src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs index 7520a4c125a78..e046b5c68addd 100644 --- a/src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs +++ b/src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs @@ -17,7 +17,7 @@ fn main() { { let c = 1; let c_ref = &c; //~ ERROR `c` does not live long enough - f = |&mut: a: int, b: int| { a + b + *c_ref }; + f = move |&mut: a: int, b: int| { a + b + *c_ref }; } } diff --git a/src/test/run-make/lto-readonly-lib/Makefile b/src/test/run-make/lto-readonly-lib/Makefile new file mode 100644 index 0000000000000..0afbbc3450ac7 --- /dev/null +++ b/src/test/run-make/lto-readonly-lib/Makefile @@ -0,0 +1,12 @@ +-include ../tools.mk + +all: + $(RUSTC) lib.rs + + # the compiler needs to copy and modify the rlib file when performing + # LTO, so we should ensure that it can cope with the original rlib + # being read-only. + chmod 444 $(TMPDIR)/*.rlib + + $(RUSTC) main.rs -C lto + $(call RUN,main) diff --git a/src/test/run-make/lto-readonly-lib/lib.rs b/src/test/run-make/lto-readonly-lib/lib.rs new file mode 100644 index 0000000000000..04d3ae6720722 --- /dev/null +++ b/src/test/run-make/lto-readonly-lib/lib.rs @@ -0,0 +1,11 @@ +// 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. + +#![crate_type = "rlib"] diff --git a/src/test/run-make/lto-readonly-lib/main.rs b/src/test/run-make/lto-readonly-lib/main.rs new file mode 100644 index 0000000000000..e12ac9e01dc17 --- /dev/null +++ b/src/test/run-make/lto-readonly-lib/main.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. + +extern crate lib; + +fn main() {} diff --git a/src/test/run-make/rustdoc-where/Makefile b/src/test/run-make/rustdoc-where/Makefile new file mode 100644 index 0000000000000..864d594cf9963 --- /dev/null +++ b/src/test/run-make/rustdoc-where/Makefile @@ -0,0 +1,6 @@ +-include ../tools.mk + +all: verify.sh foo.rs + $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs + cp verify.sh $(TMPDIR) + $(call RUN,verify.sh) $(TMPDIR) diff --git a/src/test/run-make/rustdoc-where/foo.rs b/src/test/run-make/rustdoc-where/foo.rs new file mode 100644 index 0000000000000..7e6df7f011ab7 --- /dev/null +++ b/src/test/run-make/rustdoc-where/foo.rs @@ -0,0 +1,26 @@ +// 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 trait MyTrait {} + +pub struct Alpha where A: MyTrait; +pub trait Bravo where B: MyTrait {} +pub fn charlie() where C: MyTrait {} + +pub struct Delta; +impl Delta where D: MyTrait { + pub fn delta() {} +} + +pub struct Echo; +impl MyTrait for Echo where E: MyTrait {} + +pub enum Foxtrot {} +impl MyTrait for Foxtrot where F: MyTrait {} diff --git a/src/test/run-make/rustdoc-where/verify.sh b/src/test/run-make/rustdoc-where/verify.sh new file mode 100755 index 0000000000000..5d424da02adb9 --- /dev/null +++ b/src/test/run-make/rustdoc-where/verify.sh @@ -0,0 +1,23 @@ +#!/bin/bash +set -e + +# $1 is the TMPDIR +DOC=$1/doc/foo + +grep "Alpha.*where.*A:.*MyTrait" $DOC/struct.Alpha.html > /dev/null +echo "Alpha" +grep "Bravo.*where.*B:.*MyTrait" $DOC/trait.Bravo.html > /dev/null +echo "Bravo" +grep "charlie.*where.*C:.*MyTrait" $DOC/fn.charlie.html > /dev/null +echo "Charlie" +grep "impl.*Delta.*where.*D:.*MyTrait" $DOC/struct.Delta.html > /dev/null +echo "Delta" +grep "impl.*MyTrait.*for.*Echo.*where.*E:.*MyTrait" $DOC/struct.Echo.html > /dev/null +echo "Echo" +grep "impl.*MyTrait.*for.*Foxtrot.*where.*F:.*MyTrait" $DOC/enum.Foxtrot.html > /dev/null +echo "Foxtrot" + +# check "Implementors" section of MyTrait +grep "impl.*MyTrait.*for.*Echo.*where.*E:.*MyTrait" $DOC/trait.MyTrait.html > /dev/null +grep "impl.*MyTrait.*for.*Foxtrot.*where.*F:.*MyTrait" $DOC/trait.MyTrait.html > /dev/null +echo "Implementors OK" diff --git a/src/test/run-pass/capture-clauses-boxed-closures.rs b/src/test/run-pass/capture-clauses-boxed-closures.rs index c88b44925d06a..a1411146ddda6 100644 --- a/src/test/run-pass/capture-clauses-boxed-closures.rs +++ b/src/test/run-pass/capture-clauses-boxed-closures.rs @@ -17,7 +17,7 @@ fn each(x: &[T], f: |&T|) { fn main() { let mut sum = 0u; let elems = [ 1u, 2, 3, 4, 5 ]; - each(elems, ref |val| sum += *val); + each(elems, |val| sum += *val); assert_eq!(sum, 15); } diff --git a/src/test/run-pass/non-built-in-quote.rs b/src/test/run-pass/non-built-in-quote.rs new file mode 100644 index 0000000000000..c6dd373685794 --- /dev/null +++ b/src/test/run-pass/non-built-in-quote.rs @@ -0,0 +1,17 @@ +// 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. + +#![feature(macro_rules)] + +macro_rules! quote_tokens ( () => (()) ) + +pub fn main() { + quote_tokens!(); +} diff --git a/src/test/run-pass/unboxed-closures-all-traits.rs b/src/test/run-pass/unboxed-closures-all-traits.rs index d91204951551a..508d1e46f7e18 100644 --- a/src/test/run-pass/unboxed-closures-all-traits.rs +++ b/src/test/run-pass/unboxed-closures-all-traits.rs @@ -24,8 +24,8 @@ fn c int>(f: F) -> int { fn main() { let z: int = 7; - assert_eq!(a(|&: x: int, y| x + y + z), 10); - assert_eq!(b(|&mut: x: int, y| x + y + z), 14); - assert_eq!(c(|: x: int, y| x + y + z), 18); + assert_eq!(a(move |&: x: int, y| x + y + z), 10); + assert_eq!(b(move |&mut: x: int, y| x + y + z), 14); + assert_eq!(c(move |: x: int, y| x + y + z), 18); } diff --git a/src/test/run-pass/unboxed-closures-boxed.rs b/src/test/run-pass/unboxed-closures-boxed.rs index 746af1b9cf524..ab3faa16f948f 100644 --- a/src/test/run-pass/unboxed-closures-boxed.rs +++ b/src/test/run-pass/unboxed-closures-boxed.rs @@ -13,7 +13,8 @@ use std::ops::FnMut; fn make_adder(x: int) -> Box+'static> { - (box |&mut: y: int| -> int { x + y }) as Box+'static> + (box move |&mut: y: int| -> int { x + y }) as + Box+'static> } pub fn main() { diff --git a/src/test/run-pass/unboxed-closures-drop.rs b/src/test/run-pass/unboxed-closures-drop.rs index a455e4d203263..00bf5fac095cd 100644 --- a/src/test/run-pass/unboxed-closures-drop.rs +++ b/src/test/run-pass/unboxed-closures-drop.rs @@ -55,13 +55,13 @@ fn c int>(f: F) -> int { fn test_fn() { { - a(|&: a: int, b| { a + b }); + a(move |&: a: int, b| { a + b }); } assert_eq!(drop_count(), 0); { let z = &Droppable::new(); - a(|&: a: int, b| { z; a + b }); + a(move |&: a: int, b| { z; a + b }); assert_eq!(drop_count(), 0); } assert_eq!(drop_count(), 1); @@ -69,7 +69,7 @@ fn test_fn() { { let z = &Droppable::new(); let zz = &Droppable::new(); - a(|&: a: int, b| { z; zz; a + b }); + a(move |&: a: int, b| { z; zz; a + b }); assert_eq!(drop_count(), 1); } assert_eq!(drop_count(), 3); @@ -77,13 +77,13 @@ fn test_fn() { fn test_fn_mut() { { - b(|&mut: a: int, b| { a + b }); + b(move |&mut: a: int, b| { a + b }); } assert_eq!(drop_count(), 3); { let z = &Droppable::new(); - b(|&mut: a: int, b| { z; a + b }); + b(move |&mut: a: int, b| { z; a + b }); assert_eq!(drop_count(), 3); } assert_eq!(drop_count(), 4); @@ -91,7 +91,7 @@ fn test_fn_mut() { { let z = &Droppable::new(); let zz = &Droppable::new(); - b(|&mut: a: int, b| { z; zz; a + b }); + b(move |&mut: a: int, b| { z; zz; a + b }); assert_eq!(drop_count(), 4); } assert_eq!(drop_count(), 6); @@ -99,13 +99,13 @@ fn test_fn_mut() { fn test_fn_once() { { - c(|: a: int, b| { a + b }); + c(move |: a: int, b| { a + b }); } assert_eq!(drop_count(), 6); { let z = Droppable::new(); - c(|: a: int, b| { z; a + b }); + c(move |: a: int, b| { z; a + b }); assert_eq!(drop_count(), 7); } assert_eq!(drop_count(), 7); @@ -113,7 +113,7 @@ fn test_fn_once() { { let z = Droppable::new(); let zz = Droppable::new(); - c(|: a: int, b| { z; zz; a + b }); + c(move |: a: int, b| { z; zz; a + b }); assert_eq!(drop_count(), 9); } assert_eq!(drop_count(), 9); diff --git a/src/test/run-pass/unboxed-closures-single-word-env.rs b/src/test/run-pass/unboxed-closures-single-word-env.rs index aef6956118ecb..4239cfdd8cf14 100644 --- a/src/test/run-pass/unboxed-closures-single-word-env.rs +++ b/src/test/run-pass/unboxed-closures-single-word-env.rs @@ -27,8 +27,8 @@ fn c int>(f: F) -> int { fn main() { let z = 10; - assert_eq!(a(|&: x: int, y| x + y + z), 13); - assert_eq!(b(|&mut: x: int, y| x + y + z), 17); - assert_eq!(c(|: x: int, y| x + y + z), 21); + assert_eq!(a(move |&: x: int, y| x + y + z), 13); + assert_eq!(b(move |&mut: x: int, y| x + y + z), 17); + assert_eq!(c(move |: x: int, y| x + y + z), 21); }