diff --git a/src/Cargo.lock b/src/Cargo.lock index 51d45c06fcb49..1d1d63c9ee463 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -762,14 +762,6 @@ dependencies = [ "unwind 0.0.0", ] -[[package]] -name = "std_shim" -version = "0.0.0" -dependencies = [ - "core 0.0.0", - "std 0.0.0", -] - [[package]] name = "std_unicode" version = "0.0.0" @@ -835,13 +827,6 @@ dependencies = [ "term 0.0.0", ] -[[package]] -name = "test_shim" -version = "0.0.0" -dependencies = [ - "test 0.0.0", -] - [[package]] name = "thread-id" version = "2.0.0" diff --git a/src/Cargo.toml b/src/Cargo.toml index d8dedd11f357d..0dafbb8428e3e 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -2,8 +2,8 @@ members = [ "bootstrap", "rustc", - "rustc/std_shim", - "rustc/test_shim", + "libstd", + "libtest", "tools/cargotest", "tools/compiletest", "tools/error_index_generator", diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md index ac84edb403847..2f7757fb1d5ba 100644 --- a/src/bootstrap/README.md +++ b/src/bootstrap/README.md @@ -267,8 +267,8 @@ build/ The current build is unfortunately not quite as simple as `cargo build` in a directory, but rather the compiler is split into three different Cargo projects: -* `src/rustc/std_shim` - a project which builds and compiles libstd -* `src/rustc/test_shim` - a project which builds and compiles libtest +* `src/libstd` - the standard library +* `src/libtest` - testing support, depends on libstd * `src/rustc` - the actual compiler itself Each "project" has a corresponding Cargo.lock file with all dependencies, and diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 90fd31ecbdd73..bf1da57607d5f 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -68,6 +68,7 @@ fn main() { }; let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set"); let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set"); + let mut on_fail = env::var_os("RUSTC_ON_FAIL").map(|of| Command::new(of)); let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc)); let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir)); @@ -212,9 +213,20 @@ fn main() { } // Actually run the compiler! - std::process::exit(match exec_cmd(&mut cmd) { - Ok(s) => s.code().unwrap_or(0xfe), - Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e), + std::process::exit(if let Some(ref mut on_fail) = on_fail { + match cmd.status() { + Ok(s) if s.success() => 0, + _ => { + println!("\nDid not run successfully:\n{:?}\n-------------", cmd); + exec_cmd(on_fail).expect("could not run the backup command"); + 1 + } + } + } else { + std::process::exit(match exec_cmd(&mut cmd) { + Ok(s) => s.code().unwrap_or(0xfe), + Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e), + }) }) } diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 00758460becc5..dfe96b51799c0 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -346,10 +346,10 @@ pub fn krate(build: &Build, krate: Option<&str>) { let (name, path, features, root) = match mode { Mode::Libstd => { - ("libstd", "src/rustc/std_shim", build.std_features(), "std_shim") + ("libstd", "src/libstd", build.std_features(), "std") } Mode::Libtest => { - ("libtest", "src/rustc/test_shim", String::new(), "test_shim") + ("libtest", "src/libtest", String::new(), "test") } Mode::Librustc => { ("librustc", "src/rustc", build.rustc_features(), "rustc-main") diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 0b1a1f39d8d42..00904bc776aa9 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -64,7 +64,7 @@ pub fn std(build: &Build, target: &str, compiler: &Compiler) { } cargo.arg("--features").arg(features) .arg("--manifest-path") - .arg(build.src.join("src/rustc/std_shim/Cargo.toml")); + .arg(build.src.join("src/libstd/Cargo.toml")); if let Some(target) = build.config.target_config.get(target) { if let Some(ref jemalloc) = target.jemalloc { @@ -162,7 +162,7 @@ pub fn test(build: &Build, target: &str, compiler: &Compiler) { build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target)); let mut cargo = build.cargo(compiler, Mode::Libtest, target, "build"); cargo.arg("--manifest-path") - .arg(build.src.join("src/rustc/test_shim/Cargo.toml")); + .arg(build.src.join("src/libtest/Cargo.toml")); build.run(&mut cargo); update_mtime(build, &libtest_stamp(build, compiler, target)); } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 74b13144f2ff0..3fcc15b35b541 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -152,7 +152,7 @@ pub fn std(build: &Build, stage: u32, target: &str) { let mut cargo = build.cargo(&compiler, Mode::Libstd, target, "doc"); cargo.arg("--manifest-path") - .arg(build.src.join("src/rustc/std_shim/Cargo.toml")) + .arg(build.src.join("src/libstd/Cargo.toml")) .arg("--features").arg(build.std_features()); // We don't want to build docs for internal std dependencies unless @@ -198,7 +198,7 @@ pub fn test(build: &Build, stage: u32, target: &str) { let mut cargo = build.cargo(&compiler, Mode::Libtest, target, "doc"); cargo.arg("--manifest-path") - .arg(build.src.join("src/rustc/test_shim/Cargo.toml")); + .arg(build.src.join("src/libtest/Cargo.toml")); build.run(&mut cargo); cp_r(&out_dir, &out) } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index c5bbfd89b2787..b55f3d710ca7b 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -28,6 +28,7 @@ use step; /// Deserialized version of all flags for this compile. pub struct Flags { pub verbose: usize, // verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose + pub on_fail: Option, pub stage: Option, pub keep_stage: Option, pub build: String, @@ -81,6 +82,7 @@ impl Flags { opts.optopt("", "build", "build target of the stage0 compiler", "BUILD"); opts.optmulti("", "host", "host targets to build", "HOST"); opts.optmulti("", "target", "target targets to build", "TARGET"); + opts.optopt("", "on-fail", "command to run on failure", "CMD"); opts.optopt("", "stage", "stage to build", "N"); opts.optopt("", "keep-stage", "stage to keep without recompiling", "N"); opts.optopt("", "src", "path to the root of the rust checkout", "DIR"); @@ -283,6 +285,7 @@ To learn more about a subcommand, run `./x.py -h` Flags { verbose: m.opt_count("v"), stage: stage, + on_fail: m.opt_str("on-fail"), keep_stage: m.opt_str("keep-stage").map(|j| j.parse().unwrap()), build: m.opt_str("build").unwrap_or_else(|| { env::var("BUILD").unwrap() diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 7bd611eb53e3c..a28cb24a8166f 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -499,6 +499,10 @@ impl Build { cargo.env("RUSTC_INCREMENTAL", incr_dir); } + if let Some(ref on_fail) = self.flags.on_fail { + cargo.env("RUSTC_ON_FAIL", on_fail); + } + let verbose = cmp::max(self.config.verbose, self.flags.verbose); cargo.env("RUSTC_VERBOSE", format!("{}", verbose)); diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index 8befb105ff618..5ab542b6a2489 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -43,8 +43,8 @@ struct ResolveNode { } pub fn build(build: &mut Build) { - build_krate(build, "src/rustc/std_shim"); - build_krate(build, "src/rustc/test_shim"); + build_krate(build, "src/libstd"); + build_krate(build, "src/libtest"); build_krate(build, "src/rustc"); } diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index ee5b61062fed8..ef84693b5b319 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -246,14 +246,14 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { crate_rule(build, &mut rules, "libstd-link", - "build-crate-std_shim", + "build-crate-std", compile::std_link) .dep(|s| s.name("startup-objects")) .dep(|s| s.name("create-sysroot").target(s.host)); crate_rule(build, &mut rules, "libtest-link", - "build-crate-test_shim", + "build-crate-test", compile::test_link) .dep(|s| s.name("libstd-link")); crate_rule(build, @@ -263,13 +263,13 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { compile::rustc_link) .dep(|s| s.name("libtest-link")); - for (krate, path, _default) in krates("std_shim") { + for (krate, path, _default) in krates("std") { rules.build(&krate.build_step, path) .dep(|s| s.name("startup-objects")) .dep(move |s| s.name("rustc").host(&build.config.build).target(s.host)) .run(move |s| compile::std(build, s.target, &s.compiler())); } - for (krate, path, _default) in krates("test_shim") { + for (krate, path, _default) in krates("test") { rules.build(&krate.build_step, path) .dep(|s| s.name("libstd-link")) .run(move |s| compile::test(build, s.target, &s.compiler())); @@ -384,7 +384,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { "pretty", "run-fail-fulldeps"); } - for (krate, path, _default) in krates("std_shim") { + for (krate, path, _default) in krates("std") { rules.test(&krate.test_step, path) .dep(|s| s.name("libtest")) .dep(|s| s.name("emulator-copy-libs")) @@ -400,7 +400,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { Mode::Libstd, TestKind::Test, None)); // std benchmarks - for (krate, path, _default) in krates("std_shim") { + for (krate, path, _default) in krates("std") { rules.bench(&krate.bench_step, path) .dep(|s| s.name("libtest")) .dep(|s| s.name("emulator-copy-libs")) @@ -415,7 +415,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .run(move |s| check::krate(build, &s.compiler(), s.target, Mode::Libstd, TestKind::Bench, None)); - for (krate, path, _default) in krates("test_shim") { + for (krate, path, _default) in krates("test") { rules.test(&krate.test_step, path) .dep(|s| s.name("libtest")) .dep(|s| s.name("emulator-copy-libs")) @@ -583,13 +583,13 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .default(build.config.docs) .host(true) .run(move |s| doc::error_index(build, s.target)); - for (krate, path, default) in krates("std_shim") { + for (krate, path, default) in krates("std") { rules.doc(&krate.doc_step, path) .dep(|s| s.name("libstd-link")) .default(default && build.config.docs) .run(move |s| doc::std(build, s.stage, s.target)); } - for (krate, path, default) in krates("test_shim") { + for (krate, path, default) in krates("test") { rules.doc(&krate.doc_step, path) .dep(|s| s.name("libtest-link")) .default(default && build.config.compiler_docs) @@ -1154,23 +1154,23 @@ mod tests { let mut build = Build::new(flags, config); let cwd = env::current_dir().unwrap(); - build.crates.insert("std_shim".to_string(), ::Crate { - name: "std_shim".to_string(), + build.crates.insert("std".to_string(), ::Crate { + name: "std".to_string(), deps: Vec::new(), - path: cwd.join("src/std_shim"), - doc_step: "doc-std_shim".to_string(), - build_step: "build-crate-std_shim".to_string(), - test_step: "test-std_shim".to_string(), - bench_step: "bench-std_shim".to_string(), + path: cwd.join("src/std"), + doc_step: "doc-std".to_string(), + build_step: "build-crate-std".to_string(), + test_step: "test-std".to_string(), + bench_step: "bench-std".to_string(), }); - build.crates.insert("test_shim".to_string(), ::Crate { - name: "test_shim".to_string(), + build.crates.insert("test".to_string(), ::Crate { + name: "test".to_string(), deps: Vec::new(), - path: cwd.join("src/test_shim"), - doc_step: "doc-test_shim".to_string(), - build_step: "build-crate-test_shim".to_string(), - test_step: "test-test_shim".to_string(), - bench_step: "bench-test_shim".to_string(), + path: cwd.join("src/test"), + doc_step: "doc-test".to_string(), + build_step: "build-crate-test".to_string(), + test_step: "test-test".to_string(), + bench_step: "bench-test".to_string(), }); build.crates.insert("rustc-main".to_string(), ::Crate { name: "rustc-main".to_string(), @@ -1360,7 +1360,7 @@ mod tests { let all = rules.expand(&plan); println!("all rules: {:#?}", all); assert!(!all.contains(&step.name("rustc"))); - assert!(!all.contains(&step.name("build-crate-std_shim").stage(1))); + assert!(!all.contains(&step.name("build-crate-std").stage(1))); // all stage0 compiles should be for the build target, A for step in all.iter().filter(|s| s.stage == 0) { @@ -1425,7 +1425,7 @@ mod tests { assert!(!plan.iter().any(|s| s.name.contains("rustc"))); assert!(plan.iter().all(|s| { - !s.name.contains("test_shim") || s.target == "C" + !s.name.contains("test") || s.target == "C" })); } diff --git a/src/doc/book/src/procedural-macros.md b/src/doc/book/src/procedural-macros.md index 6c4700f9305ca..079324d56d1e6 100644 --- a/src/doc/book/src/procedural-macros.md +++ b/src/doc/book/src/procedural-macros.md @@ -169,7 +169,7 @@ So this is where quotes comes in. The `ast` argument is a struct that gives us a representation of our type (which can be either a `struct` or an `enum`). Check out the [docs](https://docs.rs/syn/0.10.5/syn/struct.MacroInput.html), there is some useful information there. We are able to get the name of the -type using `ast.ident`. The `quote!` macro let's us write up the Rust code +type using `ast.ident`. The `quote!` macro lets us write up the Rust code that we wish to return and convert it into `Tokens`. `quote!` let's us use some really cool templating mechanics; we simply write `#name` and `quote!` will replace it with the variable named `name`. You can even do some repetition diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs index 8d81a09f5af0f..a496ab870c63b 100644 --- a/src/liballoc_jemalloc/lib.rs +++ b/src/liballoc_jemalloc/lib.rs @@ -122,18 +122,6 @@ mod imp { let flags = align_to_flags(align); unsafe { nallocx(size as size_t, flags) as usize } } - - // These symbols are used by jemalloc on android but the really old android - // we're building on doesn't have them defined, so just make sure the symbols - // are available. - #[no_mangle] - #[cfg(all(target_os = "android", not(cargobuild)))] - pub extern "C" fn pthread_atfork(_prefork: *mut u8, - _postfork_parent: *mut u8, - _postfork_child: *mut u8) - -> i32 { - 0 - } } #[cfg(dummy_jemalloc)] diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index d8212807eb277..3403cf0477450 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -777,6 +777,12 @@ pub enum StatementKind<'tcx> { /// End the current live range for the storage of the local. StorageDead(Lvalue<'tcx>), + InlineAsm { + asm: InlineAsm, + outputs: Vec>, + inputs: Vec> + }, + /// No-op. Useful for deleting instructions without affecting statement indices. Nop, } @@ -790,7 +796,10 @@ impl<'tcx> Debug for Statement<'tcx> { StorageDead(ref lv) => write!(fmt, "StorageDead({:?})", lv), SetDiscriminant{lvalue: ref lv, variant_index: index} => { write!(fmt, "discriminant({:?}) = {:?}", lv, index) - } + }, + InlineAsm { ref asm, ref outputs, ref inputs } => { + write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs) + }, Nop => write!(fmt, "nop"), } } @@ -1004,12 +1013,6 @@ pub enum Rvalue<'tcx> { /// that `Foo` has a destructor. These rvalues can be optimized /// away after type-checking and before lowering. Aggregate(AggregateKind<'tcx>, Vec>), - - InlineAsm { - asm: InlineAsm, - outputs: Vec>, - inputs: Vec> - } } #[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)] @@ -1111,10 +1114,6 @@ impl<'tcx> Debug for Rvalue<'tcx> { UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a), Discriminant(ref lval) => write!(fmt, "discriminant({:?})", lval), Box(ref t) => write!(fmt, "Box({:?})", t), - InlineAsm { ref asm, ref outputs, ref inputs } => { - write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs) - } - Ref(_, borrow_kind, ref lv) => { let kind_str = match borrow_kind { BorrowKind::Shared => "", diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 7b0863b4c42bc..5c8d031caf60d 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -207,7 +207,6 @@ impl<'tcx> Rvalue<'tcx> { } } } - Rvalue::InlineAsm { .. } => None } } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index be3c43db7badd..7cdbd5cae061f 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -333,6 +333,16 @@ macro_rules! make_mir_visitor { StatementKind::StorageDead(ref $($mutability)* lvalue) => { self.visit_lvalue(lvalue, LvalueContext::StorageDead, location); } + StatementKind::InlineAsm { ref $($mutability)* outputs, + ref $($mutability)* inputs, + asm: _ } => { + for output in & $($mutability)* outputs[..] { + self.visit_lvalue(output, LvalueContext::Store, location); + } + for input in & $($mutability)* inputs[..] { + self.visit_operand(input, location); + } + } StatementKind::Nop => {} } } @@ -526,17 +536,6 @@ macro_rules! make_mir_visitor { self.visit_operand(operand, location); } } - - Rvalue::InlineAsm { ref $($mutability)* outputs, - ref $($mutability)* inputs, - asm: _ } => { - for output in & $($mutability)* outputs[..] { - self.visit_lvalue(output, LvalueContext::Store, location); - } - for input in & $($mutability)* inputs[..] { - self.visit_operand(input, location); - } - } } } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 41f3f825c3d19..40c62762c3cf3 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2547,7 +2547,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // TyError and ensure they do not affect any other fields. // This could be checked after type collection for any struct // with a potentially unsized trailing field. - let params = substs_a.params().iter().enumerate().map(|(i, &k)| { + let params = substs_a.iter().enumerate().map(|(i, &k)| { if ty_params.contains(i) { Kind::from(tcx.types.err) } else { @@ -2567,7 +2567,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // Check that the source structure with the target's // type parameters is a subtype of the target. - let params = substs_a.params().iter().enumerate().map(|(i, &k)| { + let params = substs_a.iter().enumerate().map(|(i, &k)| { if ty_params.contains(i) { Kind::from(substs_b.type_at(i)) } else { diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index adedf78bba7c0..2e3009b4ed6db 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -143,7 +143,7 @@ pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R, { let tcx = relation.tcx(); - let params = a_subst.params().iter().zip(b_subst.params()).enumerate().map(|(i, (a, b))| { + let params = a_subst.iter().zip(b_subst).enumerate().map(|(i, (a, b))| { let variance = variances.map_or(ty::Invariant, |v| v[i]); if let (Some(a_ty), Some(b_ty)) = (a.as_type(), b.as_type()) { Ok(Kind::from(relation.relate_with_variance(variance, &a_ty, &b_ty)?)) diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index d6f61a12a3c6e..c0a529b936b0f 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -254,12 +254,6 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { self.is_empty() } - #[inline] - pub fn params(&self) -> &[Kind<'tcx>] { - // FIXME (dikaiosune) this should be removed, and corresponding compilation errors fixed - self - } - #[inline] pub fn types(&'a self) -> impl DoubleEndedIterator> + 'a { self.iter().filter_map(|k| k.as_type()) diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs b/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs index 1fa4da94dd6bf..7888a56d39dfb 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs @@ -473,6 +473,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> { } mir::StatementKind::StorageLive(_) | mir::StatementKind::StorageDead(_) | + mir::StatementKind::InlineAsm { .. } | mir::StatementKind::Nop => {} } } diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs index ea6ef423c92ce..940dd5433a0d9 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs @@ -104,6 +104,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } mir::StatementKind::StorageLive(_) | mir::StatementKind::StorageDead(_) | + mir::StatementKind::InlineAsm { .. } | mir::StatementKind::Nop => continue, mir::StatementKind::SetDiscriminant{ .. } => span_bug!(stmt.source_info.span, diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs index 0c7e922c48ab4..35ace6628cfed 100644 --- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs @@ -412,6 +412,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { span_bug!(stmt.source_info.span, "SetDiscriminant should not exist during borrowck"); } + StatementKind::InlineAsm { .. } | StatementKind::Nop => {} } } @@ -436,8 +437,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { } Rvalue::Ref(..) | Rvalue::Discriminant(..) | - Rvalue::Len(..) | - Rvalue::InlineAsm { .. } => {} + Rvalue::Len(..) => {} Rvalue::Box(..) => { // This returns an rvalue with uninitialized contents. We can't // move out of it here because it is an rvalue - assignments always diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs index a0c36139ddcd2..d9283e7037f50 100644 --- a/src/librustc_borrowck/borrowck/mir/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/mod.rs @@ -378,6 +378,7 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>( } mir::StatementKind::StorageLive(_) | mir::StatementKind::StorageDead(_) | + mir::StatementKind::InlineAsm { .. } | mir::StatementKind::Nop => {} }, None => { diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index dad1d713168cd..7adcc0e730b15 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -49,21 +49,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::Scope { extent, value } => { this.in_scope(extent, block, |this| this.as_rvalue(block, value)) } - ExprKind::InlineAsm { asm, outputs, inputs } => { - let outputs = outputs.into_iter().map(|output| { - unpack!(block = this.as_lvalue(block, output)) - }).collect(); - - let inputs = inputs.into_iter().map(|input| { - unpack!(block = this.as_operand(block, input)) - }).collect(); - - block.and(Rvalue::InlineAsm { - asm: asm.clone(), - outputs: outputs, - inputs: inputs - }) - } ExprKind::Repeat { value, count } => { let value_operand = unpack!(block = this.as_operand(block, value)); block.and(Rvalue::Repeat(value_operand, count)) @@ -238,6 +223,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::Break { .. } | ExprKind::Continue { .. } | ExprKind::Return { .. } | + ExprKind::InlineAsm { .. } | ExprKind::StaticRef { .. } => { // these do not have corresponding `Rvalue` variants, // so make an operand and then return that diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 35841c2cbdf01..e66f2b4e2bfc0 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -232,6 +232,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::AssignOp { .. } | ExprKind::Continue { .. } | ExprKind::Break { .. } | + ExprKind::InlineAsm { .. } | ExprKind::Return {.. } => { this.stmt_expr(block, expr) } @@ -257,7 +258,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::Index { .. } | ExprKind::Deref { .. } | ExprKind::Literal { .. } | - ExprKind::InlineAsm { .. } | ExprKind::Field { .. } => { debug_assert!(match Category::of(&expr.kind).unwrap() { Category::Rvalue(RvalueFunc::Into) => false, diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir/build/expr/stmt.rs index f04d630379a35..c577aab40dbeb 100644 --- a/src/librustc_mir/build/expr/stmt.rs +++ b/src/librustc_mir/build/expr/stmt.rs @@ -117,6 +117,23 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { this.exit_scope(expr_span, extent, block, return_block); this.cfg.start_new_block().unit() } + ExprKind::InlineAsm { asm, outputs, inputs } => { + let outputs = outputs.into_iter().map(|output| { + unpack!(block = this.as_lvalue(block, output)) + }).collect(); + let inputs = inputs.into_iter().map(|input| { + unpack!(block = this.as_operand(block, input)) + }).collect(); + this.cfg.push(block, Statement { + source_info: source_info, + kind: StatementKind::InlineAsm { + asm: asm.clone(), + outputs: outputs, + inputs: inputs + }, + }); + block.unit() + } _ => { let expr_ty = expr.ty; let temp = this.temp(expr.ty.clone()); diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 922521726c626..4459142cfb274 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -774,10 +774,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } } } - - Rvalue::InlineAsm {..} => { - self.not_const(); - } } } @@ -933,6 +929,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { StatementKind::SetDiscriminant { .. } | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | + StatementKind::InlineAsm {..} | StatementKind::Nop => {} } }); diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 8ede7aaab5f68..8d108815e0f3c 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -361,9 +361,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { span_mirbug!(self, stmt, "bad assignment ({:?} = {:?}): {:?}", lv_ty, rv_ty, terr); } - // FIXME: rvalue with undeterminable type - e.g. inline - // asm. } + // FIXME: rvalue with undeterminable type - e.g. AggregateKind::Array branch that + // returns `None`. } StatementKind::SetDiscriminant{ ref lvalue, variant_index } => { let lvalue_type = lvalue.ty(mir, tcx).to_ty(tcx); @@ -392,6 +392,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } } } + StatementKind::InlineAsm { .. } | StatementKind::Nop => {} } } diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs index 517a472056334..33b7089c38214 100644 --- a/src/librustc_passes/mir_stats.rs +++ b/src/librustc_passes/mir_stats.rs @@ -128,6 +128,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> { StatementKind::SetDiscriminant { .. } => "StatementKind::SetDiscriminant", StatementKind::StorageLive(..) => "StatementKind::StorageLive", StatementKind::StorageDead(..) => "StatementKind::StorageDead", + StatementKind::InlineAsm { .. } => "StatementKind::InlineAsm", StatementKind::Nop => "StatementKind::Nop", }, &statement.kind); self.super_statement(block, statement, location); @@ -198,7 +199,6 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> { "Rvalue::Aggregate" } - Rvalue::InlineAsm { .. } => "Rvalue::InlineAsm", }; self.record(rvalue_kind, rvalue); self.super_rvalue(rvalue, location); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 676ff98e602d6..7a64e0f098c81 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -96,6 +96,12 @@ enum AssocSuggestion { AssocItem, } +struct BindingError { + name: Name, + origin: FxHashSet, + target: FxHashSet, +} + enum ResolutionError<'a> { /// error E0401: can't use type parameters from outer function TypeParametersFromOuterFunction, @@ -109,10 +115,10 @@ enum ResolutionError<'a> { TypeNotMemberOfTrait(Name, &'a str), /// error E0438: const is not a member of trait ConstNotMemberOfTrait(Name, &'a str), - /// error E0408: variable `{}` from pattern #{} is not bound in pattern #{} - VariableNotBoundInPattern(Name, usize, usize), - /// error E0409: variable is bound with different mode in pattern #{} than in pattern #1 - VariableBoundWithDifferentMode(Name, usize, Span), + /// error E0408: variable `{}` is not bound in all patterns + VariableNotBoundInPattern(BindingError), + /// error E0409: variable `{}` is bound in inconsistent ways within the same match arm + VariableBoundWithDifferentMode(Name, Span), /// error E0415: identifier is bound more than once in this parameter list IdentifierBoundMoreThanOnceInParameterList(&'a str), /// error E0416: identifier is bound more than once in the same pattern @@ -204,27 +210,26 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver, err.span_label(span, &format!("not a member of trait `{}`", trait_)); err } - ResolutionError::VariableNotBoundInPattern(variable_name, from, to) => { - let mut err = struct_span_err!(resolver.session, - span, - E0408, - "variable `{}` from pattern #{} is not bound in pattern #{}", - variable_name, - from, - to); - err.span_label(span, &format!("pattern doesn't bind `{}`", variable_name)); + ResolutionError::VariableNotBoundInPattern(binding_error) => { + let msp = MultiSpan::from_spans(binding_error.target.iter().map(|x| *x).collect()); + let msg = format!("variable `{}` is not bound in all patterns", binding_error.name); + let mut err = resolver.session.struct_span_err_with_code(msp, &msg, "E0408"); + for sp in binding_error.target { + err.span_label(sp, &format!("pattern doesn't bind `{}`", binding_error.name)); + } + for sp in binding_error.origin { + err.span_label(sp, &"variable not in all patterns"); + } err } ResolutionError::VariableBoundWithDifferentMode(variable_name, - pattern_number, first_binding_span) => { let mut err = struct_span_err!(resolver.session, span, E0409, - "variable `{}` is bound with different mode in pattern #{} than in \ - pattern #1", - variable_name, - pattern_number); + "variable `{}` is bound in inconsistent \ + ways within the same match arm", + variable_name); err.span_label(span, &format!("bound in different ways")); err.span_label(first_binding_span, &format!("first binding")); err @@ -324,7 +329,7 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver, } } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] struct BindingInfo { span: Span, binding_mode: BindingMode, @@ -1866,36 +1871,62 @@ impl<'a> Resolver<'a> { if arm.pats.is_empty() { return; } - let map_0 = self.binding_mode_map(&arm.pats[0]); + + let mut missing_vars = FxHashMap(); + let mut inconsistent_vars = FxHashMap(); for (i, p) in arm.pats.iter().enumerate() { let map_i = self.binding_mode_map(&p); - for (&key, &binding_0) in &map_0 { - match map_i.get(&key) { - None => { - let error = ResolutionError::VariableNotBoundInPattern(key.name, 1, i + 1); - resolve_error(self, p.span, error); + for (j, q) in arm.pats.iter().enumerate() { + if i == j { + continue; + } + + let map_j = self.binding_mode_map(&q); + for (&key, &binding_i) in &map_i { + if map_j.len() == 0 { // Account for missing bindings when + let binding_error = missing_vars // map_j has none. + .entry(key.name) + .or_insert(BindingError { + name: key.name, + origin: FxHashSet(), + target: FxHashSet(), + }); + binding_error.origin.insert(binding_i.span); + binding_error.target.insert(q.span); } - Some(binding_i) => { - if binding_0.binding_mode != binding_i.binding_mode { - resolve_error(self, - binding_i.span, - ResolutionError::VariableBoundWithDifferentMode( - key.name, - i + 1, - binding_0.span)); + for (&key_j, &binding_j) in &map_j { + match map_i.get(&key_j) { + None => { // missing binding + let binding_error = missing_vars + .entry(key_j.name) + .or_insert(BindingError { + name: key_j.name, + origin: FxHashSet(), + target: FxHashSet(), + }); + binding_error.origin.insert(binding_j.span); + binding_error.target.insert(p.span); + } + Some(binding_i) => { // check consistent binding + if binding_i.binding_mode != binding_j.binding_mode { + inconsistent_vars + .entry(key.name) + .or_insert((binding_j.span, binding_i.span)); + } + } } } } } - - for (&key, &binding) in &map_i { - if !map_0.contains_key(&key) { - resolve_error(self, - binding.span, - ResolutionError::VariableNotBoundInPattern(key.name, i + 1, 1)); - } - } + } + for (_, v) in missing_vars { + resolve_error(self, + *v.origin.iter().next().unwrap(), + ResolutionError::VariableNotBoundInPattern(v)); + } + for (name, v) in inconsistent_vars { + resolve_error(self, v.0, ResolutionError::VariableBoundWithDifferentMode(name, v.1)); } } diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 19139301bb0c4..7e17ae5f1d389 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -287,8 +287,9 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { mir::StatementKind::StorageLive(_) | mir::StatementKind::StorageDead(_) | mir::StatementKind::Nop => {} + mir::StatementKind::InlineAsm { .. } | mir::StatementKind::SetDiscriminant{ .. } => { - span_bug!(span, "SetDiscriminant should not appear in constants?"); + span_bug!(span, "{:?} should not appear in constants?", statement.kind); } } } diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 38ee67796c6de..7d4f542addbb1 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -16,7 +16,6 @@ use rustc::mir::tcx::LvalueTy; use rustc::mir; use middle::lang_items::ExchangeMallocFnLangItem; -use asm; use base; use builder::Builder; use callee::Callee; @@ -156,20 +155,6 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { bcx } - mir::Rvalue::InlineAsm { ref asm, ref outputs, ref inputs } => { - let outputs = outputs.iter().map(|output| { - let lvalue = self.trans_lvalue(&bcx, output); - (lvalue.llval, lvalue.ty.to_ty(bcx.tcx())) - }).collect(); - - let input_vals = inputs.iter().map(|input| { - self.trans_operand(&bcx, input).immediate() - }).collect(); - - asm::trans_inline_asm(&bcx, asm, outputs, input_vals); - bcx - } - _ => { assert!(rvalue_creates_operand(rvalue)); let (bcx, temp) = self.trans_rvalue_operand(bcx, rvalue); @@ -468,8 +453,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { (bcx, operand) } mir::Rvalue::Repeat(..) | - mir::Rvalue::Aggregate(..) | - mir::Rvalue::InlineAsm { .. } => { + mir::Rvalue::Aggregate(..) => { bug!("cannot generate operand from rvalue {:?}", rvalue); } @@ -669,8 +653,7 @@ pub fn rvalue_creates_operand(rvalue: &mir::Rvalue) -> bool { mir::Rvalue::Use(..) => true, mir::Rvalue::Repeat(..) | - mir::Rvalue::Aggregate(..) | - mir::Rvalue::InlineAsm { .. } => + mir::Rvalue::Aggregate(..) => false, } diff --git a/src/librustc_trans/mir/statement.rs b/src/librustc_trans/mir/statement.rs index 48fc9720e4b83..29a0648c8f8f8 100644 --- a/src/librustc_trans/mir/statement.rs +++ b/src/librustc_trans/mir/statement.rs @@ -11,6 +11,7 @@ use rustc::mir; use base; +use asm; use common; use builder::Builder; @@ -73,6 +74,19 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { mir::StatementKind::StorageDead(ref lvalue) => { self.trans_storage_liveness(bcx, lvalue, base::Lifetime::End) } + mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => { + let outputs = outputs.iter().map(|output| { + let lvalue = self.trans_lvalue(&bcx, output); + (lvalue.llval, lvalue.ty.to_ty(bcx.tcx())) + }).collect(); + + let input_vals = inputs.iter().map(|input| { + self.trans_operand(&bcx, input).immediate() + }).collect(); + + asm::trans_inline_asm(&bcx, asm, outputs, input_vals); + bcx + } mir::StatementKind::Nop => bcx, } } diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index ff9eaa012ba41..2d90394025d21 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -309,17 +309,17 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // parameters from the type and those from the method. // // FIXME -- permit users to manually specify lifetimes - let supplied_start = substs.params().len() + method_generics.regions.len(); + let supplied_start = substs.len() + method_generics.regions.len(); Substs::for_item(self.tcx, pick.item.def_id, |def, _| { let i = def.index as usize; - if i < substs.params().len() { + if i < substs.len() { substs.region_at(i) } else { self.region_var_for_def(self.span, def) } }, |def, cur_substs| { let i = def.index as usize; - if i < substs.params().len() { + if i < substs.len() { substs.type_at(i) } else if supplied_method_types.is_empty() { self.type_var_for_def(self.span, def, cur_substs) diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 201a223c15f15..fd29ff0be43b4 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1326,7 +1326,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { } else { let substs = Substs::for_item(self.tcx, method, |def, _| { let i = def.index as usize; - if i < substs.params().len() { + if i < substs.len() { substs.region_at(i) } else { // In general, during probe we erase regions. See @@ -1335,7 +1335,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { } }, |def, cur_substs| { let i = def.index as usize; - if i < substs.params().len() { + if i < substs.len() { substs.type_at(i) } else { self.type_var_for_def(self.span, def, cur_substs) diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 28156dd616b3a..a292227058379 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -100,7 +100,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { let gcx = fcx.tcx.global_tcx(); let free_substs = fcx.parameter_environment.free_substs; - for (i, k) in free_substs.params().iter().enumerate() { + for (i, k) in free_substs.iter().enumerate() { let r = if let Some(r) = k.as_region() { r } else { diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 1c37067d7f69d..c7000ee1e40e7 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -12,7 +12,7 @@ use std::env; use std::ffi::OsString; use std::io::prelude::*; use std::io; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::panic::{self, AssertUnwindSafe}; use std::process::Command; use std::rc::Rc; @@ -485,7 +485,15 @@ impl Collector { pub fn get_filename(&self) -> String { if let Some(ref codemap) = self.codemap { - codemap.span_to_filename(self.position) + let filename = codemap.span_to_filename(self.position); + if let Ok(cur_dir) = env::current_dir() { + if let Ok(path) = Path::new(&filename).strip_prefix(&cur_dir) { + if let Some(path) = path.to_str() { + return path.to_owned(); + } + } + } + filename } else if let Some(ref filename) = self.filename { filename.clone() } else { diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index 0cff8661d8871..60767ea478661 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -200,18 +200,20 @@ impl Cursor { #[stable(feature = "rust1", since = "1.0.0")] impl io::Seek for Cursor where T: AsRef<[u8]> { fn seek(&mut self, style: SeekFrom) -> io::Result { - let pos = match style { - SeekFrom::Start(n) => { self.pos = n; return Ok(n) } - SeekFrom::End(n) => self.inner.as_ref().len() as i64 + n, - SeekFrom::Current(n) => self.pos as i64 + n, + let (base_pos, offset) = match style { + SeekFrom::Start(n) => { self.pos = n; return Ok(n); } + SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n), + SeekFrom::Current(n) => (self.pos, n), }; - - if pos < 0 { - Err(Error::new(ErrorKind::InvalidInput, - "invalid seek to a negative position")) + let new_pos = if offset >= 0 { + base_pos.checked_add(offset as u64) } else { - self.pos = pos as u64; - Ok(self.pos) + base_pos.checked_sub((offset.wrapping_neg()) as u64) + }; + match new_pos { + Some(n) => {self.pos = n; Ok(self.pos)} + None => Err(Error::new(ErrorKind::InvalidInput, + "invalid seek to a negative or overflowing position")) } } } @@ -526,6 +528,43 @@ mod tests { assert_eq!(r.write(&[3]).unwrap(), 0); } + #[test] + fn seek_past_i64() { + let buf = [0xff]; + let mut r = Cursor::new(&buf[..]); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + + let mut r = Cursor::new(vec![10]); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + + let mut buf = [0]; + let mut r = Cursor::new(&mut buf[..]); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + + let mut r = Cursor::new(vec![10].into_boxed_slice()); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + } + #[test] fn seek_before_0() { let buf = [0xff]; diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index ba99375139139..1e7394c0b09e7 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -316,7 +316,7 @@ impl Once { } // Once we've enqueued ourselves, wait in a loop. - // Aftewards reload the state and continue with what we + // Afterwards reload the state and continue with what we // were doing from before. while !node.signaled.load(Ordering::SeqCst) { thread::park(); diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index 5166ddf8a21b6..66f09a7069c13 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -28,8 +28,8 @@ use mem; /// # Initialization and Destruction /// /// Initialization is dynamically performed on the first call to `with()` -/// within a thread, and values support destructors which will be run when a -/// thread exits. +/// within a thread, and values that implement `Drop` get destructed when a +/// thread exits. Some caveats apply, which are explained below. /// /// # Examples /// diff --git a/src/rustc/std_shim/Cargo.toml b/src/rustc/std_shim/Cargo.toml deleted file mode 100644 index db96079d3e916..0000000000000 --- a/src/rustc/std_shim/Cargo.toml +++ /dev/null @@ -1,46 +0,0 @@ -# This is a shim Cargo.toml which serves as a proxy for building the standard -# library. The reason for this is a little subtle, as one might reasonably -# expect that we just `cargo build` the standard library itself. -# -# One of the output artifacts for the standard library is a dynamic library, and -# on platforms like OSX the name of the output artifact is actually encoded into -# the library itself (similar to a soname on Linux). When the library is linked -# against, this encoded name is what's literally looked for at runtime when the -# dynamic loader is probing for libraries. -# -# Cargo, however, by default will not mangle the output filename of the -# top-level target. If we were to run `cargo build` on libstd itself, we would -# generate a file `libstd.so`. When installing, however, this file is called -# something like `libstd-abcdef0123.so`. On OSX at least this causes a failure -# at runtime because the encoded "soname" is `libstd.so`, not what the file is -# actually called. -# -# By using this shim library to build the standard library by proxy we sidestep -# this problem. The standard library is built with mangled hex already in its -# name so there's nothing extra we need to do. - -[package] -name = "std_shim" -version = "0.0.0" -authors = ["The Rust Project Developers"] - -[lib] -name = "std_shim" -path = "lib.rs" -doc = false - -[dependencies] -std = { path = "../../libstd" } -core = { path = "../../libcore" } - -# Reexport features from std -[features] -asan = ["std/asan"] -backtrace = ["std/backtrace"] -debug-jemalloc = ["std/debug-jemalloc"] -jemalloc = ["std/jemalloc"] -force_alloc_system = ["std/force_alloc_system"] -lsan = ["std/lsan"] -msan = ["std/msan"] -panic-unwind = ["std/panic-unwind"] -tsan = ["std/tsan"] diff --git a/src/rustc/std_shim/lib.rs b/src/rustc/std_shim/lib.rs deleted file mode 100644 index 2fc5d8d6e5321..0000000000000 --- a/src/rustc/std_shim/lib.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// See comments in Cargo.toml for why this exists - -// There's a bug right now where if we pass --extern std=... and we're cross -// compiling then this doesn't work with `#[macro_use] extern crate std;`. Work -// around this by not having `#[macro_use] extern crate std;` -#![no_std] -extern crate std; diff --git a/src/rustc/test_shim/Cargo.toml b/src/rustc/test_shim/Cargo.toml deleted file mode 100644 index 6ef613eee0628..0000000000000 --- a/src/rustc/test_shim/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -# This is a shim Cargo.toml which serves as a proxy for building libtest. -# -# The reason this shim exists is basically the same reason that `std_shim` -# exists, and more documentation can be found in that `Cargo.toml` as to why. - -[package] -name = "test_shim" -version = "0.0.0" -authors = ["The Rust Project Developers"] - -[lib] -name = "test_shim" -path = "lib.rs" - -[dependencies] -test = { path = "../../libtest" } diff --git a/src/test/compile-fail/E0408.rs b/src/test/compile-fail/E0408.rs index d75f612482772..ce77a537e263d 100644 --- a/src/test/compile-fail/E0408.rs +++ b/src/test/compile-fail/E0408.rs @@ -12,7 +12,8 @@ fn main() { let x = Some(0); match x { - Some(y) | None => {} //~ ERROR variable `y` from pattern #1 is not bound in pattern #2 + Some(y) | None => {} //~ ERROR variable `y` is not bound in all patterns _ => () //~| NOTE pattern doesn't bind `y` + //~| NOTE variable not in all patterns } } diff --git a/src/test/compile-fail/issue-2848.rs b/src/test/compile-fail/issue-2848.rs index f5e0c545bb524..38bd7adefd91f 100644 --- a/src/test/compile-fail/issue-2848.rs +++ b/src/test/compile-fail/issue-2848.rs @@ -19,7 +19,8 @@ mod bar { fn main() { use bar::foo::{alpha, charlie}; match alpha { - alpha | beta => {} //~ ERROR variable `beta` from pattern #2 is not bound in pattern #1 + alpha | beta => {} //~ ERROR variable `beta` is not bound in all patterns charlie => {} //~| NOTE pattern doesn't bind `beta` + //~| NOTE variable not in all patterns } } diff --git a/src/test/compile-fail/issue-2849.rs b/src/test/compile-fail/issue-2849.rs index 48f4cac9711a8..203b28bd5e417 100644 --- a/src/test/compile-fail/issue-2849.rs +++ b/src/test/compile-fail/issue-2849.rs @@ -13,6 +13,6 @@ enum foo { alpha, beta(isize) } fn main() { match foo::alpha { foo::alpha | foo::beta(i) => {} - //~^ ERROR variable `i` from pattern #2 is not bound in pattern #1 + //~^ ERROR variable `i` is not bound in all patterns } } diff --git a/src/test/compile-fail/resolve-inconsistent-binding-mode.rs b/src/test/compile-fail/resolve-inconsistent-binding-mode.rs index 284c08ef09b28..63d33a9e5fa6f 100644 --- a/src/test/compile-fail/resolve-inconsistent-binding-mode.rs +++ b/src/test/compile-fail/resolve-inconsistent-binding-mode.rs @@ -15,7 +15,7 @@ enum opts { fn matcher1(x: opts) { match x { opts::a(ref i) | opts::b(i) => {} - //~^ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1 + //~^ ERROR variable `i` is bound in inconsistent ways within the same match arm //~^^ ERROR mismatched types opts::c(_) => {} } @@ -24,7 +24,7 @@ fn matcher1(x: opts) { fn matcher2(x: opts) { match x { opts::a(ref i) | opts::b(i) => {} - //~^ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1 + //~^ ERROR variable `i` is bound in inconsistent ways within the same match arm //~^^ ERROR mismatched types opts::c(_) => {} } @@ -33,7 +33,7 @@ fn matcher2(x: opts) { fn matcher4(x: opts) { match x { opts::a(ref mut i) | opts::b(ref i) => {} - //~^ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1 + //~^ ERROR variable `i` is bound in inconsistent ways within the same match arm //~^^ ERROR mismatched types opts::c(_) => {} } diff --git a/src/test/compile-fail/resolve-inconsistent-names.rs b/src/test/compile-fail/resolve-inconsistent-names.rs index 1e2541502ace8..7fee5aedb06ed 100644 --- a/src/test/compile-fail/resolve-inconsistent-names.rs +++ b/src/test/compile-fail/resolve-inconsistent-names.rs @@ -11,9 +11,11 @@ fn main() { let y = 1; match y { - a | b => {} //~ ERROR variable `a` from pattern #1 is not bound in pattern #2 - //~^ ERROR variable `b` from pattern #2 is not bound in pattern #1 + a | b => {} //~ ERROR variable `a` is not bound in all patterns + //~^ ERROR variable `b` is not bound in all patterns //~| NOTE pattern doesn't bind `a` //~| NOTE pattern doesn't bind `b` + //~| NOTE variable not in all patterns + //~| NOTE variable not in all patterns } } diff --git a/src/test/run-make/sysroot-crates-are-unstable/Makefile b/src/test/run-make/sysroot-crates-are-unstable/Makefile new file mode 100644 index 0000000000000..f08b62ad3aafe --- /dev/null +++ b/src/test/run-make/sysroot-crates-are-unstable/Makefile @@ -0,0 +1,28 @@ +# This is a whitelist of crates which are stable, we don't check for the +# instability of these crates as they're all stable! +STABLE_CRATES := \ + std \ + core \ + proc_macro + +# Generate a list of all crates in the sysroot. To do this we list all files in +# rustc's sysroot, look at the filename, strip everything after the `-`, and +# strip the leading `lib` (if present) +SYSROOT := $(shell $(RUSTC) --print sysroot) +LIBS := $(wildcard $(SYSROOT)/lib/rustlib/$(TARGET)/lib/*) +LIBS := $(foreach lib,$(LIBS),$(notdir $(lib))) +LIBS := $(foreach lib,$(LIBS),$(word 1,$(subst -, ,$(lib)))) +LIBS := $(foreach lib,$(LIBS),$(patsubst lib%,%,$(lib))) +LIBS := $(filter-out $(STABLE_CRATES),$(LIBS)) + +all: $(foreach lib,$(LIBS),check-crate-$(lib)-is-unstable) + +check-crate-%-is-unstable: + @echo verifying $* is an unstable crate + @echo 'extern crate $*;' | \ + $(RUSTC) - --crate-type rlib 2>&1 | cat > $(TMPDIR)/$*; \ + true + @grep -q 'use of unstable library feature' $(TMPDIR)/$* || \ + (echo crate $* is not unstable && \ + cat $(TMPDIR)/$* && \ + false) diff --git a/src/test/ui/mismatched_types/E0409.stderr b/src/test/ui/mismatched_types/E0409.stderr index 251e247fa28ba..45a42b1c271f8 100644 --- a/src/test/ui/mismatched_types/E0409.stderr +++ b/src/test/ui/mismatched_types/E0409.stderr @@ -1,4 +1,4 @@ -error[E0409]: variable `y` is bound with different mode in pattern #2 than in pattern #1 +error[E0409]: variable `y` is bound in inconsistent ways within the same match arm --> $DIR/E0409.rs:15:23 | 15 | (0, ref y) | (y, 0) => {} //~ ERROR E0409 diff --git a/src/rustc/test_shim/lib.rs b/src/test/ui/span/issue-39698.rs similarity index 60% rename from src/rustc/test_shim/lib.rs rename to src/test/ui/span/issue-39698.rs index d614d967e3b07..17b3f1c5a885e 100644 --- a/src/rustc/test_shim/lib.rs +++ b/src/test/ui/span/issue-39698.rs @@ -1,4 +1,4 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,8 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// See comments in Cargo.toml for why this exists +enum T { + T1(i32, i32), + T2(i32, i32), + T3(i32), + T4(i32), +} -#![feature(test)] - -extern crate test; +fn main() { + match T::T1(123, 456) { + T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } + } +} diff --git a/src/test/ui/span/issue-39698.stderr b/src/test/ui/span/issue-39698.stderr new file mode 100644 index 0000000000000..3d8bfbf5ee8a4 --- /dev/null +++ b/src/test/ui/span/issue-39698.stderr @@ -0,0 +1,42 @@ +error[E0408]: variable `d` is not bound in all patterns + --> $DIR/issue-39698.rs:20:37 + | +20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } + | - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d` + | | | | + | | | pattern doesn't bind `d` + | | variable not in all patterns + | variable not in all patterns + +error[E0408]: variable `c` is not bound in all patterns + --> $DIR/issue-39698.rs:20:48 + | +20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } + | ^^^^^^^^^^^ ^^^^^^^^^^^ - ^^^^^^^^ pattern doesn't bind `c` + | | | | + | | | variable not in all patterns + | | pattern doesn't bind `c` + | pattern doesn't bind `c` + +error[E0408]: variable `a` is not bound in all patterns + --> $DIR/issue-39698.rs:20:37 + | +20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } + | - ^^^^^^^^^^^ ^^^^^^^^ - variable not in all patterns + | | | | + | | | pattern doesn't bind `a` + | | pattern doesn't bind `a` + | variable not in all patterns + +error[E0408]: variable `b` is not bound in all patterns + --> $DIR/issue-39698.rs:20:37 + | +20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } + | ^^^^^^^^^^^ - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `b` + | | | | + | | | pattern doesn't bind `b` + | | variable not in all patterns + | pattern doesn't bind `b` + +error: aborting due to 4 previous errors +