]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #41572 - frewsxcv:bump-mdbook, r=steveklabnik
authorCorey Farwell <coreyf@rwell.org>
Thu, 27 Apr 2017 23:59:17 +0000 (19:59 -0400)
committerGitHub <noreply@github.com>
Thu, 27 Apr 2017 23:59:17 +0000 (19:59 -0400)
Bump mdbook dep to pick up new 'create missing' toggle feature.

This will avoid obscure Travis CI error messages:

* https://github.com/rust-lang/rust/pull/40290#issuecomment-294137045

Original mdbook issue:

* https://github.com/azerupi/mdBook/issues/253

mdbook PR:

* https://github.com/azerupi/mdBook/pull/254

142 files changed:
.travis.yml
appveyor.yml
src/Cargo.lock
src/bootstrap/Cargo.toml
src/bootstrap/bin/sccache-plus-cl.rs [new file with mode: 0644]
src/bootstrap/bootstrap.py
src/bootstrap/config.toml.example
src/bootstrap/dist.rs
src/bootstrap/native.rs
src/bootstrap/util.rs
src/ci/docker/armhf-gnu/Dockerfile
src/ci/docker/cross/Dockerfile
src/ci/docker/dist-aarch64-linux/Dockerfile
src/ci/docker/dist-android/Dockerfile
src/ci/docker/dist-arm-linux/Dockerfile
src/ci/docker/dist-armhf-linux/Dockerfile
src/ci/docker/dist-armv7-linux/Dockerfile
src/ci/docker/dist-fuchsia/Dockerfile
src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile
src/ci/docker/dist-i686-freebsd/Dockerfile
src/ci/docker/dist-i686-linux/Dockerfile
src/ci/docker/dist-mips-linux/Dockerfile
src/ci/docker/dist-mips64-linux/Dockerfile
src/ci/docker/dist-mips64el-linux/Dockerfile
src/ci/docker/dist-mipsel-linux/Dockerfile
src/ci/docker/dist-powerpc-linux/Dockerfile
src/ci/docker/dist-powerpc64-linux/Dockerfile
src/ci/docker/dist-powerpc64le-linux/Dockerfile
src/ci/docker/dist-s390x-linux/Dockerfile
src/ci/docker/dist-x86_64-freebsd/Dockerfile
src/ci/docker/dist-x86_64-linux/Dockerfile
src/ci/docker/dist-x86_64-musl/Dockerfile
src/ci/docker/dist-x86_64-netbsd/Dockerfile
src/ci/docker/emscripten/Dockerfile
src/ci/docker/i686-gnu-nopt/Dockerfile
src/ci/docker/i686-gnu/Dockerfile
src/ci/docker/x86_64-gnu-aux/Dockerfile
src/ci/docker/x86_64-gnu-debug/Dockerfile
src/ci/docker/x86_64-gnu-distcheck/Dockerfile
src/ci/docker/x86_64-gnu-full-bootstrap/Dockerfile
src/ci/docker/x86_64-gnu-incremental/Dockerfile
src/ci/docker/x86_64-gnu-llvm-3.7/Dockerfile
src/ci/docker/x86_64-gnu-nopt/Dockerfile
src/ci/docker/x86_64-gnu/Dockerfile
src/grammar/parser-lalr.y
src/libcore/iter/range.rs
src/libcore/tests/iter.rs
src/libcore/tests/lib.rs
src/librustc/dep_graph/dep_node.rs
src/librustc/hir/lowering.rs
src/librustc/hir/mod.rs
src/librustc/hir/print.rs
src/librustc/ich/impls_hir.rs
src/librustc/middle/cstore.rs
src/librustc/middle/reachable.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/traits/project.rs
src/librustc/traits/util.rs
src/librustc/ty/item_path.rs
src/librustc/ty/maps.rs
src/librustc/ty/mod.rs
src/librustc_back/dynamic_lib.rs
src/librustc_back/target/haiku_base.rs
src/librustc_borrowck/borrowck/gather_loans/move_error.rs
src/librustc_data_structures/flock.rs
src/librustc_driver/driver.rs
src/librustc_llvm/build.rs
src/librustc_llvm/lib.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/schema.rs
src/librustc_save_analysis/dump_visitor.rs
src/librustc_trans/abi.rs
src/librustc_trans/back/symbol_export.rs
src/librustc_trans/back/symbol_names.rs
src/librustc_trans/base.rs
src/librustc_trans/cabi_hexagon.rs [new file with mode: 0644]
src/librustc_trans/callee.rs
src/librustc_trans/collector.rs
src/librustc_trans/consts.rs
src/librustc_trans/context.rs
src/librustc_trans/lib.rs
src/librustc_trans/partitioning.rs
src/librustc_trans/symbol_cache.rs [deleted file]
src/librustc_trans/symbol_map.rs [deleted file]
src/librustc_trans/symbol_names_test.rs
src/librustc_trans/trans_item.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/coherence/unsafety.rs
src/librustc_typeck/collect.rs
src/librustdoc/doctree.rs
src/librustdoc/visit_ast.rs
src/libstd/net/tcp.rs
src/libstd/sync/mpsc/mod.rs
src/libsyntax/ast.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libunwind/build.rs
src/llvm
src/rustllvm/PassWrapper.cpp
src/rustllvm/llvm-rebuild-trigger
src/test/compile-fail/borrowck/borrowck-in-static.rs [deleted file]
src/test/compile-fail/numeric-fields.rs
src/test/compile-fail/specialization/defaultimpl/specialization-default-projection.rs [new file with mode: 0644]
src/test/compile-fail/specialization/defaultimpl/specialization-default-types.rs [new file with mode: 0644]
src/test/compile-fail/specialization/defaultimpl/specialization-feature-gate-default.rs [new file with mode: 0644]
src/test/compile-fail/specialization/defaultimpl/specialization-no-default-trait-implementations.rs [new file with mode: 0644]
src/test/compile-fail/specialization/defaultimpl/specialization-no-default.rs [new file with mode: 0644]
src/test/compile-fail/unboxed-closures-move-upvar-from-non-once-ref-closure.rs [deleted file]
src/test/run-pass/issue-33287.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/auxiliary/go_trait.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/auxiliary/specialization_cross_crate.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/auxiliary/specialization_cross_crate_defaults.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/specialization-allowed-cross-crate.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/specialization-assoc-fns.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/specialization-basics-unsafe.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/specialization-basics.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/specialization-cross-crate-defaults.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/specialization-cross-crate-no-gate.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/specialization-cross-crate.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/specialization-default-methods.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/specialization-out-of-order.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/specialization-overlap-projection.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/specialization-projection-alias.rs [new file with mode: 0644]
src/test/run-pass/specialization/defaultimpl/specialization-projection.rs [new file with mode: 0644]
src/test/ui/borrowck/borrowck-in-static.rs [new file with mode: 0644]
src/test/ui/borrowck/borrowck-in-static.stderr [new file with mode: 0644]
src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs [new file with mode: 0644]
src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr [new file with mode: 0644]
src/test/ui/invalid-module-declaration/auxiliary/foo/bar.rs [new file with mode: 0644]
src/test/ui/invalid-module-declaration/auxiliary/foo/mod.rs [new file with mode: 0644]
src/test/ui/invalid-module-declaration/invalid-module-declaration.rs [new file with mode: 0644]
src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr [new file with mode: 0644]
src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs
src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
src/tools/compiletest/src/procsrv.rs

index c5372609e9bc622eb8f0385fd0db681d906ba0b0..530ae4aa65cc837ea2e0df82a3c00175dc2f75d5 100644 (file)
@@ -63,7 +63,7 @@ matrix:
       os: osx
       osx_image: xcode8.2
       install: &osx_install_sccache >
-        travis_retry curl -o /usr/local/bin/sccache https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-apple-darwin &&
+        travis_retry curl -o /usr/local/bin/sccache https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-apple-darwin &&
           chmod +x /usr/local/bin/sccache &&
         travis_retry curl -o /usr/local/bin/stamp https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-17-stamp-x86_64-apple-darwin &&
           chmod +x /usr/local/bin/stamp
index c662ba03602549485ff48ffb57c802f9e08b67fd..7f9ba5a057f532f7545739ae55e996558ecfae04 100644 (file)
@@ -32,14 +32,14 @@ environment:
   # came from the mingw-w64 SourceForge download site. Unfortunately
   # SourceForge is notoriously flaky, so we mirror it on our own infrastructure.
   - MSYS_BITS: 32
-    RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-ninja
+    RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
     SCRIPT: python x.py test
     MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror
     MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z
     MINGW_DIR: mingw32
   - MSYS_BITS: 64
     SCRIPT: python x.py test
-    RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-ninja
+    RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
     MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror
     MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z
     MINGW_DIR: mingw64
@@ -57,7 +57,7 @@ environment:
     SCRIPT: python x.py dist
     DEPLOY: 1
   - MSYS_BITS: 32
-    RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-extended --enable-ninja
+    RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-extended
     SCRIPT: python x.py dist
     MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror
     MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z
@@ -65,7 +65,7 @@ environment:
     DEPLOY: 1
   - MSYS_BITS: 64
     SCRIPT: python x.py dist
-    RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-extended --enable-ninja
+    RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-extended
     MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror
     MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z
     MINGW_DIR: mingw64
@@ -124,8 +124,8 @@ install:
   - set PATH=C:\Python27;%PATH%
 
   # Download and install sccache
-  - appveyor-retry appveyor DownloadFile https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-pc-windows-msvc
-  - mv 2017-04-04-sccache-x86_64-pc-windows-msvc sccache.exe
+  - appveyor-retry appveyor DownloadFile https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-pc-windows-msvc
+  - mv 2017-04-19-sccache-x86_64-pc-windows-msvc sccache.exe
   - set PATH=%PATH%;%CD%
 
   # Download and install ninja
@@ -133,6 +133,7 @@ install:
   # Note that this is originally from the github releases patch of Ninja
   - appveyor-retry appveyor DownloadFile https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-15-ninja-win.zip
   - 7z x 2017-03-15-ninja-win.zip
+  - set RUST_CONFIGURE_ARGS=%RUST_CONFIGURE_ARGS% --enable-ninja
   # - set PATH=%PATH%;%CD% -- this already happens above for sccache
 
   # Install InnoSetup to get `iscc` used to produce installers
@@ -159,12 +160,6 @@ test_script:
 on_failure:
   - cat %CD%\sccache.log || exit 0
 
-cache:
-  - "build/i686-pc-windows-msvc/llvm -> src/rustllvm/llvm-rebuild-trigger"
-  - "build/x86_64-pc-windows-msvc/llvm -> src/rustllvm/llvm-rebuild-trigger"
-  - "i686-pc-windows-msvc/llvm -> src/rustllvm/llvm-rebuild-trigger"
-  - "x86_64-pc-windows-msvc/llvm -> src/rustllvm/llvm-rebuild-trigger"
-
 branches:
   only:
     - auto
index a1e403c6f1389c92c132e46c54603ef07594248f..659feef80a4b9a276d7554a01b92089733c82063 100644 (file)
@@ -78,7 +78,7 @@ dependencies = [
  "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -299,7 +299,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "num_cpus"
-version = "0.2.13"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1004,7 +1004,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum mdbook 0.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e2e9d848514dcfad4195788d0d42ae5153a477c191d75d5b84fab10f222fbd"
 "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
 "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
-"checksum num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "cee7e88156f3f9e19bdd598f8d6c9db7bf4078f99f8381f43a55b09648d1a6e3"
+"checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167"
 "checksum open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3478ed1686bd1300c8a981a940abc92b06fac9cbef747f4c668d4e032ff7b842"
 "checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8"
 "checksum pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ab1e588ef8efd702c7ed9d2bd774db5e6f4d878bb5a1a9f371828fbdff6973"
index 1eda1608c4709c4de84b57b8473ca62cbbaad820..1088067c2de57dce0df437d9ab661e5bd710c813 100644 (file)
@@ -23,11 +23,16 @@ name = "rustdoc"
 path = "bin/rustdoc.rs"
 test = false
 
+[[bin]]
+name = "sccache-plus-cl"
+path = "bin/sccache-plus-cl.rs"
+test = false
+
 [dependencies]
 build_helper = { path = "../build_helper" }
 cmake = "0.1.17"
 filetime = "0.1"
-num_cpus = "0.2"
+num_cpus = "1.0"
 toml = "0.1"
 getopts = "0.2"
 rustc-serialize = "0.3"
diff --git a/src/bootstrap/bin/sccache-plus-cl.rs b/src/bootstrap/bin/sccache-plus-cl.rs
new file mode 100644 (file)
index 0000000..cf0c127
--- /dev/null
@@ -0,0 +1,43 @@
+// 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.
+//
+// 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 crate gcc;
+
+use std::env;
+use std::process::{self, Command};
+
+fn main() {
+    let target = env::var("SCCACHE_TARGET").unwrap();
+    // Locate the actual compiler that we're invoking
+    env::remove_var("CC");
+    env::remove_var("CXX");
+    let mut cfg = gcc::Config::new();
+    cfg.cargo_metadata(false)
+       .out_dir("/")
+       .target(&target)
+       .host(&target)
+       .opt_level(0)
+       .debug(false);
+    let compiler = cfg.get_compiler();
+
+    // Invoke sccache with said compiler
+    let sccache_path = env::var_os("SCCACHE_PATH").unwrap();
+    let mut cmd = Command::new(&sccache_path);
+    cmd.arg(compiler.path());
+    for &(ref k, ref v) in compiler.env() {
+        cmd.env(k, v);
+    }
+    for arg in env::args().skip(1) {
+        cmd.arg(arg);
+    }
+
+    let status = cmd.status().expect("failed to spawn");
+    process::exit(status.code().unwrap_or(2))
+}
index 3233a73b007cc7c736de25cab619b58ffedb4132..e5f8143b41871e424276c9958c786822a5293ffe 100644 (file)
@@ -367,6 +367,9 @@ class RustBuild(object):
         env["DYLD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
                                    (os.pathsep + env["DYLD_LIBRARY_PATH"]) \
                                    if "DYLD_LIBRARY_PATH" in env else ""
+        env["LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
+                                   (os.pathsep + env["LIBRARY_PATH"]) \
+                                   if "LIBRARY_PATH" in env else ""
         env["PATH"] = os.path.join(self.bin_root(), "bin") + \
                       os.pathsep + env["PATH"]
         if not os.path.isfile(self.cargo()):
@@ -407,7 +410,11 @@ class RustBuild(object):
         # The goal here is to come up with the same triple as LLVM would,
         # at least for the subset of platforms we're willing to target.
         if ostype == 'Linux':
-            ostype = 'unknown-linux-gnu'
+            os = subprocess.check_output(['uname', '-o']).strip().decode(default_encoding)
+            if os == 'Android':
+                ostype = 'linux-android'
+            else:
+                ostype = 'unknown-linux-gnu'
         elif ostype == 'FreeBSD':
             ostype = 'unknown-freebsd'
         elif ostype == 'DragonFly':
@@ -464,15 +471,21 @@ class RustBuild(object):
             cputype = 'i686'
         elif cputype in {'xscale', 'arm'}:
             cputype = 'arm'
+            if ostype == 'linux-android':
+                ostype = 'linux-androideabi'
         elif cputype == 'armv6l':
             cputype = 'arm'
-            ostype += 'eabihf'
+            if ostype == 'linux-android':
+                ostype = 'linux-androideabi'
+            else:
+                ostype += 'eabihf'
         elif cputype in {'armv7l', 'armv8l'}:
             cputype = 'armv7'
-            ostype += 'eabihf'
-        elif cputype == 'aarch64':
-            cputype = 'aarch64'
-        elif cputype == 'arm64':
+            if ostype == 'linux-android':
+                ostype = 'linux-androideabi'
+            else:
+                ostype += 'eabihf'
+        elif cputype in {'aarch64', 'arm64'}:
             cputype = 'aarch64'
         elif cputype == 'mips':
             if sys.byteorder == 'big':
index fad79022043e33dbc800288edc60bd5174dc4f93..0309eca0e5deaec6a4f94081843386434397b684 100644 (file)
@@ -51,7 +51,7 @@
 # support. You'll need to write a target specification at least, and most
 # likely, teach rustc about the C ABI of the target. Get in touch with the
 # Rust team and file an issue if you need assistance in porting!
-#targets = "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX"
+#targets = "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX;Hexagon"
 
 # Cap the number of parallel linker invocations when compiling LLVM.
 # This can be useful when building LLVM with debug info, which significantly
index ada8d4df604e3550a0a9306a7352633c281a65c5..639ba5d5b0c48bc69e206700c1396a0154085341 100644 (file)
@@ -374,13 +374,11 @@ pub fn rust_src(build: &Build) {
 
     println!("Dist src");
 
-    let name = pkgname(build, "rust-src");
-    let image = tmpdir(build).join(format!("{}-image", name));
-    let _ = fs::remove_dir_all(&image);
-
-    let dst = image.join("lib/rustlib/src");
-    let dst_src = dst.join("rust");
-    t!(fs::create_dir_all(&dst_src));
+    // Make sure that the root folder of tarball has the correct name
+    let plain_name = format!("rustc-{}-src", build.rust_package_vers());
+    let plain_dst_src = tmpdir(build).join(&plain_name);
+    let _ = fs::remove_dir_all(&plain_dst_src);
+    t!(fs::create_dir_all(&plain_dst_src));
 
     // This is the set of root paths which will become part of the source package
     let src_files = [
@@ -429,13 +427,13 @@ pub fn rust_src(build: &Build) {
 
     // Copy the directories using our filter
     for item in &src_dirs {
-        let dst = &dst_src.join(item);
+        let dst = &plain_dst_src.join(item);
         t!(fs::create_dir(dst));
         cp_filtered(&build.src.join(item), dst, &filter_fn);
     }
     // Copy the files normally
     for item in &src_files {
-        copy(&build.src.join(item), &dst_src.join(item));
+        copy(&build.src.join(item), &plain_dst_src.join(item));
     }
 
     // If we're building from git sources, we need to vendor a complete distribution.
@@ -460,10 +458,63 @@ pub fn rust_src(build: &Build) {
         // Vendor all Cargo dependencies
         let mut cmd = Command::new(&build.cargo);
         cmd.arg("vendor")
-           .current_dir(&dst_src.join("src"));
+           .current_dir(&plain_dst_src.join("src"));
         build.run(&mut cmd);
     }
 
+    // Create the version file
+    write_file(&plain_dst_src.join("version"), build.rust_version().as_bytes());
+
+    // Create plain source tarball
+    let tarball = rust_src_location(build);
+    if let Some(dir) = tarball.parent() {
+        t!(fs::create_dir_all(dir));
+    }
+    let mut cmd = Command::new("tar");
+    cmd.arg("-czf").arg(sanitize_sh(&tarball))
+       .arg(&plain_name)
+       .current_dir(tmpdir(build));
+    build.run(&mut cmd);
+
+
+    let name = pkgname(build, "rust-src");
+    let image = tmpdir(build).join(format!("{}-image", name));
+    let _ = fs::remove_dir_all(&image);
+
+    let dst = image.join("lib/rustlib/src");
+    let dst_src = dst.join("rust");
+    t!(fs::create_dir_all(&dst_src));
+
+    // This is the reduced set of paths which will become the rust-src component
+    // (essentially libstd and all of its path dependencies)
+    let std_src_dirs = [
+        "src/build_helper",
+        "src/liballoc",
+        "src/liballoc_jemalloc",
+        "src/liballoc_system",
+        "src/libcollections",
+        "src/libcompiler_builtins",
+        "src/libcore",
+        "src/liblibc",
+        "src/libpanic_abort",
+        "src/libpanic_unwind",
+        "src/librand",
+        "src/librustc_asan",
+        "src/librustc_lsan",
+        "src/librustc_msan",
+        "src/librustc_tsan",
+        "src/libstd",
+        "src/libstd_unicode",
+        "src/libunwind",
+        "src/rustc/libc_shim",
+    ];
+
+    for item in &std_src_dirs {
+        let dst = &dst_src.join(item);
+        t!(fs::create_dir_all(dst));
+        cp_r(&plain_dst_src.join(item), dst);
+    }
+
     // Create source tarball in rust-installer format
     let mut cmd = Command::new(SH_CMD);
     cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh")))
@@ -478,23 +529,6 @@ pub fn rust_src(build: &Build) {
        .arg("--legacy-manifest-dirs=rustlib,cargo");
     build.run(&mut cmd);
 
-    // Rename directory, so that root folder of tarball has the correct name
-    let plain_name = format!("rustc-{}-src", build.rust_package_vers());
-    let plain_dst_src = tmpdir(build).join(&plain_name);
-    let _ = fs::remove_dir_all(&plain_dst_src);
-    t!(fs::create_dir_all(&plain_dst_src));
-    cp_r(&dst_src, &plain_dst_src);
-
-    // Create the version file
-    write_file(&plain_dst_src.join("version"), build.rust_version().as_bytes());
-
-    // Create plain source tarball
-    let mut cmd = Command::new("tar");
-    cmd.arg("-czf").arg(sanitize_sh(&rust_src_location(build)))
-       .arg(&plain_name)
-       .current_dir(tmpdir(build));
-    build.run(&mut cmd);
-
     t!(fs::remove_dir_all(&image));
     t!(fs::remove_dir_all(&plain_dst_src));
 }
index 3a95aec388d301105e0c43c7be6d8d7fb22310e1..3d87f701b2a56971b1c8fc34f30bf6086a72ce2f 100644 (file)
@@ -19,6 +19,7 @@
 //! ensure that they're always in place if needed.
 
 use std::env;
+use std::ffi::OsString;
 use std::fs::{self, File};
 use std::io::{Read, Write};
 use std::path::Path;
@@ -81,7 +82,7 @@ pub fn llvm(build: &Build, target: &str) {
     // NOTE: remember to also update `config.toml.example` when changing the defaults!
     let llvm_targets = match build.config.llvm_targets {
         Some(ref s) => s,
-        None => "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX",
+        None => "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX;Hexagon",
     };
 
     let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"};
@@ -129,22 +130,56 @@ pub fn llvm(build: &Build, target: &str) {
            .define("LLVM_TABLEGEN", &host);
     }
 
-    // MSVC handles compiler business itself
-    if !target.contains("msvc") {
-        if let Some(ref ccache) = build.config.ccache {
+    let sanitize_cc = |cc: &Path| {
+        if target.contains("msvc") {
+            OsString::from(cc.to_str().unwrap().replace("\\", "/"))
+        } else {
+            cc.as_os_str().to_owned()
+        }
+    };
+
+    let configure_compilers = |cfg: &mut cmake::Config| {
+        // MSVC with CMake uses msbuild by default which doesn't respect these
+        // vars that we'd otherwise configure. In that case we just skip this
+        // entirely.
+        if target.contains("msvc") && !build.config.ninja {
+            return
+        }
+
+        let cc = build.cc(target);
+        let cxx = build.cxx(target);
+
+        // Handle msvc + ninja + ccache specially (this is what the bots use)
+        if target.contains("msvc") &&
+           build.config.ninja &&
+           build.config.ccache.is_some() {
+            let mut cc = env::current_exe().expect("failed to get cwd");
+            cc.set_file_name("sccache-plus-cl.exe");
+
+           cfg.define("CMAKE_C_COMPILER", sanitize_cc(&cc))
+              .define("CMAKE_CXX_COMPILER", sanitize_cc(&cc));
+           cfg.env("SCCACHE_PATH",
+                   build.config.ccache.as_ref().unwrap())
+              .env("SCCACHE_TARGET", target);
+
+        // If ccache is configured we inform the build a little differently hwo
+        // to invoke ccache while also invoking our compilers.
+        } else if let Some(ref ccache) = build.config.ccache {
            cfg.define("CMAKE_C_COMPILER", ccache)
-              .define("CMAKE_C_COMPILER_ARG1", build.cc(target))
+              .define("CMAKE_C_COMPILER_ARG1", sanitize_cc(cc))
               .define("CMAKE_CXX_COMPILER", ccache)
-              .define("CMAKE_CXX_COMPILER_ARG1", build.cxx(target));
+              .define("CMAKE_CXX_COMPILER_ARG1", sanitize_cc(cxx));
         } else {
-           cfg.define("CMAKE_C_COMPILER", build.cc(target))
-              .define("CMAKE_CXX_COMPILER", build.cxx(target));
+           cfg.define("CMAKE_C_COMPILER", sanitize_cc(cc))
+              .define("CMAKE_CXX_COMPILER", sanitize_cc(cxx));
         }
-        cfg.build_arg("-j").build_arg(build.jobs().to_string());
 
+        cfg.build_arg("-j").build_arg(build.jobs().to_string());
         cfg.define("CMAKE_C_FLAGS", build.cflags(target).join(" "));
         cfg.define("CMAKE_CXX_FLAGS", build.cflags(target).join(" "));
-    }
+    };
+
+    configure_compilers(&mut cfg);
 
     if env::var_os("SCCACHE_ERROR_LOG").is_some() {
         cfg.env("RUST_LOG", "sccache=info");
index dab20f44bc361d4e18cdeb0d50fa1236ebe320c2..e01c06b10fcd63097de8a14f8b5e2b0f525bccb3 100644 (file)
@@ -139,6 +139,8 @@ pub fn dylib_path_var() -> &'static str {
         "PATH"
     } else if cfg!(target_os = "macos") {
         "DYLD_LIBRARY_PATH"
+    } else if cfg!(target_os = "haiku") {
+        "LIBRARY_PATH"
     } else {
         "LD_LIBRARY_PATH"
     }
index d42b35d488c3d5be27afee72e36174a513ec5e47..212d14c6a80fc21353d4ffe68bfd9f8c30ca8aae 100644 (file)
@@ -74,7 +74,7 @@ RUN arm-linux-gnueabihf-gcc addentropy.c -o rootfs/addentropy -static
 RUN curl -O http://ftp.nl.debian.org/debian/dists/jessie/main/installer-armhf/current/images/device-tree/vexpress-v2p-ca15-tc1.dtb
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 02d4eaf534acdd4d152bd963cef2655e91aaee65..649b106e2ff5de1da77c02effc3a44f940ef4a84 100644 (file)
@@ -22,7 +22,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index d9a5429d2b8e894b8b3dbff2b06f09015ea7406f..1f816585afeef87b1d4f9a231af6a99b81d6ad1c 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-toolchains.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/aarch64-unknown-linux-gnueabi/bin
index 28cc885ed30dabae3cc7fb5e14be7179a1713425..43a982c960a1c445224750103173aa8b3ba29503 100644 (file)
@@ -32,7 +32,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV TARGETS=arm-linux-androideabi
index 7162aa0efc0cfa1eae6ca5d1bc3608f6603692be..a3837296dfa3cf80e6395b1502067f6d136550af 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-toolchains.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/arm-unknown-linux-gnueabi/bin
index 8fa1cbe492fac67ab03ed1365a57909b3ebcf482..e91027bed2de9e2e54379218655facaed284531f 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-toolchains.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/arm-unknown-linux-gnueabihf/bin
index 9fcd827fc9962cda2f27ef26033fc831618f354d..2e99507cadfd0da40734b426bc275dbf12f66eae 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-toolchains.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/armv7-unknown-linux-gnueabihf/bin
index 294460ed7604e93b1db7ca4afe365296c3e8278c..abc826f790b10679cd421b8c126342c2797a92bb 100644 (file)
@@ -30,7 +30,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV \
index 1ef3e569cb4bf15c85305e90adeb7b6bd74d9a13..1eafe6cf9d315935801de24b9eb4367a4ea2c73b 100644 (file)
@@ -26,7 +26,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV RUST_CONFIGURE_ARGS \
index 3b81216c6431edc91ec7e3148b7329d9cbf38c58..b94a5f4f6226683768789d579b78784d88e445cb 100644 (file)
@@ -25,7 +25,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV \
index c25c770136f90c9a406c7d3262eec4634b745728..686060551daea0cec192e2b6d6b7084549a8a203 100644 (file)
@@ -82,7 +82,7 @@ RUN curl -Lo /rustroot/dumb-init \
 ENTRYPOINT ["/rustroot/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV HOSTS=i686-unknown-linux-gnu
index 33cca061103a333406ddf9d648c1db9cf5ed36b2..419dbec310bcaec9033272a1428efe7cb7e9e6a3 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 157de83abb783bc5e9cf608a3c7b75f4050dc754..d4818062e3b8e94b5de0649e5a64e7fbf1929299 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 739d5ff6ac4aaddcce445c4f3ba8c414bdf81d2e..2739dfb12af5950ab67859b765a2639db4268aaa 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 9339063bc19ebb91c4a84f1d3c30a88141170bc0..9a36d901cf93f9c984c312cc91c7632d1b74a5aa 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 92342caed2a9540da682ce3dab052b27e2e3c26d..ff5c66a2a5ffe8687807d7c51377c2896194e9a2 100644 (file)
@@ -63,7 +63,7 @@ RUN ./build-powerpc-toolchain.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/powerpc-unknown-linux-gnu/bin
index 182dfd93cc76fea34780f15c11cc62050de6977b..2c245e1acde26fc5db279d014aa511c261b989cc 100644 (file)
@@ -63,7 +63,7 @@ RUN ./build-powerpc64-toolchain.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/powerpc64-unknown-linux-gnu/bin
index 6b9f964d5a38379f12e58d09e80c7bd0156bcda3..d2fec535f4118fe552b94cb6129ee07cf972986f 100644 (file)
@@ -63,7 +63,7 @@ COPY shared.sh build-powerpc64le-toolchain.sh /tmp/
 RUN ./build-powerpc64le-toolchain.sh
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV \
index 7c94f713e18759a7b55fb83e7c6440f13495dd49..2223b0c758e7493113a3e5483705bea88d3c0434 100644 (file)
@@ -63,7 +63,7 @@ RUN ./build-s390x-toolchain.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/s390x-ibm-linux-gnu/bin
index a2939c8c48591065be4515e3840d0d2e3a90aa1c..289bbbdf1ddaec73f7ff11f42b047015be48fdb8 100644 (file)
@@ -25,7 +25,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV \
index e835e8d2f7161b451d0403fbcfae52a5e8cda92d..aef0a0ecf8cc925015dfad9dddffb1f00f521442 100644 (file)
@@ -82,7 +82,7 @@ RUN curl -Lo /rustroot/dumb-init \
 ENTRYPOINT ["/rustroot/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV HOSTS=x86_64-unknown-linux-gnu
index f462ccbb9119afcd1887e606a013dd9a014d11fd..eb41e2e7dfd01ceaaccb5b7a29d9df539581f401 100644 (file)
@@ -26,7 +26,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV RUST_CONFIGURE_ARGS \
index a1dd9a3724a882004e62f8038a8c993aeb3f7f50..cf08e891fcd9cbfcda300c6dbe433bc88a941502 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-netbsd-toolchain.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/x86_64-unknown-netbsd/bin
index cbbca23f6e3dbd5561927cdc48f4c9cd234b6e61..13aac10ed15536496786dc529f324cbd42a990ee 100644 (file)
@@ -15,7 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   lib32stdc++6
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 34d0567a440f9debc694a256a4b54aeaf7149b9f..707ea2478286df6c6c5c36469c769f17fe7118f4 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 960a0fa7a385f9aec3dd05e9111065fe5e54323d..6adb87f51aab167671db0430fb0aef800f76fb1b 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 9871df90e00d509e55f22ad9a8c4050e5bb56cb2..3a22a6f8b493c59507303825bdba4b1c5256c6bc 100644 (file)
@@ -15,7 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 197b0ec9b9bb64bbe041682cdfb7771997c50004..4ec3f896af76b960479b78c9b31699e20444ad59 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 60af302791a74406e67923bbc71c7bb1c25aa943..6d90270023ece5108af0e6cb42bf64524e8577b3 100644 (file)
@@ -16,7 +16,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 4ec0b5c152575951bd6022d423670db169330af9..cd0c0272c1ff36c1744323a67e75cbde4c1947db 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 6448f88950f0df30e7bee4b02f6b348b695294c7..dcb5dc5d9083dd6315f9598d571dbc8abf9586f2 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index c00667fe1dd00020f22007714fd98d71c9872684..9f98dea61c986db7154833430edd21f70633890e 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 7284d231b844bd67c8b3bc3abbdac29cb8a49231..4dbb05a3133e4ef8ec970b5ed3895ccb356c151e 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 1dce84bc5fd73e61eda10ef6f4440151e1fba357..770a4c8c30200adc95a8e7eac54a668bbcdb3c5a 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-19-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 3aa76d168df077ae02358f8a247ee96e104661d8..c9fcdf7647b9cfa79e42164ca858d728a7685dd7 100644 (file)
@@ -89,6 +89,7 @@ extern char *yytext;
 %token TRAIT
 %token TYPE
 %token UNSAFE
+%token DEFAULT
 %token USE
 %token WHILE
 %token CONTINUE
@@ -534,6 +535,12 @@ maybe_unsafe
 | %empty { $$ = mk_none(); }
 ;
 
+maybe_default_maybe_unsafe
+: DEFAULT UNSAFE { $$ = mk_atom("DefaultUnsafe"); }
+| DEFAULT        { $$ = mk_atom("Default"); }
+|         UNSAFE { $$ = mk_atom("Unsafe"); }
+| %empty { $$ = mk_none(); }
+
 trait_method
 : type_method { $$ = mk_node("Required", 1, $1); }
 | method      { $$ = mk_node("Provided", 1, $1); }
@@ -588,27 +595,27 @@ impl_method
 // they are ambiguous with traits. We do the same here, regrettably,
 // by splitting ty into ty and ty_prim.
 item_impl
-: maybe_unsafe IMPL generic_params ty_prim_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
+: maybe_default_maybe_unsafe IMPL generic_params ty_prim_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
 {
   $$ = mk_node("ItemImpl", 6, $1, $3, $4, $5, $7, $8);
 }
-| maybe_unsafe IMPL generic_params '(' ty ')' maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
+| maybe_default_maybe_unsafe IMPL generic_params '(' ty ')' maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
 {
   $$ = mk_node("ItemImpl", 6, $1, $3, 5, $6, $9, $10);
 }
-| maybe_unsafe IMPL generic_params trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
+| maybe_default_maybe_unsafe IMPL generic_params trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
 {
   $$ = mk_node("ItemImpl", 6, $3, $4, $6, $7, $9, $10);
 }
-| maybe_unsafe IMPL generic_params '!' trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
+| maybe_default_maybe_unsafe IMPL generic_params '!' trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
 {
   $$ = mk_node("ItemImplNeg", 7, $1, $3, $5, $7, $8, $10, $11);
 }
-| maybe_unsafe IMPL generic_params trait_ref FOR DOTDOT '{' '}'
+| maybe_default_maybe_unsafe IMPL generic_params trait_ref FOR DOTDOT '{' '}'
 {
   $$ = mk_node("ItemImplDefault", 3, $1, $3, $4);
 }
-| maybe_unsafe IMPL generic_params '!' trait_ref FOR DOTDOT '{' '}'
+| maybe_default_maybe_unsafe IMPL generic_params '!' trait_ref FOR DOTDOT '{' '}'
 {
   $$ = mk_node("ItemImplDefaultNeg", 3, $1, $3, $4);
 }
@@ -1935,4 +1942,4 @@ brackets_delimited_token_trees
                $2,
                mk_node("TTTok", 1, mk_atom("]")));
 }
-;
+;
\ No newline at end of file
index 687c477f19e4c744aff29905f0fd43973fd6cb3d..bd831d638c0c4cc24e8573501345ab809c489477 100644 (file)
@@ -86,12 +86,12 @@ fn is_negative(&self) -> bool {
 
             #[inline]
             fn replace_one(&mut self) -> Self {
-                mem::replace(self, 0)
+                mem::replace(self, 1)
             }
 
             #[inline]
             fn replace_zero(&mut self) -> Self {
-                mem::replace(self, 1)
+                mem::replace(self, 0)
             }
 
             #[inline]
@@ -157,12 +157,12 @@ fn is_negative(&self) -> bool {
 
             #[inline]
             fn replace_one(&mut self) -> Self {
-                mem::replace(self, 0)
+                mem::replace(self, 1)
             }
 
             #[inline]
             fn replace_zero(&mut self) -> Self {
-                mem::replace(self, 1)
+                mem::replace(self, 0)
             }
 
             #[inline]
@@ -206,12 +206,12 @@ fn is_negative(&self) -> bool {
 
             #[inline]
             fn replace_one(&mut self) -> Self {
-                mem::replace(self, 0)
+                mem::replace(self, 1)
             }
 
             #[inline]
             fn replace_zero(&mut self) -> Self {
-                mem::replace(self, 1)
+                mem::replace(self, 0)
             }
 
             #[inline]
index 08442f9bcbff522d498b826d3dda8d1faf1b011e..001fa304cd08f5185c7c812a70add563f92cc5d6 100644 (file)
@@ -1082,3 +1082,41 @@ fn test_chain_fold() {
     assert_eq!(&[2, 3, 1, 2, 0], &result[..]);
 }
 
+#[test]
+fn test_step_replace_unsigned() {
+    let mut x = 4u32;
+    let y = x.replace_zero();
+    assert_eq!(x, 0);
+    assert_eq!(y, 4);
+
+    x = 5;
+    let y = x.replace_one();
+    assert_eq!(x, 1);
+    assert_eq!(y, 5);
+}
+
+#[test]
+fn test_step_replace_signed() {
+    let mut x = 4i32;
+    let y = x.replace_zero();
+    assert_eq!(x, 0);
+    assert_eq!(y, 4);
+
+    x = 5;
+    let y = x.replace_one();
+    assert_eq!(x, 1);
+    assert_eq!(y, 5);
+}
+
+#[test]
+fn test_step_replace_no_between() {
+    let mut x = 4u128;
+    let y = x.replace_zero();
+    assert_eq!(x, 0);
+    assert_eq!(y, 4);
+
+    x = 5;
+    let y = x.replace_one();
+    assert_eq!(x, 1);
+    assert_eq!(y, 5);
+}
\ No newline at end of file
index 528ab3bc84523e184ee7b41b12bbce7d9e36ee57..f0c46a6f194d55b5654f0fa2d78047cc3e4975ea 100644 (file)
@@ -20,6 +20,7 @@
 #![feature(fixed_size_array)]
 #![feature(flt2dec)]
 #![feature(fmt_internals)]
+#![feature(i128_type)]
 #![feature(iter_rfind)]
 #![feature(libc)]
 #![feature(nonzero)]
@@ -30,6 +31,7 @@
 #![feature(sort_internals)]
 #![feature(sort_unstable)]
 #![feature(step_by)]
+#![feature(step_trait)]
 #![feature(test)]
 #![feature(try_from)]
 #![feature(unicode)]
index 33133f6834b9ab70a32a3e45de54c27929363d35..31e6a3106a438890a49d7f960e6b6aad12b1caaf 100644 (file)
@@ -99,6 +99,7 @@ pub enum DepNode<D: Clone + Debug> {
     TypeckTables(D),
     UsedTraitImports(D),
     ConstEval(D),
+    SymbolName(D),
 
     // The set of impls for a given trait. Ultimately, it would be
     // nice to get more fine-grained here (e.g., to include a
@@ -236,6 +237,7 @@ pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
             TypeckTables(ref d) => op(d).map(TypeckTables),
             UsedTraitImports(ref d) => op(d).map(UsedTraitImports),
             ConstEval(ref d) => op(d).map(ConstEval),
+            SymbolName(ref d) => op(d).map(SymbolName),
             TraitImpls(ref d) => op(d).map(TraitImpls),
             TraitItems(ref d) => op(d).map(TraitItems),
             ReprHints(ref d) => op(d).map(ReprHints),
index b7aafa0a9ab0b06b1c082ee795ab51c5a0791bf5..8f4dce5a78303d51d2c5850fd4fceb6af612df39 100644 (file)
@@ -1326,7 +1326,13 @@ fn lower_item_kind(&mut self,
                 hir::ItemDefaultImpl(self.lower_unsafety(unsafety),
                                      trait_ref)
             }
-            ItemKind::Impl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => {
+            ItemKind::Impl(unsafety,
+                           polarity,
+                           defaultness,
+                           ref generics,
+                           ref ifce,
+                           ref ty,
+                           ref impl_items) => {
                 let new_impl_items = impl_items.iter()
                                                .map(|item| self.lower_impl_item_ref(item))
                                                .collect();
@@ -1340,6 +1346,7 @@ fn lower_item_kind(&mut self,
 
                 hir::ItemImpl(self.lower_unsafety(unsafety),
                               self.lower_impl_polarity(polarity),
+                              self.lower_defaultness(defaultness, true /* [1] */),
                               self.lower_generics(generics),
                               ifce,
                               self.lower_ty(ty),
@@ -1355,6 +1362,9 @@ fn lower_item_kind(&mut self,
             }
             ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"),
         }
+
+        // [1] `defaultness.has_value()` is never called for an `impl`, always `true` in order to
+        //     not cause an assertion failure inside the `lower_defaultness` function
     }
 
     fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
index 562b58844409dc495da711300e5cd3aae63f3af1..cb7f530b9952f779011e899b13dbde7fde04b977 100644 (file)
@@ -1712,6 +1712,7 @@ pub enum Item_ {
     /// An implementation, eg `impl<A> Trait for Foo { .. }`
     ItemImpl(Unsafety,
              ImplPolarity,
+             Defaultness,
              Generics,
              Option<TraitRef>, // (optional) trait this impl implements
              P<Ty>, // self
index 5144f75b1a3634d8449f82d8ca5d6b073ce05ab8..a78d5ce1c16d0995e38372b9f911fd80af70208b 100644 (file)
@@ -678,12 +678,14 @@ pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
             }
             hir::ItemImpl(unsafety,
                           polarity,
+                          defaultness,
                           ref generics,
                           ref opt_trait,
                           ref ty,
                           ref impl_items) => {
                 self.head("")?;
                 self.print_visibility(&item.vis)?;
+                self.print_defaultness(defaultness)?;
                 self.print_unsafety(unsafety)?;
                 self.word_nbsp("impl")?;
 
@@ -820,6 +822,14 @@ pub fn print_visibility(&mut self, vis: &hir::Visibility) -> io::Result<()> {
         }
     }
 
+    pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) -> io::Result<()> {
+        match defaultness {
+            hir::Defaultness::Default { .. } => self.word_nbsp("default")?,
+            hir::Defaultness::Final => (),
+        }
+        Ok(())
+    }
+
     pub fn print_struct(&mut self,
                         struct_def: &hir::VariantData,
                         generics: &hir::Generics,
@@ -931,11 +941,7 @@ pub fn print_impl_item(&mut self, ii: &hir::ImplItem) -> io::Result<()> {
         self.hardbreak_if_not_bol()?;
         self.maybe_print_comment(ii.span.lo)?;
         self.print_outer_attributes(&ii.attrs)?;
-
-        match ii.defaultness {
-            hir::Defaultness::Default { .. } => self.word_nbsp("default")?,
-            hir::Defaultness::Final => (),
-        }
+        self.print_defaultness(ii.defaultness)?;
 
         match ii.node {
             hir::ImplItemKind::Const(ref ty, expr) => {
index 82e03a9fddc35a94564c2fae13cc815cfdd78541..3aeee1c1b981f4e861213579e7fa23a2f6a83641 100644 (file)
@@ -933,7 +933,7 @@ fn hash_stable<W: StableHasherResult>(&self,
     ItemUnion(variant_data, generics),
     ItemTrait(unsafety, generics, bounds, item_refs),
     ItemDefaultImpl(unsafety, trait_ref),
-    ItemImpl(unsafety, impl_polarity, generics, trait_ref, ty, impl_item_refs)
+    ItemImpl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
 });
 
 impl_stable_hash_for!(struct hir::TraitItemRef {
index 3251addcb3283310ffaf7b32dcca5f5019c58d95..60171f1a4289a9afb51a97a8b04fe7894727ca00 100644 (file)
@@ -195,6 +195,7 @@ pub trait CrateStore {
     fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>;
 
     // impl info
+    fn impl_defaultness(&self, def: DefId) -> hir::Defaultness;
     fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;
 
     // trait/impl-item info
@@ -329,6 +330,7 @@ fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name> { bug!("fn_arg_names") }
     fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId> { vec![] }
 
     // impl info
+    fn impl_defaultness(&self, def: DefId) -> hir::Defaultness { bug!("impl_defaultness") }
     fn impl_parent(&self, def: DefId) -> Option<DefId> { bug!("impl_parent") }
 
     // trait/impl-item info
index 431760b6fcd65187bca5eafec3f080bc1bea4cc1..939d7364d9e06bcedb839db9af70948b6342a8b8 100644 (file)
@@ -49,7 +49,7 @@ fn item_might_be_inlined(item: &hir::Item) -> bool {
     }
 
     match item.node {
-        hir::ItemImpl(_, _, ref generics, ..) |
+        hir::ItemImpl(_, _, _, ref generics, ..) |
         hir::ItemFn(.., ref generics, _) => {
             generics_require_inlining(generics)
         }
@@ -185,7 +185,7 @@ fn def_id_represents_local_inlined_item(&self, def_id: DefId) -> bool {
                             // does too.
                             let impl_node_id = self.tcx.hir.as_local_node_id(impl_did).unwrap();
                             match self.tcx.hir.expect_item(impl_node_id).node {
-                                hir::ItemImpl(_, _, ref generics, ..) => {
+                                hir::ItemImpl(_, _, _, ref generics, ..) => {
                                     generics_require_inlining(generics)
                                 }
                                 _ => false
index a1aabc775a31a69f4269767959832481e919fba9..a8ba708cc2cd41427904d4fdb279b3a53efd2f8b 100644 (file)
@@ -331,7 +331,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
             hir::ItemStruct(_, ref generics) |
             hir::ItemUnion(_, ref generics) |
             hir::ItemTrait(_, ref generics, ..) |
-            hir::ItemImpl(_, _, ref generics, ..) => {
+            hir::ItemImpl(_, _, _, ref generics, ..) => {
                 // These kinds of items have only early bound lifetime parameters.
                 let mut index = if let hir::ItemTrait(..) = item.node {
                     1 // Self comes before lifetimes
@@ -834,7 +834,7 @@ fn visit_early_late<F>(&mut self,
             }
             match parent.node {
                 hir::ItemTrait(_, ref generics, ..) |
-                hir::ItemImpl(_, _, ref generics, ..) => {
+                hir::ItemImpl(_, _, _, ref generics, ..) => {
                     index += (generics.lifetimes.len() + generics.ty_params.len()) as u32;
                 }
                 _ => {}
index 7e0954c92a660961a309a6ebf95ed74a71b44998..e01f97eb1f3a0340dbe635139ed7985becf977b6 100644 (file)
@@ -923,7 +923,8 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
                         // being invoked).
                         node_item.item.defaultness.has_value()
                     } else {
-                        node_item.item.defaultness.is_default()
+                        node_item.item.defaultness.is_default() ||
+                        selcx.tcx().impl_is_default(node_item.node.def_id())
                     };
 
                     // Only reveal a specializable default if we're past type-checking
index 396c7dbd1a874b293c6d6b703c2400a33a11e9d4..1d10c3a969509cacff5f5508bb35cdbc38b3300a 100644 (file)
@@ -13,6 +13,8 @@
 use ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef};
 use ty::outlives::Component;
 use util::nodemap::FxHashSet;
+use hir::{self};
+use traits::specialize::specialization_graph::NodeItem;
 
 use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext, Normalized};
 
@@ -504,6 +506,30 @@ pub fn closure_trait_ref_and_return_type(self,
         };
         ty::Binder((trait_ref, sig.skip_binder().output()))
     }
+
+    pub fn impl_is_default(self, node_item_def_id: DefId) -> bool {
+        match self.hir.as_local_node_id(node_item_def_id) {
+            Some(node_id) => {
+                let item = self.hir.expect_item(node_id);
+                if let hir::ItemImpl(_, _, defaultness, ..) = item.node {
+                    defaultness.is_default()
+                } else {
+                    false
+                }
+            }
+            None => {
+                self.global_tcx()
+                    .sess
+                    .cstore
+                    .impl_defaultness(node_item_def_id)
+                    .is_default()
+            }
+        }
+    }
+
+    pub fn impl_item_is_final(self, node_item: &NodeItem<hir::Defaultness>) -> bool {
+        node_item.item.is_final() && !self.impl_is_default(node_item.node.def_id())
+    }
 }
 
 pub enum TupleArgumentsFlag { Yes, No }
index 9aa2caadd1d37911acc8924f3992f65147c0d3c6..eb31dfba4a4d8e14e2ae10534dff4935cc4d2657 100644 (file)
@@ -175,7 +175,6 @@ pub fn push_item_path<T>(self, buffer: &mut T, def_id: DefId)
             data @ DefPathData::LifetimeDef(..) |
             data @ DefPathData::EnumVariant(..) |
             data @ DefPathData::Field(..) |
-            data @ DefPathData::StructCtor |
             data @ DefPathData::Initializer |
             data @ DefPathData::MacroDef(..) |
             data @ DefPathData::ClosureExpr |
@@ -186,6 +185,10 @@ pub fn push_item_path<T>(self, buffer: &mut T, def_id: DefId)
                 self.push_item_path(buffer, parent_def_id);
                 buffer.push(&data.as_interned_str());
             }
+            DefPathData::StructCtor => { // present `X` instead of `X::{{constructor}}`
+                let parent_def_id = self.parent_def_id(def_id).unwrap();
+                self.push_item_path(buffer, parent_def_id);
+            }
         }
     }
 
index 1407e57dc2a6a7e48f56b027aaa34ca24462dd8d..c80ae87d941ffa96dcc308acfc8d49c85ad364dd 100644 (file)
@@ -24,6 +24,7 @@
 use std::ops::Deref;
 use std::rc::Rc;
 use syntax_pos::{Span, DUMMY_SP};
+use syntax::symbol::Symbol;
 
 trait Key {
     fn map_crate(&self) -> CrateNum;
@@ -40,6 +41,16 @@ fn default_span(&self, tcx: TyCtxt) -> Span {
     }
 }
 
+impl<'tcx> Key for ty::Instance<'tcx> {
+    fn map_crate(&self) -> CrateNum {
+        LOCAL_CRATE
+    }
+
+    fn default_span(&self, tcx: TyCtxt) -> Span {
+        tcx.def_span(self.def_id())
+    }
+}
+
 impl Key for CrateNum {
     fn map_crate(&self) -> CrateNum {
         *self
@@ -108,13 +119,18 @@ fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
     }
 }
 
-
 impl<'tcx> Value<'tcx> for ty::DtorckConstraint<'tcx> {
     fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
         Self::empty()
     }
 }
 
+impl<'tcx> Value<'tcx> for ty::SymbolName {
+    fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
+        ty::SymbolName { name: Symbol::intern("<error>").as_str() }
+    }
+}
+
 pub struct CycleError<'a, 'tcx: 'a> {
     span: Span,
     cycle: RefMut<'a, [(Span, Query<'tcx>)]>,
@@ -242,6 +258,12 @@ fn describe(tcx: TyCtxt, (def_id, _): (DefId, &'tcx Substs<'tcx>)) -> String {
     }
 }
 
+impl<'tcx> QueryDescription for queries::symbol_name<'tcx> {
+    fn describe(_tcx: TyCtxt, instance: ty::Instance<'tcx>) -> String {
+        format!("computing the symbol for `{}`", instance)
+    }
+}
+
 macro_rules! define_maps {
     (<$tcx:tt>
      $($(#[$attr:meta])*
@@ -513,7 +535,10 @@ fn default() -> Self {
 
     pub reachable_set: reachability_dep_node(CrateNum) -> Rc<NodeSet>,
 
-    pub mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>
+    pub mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>,
+
+    pub def_symbol_name: SymbolName(DefId) -> ty::SymbolName,
+    pub symbol_name: symbol_name_dep_node(ty::Instance<'tcx>) -> ty::SymbolName
 }
 
 fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
@@ -532,6 +557,12 @@ fn mir_shim_dep_node(instance: ty::InstanceDef) -> DepNode<DefId> {
     instance.dep_node()
 }
 
+fn symbol_name_dep_node(instance: ty::Instance) -> DepNode<DefId> {
+    // symbol_name uses the substs only to traverse them to find the
+    // hash, and that does not create any new dep-nodes.
+    DepNode::SymbolName(instance.def.def_id())
+}
+
 fn typeck_item_bodies_dep_node(_: CrateNum) -> DepNode<DefId> {
     DepNode::TypeckBodiesKrate
 }
index 9a8c91f5820dcfac4377bcb540bce5eeebe138f7..de207df7d15eb0baf3aed24a42d7b84a2838843b 100644 (file)
@@ -38,6 +38,7 @@
 use std::cell::{Cell, RefCell, Ref};
 use std::collections::BTreeMap;
 use std::cmp;
+use std::fmt;
 use std::hash::{Hash, Hasher};
 use std::iter::FromIterator;
 use std::ops::Deref;
@@ -2745,3 +2746,22 @@ fn dedup<'a>(&mut self) {
         self.dtorck_types.retain(|&val| dtorck_types.replace(val).is_none());
     }
 }
+
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct SymbolName {
+    // FIXME: we don't rely on interning or equality here - better have
+    // this be a `&'tcx str`.
+    pub name: InternedString
+}
+
+impl Deref for SymbolName {
+    type Target = str;
+
+    fn deref(&self) -> &str { &self.name }
+}
+
+impl fmt::Display for SymbolName {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(&self.name, fmt)
+    }
+}
index 38e60060925e6f59c4b5df25317b59526e10cbde..e6f305c22b2d4f621a1b7ecc0c4ac2ddd8fb261a 100644 (file)
@@ -68,6 +68,8 @@ pub fn envvar() -> &'static str {
             "PATH"
         } else if cfg!(target_os = "macos") {
             "DYLD_LIBRARY_PATH"
+        } else if cfg!(target_os = "haiku") {
+            "LIBRARY_PATH"
         } else {
             "LD_LIBRARY_PATH"
         }
index bfdc9faaa8a736b37addb6b2c67868ca5cf37c63..8e7f463563c38e947d1775cde793d35cfac86aa1 100644 (file)
@@ -16,9 +16,10 @@ pub fn opts() -> TargetOptions {
         linker: "cc".to_string(),
         dynamic_linking: true,
         executables: true,
-        has_rpath: true,
+        has_rpath: false,
         target_family: Some("unix".to_string()),
         linker_is_gnu: true,
+        no_integrated_as: true,
         .. Default::default()
     }
 }
index 3678c2e55c1fdb17d0d175796e282f167f98f861..ebe2de584095461acf5e9fcdaac5734e479c3738 100644 (file)
@@ -11,6 +11,7 @@
 use borrowck::BorrowckCtxt;
 use rustc::middle::mem_categorization as mc;
 use rustc::middle::mem_categorization::Categorization;
+use rustc::middle::mem_categorization::NoteClosureEnv;
 use rustc::middle::mem_categorization::InteriorOffsetKind as Kind;
 use rustc::ty;
 use syntax::ast;
@@ -71,10 +72,12 @@ fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
         let mut err = report_cannot_move_out_of(bccx, error.move_from.clone());
         let mut is_first_note = true;
         for move_to in &error.move_to_places {
-            err = note_move_destination(err, move_to.span,
-                                  move_to.name, is_first_note);
+            err = note_move_destination(err, move_to.span, move_to.name, is_first_note);
             is_first_note = false;
         }
+        if let NoteClosureEnv(upvar_id) = error.move_from.note {
+            err.span_label(bccx.tcx.hir.span(upvar_id.var_id), &"captured outer variable");
+        }
         err.emit();
     }
 }
index 26417e3ba7cd1ef825662510bf3638cba933093c..32f0fd4199776656b52c81ba80b3568097370039 100644 (file)
@@ -113,6 +113,7 @@ pub struct flock {
             pub l_sysid: libc::c_int,
         }
 
+        pub const F_RDLCK: libc::c_short = 0x0040;
         pub const F_UNLCK: libc::c_short = 0x0200;
         pub const F_WRLCK: libc::c_short = 0x0400;
         pub const F_SETLK: libc::c_int = 0x0080;
index 438f482fa55c7bfbd90be456920f77f3edfbbbfd..dab2a0758a2176df55fce2128f6ddefc127800a8 100644 (file)
@@ -225,8 +225,6 @@ macro_rules! controller_entry_point {
         sess.code_stats.borrow().print_type_sizes();
     }
 
-    if ::std::env::var("SKIP_LLVM").is_ok() { ::std::process::exit(0); }
-
     let phase5_result = phase_5_run_llvm_passes(sess, &trans, &outputs);
 
     controller_entry_point!(after_llvm,
@@ -895,6 +893,7 @@ macro_rules! try_with_f {
     mir::provide(&mut local_providers);
     reachable::provide(&mut local_providers);
     rustc_privacy::provide(&mut local_providers);
+    trans::provide(&mut local_providers);
     typeck::provide(&mut local_providers);
     ty::provide(&mut local_providers);
     reachable::provide(&mut local_providers);
@@ -902,6 +901,7 @@ macro_rules! try_with_f {
 
     let mut extern_providers = ty::maps::Providers::default();
     cstore::provide(&mut extern_providers);
+    trans::provide(&mut extern_providers);
     ty::provide_extern(&mut extern_providers);
     // FIXME(eddyb) get rid of this once we replace const_eval with miri.
     rustc_const_eval::provide(&mut extern_providers);
index 4871f60466dfd1b8062c534254da2aeea1b637e0..3fd75146193e75e7712098c6022b5ded840be514 100644 (file)
 
 use build_helper::output;
 
-fn detect_llvm_link(llvm_config: &Path) -> (&'static str, Option<&'static str>) {
-    let mut version_cmd = Command::new(llvm_config);
-    version_cmd.arg("--version");
-    let version_output = output(&mut version_cmd);
-    let mut parts = version_output.split('.').take(2)
-        .filter_map(|s| s.parse::<u32>().ok());
-    if let (Some(major), Some(minor)) = (parts.next(), parts.next()) {
-        if major > 3 || (major == 3 && minor >= 9) {
-            // Force the link mode we want, preferring static by default, but
-            // possibly overridden by `configure --enable-llvm-link-shared`.
-            if env::var_os("LLVM_LINK_SHARED").is_some() {
-                return ("dylib", Some("--link-shared"));
-            } else {
-                return ("static", Some("--link-static"));
-            }
-        } else if major == 3 && minor == 8 {
-            // Find out LLVM's default linking mode.
-            let mut mode_cmd = Command::new(llvm_config);
-            mode_cmd.arg("--shared-mode");
-            if output(&mut mode_cmd).trim() == "shared" {
-                return ("dylib", None);
-            } else {
-                return ("static", None);
-            }
+fn detect_llvm_link(major: u32, minor: u32, llvm_config: &Path)
+    -> (&'static str, Option<&'static str>) {
+    if major > 3 || (major == 3 && minor >= 9) {
+        // Force the link mode we want, preferring static by default, but
+        // possibly overridden by `configure --enable-llvm-link-shared`.
+        if env::var_os("LLVM_LINK_SHARED").is_some() {
+            return ("dylib", Some("--link-shared"));
+        } else {
+            return ("static", Some("--link-static"));
+        }
+    } else if major == 3 && minor == 8 {
+        // Find out LLVM's default linking mode.
+        let mut mode_cmd = Command::new(llvm_config);
+        mode_cmd.arg("--shared-mode");
+        if output(&mut mode_cmd).trim() == "shared" {
+            return ("dylib", None);
+        } else {
+            return ("static", None);
         }
     }
     ("static", None)
@@ -92,9 +86,25 @@ fn main() {
     let host = env::var("HOST").expect("HOST was not set");
     let is_crossed = target != host;
 
-    let optional_components =
-        ["x86", "arm", "aarch64", "mips", "powerpc", "pnacl", "systemz", "jsbackend", "msp430",
-         "sparc", "nvptx"];
+    let mut optional_components =
+        vec!["x86", "arm", "aarch64", "mips", "powerpc", "pnacl",
+             "systemz", "jsbackend", "msp430", "sparc", "nvptx"];
+
+    let mut version_cmd = Command::new(&llvm_config);
+    version_cmd.arg("--version");
+    let version_output = output(&mut version_cmd);
+    let mut parts = version_output.split('.').take(2)
+        .filter_map(|s| s.parse::<u32>().ok());
+    let (major, minor) =
+        if let (Some(major), Some(minor)) = (parts.next(), parts.next()) {
+            (major, minor)
+        } else {
+            (3, 7)
+        };
+
+    if major > 3 {
+        optional_components.push("hexagon");
+    }
 
     // FIXME: surely we don't need all these components, right? Stuff like mcjit
     //        or interpreter the compiler itself never uses.
@@ -158,7 +168,7 @@ fn main() {
        .cpp_link_stdlib(None) // we handle this below
        .compile("librustllvm.a");
 
-    let (llvm_kind, llvm_link_arg) = detect_llvm_link(&llvm_config);
+    let (llvm_kind, llvm_link_arg) = detect_llvm_link(major, minor, &llvm_config);
 
     // Link in all LLVM libraries, if we're uwring the "wrong" llvm-config then
     // we don't pick up system libs because unfortunately they're for the host
index 7c52ceae459cdbef0fbb55f7a759c849fb85ef22..c9b3a7ff3f3aac4d1880c8610c66ef2761092d47 100644 (file)
@@ -382,6 +382,12 @@ fn init() { }
                  LLVMInitializeNVPTXTarget,
                  LLVMInitializeNVPTXTargetMC,
                  LLVMInitializeNVPTXAsmPrinter);
+    init_target!(llvm_component = "hexagon",
+                 LLVMInitializeHexagonTargetInfo,
+                 LLVMInitializeHexagonTarget,
+                 LLVMInitializeHexagonTargetMC,
+                 LLVMInitializeHexagonAsmPrinter,
+                 LLVMInitializeHexagonAsmParser);
 }
 
 pub fn last_error() -> Option<String> {
index f310279ea3c3a5cbed159dd5bf7304bb0a677fc2..ddb3332be37318d273add716e883bf15e750c022 100644 (file)
@@ -178,6 +178,12 @@ fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>
         result
     }
 
+    fn impl_defaultness(&self, def: DefId) -> hir::Defaultness
+    {
+        self.dep_graph.read(DepNode::MetaData(def));
+        self.get_crate_data(def.krate).get_impl_defaultness(def.index)
+    }
+
     fn impl_parent(&self, impl_def: DefId) -> Option<DefId> {
         self.dep_graph.read(DepNode::MetaData(impl_def));
         self.get_crate_data(impl_def.krate).get_parent_impl(impl_def.index)
index 1656d489269d0fe9cfc364d584f0d20c1df5939a..37913dad7eeb58a2cd174158f6d40281d78030cf 100644 (file)
@@ -629,6 +629,10 @@ pub fn get_impl_polarity(&self, id: DefIndex) -> hir::ImplPolarity {
         self.get_impl_data(id).polarity
     }
 
+    pub fn get_impl_defaultness(&self, id: DefIndex) -> hir::Defaultness {
+        self.get_impl_data(id).defaultness
+    }
+
     pub fn get_coerce_unsized_info(&self,
                                    id: DefIndex)
                                    -> Option<ty::adjustment::CoerceUnsizedInfo> {
index 783e7604cdaf1b424e0effa9d38b4f0a94ece427..3676e5a7f0f724d83cd9dc58971f15b219014464 100644 (file)
@@ -706,6 +706,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
             hir::ItemDefaultImpl(..) => {
                 let data = ImplData {
                     polarity: hir::ImplPolarity::Positive,
+                    defaultness: hir::Defaultness::Final,
                     parent_impl: None,
                     coerce_unsized_info: None,
                     trait_ref: tcx.impl_trait_ref(def_id).map(|trait_ref| self.lazy(&trait_ref)),
@@ -713,7 +714,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
 
                 EntryKind::DefaultImpl(self.lazy(&data))
             }
-            hir::ItemImpl(_, polarity, ..) => {
+            hir::ItemImpl(_, polarity, defaultness, ..) => {
                 let trait_ref = tcx.impl_trait_ref(def_id);
                 let parent = if let Some(trait_ref) = trait_ref {
                     let trait_def = tcx.trait_def(trait_ref.def_id);
@@ -740,6 +741,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
 
                 let data = ImplData {
                     polarity: polarity,
+                    defaultness: defaultness,
                     parent_impl: parent,
                     coerce_unsized_info: coerce_unsized_info,
                     trait_ref: trait_ref.map(|trait_ref| self.lazy(&trait_ref)),
index 2f2e0e125aea5673959122f19bd3c89d55b360b0..5870903e7718fd0820cb1341d78d9ab321abb2d4 100644 (file)
@@ -406,6 +406,7 @@ pub struct TraitData<'tcx> {
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct ImplData<'tcx> {
     pub polarity: hir::ImplPolarity,
+    pub defaultness: hir::Defaultness,
     pub parent_impl: Option<DefId>,
 
     /// This is `Some` only for impls of `CoerceUnsized`.
@@ -415,6 +416,7 @@ pub struct ImplData<'tcx> {
 
 impl_stable_hash_for!(struct ImplData<'tcx> {
     polarity,
+    defaultness,
     parent_impl,
     coerce_unsized_info,
     trait_ref
index 9e3e727d4bdcd0d2d9b68ac9851ce1fbfc0928bc..4639847651c74f41ccaedcd818ecf6a94c2d2892 100644 (file)
@@ -430,7 +430,7 @@ fn process_method(&mut self,
                             }
                             None => {
                                 if let Some(NodeItem(item)) = self.tcx.hir.get_if_local(id) {
-                                    if let hir::ItemImpl(_, _, _, _, ref ty, _) = item.node {
+                                    if let hir::ItemImpl(_, _, _, _, _, ref ty, _) = item.node {
                                         trait_id = self.lookup_def_id(ty.id);
                                     }
                                 }
index 998e392b1f9078ac78dc68e4746666e8d0309e2e..a6b0eb473eb8e106b2ec731843fdcd858945d127 100644 (file)
@@ -29,6 +29,7 @@
 use cabi_sparc64;
 use cabi_nvptx;
 use cabi_nvptx64;
+use cabi_hexagon;
 use machine::llalign_of_min;
 use type_::Type;
 use type_of;
@@ -896,6 +897,7 @@ fn adjust_for_abi(&mut self,
             "sparc64" => cabi_sparc64::compute_abi_info(ccx, self),
             "nvptx" => cabi_nvptx::compute_abi_info(ccx, self),
             "nvptx64" => cabi_nvptx64::compute_abi_info(ccx, self),
+            "hexagon" => cabi_hexagon::compute_abi_info(ccx, self),
             a => ccx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a))
         }
 
index 221c52141a8323de0193f3d2a926599df704a5b9..ddd86c4679934d79493a9d20e2755e6d0fd1b164 100644 (file)
 
 use context::SharedCrateContext;
 use monomorphize::Instance;
-use symbol_map::SymbolMap;
-use back::symbol_names::symbol_name;
 use util::nodemap::FxHashMap;
 use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
 use rustc::session::config;
 use rustc::ty::TyCtxt;
 use syntax::attr;
-use trans_item::TransItem;
 
 /// The SymbolExportLevel of a symbols specifies from which kinds of crates
 /// the symbol will be exported. `C` symbols will be exported from any
@@ -36,16 +33,13 @@ pub struct ExportedSymbols {
 }
 
 impl ExportedSymbols {
-
     pub fn empty() -> ExportedSymbols {
         ExportedSymbols {
             exports: FxHashMap(),
         }
     }
 
-    pub fn compute_from<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
-                                  symbol_map: &SymbolMap<'tcx>)
-                                  -> ExportedSymbols {
+    pub fn compute<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>) -> ExportedSymbols {
         let mut local_crate: Vec<_> = scx
             .exported_symbols()
             .iter()
@@ -53,10 +47,10 @@ pub fn compute_from<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
                 scx.tcx().hir.local_def_id(node_id)
             })
             .map(|def_id| {
-                let name = symbol_for_def_id(scx.tcx(), def_id, symbol_map);
+                let name = scx.tcx().symbol_name(Instance::mono(scx.tcx(), def_id));
                 let export_level = export_level(scx, def_id);
                 debug!("EXPORTED SYMBOL (local): {} ({:?})", name, export_level);
-                (name, export_level)
+                (str::to_owned(&name), export_level)
             })
             .collect();
 
@@ -108,7 +102,7 @@ pub fn compute_from<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
                 .exported_symbols(cnum)
                 .iter()
                 .map(|&def_id| {
-                    let name = symbol_name(Instance::mono(scx.tcx(), def_id), scx.tcx());
+                    let name = scx.tcx().symbol_name(Instance::mono(scx.tcx(), def_id));
                     let export_level = if special_runtime_crate {
                         // We can probably do better here by just ensuring that
                         // it has hidden visibility rather than public
@@ -117,9 +111,9 @@ pub fn compute_from<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
                         //
                         // In general though we won't link right if these
                         // symbols are stripped, and LTO currently strips them.
-                        if name == "rust_eh_personality" ||
-                           name == "rust_eh_register_frames" ||
-                           name == "rust_eh_unregister_frames" {
+                        if &*name == "rust_eh_personality" ||
+                           &*name == "rust_eh_register_frames" ||
+                           &*name == "rust_eh_unregister_frames" {
                             SymbolExportLevel::C
                         } else {
                             SymbolExportLevel::Rust
@@ -128,7 +122,7 @@ pub fn compute_from<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
                         export_level(scx, def_id)
                     };
                     debug!("EXPORTED SYMBOL (re-export): {} ({:?})", name, export_level);
-                    (name, export_level)
+                    (str::to_owned(&name), export_level)
                 })
                 .collect();
 
@@ -213,22 +207,3 @@ pub fn is_below_threshold(level: SymbolExportLevel,
         level == SymbolExportLevel::C
     }
 }
-
-fn symbol_for_def_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                               def_id: DefId,
-                               symbol_map: &SymbolMap<'tcx>)
-                               -> String {
-    // Just try to look things up in the symbol map. If nothing's there, we
-    // recompute.
-    if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
-        if let Some(sym) = symbol_map.get(TransItem::Static(node_id)) {
-            return sym.to_owned();
-        }
-    }
-
-    let instance = Instance::mono(tcx, def_id);
-
-    symbol_map.get(TransItem::Fn(instance))
-              .map(str::to_owned)
-              .unwrap_or_else(|| symbol_name(instance, tcx))
-}
index a96128fcf2f5305a06afb2105fd28baff96aba7b..aef9140ba4556cf9b14f927daaf13d12bbadc4a7 100644 (file)
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc::ty::fold::TypeVisitor;
 use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
+use rustc::ty::maps::Providers;
 use rustc::ty::subst::Substs;
 use rustc::hir::map::definitions::DefPathData;
 use rustc::util::common::record_time;
 
 use syntax::attr;
+use syntax_pos::symbol::Symbol;
 
 use std::fmt::Write;
 
+pub fn provide(providers: &mut Providers) {
+    *providers = Providers {
+        def_symbol_name,
+        symbol_name,
+        ..*providers
+    };
+}
+
 fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
                              // the DefId of the item this name is for
@@ -127,7 +137,7 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                              // values for generic type parameters,
                              // if any.
                              substs: Option<&'tcx Substs<'tcx>>)
-                             -> String {
+                             -> u64 {
     debug!("get_symbol_hash(def_id={:?}, parameters={:?})", def_id, substs);
 
     let mut hasher = ty::util::TypeIdHasher::<u64>::new(tcx);
@@ -162,11 +172,28 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     });
 
     // 64 bits should be enough to avoid collisions.
-    format!("h{:016x}", hasher.finish())
+    hasher.finish()
+}
+
+fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
+                             -> ty::SymbolName
+{
+    let mut buffer = SymbolPathBuffer::new();
+    item_path::with_forced_absolute_paths(|| {
+        tcx.push_item_path(&mut buffer, def_id);
+    });
+    buffer.into_interned()
 }
 
-pub fn symbol_name<'a, 'tcx>(instance: Instance<'tcx>,
-                             tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
+fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>)
+                         -> ty::SymbolName
+{
+    ty::SymbolName { name: Symbol::intern(&compute_symbol_name(tcx, instance)).as_str() }
+}
+
+fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>)
+    -> String
+{
     let def_id = instance.def_id();
     let substs = instance.substs;
 
@@ -253,11 +280,7 @@ pub fn symbol_name<'a, 'tcx>(instance: Instance<'tcx>,
 
     let hash = get_symbol_hash(tcx, Some(def_id), instance_ty, Some(substs));
 
-    let mut buffer = SymbolPathBuffer::new();
-    item_path::with_forced_absolute_paths(|| {
-        tcx.push_item_path(&mut buffer, def_id);
-    });
-    buffer.finish(&hash)
+    SymbolPathBuffer::from_interned(tcx.def_symbol_name(def_id)).finish(hash)
 }
 
 // Follow C++ namespace-mangling style, see
@@ -288,10 +311,22 @@ fn new() -> Self {
         result
     }
 
-    fn finish(mut self, hash: &str) -> String {
-        // end name-sequence
-        self.push(hash);
-        self.result.push('E');
+    fn from_interned(symbol: ty::SymbolName) -> Self {
+        let mut result = SymbolPathBuffer {
+            result: String::with_capacity(64),
+            temp_buf: String::with_capacity(16)
+        };
+        result.result.push_str(&symbol.name);
+        result
+    }
+
+    fn into_interned(self) -> ty::SymbolName {
+        ty::SymbolName { name: Symbol::intern(&self.result).as_str() }
+    }
+
+    fn finish(mut self, hash: u64) -> String {
+        // E = end name-sequence
+        let _ = write!(self.result, "17h{:016x}E", hash);
         self.result
     }
 }
@@ -320,7 +355,7 @@ pub fn exported_name_from_type_and_prefix<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let hash = get_symbol_hash(tcx, None, t, None);
     let mut buffer = SymbolPathBuffer::new();
     buffer.push(prefix);
-    buffer.finish(&hash)
+    buffer.finish(hash)
 }
 
 // Name sanitation. LLVM will happily accept identifiers with weird names, but
index e8cca7bc74f1a7d0050284ce24d21ca8760a5246..56ff5ebb069ea4a5f044a912fda677f656d726c1 100644 (file)
@@ -65,8 +65,6 @@
 use mir;
 use monomorphize::{self, Instance};
 use partitioning::{self, PartitioningStrategy, CodegenUnit};
-use symbol_cache::SymbolCache;
-use symbol_map::SymbolMap;
 use symbol_names_test;
 use trans_item::{TransItem, DefPathBasedNames};
 use type_::Type;
@@ -804,7 +802,6 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
                                  scx: &SharedCrateContext<'a, 'tcx>,
                                  translation_items: &FxHashSet<TransItem<'tcx>>,
                                  llvm_modules: &[ModuleLlvm],
-                                 symbol_map: &SymbolMap<'tcx>,
                                  exported_symbols: &ExportedSymbols) {
     let export_threshold =
         symbol_export::crates_export_threshold(&sess.crate_types.borrow());
@@ -856,7 +853,7 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
             let mut linkage_fixed_explicitly = FxHashSet();
 
             for trans_item in translation_items {
-                let symbol_name = symbol_map.get_or_compute(scx, *trans_item);
+                let symbol_name = str::to_owned(&trans_item.symbol_name(tcx));
                 if trans_item.explicit_linkage(tcx).is_some() {
                     linkage_fixed_explicitly.insert(symbol_name.clone());
                 }
@@ -1110,7 +1107,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     // Run the translation item collector and partition the collected items into
     // codegen units.
-    let (translation_items, codegen_units, symbol_map) =
+    let (translation_items, codegen_units) =
         collect_and_partition_translation_items(&shared_ccx);
 
     let mut all_stats = Stats::default();
@@ -1139,8 +1136,7 @@ fn module_translation<'a, 'tcx>(
 
         let cgu_name = String::from(cgu.name());
         let cgu_id = cgu.work_product_id();
-        let symbol_cache = SymbolCache::new(scx.tcx());
-        let symbol_name_hash = cgu.compute_symbol_name_hash(scx, &symbol_cache);
+        let symbol_name_hash = cgu.compute_symbol_name_hash(scx);
 
         // Check whether there is a previous work-product we can
         // re-use.  Not only must the file exist, and the inputs not
@@ -1175,11 +1171,11 @@ fn module_translation<'a, 'tcx>(
         }
 
         // Instantiate translation items without filling out definitions yet...
-        let lcx = LocalCrateContext::new(scx, cgu, &symbol_cache);
+        let lcx = LocalCrateContext::new(scx, cgu);
         let module = {
             let ccx = CrateContext::new(scx, &lcx);
             let trans_items = ccx.codegen_unit()
-                                 .items_in_deterministic_order(ccx.tcx(), &symbol_cache);
+                                 .items_in_deterministic_order(ccx.tcx());
             for &(trans_item, linkage) in &trans_items {
                 trans_item.predefine(&ccx, linkage);
             }
@@ -1271,8 +1267,7 @@ fn module_translation<'a, 'tcx>(
 
     let sess = shared_ccx.sess();
 
-    let exported_symbols = ExportedSymbols::compute_from(&shared_ccx,
-                                                         &symbol_map);
+    let exported_symbols = ExportedSymbols::compute(&shared_ccx);
 
     // Get the list of llvm modules we created. We'll do a few wacky
     // transforms on them now.
@@ -1292,7 +1287,6 @@ fn module_translation<'a, 'tcx>(
                             &shared_ccx,
                             &translation_items,
                             &llvm_modules,
-                            &symbol_map,
                             &exported_symbols);
     });
 
@@ -1518,10 +1512,57 @@ enum Fields<'a> {
     }
 }
 
+#[inline(never)] // give this a place in the profiler
+fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trans_items: I)
+    where I: Iterator<Item=&'a TransItem<'tcx>>
+{
+    let mut symbols: Vec<_> = trans_items.map(|trans_item| {
+        (trans_item, trans_item.symbol_name(tcx))
+    }).collect();
+
+    (&mut symbols[..]).sort_by(|&(_, ref sym1), &(_, ref sym2)|{
+        sym1.cmp(sym2)
+    });
+
+    for pair in (&symbols[..]).windows(2) {
+        let sym1 = &pair[0].1;
+        let sym2 = &pair[1].1;
+
+        if *sym1 == *sym2 {
+            let trans_item1 = pair[0].0;
+            let trans_item2 = pair[1].0;
+
+            let span1 = trans_item1.local_span(tcx);
+            let span2 = trans_item2.local_span(tcx);
+
+            // Deterministically select one of the spans for error reporting
+            let span = match (span1, span2) {
+                (Some(span1), Some(span2)) => {
+                    Some(if span1.lo.0 > span2.lo.0 {
+                        span1
+                    } else {
+                        span2
+                    })
+                }
+                (Some(span), None) |
+                (None, Some(span)) => Some(span),
+                _ => None
+            };
+
+            let error_message = format!("symbol `{}` is already defined", sym1);
+
+            if let Some(span) = span {
+                tcx.sess.span_fatal(span, &error_message)
+            } else {
+                tcx.sess.fatal(&error_message)
+            }
+        }
+    }
+}
+
 fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>)
                                                      -> (FxHashSet<TransItem<'tcx>>,
-                                                         Vec<CodegenUnit<'tcx>>,
-                                                         SymbolMap<'tcx>) {
+                                                         Vec<CodegenUnit<'tcx>>) {
     let time_passes = scx.sess().time_passes();
 
     let collection_mode = match scx.sess().opts.debugging_opts.print_trans_items {
@@ -1549,7 +1590,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
             collector::collect_crate_translation_items(&scx, collection_mode)
     });
 
-    let symbol_map = SymbolMap::build(scx, items.iter().cloned());
+    assert_symbols_are_distinct(scx.tcx(), items.iter());
 
     let strategy = if scx.sess().opts.debugging_opts.incremental.is_some() {
         PartitioningStrategy::PerModule
@@ -1622,5 +1663,5 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
         }
     }
 
-    (translation_items, codegen_units, symbol_map)
+    (translation_items, codegen_units)
 }
diff --git a/src/librustc_trans/cabi_hexagon.rs b/src/librustc_trans/cabi_hexagon.rs
new file mode 100644 (file)
index 0000000..1acda72
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2012-2013 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.
+
+#![allow(non_upper_case_globals)]
+
+use abi::{FnType, ArgType, LayoutExt};
+use context::CrateContext;
+
+fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ret: &mut ArgType<'tcx>) {
+    if ret.layout.is_aggregate() && ret.layout.size(ccx).bits() > 64 {
+        ret.make_indirect(ccx);
+    } else {
+        ret.extend_integer_width_to(32);
+    }
+}
+
+fn classify_arg_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tcx>) {
+    if arg.layout.is_aggregate() && arg.layout.size(ccx).bits() > 64 {
+        arg.make_indirect(ccx);
+    } else {
+        arg.extend_integer_width_to(32);
+    }
+}
+
+pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType<'tcx>) {
+    if !fty.ret.is_ignore() {
+        classify_ret_ty(ccx, &mut fty.ret);
+    }
+
+    for arg in &mut fty.args {
+        if arg.is_ignore() {
+            continue;
+        }
+        classify_arg_ty(ccx, arg);
+    }
+}
index 78e0a524ef2dc833b4912f9393833d78c1f9c0be..dc788dc4b48342026eab14e1611ed38b2f6dbc39 100644 (file)
@@ -23,7 +23,6 @@
 use rustc::hir::def_id::DefId;
 use rustc::ty::TypeFoldable;
 use rustc::ty::subst::Substs;
-use trans_item::TransItem;
 use type_of;
 
 /// Translates a reference to a fn/method item, monomorphizing and
@@ -50,7 +49,7 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         return llfn;
     }
 
-    let sym = ccx.symbol_cache().get(TransItem::Fn(instance));
+    let sym = tcx.symbol_name(instance);
     debug!("get_fn({:?}: {:?}) => {}", instance, fn_ty, sym);
 
     // This is subtle and surprising, but sometimes we have to bitcast
index 93ec7e11606dfa1ac9112fbae714c51d0b6876eb..77155a474aed44c253d86328bd7bda8767fd1f62 100644 (file)
@@ -880,7 +880,7 @@ fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) {
                 let parent_node_id = hir_map.get_parent_node(ii.id);
                 let is_impl_generic = match hir_map.expect_item(parent_node_id) {
                     &hir::Item {
-                        node: hir::ItemImpl(_, _, ref generics, ..),
+                        node: hir::ItemImpl(_, _, _, ref generics, ..),
                         ..
                     } => {
                         generics.is_type_parameterized()
@@ -911,6 +911,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(scx: &SharedCrateContext<'a, '
     let tcx = scx.tcx();
     match item.node {
         hir::ItemImpl(_,
+                      _,
                       _,
                       ref generics,
                       ..,
index 3d614cfbcbf3c5c5f961a0d8b5b361c2df6274e2..6afb340107d6661aa1c3a5ad517319757942f887 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-use back::symbol_names;
 use llvm;
 use llvm::{SetUnnamedAddr};
 use llvm::{ValueRef, True};
@@ -93,8 +91,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
             hir_map::NodeItem(&hir::Item {
                 ref attrs, span, node: hir::ItemStatic(..), ..
             }) => {
-                let sym = ccx.symbol_cache()
-                             .get(TransItem::Static(id));
+                let sym = TransItem::Static(id).symbol_name(ccx.tcx());
 
                 let defined_in_current_codegen_unit = ccx.codegen_unit()
                                                          .items()
@@ -113,7 +110,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
             hir_map::NodeForeignItem(&hir::ForeignItem {
                 ref attrs, span, node: hir::ForeignItemStatic(..), ..
             }) => {
-                let sym = symbol_names::symbol_name(instance, ccx.tcx());
+                let sym = ccx.tcx().symbol_name(instance);
                 let g = if let Some(name) =
                         attr::first_attr_value_str_by_name(&attrs, "linkage") {
                     // If this is a static with a linkage specified, then we need to handle
@@ -173,7 +170,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
 
         g
     } else {
-        let sym = symbol_names::symbol_name(instance, ccx.tcx());
+        let sym = ccx.tcx().symbol_name(instance);
 
         // FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
         // FIXME(nagisa): investigate whether it can be changed into define_global
index bef22cf304dcb938f962c7e58c50429617807efb..90cda2f5cad3d582378141b12184d4e5ea05b4a3 100644 (file)
@@ -29,7 +29,6 @@
 use session::config::NoDebugInfo;
 use session::Session;
 use session::config;
-use symbol_cache::SymbolCache;
 use util::nodemap::{NodeSet, DefIdMap, FxHashMap};
 
 use std::ffi::{CStr, CString};
@@ -37,6 +36,7 @@
 use std::ptr;
 use std::iter;
 use std::str;
+use std::marker::PhantomData;
 use syntax::ast;
 use syntax::symbol::InternedString;
 use syntax_pos::DUMMY_SP;
@@ -94,7 +94,6 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> {
     llcx: ContextRef,
     stats: Stats,
     codegen_unit: CodegenUnit<'tcx>,
-    needs_unwind_cleanup_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
     /// Cache instances of monomorphic and polymorphic items
     instances: RefCell<FxHashMap<Instance<'tcx>, ValueRef>>,
     /// Cache generated vtables
@@ -125,11 +124,6 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> {
     /// Mapping from static definitions to their DefId's.
     statics: RefCell<FxHashMap<ValueRef, DefId>>,
 
-    impl_method_cache: RefCell<FxHashMap<(DefId, ast::Name), DefId>>,
-
-    /// Cache of closure wrappers for bare fn's.
-    closure_bare_wrapper_cache: RefCell<FxHashMap<ValueRef, ValueRef>>,
-
     /// List of globals for static variables which need to be passed to the
     /// LLVM function ReplaceAllUsesWith (RAUW) when translation is complete.
     /// (We have to make sure we don't invalidate any ValueRefs referring
@@ -141,15 +135,11 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> {
     used_statics: RefCell<Vec<ValueRef>>,
 
     lltypes: RefCell<FxHashMap<Ty<'tcx>, Type>>,
-    llsizingtypes: RefCell<FxHashMap<Ty<'tcx>, Type>>,
     type_hashcodes: RefCell<FxHashMap<Ty<'tcx>, String>>,
     int_type: Type,
     opaque_vec_type: Type,
     str_slice_type: Type,
 
-    /// Holds the LLVM values for closure IDs.
-    closure_vals: RefCell<FxHashMap<Instance<'tcx>, ValueRef>>,
-
     dbg_cx: Option<debuginfo::CrateDebugContext<'tcx>>,
 
     eh_personality: Cell<Option<ValueRef>>,
@@ -164,7 +154,8 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> {
     /// A counter that is used for generating local symbol names
     local_gen_sym_counter: Cell<usize>,
 
-    symbol_cache: &'a SymbolCache<'a, 'tcx>,
+    /// A placeholder so we can add lifetimes
+    placeholder: PhantomData<&'a ()>,
 }
 
 /// A CrateContext value binds together one LocalCrateContext with the
@@ -366,8 +357,7 @@ pub fn use_dll_storage_attrs(&self) -> bool {
 
 impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
     pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
-               codegen_unit: CodegenUnit<'tcx>,
-               symbol_cache: &'a SymbolCache<'a, 'tcx>)
+               codegen_unit: CodegenUnit<'tcx>)
                -> LocalCrateContext<'a, 'tcx> {
         unsafe {
             // Append ".rs" to LLVM module identifier.
@@ -396,7 +386,6 @@ pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
                 llcx: llcx,
                 stats: Stats::default(),
                 codegen_unit: codegen_unit,
-                needs_unwind_cleanup_cache: RefCell::new(FxHashMap()),
                 instances: RefCell::new(FxHashMap()),
                 vtables: RefCell::new(FxHashMap()),
                 const_cstr_cache: RefCell::new(FxHashMap()),
@@ -405,17 +394,13 @@ pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
                 const_values: RefCell::new(FxHashMap()),
                 extern_const_values: RefCell::new(DefIdMap()),
                 statics: RefCell::new(FxHashMap()),
-                impl_method_cache: RefCell::new(FxHashMap()),
-                closure_bare_wrapper_cache: RefCell::new(FxHashMap()),
                 statics_to_rauw: RefCell::new(Vec::new()),
                 used_statics: RefCell::new(Vec::new()),
                 lltypes: RefCell::new(FxHashMap()),
-                llsizingtypes: RefCell::new(FxHashMap()),
                 type_hashcodes: RefCell::new(FxHashMap()),
                 int_type: Type::from_ref(ptr::null_mut()),
                 opaque_vec_type: Type::from_ref(ptr::null_mut()),
                 str_slice_type: Type::from_ref(ptr::null_mut()),
-                closure_vals: RefCell::new(FxHashMap()),
                 dbg_cx: dbg_cx,
                 eh_personality: Cell::new(None),
                 eh_unwind_resume: Cell::new(None),
@@ -423,7 +408,7 @@ pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
                 intrinsics: RefCell::new(FxHashMap()),
                 type_of_depth: Cell::new(0),
                 local_gen_sym_counter: Cell::new(0),
-                symbol_cache: symbol_cache,
+                placeholder: PhantomData,
             };
 
             let (int_type, opaque_vec_type, str_slice_ty, mut local_ccx) = {
@@ -515,10 +500,6 @@ pub fn td(&self) -> llvm::TargetDataRef {
         unsafe { llvm::LLVMRustGetModuleDataLayout(self.llmod()) }
     }
 
-    pub fn needs_unwind_cleanup_cache(&self) -> &RefCell<FxHashMap<Ty<'tcx>, bool>> {
-        &self.local().needs_unwind_cleanup_cache
-    }
-
     pub fn instances<'a>(&'a self) -> &'a RefCell<FxHashMap<Instance<'tcx>, ValueRef>> {
         &self.local().instances
     }
@@ -554,15 +535,6 @@ pub fn statics<'a>(&'a self) -> &'a RefCell<FxHashMap<ValueRef, DefId>> {
         &self.local().statics
     }
 
-    pub fn impl_method_cache<'a>(&'a self)
-            -> &'a RefCell<FxHashMap<(DefId, ast::Name), DefId>> {
-        &self.local().impl_method_cache
-    }
-
-    pub fn closure_bare_wrapper_cache<'a>(&'a self) -> &'a RefCell<FxHashMap<ValueRef, ValueRef>> {
-        &self.local().closure_bare_wrapper_cache
-    }
-
     pub fn statics_to_rauw<'a>(&'a self) -> &'a RefCell<Vec<(ValueRef, ValueRef)>> {
         &self.local().statics_to_rauw
     }
@@ -575,10 +547,6 @@ pub fn lltypes<'a>(&'a self) -> &'a RefCell<FxHashMap<Ty<'tcx>, Type>> {
         &self.local().lltypes
     }
 
-    pub fn llsizingtypes<'a>(&'a self) -> &'a RefCell<FxHashMap<Ty<'tcx>, Type>> {
-        &self.local().llsizingtypes
-    }
-
     pub fn type_hashcodes<'a>(&'a self) -> &'a RefCell<FxHashMap<Ty<'tcx>, String>> {
         &self.local().type_hashcodes
     }
@@ -599,10 +567,6 @@ pub fn str_slice_type(&self) -> Type {
         self.local().str_slice_type
     }
 
-    pub fn closure_vals<'a>(&'a self) -> &'a RefCell<FxHashMap<Instance<'tcx>, ValueRef>> {
-        &self.local().closure_vals
-    }
-
     pub fn dbg_cx<'a>(&'a self) -> &'a Option<debuginfo::CrateDebugContext<'tcx>> {
         &self.local().dbg_cx
     }
@@ -644,10 +608,6 @@ pub fn use_dll_storage_attrs(&self) -> bool {
         self.shared.use_dll_storage_attrs()
     }
 
-    pub fn symbol_cache(&self) -> &'b SymbolCache<'b, 'tcx> {
-        self.local().symbol_cache
-    }
-
     /// Given the def-id of some item that has no type parameters, make
     /// a suitable "empty substs" for it.
     pub fn empty_substs_for_def_id(&self, item_def_id: DefId) -> &'tcx Substs<'tcx> {
index 117d8568500b8a61176374b31d56aa5cc49d64b5..111c2547721663decc75b17ae753e0576c5c204f 100644 (file)
@@ -67,6 +67,7 @@
 pub use rustc::util;
 
 pub use base::trans_crate;
+pub use back::symbol_names::provide;
 
 pub mod back {
     pub use rustc::hir::svh;
@@ -97,6 +98,7 @@ pub mod back {
 mod cabi_aarch64;
 mod cabi_arm;
 mod cabi_asmjs;
+mod cabi_hexagon;
 mod cabi_mips;
 mod cabi_mips64;
 mod cabi_msp430;
@@ -124,8 +126,6 @@ pub mod back {
 mod mir;
 mod monomorphize;
 mod partitioning;
-mod symbol_cache;
-mod symbol_map;
 mod symbol_names_test;
 mod trans_item;
 mod tvec;
index 6b89d11cfb68f161e9356ba6934a46e943f306bc..2c76cdeb48cdf7cda90d2699399560d1f5a19057 100644 (file)
 use rustc::ty::{self, TyCtxt};
 use rustc::ty::item_path::characteristic_def_id_of_type;
 use rustc_incremental::IchHasher;
-use std::cmp::Ordering;
 use std::hash::Hash;
 use std::sync::Arc;
-use symbol_cache::SymbolCache;
 use syntax::ast::NodeId;
 use syntax::symbol::{Symbol, InternedString};
 use trans_item::{TransItem, InstantiationMode};
@@ -175,14 +173,13 @@ pub fn work_product_dep_node(&self) -> DepNode<DefId> {
     }
 
     pub fn compute_symbol_name_hash<'a>(&self,
-                                        scx: &SharedCrateContext<'a, 'tcx>,
-                                        symbol_cache: &SymbolCache<'a, 'tcx>)
+                                        scx: &SharedCrateContext<'a, 'tcx>)
                                         -> u64 {
         let mut state = IchHasher::new();
         let exported_symbols = scx.exported_symbols();
-        let all_items = self.items_in_deterministic_order(scx.tcx(), symbol_cache);
+        let all_items = self.items_in_deterministic_order(scx.tcx());
         for (item, _) in all_items {
-            let symbol_name = symbol_cache.get(item);
+            let symbol_name = item.symbol_name(scx.tcx());
             symbol_name.len().hash(&mut state);
             symbol_name.hash(&mut state);
             let exported = match item {
@@ -203,53 +200,30 @@ pub fn compute_symbol_name_hash<'a>(&self,
     }
 
     pub fn items_in_deterministic_order<'a>(&self,
-                                            tcx: TyCtxt,
-                                            symbol_cache: &SymbolCache<'a, 'tcx>)
+                                            tcx: TyCtxt<'a, 'tcx, 'tcx>)
                                             -> Vec<(TransItem<'tcx>, llvm::Linkage)> {
-        let mut items: Vec<(TransItem<'tcx>, llvm::Linkage)> =
-            self.items.iter().map(|(item, linkage)| (*item, *linkage)).collect();
-
         // The codegen tests rely on items being process in the same order as
         // they appear in the file, so for local items, we sort by node_id first
-        items.sort_by(|&(trans_item1, _), &(trans_item2, _)| {
-            let node_id1 = local_node_id(tcx, trans_item1);
-            let node_id2 = local_node_id(tcx, trans_item2);
-
-            match (node_id1, node_id2) {
-                (None, None) => {
-                    let symbol_name1 = symbol_cache.get(trans_item1);
-                    let symbol_name2 = symbol_cache.get(trans_item2);
-                    symbol_name1.cmp(&symbol_name2)
-                }
-                // In the following two cases we can avoid looking up the symbol
-                (None, Some(_)) => Ordering::Less,
-                (Some(_), None) => Ordering::Greater,
-                (Some(node_id1), Some(node_id2)) => {
-                    let ordering = node_id1.cmp(&node_id2);
-
-                    if ordering != Ordering::Equal {
-                        return ordering;
-                    }
-
-                    let symbol_name1 = symbol_cache.get(trans_item1);
-                    let symbol_name2 = symbol_cache.get(trans_item2);
-                    symbol_name1.cmp(&symbol_name2)
-                }
-            }
-        });
-
-        return items;
+        #[derive(PartialEq, Eq, PartialOrd, Ord)]
+        pub struct ItemSortKey(Option<NodeId>, ty::SymbolName);
 
-        fn local_node_id(tcx: TyCtxt, trans_item: TransItem) -> Option<NodeId> {
-            match trans_item {
+        fn item_sort_key<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                   item: TransItem<'tcx>) -> ItemSortKey {
+            ItemSortKey(match item {
                 TransItem::Fn(instance) => {
                     tcx.hir.as_local_node_id(instance.def_id())
                 }
                 TransItem::Static(node_id) | TransItem::GlobalAsm(node_id) => {
                     Some(node_id)
                 }
-            }
+            }, item.symbol_name(tcx))
         }
+
+        let items: Vec<_> = self.items.iter().map(|(&i, &l)| (i, l)).collect();
+        let mut items : Vec<_> = items.iter()
+            .map(|il| (il, item_sort_key(tcx, il.0))).collect();
+        items.sort_by(|&(_, ref key1), &(_, ref key2)| key1.cmp(key2));
+        items.into_iter().map(|(&item_linkage, _)| item_linkage).collect()
     }
 }
 
@@ -537,12 +511,11 @@ fn debug_dump<'a, 'b, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 {
     if cfg!(debug_assertions) {
         debug!("{}", label);
-        let symbol_cache = SymbolCache::new(tcx);
         for cgu in cgus {
             debug!("CodegenUnit {}:", cgu.name);
 
             for (trans_item, linkage) in &cgu.items {
-                let symbol_name = symbol_cache.get(*trans_item);
+                let symbol_name = trans_item.symbol_name(tcx);
                 let symbol_hash_start = symbol_name.rfind('h');
                 let symbol_hash = symbol_hash_start.map(|i| &symbol_name[i ..])
                                                    .unwrap_or("<no hash>");
diff --git a/src/librustc_trans/symbol_cache.rs b/src/librustc_trans/symbol_cache.rs
deleted file mode 100644 (file)
index ddc1ef5..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// 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 rustc::ty::TyCtxt;
-use std::cell::RefCell;
-use syntax_pos::symbol::{InternedString, Symbol};
-use trans_item::TransItem;
-use util::nodemap::FxHashMap;
-
-// In the SymbolCache we collect the symbol names of translation items
-// and cache them for later reference. This is just a performance
-// optimization and the cache is populated lazilly; symbol names of
-// translation items are deterministic and fully defined by the item.
-// Thus they can always be recomputed if needed.
-
-pub struct SymbolCache<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    index: RefCell<FxHashMap<TransItem<'tcx>, Symbol>>,
-}
-
-impl<'a, 'tcx> SymbolCache<'a, 'tcx> {
-    pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
-        SymbolCache {
-            tcx: tcx,
-            index: RefCell::new(FxHashMap())
-        }
-    }
-
-    pub fn get(&self, trans_item: TransItem<'tcx>) -> InternedString {
-        let mut index = self.index.borrow_mut();
-        index.entry(trans_item)
-             .or_insert_with(|| Symbol::intern(&trans_item.compute_symbol_name(self.tcx)))
-             .as_str()
-    }
-}
diff --git a/src/librustc_trans/symbol_map.rs b/src/librustc_trans/symbol_map.rs
deleted file mode 100644 (file)
index 9d3e628..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-// 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 context::SharedCrateContext;
-use monomorphize::Instance;
-use rustc::ty::TyCtxt;
-use std::borrow::Cow;
-use syntax::codemap::Span;
-use trans_item::TransItem;
-use util::nodemap::FxHashMap;
-
-// In the SymbolMap we collect the symbol names of all translation items of
-// the current crate. This map exists as a performance optimization. Symbol
-// names of translation items are deterministic and fully defined by the item.
-// Thus they could also always be recomputed if needed.
-
-pub struct SymbolMap<'tcx> {
-    index: FxHashMap<TransItem<'tcx>, (usize, usize)>,
-    arena: String,
-}
-
-impl<'tcx> SymbolMap<'tcx> {
-
-    pub fn build<'a, I>(scx: &SharedCrateContext<'a, 'tcx>,
-                        trans_items: I)
-                        -> SymbolMap<'tcx>
-        where I: Iterator<Item=TransItem<'tcx>>
-    {
-        // Check for duplicate symbol names
-        let tcx = scx.tcx();
-        let mut symbols: Vec<_> = trans_items.map(|trans_item| {
-            (trans_item, trans_item.compute_symbol_name(tcx))
-        }).collect();
-
-        (&mut symbols[..]).sort_by(|&(_, ref sym1), &(_, ref sym2)|{
-            sym1.cmp(sym2)
-        });
-
-        for pair in (&symbols[..]).windows(2) {
-            let sym1 = &pair[0].1;
-            let sym2 = &pair[1].1;
-
-            if *sym1 == *sym2 {
-                let trans_item1 = pair[0].0;
-                let trans_item2 = pair[1].0;
-
-                let span1 = get_span(scx.tcx(), trans_item1);
-                let span2 = get_span(scx.tcx(), trans_item2);
-
-                // Deterministically select one of the spans for error reporting
-                let span = match (span1, span2) {
-                    (Some(span1), Some(span2)) => {
-                        Some(if span1.lo.0 > span2.lo.0 {
-                            span1
-                        } else {
-                            span2
-                        })
-                    }
-                    (Some(span), None) |
-                    (None, Some(span)) => Some(span),
-                    _ => None
-                };
-
-                let error_message = format!("symbol `{}` is already defined", sym1);
-
-                if let Some(span) = span {
-                    scx.sess().span_fatal(span, &error_message)
-                } else {
-                    scx.sess().fatal(&error_message)
-                }
-            }
-        }
-
-        let mut symbol_map = SymbolMap {
-            index: FxHashMap(),
-            arena: String::with_capacity(1024),
-        };
-
-        for (trans_item, symbol) in symbols {
-            let start_index = symbol_map.arena.len();
-            symbol_map.arena.push_str(&symbol[..]);
-            let end_index = symbol_map.arena.len();
-            let prev_entry = symbol_map.index.insert(trans_item,
-                                                     (start_index, end_index));
-            if prev_entry.is_some() {
-                bug!("TransItem encountered twice?")
-            }
-        }
-
-        fn get_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                              trans_item: TransItem<'tcx>) -> Option<Span> {
-            match trans_item {
-                TransItem::Fn(Instance { def, .. }) => {
-                    tcx.hir.as_local_node_id(def.def_id())
-                }
-                TransItem::Static(node_id) |
-                TransItem::GlobalAsm(node_id) => {
-                    Some(node_id)
-                }
-            }.map(|node_id| {
-                tcx.hir.span(node_id)
-            })
-        }
-
-        symbol_map
-    }
-
-    pub fn get(&self, trans_item: TransItem<'tcx>) -> Option<&str> {
-        self.index.get(&trans_item).map(|&(start_index, end_index)| {
-            &self.arena[start_index .. end_index]
-        })
-    }
-
-    pub fn get_or_compute<'map, 'scx>(&'map self,
-                                      scx: &SharedCrateContext<'scx, 'tcx>,
-                                      trans_item: TransItem<'tcx>)
-                                      -> Cow<'map, str> {
-        if let Some(sym) = self.get(trans_item) {
-            Cow::from(sym)
-        } else {
-            Cow::from(trans_item.compute_symbol_name(scx.tcx()))
-        }
-    }
-}
index fd817cb94c1c1db1251d73e7ea84c6832a300d47..d96757be9f3a5e046f9ba0f1522e4d36bfe7e879 100644 (file)
@@ -14,7 +14,6 @@
 //! item-path. This is used for unit testing the code that generates
 //! paths etc in all kinds of annoying scenarios.
 
-use back::symbol_names;
 use rustc::hir;
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::ty::TyCtxt;
@@ -52,7 +51,7 @@ fn process_attrs(&mut self,
             if attr.check_name(SYMBOL_NAME) {
                 // for now, can only use on monomorphic names
                 let instance = Instance::mono(tcx, def_id);
-                let name = symbol_names::symbol_name(instance, self.tcx);
+                let name = self.tcx.symbol_name(instance);
                 tcx.sess.span_err(attr.span, &format!("symbol-name({})", name));
             } else if attr.check_name(ITEM_PATH) {
                 let path = tcx.item_path_str(def_id);
index d8e139dc505b6129764db5f8990224352f5058f6..392ee71d52b44c751d44523928293f9549aa53fb 100644 (file)
@@ -30,8 +30,9 @@
 use rustc::ty::subst::Substs;
 use syntax::ast::{self, NodeId};
 use syntax::attr;
+use syntax_pos::Span;
+use syntax_pos::symbol::Symbol;
 use type_of;
-use back::symbol_names;
 use std::fmt::Write;
 use std::iter;
 
@@ -118,7 +119,7 @@ pub fn predefine(&self,
                self.to_raw_string(),
                ccx.codegen_unit().name());
 
-        let symbol_name = ccx.symbol_cache().get(*self);
+        let symbol_name = self.symbol_name(ccx.tcx());
 
         debug!("symbol {}", &symbol_name);
 
@@ -184,20 +185,34 @@ fn predefine_fn(ccx: &CrateContext<'a, 'tcx>,
         ccx.instances().borrow_mut().insert(instance, lldecl);
     }
 
-    pub fn compute_symbol_name(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
+    pub fn symbol_name(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::SymbolName {
         match *self {
-            TransItem::Fn(instance) => symbol_names::symbol_name(instance, tcx),
+            TransItem::Fn(instance) => tcx.symbol_name(instance),
             TransItem::Static(node_id) => {
                 let def_id = tcx.hir.local_def_id(node_id);
-                symbol_names::symbol_name(Instance::mono(tcx, def_id), tcx)
+                tcx.symbol_name(Instance::mono(tcx, def_id))
             }
             TransItem::GlobalAsm(node_id) => {
                 let def_id = tcx.hir.local_def_id(node_id);
-                format!("global_asm_{:?}", def_id)
+                ty::SymbolName {
+                    name: Symbol::intern(&format!("global_asm_{:?}", def_id)).as_str()
+                }
             }
         }
     }
 
+    pub fn local_span(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<Span> {
+        match *self {
+            TransItem::Fn(Instance { def, .. }) => {
+                tcx.hir.as_local_node_id(def.def_id())
+            }
+            TransItem::Static(node_id) |
+            TransItem::GlobalAsm(node_id) => {
+                Some(node_id)
+            }
+        }.map(|node_id| tcx.hir.span(node_id))
+    }
+
     pub fn instantiation_mode(&self,
                               tcx: TyCtxt<'a, 'tcx, 'tcx>)
                               -> InstantiationMode {
index 1c0c68ae7d7cb14998795c08a98944393c66010c..fe003f3f24230acbea01fd04a876a49a17808cf1 100644 (file)
@@ -1141,7 +1141,7 @@ fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         .map(|node_item| node_item.map(|parent| parent.defaultness));
 
     if let Some(parent) = parent {
-        if parent.item.is_final() {
+        if tcx.impl_item_is_final(&parent) {
             report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
         }
     }
index 5bb45cbb1ae8ae3472edeefa124157ea181bdb3b..503212f2c970e24d105a3e712e9e8b3746d7745e 100644 (file)
@@ -105,11 +105,11 @@ fn check_item_well_formed(&mut self, item: &hir::Item) {
             ///
             /// won't be allowed unless there's an *explicit* implementation of `Send`
             /// for `T`
-            hir::ItemImpl(_, hir::ImplPolarity::Positive, _,
+            hir::ItemImpl(_, hir::ImplPolarity::Positive, _, _,
                           ref trait_ref, ref self_ty, _) => {
                 self.check_impl(item, self_ty, trait_ref);
             }
-            hir::ItemImpl(_, hir::ImplPolarity::Negative, _, Some(_), ..) => {
+            hir::ItemImpl(_, hir::ImplPolarity::Negative, _, _, Some(_), ..) => {
                 // FIXME(#27579) what amount of WF checking do we need for neg impls?
 
                 let trait_ref = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id)).unwrap();
index 4463cff9c503f50161fa0b0b52d710c24d1fca06..4672975d056b8679c897a079f4e0d8a7f283146f 100644 (file)
@@ -87,7 +87,7 @@ fn visit_item(&mut self, item: &'v hir::Item) {
             hir::ItemDefaultImpl(unsafety, _) => {
                 self.check_unsafety_coherence(item, None, unsafety, hir::ImplPolarity::Positive);
             }
-            hir::ItemImpl(unsafety, polarity, ref generics, Some(_), _, _) => {
+            hir::ItemImpl(unsafety, polarity, _, ref generics, ..) => {
                 self.check_unsafety_coherence(item, Some(generics), unsafety, polarity);
             }
             _ => {}
index 099586e6bcc2a5b9482ab198b8f7ff254a626b0b..3cd8b8bd48914891539049aa377399a9fad2da28 100644 (file)
@@ -309,7 +309,7 @@ fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         NodeItem(item) => {
             match item.node {
                 ItemFn(.., ref generics, _) |
-                ItemImpl(_, _, ref generics, ..) |
+                ItemImpl(_, _, _, ref generics, ..) |
                 ItemTy(_, ref generics) |
                 ItemEnum(_, ref generics) |
                 ItemStruct(_, ref generics) |
@@ -825,7 +825,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         NodeItem(item) => {
             match item.node {
                 ItemFn(.., ref generics, _) |
-                ItemImpl(_, _, ref generics, ..) => generics,
+                ItemImpl(_, _, _, ref generics, ..) => generics,
 
                 ItemTy(_, ref generics) |
                 ItemEnum(_, ref generics) |
@@ -1236,7 +1236,7 @@ fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         NodeItem(item) => {
             match item.node {
                 ItemFn(.., ref generics, _) |
-                ItemImpl(_, _, ref generics, ..) |
+                ItemImpl(_, _, _, ref generics, ..) |
                 ItemTy(_, ref generics) |
                 ItemEnum(_, ref generics) |
                 ItemStruct(_, ref generics) |
index d819268240badca941579c315ac882df1194bcd0..71594825cdb01215c8ab5fdcbd2a0a74a526c9fa 100644 (file)
@@ -214,6 +214,7 @@ pub struct Trait {
 pub struct Impl {
     pub unsafety: hir::Unsafety,
     pub polarity: hir::ImplPolarity,
+    pub defaultness: hir::Defaultness,
     pub generics: hir::Generics,
     pub trait_: Option<hir::TraitRef>,
     pub for_: P<hir::Ty>,
index 4252f2981ed6193e1ba5d59166c7c7eea0b037ab..d463e41c58a2a3281206510a116a8d29687ed4e5 100644 (file)
@@ -502,7 +502,13 @@ pub fn visit_item(&mut self, item: &hir::Item,
                 om.traits.push(t);
             },
 
-            hir::ItemImpl(unsafety, polarity, ref gen, ref tr, ref ty, ref item_ids) => {
+            hir::ItemImpl(unsafety,
+                          polarity,
+                          defaultness,
+                          ref gen,
+                          ref tr,
+                          ref ty,
+                          ref item_ids) => {
                 // Don't duplicate impls when inlining, we'll pick them up
                 // regardless of where they're located.
                 if !self.inlining {
@@ -512,6 +518,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
                     let i = Impl {
                         unsafety: unsafety,
                         polarity: polarity,
+                        defaultness: defaultness,
                         generics: gen.clone(),
                         trait_: tr.clone(),
                         for_: ty.clone(),
index bc315d54100e42d1048a90baa96d64cda64d2722..34229f80769aba8108f10553346af51b271cab35 100644 (file)
 ///
 /// # Examples
 ///
-/// ```no_run
+/// ```
+/// # use std::io;
 /// use std::net::{TcpListener, TcpStream};
 ///
-/// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
-///
 /// fn handle_client(stream: TcpStream) {
 ///     // ...
 /// }
 ///
+/// # fn process() -> io::Result<()> {
+/// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
+///
 /// // accept connections and process them serially
 /// for stream in listener.incoming() {
-///     match stream {
-///         Ok(stream) => {
-///             handle_client(stream);
-///         }
-///         Err(e) => { /* connection failed */ }
-///     }
+///     handle_client(stream?);
 /// }
+/// # Ok(())
+/// # }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct TcpListener(net_imp::TcpListener);
@@ -177,6 +176,13 @@ pub fn local_addr(&self) -> io::Result<SocketAddr> {
     ///
     /// [`Shutdown`]: ../../std/net/enum.Shutdown.html
     ///
+    /// # Platform-specific behavior
+    ///
+    /// Calling this function multiple times may result in different behavior,
+    /// depending on the operating system. On Linux, the second call will
+    /// return `Ok(())`, but on macOS, it will return `ErrorKind::NotConnected`.
+    /// This may change in the future.
+    ///
     /// # Examples
     ///
     /// ```no_run
index 6c8839224f77dafb5f00f039ec22b18a09f50d5c..2cb649ce67b9c0c1cc8e26b8d5b5d8c533a12680 100644 (file)
 mod mpsc_queue;
 mod spsc_queue;
 
-/// The receiving-half of Rust's channel type. This half can only be owned by
-/// one thread.
+/// The receiving half of Rust's [`channel`][] (or [`sync_channel`]) type.
+/// This half can only be owned by one thread.
 ///
 /// Messages sent to the channel can be retrieved using [`recv`].
 ///
-/// [`recv`]: ../../../std/sync/mpsc/struct.Receiver.html#method.recv
+/// [`channel`]: fn.channel.html
+/// [`sync_channel`]: fn.sync_channel.html
+/// [`recv`]: struct.Receiver.html#method.recv
 ///
 /// # Examples
 ///
@@ -336,51 +338,128 @@ unsafe impl<T: Send> Send for Receiver<T> { }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> !Sync for Receiver<T> { }
 
-/// An iterator over messages on a receiver, this iterator will block whenever
-/// [`next`] is called, waiting for a new message, and [`None`] will be returned
+/// An iterator over messages on a [`Receiver`], created by [`iter`].
+///
+/// This iterator will block whenever [`next`] is called,
+/// waiting for a new message, and [`None`] will be returned
 /// when the corresponding channel has hung up.
 ///
+/// [`iter`]: struct.Receiver.html#method.iter
+/// [`Receiver`]: struct.Receiver.html
 /// [`next`]: ../../../std/iter/trait.Iterator.html#tymethod.next
 /// [`None`]: ../../../std/option/enum.Option.html#variant.None
+///
+/// # Examples
+///
+/// ```rust
+/// use std::sync::mpsc::channel;
+/// use std::thread;
+///
+/// let (send, recv) = channel();
+///
+/// thread::spawn(move || {
+///     send.send(1u8).unwrap();
+///     send.send(2u8).unwrap();
+///     send.send(3u8).unwrap();
+/// });
+///
+/// for x in recv.iter() {
+///     println!("Got: {}", x);
+/// }
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct Iter<'a, T: 'a> {
     rx: &'a Receiver<T>
 }
 
-/// An iterator that attempts to yield all pending values for a receiver.
-/// [`None`] will be returned when there are no pending values remaining or if
-/// the corresponding channel has hung up.
+/// An iterator that attempts to yield all pending values for a [`Receiver`],
+/// created by [`try_iter`].
+///
+/// [`None`] will be returned when there are no pending values remaining or
+/// if the corresponding channel has hung up.
 ///
-/// This Iterator will never block the caller in order to wait for data to
+/// This iterator will never block the caller in order to wait for data to
 /// become available. Instead, it will return [`None`].
 ///
+/// [`Receiver`]: struct.Receiver.html
+/// [`try_iter`]: struct.Receiver.html#method.try_iter
 /// [`None`]: ../../../std/option/enum.Option.html#variant.None
+///
+/// # Examples
+///
+/// ```rust
+/// use std::sync::mpsc::channel;
+/// use std::thread;
+/// use std::time::Duration;
+///
+/// let (sender, receiver) = channel();
+///
+/// // Nothing is in the buffer yet
+/// assert!(receiver.try_iter().next().is_none());
+/// println!("Nothing in the buffer...");
+///
+/// thread::spawn(move || {
+///     sender.send(1).unwrap();
+///     sender.send(2).unwrap();
+///     sender.send(3).unwrap();
+/// });
+///
+/// println!("Going to sleep...");
+/// thread::sleep(Duration::from_secs(2)); // block for two seconds
+///
+/// for x in receiver.try_iter() {
+///     println!("Got: {}", x);
+/// }
+/// ```
 #[stable(feature = "receiver_try_iter", since = "1.15.0")]
 #[derive(Debug)]
 pub struct TryIter<'a, T: 'a> {
     rx: &'a Receiver<T>
 }
 
-/// An owning iterator over messages on a receiver, this iterator will block
-/// whenever [`next`] is called, waiting for a new message, and [`None`] will be
-/// returned when the corresponding channel has hung up.
+/// An owning iterator over messages on a [`Receiver`],
+/// created by **Receiver::into_iter**.
+///
+/// This iterator will block whenever [`next`]
+/// is called, waiting for a new message, and [`None`] will be
+/// returned if the corresponding channel has hung up.
 ///
+/// [`Receiver`]: struct.Receiver.html
 /// [`next`]: ../../../std/iter/trait.Iterator.html#tymethod.next
 /// [`None`]: ../../../std/option/enum.Option.html#variant.None
 ///
+/// # Examples
+///
+/// ```rust
+/// use std::sync::mpsc::channel;
+/// use std::thread;
+///
+/// let (send, recv) = channel();
+///
+/// thread::spawn(move || {
+///     send.send(1u8).unwrap();
+///     send.send(2u8).unwrap();
+///     send.send(3u8).unwrap();
+/// });
+///
+/// for x in recv.into_iter() {
+///     println!("Got: {}", x);
+/// }
+/// ```
 #[stable(feature = "receiver_into_iter", since = "1.1.0")]
 #[derive(Debug)]
 pub struct IntoIter<T> {
     rx: Receiver<T>
 }
 
-/// The sending-half of Rust's asynchronous channel type. This half can only be
+/// The sending-half of Rust's asynchronous [`channel`] type. This half can only be
 /// owned by one thread, but it can be cloned to send to other threads.
 ///
 /// Messages can be sent through this channel with [`send`].
 ///
-/// [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send
+/// [`channel`]: fn.channel.html
+/// [`send`]: struct.Sender.html#method.send
 ///
 /// # Examples
 ///
@@ -419,12 +498,55 @@ unsafe impl<T: Send> Send for Sender<T> { }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> !Sync for Sender<T> { }
 
-/// The sending-half of Rust's synchronous channel type. This half can only be
-/// owned by one thread, but it can be cloned to send to other threads.
+/// The sending-half of Rust's synchronous [`sync_channel`] type.
+/// This half can only be owned by one thread, but it can be cloned
+/// to send to other threads.
+///
+/// Messages can be sent through this channel with [`send`] or [`try_send`].
+///
+/// [`send`] will block if there is no space in the internal buffer.
+///
+/// [`sync_channel`]: fn.sync_channel.html
+/// [`send`]: struct.SyncSender.html#method.send
+/// [`try_send`]: struct.SyncSender.html#method.try_send
+///
+/// # Examples
+///
+/// ```rust
+/// use std::sync::mpsc::sync_channel;
+/// use std::thread;
 ///
-/// [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send
-/// [`SyncSender::send`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.send
+/// // Create a sync_channel with buffer size 2
+/// let (sync_sender, receiver) = sync_channel(2);
+/// let sync_sender2 = sync_sender.clone();
 ///
+/// // First thread owns sync_sender
+/// thread::spawn(move || {
+///     sync_sender.send(1).unwrap();
+///     sync_sender.send(2).unwrap();
+/// });
+///
+/// // Second thread owns sync_sender2
+/// thread::spawn(move || {
+///     sync_sender2.send(3).unwrap();
+///     // thread will now block since the buffer is full
+///     println!("Thread unblocked!");
+/// });
+///
+/// let mut msg;
+///
+/// msg = receiver.recv().unwrap();
+/// println!("message {} received", msg);
+///
+/// // "Thread unblocked!" will be printed now
+///
+/// msg = receiver.recv().unwrap();
+/// println!("message {} received", msg);
+///
+/// msg = receiver.recv().unwrap();
+///
+/// println!("message {} received", msg);
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct SyncSender<T> {
     inner: Arc<sync::Packet<T>>,
@@ -823,8 +945,9 @@ fn new(inner: Arc<sync::Packet<T>>) -> SyncSender<T> {
     /// Note that a successful send does *not* guarantee that the receiver will
     /// ever see the data if there is a buffer on this channel. Items may be
     /// enqueued in the internal buffer for the receiver to receive at a later
-    /// time. If the buffer size is 0, however, it can be guaranteed that the
-    /// receiver has indeed received the data if this function returns success.
+    /// time. If the buffer size is 0, however, the channel becomes a rendezvous
+    /// channel and it guarantees that the receiver has indeed received
+    /// the data if this function returns success.
     ///
     /// This function will never panic, but it may return [`Err`] if the
     /// [`Receiver`] has disconnected and is no longer able to receive
@@ -832,6 +955,27 @@ fn new(inner: Arc<sync::Packet<T>>) -> SyncSender<T> {
     ///
     /// [`Err`]: ../../../std/result/enum.Result.html#variant.Err
     /// [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::sync::mpsc::sync_channel;
+    /// use std::thread;
+    ///
+    /// // Create a rendezvous sync_channel with buffer size 0
+    /// let (sync_sender, receiver) = sync_channel(0);
+    ///
+    /// thread::spawn(move || {
+    ///    println!("sending message...");
+    ///    sync_sender.send(1).unwrap();
+    ///    // Thread is now blocked until the message is received
+    ///
+    ///    println!("...message received!");
+    /// });
+    ///
+    /// let msg = receiver.recv().unwrap();
+    /// assert_eq!(1, msg);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn send(&self, t: T) -> Result<(), SendError<T>> {
         self.inner.send(t).map_err(SendError)
@@ -844,11 +988,48 @@ pub fn send(&self, t: T) -> Result<(), SendError<T>> {
     /// data. Compared with [`send`], this function has two failure cases
     /// instead of one (one for disconnection, one for a full buffer).
     ///
-    /// See [`SyncSender::send`] for notes about guarantees of whether the
+    /// See [`send`] for notes about guarantees of whether the
     /// receiver has received the data or not if this function is successful.
     ///
-    /// [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send
-    /// [`SyncSender::send`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.send
+    /// [`send`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.send
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::sync::mpsc::sync_channel;
+    /// use std::thread;
+    ///
+    /// // Create a sync_channel with buffer size 1
+    /// let (sync_sender, receiver) = sync_channel(1);
+    /// let sync_sender2 = sync_sender.clone();
+    ///
+    /// // First thread owns sync_sender
+    /// thread::spawn(move || {
+    ///     sync_sender.send(1).unwrap();
+    ///     sync_sender.send(2).unwrap();
+    ///     // Thread blocked
+    /// });
+    ///
+    /// // Second thread owns sync_sender2
+    /// thread::spawn(move || {
+    ///     // This will return an error and send
+    ///     // no message if the buffer is full
+    ///     sync_sender2.try_send(3).is_err();
+    /// });
+    ///
+    /// let mut msg;
+    /// msg = receiver.recv().unwrap();
+    /// println!("message {} received", msg);
+    ///
+    /// msg = receiver.recv().unwrap();
+    /// println!("message {} received", msg);
+    ///
+    /// // Third message may have never been sent
+    /// match receiver.try_recv() {
+    ///     Ok(msg) => println!("message {} received", msg),
+    ///     Err(_) => println!("the third message was never sent"),
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> {
         self.inner.try_send(t)
@@ -894,6 +1075,21 @@ fn new(inner: Flavor<T>) -> Receiver<T> {
     ///
     /// This is useful for a flavor of "optimistic check" before deciding to
     /// block on a receiver.
+    ///
+    /// Compared with [`recv`], this function has two failure cases instead of one
+    /// (one for disconnection, one for an empty buffer).
+    ///
+    /// [`recv`]: struct.Receiver.html#method.recv
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::sync::mpsc::{Receiver, channel};
+    ///
+    /// let (_, receiver): (_, Receiver<i32>) = channel();
+    ///
+    /// assert!(receiver.try_recv().is_err());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_recv(&self) -> Result<T, TryRecvError> {
         loop {
@@ -949,8 +1145,8 @@ pub fn try_recv(&self) -> Result<T, TryRecvError> {
     ///
     /// This function will always block the current thread if there is no data
     /// available and it's possible for more data to be sent. Once a message is
-    /// sent to the corresponding [`Sender`], then this receiver will wake up and
-    /// return that message.
+    /// sent to the corresponding [`Sender`][] (or [`SyncSender`]), then this
+    /// receiver will wake up and return that message.
     ///
     /// If the corresponding [`Sender`] has disconnected, or it disconnects while
     /// this call is blocking, this call will wake up and return [`Err`] to
@@ -958,7 +1154,8 @@ pub fn try_recv(&self) -> Result<T, TryRecvError> {
     /// However, since channels are buffered, messages sent before the disconnect
     /// will still be properly received.
     ///
-    /// [`Sender`]: ../../../std/sync/mpsc/struct.Sender.html
+    /// [`Sender`]: struct.Sender.html
+    /// [`SyncSender`]: struct.SyncSender.html
     /// [`Err`]: ../../../std/result/enum.Result.html#variant.Err
     ///
     /// # Examples
@@ -1040,8 +1237,8 @@ pub fn recv(&self) -> Result<T, RecvError> {
     ///
     /// This function will always block the current thread if there is no data
     /// available and it's possible for more data to be sent. Once a message is
-    /// sent to the corresponding [`Sender`], then this receiver will wake up and
-    /// return that message.
+    /// sent to the corresponding [`Sender`][] (or [`SyncSender`]), then this
+    /// receiver will wake up and return that message.
     ///
     /// If the corresponding [`Sender`] has disconnected, or it disconnects while
     /// this call is blocking, this call will wake up and return [`Err`] to
@@ -1049,7 +1246,8 @@ pub fn recv(&self) -> Result<T, RecvError> {
     /// However, since channels are buffered, messages sent before the disconnect
     /// will still be properly received.
     ///
-    /// [`Sender`]: ../../../std/sync/mpsc/struct.Sender.html
+    /// [`Sender`]: struct.Sender.html
+    /// [`SyncSender`]: struct.SyncSender.html
     /// [`Err`]: ../../../std/result/enum.Result.html#variant.Err
     ///
     /// # Examples
@@ -1163,6 +1361,33 @@ pub fn iter(&self) -> Iter<T> {
     /// user by waiting for values.
     ///
     /// [`panic!`]: ../../../std/macro.panic.html
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::sync::mpsc::channel;
+    /// use std::thread;
+    /// use std::time::Duration;
+    ///
+    /// let (sender, receiver) = channel();
+    ///
+    /// // Nothing is in the buffer yet
+    /// assert!(receiver.try_iter().next().is_none());
+    /// println!("Nothing in the buffer...");
+    ///
+    /// thread::spawn(move || {
+    ///     sender.send(1).unwrap();
+    ///     sender.send(2).unwrap();
+    ///     sender.send(3).unwrap();
+    /// });
+    ///
+    /// println!("Going to sleep...");
+    /// thread::sleep(Duration::from_secs(2)); // block for two seconds
+    ///
+    /// for x in receiver.try_iter() {
+    ///     println!("Got: {}", x);
+    /// }
+    /// ```
     #[stable(feature = "receiver_try_iter", since = "1.15.0")]
     pub fn try_iter(&self) -> TryIter<T> {
         TryIter { rx: self }
index 131adfe47afdac6646dbd31819235deb53b20e02..e5bb02fe08230253ddfa15006aa864a9879c0a9d 100644 (file)
@@ -1852,6 +1852,7 @@ pub enum ItemKind {
     /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
     Impl(Unsafety,
              ImplPolarity,
+             Defaultness,
              Generics,
              Option<TraitRef>, // (optional) trait this impl implements
              P<Ty>, // self
index 9b55a860b3595a0e4edd1bfb5e837d22f71ee7fd..b6a2c983fd4d7fb687abc39bea3ea65ddb14a844 100644 (file)
@@ -1215,7 +1215,7 @@ fn visit_item(&mut self, i: &'a ast::Item) {
                                     and possibly buggy");
             }
 
-            ast::ItemKind::Impl(_, polarity, _, _, _, _) => {
+            ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, _) => {
                 match polarity {
                     ast::ImplPolarity::Negative => {
                         gate_feature_post!(&self, optin_builtin_traits,
@@ -1225,6 +1225,12 @@ fn visit_item(&mut self, i: &'a ast::Item) {
                     },
                     _ => {}
                 }
+
+                if let ast::Defaultness::Default = defaultness {
+                    gate_feature_post!(&self, specialization,
+                                       i.span,
+                                       "specialization is unstable");
+                }
             }
 
             _ => {}
index f39399a62e856c366fb62d73361cc8c68b3b6121..58cf50cdc000ce3026dda2ad2ec1814926237378 100644 (file)
@@ -897,9 +897,16 @@ pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind {
         ItemKind::DefaultImpl(unsafety, ref trait_ref) => {
             ItemKind::DefaultImpl(unsafety, folder.fold_trait_ref((*trait_ref).clone()))
         }
-        ItemKind::Impl(unsafety, polarity, generics, ifce, ty, impl_items) => ItemKind::Impl(
+        ItemKind::Impl(unsafety,
+                       polarity,
+                       defaultness,
+                       generics,
+                       ifce,
+                       ty,
+                       impl_items) => ItemKind::Impl(
             unsafety,
             polarity,
+            defaultness,
             folder.fold_generics(generics),
             ifce.map(|trait_ref| folder.fold_trait_ref(trait_ref.clone())),
             folder.fold_ty(ty),
index 1baf0d1b54ce1f7530dd6ab9736134be4661c80d..cba77335143710d89e83d091dc2ead945c58e6b5 100644 (file)
 use symbol::{Symbol, keywords};
 use util::ThinVec;
 
+use std::cmp;
 use std::collections::HashSet;
-use std::{cmp, mem, slice};
+use std::mem;
 use std::path::{self, Path, PathBuf};
+use std::slice;
 
 bitflags! {
     flags Restrictions: u8 {
@@ -4863,7 +4865,9 @@ fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
     ///    impl<T> Foo { ... }
     ///    impl<T> ToString for &'static T { ... }
     ///    impl Send for .. {}
-    fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> PResult<'a, ItemInfo> {
+    fn parse_item_impl(&mut self,
+                       unsafety: ast::Unsafety,
+                       defaultness: Defaultness) -> PResult<'a, ItemInfo> {
         let impl_span = self.span;
 
         // First, parse type parameters if necessary.
@@ -4916,6 +4920,11 @@ fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> PResult<'a, ItemInfo>
                                           allowed to have generics");
             }
 
+            if let ast::Defaultness::Default = defaultness {
+                self.span_err(impl_span, "`default impl` is not allowed for \
+                                         default trait implementations");
+            }
+
             self.expect(&token::OpenDelim(token::Brace))?;
             self.expect(&token::CloseDelim(token::Brace))?;
             Ok((keywords::Invalid.ident(),
@@ -4944,7 +4953,7 @@ fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> PResult<'a, ItemInfo>
             }
 
             Ok((keywords::Invalid.ident(),
-             ItemKind::Impl(unsafety, polarity, generics, opt_trait, ty, impl_items),
+             ItemKind::Impl(unsafety, polarity, defaultness, generics, opt_trait, ty, impl_items),
              Some(attrs)))
         }
     }
@@ -5363,24 +5372,25 @@ fn submod_path(&mut self,
             }
             let mut err = self.diagnostic().struct_span_err(id_sp,
                 "cannot declare a new module at this location");
-            let this_module = match self.directory.path.file_name() {
-                Some(file_name) => file_name.to_str().unwrap().to_owned(),
-                None => self.root_module_name.as_ref().unwrap().clone(),
-            };
-            err.span_note(id_sp,
-                          &format!("maybe move this module `{0}` to its own directory \
-                                    via `{0}{1}mod.rs`",
-                                   this_module,
-                                   path::MAIN_SEPARATOR));
+            if id_sp != syntax_pos::DUMMY_SP {
+                let src_path = PathBuf::from(self.sess.codemap().span_to_filename(id_sp));
+                if let Some(stem) = src_path.file_stem() {
+                    let mut dest_path = src_path.clone();
+                    dest_path.set_file_name(stem);
+                    dest_path.push("mod.rs");
+                    err.span_note(id_sp,
+                                  &format!("maybe move this module `{}` to its own \
+                                            directory via `{}`", src_path.to_string_lossy(),
+                                           dest_path.to_string_lossy()));
+                }
+            }
             if paths.path_exists {
                 err.span_note(id_sp,
                               &format!("... or maybe `use` the module `{}` instead \
                                         of possibly redeclaring it",
                                        paths.name));
-                Err(err)
-            } else {
-                Err(err)
             }
+            Err(err)
         } else {
             paths.result.map_err(|err| self.span_fatal_err(id_sp, err))
         }
@@ -5756,13 +5766,19 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
                                     maybe_append(attrs, extra_attrs));
             return Ok(Some(item));
         }
-        if self.check_keyword(keywords::Unsafe) &&
-            self.look_ahead(1, |t| t.is_keyword(keywords::Impl))
+        if (self.check_keyword(keywords::Unsafe) &&
+            self.look_ahead(1, |t| t.is_keyword(keywords::Impl))) ||
+           (self.check_keyword(keywords::Default) &&
+            self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe)) &&
+            self.look_ahead(2, |t| t.is_keyword(keywords::Impl)))
         {
             // IMPL ITEM
+            let defaultness = self.parse_defaultness()?;
             self.expect_keyword(keywords::Unsafe)?;
             self.expect_keyword(keywords::Impl)?;
-            let (ident, item_, extra_attrs) = self.parse_item_impl(ast::Unsafety::Unsafe)?;
+            let (ident,
+                 item_,
+                 extra_attrs) = self.parse_item_impl(ast::Unsafety::Unsafe, defaultness)?;
             let prev_span = self.prev_span;
             let item = self.mk_item(lo.to(prev_span),
                                     ident,
@@ -5856,9 +5872,16 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
                                     maybe_append(attrs, extra_attrs));
             return Ok(Some(item));
         }
-        if self.eat_keyword(keywords::Impl) {
+        if (self.check_keyword(keywords::Impl)) ||
+           (self.check_keyword(keywords::Default) &&
+            self.look_ahead(1, |t| t.is_keyword(keywords::Impl)))
+        {
             // IMPL ITEM
-            let (ident, item_, extra_attrs) = self.parse_item_impl(ast::Unsafety::Normal)?;
+            let defaultness = self.parse_defaultness()?;
+            self.expect_keyword(keywords::Impl)?;
+            let (ident,
+                 item_,
+                 extra_attrs) = self.parse_item_impl(ast::Unsafety::Normal, defaultness)?;
             let prev_span = self.prev_span;
             let item = self.mk_item(lo.to(prev_span),
                                     ident,
index be1d26f8fe4872c5f82346707883d50141ee3c2c..a911c21ed98d05e890c3c84e0c2b86667567c9e7 100644 (file)
@@ -1317,12 +1317,14 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
             }
             ast::ItemKind::Impl(unsafety,
                           polarity,
+                          defaultness,
                           ref generics,
                           ref opt_trait,
                           ref ty,
                           ref impl_items) => {
                 self.head("")?;
                 self.print_visibility(&item.vis)?;
+                self.print_defaultness(defaultness)?;
                 self.print_unsafety(unsafety)?;
                 self.word_nbsp("impl")?;
 
@@ -1477,6 +1479,13 @@ pub fn print_visibility(&mut self, vis: &ast::Visibility) -> io::Result<()> {
         }
     }
 
+    pub fn print_defaultness(&mut self, defatulness: ast::Defaultness) -> io::Result<()> {
+        if let ast::Defaultness::Default = defatulness {
+            try!(self.word_nbsp("default"));
+        }
+        Ok(())
+    }
+
     pub fn print_struct(&mut self,
                         struct_def: &ast::VariantData,
                         generics: &ast::Generics,
@@ -1602,9 +1611,7 @@ pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> {
         self.hardbreak_if_not_bol()?;
         self.maybe_print_comment(ii.span.lo)?;
         self.print_outer_attributes(&ii.attrs)?;
-        if let ast::Defaultness::Default = ii.defaultness {
-            self.word_nbsp("default")?;
-        }
+        self.print_defaultness(ii.defaultness)?;
         match ii.node {
             ast::ImplItemKind::Const(ref ty, ref expr) => {
                 self.print_associated_const(ii.ident, &ty, Some(&expr), &ii.vis)?;
index bae1c56db007c66d137cca850179820e91b77eaa..2e42c6986e64e1d527af2b5699958e6c98e144c5 100644 (file)
@@ -266,7 +266,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
         ItemKind::DefaultImpl(_, ref trait_ref) => {
             visitor.visit_trait_ref(trait_ref)
         }
-        ItemKind::Impl(_, _,
+        ItemKind::Impl(_, _, _,
                  ref type_parameters,
                  ref opt_trait_reference,
                  ref typ,
index e96883c26f33a1c854996e89ecbdc39d1cb78655..be7883cad5f38ca52bda1c23a70b7dc4e49bded9 100644 (file)
@@ -658,6 +658,7 @@ fn create_derived_impl(&self,
                 a,
                 ast::ItemKind::Impl(unsafety,
                                     ast::ImplPolarity::Positive,
+                                    ast::Defaultness::Final,
                                     trait_generics,
                                     opt_trait_ref,
                                     self_type,
index 9b8099d55a024eea1e7e8f80a2f6049c76c6aed4..be9aa6c5d40ba7f3d35697f183432145934fb5d7 100644 (file)
@@ -39,5 +39,7 @@ fn main() {
         println!("cargo:rustc-link-lib=static-nobundle=pthread");
     } else if target.contains("fuchsia") {
         println!("cargo:rustc-link-lib=unwind");
+    } else if target.contains("haiku") {
+        println!("cargo:rustc-link-lib=gcc_s");
     }
 }
index a884d21cc5f0b23a1693d1e872fd8998a4fdd17f..15745af7683844e43bdec966072b8e7b44772450 160000 (submodule)
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit a884d21cc5f0b23a1693d1e872fd8998a4fdd17f
+Subproject commit 15745af7683844e43bdec966072b8e7b44772450
index c410a6b1349d68598d94bef86724d0cc325573d9..b938f94cda2cb3596bf1cbbb8ef248b18a54cffe 100644 (file)
@@ -147,6 +147,12 @@ extern "C" void LLVMRustAddPass(LLVMPassManagerRef PMR, LLVMPassRef RustPass) {
 #define SUBTARGET_SPARC
 #endif
 
+#ifdef LLVM_COMPONENT_HEXAGON
+#define SUBTARGET_HEXAGON SUBTARGET(Hexagon)
+#else
+#define SUBTARGET_HEXAGON
+#endif
+
 #define GEN_SUBTARGETS                                                         \
   SUBTARGET_X86                                                                \
   SUBTARGET_ARM                                                                \
@@ -155,7 +161,8 @@ extern "C" void LLVMRustAddPass(LLVMPassManagerRef PMR, LLVMPassRef RustPass) {
   SUBTARGET_PPC                                                                \
   SUBTARGET_SYSTEMZ                                                            \
   SUBTARGET_MSP430                                                             \
-  SUBTARGET_SPARC
+  SUBTARGET_SPARC                                                              \
+  SUBTARGET_HEXAGON
 
 #define SUBTARGET(x)                                                           \
   namespace llvm {                                                             \
index c8732e27b82528e9e988d4ebfe21385aa5d41c72..1006445ade6a1036cc3a4f71678e65b7ca3565b9 100644 (file)
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be (optionally) cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2017-03-23
+2017-04-26
diff --git a/src/test/compile-fail/borrowck/borrowck-in-static.rs b/src/test/compile-fail/borrowck/borrowck-in-static.rs
deleted file mode 100644 (file)
index 16b0e86..0000000
+++ /dev/null
@@ -1,22 +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 <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.
-
-// check that borrowck looks inside consts/statics
-
-static FN : &'static (Fn() -> (Box<Fn()->Box<i32>>) + Sync) = &|| {
-    let x = Box::new(0);
-    Box::new(|| x) //~ ERROR cannot move out of captured outer variable
-};
-
-fn main() {
-    let f = (FN)();
-    f();
-    f();
-}
index a67707257d2f2ac44a1bd757c1142f07839a70b0..0dc5c4bcfa201a1d539707791787f945cd25d3d2 100644 (file)
@@ -19,6 +19,6 @@ fn main() {
     match s {
         S{0: a, 0x1: b, ..} => {}
         //~^ ERROR does not have a field named `0x1`
-        //~| NOTE struct `S::{{constructor}}` does not have field `0x1`
+        //~| NOTE struct `S` does not have field `0x1`
     }
 }
diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-default-projection.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-default-projection.rs
new file mode 100644 (file)
index 0000000..ad55f44
--- /dev/null
@@ -0,0 +1,46 @@
+// 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 <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(specialization)]
+
+// Make sure we can't project defaulted associated types
+
+trait Foo {
+    type Assoc;
+}
+
+default impl<T> Foo for T {
+    type Assoc = ();
+}
+
+impl Foo for u8 {
+    type Assoc = String;
+}
+
+fn generic<T>() -> <T as Foo>::Assoc {
+    // `T` could be some downstream crate type that specializes (or,
+    // for that matter, `u8`).
+
+    () //~ ERROR mismatched types
+}
+
+fn monomorphic() -> () {
+    // Even though we know that `()` is not specialized in a
+    // downstream crate, typeck refuses to project here.
+
+    generic::<()>() //~ ERROR mismatched types
+}
+
+fn main() {
+    // No error here, we CAN project from `u8`, as there is no `default`
+    // in that impl.
+    let s: String = generic::<u8>();
+    println!("{}", s); // bad news if this all compiles
+}
diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-default-types.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-default-types.rs
new file mode 100644 (file)
index 0000000..7353f7a
--- /dev/null
@@ -0,0 +1,45 @@
+// 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 <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.
+
+// It should not be possible to use the concrete value of a defaulted
+// associated type in the impl defining it -- otherwise, what happens
+// if it's overridden?
+
+#![feature(specialization)]
+
+trait Example {
+    type Output;
+    fn generate(self) -> Self::Output;
+}
+
+default impl<T> Example for T {
+    type Output = Box<T>;
+    fn generate(self) -> Self::Output {
+        Box::new(self) //~ ERROR mismatched types
+    }
+}
+
+impl Example for bool {
+    type Output = bool;
+    fn generate(self) -> bool { self }
+}
+
+fn trouble<T>(t: T) -> Box<T> {
+    Example::generate(t) //~ ERROR mismatched types
+}
+
+fn weaponize() -> bool {
+    let b: Box<bool> = trouble(true);
+    *b
+}
+
+fn main() {
+    weaponize();
+}
diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-feature-gate-default.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-feature-gate-default.rs
new file mode 100644 (file)
index 0000000..5bab4c5
--- /dev/null
@@ -0,0 +1,21 @@
+// 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 <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.
+
+// Check that specialization must be ungated to use the `default` keyword
+
+trait Foo {
+    fn foo(&self);
+}
+
+default impl<T> Foo for T { //~ ERROR specialization is unstable
+    fn foo(&self) {}
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-no-default-trait-implementations.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-no-default-trait-implementations.rs
new file mode 100644 (file)
index 0000000..c1746d7
--- /dev/null
@@ -0,0 +1,19 @@
+// 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 <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(specialization)]
+#![feature(optin_builtin_traits)]
+
+trait Foo {}
+
+default impl Foo for .. {}
+//~^ ERROR `default impl` is not allowed for default trait implementations
+
+fn main() {}
diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-no-default.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-no-default.rs
new file mode 100644 (file)
index 0000000..2874108
--- /dev/null
@@ -0,0 +1,95 @@
+// 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 <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(specialization)]
+
+// Check a number of scenarios in which one impl tries to override another,
+// without correctly using `default`.
+
+////////////////////////////////////////////////////////////////////////////////
+// Test 1: one layer of specialization, multiple methods, missing `default`
+////////////////////////////////////////////////////////////////////////////////
+
+trait Foo {
+    fn foo(&self);
+    fn bar(&self);
+}
+
+impl<T> Foo for T {
+    fn foo(&self) {}
+    fn bar(&self) {}
+}
+
+impl Foo for u8 {}
+impl Foo for u16 {
+    fn foo(&self) {} //~ ERROR E0520
+}
+impl Foo for u32 {
+    fn bar(&self) {} //~ ERROR E0520
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Test 2: one layer of specialization, missing `default` on associated type
+////////////////////////////////////////////////////////////////////////////////
+
+trait Bar {
+    type T;
+}
+
+impl<T> Bar for T {
+    type T = u8;
+}
+
+impl Bar for u8 {
+    type T = (); //~ ERROR E0520
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Test 3a: multiple layers of specialization, missing interior `default`
+////////////////////////////////////////////////////////////////////////////////
+
+trait Baz {
+    fn baz(&self);
+}
+
+default impl<T> Baz for T {
+    fn baz(&self) {}
+}
+
+impl<T: Clone> Baz for T {
+    fn baz(&self) {}
+}
+
+impl Baz for i32 {
+    fn baz(&self) {} //~ ERROR E0520
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Test 3b: multiple layers of specialization, missing interior `default`,
+// redundant `default` in bottom layer.
+////////////////////////////////////////////////////////////////////////////////
+
+trait Redundant {
+    fn redundant(&self);
+}
+
+default impl<T> Redundant for T {
+    fn redundant(&self) {}
+}
+
+impl<T: Clone> Redundant for T {
+    fn redundant(&self) {}
+}
+
+default impl Redundant for i32 {
+    fn redundant(&self) {} //~ ERROR E0520
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/unboxed-closures-move-upvar-from-non-once-ref-closure.rs b/src/test/compile-fail/unboxed-closures-move-upvar-from-non-once-ref-closure.rs
deleted file mode 100644 (file)
index cd9f163..0000000
+++ /dev/null
@@ -1,24 +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 <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.
-
-// Test that a by-ref `FnMut` closure gets an error when it tries to
-// consume a value.
-
-fn call<F>(f: F) where F : Fn() {
-    f();
-}
-
-fn main() {
-    let y = vec![format!("World")];
-    call(|| {
-        y.into_iter();
-        //~^ ERROR cannot move out of captured outer variable in an `Fn` closure
-    });
-}
diff --git a/src/test/run-pass/issue-33287.rs b/src/test/run-pass/issue-33287.rs
new file mode 100644 (file)
index 0000000..a2021e0
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+//
+// 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.
+
+const A: [u32; 1] = [0];
+
+fn test() {
+    let range = A[1]..;
+}
+
+fn main() { }
+
diff --git a/src/test/run-pass/specialization/defaultimpl/auxiliary/go_trait.rs b/src/test/run-pass/specialization/defaultimpl/auxiliary/go_trait.rs
new file mode 100644 (file)
index 0000000..dd060f8
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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(specialization)]
+
+// Common code used for tests that model the Fn/FnMut/FnOnce hierarchy.
+
+pub trait Go {
+    fn go(&self, arg: isize);
+}
+
+pub fn go<G:Go>(this: &G, arg: isize) {
+    this.go(arg)
+}
+
+pub trait GoMut {
+    fn go_mut(&mut self, arg: isize);
+}
+
+pub fn go_mut<G:GoMut>(this: &mut G, arg: isize) {
+    this.go_mut(arg)
+}
+
+pub trait GoOnce {
+    fn go_once(self, arg: isize);
+}
+
+pub fn go_once<G:GoOnce>(this: G, arg: isize) {
+    this.go_once(arg)
+}
+
+default impl<G> GoMut for G
+    where G : Go
+{
+    fn go_mut(&mut self, arg: isize) {
+        go(&*self, arg)
+    }
+}
+
+default impl<G> GoOnce for G
+    where G : GoMut
+{
+    fn go_once(mut self, arg: isize) {
+        go_mut(&mut self, arg)
+    }
+}
diff --git a/src/test/run-pass/specialization/defaultimpl/auxiliary/specialization_cross_crate.rs b/src/test/run-pass/specialization/defaultimpl/auxiliary/specialization_cross_crate.rs
new file mode 100644 (file)
index 0000000..71dd7c9
--- /dev/null
@@ -0,0 +1,82 @@
+// 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 <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(specialization)]
+
+pub trait Foo {
+    fn foo(&self) -> &'static str;
+}
+
+default impl<T> Foo for T {
+    fn foo(&self) -> &'static str {
+        "generic"
+    }
+}
+
+default impl<T: Clone> Foo for T {
+    fn foo(&self) -> &'static str {
+        "generic Clone"
+    }
+}
+
+default impl<T, U> Foo for (T, U) where T: Clone, U: Clone {
+    fn foo(&self) -> &'static str {
+        "generic pair"
+    }
+}
+
+default impl<T: Clone> Foo for (T, T) {
+    fn foo(&self) -> &'static str {
+        "generic uniform pair"
+    }
+}
+
+default impl Foo for (u8, u32) {
+    fn foo(&self) -> &'static str {
+        "(u8, u32)"
+    }
+}
+
+default impl Foo for (u8, u8) {
+    fn foo(&self) -> &'static str {
+        "(u8, u8)"
+    }
+}
+
+default impl<T: Clone> Foo for Vec<T> {
+    fn foo(&self) -> &'static str {
+        "generic Vec"
+    }
+}
+
+impl Foo for Vec<i32> {
+    fn foo(&self) -> &'static str {
+        "Vec<i32>"
+    }
+}
+
+impl Foo for String {
+    fn foo(&self) -> &'static str {
+        "String"
+    }
+}
+
+impl Foo for i32 {
+    fn foo(&self) -> &'static str {
+        "i32"
+    }
+}
+
+pub trait MyMarker {}
+default impl<T: Clone + MyMarker> Foo for T {
+    fn foo(&self) -> &'static str {
+        "generic Clone + MyMarker"
+    }
+}
diff --git a/src/test/run-pass/specialization/defaultimpl/auxiliary/specialization_cross_crate_defaults.rs b/src/test/run-pass/specialization/defaultimpl/auxiliary/specialization_cross_crate_defaults.rs
new file mode 100644 (file)
index 0000000..9d0ea64
--- /dev/null
@@ -0,0 +1,49 @@
+// 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 <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(specialization)]
+
+// First, test only use of explicit `default` items:
+
+pub trait Foo {
+    fn foo(&self) -> bool;
+}
+
+default impl<T> Foo for T {
+    fn foo(&self) -> bool { false }
+}
+
+impl Foo for i32 {}
+
+impl Foo for i64 {
+    fn foo(&self) -> bool { true }
+}
+
+// Next, test mixture of explicit `default` and provided methods:
+
+pub trait Bar {
+    fn bar(&self) -> i32 { 0 }
+}
+
+impl<T> Bar for T {} // use the provided method
+
+impl Bar for i32 {
+    fn bar(&self) -> i32 { 1 }
+}
+impl<'a> Bar for &'a str {}
+
+default impl<T> Bar for Vec<T> {
+    fn bar(&self) -> i32 { 2 }
+}
+impl Bar for Vec<i32> {}
+impl Bar for Vec<i64> {
+    fn bar(&self) -> i32 { 3 }
+}
diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-allowed-cross-crate.rs b/src/test/run-pass/specialization/defaultimpl/specialization-allowed-cross-crate.rs
new file mode 100644 (file)
index 0000000..6b999f3
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+// aux-build:go_trait.rs
+
+#![feature(specialization)]
+
+extern crate go_trait;
+
+use go_trait::{Go,GoMut};
+use std::fmt::Debug;
+use std::default::Default;
+
+struct MyThingy;
+
+impl Go for MyThingy {
+    fn go(&self, arg: isize) { }
+}
+
+impl GoMut for MyThingy {
+    fn go_mut(&mut self, arg: isize) { }
+}
+
+fn main() { }
diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-assoc-fns.rs b/src/test/run-pass/specialization/defaultimpl/specialization-assoc-fns.rs
new file mode 100644 (file)
index 0000000..b99ba3d
--- /dev/null
@@ -0,0 +1,37 @@
+// 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 <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.
+
+// Test that non-method associated functions can be specialized
+
+#![feature(specialization)]
+
+trait Foo {
+    fn mk() -> Self;
+}
+
+default impl<T: Default> Foo for T {
+    fn mk() -> T {
+        T::default()
+    }
+}
+
+impl Foo for Vec<u8> {
+    fn mk() -> Vec<u8> {
+        vec![0]
+    }
+}
+
+fn main() {
+    let v1: Vec<i32> = Foo::mk();
+    let v2: Vec<u8> = Foo::mk();
+
+    assert!(v1.len() == 0);
+    assert!(v2.len() == 1);
+}
diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-basics-unsafe.rs b/src/test/run-pass/specialization/defaultimpl/specialization-basics-unsafe.rs
new file mode 100644 (file)
index 0000000..7daecc8
--- /dev/null
@@ -0,0 +1,106 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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(specialization)]
+
+// Tests a variety of basic specialization scenarios and method
+// dispatch for them.
+
+unsafe trait Foo {
+    fn foo(&self) -> &'static str;
+}
+
+default unsafe impl<T> Foo for T {
+    fn foo(&self) -> &'static str {
+        "generic"
+    }
+}
+
+default unsafe impl<T: Clone> Foo for T {
+    fn foo(&self) -> &'static str {
+        "generic Clone"
+    }
+}
+
+default unsafe impl<T, U> Foo for (T, U) where T: Clone, U: Clone {
+    fn foo(&self) -> &'static str {
+        "generic pair"
+    }
+}
+
+default unsafe impl<T: Clone> Foo for (T, T) {
+    fn foo(&self) -> &'static str {
+        "generic uniform pair"
+    }
+}
+
+default unsafe impl Foo for (u8, u32) {
+    fn foo(&self) -> &'static str {
+        "(u8, u32)"
+    }
+}
+
+default unsafe impl Foo for (u8, u8) {
+    fn foo(&self) -> &'static str {
+        "(u8, u8)"
+    }
+}
+
+default unsafe impl<T: Clone> Foo for Vec<T> {
+    fn foo(&self) -> &'static str {
+        "generic Vec"
+    }
+}
+
+default unsafe impl Foo for Vec<i32> {
+    fn foo(&self) -> &'static str {
+        "Vec<i32>"
+    }
+}
+
+default unsafe impl Foo for String {
+    fn foo(&self) -> &'static str {
+        "String"
+    }
+}
+
+default unsafe impl Foo for i32 {
+    fn foo(&self) -> &'static str {
+        "i32"
+    }
+}
+
+struct NotClone;
+
+unsafe trait MyMarker {}
+default unsafe impl<T: Clone + MyMarker> Foo for T {
+    fn foo(&self) -> &'static str {
+        "generic Clone + MyMarker"
+    }
+}
+
+#[derive(Clone)]
+struct MarkedAndClone;
+unsafe impl MyMarker for MarkedAndClone {}
+
+fn  main() {
+    assert!(NotClone.foo() == "generic");
+    assert!(0u8.foo() == "generic Clone");
+    assert!(vec![NotClone].foo() == "generic");
+    assert!(vec![0u8].foo() == "generic Vec");
+    assert!(vec![0i32].foo() == "Vec<i32>");
+    assert!(0i32.foo() == "i32");
+    assert!(String::new().foo() == "String");
+    assert!(((), 0).foo() == "generic pair");
+    assert!(((), ()).foo() == "generic uniform pair");
+    assert!((0u8, 0u32).foo() == "(u8, u32)");
+    assert!((0u8, 0u8).foo() == "(u8, u8)");
+    assert!(MarkedAndClone.foo() == "generic Clone + MyMarker");
+}
diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-basics.rs b/src/test/run-pass/specialization/defaultimpl/specialization-basics.rs
new file mode 100644 (file)
index 0000000..594f1e4
--- /dev/null
@@ -0,0 +1,106 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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(specialization)]
+
+// Tests a variety of basic specialization scenarios and method
+// dispatch for them.
+
+trait Foo {
+    fn foo(&self) -> &'static str;
+}
+
+default impl<T> Foo for T {
+    fn foo(&self) -> &'static str {
+        "generic"
+    }
+}
+
+default impl<T: Clone> Foo for T {
+    fn foo(&self) -> &'static str {
+        "generic Clone"
+    }
+}
+
+default impl<T, U> Foo for (T, U) where T: Clone, U: Clone {
+    fn foo(&self) -> &'static str {
+        "generic pair"
+    }
+}
+
+default impl<T: Clone> Foo for (T, T) {
+    fn foo(&self) -> &'static str {
+        "generic uniform pair"
+    }
+}
+
+default impl Foo for (u8, u32) {
+    fn foo(&self) -> &'static str {
+        "(u8, u32)"
+    }
+}
+
+default impl Foo for (u8, u8) {
+    fn foo(&self) -> &'static str {
+        "(u8, u8)"
+    }
+}
+
+default impl<T: Clone> Foo for Vec<T> {
+    fn foo(&self) -> &'static str {
+        "generic Vec"
+    }
+}
+
+impl Foo for Vec<i32> {
+    fn foo(&self) -> &'static str {
+        "Vec<i32>"
+    }
+}
+
+impl Foo for String {
+    fn foo(&self) -> &'static str {
+        "String"
+    }
+}
+
+impl Foo for i32 {
+    fn foo(&self) -> &'static str {
+        "i32"
+    }
+}
+
+struct NotClone;
+
+trait MyMarker {}
+default impl<T: Clone + MyMarker> Foo for T {
+    fn foo(&self) -> &'static str {
+        "generic Clone + MyMarker"
+    }
+}
+
+#[derive(Clone)]
+struct MarkedAndClone;
+impl MyMarker for MarkedAndClone {}
+
+fn  main() {
+    assert!(NotClone.foo() == "generic");
+    assert!(0u8.foo() == "generic Clone");
+    assert!(vec![NotClone].foo() == "generic");
+    assert!(vec![0u8].foo() == "generic Vec");
+    assert!(vec![0i32].foo() == "Vec<i32>");
+    assert!(0i32.foo() == "i32");
+    assert!(String::new().foo() == "String");
+    assert!(((), 0).foo() == "generic pair");
+    assert!(((), ()).foo() == "generic uniform pair");
+    assert!((0u8, 0u32).foo() == "(u8, u32)");
+    assert!((0u8, 0u8).foo() == "(u8, u8)");
+    assert!(MarkedAndClone.foo() == "generic Clone + MyMarker");
+}
diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-cross-crate-defaults.rs b/src/test/run-pass/specialization/defaultimpl/specialization-cross-crate-defaults.rs
new file mode 100644 (file)
index 0000000..62c7e3e
--- /dev/null
@@ -0,0 +1,49 @@
+// 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 <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.
+
+// aux-build:specialization_cross_crate_defaults.rs
+
+#![feature(specialization)]
+
+extern crate specialization_cross_crate_defaults;
+
+use specialization_cross_crate_defaults::*;
+
+struct LocalDefault;
+struct LocalOverride;
+
+impl Foo for LocalDefault {}
+
+impl Foo for LocalOverride {
+    fn foo(&self) -> bool { true }
+}
+
+fn test_foo() {
+    assert!(!0i8.foo());
+    assert!(!0i32.foo());
+    assert!(0i64.foo());
+
+    assert!(!LocalDefault.foo());
+    assert!(LocalOverride.foo());
+}
+
+fn test_bar() {
+    assert!(0u8.bar() == 0);
+    assert!(0i32.bar() == 1);
+    assert!("hello".bar() == 0);
+    assert!(vec![()].bar() == 2);
+    assert!(vec![0i32].bar() == 2);
+    assert!(vec![0i64].bar() == 3);
+}
+
+fn main() {
+    test_foo();
+    test_bar();
+}
diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-cross-crate-no-gate.rs b/src/test/run-pass/specialization/defaultimpl/specialization-cross-crate-no-gate.rs
new file mode 100644 (file)
index 0000000..b954853
--- /dev/null
@@ -0,0 +1,29 @@
+// 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 <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.
+
+// Test that specialization works even if only the upstream crate enables it
+
+// aux-build:specialization_cross_crate.rs
+
+extern crate specialization_cross_crate;
+
+use specialization_cross_crate::*;
+
+fn  main() {
+    assert!(0u8.foo() == "generic Clone");
+    assert!(vec![0u8].foo() == "generic Vec");
+    assert!(vec![0i32].foo() == "Vec<i32>");
+    assert!(0i32.foo() == "i32");
+    assert!(String::new().foo() == "String");
+    assert!(((), 0).foo() == "generic pair");
+    assert!(((), ()).foo() == "generic uniform pair");
+    assert!((0u8, 0u32).foo() == "(u8, u32)");
+    assert!((0u8, 0u8).foo() == "(u8, u8)");
+}
diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-cross-crate.rs b/src/test/run-pass/specialization/defaultimpl/specialization-cross-crate.rs
new file mode 100644 (file)
index 0000000..7517824
--- /dev/null
@@ -0,0 +1,58 @@
+// 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 <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.
+
+// aux-build:specialization_cross_crate.rs
+
+#![feature(specialization)]
+
+extern crate specialization_cross_crate;
+
+use specialization_cross_crate::*;
+
+struct NotClone;
+
+#[derive(Clone)]
+struct MarkedAndClone;
+impl MyMarker for MarkedAndClone {}
+
+struct MyType<T>(T);
+default impl<T> Foo for MyType<T> {
+    fn foo(&self) -> &'static str {
+        "generic MyType"
+    }
+}
+
+impl Foo for MyType<u8> {
+    fn foo(&self) -> &'static str {
+        "MyType<u8>"
+    }
+}
+
+struct MyOtherType;
+impl Foo for MyOtherType {}
+
+fn  main() {
+    assert!(NotClone.foo() == "generic");
+    assert!(0u8.foo() == "generic Clone");
+    assert!(vec![NotClone].foo() == "generic");
+    assert!(vec![0u8].foo() == "generic Vec");
+    assert!(vec![0i32].foo() == "Vec<i32>");
+    assert!(0i32.foo() == "i32");
+    assert!(String::new().foo() == "String");
+    assert!(((), 0).foo() == "generic pair");
+    assert!(((), ()).foo() == "generic uniform pair");
+    assert!((0u8, 0u32).foo() == "(u8, u32)");
+    assert!((0u8, 0u8).foo() == "(u8, u8)");
+    assert!(MarkedAndClone.foo() == "generic Clone + MyMarker");
+
+    assert!(MyType(()).foo() == "generic MyType");
+    assert!(MyType(0u8).foo() == "MyType<u8>");
+    assert!(MyOtherType.foo() == "generic");
+}
diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-default-methods.rs b/src/test/run-pass/specialization/defaultimpl/specialization-default-methods.rs
new file mode 100644 (file)
index 0000000..4ac9afc
--- /dev/null
@@ -0,0 +1,94 @@
+// 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 <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(specialization)]
+
+// Test that default methods are cascaded correctly
+
+// First, test only use of explicit `default` items:
+
+trait Foo {
+    fn foo(&self) -> bool;
+}
+
+// Specialization tree for Foo:
+//
+//        T
+//       / \
+//    i32   i64
+
+default impl<T> Foo for T {
+    fn foo(&self) -> bool { false }
+}
+
+impl Foo for i32 {}
+
+impl Foo for i64 {
+    fn foo(&self) -> bool { true }
+}
+
+fn test_foo() {
+    assert!(!0i8.foo());
+    assert!(!0i32.foo());
+    assert!(0i64.foo());
+}
+
+// Next, test mixture of explicit `default` and provided methods:
+
+trait Bar {
+    fn bar(&self) -> i32 { 0 }
+}
+
+// Specialization tree for Bar.
+// Uses of $ designate that method is provided
+//
+//           $Bar   (the trait)
+//             |
+//             T
+//            /|\
+//           / | \
+//          /  |  \
+//         /   |   \
+//        /    |    \
+//       /     |     \
+//     $i32   &str  $Vec<T>
+//                    /\
+//                   /  \
+//            Vec<i32>  $Vec<i64>
+
+// use the provided method
+impl<T> Bar for T {}
+
+impl Bar for i32 {
+    fn bar(&self) -> i32 { 1 }
+}
+impl<'a> Bar for &'a str {}
+
+default impl<T> Bar for Vec<T> {
+    fn bar(&self) -> i32 { 2 }
+}
+impl Bar for Vec<i32> {}
+impl Bar for Vec<i64> {
+    fn bar(&self) -> i32 { 3 }
+}
+
+fn test_bar() {
+    assert!(0u8.bar() == 0);
+    assert!(0i32.bar() == 1);
+    assert!("hello".bar() == 0);
+    assert!(vec![()].bar() == 2);
+    assert!(vec![0i32].bar() == 2);
+    assert!(vec![0i64].bar() == 3);
+}
+
+fn main() {
+    test_foo();
+    test_bar();
+}
diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-out-of-order.rs b/src/test/run-pass/specialization/defaultimpl/specialization-out-of-order.rs
new file mode 100644 (file)
index 0000000..f77b88e
--- /dev/null
@@ -0,0 +1,27 @@
+// 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.
+
+// Test that you can list the more specific impl before the more general one.
+
+#![feature(specialization)]
+
+trait Foo {
+    type Out;
+}
+
+impl Foo for bool {
+    type Out = ();
+}
+
+default impl<T> Foo for T {
+    type Out = bool;
+}
+
+fn main() {}
diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-overlap-projection.rs b/src/test/run-pass/specialization/defaultimpl/specialization-overlap-projection.rs
new file mode 100644 (file)
index 0000000..500cded
--- /dev/null
@@ -0,0 +1,33 @@
+// 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.
+
+// Test that impls on projected self types can resolve overlap, even when the
+// projections involve specialization, so long as the associated type is
+// provided by the most specialized impl.
+
+#![feature(specialization)]
+
+trait Assoc {
+    type Output;
+}
+
+default impl<T> Assoc for T {
+    type Output = bool;
+}
+
+impl Assoc for u8 { type Output = u8; }
+impl Assoc for u16 { type Output = u16; }
+
+trait Foo {}
+impl Foo for u32 {}
+impl Foo for <u8 as Assoc>::Output {}
+impl Foo for <u16 as Assoc>::Output {}
+
+fn main() {}
diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-projection-alias.rs b/src/test/run-pass/specialization/defaultimpl/specialization-projection-alias.rs
new file mode 100644 (file)
index 0000000..2397c3e
--- /dev/null
@@ -0,0 +1,32 @@
+// 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(specialization)]
+
+// Regression test for ICE when combining specialized associated types and type
+// aliases
+
+trait Id_ {
+    type Out;
+}
+
+type Id<T> = <T as Id_>::Out;
+
+default impl<T> Id_ for T {
+    type Out = T;
+}
+
+fn test_proection() {
+    let x: Id<bool> = panic!();
+}
+
+fn main() {
+
+}
diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-projection.rs b/src/test/run-pass/specialization/defaultimpl/specialization-projection.rs
new file mode 100644 (file)
index 0000000..6a833ba
--- /dev/null
@@ -0,0 +1,49 @@
+// 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 <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(specialization)]
+
+// Make sure we *can* project non-defaulted associated types
+// cf compile-fail/specialization-default-projection.rs
+
+// First, do so without any use of specialization
+
+trait Foo {
+    type Assoc;
+}
+
+impl<T> Foo for T {
+    type Assoc = ();
+}
+
+fn generic_foo<T>() -> <T as Foo>::Assoc {
+    ()
+}
+
+// Next, allow for one layer of specialization
+
+trait Bar {
+    type Assoc;
+}
+
+default impl<T> Bar for T {
+    type Assoc = ();
+}
+
+impl<T: Clone> Bar for T {
+    type Assoc = u8;
+}
+
+fn generic_bar_clone<T: Clone>() -> <T as Bar>::Assoc {
+    0u8
+}
+
+fn main() {
+}
diff --git a/src/test/ui/borrowck/borrowck-in-static.rs b/src/test/ui/borrowck/borrowck-in-static.rs
new file mode 100644 (file)
index 0000000..9244c12
--- /dev/null
@@ -0,0 +1,22 @@
+// 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 <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.
+
+// check that borrowck looks inside consts/statics
+
+static FN : &'static (Fn() -> (Box<Fn()->Box<i32>>) + Sync) = &|| {
+    let x = Box::new(0); //~ NOTE moved
+    Box::new(|| x) //~ ERROR cannot move out of captured outer variable
+};
+
+fn main() {
+    let f = (FN)();
+    f();
+    f();
+}
diff --git a/src/test/ui/borrowck/borrowck-in-static.stderr b/src/test/ui/borrowck/borrowck-in-static.stderr
new file mode 100644 (file)
index 0000000..6083a82
--- /dev/null
@@ -0,0 +1,10 @@
+error[E0507]: cannot move out of captured outer variable in an `Fn` closure
+  --> $DIR/borrowck-in-static.rs:15:17
+   |
+14 |     let x = Box::new(0); //~ NOTE moved
+   |         - captured outer variable
+15 |     Box::new(|| x) //~ ERROR cannot move out of captured outer variable
+   |                 ^ cannot move out of captured outer variable in an `Fn` closure
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs
new file mode 100644 (file)
index 0000000..9c89c26
--- /dev/null
@@ -0,0 +1,24 @@
+// 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 <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.
+
+// Test that a by-ref `FnMut` closure gets an error when it tries to
+// consume a value.
+
+fn call<F>(f: F) where F : Fn() {
+    f();
+}
+
+fn main() {
+    let y = vec![format!("World")];  //~ NOTE moved
+    call(|| {
+        y.into_iter();
+        //~^ ERROR cannot move out of captured outer variable in an `Fn` closure
+    });
+}
diff --git a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
new file mode 100644 (file)
index 0000000..dbfcb2e
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0507]: cannot move out of captured outer variable in an `Fn` closure
+  --> $DIR/unboxed-closures-move-upvar-from-non-once-ref-closure.rs:21:9
+   |
+19 |     let y = vec![format!("World")];  //~ NOTE moved
+   |         - captured outer variable
+20 |     call(|| {
+21 |         y.into_iter();
+   |         ^ cannot move out of captured outer variable in an `Fn` closure
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/invalid-module-declaration/auxiliary/foo/bar.rs b/src/test/ui/invalid-module-declaration/auxiliary/foo/bar.rs
new file mode 100644 (file)
index 0000000..4b6b4f5
--- /dev/null
@@ -0,0 +1,11 @@
+// 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.
+//
+// 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.
+
+pub mod baz;
diff --git a/src/test/ui/invalid-module-declaration/auxiliary/foo/mod.rs b/src/test/ui/invalid-module-declaration/auxiliary/foo/mod.rs
new file mode 100644 (file)
index 0000000..6d77fb6
--- /dev/null
@@ -0,0 +1,11 @@
+// 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.
+//
+// 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.
+
+pub mod bar;
diff --git a/src/test/ui/invalid-module-declaration/invalid-module-declaration.rs b/src/test/ui/invalid-module-declaration/invalid-module-declaration.rs
new file mode 100644 (file)
index 0000000..c15cfb8
--- /dev/null
@@ -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.
+
+// ignore-tidy-linelength
+
+// error-pattern: cannot declare a new module at this location
+// error-pattern: maybe move this module
+
+mod auxiliary {
+    mod foo;
+}
+
+fn main() {}
diff --git a/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr b/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr
new file mode 100644 (file)
index 0000000..3e9b21c
--- /dev/null
@@ -0,0 +1,14 @@
+error: cannot declare a new module at this location
+  --> $DIR/auxiliary/foo/bar.rs:11:9
+   |
+11 | pub mod baz;
+   |         ^^^
+   |
+note: maybe move this module `$DIR/auxiliary/foo/bar.rs` to its own directory via `$DIR/auxiliary/foo/bar/mod.rs`
+  --> $DIR/auxiliary/foo/bar.rs:11:9
+   |
+11 | pub mod baz;
+   |         ^^^
+
+error: aborting due to previous error
+
index 6264d11186452b7e164eeb354acd5a60be80c855..29fea052b06c2f0c447dde602dbf40d001f0a33c 100644 (file)
@@ -21,8 +21,11 @@ struct Test<'a> {
 fn call<F>(mut f: F) where F: FnMut(Fn) {
     f(Box::new(|| {
     //~^ ERROR: cannot borrow `f` as mutable more than once
+    //~| NOTE first mutable borrow occurs here
+    //~| NOTE second mutable borrow occurs here
         f((Box::new(|| {})))
     }));
+    //~^ NOTE first borrow ends here
 }
 
 fn test1() {
@@ -32,7 +35,10 @@ fn test1() {
 }
 
 fn test2<F>(f: &F) where F: FnMut() {
-    (*f)(); //~ ERROR: cannot borrow immutable borrowed content `*f` as mutable
+    //~^ NOTE use `&mut F` here to make mutable
+    (*f)();
+    //~^ ERROR cannot borrow immutable borrowed content `*f` as mutable
+    //~| NOTE cannot borrow as mutable
 }
 
 fn test3<F>(f: &mut F) where F: FnMut() {
@@ -40,7 +46,10 @@ fn test3<F>(f: &mut F) where F: FnMut() {
 }
 
 fn test4(f: &Test) {
-    f.f.call_mut(()) //~ ERROR: cannot borrow immutable `Box` content `*f.f` as mutable
+    //~^ NOTE use `&mut Test` here to make mutable
+    f.f.call_mut(())
+    //~^ ERROR: cannot borrow immutable `Box` content `*f.f` as mutable
+    //~| NOTE cannot borrow as mutable
 }
 
 fn test5(f: &mut Test) {
@@ -57,10 +66,14 @@ fn test6() {
 fn test7() {
     fn foo<F>(_: F) where F: FnMut(Box<FnMut(isize)>, isize) {}
     let mut f = |g: Box<FnMut(isize)>, b: isize| {};
+    //~^ NOTE moved
     f(Box::new(|a| {
+    //~^ NOTE borrow of `f` occurs here
         foo(f);
         //~^ ERROR cannot move `f` into closure because it is borrowed
         //~| ERROR cannot move out of captured outer variable in an `FnMut` closure
+        //~| NOTE move into closure occurs here
+        //~| NOTE cannot move out of captured outer variable in an `FnMut` closure
     }), 3);
 }
 
index 58b3f205fe35289c9dc185c3ab32ab6f0cf4e2c9..4ece8bc6af10fb06867356f608244c382ff823a5 100644 (file)
@@ -5,40 +5,46 @@ error[E0499]: cannot borrow `f` as mutable more than once at a time
    |     -          ^^ second mutable borrow occurs here
    |     |
    |     first mutable borrow occurs here
-23 |     //~^ ERROR: cannot borrow `f` as mutable more than once
-24 |         f((Box::new(|| {})))
+...
+26 |         f((Box::new(|| {})))
    |         - borrow occurs due to use of `f` in closure
-25 |     }));
+27 |     }));
    |       - first borrow ends here
 
 error: cannot borrow immutable borrowed content `*f` as mutable
-  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:35:5
+  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:39:5
    |
-34 | fn test2<F>(f: &F) where F: FnMut() {
+37 | fn test2<F>(f: &F) where F: FnMut() {
    |                -- use `&mut F` here to make mutable
-35 |     (*f)(); //~ ERROR: cannot borrow immutable borrowed content `*f` as mutable
+38 |     //~^ NOTE use `&mut F` here to make mutable
+39 |     (*f)();
    |     ^^^^ cannot borrow as mutable
 
 error: cannot borrow immutable `Box` content `*f.f` as mutable
-  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:43:5
+  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:50:5
    |
-42 | fn test4(f: &Test) {
+48 | fn test4(f: &Test) {
    |             ----- use `&mut Test` here to make mutable
-43 |     f.f.call_mut(()) //~ ERROR: cannot borrow immutable `Box` content `*f.f` as mutable
+49 |     //~^ NOTE use `&mut Test` here to make mutable
+50 |     f.f.call_mut(())
    |     ^^^ cannot borrow as mutable
 
 error[E0504]: cannot move `f` into closure because it is borrowed
-  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:61:13
+  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:72:13
    |
-60 |     f(Box::new(|a| {
+70 |     f(Box::new(|a| {
    |     - borrow of `f` occurs here
-61 |         foo(f);
+71 |     //~^ NOTE borrow of `f` occurs here
+72 |         foo(f);
    |             ^ move into closure occurs here
 
 error[E0507]: cannot move out of captured outer variable in an `FnMut` closure
-  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:61:13
+  --> $DIR/borrowck-call-is-borrow-issue-12224.rs:72:13
    |
-61 |         foo(f);
+68 |     let mut f = |g: Box<FnMut(isize)>, b: isize| {};
+   |         ----- captured outer variable
+...
+72 |         foo(f);
    |             ^ cannot move out of captured outer variable in an `FnMut` closure
 
 error: aborting due to 5 previous errors
index 3d8f2296236a2014c6c60df5657c7ab5fd522b26..dbda8f4d802c02a0f6689a7709a59fd8aea7602a 100644 (file)
@@ -20,6 +20,8 @@ pub fn dylib_env_var() -> &'static str {
         "PATH"
     } else if cfg!(target_os = "macos") {
         "DYLD_LIBRARY_PATH"
+    } else if cfg!(target_os = "haiku") {
+        "LIBRARY_PATH"
     } else {
         "LD_LIBRARY_PATH"
     }