diff options
44 files changed, 988 insertions, 367 deletions
diff --git a/RELEASES.md b/RELEASES.md index a5e307ac0d0..5682960709f 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,211 @@ +Version 1.8.0 (2016-04-14) +========================== + +Language +-------- + +* Rust supports overloading of compound assignment statements like + `+=` by implementing the [`AddAssign`], [`SubAssign`], + [`MulAssign`], [`DivAssign`], [`RemAssign`], [`BitAndAssign`], + [`BitOrAssign`], [`BitXorAssign`], [`ShlAssign`], or [`ShrAssign`] + traits. [RFC 953]. +* Empty structs can be defined with braces, as in `struct Foo { }`, in + addition to the non-braced form, `struct Foo;`. [RFC 218]. + +Libraries +--------- + +* Stabilized APIs: + * [`str::encode_utf16`][] (renamed from `utf16_units`) + * [`str::EncodeUtf16`][] (renamed from `Utf16Units`) + * [`Ref::map`] + * [`RefMut::map`] + * [`ptr::drop_in_place`] + * [`time::Instant`] + * [`time::SystemTime`] + * [`Instant::now`] + * [`Instant::duration_since`][] (renamed from `duration_from_earlier`) + * [`Instant::elapsed`] + * [`SystemTime::now`] + * [`SystemTime::duration_since`][] (renamed from `duration_from_earlier`) + * [`SystemTime::elapsed`] + * Various `Add`/`Sub` impls for `Time` and `SystemTime` + * [`SystemTimeError`] + * [`SystemTimeError::duration`] + * Various impls for `SystemTimeError` + * [`UNIX_EPOCH`] + * [`AddAssign`], [`SubAssign`], [`MulAssign`], [`DivAssign`], + [`RemAssign`], [`BitAndAssign`], [`BitOrAssign`], + [`BitXorAssign`], [`ShlAssign`], [`ShrAssign`]. +* [The `write!` and `writeln!` macros correctly emit errors if any of + their arguments can't be formatted][1.8w]. +* [Various I/O functions support large files on 32-bit Linux][1.8l]. +* [The Unix-specific `raw` modules, which contain a number of + redefined C types are deprecated][1.8r], including `os::raw::unix`, + `os::raw::macos`, and `os::raw::linux`. These modules defined types + such as `ino_t` and `dev_t`. The inconsistency of these definitions + across platforms was making it difficult to implement `std` + correctly. Those that need these definitions should use the `libc` + crate. [RFC 1415]. +* The Unix-specific `MetadataExt` traits, including + `os::unix::fs::MetadataExt`, which expose values such as inode + numbers [no longer return platform-specific types][1.8r], but + instead return widened integers. [RFC 1415]. +* [`btree_set::{IntoIter, Iter, Range}` are covariant][1.8cv]. +* [Atomic loads and stores are not volatile][1.8a]. +* [All types in `sync::mpsc` implement `fmt::Debug`][1.8mp]. + +Performance +----------- + +* [Inlining hash functions lead to a 3% compile-time improvement in + some workloads][1.8h]. +* When using jemalloc, its symbols are [unprefixed so that it + overrides the libc malloc implementation][1.8h]. This means that for + rustc, LLVM is now using jemalloc, which results in a 6% + compile-time improvement on a specific workload. +* [Avoid quadratic growth in function size due to cleanups][1.8cu]. + +Misc +---- + +* [32-bit MSVC builds finally implement unwinding][1.8ms]. + i686-pc-windows-msvc is now considered a tier-1 platform. +* [The `--print targets` flag prints a list of supported targets][1.8t]. +* [The `--print cfg` flag prints the `cfg`s defined for the current + target][1.8cf]. +* [`rustc` can be built with an new Cargo-based build system, written + in Rust][1.8b]. It will eventually replace Rust's Makefile-based + build system. To enable it configure with `configure --rustbuild`. +* [Errors for non-exhaustive `match` patterns now list up to 3 missing + variants while also indicating the total number of missing variants + if more than 3][1.8m]. +* [Executable stacks are disabled on Linux and BSD][1.8nx]. +* The Rust Project now publishes binary releases of the standard + library for a number of tier-2 targets: + `armv7-unknown-linux-gnueabihf`, `powerpc-unknown-linux-gnu`, + `powerpc64-unknown-linux-gnu`, `powerpc64le-unknown-linux-gnu` + `x86_64-rumprun-netbsd`. These can be installed with + tools such as [multirust][1.8mr]. + +Cargo +----- + +* [`cargo init` creates a new Cargo project in the current + directory][1.8ci]. It is otherwise like `cargo new`. +* [Cargo has configuration keys for `-v` and + `--color`][1.8cc]. `verbose` and `color`, respectively, go in the + `[term]` section of `.cargo/config`. +* [Configuration keys that evaluate to strings or integers can be set + via environment variables][1.8ce]. For example the `build.jobs` key + can be set via `CARGO_BUILD_JOBS`. Environment variables take + precedence over config files. +* [Target-specific dependencies support Rust `cfg` syntax for + describing targets][1.8cfg] so that dependencies for multiple + targets can be specified together. [RFC 1361]. +* [The environment variables `CARGO_TARGET_ROOT`, `RUSTC`, and + `RUSTDOC` take precedence over the `build.target-dir`, + `build.rustc`, and `build.rustdoc` configuration values][1.8cv]. +* [The child process tree is killed on Windows when Cargo is + killed][1.8ck]. +* [The `build.target` configuration value sets the target platform, + like `--target`][1.8ct]. + +Compatibility Notes +------------------- + +* [Unstable compiler flags have been further restricted][1.8u]. Since + 1.0 `-Z` flags have been considered unstable, and other flags that + were considered unstable additionally required passing `-Z + unstable-options` to access. Unlike unstable language and library + features though, these options have been accessible on the stable + release channel. Going forward, *new unstable flags will not be + available on the stable release channel*, and old unstable flags + will warn about their usage. In the future, all unstable flags will + be unavailable on the stable release channel. +* [It is no longer possible to `match` on empty enum variants using + the `Variant(..)` syntax][1.8v]. This has been a warning since 1.6. +* The Unix-specific `MetadataExt` traits, including + `os::unix::fs::MetadataExt`, which expose values such as inode + numbers [no longer return platform-specific types][1.8r], but + instead return widened integers. [RFC 1415]. +* [Modules sourced from the filesystem cannot appear within arbitrary + blocks, but only within other modules][1.8m]. +* [`--cfg` compiler flags are parsed strictly as identifiers][1.8c]. +* On Unix, [stack overflow triggers a runtime abort instead of a + SIGSEGV][1.8so]. +* [`Command::spawn` and its equivalents return an error if any of + its command-line arguments contain interior `NUL`s][1.8n]. +* [Tuple and unit enum variants from other crates are in the type + namespace][1.8tn]. +* [On Windows `rustc` emits `.lib` files for the `staticlib` library + type instead of `.a` files][1.8st]. Additionally, for the MSVC + toolchain, `rustc` emits import libraries named `foo.dll.lib` + instead of `foo.lib`. + + +[1.8a]: https://github.com/rust-lang/rust/pull/30962 +[1.8b]: https://github.com/rust-lang/rust/pull/31123 +[1.8c]: https://github.com/rust-lang/rust/pull/31530 +[1.8cc]: https://github.com/rust-lang/cargo/pull/2397 +[1.8ce]: https://github.com/rust-lang/cargo/pull/2398 +[1.8cf]: https://github.com/rust-lang/rust/pull/31278 +[1.8cfg]: https://github.com/rust-lang/cargo/pull/2328 +[1.8ci]: https://github.com/rust-lang/cargo/pull/2081 +[1.8ck]: https://github.com/rust-lang/cargo/pull/2370 +[1.8ct]: https://github.com/rust-lang/cargo/pull/2335 +[1.8cu]: https://github.com/rust-lang/rust/pull/31390 +[1.8cv]: https://github.com/rust-lang/cargo/issues/2365 +[1.8cv]: https://github.com/rust-lang/rust/pull/30998 +[1.8h]: https://github.com/rust-lang/rust/pull/31460 +[1.8l]: https://github.com/rust-lang/rust/pull/31668 +[1.8m]: https://github.com/rust-lang/rust/pull/31020 +[1.8m]: https://github.com/rust-lang/rust/pull/31534 +[1.8mp]: https://github.com/rust-lang/rust/pull/30894 +[1.8mr]: https://users.rust-lang.org/t/multirust-0-8-with-cross-std-installation/4901 +[1.8ms]: https://github.com/rust-lang/rust/pull/30448 +[1.8n]: https://github.com/rust-lang/rust/pull/31056 +[1.8nx]: https://github.com/rust-lang/rust/pull/30859 +[1.8r]: https://github.com/rust-lang/rust/pull/31551 +[1.8so]: https://github.com/rust-lang/rust/pull/31333 +[1.8st]: https://github.com/rust-lang/rust/pull/29520 +[1.8t]: https://github.com/rust-lang/rust/pull/31358 +[1.8tn]: https://github.com/rust-lang/rust/pull/30882 +[1.8u]: https://github.com/rust-lang/rust/pull/31793 +[1.8v]: https://github.com/rust-lang/rust/pull/31757 +[1.8w]: https://github.com/rust-lang/rust/pull/31904 +[RFC 1361]: https://github.com/rust-lang/rfcs/blob/master/text/1361-cargo-cfg-dependencies.md +[RFC 1415]: https://github.com/rust-lang/rfcs/blob/master/text/1415-trim-std-os.md +[RFC 218]: https://github.com/rust-lang/rfcs/blob/master/text/0218-empty-struct-with-braces.md +[RFC 953]: https://github.com/rust-lang/rfcs/blob/master/text/0953-op-assign.md +[`AddAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.AddAssign.html +[`BitAndAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.BitAndAssign.html +[`BitOrAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.BitOrAssign.html +[`BitXorAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.BitXorAssign.html +[`DivAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.DivAssign.html +[`Instant::duration_since`]: http://doc.rust-lang.org/nightly/std/time/struct.Instant.html#method.duration_since +[`Instant::elapsed`]: http://doc.rust-lang.org/nightly/std/time/struct.Instant.html#method.elapsed +[`Instant::now`]: http://doc.rust-lang.org/nightly/std/time/struct.Instant.html#method.now +[`MulAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.MulAssign.html +[`Ref::map`]: http://doc.rust-lang.org/nightly/std/cell/struct.Ref.html#method.map +[`RefMut::map`]: http://doc.rust-lang.org/nightly/std/cell/struct.RefMut.html#method.map +[`RemAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.RemAssign.html +[`ShlAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.ShlAssign.html +[`ShrAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.ShrAssign.html +[`SubAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.SubAssign.html +[`SystemTime::duration_since`]: http://doc.rust-lang.org/nightly/std/time/struct.SystemTime.html#method.duration_since +[`SystemTime::elapsed`]: http://doc.rust-lang.org/nightly/std/time/struct.SystemTime.html#method.elapsed +[`SystemTime::now`]: http://doc.rust-lang.org/nightly/std/time/struct.SystemTime.html#method.now +[`SystemTimeError::duration`]: http://doc.rust-lang.org/nightly/std/time/struct.SystemTimeError.html#method.duration +[`SystemTimeError`]: http://doc.rust-lang.org/nightly/std/time/struct.SystemTimeError.html +[`UNIX_EPOCH`]: http://doc.rust-lang.org/nightly/std/time/constant.UNIX_EPOCH.html +[`ptr::drop_in_place`]: http://doc.rust-lang.org/nightly/std/ptr/fn.drop_in_place.html +[`str::EncodeUtf16`]: http://doc.rust-lang.org/nightly/std/str/struct.EncodeUtf16.html +[`str::encode_utf16`]: http://doc.rust-lang.org/nightly/std/primitive.str.html#method.encode_utf16 +[`time::Instant`]: http://doc.rust-lang.org/nightly/std/time/struct.Instant.html +[`time::SystemTime`]: http://doc.rust-lang.org/nightly/std/time/struct.SystemTime.html + + Version 1.7.0 (2016-03-03) ========================== diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 05186d48ce2..c33838a146c 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -3,16 +3,16 @@ name = "bootstrap" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "cmake 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -21,10 +21,10 @@ version = "0.1.0" [[package]] name = "cmake" -version = "0.1.13" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -32,12 +32,12 @@ name = "filetime" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "gcc" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -50,13 +50,13 @@ name = "kernel32-sys" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libc" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -64,25 +64,25 @@ name = "num_cpus" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-serialize" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "toml" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "winapi" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] diff --git a/src/bootstrap/build/check.rs b/src/bootstrap/build/check.rs index 4e2ee475285..a2445ae498a 100644 --- a/src/bootstrap/build/check.rs +++ b/src/bootstrap/build/check.rs @@ -18,9 +18,18 @@ pub fn linkcheck(build: &Build, stage: u32, host: &str) { } pub fn cargotest(build: &Build, stage: u32, host: &str) { + let ref compiler = Compiler::new(stage, host); + + // Configure PATH to find the right rustc. NB. we have to use PATH + // and not RUSTC because the Cargo test suite has tests that will + // fail if rustc is not spelled `rustc`. + let path = build.sysroot(compiler).join("bin"); + let old_path = ::std::env::var("PATH").expect(""); + let sep = if cfg!(windows) { ";" } else {":" }; + let ref newpath = format!("{}{}{}", path.display(), sep, old_path); + build.run(build.tool_cmd(compiler, "cargotest") - .env("RUSTC", build.compiler_path(compiler)) - .env("RUSTDOC", build.rustdoc(compiler)) + .env("PATH", newpath) .arg(&build.cargo)); } diff --git a/src/bootstrap/build/compile.rs b/src/bootstrap/build/compile.rs index dee586c7699..a67f1ba48b5 100644 --- a/src/bootstrap/build/compile.rs +++ b/src/bootstrap/build/compile.rs @@ -15,7 +15,7 @@ use std::process::Command; use build_helper::output; -use build::util::{exe, staticlib, libdir, mtime, is_dylib}; +use build::util::{exe, staticlib, libdir, mtime, is_dylib, copy}; use build::{Build, Compiler, Mode}; /// Build the standard library. @@ -32,8 +32,8 @@ pub fn std<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) { let libdir = build.sysroot_libdir(compiler, target); let _ = fs::remove_dir_all(&libdir); t!(fs::create_dir_all(&libdir)); - t!(fs::hard_link(&build.compiler_rt_built.borrow()[target], - libdir.join(staticlib("compiler-rt", target)))); + copy(&build.compiler_rt_built.borrow()[target], + &libdir.join(staticlib("compiler-rt", target))); build_startup_objects(build, target, &libdir); @@ -77,8 +77,8 @@ pub fn std_link(build: &Build, if host != compiler.host { let _ = fs::remove_dir_all(&libdir); t!(fs::create_dir_all(&libdir)); - t!(fs::hard_link(&build.compiler_rt_built.borrow()[target], - libdir.join(staticlib("compiler-rt", target)))); + copy(&build.compiler_rt_built.borrow()[target], + &libdir.join(staticlib("compiler-rt", target))); } add_to_sysroot(&out_dir, &libdir); @@ -93,7 +93,7 @@ pub fn std_link(build: &Build, /// Only required for musl targets that statically link to libc fn copy_third_party_objects(build: &Build, target: &str, into: &Path) { for &obj in &["crt1.o", "crti.o", "crtn.o"] { - t!(fs::copy(compiler_file(build.cc(target), obj), into.join(obj))); + copy(&compiler_file(build.cc(target), obj), &into.join(obj)); } } @@ -119,7 +119,7 @@ fn build_startup_objects(build: &Build, target: &str, into: &Path) { } for obj in ["crt2.o", "dllcrt2.o"].iter() { - t!(fs::copy(compiler_file(build.cc(target), obj), into.join(obj))); + copy(&compiler_file(build.cc(target), obj), &into.join(obj)); } } @@ -240,9 +240,10 @@ fn libtest_shim(build: &Build, compiler: &Compiler, target: &str) -> PathBuf { build.cargo_out(compiler, Mode::Libtest, target).join("libtest_shim.rlib") } -fn compiler_file(compiler: &Path, file: &str) -> String { - output(Command::new(compiler) - .arg(format!("-print-file-name={}", file))).trim().to_string() +fn compiler_file(compiler: &Path, file: &str) -> PathBuf { + let out = output(Command::new(compiler) + .arg(format!("-print-file-name={}", file))); + PathBuf::from(out.trim()) } /// Prepare a new compiler from the artifacts in `stage` @@ -270,7 +271,7 @@ pub fn assemble_rustc(build: &Build, stage: u32, host: &str) { for f in t!(fs::read_dir(&src_libdir)).map(|f| t!(f)) { let filename = f.file_name().into_string().unwrap(); if is_dylib(&filename) { - t!(fs::hard_link(&f.path(), sysroot_libdir.join(&filename))); + copy(&f.path(), &sysroot_libdir.join(&filename)); } } @@ -282,7 +283,7 @@ pub fn assemble_rustc(build: &Build, stage: u32, host: &str) { t!(fs::create_dir_all(&bindir)); let compiler = build.compiler_path(&Compiler::new(stage, host)); let _ = fs::remove_file(&compiler); - t!(fs::hard_link(rustc, compiler)); + copy(&rustc, &compiler); // See if rustdoc exists to link it into place let rustdoc = exe("rustdoc", host); @@ -290,7 +291,7 @@ pub fn assemble_rustc(build: &Build, stage: u32, host: &str) { let rustdoc_dst = bindir.join(&rustdoc); if fs::metadata(&rustdoc_src).is_ok() { let _ = fs::remove_file(&rustdoc_dst); - t!(fs::hard_link(&rustdoc_src, &rustdoc_dst)); + copy(&rustdoc_src, &rustdoc_dst); } } @@ -329,8 +330,7 @@ fn add_to_sysroot(out_dir: &Path, sysroot_dst: &Path) { let (_, path) = paths.iter().map(|path| { (mtime(&path).seconds(), path) }).max().unwrap(); - t!(fs::hard_link(&path, - sysroot_dst.join(path.file_name().unwrap()))); + copy(&path, &sysroot_dst.join(path.file_name().unwrap())); } } diff --git a/src/bootstrap/build/dist.rs b/src/bootstrap/build/dist.rs index 855528ea440..6ae652bd66d 100644 --- a/src/bootstrap/build/dist.rs +++ b/src/bootstrap/build/dist.rs @@ -52,7 +52,7 @@ pub fn docs(build: &Build, stage: u32, host: &str) { .arg(format!("--image-dir={}", sanitize_sh(&image))) .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) - .arg(format!("--package-name={}", name)) + .arg(format!("--package-name={}-{}", name, host)) .arg("--component-name=rust-docs") .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--bulk-dirs=share/doc/rust/html"); @@ -61,9 +61,11 @@ pub fn docs(build: &Build, stage: u32, host: &str) { // As part of this step, *also* copy the docs directory to a directory which // buildbot typically uploads. - let dst = distdir(build).join("doc").join(&build.package_vers); - t!(fs::create_dir_all(&dst)); - cp_r(&src, &dst); + if host == build.config.build { + let dst = distdir(build).join("doc").join(&build.package_vers); + t!(fs::create_dir_all(&dst)); + cp_r(&src, &dst); + } } pub fn mingw(build: &Build, host: &str) { diff --git a/src/bootstrap/build/doc.rs b/src/bootstrap/build/doc.rs index 50c0c56807b..5782dd5ec28 100644 --- a/src/bootstrap/build/doc.rs +++ b/src/bootstrap/build/doc.rs @@ -16,18 +16,18 @@ use std::process::Command; use build::{Build, Compiler, Mode}; use build::util::{up_to_date, cp_r}; -pub fn rustbook(build: &Build, stage: u32, host: &str, name: &str, out: &Path) { +pub fn rustbook(build: &Build, stage: u32, target: &str, name: &str, out: &Path) { t!(fs::create_dir_all(out)); let out = out.join(name); - let compiler = Compiler::new(stage, host); + let compiler = Compiler::new(stage, &build.config.build); let src = build.src.join("src/doc").join(name); let index = out.join("index.html"); let rustbook = build.tool(&compiler, "rustbook"); if up_to_date(&src, &index) && up_to_date(&rustbook, &index) { return } - println!("Rustbook stage{} ({}) - {}", stage, host, name); + println!("Rustbook stage{} ({}) - {}", stage, target, name); let _ = fs::remove_dir_all(&out); build.run(build.tool_cmd(&compiler, "rustbook") .arg("build") @@ -35,11 +35,11 @@ pub fn rustbook(build: &Build, stage: u32, host: &str, name: &str, out: &Path) { .arg(out)); } -pub fn standalone(build: &Build, stage: u32, host: &str, out: &Path) { - println!("Documenting stage{} standalone ({})", stage, host); +pub fn standalone(build: &Build, stage: u32, target: &str, out: &Path) { + println!("Documenting stage{} standalone ({})", stage, target); t!(fs::create_dir_all(out)); - let compiler = Compiler::new(stage, host); + let compiler = Compiler::new(stage, &build.config.build); let favicon = build.src.join("src/doc/favicon.inc"); let footer = build.src.join("src/doc/footer.inc"); @@ -105,16 +105,17 @@ pub fn standalone(build: &Build, stage: u32, host: &str, out: &Path) { } } -pub fn std(build: &Build, stage: u32, host: &str, out: &Path) { - println!("Documenting stage{} std ({})", stage, host); - let compiler = Compiler::new(stage, host); +pub fn std(build: &Build, stage: u32, target: &str, out: &Path) { + println!("Documenting stage{} std ({})", stage, target); + t!(fs::create_dir_all(out)); + let compiler = Compiler::new(stage, &build.config.build); let out_dir = build.stage_out(&compiler, Mode::Libstd) - .join(host).join("doc"); + .join(target).join("doc"); let rustdoc = build.rustdoc(&compiler); build.clear_if_dirty(&out_dir, &rustdoc); - let mut cargo = build.cargo(&compiler, Mode::Libstd, host, "doc"); + 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("--features").arg(build.std_features()); @@ -122,32 +123,32 @@ pub fn std(build: &Build, stage: u32, host: &str, out: &Path) { cp_r(&out_dir, out) } -pub fn test(build: &Build, stage: u32, host: &str, out: &Path) { - println!("Documenting stage{} test ({})", stage, host); - let compiler = Compiler::new(stage, host); +pub fn test(build: &Build, stage: u32, target: &str, out: &Path) { + println!("Documenting stage{} test ({})", stage, target); + let compiler = Compiler::new(stage, &build.config.build); let out_dir = build.stage_out(&compiler, Mode::Libtest) - .join(host).join("doc"); + .join(target).join("doc"); let rustdoc = build.rustdoc(&compiler); build.clear_if_dirty(&out_dir, &rustdoc); - let mut cargo = build.cargo(&compiler, Mode::Libtest, host, "doc"); + let mut cargo = build.cargo(&compiler, Mode::Libtest, target, "doc"); cargo.arg("--manifest-path") .arg(build.src.join("src/rustc/test_shim/Cargo.toml")); build.run(&mut cargo); cp_r(&out_dir, out) } -pub fn rustc(build: &Build, stage: u32, host: &str, out: &Path) { - println!("Documenting stage{} compiler ({})", stage, host); - let compiler = Compiler::new(stage, host); +pub fn rustc(build: &Build, stage: u32, target: &str, out: &Path) { + println!("Documenting stage{} compiler ({})", stage, target); + let compiler = Compiler::new(stage, &build.config.build); let out_dir = build.stage_out(&compiler, Mode::Librustc) - .join(host).join("doc"); + .join(target).join("doc"); let rustdoc = build.rustdoc(&compiler); if !up_to_date(&rustdoc, &out_dir.join("rustc/index.html")) { t!(fs::remove_dir_all(&out_dir)); } - let mut cargo = build.cargo(&compiler, Mode::Librustc, host, "doc"); + let mut cargo = build.cargo(&compiler, Mode::Librustc, target, "doc"); cargo.arg("--manifest-path") .arg(build.src.join("src/rustc/Cargo.toml")) .arg("--features").arg(build.rustc_features()); @@ -155,9 +156,10 @@ pub fn rustc(build: &Build, stage: u32, host: &str, out: &Path) { cp_r(&out_dir, out) } -pub fn error_index(build: &Build, stage: u32, host: &str, out: &Path) { - println!("Documenting stage{} error index ({})", stage, host); - let compiler = Compiler::new(stage, host); +pub fn error_index(build: &Build, stage: u32, target: &str, out: &Path) { + println!("Documenting stage{} error index ({})", stage, target); + t!(fs::create_dir_all(out)); + let compiler = Compiler::new(stage, &build.config.build); let mut index = build.tool_cmd(&compiler, "error_index_generator"); index.arg("html"); index.arg(out.join("error-index.html")); diff --git a/src/bootstrap/build/sanity.rs b/src/bootstrap/build/sanity.rs index be4416c697c..6ce27496388 100644 --- a/src/bootstrap/build/sanity.rs +++ b/src/bootstrap/build/sanity.rs @@ -119,4 +119,16 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake } } } + + for host in build.flags.host.iter() { + if !build.config.host.contains(host) { + panic!("specified host `{}` is not in the ./configure list", host); + } + } + for target in build.flags.target.iter() { + if !build.config.target.contains(target) { + panic!("specified target `{}` is not in the ./configure list", + target); + } + } } diff --git a/src/bootstrap/build/step.rs b/src/bootstrap/build/step.rs index 4e3aacd3720..80fcc32e537 100644 --- a/src/bootstrap/build/step.rs +++ b/src/bootstrap/build/step.rs @@ -274,22 +274,28 @@ impl<'a> Step<'a> { vec![self.llvm(()).target(&build.config.build)] } Source::Llvm { _dummy } => Vec::new(), + + // Note that all doc targets depend on artifacts from the build + // architecture, not the target (which is where we're generating + // docs into). Source::DocStd { stage } => { - vec![self.libstd(self.compiler(stage))] + let compiler = self.target(&build.config.build).compiler(stage); + vec![self.libstd(compiler)] } Source::DocTest { stage } => { - vec![self.libtest(self.compiler(stage))] + let compiler = self.target(&build.config.build).compiler(stage); + vec![self.libtest(compiler)] } Source::DocBook { stage } | Source::DocNomicon { stage } | Source::DocStyle { stage } => { - vec![self.tool_rustbook(stage)] + vec![self.target(&build.config.build).tool_rustbook(stage)] } Source::DocErrorIndex { stage } => { - vec![self.tool_error_index(stage)] + vec![self.target(&build.config.build).tool_error_index(stage)] } Source::DocStandalone { stage } => { - vec![self.rustc(stage)] + vec![self.target(&build.config.build).rustc(stage)] } Source::DocRustc { stage } => { vec![self.doc_test(stage)] @@ -319,7 +325,7 @@ impl<'a> Step<'a> { vec![self.librustc(self.compiler(stage))] } Source::ToolCargoTest { stage } => { - vec![self.libstd(self.compiler(stage))] + vec![self.librustc(self.compiler(stage))] } Source::DistDocs { stage } => vec![self.doc(stage)], @@ -333,7 +339,6 @@ impl<'a> Step<'a> { Source::Dist { stage } => { let mut base = Vec::new(); - base.push(self.dist_docs(stage)); for host in build.config.host.iter() { let host = self.target(host); @@ -344,7 +349,9 @@ impl<'a> Step<'a> { let compiler = self.compiler(stage); for target in build.config.target.iter() { - base.push(self.target(target).dist_std(compiler)); + let target = self.target(target); + base.push(target.dist_docs(stage)); + base.push(target.dist_std(compiler)); } } return base diff --git a/src/bootstrap/build/util.rs b/src/bootstrap/build/util.rs index 35d22ee5d26..41cf924d44a 100644 --- a/src/bootstrap/build/util.rs +++ b/src/bootstrap/build/util.rs @@ -30,6 +30,15 @@ pub fn mtime(path: &Path) -> FileTime { }).unwrap_or(FileTime::zero()) } +pub fn copy(src: &Path, dst: &Path) { + let res = fs::hard_link(src, dst); + let res = res.or_else(|_| fs::copy(src, dst).map(|_| ())); + if let Err(e) = res { + panic!("failed to copy `{}` to `{}`: {}", src.display(), + dst.display(), e) + } +} + pub fn cp_r(src: &Path, dst: &Path) { for f in t!(fs::read_dir(src)) { let f = t!(f); @@ -42,7 +51,7 @@ pub fn cp_r(src: &Path, dst: &Path) { cp_r(&path, &dst); } else { let _ = fs::remove_file(&dst); - t!(fs::hard_link(&path, dst)); + copy(&path, &dst); } } } diff --git a/src/doc/book/concurrency.md b/src/doc/book/concurrency.md index ba4496b93f3..c179629a79a 100644 --- a/src/doc/book/concurrency.md +++ b/src/doc/book/concurrency.md @@ -162,7 +162,7 @@ The same [ownership system](ownership.html) that helps prevent using pointers incorrectly also helps rule out data races, one of the worst kinds of concurrency bugs. -As an example, here is a Rust program that could have a data race in many +As an example, here is a Rust program that would have a data race in many languages. It will not compile: ```ignore @@ -174,7 +174,7 @@ fn main() { for i in 0..3 { thread::spawn(move || { - data[i] += 1; + data[0] += i; }); } @@ -186,7 +186,7 @@ This gives us an error: ```text 8:17 error: capture of moved value: `data` - data[i] += 1; + data[0] += i; ^~~~ ``` @@ -195,11 +195,6 @@ thread, and the thread takes ownership of the reference, we'd have three owners! `data` gets moved out of `main` in the first call to `spawn()`, so subsequent calls in the loop cannot use this variable. -Note that this specific example will not cause a data race since different array -indices are being accessed. But this can't be determined at compile time, and in -a similar situation where `i` is a constant or is random, you would have a data -race. - So, we need some type that lets us have more than one owning reference to a value. Usually, we'd use `Rc<T>` for this, which is a reference counted type that provides shared ownership. It has some runtime bookkeeping that keeps track @@ -223,7 +218,7 @@ fn main() { // use it in a thread thread::spawn(move || { - data_ref[i] += 1; + data_ref[0] += i; }); } @@ -266,7 +261,7 @@ fn main() { for i in 0..3 { let data = data.clone(); thread::spawn(move || { - data[i] += 1; + data[0] += i; }); } @@ -281,7 +276,7 @@ And... still gives us an error. ```text <anon>:11:24 error: cannot borrow immutable borrowed content as mutable -<anon>:11 data[i] += 1; +<anon>:11 data[0] += i; ^~~~ ``` @@ -317,7 +312,7 @@ fn main() { let data = data.clone(); thread::spawn(move || { let mut data = data.lock().unwrap(); - data[i] += 1; + data[0] += i; }); } @@ -360,7 +355,7 @@ Let's examine the body of the thread more closely: # let data = data.clone(); thread::spawn(move || { let mut data = data.lock().unwrap(); - data[i] += 1; + data[0] += i; }); # } # thread::sleep(Duration::from_millis(50)); diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 229a864d712..9af8ef53851 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -149,7 +149,7 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// assert_eq!(u32::from_str_radix("A", 16), Ok(10)); + /// assert_eq!(i32::from_str_radix("A", 16), Ok(10)); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> { @@ -163,9 +163,9 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// let n = 0b01001100u8; + /// let n = -0b1000_0000i8; /// - /// assert_eq!(n.count_ones(), 3); + /// assert_eq!(n.count_ones(), 1); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -178,9 +178,9 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// let n = 0b01001100u8; + /// let n = -0b1000_0000i8; /// - /// assert_eq!(n.count_zeros(), 5); + /// assert_eq!(n.count_zeros(), 7); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -196,9 +196,9 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// let n = 0b0101000u16; + /// let n = -1i16; /// - /// assert_eq!(n.leading_zeros(), 10); + /// assert_eq!(n.leading_zeros(), 0); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -214,9 +214,9 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// let n = 0b0101000u16; + /// let n = -4i8; /// - /// assert_eq!(n.trailing_zeros(), 3); + /// assert_eq!(n.trailing_zeros(), 2); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -232,10 +232,10 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// let n = 0x0123456789ABCDEFu64; - /// let m = 0x3456789ABCDEF012u64; + /// let n = 0x0123456789ABCDEFi64; + /// let m = -0x76543210FEDCBA99i64; /// - /// assert_eq!(n.rotate_left(12), m); + /// assert_eq!(n.rotate_left(32), m); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -252,10 +252,10 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// let n = 0x0123456789ABCDEFu64; - /// let m = 0xDEF0123456789ABCu64; + /// let n = 0x0123456789ABCDEFi64; + /// let m = -0xFEDCBA987654322i64; /// - /// assert_eq!(n.rotate_right(12), m); + /// assert_eq!(n.rotate_right(4), m); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -270,8 +270,8 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// let n = 0x0123456789ABCDEFu64; - /// let m = 0xEFCDAB8967452301u64; + /// let n = 0x0123456789ABCDEFi64; + /// let m = -0x1032547698BADCFFi64; /// /// assert_eq!(n.swap_bytes(), m); /// ``` @@ -291,12 +291,12 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// let n = 0x0123456789ABCDEFu64; + /// let n = 0x0123456789ABCDEFi64; /// /// if cfg!(target_endian = "big") { - /// assert_eq!(u64::from_be(n), n) + /// assert_eq!(i64::from_be(n), n) /// } else { - /// assert_eq!(u64::from_be(n), n.swap_bytes()) + /// assert_eq!(i64::from_be(n), n.swap_bytes()) /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -315,12 +315,12 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// let n = 0x0123456789ABCDEFu64; + /// let n = 0x0123456789ABCDEFi64; /// /// if cfg!(target_endian = "little") { - /// assert_eq!(u64::from_le(n), n) + /// assert_eq!(i64::from_le(n), n) /// } else { - /// assert_eq!(u64::from_le(n), n.swap_bytes()) + /// assert_eq!(i64::from_le(n), n.swap_bytes()) /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -339,7 +339,7 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// let n = 0x0123456789ABCDEFu64; + /// let n = 0x0123456789ABCDEFi64; /// /// if cfg!(target_endian = "big") { /// assert_eq!(n.to_be(), n) @@ -363,7 +363,7 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// let n = 0x0123456789ABCDEFu64; + /// let n = 0x0123456789ABCDEFi64; /// /// if cfg!(target_endian = "little") { /// assert_eq!(n.to_le(), n) @@ -385,8 +385,8 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// assert_eq!(5u16.checked_add(65530), Some(65535)); - /// assert_eq!(6u16.checked_add(65530), None); + /// assert_eq!(7i16.checked_add(32760), Some(32767)); + /// assert_eq!(8i16.checked_add(32760), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -421,8 +421,8 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// assert_eq!(5u8.checked_mul(51), Some(255)); - /// assert_eq!(5u8.checked_mul(52), None); + /// assert_eq!(6i8.checked_mul(21), Some(126)); + /// assert_eq!(6i8.checked_mul(22), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -753,8 +753,8 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// assert_eq!(1u8.wrapping_shl(7), 128); - /// assert_eq!(1u8.wrapping_shl(8), 1); + /// assert_eq!((-1i8).wrapping_shl(7), -128); + /// assert_eq!((-1i8).wrapping_shl(8), -1); /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] @@ -778,8 +778,8 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// assert_eq!(128u8.wrapping_shr(7), 1); - /// assert_eq!(128u8.wrapping_shr(8), 128); + /// assert_eq!((-128i8).wrapping_shr(7), -1); + /// assert_eq!((-128i8).wrapping_shr(8), -128); /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] @@ -1193,15 +1193,13 @@ macro_rules! uint_impl { /// /// Leading and trailing whitespace represent an error. /// - /// # Arguments - /// - /// * src - A string slice - /// * radix - The base to use. Must lie in the range [2 .. 36] + /// # Examples /// - /// # Return value + /// Basic usage: /// - /// `Err(ParseIntError)` if the string did not represent a valid number. - /// Otherwise, `Ok(n)` where `n` is the integer represented by `src`. + /// ``` + /// assert_eq!(u32::from_str_radix("A", 16), Ok(10)); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> { from_str_radix(src, radix) @@ -1745,7 +1743,7 @@ macro_rules! uint_impl { /// Basic usage: /// /// ``` - /// assert_eq!(100i8.wrapping_rem(10), 0); + /// assert_eq!(100u8.wrapping_rem(10), 0); /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] @@ -1783,6 +1781,13 @@ macro_rules! uint_impl { /// where `mask` removes any high-order bits of `rhs` that /// would cause the shift to exceed the bitwidth of the type. /// + /// Note that this is *not* the same as a rotate-left; the + /// RHS of a wrapping shift-left is restricted to the range + /// of the type, rather than the bits shifted out of the LHS + /// being returned to the other end. The primitive integer + /// types all implement a `rotate_left` function, which may + /// be what you want instead. + /// /// # Examples /// /// Basic usage: @@ -1801,6 +1806,13 @@ macro_rules! uint_impl { /// where `mask` removes any high-order bits of `rhs` that /// would cause the shift to exceed the bitwidth of the type. /// + /// Note that this is *not* the same as a rotate-right; the + /// RHS of a wrapping shift-right is restricted to the range + /// of the type, rather than the bits shifted out of the LHS + /// being returned to the other end. The primitive integer + /// types all implement a `rotate_right` function, which may + /// be what you want instead. + /// /// # Examples /// /// Basic usage: diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 7f8cf531d26..4d9f042fdde 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -19,7 +19,7 @@ //! # #[allow(dead_code)] //! enum Result<T, E> { //! Ok(T), -//! Err(E) +//! Err(E), //! } //! ``` //! @@ -39,7 +39,7 @@ //! None => Err("invalid header length"), //! Some(&1) => Ok(Version::Version1), //! Some(&2) => Ok(Version::Version2), -//! Some(_) => Err("invalid version") +//! Some(_) => Err("invalid version"), //! } //! } //! @@ -254,7 +254,7 @@ pub enum Result<T, E> { /// Contains the error value #[stable(feature = "rust1", since = "1.0.0")] - Err(#[stable(feature = "rust1", since = "1.0.0")] E) + Err(#[stable(feature = "rust1", since = "1.0.0")] E), } ///////////////////////////////////////////////////////////////////////////// @@ -270,6 +270,8 @@ impl<T, E> Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// let x: Result<i32, &str> = Ok(-3); /// assert_eq!(x.is_ok(), true); @@ -290,6 +292,8 @@ impl<T, E> Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// let x: Result<i32, &str> = Ok(-3); /// assert_eq!(x.is_err(), false); @@ -314,6 +318,8 @@ impl<T, E> Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// let x: Result<u32, &str> = Ok(2); /// assert_eq!(x.ok(), Some(2)); @@ -337,6 +343,8 @@ impl<T, E> Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// let x: Result<u32, &str> = Ok(2); /// assert_eq!(x.err(), None); @@ -362,6 +370,10 @@ impl<T, E> Result<T, E> { /// Produces a new `Result`, containing a reference /// into the original, leaving the original in place. /// + /// # Examples + /// + /// Basic usage: + /// /// ``` /// let x: Result<u32, &str> = Ok(2); /// assert_eq!(x.as_ref(), Ok(&2)); @@ -380,6 +392,10 @@ impl<T, E> Result<T, E> { /// Converts from `Result<T, E>` to `Result<&mut T, &mut E>` /// + /// # Examples + /// + /// Basic usage: + /// /// ``` /// fn mutate(r: &mut Result<i32, i32>) { /// match r.as_mut() { @@ -445,6 +461,8 @@ impl<T, E> Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// fn stringify(x: u32) -> String { format!("error code: {}", x) } /// @@ -471,6 +489,8 @@ impl<T, E> Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// let x: Result<u32, &str> = Ok(7); /// assert_eq!(x.iter().next(), Some(&7)); @@ -488,6 +508,8 @@ impl<T, E> Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// let mut x: Result<u32, &str> = Ok(7); /// match x.iter_mut().next() { @@ -513,6 +535,8 @@ impl<T, E> Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// let x: Result<u32, &str> = Ok(2); /// let y: Result<&str, &str> = Err("late error"); @@ -545,6 +569,8 @@ impl<T, E> Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) } /// fn err(x: u32) -> Result<u32, u32> { Err(x) } @@ -567,6 +593,8 @@ impl<T, E> Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// let x: Result<u32, &str> = Ok(2); /// let y: Result<u32, &str> = Err("late error"); @@ -599,6 +627,8 @@ impl<T, E> Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) } /// fn err(x: u32) -> Result<u32, u32> { Err(x) } @@ -622,6 +652,8 @@ impl<T, E> Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// let optb = 2; /// let x: Result<u32, &str> = Ok(9); @@ -644,6 +676,8 @@ impl<T, E> Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// fn count(x: &str) -> usize { x.len() } /// @@ -670,6 +704,8 @@ impl<T, E: fmt::Debug> Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// let x: Result<u32, &str> = Ok(2); /// assert_eq!(x.unwrap(), 2); @@ -696,6 +732,9 @@ impl<T, E: fmt::Debug> Result<T, E> { /// passed message, and the content of the `Err`. /// /// # Examples + /// + /// Basic usage: + /// /// ```{.should_panic} /// let x: Result<u32, &str> = Err("emergency failure"); /// x.expect("Testing expect"); // panics with `Testing expect: emergency failure` @@ -759,6 +798,8 @@ impl<T, E> IntoIterator for Result<T, E> { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// let x: Result<u32, &str> = Ok(5); /// let v: Vec<u32> = x.into_iter().collect(); diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index ca1abb4fe0b..2e91238bff3 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -877,6 +877,20 @@ macro_rules! make_mut_slice { } /// Immutable slice iterator +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// // First, we declare a type which has `iter` method to get the `Iter` struct (&[usize here]): +/// let slice = &[1, 2, 3]; +/// +/// // Then, we iterate over it: +/// for element in slice.iter() { +/// println!("{}", element); +/// } +/// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, T: 'a> { ptr: *const T, @@ -903,6 +917,26 @@ impl<'a, T> Iter<'a, T> { /// /// This has the same lifetime as the original slice, and so the /// iterator can continue to be used while this exists. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// // First, we declare a type which has the `iter` method to get the `Iter` + /// // struct (&[usize here]): + /// let slice = &[1, 2, 3]; + /// + /// // Then, we get the iterator: + /// let mut iter = slice.iter(); + /// // So if we print what `as_slice` method returns here, we have "[1, 2, 3]": + /// println!("{:?}", iter.as_slice()); + /// + /// // Next, we move to the second element of the slice: + /// iter.next(); + /// // Now `as_slice` returns "[2, 3]": + /// println!("{:?}", iter.as_slice()); + /// ``` #[stable(feature = "iter_to_slice", since = "1.4.0")] pub fn as_slice(&self) -> &'a [T] { make_slice!(self.ptr, self.end) @@ -934,6 +968,24 @@ impl<'a, T> Clone for Iter<'a, T> { } /// Mutable slice iterator. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// // First, we declare a type which has `iter_mut` method to get the `IterMut` +/// // struct (&[usize here]): +/// let mut slice = &mut [1, 2, 3]; +/// +/// // Then, we iterate over it and increment each element value: +/// for element in slice.iter_mut() { +/// *element += 1; +/// } +/// +/// // We now have "[2, 3, 4]": +/// println!("{:?}", slice); +/// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct IterMut<'a, T: 'a> { ptr: *mut T, @@ -962,6 +1014,35 @@ impl<'a, T> IterMut<'a, T> { /// to consume the iterator. Consider using the `Slice` and /// `SliceMut` implementations for obtaining slices with more /// restricted lifetimes that do not consume the iterator. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// // First, we declare a type which has `iter_mut` method to get the `IterMut` + /// // struct (&[usize here]): + /// let mut slice = &mut [1, 2, 3]; + /// + /// { + /// // Then, we get the iterator: + /// let mut iter = slice.iter_mut(); + /// // We move to next element: + /// iter.next(); + /// // So if we print what `into_slice` method returns here, we have "[2, 3]": + /// println!("{:?}", iter.into_slice()); + /// } + /// + /// // Now let's modify a value of the slice: + /// { + /// // First we get back the iterator: + /// let mut iter = slice.iter_mut(); + /// // We change the value of the first element of the slice returned by the `next` method: + /// *iter.next().unwrap() += 1; + /// } + /// // Now slice is "[2, 2, 3]": + /// println!("{:?}", slice); + /// ``` #[stable(feature = "iter_to_slice", since = "1.4.0")] pub fn into_slice(self) -> &'a mut [T] { make_mut_slice!(self.ptr, self.end) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index ef8670df912..f3c31d59fc4 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1942,7 +1942,8 @@ impl StrExt for str { if index == 0 || index == self.len() { return true; } match self.as_bytes().get(index) { None => false, - Some(&b) => b < 128 || b >= 192, + // This is bit magic equivalent to: b < 128 || b >= 192 + Some(&b) => (b as i8) >= -0x40, } } diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index f8c0b63bf11..de349917258 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -44,8 +44,9 @@ impl fmt::Debug for CodeExtent { ty::tls::with_opt(|opt_tcx| { if let Some(tcx) = opt_tcx { - let data = tcx.region_maps.code_extents.borrow()[self.0 as usize]; - write!(f, "/{:?}", data)?; + if let Some(data) = tcx.region_maps.code_extents.borrow().get(self.0 as usize) { + write!(f, "/{:?}", data)?; + } } Ok(()) })?; diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index ae803f50231..450d25b6067 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -407,7 +407,7 @@ macro_rules! make_mir_visitor { self.visit_operand(arg); } if let Some((ref $($mutability)* destination, target)) = *destination { - self.visit_lvalue(destination, LvalueContext::Store); + self.visit_lvalue(destination, LvalueContext::Call); self.visit_branch(block, target); } cleanup.map(|t| self.visit_branch(block, t)); @@ -692,9 +692,12 @@ make_mir_visitor!(MutVisitor,mut); #[derive(Copy, Clone, Debug)] pub enum LvalueContext { - // Appears as LHS of an assignment or as dest of a call + // Appears as LHS of an assignment Store, + // Dest of a call + Call, + // Being dropped Drop, diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index a8eac524971..bde88605e88 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -436,6 +436,7 @@ impl Target { key!(target_family, optional); key!(is_like_osx, bool); key!(is_like_windows, bool); + key!(is_like_msvc, bool); key!(linker_is_gnu, bool); key!(has_rpath, bool); key!(no_compiler_rt, bool); diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 738a99fbe92..f0e834d4303 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -539,6 +539,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { (&Failed(_), &Failed(_)) => { let resolutions = target_module.resolutions.borrow(); let names = resolutions.iter().filter_map(|(&(ref name, _), resolution)| { + if *name == source { return None; } // Never suggest the same name match *resolution.borrow() { NameResolution { binding: Some(_), .. } => Some(name), NameResolution { single_imports: SingleImports::None, .. } => None, @@ -549,9 +550,12 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { Some(name) => format!(". Did you mean to use `{}`?", name), None => "".to_owned(), }; - let msg = format!("There is no `{}` in `{}`{}", - source, - module_to_string(target_module), lev_suggestion); + let module_str = module_to_string(target_module); + let msg = if &module_str == "???" { + format!("There is no `{}` in the crate root{}", source, lev_suggestion) + } else { + format!("There is no `{}` in `{}`{}", source, module_str, lev_suggestion) + }; return Failed(Some((directive.span, msg))); } _ => (), diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 5014186d13b..8471b6a274c 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -326,7 +326,7 @@ impl<'tcx> TypeMap<'tcx> { output: &mut String) { // First, find out the 'real' def_id of the type. Items inlined from // other crates have to be mapped back to their source. - let source_def_id = if let Some(node_id) = cx.tcx().map.as_local_node_id(def_id) { + let def_id = if let Some(node_id) = cx.tcx().map.as_local_node_id(def_id) { match cx.external_srcs().borrow().get(&node_id).cloned() { Some(source_def_id) => { // The given def_id identifies the inlined copy of a @@ -339,19 +339,21 @@ impl<'tcx> TypeMap<'tcx> { def_id }; - // Get the crate hash as first part of the identifier. - let crate_hash = if source_def_id.is_local() { - cx.link_meta().crate_hash.clone() + // Get the crate name/disambiguator as first part of the identifier. + let crate_name = if def_id.is_local() { + cx.tcx().crate_name.clone() } else { - cx.sess().cstore.crate_hash(source_def_id.krate) + cx.sess().cstore.original_crate_name(def_id.krate) }; + let crate_disambiguator = cx.tcx().crate_disambiguator(def_id.krate); - output.push_str(crate_hash.as_str()); + output.push_str(&crate_name[..]); output.push_str("/"); + output.push_str(&crate_disambiguator[..]); + output.push_str("/"); + // Add the def-index as the second part output.push_str(&format!("{:x}", def_id.index.as_usize())); - // Maybe check that there is no self type here. - let tps = substs.types.get_slice(subst::TypeSpace); if !tps.is_empty() { output.push('<'); diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index 9aa3d6c7dd0..f721e88a954 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -105,6 +105,9 @@ impl<'tcx> Visitor<'tcx> for TempAnalyzer { match *lvalue { mir::Lvalue::Temp(index) => { match context { + LvalueContext::Call => { + self.mark_assigned(index as usize); + } LvalueContext::Consume => { } LvalueContext::Store | diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 3fabdd8fd42..303cf61ad33 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -11,12 +11,12 @@ use llvm::{self, BasicBlockRef, ValueRef, OperandBundleDef}; use rustc::ty; use rustc::mir::repr as mir; -use abi::{Abi, FnType}; +use abi::{Abi, FnType, ArgType}; use adt; use base; use build; use callee::{Callee, CalleeData, Fn, Intrinsic, NamedTupleConstructor, Virtual}; -use common::{self, Block, BlockAndBuilder, C_undef}; +use common::{self, type_is_fat_ptr, Block, BlockAndBuilder, C_undef}; use debuginfo::DebugLoc; use Disr; use machine::{llalign_of_min, llbitsize_of_real}; @@ -25,7 +25,7 @@ use type_of; use glue; use type_::Type; -use super::{MirContext, drop}; +use super::{MirContext, TempRef, drop}; use super::lvalue::{LvalueRef, load_fat_ptr}; use super::operand::OperandRef; use super::operand::OperandValue::{self, FatPtr, Immediate, Ref}; @@ -169,6 +169,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { _ => bug!("{} is not callable", callee.ty) }; + let sig = bcx.tcx().erase_late_bound_regions(sig); + // Handle intrinsics old trans wants Expr's for, ourselves. let intrinsic = match (&callee.ty.sty, &callee.data) { (&ty::TyFnDef(def_id, _, _), &Intrinsic) => { @@ -191,31 +193,16 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { if intrinsic == Some("transmute") { let &(ref dest, target) = destination.as_ref().unwrap(); - let dst = self.trans_lvalue(&bcx, dest); - let mut val = self.trans_operand(&bcx, &args[0]); - if let ty::TyFnDef(def_id, substs, _) = val.ty.sty { - let llouttype = type_of::type_of(bcx.ccx(), dst.ty.to_ty(bcx.tcx())); - let out_type_size = llbitsize_of_real(bcx.ccx(), llouttype); - if out_type_size != 0 { - // FIXME #19925 Remove this hack after a release cycle. - let f = Callee::def(bcx.ccx(), def_id, substs); - let datum = f.reify(bcx.ccx()); - val = OperandRef { - val: OperandValue::Immediate(datum.val), - ty: datum.ty - }; - } - } + self.with_lvalue_ref(&bcx, dest, |this, dest| { + this.trans_transmute(&bcx, &args[0], dest); + }); - let llty = type_of::type_of(bcx.ccx(), val.ty); - let cast_ptr = bcx.pointercast(dst.llval, llty.ptr_to()); - self.store_operand(&bcx, cast_ptr, val); self.set_operand_dropped(&bcx, &args[0]); funclet_br(bcx, self.llblock(target)); return; } - let extra_args = &args[sig.0.inputs.len()..]; + let extra_args = &args[sig.inputs.len()..]; let extra_args = extra_args.iter().map(|op_arg| { self.mir.operand_ty(bcx.tcx(), op_arg) }).collect::<Vec<_>>(); @@ -226,18 +213,15 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { let mut llargs = Vec::with_capacity(arg_count); // Prepare the return value destination - let ret_dest = if let Some((ref d, _)) = *destination { - let dest = self.trans_lvalue(&bcx, d); - if fn_ty.ret.is_indirect() { - llargs.push(dest.llval); - None - } else if fn_ty.ret.is_ignore() { - None + let ret_dest = if let Some((ref dest, _)) = *destination { + let is_intrinsic = if let Intrinsic = callee.data { + true } else { - Some(dest) - } + false + }; + self.make_return_dest(&bcx, dest, &fn_ty.ret, &mut llargs, is_intrinsic) } else { - None + ReturnDest::Nothing }; // Split the rust-call tupled arguments off. @@ -269,29 +253,42 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { use expr::{Ignore, SaveIn}; use intrinsic::trans_intrinsic_call; - let (dest, llargs) = if fn_ty.ret.is_indirect() { - (SaveIn(llargs[0]), &llargs[1..]) - } else if let Some(dest) = ret_dest { - (SaveIn(dest.llval), &llargs[..]) - } else { - (Ignore, &llargs[..]) + let (dest, llargs) = match ret_dest { + _ if fn_ty.ret.is_indirect() => { + (SaveIn(llargs[0]), &llargs[1..]) + } + ReturnDest::Nothing => (Ignore, &llargs[..]), + ReturnDest::IndirectOperand(dst, _) | + ReturnDest::Store(dst) => (SaveIn(dst), &llargs[..]), + ReturnDest::DirectOperand(_) => + bug!("Cannot use direct operand with an intrinsic call") }; bcx.with_block(|bcx| { - let res = trans_intrinsic_call(bcx, callee.ty, &fn_ty, + trans_intrinsic_call(bcx, callee.ty, &fn_ty, ArgVals(llargs), dest, DebugLoc::None); - let bcx = res.bcx.build(); - if let Some((_, target)) = *destination { - for op in args { - self.set_operand_dropped(&bcx, op); - } - funclet_br(bcx, self.llblock(target)); - } else { - // trans_intrinsic_call already used Unreachable. - // bcx.unreachable(); - } }); + + if let ReturnDest::IndirectOperand(dst, _) = ret_dest { + // Make a fake operand for store_return + let op = OperandRef { + val: OperandValue::Ref(dst), + ty: sig.output.unwrap() + }; + self.store_return(&bcx, ret_dest, fn_ty.ret, op); + } + + if let Some((_, target)) = *destination { + for op in args { + self.set_operand_dropped(&bcx, op); + } + funclet_br(bcx, self.llblock(target)); + } else { + // trans_intrinsic_call already used Unreachable. + // bcx.unreachable(); + } + return; } Fn(f) => f, @@ -321,9 +318,11 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { if destination.is_some() { let ret_bcx = ret_bcx.build(); ret_bcx.at_start(|ret_bcx| { - if let Some(ret_dest) = ret_dest { - fn_ty.ret.store(&ret_bcx, invokeret, ret_dest.llval); - } + let op = OperandRef { + val: OperandValue::Immediate(invokeret), + ty: sig.output.unwrap() + }; + self.store_return(&ret_bcx, ret_dest, fn_ty.ret, op); for op in args { self.set_operand_dropped(&ret_bcx, op); } @@ -333,9 +332,11 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { let llret = bcx.call(fn_ptr, &llargs, cleanup_bundle.as_ref()); fn_ty.apply_attrs_callsite(llret); if let Some((_, target)) = *destination { - if let Some(ret_dest) = ret_dest { - fn_ty.ret.store(&bcx, llret, ret_dest.llval); - } + let op = OperandRef { + val: OperandValue::Immediate(llret), + ty: sig.output.unwrap() + }; + self.store_return(&bcx, ret_dest, fn_ty.ret, op); for op in args { self.set_operand_dropped(&bcx, op); } @@ -544,4 +545,122 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { pub fn llblock(&self, bb: mir::BasicBlock) -> BasicBlockRef { self.blocks[bb.index()].llbb } + + fn make_return_dest(&mut self, bcx: &BlockAndBuilder<'bcx, 'tcx>, + dest: &mir::Lvalue<'tcx>, fn_ret_ty: &ArgType, + llargs: &mut Vec<ValueRef>, is_intrinsic: bool) -> ReturnDest { + // If the return is ignored, we can just return a do-nothing ReturnDest + if fn_ret_ty.is_ignore() { + return ReturnDest::Nothing; + } + let dest = match *dest { + mir::Lvalue::Temp(idx) => { + let lvalue_ty = self.mir.lvalue_ty(bcx.tcx(), dest); + let lvalue_ty = bcx.monomorphize(&lvalue_ty); + let ret_ty = lvalue_ty.to_ty(bcx.tcx()); + match self.temps[idx as usize] { + TempRef::Lvalue(dest) => dest, + TempRef::Operand(None) => { + // Handle temporary lvalues, specifically Operand ones, as + // they don't have allocas + return if fn_ret_ty.is_indirect() { + // Odd, but possible, case, we have an operand temporary, + // but the calling convention has an indirect return. + let tmp = bcx.with_block(|bcx| { + base::alloc_ty(bcx, ret_ty, "tmp_ret") + }); + llargs.push(tmp); + ReturnDest::IndirectOperand(tmp, idx) + } else if is_intrinsic { + // Currently, intrinsics always need a location to store + // the result. so we create a temporary alloca for the + // result + let tmp = bcx.with_block(|bcx| { + base::alloc_ty(bcx, ret_ty, "tmp_ret") + }); + ReturnDest::IndirectOperand(tmp, idx) + } else { + ReturnDest::DirectOperand(idx) + }; + } + TempRef::Operand(Some(_)) => { + bug!("lvalue temp already assigned to"); + } + } + } + _ => self.trans_lvalue(bcx, dest) + }; + if fn_ret_ty.is_indirect() { + llargs.push(dest.llval); + ReturnDest::Nothing + } else { + ReturnDest::Store(dest.llval) + } + } + + fn trans_transmute(&mut self, bcx: &BlockAndBuilder<'bcx, 'tcx>, + src: &mir::Operand<'tcx>, dst: LvalueRef<'tcx>) { + let mut val = self.trans_operand(bcx, src); + if let ty::TyFnDef(def_id, substs, _) = val.ty.sty { + let llouttype = type_of::type_of(bcx.ccx(), dst.ty.to_ty(bcx.tcx())); + let out_type_size = llbitsize_of_real(bcx.ccx(), llouttype); + if out_type_size != 0 { + // FIXME #19925 Remove this hack after a release cycle. + let f = Callee::def(bcx.ccx(), def_id, substs); + let datum = f.reify(bcx.ccx()); + val = OperandRef { + val: OperandValue::Immediate(datum.val), + ty: datum.ty + }; + } + } + + let llty = type_of::type_of(bcx.ccx(), val.ty); + let cast_ptr = bcx.pointercast(dst.llval, llty.ptr_to()); + self.store_operand(bcx, cast_ptr, val); + } + + // Stores the return value of a function call into it's final location. + fn store_return(&mut self, + bcx: &BlockAndBuilder<'bcx, 'tcx>, + dest: ReturnDest, + ret_ty: ArgType, + op: OperandRef<'tcx>) { + use self::ReturnDest::*; + + match dest { + Nothing => (), + Store(dst) => ret_ty.store(bcx, op.immediate(), dst), + IndirectOperand(tmp, idx) => { + let op = self.trans_load(bcx, tmp, op.ty); + self.temps[idx as usize] = TempRef::Operand(Some(op)); + } + DirectOperand(idx) => { + let op = if type_is_fat_ptr(bcx.tcx(), op.ty) { + let llval = op.immediate(); + let ptr = bcx.extract_value(llval, 0); + let meta = bcx.extract_value(llval, 1); + + OperandRef { + val: OperandValue::FatPtr(ptr, meta), + ty: op.ty + } + } else { + op + }; + self.temps[idx as usize] = TempRef::Operand(Some(op)); + } + } + } +} + +enum ReturnDest { + // Do nothing, the return value is indirect or ignored + Nothing, + // Store the return value to the pointer + Store(ValueRef), + // Stores an indirect return value to an operand temporary lvalue + IndirectOperand(ValueRef, u32), + // Stores a direct return value to an operand temporary lvalue + DirectOperand(u32) } diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs index c9087181f9d..695806aa82c 100644 --- a/src/librustc_trans/mir/lvalue.rs +++ b/src/librustc_trans/mir/lvalue.rs @@ -207,6 +207,40 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { } } + // Perform an action using the given Lvalue. + // If the Lvalue is an empty TempRef::Operand, then a temporary stack slot + // is created first, then used as an operand to update the Lvalue. + pub fn with_lvalue_ref<F, U>(&mut self, bcx: &BlockAndBuilder<'bcx, 'tcx>, + lvalue: &mir::Lvalue<'tcx>, f: F) -> U + where F: FnOnce(&mut Self, LvalueRef<'tcx>) -> U + { + match *lvalue { + mir::Lvalue::Temp(idx) => { + match self.temps[idx as usize] { + TempRef::Lvalue(lvalue) => f(self, lvalue), + TempRef::Operand(None) => { + let lvalue_ty = self.mir.lvalue_ty(bcx.tcx(), lvalue); + let lvalue_ty = bcx.monomorphize(&lvalue_ty); + let lvalue = LvalueRef::alloca(bcx, + lvalue_ty.to_ty(bcx.tcx()), + "lvalue_temp"); + let ret = f(self, lvalue); + let op = self.trans_load(bcx, lvalue.llval, lvalue_ty.to_ty(bcx.tcx())); + self.temps[idx as usize] = TempRef::Operand(Some(op)); + ret + } + TempRef::Operand(Some(_)) => { + bug!("Lvalue temp already set"); + } + } + } + _ => { + let lvalue = self.trans_lvalue(bcx, lvalue); + f(self, lvalue) + } + } + } + /// Adjust the bitwidth of an index since LLVM is less forgiving /// than we are. /// diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index 500eda2624c..1f0a18ad4fa 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -182,7 +182,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> debug!("type_of {:?}", t); - assert!(!t.has_escaping_regions()); + assert!(!t.has_escaping_regions(), "{:?} has escaping regions", t); // Replace any typedef'd types with their equivalent non-typedef // type. This ensures that all LLVM nominal types that contain diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 45877d7099b..67b91f7838c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2578,24 +2578,33 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, ty::TyFloat(ast::FloatTy::F32) => { fcx.type_error_message(arg.span, |t| { - format!("can't pass an {} to variadic \ - function, cast to c_double", t) + format!("can't pass an `{}` to variadic \ + function, cast to `c_double`", t) }, arg_ty, None); } ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => { fcx.type_error_message(arg.span, |t| { - format!("can't pass {} to variadic \ - function, cast to c_int", + format!("can't pass `{}` to variadic \ + function, cast to `c_int`", t) }, arg_ty, None); } ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => { fcx.type_error_message(arg.span, |t| { - format!("can't pass {} to variadic \ - function, cast to c_uint", + format!("can't pass `{}` to variadic \ + function, cast to `c_uint`", t) }, arg_ty, None); } + ty::TyFnDef(_, _, f) => { + let ptr_ty = fcx.tcx().mk_ty(ty::TyFnPtr(f)); + let ptr_ty = fcx.infcx().resolve_type_vars_if_possible(&ptr_ty); + fcx.type_error_message(arg.span, + |t| { + format!("can't pass `{}` to variadic \ + function, cast to `{}`", t, ptr_ty) + }, arg_ty, None); + } _ => {} } } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index bef6c1ed43a..8f76bf92ef4 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -3644,6 +3644,68 @@ fn main() { ``` "##, +E0520: r##" +A non-default implementation was already made on this type so it cannot be +specialized further. Erroneous code example: + +```compile_fail +#![feature(specialization)] + +trait SpaceLlama { + fn fly(&self); +} + +// applies to all T +impl<T> SpaceLlama for T { + default fn fly(&self) {} +} + +// non-default impl +// applies to all `Clone` T and overrides the previous impl +impl<T: Clone> SpaceLlama for T { + fn fly(&self) {} +} + +// since `i32` is clone, this conflicts with the previous implementation +impl SpaceLlama for i32 { + default fn fly(&self) {} + // error: item `fly` is provided by an `impl` that specializes + // another, but the item in the parent `impl` is not marked + // `default` and so it cannot be specialized. +} +``` + +Specialization only allows you to override `default` functions in +implementations. + +To fix this error, you need to mark all the parent implementations as default. +Example: + +``` +#![feature(specialization)] + +trait SpaceLlama { + fn fly(&self); +} + +// applies to all T +impl<T> SpaceLlama for T { + default fn fly(&self) {} // This is a parent implementation. +} + +// applies to all `Clone` T; overrides the previous impl +impl<T: Clone> SpaceLlama for T { + default fn fly(&self) {} // This is a parent implementation but was + // previously not a default one, causing the error +} + +// applies to i32, overrides the previous two impls +impl SpaceLlama for i32 { + fn fly(&self) {} // And now that's ok! +} +``` +"##, + } register_diagnostics! { @@ -3720,6 +3782,5 @@ register_diagnostics! { // type `{}` was overridden E0436, // functional record update requires a struct E0513, // no type for local variable .. - E0520, // cannot specialize non-default item E0521 // redundant default implementations of trait } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 673aa17ecd1..d8d1472560d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -54,10 +54,6 @@ use doctree; use visit_ast; use html::item_type::ItemType; -/// A stable identifier to the particular version of JSON output. -/// Increment this when the `Crate` and related structures change. -pub const SCHEMA_VERSION: &'static str = "0.8.3"; - mod inline; mod simplify; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index ba0dae6efb9..bc7c7c5e0ca 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -52,22 +52,16 @@ use std::cell::RefCell; use std::collections::HashMap; use std::default::Default; use std::env; -use std::fs::File; -use std::io::{self, Read, Write}; +use std::io::Read; use std::path::PathBuf; use std::process; use std::rc::Rc; use std::sync::mpsc::channel; use externalfiles::ExternalHtml; -use serialize::Decodable; -use serialize::json::{self, Json}; use rustc::session::search_paths::SearchPaths; use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options}; -// reexported from `clean` so it can be easily updated with the mod itself -pub use clean::SCHEMA_VERSION; - #[macro_use] pub mod externalfiles; @@ -125,7 +119,6 @@ thread_local!(pub static ANALYSISKEY: Rc<RefCell<Option<core::CrateAnalysis>>> = struct Output { krate: clean::Crate, - json_plugins: Vec<plugins::PluginJson>, passes: Vec<String>, } @@ -148,9 +141,9 @@ pub fn opts() -> Vec<RustcOptGroup> { stable(optflag("V", "version", "print rustdoc's version")), stable(optflag("v", "verbose", "use verbose output")), stable(optopt("r", "input-format", "the input type of the specified file", - "[rust|json]")), + "[rust]")), stable(optopt("w", "output-format", "the output type to write", - "[html|json]")), + "[html]")), stable(optopt("o", "output", "where to place the output", "PATH")), stable(optopt("", "crate-name", "specify the name of this crate", "NAME")), stable(optmulti("L", "library-path", "directory to add to crate search path", @@ -309,7 +302,7 @@ pub fn main_args(args: &[String]) -> isize { return 1; } }; - let Output { krate, json_plugins, passes, } = out; + let Output { krate, passes, } = out; info!("going to format"); match matches.opt_str("w").as_ref().map(|s| &**s) { Some("html") | None => { @@ -319,11 +312,6 @@ pub fn main_args(args: &[String]) -> isize { css_file_extension) .expect("failed to generate documentation") } - Some("json") => { - json_output(krate, json_plugins, - output.unwrap_or(PathBuf::from("doc.json"))) - .expect("failed to write json") - } Some(s) => { println!("unknown output format: {}", s); return 1; @@ -340,14 +328,9 @@ fn acquire_input(input: &str, matches: &getopts::Matches) -> Result<Output, String> { match matches.opt_str("r").as_ref().map(|s| &**s) { Some("rust") => Ok(rust_input(input, externs, matches)), - Some("json") => json_input(input), Some(s) => Err(format!("unknown input format: {}", s)), None => { - if input.ends_with(".json") { - json_input(input) - } else { - Ok(rust_input(input, externs, matches)) - } + Ok(rust_input(input, externs, matches)) } } } @@ -459,76 +442,6 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche // Run everything! info!("Executing passes/plugins"); - let (krate, json) = pm.run_plugins(krate); - Output { krate: krate, json_plugins: json, passes: passes } -} - -/// This input format purely deserializes the json output file. No passes are -/// run over the deserialized output. -fn json_input(input: &str) -> Result<Output, String> { - let mut bytes = Vec::new(); - if let Err(e) = File::open(input).and_then(|mut f| f.read_to_end(&mut bytes)) { - return Err(format!("couldn't open {}: {}", input, e)) - } - match json::from_reader(&mut &bytes[..]) { - Err(s) => Err(format!("{:?}", s)), - Ok(Json::Object(obj)) => { - let mut obj = obj; - // Make sure the schema is what we expect - match obj.remove(&"schema".to_string()) { - Some(Json::String(version)) => { - if version != SCHEMA_VERSION { - return Err(format!( - "sorry, but I only understand version {}", - SCHEMA_VERSION)) - } - } - Some(..) => return Err("malformed json".to_string()), - None => return Err("expected a schema version".to_string()), - } - let krate = match obj.remove(&"crate".to_string()) { - Some(json) => { - let mut d = json::Decoder::new(json); - Decodable::decode(&mut d).unwrap() - } - None => return Err("malformed json".to_string()), - }; - // FIXME: this should read from the "plugins" field, but currently - // Json doesn't implement decodable... - let plugin_output = Vec::new(); - Ok(Output { krate: krate, json_plugins: plugin_output, passes: Vec::new(), }) - } - Ok(..) => { - Err("malformed json input: expected an object at the \ - top".to_string()) - } - } -} - -/// Outputs the crate/plugin json as a giant json blob at the specified -/// destination. -fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> , - dst: PathBuf) -> io::Result<()> { - // { - // "schema": version, - // "crate": { parsed crate ... }, - // "plugins": { output of plugins ... } - // } - let mut json = std::collections::BTreeMap::new(); - json.insert("schema".to_string(), Json::String(SCHEMA_VERSION.to_string())); - let plugins_json = res.into_iter() - .filter_map(|opt| { - opt.map(|(string, json)| (string.to_string(), json)) - }).collect(); - - // FIXME #8335: yuck, Rust -> str -> JSON round trip! No way to .encode - // straight to the Rust JSON representation. - let crate_json_str = format!("{}", json::as_json(&krate)); - let crate_json = json::from_str(&crate_json_str).expect("Rust generated JSON is invalid"); - - json.insert("crate".to_string(), crate_json); - json.insert("plugins".to_string(), Json::Object(plugins_json)); - - let mut file = File::create(&dst)?; - write!(&mut file, "{}", Json::Object(json)) + let krate = pm.run_plugins(krate); + Output { krate: krate, passes: passes } } diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs index ff2a9f13e8a..adc39b69986 100644 --- a/src/librustdoc/passes.rs +++ b/src/librustdoc/passes.rs @@ -54,7 +54,7 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult { }; // strip any traits implemented on stripped items - let krate = { + { struct ImplStripper<'a> { stripped: &'a mut DefIdSet } @@ -80,9 +80,7 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult { } let mut stripper = ImplStripper{ stripped: &mut stripped }; stripper.fold_crate(krate) - }; - - (krate, None) + } } /// Strip private items from the point of view of a crate or externally from a @@ -107,9 +105,8 @@ pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult { // strip all private implementations of traits { let mut stripper = ImplStripper(&retained); - krate = stripper.fold_crate(krate); + stripper.fold_crate(krate) } - (krate, None) } struct Stripper<'a> { @@ -192,17 +189,19 @@ impl<'a> fold::DocFolder for Stripper<'a> { self.fold_item_recur(i) }; - i.and_then(|i| { match i.inner { - // emptied modules/impls have no need to exist - clean::ModuleItem(ref m) - if m.items.is_empty() && - i.doc_value().is_none() => None, - clean::ImplItem(ref i) if i.items.is_empty() => None, - _ => { - self.retained.insert(i.def_id); - Some(i) + i.and_then(|i| { + match i.inner { + // emptied modules/impls have no need to exist + clean::ModuleItem(ref m) + if m.items.is_empty() && + i.doc_value().is_none() => None, + clean::ImplItem(ref i) if i.items.is_empty() => None, + _ => { + self.retained.insert(i.def_id); + Some(i) + } } - }}) + }) } } @@ -234,7 +233,7 @@ impl fold::DocFolder for ImportStripper { } pub fn strip_priv_imports(krate: clean::Crate) -> plugins::PluginResult { - (ImportStripper.fold_crate(krate), None) + ImportStripper.fold_crate(krate) } pub fn unindent_comments(krate: clean::Crate) -> plugins::PluginResult { @@ -258,7 +257,7 @@ pub fn unindent_comments(krate: clean::Crate) -> plugins::PluginResult { } let mut cleaner = CommentCleaner; let krate = cleaner.fold_crate(krate); - (krate, None) + krate } pub fn collapse_docs(krate: clean::Crate) -> plugins::PluginResult { @@ -287,7 +286,7 @@ pub fn collapse_docs(krate: clean::Crate) -> plugins::PluginResult { } let mut collapser = Collapser; let krate = collapser.fold_crate(krate); - (krate, None) + krate } pub fn unindent(s: &str) -> String { diff --git a/src/librustdoc/plugins.rs b/src/librustdoc/plugins.rs index 83ce3e61ab2..b8be84825c9 100644 --- a/src/librustdoc/plugins.rs +++ b/src/librustdoc/plugins.rs @@ -12,15 +12,13 @@ use clean; -use serialize::json; use std::mem; use std::string::String; use std::path::PathBuf; use rustc_back::dynamic_lib as dl; -pub type PluginJson = Option<(String, json::Json)>; -pub type PluginResult = (clean::Crate, PluginJson); +pub type PluginResult = clean::Crate; pub type PluginCallback = fn (clean::Crate) -> PluginResult; /// Manages loading and running of plugins @@ -65,15 +63,11 @@ impl PluginManager { self.callbacks.push(plugin); } /// Run all the loaded plugins over the crate, returning their results - pub fn run_plugins(&self, krate: clean::Crate) -> (clean::Crate, Vec<PluginJson> ) { - let mut out_json = Vec::new(); - let mut krate = krate; + pub fn run_plugins(&self, mut krate: clean::Crate) -> clean::Crate { for &callback in &self.callbacks { - let (c, res) = callback(krate); - krate = c; - out_json.push(res); + krate = callback(krate); } - (krate, out_json) + krate } } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 71c522e9e75..982f477fc4a 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -122,8 +122,8 @@ pub fn run(input: &str, if let Some(name) = crate_name { krate.name = name; } - let (krate, _) = passes::collapse_docs(krate); - let (krate, _) = passes::unindent_comments(krate); + let krate = passes::collapse_docs(krate); + let krate = passes::unindent_comments(krate); let mut collector = Collector::new(krate.name.to_string(), cfgs, diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 5309cc3c858..f413bed86a8 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -466,7 +466,7 @@ enum State { Done = 3, } -/// A Windows path prefix, e.g. `C:` or `\server\share`. +/// A Windows path prefix, e.g. `C:` or `\\server\share`. /// /// Does not occur on Unix. #[stable(feature = "rust1", since = "1.0.0")] @@ -528,7 +528,7 @@ impl<'a> Hash for PrefixComponent<'a> { #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub enum Component<'a> { - /// A Windows path prefix, e.g. `C:` or `\server\share`. + /// A Windows path prefix, e.g. `C:` or `\\server\share`. /// /// Does not occur on Unix. #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 99de4aa0086..fc18ef407ab 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -218,10 +218,10 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status ("naked_functions", "1.9.0", Some(32408), Active), // allow empty structs and enum variants with braces - ("braced_empty_structs", "1.5.0", Some(29720), Accepted), + ("braced_empty_structs", "1.8.0", Some(29720), Accepted), // allow overloading augmented assignment operations like `a += b` - ("augmented_assignments", "1.5.0", Some(28235), Accepted), + ("augmented_assignments", "1.8.0", Some(28235), Accepted), // allow `#[no_debug]` ("no_debug", "1.5.0", Some(29721), Active), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b8c926f8de9..c4997348537 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2578,7 +2578,7 @@ impl<'a> Parser<'a> { loop { // expr? while self.eat(&token::Question) { - let hi = self.span.hi; + let hi = self.last_span.hi; e = self.mk_expr(lo, hi, ExprKind::Try(e), None); } diff --git a/src/test/compile-fail/extern-crate-visibility.rs b/src/test/compile-fail/extern-crate-visibility.rs index 56a41a15ab3..86aae472148 100644 --- a/src/test/compile-fail/extern-crate-visibility.rs +++ b/src/test/compile-fail/extern-crate-visibility.rs @@ -30,5 +30,14 @@ fn f() { mod core {} // Check that private crates are not glob imported } +mod bar { + pub extern crate core; +} + +mod baz { + pub use bar::*; + use self::core::cell; // Check that public extern crates are glob imported +} + #[rustc_error] fn main() {} //~ ERROR compilation successful diff --git a/src/test/compile-fail/issue-24883.rs b/src/test/compile-fail/issue-24883.rs new file mode 100644 index 00000000000..097f2a5630c --- /dev/null +++ b/src/test/compile-fail/issue-24883.rs @@ -0,0 +1,28 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rustc_attrs)] + +mod a { + pub mod b { pub struct Foo; } + + pub mod c { + use super::b; + pub struct Bar(pub b::Foo); + } + + pub use self::c::*; +} + +#[rustc_error] +fn main() { //~ ERROR compilation successful + let _ = a::c::Bar(a::b::Foo); + let _ = a::Bar(a::b::Foo); +} diff --git a/src/test/compile-fail/issue-26930.rs b/src/test/compile-fail/issue-26930.rs new file mode 100644 index 00000000000..6c98f3e8560 --- /dev/null +++ b/src/test/compile-fail/issue-26930.rs @@ -0,0 +1,20 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rustc_attrs)] +#![allow(unused)] + +extern crate core; +use core as core_export; +use self::x::*; +mod x {} + +#[rustc_error] +fn main() {} //~ ERROR compilation successful diff --git a/src/test/compile-fail/issue-32201.rs b/src/test/compile-fail/issue-32201.rs new file mode 100644 index 00000000000..bcc53df68a3 --- /dev/null +++ b/src/test/compile-fail/issue-32201.rs @@ -0,0 +1,22 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern { + fn foo(a: i32, ...); +} + +fn bar(_: *const u8) {} + +fn main() { + unsafe { + foo(0, bar); + //~^ ERROR can't pass `fn(*const u8) {bar}` to variadic function, cast to `fn(*const u8)` + } +} diff --git a/src/test/compile-fail/issue-32833.rs b/src/test/compile-fail/issue-32833.rs new file mode 100644 index 00000000000..22261d98a12 --- /dev/null +++ b/src/test/compile-fail/issue-32833.rs @@ -0,0 +1,16 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use bar::Foo; //~ ERROR There is no `Foo` in `bar` [E0432] +mod bar { + use Foo; //~ ERROR There is no `Foo` in the crate root [E0432] +} + +fn main() {} diff --git a/src/test/compile-fail/symbol-names/issue-32709.rs b/src/test/compile-fail/symbol-names/issue-32709.rs new file mode 100644 index 00000000000..f9d11f3a171 --- /dev/null +++ b/src/test/compile-fail/symbol-names/issue-32709.rs @@ -0,0 +1,20 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(question_mark)] + +// Make sure that the span of try shorthand does not include the trailing +// semicolon; +fn a() -> Result<i32, ()> { + Err(5)?; //~ ERROR 16:5: 16:12 + Ok(1) +} + +fn main() {} diff --git a/src/test/compile-fail/use-mod-2.rs b/src/test/compile-fail/use-mod-2.rs index e98224bee02..f2384912cdb 100644 --- a/src/test/compile-fail/use-mod-2.rs +++ b/src/test/compile-fail/use-mod-2.rs @@ -10,10 +10,10 @@ mod foo { use self::{self}; - //~^ ERROR unresolved import `self`. There is no `self` in `???` + //~^ ERROR unresolved import `self`. There is no `self` in the crate root use super::{self}; - //~^ ERROR unresolved import `super`. There is no `super` in `???` + //~^ ERROR unresolved import `super`. There is no `super` in the crate root } fn main() {} diff --git a/src/test/compile-fail/variadic-ffi-3.rs b/src/test/compile-fail/variadic-ffi-3.rs index 1d5ebdbae3e..6e60562da67 100644 --- a/src/test/compile-fail/variadic-ffi-3.rs +++ b/src/test/compile-fail/variadic-ffi-3.rs @@ -33,11 +33,11 @@ fn main() { //~| expected variadic fn //~| found non-variadic function - foo(1, 2, 3f32); //~ ERROR: can't pass an f32 to variadic function, cast to c_double - foo(1, 2, true); //~ ERROR: can't pass bool to variadic function, cast to c_int - foo(1, 2, 1i8); //~ ERROR: can't pass i8 to variadic function, cast to c_int - foo(1, 2, 1u8); //~ ERROR: can't pass u8 to variadic function, cast to c_uint - foo(1, 2, 1i16); //~ ERROR: can't pass i16 to variadic function, cast to c_int - foo(1, 2, 1u16); //~ ERROR: can't pass u16 to variadic function, cast to c_uint + foo(1, 2, 3f32); //~ ERROR: can't pass an `f32` to variadic function, cast to `c_double` + foo(1, 2, true); //~ ERROR: can't pass `bool` to variadic function, cast to `c_int` + foo(1, 2, 1i8); //~ ERROR: can't pass `i8` to variadic function, cast to `c_int` + foo(1, 2, 1u8); //~ ERROR: can't pass `u8` to variadic function, cast to `c_uint` + foo(1, 2, 1i16); //~ ERROR: can't pass `i16` to variadic function, cast to `c_int` + foo(1, 2, 1u16); //~ ERROR: can't pass `u16` to variadic function, cast to `c_uint` } } diff --git a/src/test/run-make/rustdoc-json/foo.rs b/src/test/parse-fail/issue-32505.rs index 3bd56c14193..e697e98bc06 100644 --- a/src/test/run-make/rustdoc-json/foo.rs +++ b/src/test/parse-fail/issue-32505.rs @@ -8,18 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![crate_name = "foo"] +// compile-flags: -Z parse-only -Z continue-parse-after-error -//! Very docs - -pub mod bar { - - /// So correct - pub mod baz { - /// Much detail - pub fn baz() { } - } - - /// *wow* - pub trait Doge { fn dummy(&self) { } } +pub fn test() { + foo(|_|) //~ ERROR unexpected token: `)` } + +fn main() { } diff --git a/src/test/run-make/rustdoc-json/Makefile b/src/test/run-make/rustdoc-json/Makefile deleted file mode 100644 index e49ab64b695..00000000000 --- a/src/test/run-make/rustdoc-json/Makefile +++ /dev/null @@ -1,4 +0,0 @@ --include ../tools.mk -all: - $(HOST_RPATH_ENV) $(RUSTDOC) -w json -o $(TMPDIR)/doc.json foo.rs - $(HOST_RPATH_ENV) $(RUSTDOC) -o $(TMPDIR)/doc $(TMPDIR)/doc.json diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs index 69ec9299d68..87a01038675 100644 --- a/src/tools/cargotest/main.rs +++ b/src/tools/cargotest/main.rs @@ -19,7 +19,7 @@ use std::io::Write; const TEST_REPOS: &'static [(&'static str, &'static str, Option<&'static str>)] = &[ ("https://github.com/rust-lang/cargo", - "ff02b156f094fb83e70acd965c83c9286411914e", + "fae9c539388f1b7c70c31fd0a21b5dd9cd071177", None), ("https://github.com/iron/iron", "16c858ec2901e2992fe5e529780f59fa8ed12903", |
