]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #54993 - TimNN:pda-tdl, r=eddyb
authorbors <bors@rust-lang.org>
Sun, 11 Nov 2018 03:44:16 +0000 (03:44 +0000)
committerbors <bors@rust-lang.org>
Sun, 11 Nov 2018 03:44:16 +0000 (03:44 +0000)
Support for the program data address space option of LLVM's Target Datalayout

This was introduced recently (specifically, for AVR, cc @dylanmckay).

(I came up with this when attempting to run [avr-rust](https://github.com/avr-rust/rust) rebased on the latest [rust-lang](https://github.com/rust-lang/rust) commits. If this requires a different design, some additional discussions, or is not something to pursue right now, I'd be happy to close this PR).

Note that this somewhat overlaps with @DiamondLovesYou's #51576, I think, although the implementation here is significantly simpler: Since the address space applies to _all_ program data, we can just check the pointee's type whenever we create an LLVM pointer type. If it is a function we use the program data address space; if not we use the default address space.

cc @eddyb, who has been reviewing #51576

Ref: https://llvm.org/docs/LangRef.html#data-layout

89 files changed:
src/Cargo.lock
src/bootstrap/compile.rs
src/ci/docker/asmjs/Dockerfile
src/ci/docker/disabled/wasm32/Dockerfile
src/ci/docker/scripts/emscripten.sh
src/libcore/intrinsics.rs
src/libcore/num/mod.rs
src/libpanic_abort/lib.rs
src/librustc/hir/lowering.rs
src/librustc/infer/error_reporting/mod.rs
src/librustc/mir/mod.rs
src/librustc/mir/tcx.rs
src/librustc/session/config.rs
src/librustc/traits/project.rs
src/librustc/traits/specialize/mod.rs
src/librustc/ty/query/on_disk_cache.rs
src/librustc_codegen_llvm/abi.rs
src/librustc_codegen_llvm/back/archive.rs
src/librustc_codegen_llvm/back/bytecode.rs
src/librustc_codegen_llvm/back/link.rs
src/librustc_codegen_llvm/back/lto.rs
src/librustc_codegen_llvm/back/rpath.rs
src/librustc_codegen_llvm/back/wasm.rs
src/librustc_codegen_llvm/back/write.rs
src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/builder.rs
src/librustc_codegen_llvm/context.rs
src/librustc_codegen_llvm/debuginfo/metadata.rs
src/librustc_codegen_llvm/intrinsic.rs
src/librustc_codegen_llvm/llvm/ffi.rs
src/librustc_codegen_llvm/llvm_util.rs
src/librustc_codegen_llvm/mir/block.rs
src/librustc_codegen_llvm/mir/mod.rs
src/librustc_codegen_llvm/mir/operand.rs
src/librustc_codegen_utils/linker.rs
src/librustc_codegen_utils/symbol_export.rs
src/librustc_errors/emitter.rs
src/librustc_mir/borrow_check/borrow_set.rs
src/librustc_mir/borrow_check/mod.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/borrow_check/used_muts.rs
src/librustc_mir/interpret/intrinsics.rs
src/librustc_mir/shim.rs
src/librustc_mir/transform/inline.rs
src/librustc_mir/transform/promote_consts.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_target/spec/linux_musl_base.rs
src/librustc_traits/type_op.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/intrinsic.rs
src/librustdoc/html/static/rustdoc.css
src/libstd/macros.rs
src/libstd/sync/mpsc/mod.rs
src/libstd/sync/mpsc/select.rs
src/libsyntax/ast.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/quote.rs
src/libsyntax/parse/parser.rs
src/llvm-emscripten
src/rustllvm/PassWrapper.cpp
src/rustllvm/RustWrapper.cpp
src/test/codegen/packed.rs
src/test/codegen/stores.rs
src/test/run-fail/mir_drop_panics.rs
src/test/run-fail/panic-set-handler.rs
src/test/run-pass/consts/const-endianess.rs
src/test/run-pass/issues/issue-13494.rs
src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs [new file with mode: 0644]
src/test/ui/coherence/coherence-impls-copy.stderr
src/test/ui/e0119/issue-28981.stderr
src/test/ui/extern/extern-const.fixed [new file with mode: 0644]
src/test/ui/extern/extern-const.rs
src/test/ui/extern/extern-const.stderr
src/test/ui/impl-trait/issue-55608-captures-empty-region.rs [new file with mode: 0644]
src/test/ui/impl-trait/issue-55608-captures-empty-region.stderr [new file with mode: 0644]
src/test/ui/inline-asm-bad-constraint.rs
src/test/ui/inline-asm-bad-constraint.stderr
src/test/ui/inline-asm-bad-operand.rs
src/test/ui/inline-asm-bad-operand.stderr
src/test/ui/issues/issue-23122-2.stderr
src/test/ui/issues/issue-49579.rs
src/test/ui/match/match-fn-call.rs [new file with mode: 0644]
src/test/ui/match/match-fn-call.stderr [new file with mode: 0644]
src/test/ui/nll/issue-55344.rs [new file with mode: 0644]
src/test/ui/range/issue-54505-no-std.rs
src/tools/cargo
src/tools/compiletest/src/runtest.rs
src/tools/rustc-workspace-hack/Cargo.toml

index b4317864502cee0fd48979f54fb6f057b47c0bcf..4db9801e01dfd0ff26e6907e213cbe124ecb373f 100644 (file)
@@ -197,7 +197,8 @@ dependencies = [
  "crates-io 0.21.0",
  "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -230,7 +231,7 @@ dependencies = [
  "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
  "shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -474,7 +475,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 name = "crates-io"
 version = "0.21.0"
 dependencies = [
- "curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -561,10 +562,10 @@ dependencies = [
 
 [[package]]
 name = "curl"
-version = "0.4.18"
+version = "0.4.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -576,7 +577,7 @@ dependencies = [
 
 [[package]]
 name = "curl-sys"
-version = "0.4.13"
+version = "0.4.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -848,7 +849,7 @@ name = "git2-curl"
 version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -966,7 +967,7 @@ dependencies = [
  "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "xz2 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1088,7 +1089,7 @@ version = "0.7.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2838,7 +2839,7 @@ dependencies = [
 
 [[package]]
 name = "tar"
-version = "0.4.16"
+version = "0.4.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3210,8 +3211,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
 "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
 "checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4"
-"checksum curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a9e5285b49b44401518c947d3b808d14d99a538a6c9ffb3ec0205c11f9fc4389"
-"checksum curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "08459503c415173da1ce6b41036a37b8bfdd86af46d45abb9964d4c61fe670ef"
+"checksum curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c7c9d851c825e0c033979d4516c9173bc19a78a96eb4d6ae51d4045440eafa16"
+"checksum curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "721c204978be2143fab0a84b708c49d79d1f6100b8785610f456043a90708870"
 "checksum datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16d724bf4ffe77cdceeecd461009b5f8d9e23c5d645d68bedb4586bf43e7e142"
 "checksum derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ceed73957c449214f8440eec8ad7fa282b67dc9eacbb24a3085b15d60397a17a"
 "checksum derive_more 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46c7f14685a20f5dd08e7f754f2ea8cc064d8f4214ae21116c106a2768ba7b9b"
@@ -3390,7 +3391,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
 "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
 "checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
-"checksum tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f41ca4a5689f06998f0247fcb60da6c760f1950cc9df2a10d71575ad0b062a"
+"checksum tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "69e16840a1e0a1f1a880b739ef1cc6a4b85496c99b8aa786ccffce6e0c15624c"
 "checksum tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c4b103c6d08d323b92ff42c8ce62abcd83ca8efa7fd5bf7927efefec75f58c76"
 "checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
 "checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561"
index 885ad07e0873604adb3b420b6eff5cee74f6ad98..cef0849937bf01861602cc947e48c63e562b2fc5 100644 (file)
@@ -736,7 +736,7 @@ pub fn build_codegen_backend(builder: &Builder,
 
             // Pass down configuration from the LLVM build into the build of
             // librustc_llvm and librustc_codegen_llvm.
-            if builder.is_rust_llvm(target) {
+            if builder.is_rust_llvm(target) && backend != "emscripten" {
                 cargo.env("LLVM_RUSTLLVM", "1");
             }
             cargo.env("LLVM_CONFIG", &llvm_config);
index cb85cf3d9e9f094f87ba6617250e55ef68a7fd42..9eaffbf83eb4e43e897c93dfc814c4b53ec2f50e 100644 (file)
@@ -20,11 +20,11 @@ COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
 ENV PATH=$PATH:/emsdk-portable
-ENV PATH=$PATH:/emsdk-portable/clang/e1.37.13_64bit/
-ENV PATH=$PATH:/emsdk-portable/emscripten/1.37.13/
-ENV PATH=$PATH:/emsdk-portable/node/4.1.1_64bit/bin/
-ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.37.13/
-ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.37.13_64bit/binaryen/
+ENV PATH=$PATH:/emsdk-portable/clang/e1.38.15_64bit/
+ENV PATH=$PATH:/emsdk-portable/emscripten/1.38.15/
+ENV PATH=$PATH:/emsdk-portable/node/8.9.1_64bit/bin/
+ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.38.15/
+ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.38.15_64bit/binaryen/
 ENV EM_CONFIG=/emsdk-portable/.emscripten
 
 ENV TARGETS=asmjs-unknown-emscripten
index 6ac90d17450a37fbac1bcd610a0b86eaa72b3f8e..0d2bd39303ef8e1191b6986be45d546842b2b734 100644 (file)
@@ -21,11 +21,11 @@ COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
 ENV PATH=$PATH:/emsdk-portable
-ENV PATH=$PATH:/emsdk-portable/clang/e1.37.13_64bit/
-ENV PATH=$PATH:/emsdk-portable/emscripten/1.37.13/
-ENV PATH=$PATH:/node-v8.0.0-linux-x64/bin/
-ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.37.13/
-ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.37.13_64bit/binaryen/
+ENV PATH=$PATH:/emsdk-portable/clang/e1.38.15_64bit/
+ENV PATH=$PATH:/emsdk-portable/emscripten/1.38.15/
+ENV PATH=$PATH:/emsdk-portable/node/8.9.1_64bit/bin/
+ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.38.15/
+ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.38.15_64bit/binaryen/
 ENV EM_CONFIG=/emsdk-portable/.emscripten
 
 ENV TARGETS=wasm32-unknown-emscripten
index d32ed6b461d858394775710d657f2cbe26bbfff4..1d7b33db9ed86b32f94ac2a78f16341052de0dda 100644 (file)
@@ -33,8 +33,8 @@ curl -fL https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portab
 
 cd /emsdk-portable
 ./emsdk update
-hide_output ./emsdk install sdk-1.37.13-64bit
-./emsdk activate sdk-1.37.13-64bit
+hide_output ./emsdk install sdk-1.38.15-64bit
+./emsdk activate sdk-1.38.15-64bit
 
 # Compile and cache libc
 source ./emsdk_env.sh
@@ -46,8 +46,3 @@ rm -f a.*
 # Make emsdk usable by any user
 cp /root/.emscripten /emsdk-portable
 chmod a+rxw -R /emsdk-portable
-
-# node 8 is required to run wasm
-cd /
-curl -sL https://nodejs.org/dist/v8.0.0/node-v8.0.0-linux-x64.tar.xz | \
-  tar -xJ
index cceae9249e45626a6642c366242bdc177232f2df..7ed6e4a8f51eb1ea2e3913c7b0cf4d5f5daff44e 100644 (file)
@@ -1465,6 +1465,20 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
     /// y < 0 or y >= N, where N is the width of T in bits.
     pub fn unchecked_shr<T>(x: T, y: T) -> T;
 
+    /// Performs rotate left.
+    /// The stabilized versions of this intrinsic are available on the integer
+    /// primitives via the `rotate_left` method. For example,
+    /// [`std::u32::rotate_left`](../../std/primitive.u32.html#method.rotate_left)
+    #[cfg(not(stage0))]
+    pub fn rotate_left<T>(x: T, y: T) -> T;
+
+    /// Performs rotate right.
+    /// The stabilized versions of this intrinsic are available on the integer
+    /// primitives via the `rotate_right` method. For example,
+    /// [`std::u32::rotate_right`](../../std/primitive.u32.html#method.rotate_right)
+    #[cfg(not(stage0))]
+    pub fn rotate_right<T>(x: T, y: T) -> T;
+
     /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `wrapping_add` method. For example,
index c6cbeea5a0ea61788979c6689e5a910bf9bd2b3e..090147c9fe4fa7ad06ba004eb2b86c3afd3864cb 100644 (file)
@@ -2301,7 +2301,12 @@ pub const fn trailing_zeros(self) -> u32 {
             #[rustc_const_unstable(feature = "const_int_rotate")]
             #[inline]
             pub const fn rotate_left(self, n: u32) -> Self {
-                (self << (n % $BITS)) | (self >> (($BITS - (n % $BITS)) % $BITS))
+                #[cfg(not(stage0))] {
+                    unsafe { intrinsics::rotate_left(self, n as $SelfT) }
+                }
+                #[cfg(stage0)] {
+                    (self << (n % $BITS)) | (self >> (($BITS - (n % $BITS)) % $BITS))
+                }
             }
         }
 
@@ -2326,7 +2331,12 @@ pub const fn rotate_left(self, n: u32) -> Self {
             #[rustc_const_unstable(feature = "const_int_rotate")]
             #[inline]
             pub const fn rotate_right(self, n: u32) -> Self {
-                (self >> (n % $BITS)) | (self << (($BITS - (n % $BITS)) % $BITS))
+                #[cfg(not(stage0))] {
+                    unsafe { intrinsics::rotate_right(self, n as $SelfT) }
+                }
+                #[cfg(stage0)] {
+                    (self >> (n % $BITS)) | (self << (($BITS - (n % $BITS)) % $BITS))
+                }
             }
         }
 
index b86928534cb244f79ccc09202963576208bf17fc..9235f8e7660a1112609a86e1f4ea85b237b15a08 100644 (file)
@@ -97,7 +97,10 @@ unsafe fn abort() -> ! {
 pub mod personalities {
     #[no_mangle]
     #[cfg(not(any(
-        target_arch = "wasm32",
+        all(
+            target_arch = "wasm32",
+            not(target_os = "emscripten"),
+        ),
         all(
             target_os = "windows",
             target_env = "gnu",
index e558d945516713d2f690d4b698cbadc6a3c6a886..dd5d4b8f6afff546875f9d0d29e4aad19e103f3a 100644 (file)
@@ -3705,7 +3705,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let ohs = P(self.lower_expr(ohs));
                 hir::ExprKind::Unary(op, ohs)
             }
-            ExprKind::Lit(ref l) => hir::ExprKind::Lit(P((**l).clone())),
+            ExprKind::Lit(ref l) => hir::ExprKind::Lit(P((*l).clone())),
             ExprKind::Cast(ref expr, ref ty) => {
                 let expr = P(self.lower_expr(expr));
                 hir::ExprKind::Cast(expr, self.lower_ty(ty, ImplTraitContext::disallowed()))
index 1963d366e7a66d5d5daa5ba3111852663416bd6c..f833ebc7ca763ec9ffab99f78e997de8249f35cc 100644 (file)
@@ -178,6 +178,7 @@ fn msg_span_from_free_region(self, region: ty::Region<'tcx>) -> (String, Option<
                 self.msg_span_from_early_bound_and_free_regions(region)
             }
             ty::ReStatic => ("the static lifetime".to_owned(), None),
+            ty::ReEmpty => ("an empty lifetime".to_owned(), None),
             _ => bug!("{:?}", region),
         }
     }
index c2014a5fdd23a088abb4d599a2df9244c2c7b714..a84226bf665d0df364b6604961f641233c728e1f 100644 (file)
@@ -304,6 +304,20 @@ pub fn vars_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
         })
     }
 
+    /// Returns an iterator over all user-declared mutable locals.
+    #[inline]
+    pub fn mut_vars_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
+        (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
+            let local = Local::new(index);
+            let decl = &self.local_decls[local];
+            if decl.is_user_variable.is_some() && decl.mutability == Mutability::Mut {
+                Some(local)
+            } else {
+                None
+            }
+        })
+    }
+
     /// Returns an iterator over all user-declared mutable arguments and locals.
     #[inline]
     pub fn mut_vars_and_args_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
index 4b53235eab4af2aa2f1a420e29b80d5ffc77f6cc..f773f46b6f58cd0d3b98c6065ab2e6b54372db7e 100644 (file)
@@ -80,7 +80,8 @@ pub fn projection_ty(self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
                          elem: &PlaceElem<'tcx>)
                          -> PlaceTy<'tcx>
     {
-        self.projection_ty_core(tcx, elem, |_, _, ty| ty)
+        self.projection_ty_core(tcx, elem, |_, _, ty| -> Result<Ty<'tcx>, ()> { Ok(ty) })
+            .unwrap()
     }
 
     /// `place_ty.projection_ty_core(tcx, elem, |...| { ... })`
@@ -88,11 +89,12 @@ pub fn projection_ty(self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
     /// `Ty` or downcast variant corresponding to that projection.
     /// The `handle_field` callback must map a `Field` to its `Ty`,
     /// (which should be trivial when `T` = `Ty`).
-    pub fn projection_ty_core<V, T>(self,
-                                    tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                                    elem: &ProjectionElem<'tcx, V, T>,
-                                    mut handle_field: impl FnMut(&Self, &Field, &T) -> Ty<'tcx>)
-                                    -> PlaceTy<'tcx>
+    pub fn projection_ty_core<V, T, E>(
+        self,
+        tcx: TyCtxt<'a, 'gcx, 'tcx>,
+        elem: &ProjectionElem<'tcx, V, T>,
+        mut handle_field: impl FnMut(&Self, &Field, &T) -> Result<Ty<'tcx>, E>)
+        -> Result<PlaceTy<'tcx>, E>
     where
         V: ::std::fmt::Debug, T: ::std::fmt::Debug
     {
@@ -142,10 +144,11 @@ pub fn projection_ty_core<V, T>(self,
                         bug!("cannot downcast non-ADT type: `{:?}`", self)
                     }
                 },
-            ProjectionElem::Field(ref f, ref fty) => PlaceTy::Ty { ty: handle_field(&self, f, fty) }
+            ProjectionElem::Field(ref f, ref fty) =>
+                PlaceTy::Ty { ty: handle_field(&self, f, fty)? },
         };
         debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer);
-        answer
+        Ok(answer)
     }
 }
 
index 5306f2c9689b10844f3796f1534b8f0b528b421a..78aabf86e300d72ae2a8784897db7bff0356a679 100644 (file)
@@ -2082,7 +2082,7 @@ pub fn build_session_options_and_crate_config(
                         error_format,
                         &format!(
                             "optimization level needs to be \
-                             between 0-3 (instead was `{}`)",
+                             between 0-3, s or z (instead was `{}`)",
                             arg
                         ),
                     );
index 6b5eb4293e0285311a0316bdf017530058d665e8..b59bd0e2388737085ad0cf6d4925c1556f78a943 100644 (file)
@@ -885,7 +885,7 @@ fn project_type<'cx, 'gcx, 'tcx>(
     let recursion_limit = *selcx.tcx().sess.recursion_limit.get();
     if obligation.recursion_depth >= recursion_limit {
         debug!("project: overflow!");
-        selcx.infcx().report_overflow_error(&obligation, true);
+        return Err(ProjectionTyError::TraitSelectionError(SelectionError::Overflow));
     }
 
     let obligation_trait_ref = &obligation.predicate.trait_ref(selcx.tcx());
index 0ce1d8f8227553ec5e3d312fa4ca6eda15635c66..d7b5dd049e35088f015a6628a1794e8489089d2b 100644 (file)
@@ -396,7 +396,10 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_, '_, '_>, impl_def_id: DefId) -> Option<
     if !substs.is_noop() {
         types_without_default_bounds.extend(substs.types());
         w.push('<');
-        w.push_str(&substs.iter().map(|k| k.to_string()).collect::<Vec<_>>().join(", "));
+        w.push_str(&substs.iter()
+            .map(|k| k.to_string())
+            .filter(|k| &k[..] != "'_")
+            .collect::<Vec<_>>().join(", "));
         w.push('>');
     }
 
index 3dc31c517169f2a0f9708186e3315cc797e74793..54550b8a2055f44214f38b818c6b8b88836201b6 100644 (file)
@@ -450,8 +450,7 @@ fn compute_cnum_map(tcx: TyCtxt<'_, '_, '_>,
                                      .map(|&(cnum, ..)| cnum)
                                      .max()
                                      .unwrap_or(0) + 1;
-            let mut map = IndexVec::new();
-            map.resize(map_size as usize, None);
+            let mut map = IndexVec::from_elem_n(None, map_size as usize);
 
             for &(prev_cnum, ref crate_name, crate_disambiguator) in prev_cnums {
                 let key = (crate_name.clone(), crate_disambiguator);
index 6b08a740675669ffe2769ee37aeb73574faf1299..03b0b04d4014694f5571b97745f9cffd48504ef3 100644 (file)
@@ -225,9 +225,10 @@ fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'ll,
                 // ...and then memcpy it to the intended destination.
                 base::call_memcpy(bx,
                                   bx.pointercast(dst.llval, Type::i8p(cx)),
+                                  self.layout.align,
                                   bx.pointercast(llscratch, Type::i8p(cx)),
+                                  scratch_align,
                                   C_usize(cx, self.layout.size.bytes()),
-                                  self.layout.align.min(scratch_align),
                                   MemFlags::empty());
 
                 bx.lifetime_end(llscratch, scratch_size);
index ce4cb1ea3a0423cac94695cb53dba75ab751be8d..54245a36017ab9e5631040292287495957d49730 100644 (file)
@@ -83,15 +83,16 @@ pub fn src_files(&mut self) -> Vec<String> {
         if self.src_archive().is_none() {
             return Vec::new()
         }
+
         let archive = self.src_archive.as_ref().unwrap().as_ref().unwrap();
-        let ret = archive.iter()
-                         .filter_map(|child| child.ok())
-                         .filter(is_relevant_child)
-                         .filter_map(|child| child.name())
-                         .filter(|name| !self.removals.iter().any(|x| x == name))
-                         .map(|name| name.to_string())
-                         .collect();
-        return ret;
+
+        archive.iter()
+               .filter_map(|child| child.ok())
+               .filter(is_relevant_child)
+               .filter_map(|child| child.name())
+               .filter(|name| !self.removals.iter().any(|x| x == name))
+               .map(|name| name.to_owned())
+               .collect()
     }
 
     fn src_archive(&mut self) -> Option<&ArchiveRO> {
@@ -171,7 +172,7 @@ pub fn add_file(&mut self, file: &Path) {
         let name = file.file_name().unwrap().to_str().unwrap();
         self.additions.push(Addition::File {
             path: file.to_path_buf(),
-            name_in_archive: name.to_string(),
+            name_in_archive: name.to_owned(),
         });
     }
 
@@ -184,13 +185,8 @@ pub fn update_symbols(&mut self) {
     /// Combine the provided files, rlibs, and native libraries into a single
     /// `Archive`.
     pub fn build(&mut self) {
-        let kind = match self.llvm_archive_kind() {
-            Ok(kind) => kind,
-            Err(kind) => {
-                self.config.sess.fatal(&format!("Don't know how to build archive of type: {}",
-                                                kind));
-            }
-        };
+        let kind = self.llvm_archive_kind().unwrap_or_else(|kind|
+            self.config.sess.fatal(&format!("Don't know how to build archive of type: {}", kind)));
 
         if let Err(e) = self.build_with_llvm(kind) {
             self.config.sess.fatal(&format!("failed to build archive: {}", e));
@@ -281,10 +277,9 @@ fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> {
             let ret = if r.into_result().is_err() {
                 let err = llvm::LLVMRustGetLastError();
                 let msg = if err.is_null() {
-                    "failed to write archive".to_string()
+                    "failed to write archive".into()
                 } else {
                     String::from_utf8_lossy(CStr::from_ptr(err).to_bytes())
-                            .into_owned()
                 };
                 Err(io::Error::new(io::ErrorKind::Other, msg))
             } else {
@@ -293,7 +288,7 @@ fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> {
             for member in members {
                 llvm::LLVMRustArchiveMemberFree(member);
             }
-            return ret
+            ret
         }
     }
 }
index 9a3dd9d2f88147bb3f0607f15811630698883323..0b264de18c124b4f19567053dccfe96506a8f980 100644 (file)
@@ -42,7 +42,7 @@
 
 // This is the "magic number" expected at the beginning of a LLVM bytecode
 // object in an rlib.
-pub const RLIB_BYTECODE_OBJECT_MAGIC: &'static [u8] = b"RUST_OBJECT";
+pub const RLIB_BYTECODE_OBJECT_MAGIC: &[u8] = b"RUST_OBJECT";
 
 // The version number this compiler will write to bytecode objects in rlibs
 pub const RLIB_BYTECODE_OBJECT_VERSION: u8 = 2;
@@ -106,39 +106,39 @@ pub struct DecodedBytecode<'a> {
 }
 
 impl<'a> DecodedBytecode<'a> {
-    pub fn new(data: &'a [u8]) -> Result<DecodedBytecode<'a>, String> {
+    pub fn new(data: &'a [u8]) -> Result<DecodedBytecode<'a>, &'static str> {
         if !data.starts_with(RLIB_BYTECODE_OBJECT_MAGIC) {
-            return Err("magic bytecode prefix not found".to_string())
+            return Err("magic bytecode prefix not found")
         }
         let data = &data[RLIB_BYTECODE_OBJECT_MAGIC.len()..];
         if !data.starts_with(&[RLIB_BYTECODE_OBJECT_VERSION, 0, 0, 0]) {
-            return Err("wrong version prefix found in bytecode".to_string())
+            return Err("wrong version prefix found in bytecode")
         }
         let data = &data[4..];
         if data.len() < 4 {
-            return Err("bytecode corrupted".to_string())
+            return Err("bytecode corrupted")
         }
         let identifier_len = unsafe {
             u32::from_le(ptr::read_unaligned(data.as_ptr() as *const u32)) as usize
         };
         let data = &data[4..];
         if data.len() < identifier_len {
-            return Err("bytecode corrupted".to_string())
+            return Err("bytecode corrupted")
         }
         let identifier = match str::from_utf8(&data[..identifier_len]) {
             Ok(s) => s,
-            Err(_) => return Err("bytecode corrupted".to_string())
+            Err(_) => return Err("bytecode corrupted")
         };
         let data = &data[identifier_len..];
         if data.len() < 8 {
-            return Err("bytecode corrupted".to_string())
+            return Err("bytecode corrupted")
         }
         let bytecode_len = unsafe {
             u64::from_le(ptr::read_unaligned(data.as_ptr() as *const u64)) as usize
         };
         let data = &data[8..];
         if data.len() < bytecode_len {
-            return Err("bytecode corrupted".to_string())
+            return Err("bytecode corrupted")
         }
         let encoded_bytecode = &data[..bytecode_len];
 
index dd95c3d986299491466baebddfd2d84a1c39e6b9..111637b6aa967800090441756dced4a984e29572 100644 (file)
@@ -47,8 +47,8 @@
 use syntax::attr;
 
 pub use rustc_codegen_utils::link::{find_crate_name, filename_for_input, default_output_for_target,
-                                  invalid_output_for_target, out_filename, check_file_is_writeable,
-                                  filename_for_metadata};
+                                    invalid_output_for_target, filename_for_metadata,
+                                    out_filename, check_file_is_writeable};
 
 // The third parameter is for env vars, used on windows to set up the
 // path for MSVC to find its DLLs, and gcc to find its bundled
@@ -107,13 +107,10 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB
 }
 
 pub fn remove(sess: &Session, path: &Path) {
-    match fs::remove_file(path) {
-        Ok(..) => {}
-        Err(e) => {
-            sess.err(&format!("failed to remove {}: {}",
-                             path.display(),
-                             e));
-        }
+    if let Err(e) = fs::remove_file(path) {
+        sess.err(&format!("failed to remove {}: {}",
+                          path.display(),
+                          e));
     }
 }
 
@@ -147,9 +144,7 @@ pub(crate) fn link_binary(sess: &Session,
 
     // Remove the temporary object file and metadata if we aren't saving temps
     if !sess.opts.cg.save_temps {
-        if sess.opts.output_types.should_codegen() &&
-            !preserve_objects_for_their_debuginfo(sess)
-        {
+        if sess.opts.output_types.should_codegen() && !preserve_objects_for_their_debuginfo(sess) {
             for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
                 remove(sess, obj);
             }
@@ -186,7 +181,7 @@ fn preserve_objects_for_their_debuginfo(sess: &Session) -> bool {
     // the objects as they're losslessly contained inside the archives.
     let output_linked = sess.crate_types.borrow()
         .iter()
-        .any(|x| *x != config::CrateType::Rlib && *x != config::CrateType::Staticlib);
+        .any(|&x| x != config::CrateType::Rlib && x != config::CrateType::Staticlib);
     if !output_linked {
         return false
     }
@@ -270,7 +265,7 @@ pub(crate) fn ignored_for_lto(sess: &Session, info: &CrateInfo, cnum: CrateNum)
     // crates providing these functions don't participate in LTO (e.g.
     // no_builtins or compiler builtins crates).
     !sess.target.target.options.no_builtins &&
-        (info.is_no_builtins.contains(&cnum) || info.compiler_builtins == Some(cnum))
+        (info.compiler_builtins == Some(cnum) || info.is_no_builtins.contains(&cnum))
 }
 
 fn link_binary_output(sess: &Session,
@@ -291,13 +286,10 @@ fn link_binary_output(sess: &Session,
         // final destination, with a `fs::rename` call. In order for the rename to
         // always succeed, the temporary file needs to be on the same filesystem,
         // which is why we create it inside the output directory specifically.
-        let metadata_tmpdir = match TempFileBuilder::new()
+        let metadata_tmpdir = TempFileBuilder::new()
             .prefix("rmeta")
             .tempdir_in(out_filename.parent().unwrap())
-        {
-            Ok(tmpdir) => tmpdir,
-            Err(err) => sess.fatal(&format!("couldn't create a temp dir: {}", err)),
-        };
+            .unwrap_or_else(|err| sess.fatal(&format!("couldn't create a temp dir: {}", err)));
         let metadata = emit_metadata(sess, codegen_results, &metadata_tmpdir);
         if let Err(e) = fs::rename(metadata, &out_filename) {
             sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
@@ -305,10 +297,8 @@ fn link_binary_output(sess: &Session,
         out_filenames.push(out_filename);
     }
 
-    let tmpdir = match TempFileBuilder::new().prefix("rustc").tempdir() {
-        Ok(tmpdir) => tmpdir,
-        Err(err) => sess.fatal(&format!("couldn't create a temp dir: {}", err)),
-    };
+    let tmpdir = TempFileBuilder::new().prefix("rustc").tempdir().unwrap_or_else(|err|
+        sess.fatal(&format!("couldn't create a temp dir: {}", err)));
 
     if outputs.outputs.should_codegen() {
         let out_filename = out_filename(sess, crate_type, outputs, crate_name);
@@ -342,7 +332,8 @@ fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
     sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| {
         search.push(path.to_path_buf());
     });
-    return search;
+
+    search
 }
 
 fn archive_config<'a>(sess: &'a Session,
@@ -814,8 +805,8 @@ fn escape_string(s: &[u8]) -> String {
                     .unwrap_or_else(|_| {
                         let mut x = "Non-UTF-8 output: ".to_string();
                         x.extend(s.iter()
-                                 .flat_map(|&b| ascii::escape_default(b))
-                                 .map(|b| char::from_u32(b as u32).unwrap()));
+                                  .flat_map(|&b| ascii::escape_default(b))
+                                  .map(char::from));
                         x
                     })
             }
@@ -870,9 +861,8 @@ fn escape_string(s: &[u8]) -> String {
         sess.opts.debuginfo != DebugInfo::None &&
         !preserve_objects_for_their_debuginfo(sess)
     {
-        match Command::new("dsymutil").arg(out_filename).output() {
-            Ok(..) => {}
-            Err(e) => sess.fatal(&format!("failed to run dsymutil: {}", e)),
+        if let Err(e) = Command::new("dsymutil").arg(out_filename).output() {
+            sess.fatal(&format!("failed to run dsymutil: {}", e))
         }
     }
 
@@ -1012,8 +1002,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 // ensure the line is interpreted as one whole argument.
                 for c in self.arg.chars() {
                     match c {
-                        '\\' |
-                        ' ' => write!(f, "\\{}", c)?,
+                        '\\' | ' ' => write!(f, "\\{}", c)?,
                         c => write!(f, "{}", c)?,
                     }
                 }
@@ -1426,7 +1415,6 @@ fn link_sanitizer_runtime(cmd: &mut dyn Linker,
         for f in archive.src_files() {
             if f.ends_with(RLIB_BYTECODE_EXTENSION) || f == METADATA_FILENAME {
                 archive.remove_file(&f);
-                continue
             }
         }
 
index 3d96fef7c0d6f09e9e47f93c52e475fd0d700627..76faffa25216af79e9aad8667ab8e97d3deaee80 100644 (file)
@@ -205,11 +205,11 @@ pub(crate) fn run(cgcx: &CodegenContext,
         Lto::Fat => {
             assert!(cached_modules.is_empty());
             let opt_jobs = fat_lto(cgcx,
-                                  &diag_handler,
-                                  modules,
-                                  upstream_modules,
-                                  &symbol_white_list,
-                                  timeline);
+                                   &diag_handler,
+                                   modules,
+                                   upstream_modules,
+                                   &symbol_white_list,
+                                   timeline);
             opt_jobs.map(|opt_jobs| (opt_jobs, vec![]))
         }
         Lto::Thin |
@@ -296,7 +296,7 @@ fn fat_lto(cgcx: &CodegenContext,
                 let data = bc_decoded.data();
                 linker.add(&data).map_err(|()| {
                     let msg = format!("failed to load bc of {:?}", name);
-                    write::llvm_err(&diag_handler, msg)
+                    write::llvm_err(&diag_handler, &msg)
                 })
             })?;
             timeline.record(&format!("link {:?}", name));
@@ -310,8 +310,8 @@ fn fat_lto(cgcx: &CodegenContext,
         unsafe {
             let ptr = symbol_white_list.as_ptr();
             llvm::LLVMRustRunRestrictionPass(llmod,
-                                            ptr as *const *const libc::c_char,
-                                            symbol_white_list.len() as libc::size_t);
+                                             ptr as *const *const libc::c_char,
+                                             symbol_white_list.len() as libc::size_t);
             cgcx.save_temp_bitcode(&module, "lto.after-restriction");
         }
 
@@ -490,7 +490,7 @@ fn thin_lto(cgcx: &CodegenContext,
             symbol_white_list.as_ptr(),
             symbol_white_list.len() as u32,
         ).ok_or_else(|| {
-            write::llvm_err(&diag_handler, "failed to prepare thin LTO context".to_string())
+            write::llvm_err(&diag_handler, "failed to prepare thin LTO context")
         })?;
 
         info!("thin LTO data created");
@@ -617,8 +617,7 @@ fn run_pass_manager(cgcx: &CodegenContext,
             llvm::LLVMRustAddPass(pm, pass.unwrap());
         }
 
-        time_ext(cgcx.time_passes, None, "LTO passes", ||
-             llvm::LLVMRunPassManager(pm, llmod));
+        time_ext(cgcx.time_passes, None, "LTO passes", || llvm::LLVMRunPassManager(pm, llmod));
 
         llvm::LLVMDisposePassManager(pm);
     }
@@ -747,7 +746,7 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
     {
         let diag_handler = cgcx.create_diag_handler();
         let tm = (cgcx.tm_factory)().map_err(|e| {
-            write::llvm_err(&diag_handler, e)
+            write::llvm_err(&diag_handler, &e)
         })?;
 
         // Right now the implementation we've got only works over serialized
@@ -762,7 +761,7 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
             self.data().len(),
             self.shared.module_names[self.idx].as_ptr(),
         ).ok_or_else(|| {
-            let msg = "failed to parse bitcode for thin LTO module".to_string();
+            let msg = "failed to parse bitcode for thin LTO module";
             write::llvm_err(&diag_handler, msg)
         })? as *const _;
         let module = ModuleCodegen {
@@ -786,7 +785,7 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
             let mut cu2 = ptr::null_mut();
             llvm::LLVMRustThinLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2);
             if !cu2.is_null() {
-                let msg = "multiple source DICompileUnits found".to_string();
+                let msg = "multiple source DICompileUnits found";
                 return Err(write::llvm_err(&diag_handler, msg))
             }
 
@@ -807,25 +806,25 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
             // You can find some more comments about these functions in the LLVM
             // bindings we've got (currently `PassWrapper.cpp`)
             if !llvm::LLVMRustPrepareThinLTORename(self.shared.data.0, llmod) {
-                let msg = "failed to prepare thin LTO module".to_string();
+                let msg = "failed to prepare thin LTO module";
                 return Err(write::llvm_err(&diag_handler, msg))
             }
             cgcx.save_temp_bitcode(&module, "thin-lto-after-rename");
             timeline.record("rename");
             if !llvm::LLVMRustPrepareThinLTOResolveWeak(self.shared.data.0, llmod) {
-                let msg = "failed to prepare thin LTO module".to_string();
+                let msg = "failed to prepare thin LTO module";
                 return Err(write::llvm_err(&diag_handler, msg))
             }
             cgcx.save_temp_bitcode(&module, "thin-lto-after-resolve");
             timeline.record("resolve");
             if !llvm::LLVMRustPrepareThinLTOInternalize(self.shared.data.0, llmod) {
-                let msg = "failed to prepare thin LTO module".to_string();
+                let msg = "failed to prepare thin LTO module";
                 return Err(write::llvm_err(&diag_handler, msg))
             }
             cgcx.save_temp_bitcode(&module, "thin-lto-after-internalize");
             timeline.record("internalize");
             if !llvm::LLVMRustPrepareThinLTOImport(self.shared.data.0, llmod) {
-                let msg = "failed to prepare thin LTO module".to_string();
+                let msg = "failed to prepare thin LTO module";
                 return Err(write::llvm_err(&diag_handler, msg))
             }
             cgcx.save_temp_bitcode(&module, "thin-lto-after-import");
@@ -920,12 +919,6 @@ unsafe fn from_thin_lto_data(data: *const llvm::ThinLTOData) -> ThinLTOImports {
 }
 
 fn module_name_to_str(c_str: &CStr) -> &str {
-    match c_str.to_str() {
-        Ok(s) => s,
-        Err(e) => {
-            bug!("Encountered non-utf8 LLVM module name `{}`: {}",
-                c_str.to_string_lossy(),
-                e)
-        }
-    }
+    c_str.to_str().unwrap_or_else(|e|
+        bug!("Encountered non-utf8 LLVM module name `{}`: {}", c_str.to_string_lossy(), e))
 }
index 9609cb0c1553b205319775ae8f6378a14c7d73ca..ee4a9b30a1a8542224ed72a67ad9318ae60d5f4a 100644 (file)
@@ -42,7 +42,7 @@ pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
 
     // Use DT_RUNPATH instead of DT_RPATH if available
     if config.linker_is_gnu {
-        flags.push("-Wl,--enable-new-dtags".to_string());
+        flags.push("-Wl,--enable-new-dtags".to_owned());
     }
 
     flags
@@ -59,7 +59,8 @@ fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
             ret.push(format!("-Wl,-rpath,{}", &(*rpath)));
         }
     }
-    return ret;
+
+    ret
 }
 
 fn get_rpaths(config: &mut RPathConfig, libs: &[PathBuf]) -> Vec<String> {
@@ -92,7 +93,8 @@ fn log_rpaths(desc: &str, rpaths: &[String]) {
 
     // Remove duplicates
     let rpaths = minimize_rpaths(&rpaths);
-    return rpaths;
+
+    rpaths
 }
 
 fn get_rpaths_relative_to_output(config: &mut RPathConfig,
@@ -117,8 +119,7 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String
     let relative = path_relative_from(&lib, &output).unwrap_or_else(||
         panic!("couldn't create relative path from {:?} to {:?}", output, lib));
     // FIXME (#9639): This needs to handle non-utf8 paths
-    format!("{}/{}", prefix,
-            relative.to_str().expect("non-utf8 component in path"))
+    format!("{}/{}", prefix, relative.to_str().expect("non-utf8 component in path"))
 }
 
 // This routine is adapted from the *old* Path's `path_relative_from`
@@ -168,7 +169,7 @@ fn get_install_prefix_rpath(config: &mut RPathConfig) -> String {
     let path = (config.get_install_prefix_lib_path)();
     let path = env::current_dir().unwrap().join(&path);
     // FIXME (#9639): This needs to handle non-utf8 paths
-    path.to_str().expect("non-utf8 component in rpath").to_string()
+    path.to_str().expect("non-utf8 component in rpath").to_owned()
 }
 
 fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
index f37854b7bcae0b3386b06c5f4d95cc68da87163d..7101255173cafd08d5bd88aecb4237b57dbc8530 100644 (file)
@@ -42,7 +42,7 @@
 /// https://github.com/llvm-mirror/llvm/commit/0f32e1365, although support still
 /// needs to be added, tracked at https://bugs.llvm.org/show_bug.cgi?id=37168
 pub fn rewrite_imports(path: &Path, import_map: &FxHashMap<String, String>) {
-    if import_map.len() == 0 {
+    if import_map.is_empty() {
         return
     }
 
@@ -127,7 +127,7 @@ impl<'a> Iterator for WasmSections<'a> {
     type Item = (u8, &'a [u8]);
 
     fn next(&mut self) -> Option<(u8, &'a [u8])> {
-        if self.0.data.len() == 0 {
+        if self.0.data.is_empty() {
             return None
         }
 
index 184be4b9eab39d76841af69ce451f065c2ee9757..8973852caa86b351d594d5ae1e730198ade33fe6 100644 (file)
@@ -64,7 +64,7 @@
 use std::thread;
 use libc::{c_uint, c_void, c_char, size_t};
 
-pub const RELOC_MODEL_ARGS : [(&'static str, llvm::RelocMode); 7] = [
+pub const RELOC_MODEL_ARGS : [(&str, llvm::RelocMode); 7] = [
     ("pic", llvm::RelocMode::PIC),
     ("static", llvm::RelocMode::Static),
     ("default", llvm::RelocMode::Default),
@@ -81,7 +81,7 @@
     ("large", llvm::CodeModel::Large),
 ];
 
-pub const TLS_MODEL_ARGS : [(&'static str, llvm::ThreadLocalMode); 4] = [
+pub const TLS_MODEL_ARGS : [(&str, llvm::ThreadLocalMode); 4] = [
     ("global-dynamic", llvm::ThreadLocalMode::GeneralDynamic),
     ("local-dynamic", llvm::ThreadLocalMode::LocalDynamic),
     ("initial-exec", llvm::ThreadLocalMode::InitialExec),
@@ -90,7 +90,7 @@
 
 const PRE_THIN_LTO_BC_EXT: &str = "pre-thin-lto.bc";
 
-pub fn llvm_err(handler: &errors::Handler, msg: String) -> FatalError {
+pub fn llvm_err(handler: &errors::Handler, msg: &str) -> FatalError {
     match llvm::last_error() {
         Some(err) => handler.fatal(&format!("{}: {}", msg, err)),
         None => handler.fatal(&msg),
@@ -106,11 +106,10 @@ pub fn write_output_file(
         file_type: llvm::FileType) -> Result<(), FatalError> {
     unsafe {
         let output_c = path2cstr(output);
-        let result = llvm::LLVMRustWriteOutputFile(
-                target, pm, m, output_c.as_ptr(), file_type);
+        let result = llvm::LLVMRustWriteOutputFile(target, pm, m, output_c.as_ptr(), file_type);
         if result.into_result().is_err() {
             let msg = format!("could not write output to {}", output.display());
-            Err(llvm_err(handler, msg))
+            Err(llvm_err(handler, &msg))
         } else {
             Ok(())
         }
@@ -140,7 +139,7 @@ pub fn create_target_machine(
     find_features: bool,
 ) -> &'static mut llvm::TargetMachine {
     target_machine_factory(sess, find_features)().unwrap_or_else(|err| {
-        llvm_err(sess.diagnostic(), err).raise()
+        llvm_err(sess.diagnostic(), &err).raise()
     })
 }
 
@@ -456,7 +455,7 @@ fn drop(&mut self) {
 unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext,
                                                msg: &'b str,
                                                cookie: c_uint) {
-    cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_string());
+    cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_owned());
 }
 
 unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic,
@@ -590,8 +589,7 @@ unsafe fn optimize(cgcx: &CodegenContext,
 
             for pass in &config.passes {
                 if !addpass(pass) {
-                    diag_handler.warn(&format!("unknown pass `{}`, ignoring",
-                                            pass));
+                    diag_handler.warn(&format!("unknown pass `{}`, ignoring", pass));
                 }
                 if pass == "name-anon-globals" {
                     have_name_anon_globals_pass = true;
@@ -601,8 +599,8 @@ unsafe fn optimize(cgcx: &CodegenContext,
             for pass in &cgcx.plugin_passes {
                 if !addpass(pass) {
                     diag_handler.err(&format!("a plugin asked for LLVM pass \
-                                            `{}` but LLVM does not \
-                                            recognize it", pass));
+                                               `{}` but LLVM does not \
+                                               recognize it", pass));
                 }
                 if pass == "name-anon-globals" {
                     have_name_anon_globals_pass = true;
@@ -613,12 +611,12 @@ unsafe fn optimize(cgcx: &CodegenContext,
                 // As described above, this will probably cause an error in LLVM
                 if config.no_prepopulate_passes {
                     diag_handler.err("The current compilation is going to use thin LTO buffers \
-                                     without running LLVM's NameAnonGlobals pass. \
-                                     This will likely cause errors in LLVM. Consider adding \
-                                     -C passes=name-anon-globals to the compiler command line.");
+                                      without running LLVM's NameAnonGlobals pass. \
+                                      This will likely cause errors in LLVM. Consider adding \
+                                      -C passes=name-anon-globals to the compiler command line.");
                 } else {
                     bug!("We are using thin LTO buffers without running the NameAnonGlobals pass. \
-                         This will likely cause errors in LLVM and should never happen.");
+                          This will likely cause errors in LLVM and should never happen.");
                 }
             }
         }
@@ -704,9 +702,9 @@ unsafe fn codegen(cgcx: &CodegenContext,
         // escape the closure itself, and the manager should only be
         // used once.
         unsafe fn with_codegen<'ll, F, R>(tm: &'ll llvm::TargetMachine,
-                                    llmod: &'ll llvm::Module,
-                                    no_builtins: bool,
-                                    f: F) -> R
+                                          llmod: &'ll llvm::Module,
+                                          no_builtins: bool,
+                                          f: F) -> R
             where F: FnOnce(&'ll mut PassManager<'ll>) -> R,
         {
             let cpm = llvm::LLVMCreatePassManager();
@@ -818,7 +816,7 @@ extern "C" fn demangle_callback(input_ptr: *const c_char,
                 };
                 with_codegen(tm, llmod, config.no_builtins, |cpm| {
                     write_output_file(diag_handler, tm, cpm, llmod, &path,
-                                    llvm::FileType::AssemblyFile)
+                                      llvm::FileType::AssemblyFile)
                 })?;
                 timeline.record("asm");
             }
@@ -826,7 +824,7 @@ extern "C" fn demangle_callback(input_ptr: *const c_char,
             if write_obj {
                 with_codegen(tm, llmod, config.no_builtins, |cpm| {
                     write_output_file(diag_handler, tm, cpm, llmod, &obj_out,
-                                    llvm::FileType::ObjectFile)
+                                      llvm::FileType::ObjectFile)
                 })?;
                 timeline.record("obj");
             } else if asm_to_obj {
@@ -947,11 +945,11 @@ fn need_pre_thin_lto_bitcode_for_incr_comp(sess: &Session) -> bool {
 }
 
 pub fn start_async_codegen(tcx: TyCtxt,
-                               time_graph: Option<TimeGraph>,
-                               metadata: EncodedMetadata,
-                               coordinator_receive: Receiver<Box<dyn Any + Send>>,
-                               total_cgus: usize)
-                               -> OngoingCodegen {
+                           time_graph: Option<TimeGraph>,
+                           metadata: EncodedMetadata,
+                           coordinator_receive: Receiver<Box<dyn Any + Send>>,
+                           total_cgus: usize)
+                           -> OngoingCodegen {
     let sess = tcx.sess;
     let crate_name = tcx.crate_name(LOCAL_CRATE);
     let crate_hash = tcx.crate_hash(LOCAL_CRATE);
@@ -1116,7 +1114,8 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
         }
 
         if let Some((id, product)) =
-                copy_cgu_workproducts_to_incr_comp_cache_dir(sess, &module.name, &files) {
+            copy_cgu_workproducts_to_incr_comp_cache_dir(sess, &module.name, &files)
+        {
             work_products.insert(id, product);
         }
     }
@@ -1441,15 +1440,12 @@ fn execute_copy_from_cache_work_item(cgcx: &CodegenContext,
                module.name,
                source_file,
                obj_out.display());
-        match link_or_copy(&source_file, &obj_out) {
-            Ok(_) => { }
-            Err(err) => {
-                let diag_handler = cgcx.create_diag_handler();
-                diag_handler.err(&format!("unable to copy {} to {}: {}",
-                                          source_file.display(),
-                                          obj_out.display(),
-                                          err));
-            }
+        if let Err(err) = link_or_copy(&source_file, &obj_out) {
+            let diag_handler = cgcx.create_diag_handler();
+            diag_handler.err(&format!("unable to copy {} to {}: {}",
+                                      source_file.display(),
+                                      obj_out.display(),
+                                      err));
         }
     }
 
@@ -1584,10 +1580,8 @@ fn start_executing_work(tcx: TyCtxt,
 
         let (name, mut cmd) = get_linker(sess, &linker, flavor);
         cmd.args(&sess.target.target.options.asm_args);
-        Some(Arc::new(AssemblerCommand {
-            name,
-            cmd,
-        }))
+
+        Some(Arc::new(AssemblerCommand { name, cmd }))
     } else {
         None
     };
@@ -2186,9 +2180,9 @@ pub fn run_assembler(cgcx: &CodegenContext, handler: &Handler, assembly: &Path,
                 handler.struct_err(&format!("linking with `{}` failed: {}",
                                             pname.display(),
                                             prog.status))
-                    .note(&format!("{:?}", &cmd))
-                    .note(str::from_utf8(&note[..]).unwrap())
-                    .emit();
+                       .note(&format!("{:?}", &cmd))
+                       .note(str::from_utf8(&note[..]).unwrap())
+                       .emit();
                 handler.abort_if_errors();
             }
         },
@@ -2450,8 +2444,8 @@ pub(crate) fn join(
     }
 
     pub(crate) fn submit_pre_codegened_module_to_llvm(&self,
-                                                       tcx: TyCtxt,
-                                                       module: ModuleCodegen) {
+                                                      tcx: TyCtxt,
+                                                      module: ModuleCodegen) {
         self.wait_for_signal_to_codegen_item();
         self.check_for_errors(tcx.sess);
 
index fb33fe85b005441782f340c8f880a687273bbf3e..806025937cb110c75028094c56caee1e6fda7f1e 100644 (file)
@@ -53,7 +53,7 @@
 use attributes;
 use builder::{Builder, MemFlags};
 use callee;
-use common::{C_bool, C_bytes_in_context, C_i32, C_usize};
+use common::{C_bool, C_bytes_in_context, C_usize};
 use rustc_mir::monomorphize::item::DefPathBasedNames;
 use common::{C_struct_in_context, C_array, val_ty};
 use consts;
@@ -77,7 +77,6 @@
 use std::any::Any;
 use std::cmp;
 use std::ffi::CString;
-use std::i32;
 use std::ops::{Deref, DerefMut};
 use std::sync::mpsc;
 use std::time::{Instant, Duration};
@@ -319,8 +318,8 @@ pub fn coerce_unsized_into(
                 }
 
                 if src_f.layout.ty == dst_f.layout.ty {
-                    memcpy_ty(bx, dst_f.llval, src_f.llval, src_f.layout,
-                              src_f.align.min(dst_f.align), MemFlags::empty());
+                    memcpy_ty(bx, dst_f.llval, dst_f.align, src_f.llval, src_f.align,
+                              src_f.layout, MemFlags::empty());
                 } else {
                     coerce_unsized_into(bx, src_f, dst_f);
                 }
@@ -420,36 +419,34 @@ pub fn to_immediate_scalar(
 pub fn call_memcpy(
     bx: &Builder<'_, 'll, '_>,
     dst: &'ll Value,
+    dst_align: Align,
     src: &'ll Value,
+    src_align: Align,
     n_bytes: &'ll Value,
-    align: Align,
     flags: MemFlags,
 ) {
     if flags.contains(MemFlags::NONTEMPORAL) {
         // HACK(nox): This is inefficient but there is no nontemporal memcpy.
-        let val = bx.load(src, align);
+        let val = bx.load(src, src_align);
         let ptr = bx.pointercast(dst, val_ty(val).ptr_to());
-        bx.store_with_flags(val, ptr, align, flags);
+        bx.store_with_flags(val, ptr, dst_align, flags);
         return;
     }
     let cx = bx.cx;
-    let ptr_width = &cx.sess().target.target.target_pointer_width;
-    let key = format!("llvm.memcpy.p0i8.p0i8.i{}", ptr_width);
-    let memcpy = cx.get_intrinsic(&key);
     let src_ptr = bx.pointercast(src, Type::i8p(cx));
     let dst_ptr = bx.pointercast(dst, Type::i8p(cx));
     let size = bx.intcast(n_bytes, cx.isize_ty, false);
-    let align = C_i32(cx, align.abi() as i32);
-    let volatile = C_bool(cx, flags.contains(MemFlags::VOLATILE));
-    bx.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None);
+    let volatile = flags.contains(MemFlags::VOLATILE);
+    bx.memcpy(dst_ptr, dst_align.abi(), src_ptr, src_align.abi(), size, volatile);
 }
 
 pub fn memcpy_ty(
     bx: &Builder<'_, 'll, 'tcx>,
     dst: &'ll Value,
+    dst_align: Align,
     src: &'ll Value,
+    src_align: Align,
     layout: TyLayout<'tcx>,
-    align: Align,
     flags: MemFlags,
 ) {
     let size = layout.size.bytes();
@@ -457,7 +454,7 @@ pub fn memcpy_ty(
         return;
     }
 
-    call_memcpy(bx, dst, src, C_usize(bx.cx, size), align, flags);
+    call_memcpy(bx, dst, dst_align, src, src_align, C_usize(bx.cx, size), flags);
 }
 
 pub fn call_memset(
index f70a68c72489a457df330d85794677f40ce912ca..1b1a31def3759bea88c4642f44e8b7a2d5b922c8 100644 (file)
@@ -781,6 +781,24 @@ pub fn call(&self, llfn: &'ll Value, args: &[&'ll Value],
         }
     }
 
+    pub fn memcpy(&self, dst: &'ll Value, dst_align: u64,
+                  src: &'ll Value, src_align: u64,
+                  size: &'ll Value, is_volatile: bool) -> &'ll Value {
+        unsafe {
+            llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align as c_uint,
+                                      src, src_align as c_uint, size, is_volatile)
+        }
+    }
+
+    pub fn memmove(&self, dst: &'ll Value, dst_align: u64,
+                  src: &'ll Value, src_align: u64,
+                  size: &'ll Value, is_volatile: bool) -> &'ll Value {
+        unsafe {
+            llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align as c_uint,
+                                      src, src_align as c_uint, size, is_volatile)
+        }
+    }
+
     pub fn minnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
         self.count_insn("minnum");
         unsafe {
index 120449ae2af4c2518294656eaac3aa6fb68370d5..81d615b5ad70a3505ba53819730a29fa6d1227f6 100644 (file)
@@ -530,12 +530,6 @@ macro_rules! mk_struct {
     let t_v4f64 = Type::vector(t_f64, 4);
     let t_v8f64 = Type::vector(t_f64, 8);
 
-    ifn!("llvm.memcpy.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void);
-    ifn!("llvm.memcpy.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
-    ifn!("llvm.memcpy.p0i8.p0i8.i64", fn(i8p, i8p, t_i64, t_i32, i1) -> void);
-    ifn!("llvm.memmove.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void);
-    ifn!("llvm.memmove.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
-    ifn!("llvm.memmove.p0i8.p0i8.i64", fn(i8p, i8p, t_i64, t_i32, i1) -> void);
     ifn!("llvm.memset.p0i8.i16", fn(i8p, t_i8, t_i16, t_i32, i1) -> void);
     ifn!("llvm.memset.p0i8.i32", fn(i8p, t_i8, t_i32, t_i32, i1) -> void);
     ifn!("llvm.memset.p0i8.i64", fn(i8p, t_i8, t_i64, t_i32, i1) -> void);
@@ -726,6 +720,18 @@ macro_rules! mk_struct {
     ifn!("llvm.bitreverse.i64", fn(t_i64) -> t_i64);
     ifn!("llvm.bitreverse.i128", fn(t_i128) -> t_i128);
 
+    ifn!("llvm.fshl.i8", fn(t_i8, t_i8, t_i8) -> t_i8);
+    ifn!("llvm.fshl.i16", fn(t_i16, t_i16, t_i16) -> t_i16);
+    ifn!("llvm.fshl.i32", fn(t_i32, t_i32, t_i32) -> t_i32);
+    ifn!("llvm.fshl.i64", fn(t_i64, t_i64, t_i64) -> t_i64);
+    ifn!("llvm.fshl.i128", fn(t_i128, t_i128, t_i128) -> t_i128);
+
+    ifn!("llvm.fshr.i8", fn(t_i8, t_i8, t_i8) -> t_i8);
+    ifn!("llvm.fshr.i16", fn(t_i16, t_i16, t_i16) -> t_i16);
+    ifn!("llvm.fshr.i32", fn(t_i32, t_i32, t_i32) -> t_i32);
+    ifn!("llvm.fshr.i64", fn(t_i64, t_i64, t_i64) -> t_i64);
+    ifn!("llvm.fshr.i128", fn(t_i128, t_i128, t_i128) -> t_i128);
+
     ifn!("llvm.sadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
     ifn!("llvm.sadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
     ifn!("llvm.sadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
index ba1e3f5960c8596b0d4c484aff8f703fd986d8ef..00f06645930c25209560492b8421f7f042bcdfb2 100644 (file)
@@ -23,6 +23,7 @@
 use llvm;
 use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
                       DICompositeType, DILexicalBlock, DIFlags};
+use llvm_util;
 
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc::hir::CodegenFnAttrFlags;
@@ -1169,9 +1170,8 @@ fn prepare_union_metadata(
 fn use_enum_fallback(cx: &CodegenCx) -> bool {
     // On MSVC we have to use the fallback mode, because LLVM doesn't
     // lower variant parts to PDB.
-    return cx.sess().target.target.options.is_like_msvc || unsafe {
-        llvm::LLVMRustVersionMajor() < 7
-    };
+    return cx.sess().target.target.options.is_like_msvc
+        || llvm_util::get_major_version() < 7;
 }
 
 // Describes the members of an enum value: An enum is described as a union of
index e44bd2d23672fcb371facfb0459b2a351595414d..a5f90149f4ac47293715041893956d31d8c5bae2 100644 (file)
@@ -13,6 +13,7 @@
 use attributes;
 use intrinsics::{self, Intrinsic};
 use llvm::{self, TypeKind};
+use llvm_util;
 use abi::{Abi, FnType, LlvmType, PassMode};
 use mir::place::PlaceRef;
 use mir::operand::{OperandRef, OperandValue};
@@ -23,7 +24,7 @@
 use type_::Type;
 use type_of::LayoutLlvmExt;
 use rustc::ty::{self, Ty};
-use rustc::ty::layout::{HasDataLayout, LayoutOf};
+use rustc::ty::layout::LayoutOf;
 use rustc::hir;
 use syntax::ast;
 use syntax::symbol::Symbol;
@@ -284,7 +285,8 @@ pub fn codegen_intrinsic_call(
         "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" |
         "bitreverse" | "add_with_overflow" | "sub_with_overflow" |
         "mul_with_overflow" | "overflowing_add" | "overflowing_sub" | "overflowing_mul" |
-        "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" | "exact_div" => {
+        "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" | "exact_div" |
+        "rotate_left" | "rotate_right" => {
             let ty = arg_tys[0];
             match int_type_width_signed(ty, cx) {
                 Some((width, signed)) =>
@@ -363,6 +365,27 @@ pub fn codegen_intrinsic_call(
                             } else {
                                 bx.lshr(args[0].immediate(), args[1].immediate())
                             },
+                        "rotate_left" | "rotate_right" => {
+                            let is_left = name == "rotate_left";
+                            let val = args[0].immediate();
+                            let raw_shift = args[1].immediate();
+                            if llvm_util::get_major_version() >= 7 {
+                                // rotate = funnel shift with first two args the same
+                                let llvm_name = &format!("llvm.fsh{}.i{}",
+                                                         if is_left { 'l' } else { 'r' }, width);
+                                let llfn = cx.get_intrinsic(llvm_name);
+                                bx.call(llfn, &[val, val, raw_shift], None)
+                            } else {
+                                // rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
+                                // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
+                                let width = C_uint(Type::ix(cx, width), width);
+                                let shift = bx.urem(raw_shift, width);
+                                let inv_shift = bx.urem(bx.sub(width, raw_shift), width);
+                                let shift1 = bx.shl(val, if is_left { shift } else { inv_shift });
+                                let shift2 = bx.lshr(val, if !is_left { shift } else { inv_shift });
+                                bx.or(shift1, shift2)
+                            }
+                        },
                         _ => bug!(),
                     },
                 None => {
@@ -690,28 +713,14 @@ fn copy_intrinsic(
     let cx = bx.cx;
     let (size, align) = cx.size_and_align_of(ty);
     let size = C_usize(cx, size.bytes());
-    let align = C_i32(cx, align.abi() as i32);
-
-    let operation = if allow_overlap {
-        "memmove"
-    } else {
-        "memcpy"
-    };
-
-    let name = format!("llvm.{}.p0i8.p0i8.i{}", operation,
-                       cx.data_layout().pointer_size.bits());
-
+    let align = align.abi();
     let dst_ptr = bx.pointercast(dst, Type::i8p(cx));
     let src_ptr = bx.pointercast(src, Type::i8p(cx));
-    let llfn = cx.get_intrinsic(&name);
-
-    bx.call(llfn,
-        &[dst_ptr,
-        src_ptr,
-        bx.mul(size, count),
-        align,
-        C_bool(cx, volatile)],
-        None)
+    if allow_overlap {
+        bx.memmove(dst_ptr, align, src_ptr, align, bx.mul(size, count), volatile)
+    } else {
+        bx.memcpy(dst_ptr, align, src_ptr, align, bx.mul(size, count), volatile)
+    }
 }
 
 fn memset_intrinsic(
index 12d4670e4be4bed52973273fdaf37e5b3bb2b598..b994b1ffc4bce91842b64630d4d88cf2a4afc974 100644 (file)
@@ -998,6 +998,22 @@ pub fn LLVMRustBuildCall(B: &Builder<'a>,
                              Bundle: Option<&OperandBundleDef<'a>>,
                              Name: *const c_char)
                              -> &'a Value;
+    pub fn LLVMRustBuildMemCpy(B: &Builder<'a>,
+                               Dst: &'a Value,
+                               DstAlign: c_uint,
+                               Src: &'a Value,
+                               SrcAlign: c_uint,
+                               Size: &'a Value,
+                               IsVolatile: bool)
+                               -> &'a Value;
+    pub fn LLVMRustBuildMemMove(B: &Builder<'a>,
+                                Dst: &'a Value,
+                                DstAlign: c_uint,
+                                Src: &'a Value,
+                                SrcAlign: c_uint,
+                                Size: &'a Value,
+                                IsVolatile: bool)
+                                -> &'a Value;
     pub fn LLVMBuildSelect(B: &Builder<'a>,
                            If: &'a Value,
                            Then: &'a Value,
index 0a80fdddbf9fdb4197d3b0b2f937a47e2c423a18..eaa599e0cd0fa67f8382eda55fe7575f9aadf9ad 100644 (file)
@@ -243,7 +243,8 @@ pub fn target_feature_whitelist(sess: &Session)
         "hexagon" => HEXAGON_WHITELIST,
         "mips" | "mips64" => MIPS_WHITELIST,
         "powerpc" | "powerpc64" => POWERPC_WHITELIST,
-        "wasm32" => WASM_WHITELIST,
+        // wasm32 on emscripten does not support these target features
+        "wasm32" if !sess.target.target.options.is_like_emscripten => WASM_WHITELIST,
         _ => &[],
     }
 }
@@ -256,6 +257,10 @@ pub fn print_version() {
     }
 }
 
+pub fn get_major_version() -> u32 {
+    unsafe { llvm::LLVMRustVersionMajor() }
+}
+
 pub fn print_passes() {
     // Can be called without initializing LLVM
     unsafe { llvm::LLVMRustPrintPasses(); }
index a7f4c48c89bd6c99ef8e7a559e702f14d0033b26..3f9921a5cf930b68372a3584a17f6b725727d6f4 100644 (file)
@@ -784,7 +784,8 @@ fn codegen_argument(&mut self,
                     // have scary latent bugs around.
 
                     let scratch = PlaceRef::alloca(bx, arg.layout, "arg");
-                    base::memcpy_ty(bx, scratch.llval, llval, op.layout, align, MemFlags::empty());
+                    base::memcpy_ty(bx, scratch.llval, scratch.align, llval, align,
+                                    op.layout, MemFlags::empty());
                     (scratch.llval, scratch.align, true)
                 } else {
                     (llval, align, true)
index a6e2ccf92e4e3fd416a028c1950679fb0fce14a0..e5b25ea068b3b7fd463c7fabc7afd987a7cd3a0b 100644 (file)
@@ -12,6 +12,7 @@
 use libc::c_uint;
 use llvm::{self, BasicBlock};
 use llvm::debuginfo::DIScope;
+use llvm_util;
 use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts};
 use rustc::ty::layout::{LayoutOf, TyLayout};
 use rustc::mir::{self, Mir};
@@ -612,7 +613,7 @@ fn arg_local_refs(
             // doesn't actually strip the offset when splitting the closure
             // environment into its components so it ends up out of bounds.
             // (cuviper) It seems to be fine without the alloca on LLVM 6 and later.
-            let env_alloca = !env_ref && unsafe { llvm::LLVMRustVersionMajor() < 6 };
+            let env_alloca = !env_ref && llvm_util::get_major_version() < 6;
             let env_ptr = if env_alloca {
                 let scratch = PlaceRef::alloca(bx,
                     bx.cx.layout_of(tcx.mk_mut_ptr(arg.layout.ty)),
index d1b6aa7fc4280c9cfddc1486b5601a7ca2aa05ab..c76cbfcd9717711e244a7a3b6e1421be3dfd0e2c 100644 (file)
@@ -282,8 +282,8 @@ fn store_with_flags(
         }
         match self {
             OperandValue::Ref(r, None, source_align) => {
-                base::memcpy_ty(bx, dest.llval, r, dest.layout,
-                                source_align.min(dest.align), flags)
+                base::memcpy_ty(bx, dest.llval, dest.align, r, source_align,
+                                dest.layout, flags)
             }
             OperandValue::Ref(_, Some(_), _) => {
                 bug!("cannot directly store unsized values");
@@ -324,7 +324,7 @@ pub fn store_unsized(self, bx: &Builder<'a, 'll, 'tcx>, indirect_dest: PlaceRef<
         // Allocate an appropriate region on the stack, and copy the value into it
         let (llsize, _) = glue::size_and_align_of_dst(&bx, unsized_ty, Some(llextra));
         let lldst = bx.array_alloca(Type::i8(bx.cx), llsize, "unsized_tmp", max_align);
-        base::call_memcpy(&bx, lldst, llptr, llsize, min_align, flags);
+        base::call_memcpy(&bx, lldst, max_align, llptr, min_align, llsize, flags);
 
         // Store the allocated region and the extra to the indirect place.
         let indirect_operand = OperandValue::Pair(lldst, llextra);
index c1f41fd509a143fbfa03769c5b315dc163353305..ae1d77f1521893f84a705b94c03ae89b880a76b0 100644 (file)
@@ -224,9 +224,9 @@ fn push_cross_lang_lto_args(&mut self, plugin_path: Option<&OsStr>) {
 }
 
 impl<'a> Linker for GccLinker<'a> {
-    fn link_dylib(&mut self, lib: &str) { self.hint_dynamic(); self.cmd.arg(format!("-l{}",lib)); }
+    fn link_dylib(&mut self, lib: &str) { self.hint_dynamic(); self.cmd.arg(format!("-l{}", lib)); }
     fn link_staticlib(&mut self, lib: &str) {
-        self.hint_static(); self.cmd.arg(format!("-l{}",lib));
+        self.hint_static(); self.cmd.arg(format!("-l{}", lib));
     }
     fn link_rlib(&mut self, lib: &Path) { self.hint_static(); self.cmd.arg(lib); }
     fn include_path(&mut self, path: &Path) { self.cmd.arg("-L").arg(path); }
@@ -243,7 +243,7 @@ fn link_staticlib(&mut self, lib: &str) {
 
     fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
         self.hint_dynamic();
-        self.cmd.arg(format!("-l{}",lib));
+        self.cmd.arg(format!("-l{}", lib));
     }
 
     fn link_framework(&mut self, framework: &str) {
@@ -261,7 +261,7 @@ fn link_whole_staticlib(&mut self, lib: &str, search_path: &[PathBuf]) {
         self.hint_static();
         let target = &self.sess.target.target;
         if !target.options.is_like_osx {
-            self.linker_arg("--whole-archive").cmd.arg(format!("-l{}",lib));
+            self.linker_arg("--whole-archive").cmd.arg(format!("-l{}", lib));
             self.linker_arg("--no-whole-archive");
         } else {
             // -force_load is the macOS equivalent of --whole-archive, but it
@@ -343,17 +343,13 @@ fn pgo_gen(&mut self) {
     }
 
     fn debuginfo(&mut self) {
-        match self.sess.opts.debuginfo {
-            DebugInfo::None => {
-                // If we are building without debuginfo enabled and we were called with
-                // `-Zstrip-debuginfo-if-disabled=yes`, tell the linker to strip any debuginfo
-                // found when linking to get rid of symbols from libstd.
-                match self.sess.opts.debugging_opts.strip_debuginfo_if_disabled {
-                    Some(true) => { self.linker_arg("-S"); },
-                    _ => {},
-                }
-            },
-            _ => {},
+        if let DebugInfo::None = self.sess.opts.debuginfo {
+            // If we are building without debuginfo enabled and we were called with
+            // `-Zstrip-debuginfo-if-disabled=yes`, tell the linker to strip any debuginfo
+            // found when linking to get rid of symbols from libstd.
+            if let Some(true) = self.sess.opts.debugging_opts.strip_debuginfo_if_disabled {
+                self.linker_arg("-S");
+            }
         };
     }
 
@@ -373,8 +369,7 @@ fn build_dylib(&mut self, out_filename: &Path) {
             // purely to support rustbuild right now, we should get a more
             // principled solution at some point to force the compiler to pass
             // the right `-Wl,-install_name` with an `@rpath` in it.
-            if self.sess.opts.cg.rpath ||
-               self.sess.opts.debugging_opts.osx_rpath_install_name {
+            if self.sess.opts.cg.rpath || self.sess.opts.debugging_opts.osx_rpath_install_name {
                 self.linker_arg("-install_name");
                 let mut v = OsString::from("@rpath/");
                 v.push(out_filename.file_name().unwrap());
@@ -461,9 +456,8 @@ fn subsystem(&mut self, subsystem: &str) {
 
     fn finalize(&mut self) -> Command {
         self.hint_dynamic(); // Reset to default before returning the composed command line.
-        let mut cmd = Command::new("");
-        ::std::mem::swap(&mut cmd, &mut self.cmd);
-        cmd
+
+        ::std::mem::replace(&mut self.cmd, Command::new(""))
     }
 
     fn group_start(&mut self) {
@@ -715,9 +709,7 @@ fn subsystem(&mut self, subsystem: &str) {
     }
 
     fn finalize(&mut self) -> Command {
-        let mut cmd = Command::new("");
-        ::std::mem::swap(&mut cmd, &mut self.cmd);
-        cmd
+        ::std::mem::replace(&mut self.cmd, Command::new(""))
     }
 
     // MSVC doesn't need group indicators
@@ -865,7 +857,7 @@ fn export_symbols(&mut self, _tmpdir: &Path, crate_type: CrateType) {
             let res = encoder.emit_seq(symbols.len(), |encoder| {
                 for (i, sym) in symbols.iter().enumerate() {
                     encoder.emit_seq_elt(i, |encoder| {
-                        encoder.emit_str(&("_".to_string() + sym))
+                        encoder.emit_str(&("_".to_owned() + sym))
                     })?;
                 }
                 Ok(())
@@ -885,9 +877,7 @@ fn subsystem(&mut self, _subsystem: &str) {
     }
 
     fn finalize(&mut self) -> Command {
-        let mut cmd = Command::new("");
-        ::std::mem::swap(&mut cmd, &mut self.cmd);
-        cmd
+        ::std::mem::replace(&mut self.cmd, Command::new(""))
     }
 
     // Appears not necessary on Emscripten
@@ -1085,9 +1075,7 @@ fn finalize(&mut self) -> Command {
         // indicative of bugs, let's prevent them.
         self.cmd.arg("--fatal-warnings");
 
-        let mut cmd = Command::new("");
-        ::std::mem::swap(&mut cmd, &mut self.cmd);
-        cmd
+        ::std::mem::replace(&mut self.cmd, Command::new(""))
     }
 
     // Not needed for now with LLD
index 2d650f7f18d6f5654b7da9ceb4f353365b0a24be..dff7e518630e4d23628aea3f6db9000caf04a35a 100644 (file)
@@ -47,11 +47,10 @@ fn crate_export_threshold(crate_type: config::CrateType) -> SymbolExportLevel {
     }
 }
 
-pub fn crates_export_threshold(crate_types: &[config::CrateType])
-                                      -> SymbolExportLevel {
-    if crate_types.iter().any(|&crate_type| {
-        crate_export_threshold(crate_type) == SymbolExportLevel::Rust
-    }) {
+pub fn crates_export_threshold(crate_types: &[config::CrateType]) -> SymbolExportLevel {
+    if crate_types.iter().any(|&crate_type|
+        crate_export_threshold(crate_type) == SymbolExportLevel::Rust)
+    {
         SymbolExportLevel::Rust
     } else {
         SymbolExportLevel::C
@@ -359,7 +358,7 @@ fn is_unreachable_local_definition_provider(tcx: TyCtxt, def_id: DefId) -> bool
         !tcx.reachable_set(LOCAL_CRATE).0.contains(&node_id)
     } else {
         bug!("is_unreachable_local_definition called with non-local DefId: {:?}",
-              def_id)
+             def_id)
     }
 }
 
@@ -388,6 +387,16 @@ fn symbol_export_level(tcx: TyCtxt, sym_def_id: DefId) -> SymbolExportLevel {
         codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
 
     if is_extern && !std_internal {
+        // Emscripten cannot export statics, so reduce their export level here
+        if tcx.sess.target.target.options.is_like_emscripten {
+            if let Some(Node::Item(&hir::Item {
+                node: hir::ItemKind::Static(..),
+                ..
+            })) = tcx.hir.get_if_local(sym_def_id) {
+                return SymbolExportLevel::Rust;
+            }
+        }
+
         SymbolExportLevel::C
     } else {
         SymbolExportLevel::Rust
index 720e8def5ab1c2a7d30abec1e97e67649736e39e..7e69e98071d4b1fa29ad1453d8f9733f8e1e1424 100644 (file)
@@ -108,7 +108,13 @@ pub enum ColorConfig {
 impl ColorConfig {
     fn to_color_choice(&self) -> ColorChoice {
         match *self {
-            ColorConfig::Always => ColorChoice::Always,
+            ColorConfig::Always => {
+                if atty::is(atty::Stream::Stderr) {
+                    ColorChoice::Always
+                } else {
+                    ColorChoice::AlwaysAnsi
+                }
+            }
             ColorConfig::Never => ColorChoice::Never,
             ColorConfig::Auto if atty::is(atty::Stream::Stderr) => {
                 ColorChoice::Auto
index db56ce4627410408318632f98e3ee53ac4ce9279..c432826dca865de3a8cba3850b947966b462a1b1 100644 (file)
@@ -21,7 +21,6 @@
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::bit_set::BitSet;
 use std::fmt;
-use std::hash::Hash;
 use std::ops::Index;
 
 crate struct BorrowSet<'tcx> {
@@ -233,21 +232,13 @@ fn visit_assign(
 
             self.insert_as_pending_if_two_phase(location, &assigned_place, region, kind, idx);
 
-            insert(&mut self.region_map, &region, idx);
+            self.region_map.entry(region).or_default().insert(idx);
             if let Some(local) = borrowed_place.root_local() {
-                insert(&mut self.local_map, &local, idx);
+                self.local_map.entry(local).or_default().insert(idx);
             }
         }
 
-        return self.super_assign(block, assigned_place, rvalue, location);
-
-        fn insert<'a, K, V>(map: &'a mut FxHashMap<K, FxHashSet<V>>, k: &K, v: V)
-        where
-            K: Clone + Eq + Hash,
-            V: Eq + Hash,
-        {
-            map.entry(k.clone()).or_default().insert(v);
-        }
+        self.super_assign(block, assigned_place, rvalue, location)
     }
 
     fn visit_place(
index d4f00ab3bb91a217bfdf7f8738f01455ae8f6409..4e03f6f7f5e7a3e48e41f499f1af8c35672ac615 100644 (file)
@@ -281,23 +281,21 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
     // Note that this set is expected to be small - only upvars from closures
     // would have a chance of erroneously adding non-user-defined mutable vars
     // to the set.
-    let temporary_used_locals: FxHashSet<Local> = mbcx
-        .used_mut
-        .iter()
+    let temporary_used_locals: FxHashSet<Local> = mbcx.used_mut.iter()
         .filter(|&local| mbcx.mir.local_decls[*local].is_user_variable.is_none())
         .cloned()
         .collect();
-    mbcx.gather_used_muts(temporary_used_locals);
+    // For the remaining unused locals that are marked as mutable, we avoid linting any that
+    // were never initialized. These locals may have been removed as unreachable code; or will be
+    // linted as unused variables.
+    let unused_mut_locals = mbcx.mir.mut_vars_iter()
+        .filter(|local| !mbcx.used_mut.contains(local))
+        .collect();
+    mbcx.gather_used_muts(temporary_used_locals, unused_mut_locals);
 
     debug!("mbcx.used_mut: {:?}", mbcx.used_mut);
-
     let used_mut = mbcx.used_mut;
-
-    for local in mbcx
-        .mir
-        .mut_vars_and_args_iter()
-        .filter(|local| !used_mut.contains(local))
-    {
+    for local in mbcx.mir.mut_vars_and_args_iter().filter(|local| !used_mut.contains(local)) {
         if let ClearCrossCrate::Set(ref vsi) = mbcx.mir.source_scope_local_data {
             let local_decl = &mbcx.mir.local_decls[local];
 
index 734ddbc3ab9a72af39babca2f7080aac3e3577c9..a057f2f45c0105e8090de91b4e049d2f4a466523 100644 (file)
@@ -1021,20 +1021,39 @@ fn relate_type_and_user_type(
                 let v1 = ty::Contravariant.xform(v);
 
                 let tcx = self.infcx.tcx;
-                let mut projected_ty = PlaceTy::from_ty(ty);
+                let ty = self.normalize(ty, locations);
+
+                // We need to follow any provided projetions into the type.
+                //
+                // if we hit a ty var as we descend, then just skip the
+                // attempt to relate the mir local with any type.
+                #[derive(Debug)] struct HitTyVar;
+                let mut curr_projected_ty: Result<PlaceTy, HitTyVar>;
+
+                curr_projected_ty = Ok(PlaceTy::from_ty(ty));
                 for proj in &user_ty.projs {
-                    projected_ty = projected_ty.projection_ty_core(
+                    let projected_ty = if let Ok(projected_ty) = curr_projected_ty {
+                        projected_ty
+                    } else {
+                        break;
+                    };
+                    curr_projected_ty = projected_ty.projection_ty_core(
                         tcx, proj, |this, field, &()| {
-                            let ty = this.field_ty(tcx, field);
-                            self.normalize(ty, locations)
+                            if this.to_ty(tcx).is_ty_var() {
+                                Err(HitTyVar)
+                            } else {
+                                let ty = this.field_ty(tcx, field);
+                                Ok(self.normalize(ty, locations))
+                            }
                         });
                 }
                 debug!("user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}",
-                       user_ty.base, ty, user_ty.projs, projected_ty);
+                       user_ty.base, ty, user_ty.projs, curr_projected_ty);
 
-                let ty = projected_ty.to_ty(tcx);
-
-                self.relate_types(ty, v1, a, locations, category)?;
+                if let Ok(projected_ty) = curr_projected_ty {
+                    let ty = projected_ty.to_ty(tcx);
+                    self.relate_types(ty, v1, a, locations, category)?;
+                }
             }
             UserTypeAnnotation::TypeOf(def_id, canonical_substs) => {
                 let (
index dad87ed65a7d41dce53b003a4265773651b6801c..7c75fb59917c00e5b73e8eb5dff46c2a15d9c75f 100644 (file)
 // except according to those terms.
 
 use rustc::mir::visit::{PlaceContext, Visitor};
-use rustc::mir::{Local, Location, Place};
+use rustc::mir::{BasicBlock, Local, Location, Place, Statement, StatementKind, TerminatorKind};
 
 use rustc_data_structures::fx::FxHashSet;
 
 use borrow_check::MirBorrowckCtxt;
 
 impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
-    /// Walks the MIR looking for assignments to a set of locals, as part of the unused mutable
-    /// local variables lint, to update the context's `used_mut` in a single walk.
-    crate fn gather_used_muts(&mut self, locals: FxHashSet<Local>) {
-        let mut visitor = GatherUsedMutsVisitor {
-            needles: locals,
-            mbcx: self,
-        };
-        visitor.visit_mir(visitor.mbcx.mir);
+    /// Walks the MIR adding to the set of `used_mut` locals that will be ignored for the purposes
+    /// of the `unused_mut` lint.
+    ///
+    /// `temporary_used_locals` should contain locals that were found to be temporary, mutable and
+    ///  used from borrow checking. This function looks for assignments into these locals from
+    ///  user-declared locals and adds those user-defined locals to the `used_mut` set. This can
+    ///  occur due to a rare case involving upvars in closures.
+    ///
+    /// `never_initialized_mut_locals` should contain the set of user-declared mutable locals
+    ///  (not arguments) that have not already been marked as being used.
+    ///  This function then looks for assignments from statements or the terminator into the locals
+    ///  from this set and removes them from the set. This leaves only those locals that have not
+    ///  been assigned to - this set is used as a proxy for locals that were not initialized due to
+    ///  unreachable code. These locals are then considered "used" to silence the lint for them.
+    ///  See #55344 for context.
+    crate fn gather_used_muts(
+        &mut self,
+        temporary_used_locals: FxHashSet<Local>,
+        mut never_initialized_mut_locals: FxHashSet<Local>,
+    ) {
+        {
+            let mut visitor = GatherUsedMutsVisitor {
+                temporary_used_locals,
+                never_initialized_mut_locals: &mut never_initialized_mut_locals,
+                mbcx: self,
+            };
+            visitor.visit_mir(visitor.mbcx.mir);
+        }
+
+        // Take the union of the existed `used_mut` set with those variables we've found were
+        // never initialized.
+        debug!("gather_used_muts: never_initialized_mut_locals={:?}", never_initialized_mut_locals);
+        self.used_mut = self.used_mut.union(&never_initialized_mut_locals).cloned().collect();
     }
 }
 
-/// MIR visitor gathering the assignments to a set of locals, in a single walk.
-/// 'visit = the duration of the MIR walk
+/// MIR visitor for collecting used mutable variables.
+/// The 'visit lifetime represents the duration of the MIR walk.
 struct GatherUsedMutsVisitor<'visit, 'cx: 'visit, 'gcx: 'tcx, 'tcx: 'cx> {
-    needles: FxHashSet<Local>,
+    temporary_used_locals: FxHashSet<Local>,
+    never_initialized_mut_locals: &'visit mut FxHashSet<Local>,
     mbcx: &'visit mut MirBorrowckCtxt<'cx, 'gcx, 'tcx>,
 }
 
 impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'gcx, 'tcx> {
+    fn visit_terminator_kind(
+        &mut self,
+        _block: BasicBlock,
+        kind: &TerminatorKind<'tcx>,
+        _location: Location,
+    ) {
+        debug!("visit_terminator_kind: kind={:?}", kind);
+        match &kind {
+            TerminatorKind::Call { destination: Some((into, _)), .. } => {
+                if let Some(local) = into.base_local() {
+                    debug!(
+                        "visit_terminator_kind: kind={:?} local={:?} \
+                         never_initialized_mut_locals={:?}",
+                        kind, local, self.never_initialized_mut_locals
+                    );
+                    let _ = self.never_initialized_mut_locals.remove(&local);
+                }
+            },
+            _ => {},
+        }
+    }
+
+    fn visit_statement(
+        &mut self,
+        _block: BasicBlock,
+        statement: &Statement<'tcx>,
+        _location: Location,
+    ) {
+        match &statement.kind {
+            StatementKind::Assign(into, _) => {
+                // Remove any locals that we found were initialized from the
+                // `never_initialized_mut_locals` set. At the end, the only remaining locals will
+                // be those that were never initialized - we will consider those as being used as
+                // they will either have been removed by unreachable code optimizations; or linted
+                // as unused variables.
+                if let Some(local) = into.base_local() {
+                    debug!(
+                        "visit_statement: statement={:?} local={:?} \
+                         never_initialized_mut_locals={:?}",
+                        statement, local, self.never_initialized_mut_locals
+                    );
+                    let _ = self.never_initialized_mut_locals.remove(&local);
+                }
+            },
+            _ => {},
+        }
+    }
+
     fn visit_local(
         &mut self,
         local: &Local,
         place_context: PlaceContext<'tcx>,
         location: Location,
     ) {
-        if !self.needles.contains(local) {
-            return;
-        }
-
-        if place_context.is_place_assignment() {
+        if place_context.is_place_assignment() && self.temporary_used_locals.contains(local) {
             // Propagate the Local assigned at this Location as a used mutable local variable
             for moi in &self.mbcx.move_data.loc_map[location] {
                 let mpi = &self.mbcx.move_data.moves[*moi].path;
index cb2a750f4e3b6cc4a987a5fe88ee6ac31ff9833c..3eb3d7600fd31600819df3ff5efda1c006131fa0 100644 (file)
@@ -150,6 +150,24 @@ pub fn emulate_intrinsic(
                 }
                 self.write_scalar(val, dest)?;
             }
+            "rotate_left" | "rotate_right" => {
+                // rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
+                // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
+                let layout = self.layout_of(substs.type_at(0))?;
+                let val_bits = self.read_scalar(args[0])?.to_bits(layout.size)?;
+                let raw_shift_bits = self.read_scalar(args[1])?.to_bits(layout.size)?;
+                let width_bits = layout.size.bits() as u128;
+                let shift_bits = raw_shift_bits % width_bits;
+                let inv_shift_bits = (width_bits - raw_shift_bits) % width_bits;
+                let result_bits = if intrinsic_name == "rotate_left" {
+                    (val_bits << shift_bits) | (val_bits >> inv_shift_bits)
+                } else {
+                    (val_bits >> shift_bits) | (val_bits << inv_shift_bits)
+                };
+                let truncated_bits = self.truncate(result_bits, layout);
+                let result = Scalar::from_uint(truncated_bits, layout.size);
+                self.write_scalar(result, dest)?;
+            }
             "transmute" => {
                 self.copy_op_transmute(args[0], dest)?;
             }
index 76a8501fb177a89c4375e3c99fa175a8da097aaf..54983b8f4e026abd40026540e985dd2095a7cd80 100644 (file)
@@ -196,7 +196,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE };
 
     let return_block = BasicBlock::new(1);
-    let mut blocks = IndexVec::new();
+    let mut blocks = IndexVec::with_capacity(2);
     let block = |blocks: &mut IndexVec<_, _>, kind| {
         blocks.push(BasicBlockData {
             statements: vec![],
@@ -768,7 +768,8 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }));
     }
 
-    let mut blocks = IndexVec::new();
+    let n_blocks = if let Adjustment::RefMut = rcvr_adjustment { 5 } else { 2 };
+    let mut blocks = IndexVec::with_capacity(n_blocks);
     let block = |blocks: &mut IndexVec<_, _>, statements, kind, is_cleanup| {
         blocks.push(BasicBlockData {
             statements,
index 199cf5650fda8c2f6f5f82d2f239e26d56a1f560..2db3bbda3233bf8c895e0352a587511b4b92ceb2 100644 (file)
@@ -137,7 +137,7 @@ fn run_pass(&self, caller_mir: &mut Mir<'tcx>) {
 
                 let callee_mir = match self.tcx.try_optimized_mir(callsite.location.span,
                                                                   callsite.callee) {
-                    Ok(callee_mir) if self.should_inline(callsite, callee_mir) => {
+                    Ok(callee_mir) if self.consider_optimizing(callsite, callee_mir) => {
                         self.tcx.subst_and_normalize_erasing_regions(
                             &callsite.substs,
                             param_env,
@@ -198,6 +198,18 @@ fn run_pass(&self, caller_mir: &mut Mir<'tcx>) {
         }
     }
 
+    fn consider_optimizing(&self,
+                           callsite: CallSite<'tcx>,
+                           callee_mir: &Mir<'tcx>)
+                           -> bool
+    {
+        debug!("consider_optimizing({:?})", callsite);
+        self.should_inline(callsite, callee_mir)
+            && self.tcx.consider_optimizing(|| format!("Inline {:?} into {:?}",
+                                                       callee_mir.span,
+                                                       callsite))
+    }
+
     fn should_inline(&self,
                      callsite: CallSite<'tcx>,
                      callee_mir: &Mir<'tcx>)
index e79da88a2464bf7d75d0b6815bd52bc4f316065a..c5add6260789a34e485f5852b45695cc3d093374 100644 (file)
@@ -310,16 +310,11 @@ fn promote_candidate(mut self, candidate: Candidate) {
                     match statement.kind {
                         StatementKind::Assign(_, box Rvalue::Ref(_, _, ref mut place)) => {
                             // Find the underlying local for this (necessarily interior) borrow.
-                            // HACK(eddyb) using a recursive function because of mutable borrows.
-                            fn interior_base<'a, 'tcx>(place: &'a mut Place<'tcx>)
-                                                       -> &'a mut Place<'tcx> {
-                                if let Place::Projection(ref mut proj) = *place {
-                                    assert_ne!(proj.elem, ProjectionElem::Deref);
-                                    return interior_base(&mut proj.base);
-                                }
-                                place
-                            }
-                            let place = interior_base(place);
+                            let mut place = place;
+                            while let Place::Projection(ref mut proj) = *place {
+                                assert_ne!(proj.elem, ProjectionElem::Deref);
+                                place = &mut proj.base;
+                            };
 
                             let ty = place.ty(local_decls, self.tcx).to_ty(self.tcx);
                             let span = statement.source_info.span;
index ca9c4eb9b8bb971f3d8bca1046c98d2afb4c30ee..03497be03087b4fbafa495ca41cf9279cf694949 100644 (file)
@@ -869,6 +869,8 @@ fn visit_terminator_kind(&mut self,
                             | "overflowing_mul"
                             | "unchecked_shl"
                             | "unchecked_shr"
+                            | "rotate_left"
+                            | "rotate_right"
                             | "add_with_overflow"
                             | "sub_with_overflow"
                             | "mul_with_overflow"
index 7a3f3c2a518bc7d065602ce42d30d3f9abc1ad1e..c87f14977cb1d5f50702d58e47874e6699835816 100644 (file)
@@ -24,31 +24,6 @@ pub fn opts() -> TargetOptions {
     // argument is *not* necessary for normal builds, but it can't hurt!
     base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,--eh-frame-hdr".to_string());
 
-    // There's a whole bunch of circular dependencies when dealing with MUSL
-    // unfortunately. To put this in perspective libc is statically linked to
-    // liblibc and libunwind is statically linked to libstd:
-    //
-    // * libcore depends on `fmod` which is in libc (transitively in liblibc).
-    //   liblibc, however, depends on libcore.
-    // * compiler-rt has personality symbols that depend on libunwind, but
-    //   libunwind is in libstd which depends on compiler-rt.
-    //
-    // Recall that linkers discard libraries and object files as much as
-    // possible, and with all the static linking and archives flying around with
-    // MUSL the linker is super aggressively stripping out objects. For example
-    // the first case has fmod stripped from liblibc (it's in its own object
-    // file) so it's not there when libcore needs it. In the second example all
-    // the unused symbols from libunwind are stripped (each is in its own object
-    // file in libstd) before we end up linking compiler-rt which depends on
-    // those symbols.
-    //
-    // To deal with these circular dependencies we just force the compiler to
-    // link everything as a group, not stripping anything out until everything
-    // is processed. The linker will still perform a pass to strip out object
-    // files but it won't do so until all objects/archives have been processed.
-    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,-(".to_string());
-    base.post_link_args.insert(LinkerFlavor::Gcc, vec!["-Wl,-)".to_string()]);
-
     // When generating a statically linked executable there's generally some
     // small setup needed which is listed in these files. These are provided by
     // a musl toolchain and are linked by default by the `musl-gcc` script. Note
index 2ed02a4cdab1e1a71d642439b3cae7c6ee940d56..e635bc9efc45c0572326d00d87d6776d014aae6d 100644 (file)
@@ -151,17 +151,35 @@ fn relate_mir_and_user_ty(
         debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
         let ty = self.normalize(ty);
 
-        let mut projected_ty = PlaceTy::from_ty(ty);
+        // We need to follow any provided projetions into the type.
+        //
+        // if we hit a ty var as we descend, then just skip the
+        // attempt to relate the mir local with any type.
+
+        struct HitTyVar;
+        let mut curr_projected_ty: Result<PlaceTy, HitTyVar>;
+        curr_projected_ty = Ok(PlaceTy::from_ty(ty));
         for proj in projs {
-            projected_ty = projected_ty.projection_ty_core(
+            let projected_ty = if let Ok(projected_ty) = curr_projected_ty {
+                projected_ty
+            } else {
+                break;
+            };
+            curr_projected_ty = projected_ty.projection_ty_core(
                 tcx, proj, |this, field, &()| {
-                    let ty = this.field_ty(tcx, field);
-                    self.normalize(ty)
+                    if this.to_ty(tcx).is_ty_var() {
+                        Err(HitTyVar)
+                    } else {
+                        let ty = this.field_ty(tcx, field);
+                        Ok(self.normalize(ty))
+                    }
                 });
         }
-        let ty = projected_ty.to_ty(tcx);
 
-        self.relate(mir_ty, variance, ty)?;
+        if let Ok(projected_ty) = curr_projected_ty {
+            let ty = projected_ty.to_ty(tcx);
+            self.relate(mir_ty, variance, ty)?;
+        }
 
         if let Some(UserSelfTy {
             impl_def_id,
index 40f2072079a5a1ba203536b642b3f3d14ea8c53c..4a300fe09215cbfc01e2dbd068b409dbfb2e400e 100644 (file)
@@ -814,11 +814,6 @@ fn check_pat_tuple_struct(&self,
             report_unexpected_def(def);
             return self.tcx.types.err;
         }
-        // Replace constructor type with constructed type for tuple struct patterns.
-        let pat_ty = pat_ty.fn_sig(tcx).output();
-        let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
-
-        self.demand_eqtype(pat.span, expected, pat_ty);
 
         let variant = match def {
             Def::Err => {
@@ -836,6 +831,13 @@ fn check_pat_tuple_struct(&self,
             }
             _ => bug!("unexpected pattern definition: {:?}", def)
         };
+
+        // Replace constructor type with constructed type for tuple struct patterns.
+        let pat_ty = pat_ty.fn_sig(tcx).output();
+        let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
+
+        self.demand_eqtype(pat.span, expected, pat_ty);
+
         // Type check subpatterns.
         if subpats.len() == variant.fields.len() ||
                 subpats.len() < variant.fields.len() && ddpos.is_some() {
index 3156458b4aa4abe0690057c9cbfccfadb98e72a0..84967aaf72f5797cf034129985d507d607760554 100644 (file)
@@ -292,7 +292,8 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
             "unchecked_div" | "unchecked_rem" | "exact_div" =>
                 (1, vec![param(0), param(0)], param(0)),
-            "unchecked_shl" | "unchecked_shr" =>
+            "unchecked_shl" | "unchecked_shr" |
+            "rotate_left" | "rotate_right" =>
                 (1, vec![param(0), param(0)], param(0)),
 
             "overflowing_add" | "overflowing_sub" | "overflowing_mul" =>
index 8f679b4d22b25d51f292e0b278f7ae7578e66e2f..1ae3b0b88c6dd5ea1f6120cf9471b7524da452d0 100644 (file)
@@ -70,7 +70,7 @@
 /* General structure and fonts */
 
 body {
-       font: 16px/1.4 "Source Serif Pro", Georgia, Times, "Times New Roman", serif;
+       font: 16px/1.4 "Source Serif Pro", serif;
        margin: 0;
        position: relative;
        padding: 10px 15px 20px 15px;
@@ -114,7 +114,7 @@ h3.impl, h3.method, h3.type {
 h1, h2, h3, h4,
 .sidebar, a.source, .search-input, .content table :not(code)>a,
 .collapse-toggle, div.item-list .out-of-band {
-       font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+       font-family: "Fira Sans", sans-serif;
 }
 
 ol, ul {
@@ -133,7 +133,7 @@ summary {
 }
 
 code, pre {
-       font-family: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", Inconsolata, monospace;
+       font-family: "Source Code Pro", monospace;
        white-space: pre-wrap;
 }
 .docblock code, .docblock-short code {
@@ -415,7 +415,7 @@ h4 > code, h3 > code, .invisible > code {
 }
 #main > .since {
        top: inherit;
-       font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+       font-family: "Fira Sans", sans-serif;
 }
 
 .content table:not(.table-display) {
@@ -1338,7 +1338,7 @@ h3.important {
 kbd {
        display: inline-block;
        padding: 3px 5px;
-       font: 15px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+       font: 15px monospace;
        line-height: 10px;
        vertical-align: middle;
        border: solid 1px;
index 34bbbb53d5ff1c1eaa86b0d9713464565098bf76..96c92ceb5bb4127052b311a03b2ed4b5b86f6625 100644 (file)
@@ -399,6 +399,8 @@ macro_rules! await {
 /// For more information about select, see the `std::sync::mpsc::Select` structure.
 #[macro_export]
 #[unstable(feature = "mpsc_select", issue = "27800")]
+#[rustc_deprecated(since = "1.32.0",
+                   reason = "channel selection will be removed in a future release")]
 macro_rules! select {
     (
         $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
index 81f98a55c117149bd5bfe8aa0e9f3d907853eb81..059ced4f56efda5f3fea5e7ebcc63681d8d4f698 100644 (file)
 //! ```
 
 #![stable(feature = "rust1", since = "1.0.0")]
+#![allow(deprecated)] // for mpsc_select
 
 // A description of how Rust's channel implementation works
 //
index a7a284cfb7994a766b1d3781c9d5b34e22effdec..2ec4b52dbf3cba3153f9db2721f227465a7a24a4 100644 (file)
 #![unstable(feature = "mpsc_select",
             reason = "This implementation, while likely sufficient, is unsafe and \
                       likely to be error prone. At some point in the future this \
-                      module will likely be replaced, and it is currently \
-                      unknown how much API breakage that will cause. The ability \
-                      to select over a number of channels will remain forever, \
-                      but no guarantees beyond this are being made",
+                      module will be removed.",
             issue = "27800")]
+#![rustc_deprecated(since = "1.32.0",
+                    reason = "channel selection will be removed in a future release")]
 
 
 use fmt;
index cfedda18a7e22886e2e972cc30d82a36157976a5..2f17bc0548cad75c77fa58445fff0e92e99ffea5 100644 (file)
@@ -1086,7 +1086,7 @@ pub enum ExprKind {
     /// A unary operation (For example: `!x`, `*x`)
     Unary(UnOp, P<Expr>),
     /// A literal (For example: `1`, `"foo"`)
-    Lit(P<Lit>),
+    Lit(Lit),
     /// A cast (`foo as f64`)
     Cast(P<Expr>, P<Ty>),
     Type(P<Expr>, P<Ty>),
index 1701c8da2c5bdc6283b491a97c45d3b516ca046f..88ee80e60888f93a2d8cace0b01a332e29443aa5 100644 (file)
@@ -491,7 +491,7 @@ pub fn expr(sp: Span) -> Box<dyn MacResult+'static> {
     pub fn raw_expr(sp: Span) -> P<ast::Expr> {
         P(ast::Expr {
             id: ast::DUMMY_NODE_ID,
-            node: ast::ExprKind::Lit(P(source_map::respan(sp, ast::LitKind::Bool(false)))),
+            node: ast::ExprKind::Lit(source_map::respan(sp, ast::LitKind::Bool(false))),
             span: sp,
             attrs: ThinVec::new(),
         })
index 7928ec1606b1d5b986db8f9a7df31474016d851d..cacec867cf198053cc6b187d4bf9cba2db551dcb 100644 (file)
@@ -695,7 +695,7 @@ fn expr_struct_ident(&self, span: Span,
     }
 
     fn expr_lit(&self, sp: Span, lit: ast::LitKind) -> P<ast::Expr> {
-        self.expr(sp, ast::ExprKind::Lit(P(respan(sp, lit))))
+        self.expr(sp, ast::ExprKind::Lit(respan(sp, lit)))
     }
     fn expr_usize(&self, span: Span, i: usize) -> P<ast::Expr> {
         self.expr_lit(span, ast::LitKind::Int(i as u128,
index 37800a334c6daf7ca4d54efe97e76ef9fb902426..c6e0adbb5a43e087a73b867cd13843dcc1db37a5 100644 (file)
@@ -274,7 +274,7 @@ fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
             // FIXME: This is wrong
             P(ast::Expr {
                 id: ast::DUMMY_NODE_ID,
-                node: ast::ExprKind::Lit(P(self.clone())),
+                node: ast::ExprKind::Lit(self.clone()),
                 span: DUMMY_SP,
                 attrs: ThinVec::new(),
             }).to_tokens(cx)
@@ -305,7 +305,7 @@ fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
                     let lit = ast::LitKind::Int(val as u128, ast::LitIntType::Signed($tag));
                     let lit = P(ast::Expr {
                         id: ast::DUMMY_NODE_ID,
-                        node: ast::ExprKind::Lit(P(dummy_spanned(lit))),
+                        node: ast::ExprKind::Lit(dummy_spanned(lit)),
                         span: DUMMY_SP,
                         attrs: ThinVec::new(),
                     });
index c8a686da179fbbcba51d828313dcced3743ee9fc..68e7e40c43efe4a1b74c035905c376c629e5662f 100644 (file)
@@ -1989,7 +1989,7 @@ fn parse_lit_token(&mut self) -> PResult<'a, LitKind> {
         let minus_lo = self.span;
         let minus_present = self.eat(&token::BinOp(token::Minus));
         let lo = self.span;
-        let literal = P(self.parse_lit()?);
+        let literal = self.parse_lit()?;
         let hi = self.prev_span;
         let expr = self.mk_expr(lo.to(hi), ExprKind::Lit(literal), ThinVec::new());
 
index 2717444753318e461e0c3b30dacd03ffbac96903..7f23313edff8beccb3fe44b815714269c5124c15 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 2717444753318e461e0c3b30dacd03ffbac96903
+Subproject commit 7f23313edff8beccb3fe44b815714269c5124c15
index 200175da1bf2a57d7387db7a79e0866a667eb5b2..e8bfa22220743960b2b76414da546f1d2a142b8d 100644 (file)
@@ -429,7 +429,7 @@ extern "C" void LLVMRustConfigurePassManagerBuilder(
     LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
     bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO,
     const char* PGOGenPath, const char* PGOUsePath) {
-#if LLVM_RUSTLLVM
+#if LLVM_VERSION_GE(7, 0)
   unwrap(PMBR)->MergeFunctions = MergeFunctions;
 #endif
   unwrap(PMBR)->SLPVectorize = SLPVectorize;
index 3dbde46f762411598632ce24b23b7df7c877d0dc..f00b7f3a58f9c2c91e95a263535c4a9039c5020e 100644 (file)
@@ -1237,6 +1237,40 @@ extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
       unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Bundles, Name));
 }
 
+extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
+                                            LLVMValueRef Dst, unsigned DstAlign,
+                                            LLVMValueRef Src, unsigned SrcAlign,
+                                            LLVMValueRef Size, bool IsVolatile) {
+#if LLVM_VERSION_GE(7, 0)
+  return wrap(unwrap(B)->CreateMemCpy(
+      unwrap(Dst), DstAlign,
+      unwrap(Src), SrcAlign,
+      unwrap(Size), IsVolatile));
+#else
+  unsigned Align = std::min(DstAlign, SrcAlign);
+  return wrap(unwrap(B)->CreateMemCpy(
+      unwrap(Dst), unwrap(Src),
+      unwrap(Size), Align, IsVolatile));
+#endif
+}
+
+extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
+                                             LLVMValueRef Dst, unsigned DstAlign,
+                                             LLVMValueRef Src, unsigned SrcAlign,
+                                             LLVMValueRef Size, bool IsVolatile) {
+#if LLVM_VERSION_GE(7, 0)
+  return wrap(unwrap(B)->CreateMemMove(
+      unwrap(Dst), DstAlign,
+      unwrap(Src), SrcAlign,
+      unwrap(Size), IsVolatile));
+#else
+  unsigned Align = std::min(DstAlign, SrcAlign);
+  return wrap(unwrap(B)->CreateMemMove(
+      unwrap(Dst), unwrap(Src),
+      unwrap(Size), Align, IsVolatile));
+#endif
+}
+
 extern "C" LLVMValueRef
 LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
                     unsigned NumArgs, LLVMBasicBlockRef Then,
index 10dd12909b6444a65772dfa4cd5a0c7aa85aad05..b50f5b6f16fedad9743b5be8b2be36fea7a6eb7b 100644 (file)
@@ -65,7 +65,7 @@ pub struct BigPacked2 {
 pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
 // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
 // CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 %{{.*}}, i8* align 1 %{{.*}}, i{{[0-9]+}} 32, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 %{{.*}}, i8* align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
     // check that calls whose destination is a field of a packed struct
     // go through an alloca rather than calling the function with an
     // unaligned destination.
@@ -77,7 +77,7 @@ pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
 pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 {
 // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
 // CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 2 %{{.*}}, i8* align 2 %{{.*}}, i{{[0-9]+}} 32, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 2 %{{.*}}, i8* align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
     // check that calls whose destination is a field of a packed struct
     // go through an alloca rather than calling the function with an
     // unaligned destination.
index 0aaf00bfdbe8ef1597825ed81c7d0ade8c1287f0..871bee13b1931eddf04b259ad387f3bd2cb70f08 100644 (file)
@@ -31,7 +31,7 @@ pub struct Bytes {
 // CHECK: store i32 %0, i32* [[TMP]]
 // CHECK: [[Y8:%[0-9]+]] = bitcast [4 x i8]* %y to i8*
 // CHECK: [[TMP8:%[0-9]+]] = bitcast i32* [[TMP]] to i8*
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 [[Y8]], i8* align 1 [[TMP8]], i{{[0-9]+}} 4, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 [[Y8]], i8* align 4 [[TMP8]], i{{[0-9]+}} 4, i1 false)
     *x = y;
 }
 
@@ -45,6 +45,6 @@ pub fn small_struct_alignment(x: &mut Bytes, y: Bytes) {
 // CHECK: store i32 %0, i32* [[TMP]]
 // CHECK: [[Y8:%[0-9]+]] = bitcast %Bytes* %y to i8*
 // CHECK: [[TMP8:%[0-9]+]] = bitcast i32* [[TMP]] to i8*
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 [[Y8]], i8* align 1 [[TMP8]], i{{[0-9]+}} 4, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 [[Y8]], i8* align 4 [[TMP8]], i{{[0-9]+}} 4, i1 false)
     *x = y;
 }
index 51191dd7087e483e3f9ae7eabdfe067bbfc83a72..b3980f32d2736b2195fac070946da713d2f598d5 100644 (file)
@@ -17,7 +17,7 @@ fn drop(&mut self) {
         if self.0 == 1 {
             panic!("panic 1");
         } else {
-            eprint!("drop {}", self.0);
+            eprintln!("drop {}", self.0);
         }
     }
 }
index 2d430be07ef2f2eff1f3fe97566a15696f18ba9f..2fa933d513a669e4910e58ae5f330410166c6ab8 100644 (file)
@@ -14,7 +14,7 @@
 
 fn main() {
     panic::set_hook(Box::new(|i| {
-        eprint!("greetings from the panic handler");
+        eprintln!("greetings from the panic handler");
     }));
     panic!("foobar");
 }
index 4ac469557098523dd588881eb2a66ecaf8f205fb..529c21354e3838a2eccf54d2dd6b22438f853dd6 100644 (file)
@@ -23,7 +23,7 @@ fn main() {
     assert_eq!(BE_U32, b(55u32).to_be());
     assert_eq!(LE_U32, b(55u32).to_le());
 
-    #[cfg(not(target_arch = "asmjs"))]
+    #[cfg(not(target_os = "emscripten"))]
     {
         const BE_U128: u128 = 999999u128.to_be();
         const LE_I128: i128 = (-999999i128).to_le();
index 0750a4c89593665a2a745e4e68d6c24424ef4b74..a31ad72b0881a8228f15dfce376e5f0f88ab2c78 100644 (file)
@@ -16,6 +16,7 @@
 // expose is still present.
 
 #![feature(mpsc_select)]
+#![allow(deprecated)]
 
 use std::sync::mpsc::{channel, Sender, Receiver};
 use std::thread;
diff --git a/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs b/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs
new file mode 100644 (file)
index 0000000..6d91fd3
--- /dev/null
@@ -0,0 +1,31 @@
+// compile-pass
+
+// rust-lang/rust#55552: The strategy pnkfelix landed in PR #55274
+// (for ensuring that NLL respects user-provided lifetime annotations)
+// did not handle the case where the ascribed type has some expliit
+// wildcards (`_`) mixed in, and it caused an internal compiler error
+// (ICE).
+//
+// This test is just checking that we do not ICE when such things
+// occur.
+
+struct X;
+struct Y;
+struct Z;
+
+struct Pair { x: X, y: Y }
+
+pub fn join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
+where A: FnOnce() -> RA + Send,
+      B: FnOnce() -> RB + Send,
+      RA: Send,
+      RB: Send
+{
+    (oper_a(), oper_b())
+}
+
+fn main() {
+    let ((_x, _y), _z): (_, Z) = join(|| (X, Y), || Z);
+
+    let (Pair { x: _x, y: _y }, Z): (_, Z) = join(|| Pair { x: X, y: Y }, || Z);
+}
index 613ee0a269e70cd62a285e3a469da5cde0bad64c..dc417957795f5b3b6765e7ea37de569e47ee7cce 100644 (file)
@@ -14,7 +14,7 @@ LL | impl Copy for &'static NotSync {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: conflicting implementation in crate `core`:
-           - impl<'_, T> std::marker::Copy for &T
+           - impl<T> std::marker::Copy for &T
              where T: ?Sized;
 
 error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&[NotSync]`:
@@ -24,7 +24,7 @@ LL | impl Copy for &'static [NotSync] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: conflicting implementation in crate `core`:
-           - impl<'_, T> std::marker::Copy for &T
+           - impl<T> std::marker::Copy for &T
              where T: ?Sized;
 
 error[E0206]: the trait `Copy` may not be implemented for this type
index 4886ad7717574e6eae004a6529139beccaac83d3..76ff88d6cc62346b52412741cd1026668d7b5627 100644 (file)
@@ -5,7 +5,7 @@ LL | impl<Foo> Deref for Foo { } //~ ERROR must be used
    | ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: conflicting implementation in crate `core`:
-           - impl<'_, T> std::ops::Deref for &T
+           - impl<T> std::ops::Deref for &T
              where T: ?Sized;
 
 error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g. `MyStruct<Foo>`)
diff --git a/src/test/ui/extern/extern-const.fixed b/src/test/ui/extern/extern-const.fixed
new file mode 100644 (file)
index 0000000..dca5698
--- /dev/null
@@ -0,0 +1,25 @@
+// Check extern items cannot be const + `rustfix` suggests using
+// extern static.
+//
+// #54388: an unused reference to an undefined static may or may not
+// compile. To sidestep this by using one that *is* defined.
+
+// run-rustfix
+// ignore-wasm32 no external library to link to.
+// compile-flags: -g -Z continue-parse-after-error
+#![feature(libc)]
+extern crate libc;
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern "C" {
+    static rust_dbg_static_mut: libc::c_int; //~ ERROR extern items cannot be `const`
+}
+
+fn main() {
+    // We suggest turning the (illegal) extern `const` into an extern `static`,
+    // but this also requires `unsafe` (a deny-by-default lint at comment time,
+    // future error; Issue #36247)
+    unsafe {
+        let _x = rust_dbg_static_mut;
+    }
+}
index d8a167311d55c12dbe389a2187607208fceff214..07dbe545a850a46c26fb7e68abd58a3e88e68752 100644 (file)
@@ -1,18 +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.
+// Check extern items cannot be const + `rustfix` suggests using
+// extern static.
 //
-// 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.
+// #54388: an unused reference to an undefined static may or may not
+// compile. To sidestep this by using one that *is* defined.
 
-// FIXME(#54388): re-enable rustfix later, when this test has consistent output across targets
-// compile-flags: -Z continue-parse-after-error
+// run-rustfix
+// ignore-wasm32 no external library to link to.
+// compile-flags: -g -Z continue-parse-after-error
+#![feature(libc)]
+extern crate libc;
 
+#[link(name = "rust_test_helpers", kind = "static")]
 extern "C" {
-    const C: u8; //~ ERROR extern items cannot be `const`
+    const rust_dbg_static_mut: libc::c_int; //~ ERROR extern items cannot be `const`
 }
 
 fn main() {
@@ -20,6 +20,6 @@ fn main() {
     // but this also requires `unsafe` (a deny-by-default lint at comment time,
     // future error; Issue #36247)
     unsafe {
-        let _x = C;
+        let _x = rust_dbg_static_mut;
     }
 }
index cbed5e56c76c4523c42e39712d30cfc575bd2416..7ebaec0368e3d46f53c4f429a6fc3aad5e0f0343 100644 (file)
@@ -1,7 +1,7 @@
 error: extern items cannot be `const`
   --> $DIR/extern-const.rs:15:5
    |
-LL |     const C: u8; //~ ERROR extern items cannot be `const`
+LL |     const rust_dbg_static_mut: libc::c_int; //~ ERROR extern items cannot be `const`
    |     ^^^^^ help: try using a static value: `static`
 
 error: aborting due to previous error
diff --git a/src/test/ui/impl-trait/issue-55608-captures-empty-region.rs b/src/test/ui/impl-trait/issue-55608-captures-empty-region.rs
new file mode 100644 (file)
index 0000000..7ebc348
--- /dev/null
@@ -0,0 +1,22 @@
+// This used to ICE because it creates an `impl Trait` that captures a
+// hidden empty region.
+
+#![feature(conservative_impl_trait)]
+
+fn server() -> impl FilterBase2 { //~ ERROR [E0700]
+    segment2(|| { loop { } }).map2(|| "")
+}
+
+trait FilterBase2 {
+    fn map2<F>(self, _fn: F) -> Map2<F> where Self: Sized { loop { } }
+}
+
+struct Map2<F> { _func: F }
+
+impl<F> FilterBase2 for Map2<F> { }
+
+fn segment2<F>(_fn: F) -> Map2<F> where F: Fn() -> Result<(), ()> {
+    loop { }
+}
+
+fn main() { server(); }
diff --git a/src/test/ui/impl-trait/issue-55608-captures-empty-region.stderr b/src/test/ui/impl-trait/issue-55608-captures-empty-region.stderr
new file mode 100644 (file)
index 0000000..d1f1478
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/issue-55608-captures-empty-region.rs:6:16
+   |
+LL | fn server() -> impl FilterBase2 { //~ ERROR [E0700]
+   |                ^^^^^^^^^^^^^^^^
+   |
+   = note: hidden type `Map2<[closure@$DIR/issue-55608-captures-empty-region.rs:7:36: 7:41]>` captures an empty lifetime
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0700`.
index 654f230741e96f6e9b5cef5e55fe92cec7da9b56..5a08a097fd02faf3c60ec92bdbe04261c0af0105 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test that the compiler will catch invalid inline assembly constraints.
 
+// ignore-emscripten
+
 #![feature(asm)]
 
 extern "C" {
index ce1f274749f1f70b67e5c70bfe67cdca050b9aa2..44facff080543aa8ea85917ae04c546126a25e90 100644 (file)
@@ -1,17 +1,17 @@
 error[E0668]: malformed inline assembly
-  --> $DIR/inline-asm-bad-constraint.rs:29:9
+  --> $DIR/inline-asm-bad-constraint.rs:31:9
    |
 LL |         asm!("" :"={rax"(rax)) //~ ERROR E0668
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0668]: malformed inline assembly
-  --> $DIR/inline-asm-bad-constraint.rs:37:9
+  --> $DIR/inline-asm-bad-constraint.rs:39:9
    |
 LL |         asm!("callq $0" : : "0"(foo)) //~ ERROR E0668
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0668]: malformed inline assembly
-  --> $DIR/inline-asm-bad-constraint.rs:44:9
+  --> $DIR/inline-asm-bad-constraint.rs:46:9
    |
 LL |         asm!("addb $1, $0" : "={rax}"((0i32, rax))); //~ ERROR E0668
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index bbfb14b8d9d22d5e4ed00523bf0351610f394cba..0ee4080fd0cb1c4adefdb901d703881bf8619489 100644 (file)
@@ -11,6 +11,8 @@
 // Test that the compiler will catch passing invalid values to inline assembly
 // operands.
 
+// ignore-emscripten
+
 #![feature(asm)]
 
 #[repr(C)]
index 2f650bfcab7b52ac1ef27f4f8fe196da1909a2ca..1a99aa28f584ada4105e95324569404c7b9d5a28 100644 (file)
@@ -1,41 +1,41 @@
 error[E0669]: invalid value for constraint in inline assembly
-  --> $DIR/inline-asm-bad-operand.rs:29:24
+  --> $DIR/inline-asm-bad-operand.rs:31:24
    |
 LL |         asm!("" :: "r"("")); //~ ERROR E0669
    |                        ^^
 
 error[E0669]: invalid value for constraint in inline assembly
-  --> $DIR/inline-asm-bad-operand.rs:34:32
+  --> $DIR/inline-asm-bad-operand.rs:36:32
    |
 LL |         asm!("ret" : : "{rdi}"(target)); //~ ERROR E0669
    |                                ^^^^^^
 
 error[E0669]: invalid value for constraint in inline assembly
-  --> $DIR/inline-asm-bad-operand.rs:41:29
+  --> $DIR/inline-asm-bad-operand.rs:43:29
    |
 LL |     unsafe { asm!("" :: "i"(hello)) }; //~ ERROR E0669
    |                             ^^^^^
 
 error[E0669]: invalid value for constraint in inline assembly
-  --> $DIR/inline-asm-bad-operand.rs:49:38
+  --> $DIR/inline-asm-bad-operand.rs:51:38
    |
 LL |         asm!("movups $1, %xmm0"::"m"(arr)); //~ ERROR E0669
    |                                      ^^^
 
 error[E0669]: invalid value for constraint in inline assembly
-  --> $DIR/inline-asm-bad-operand.rs:56:32
+  --> $DIR/inline-asm-bad-operand.rs:58:32
    |
 LL |         asm!("mov sp, $0"::"r"(addr)); //~ ERROR E0669
    |                                ^^^^
 
 error[E0669]: invalid value for constraint in inline assembly
-  --> $DIR/inline-asm-bad-operand.rs:63:32
+  --> $DIR/inline-asm-bad-operand.rs:65:32
    |
 LL |         asm!("mov sp, $0"::"r"(addr), //~ ERROR E0669
    |                                ^^^^
 
 error[E0669]: invalid value for constraint in inline assembly
-  --> $DIR/inline-asm-bad-operand.rs:64:32
+  --> $DIR/inline-asm-bad-operand.rs:66:32
    |
 LL |                            "r"("hello e0669")); //~ ERROR E0669
    |                                ^^^^^^^^^^^^^
index c43f8d778239771a7478c6daac54feab38304b66..9620f89338620c3bd715c9066d90e65d812c88f4 100644 (file)
@@ -1,10 +1,11 @@
-error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next`
+error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: std::marker::Sized`
   --> $DIR/issue-23122-2.rs:17:15
    |
 LL | impl<T: Next> Next for GetNext<T> {
    |               ^^^^
    |
    = help: consider adding a `#![recursion_limit="128"]` attribute to your crate
+   = note: required because of the requirements on the impl of `Next` for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>`
 
 error: aborting due to previous error
 
index e4e97c58d8aa3f1703bcfd3e8015123b5b180bfd..83ebc92315552a291ef1722f3ba5f304c716f3f6 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 // compile-pass
+// ignore-emscripten no i128 support
 
 #![feature(nll)]
 
diff --git a/src/test/ui/match/match-fn-call.rs b/src/test/ui/match/match-fn-call.rs
new file mode 100644 (file)
index 0000000..d9c50e7
--- /dev/null
@@ -0,0 +1,12 @@
+use std::path::Path;
+
+fn main() {
+    let path = Path::new("foo");
+    match path {
+        Path::new("foo") => println!("foo"),
+        //~^ ERROR expected tuple struct/variant
+        Path::new("bar") => println!("bar"),
+        //~^ ERROR expected tuple struct/variant
+        _ => (),
+    }
+}
diff --git a/src/test/ui/match/match-fn-call.stderr b/src/test/ui/match/match-fn-call.stderr
new file mode 100644 (file)
index 0000000..4e24621
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0164]: expected tuple struct/variant, found method `<Path>::new`
+  --> $DIR/match-fn-call.rs:6:9
+   |
+LL |         Path::new("foo") => println!("foo"),
+   |         ^^^^^^^^^^^^^^^^ not a tuple variant or struct
+
+error[E0164]: expected tuple struct/variant, found method `<Path>::new`
+  --> $DIR/match-fn-call.rs:8:9
+   |
+LL |         Path::new("bar") => println!("bar"),
+   |         ^^^^^^^^^^^^^^^^ not a tuple variant or struct
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0164`.
diff --git a/src/test/ui/nll/issue-55344.rs b/src/test/ui/nll/issue-55344.rs
new file mode 100644 (file)
index 0000000..131c979
--- /dev/null
@@ -0,0 +1,26 @@
+// 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.
+
+// compile-pass
+
+#![feature(nll)]
+#![allow(unreachable_code)]
+#![deny(unused_mut)]
+
+pub fn foo() {
+    return;
+
+    let mut v = 0;
+    assert_eq!(v, 0);
+    v = 1;
+    assert_eq!(v, 1);
+}
+
+fn main() {}
index 1915fd82899aa2669898059cf37cce77d0bcc945..22cf15fb2e4a1458b8bab26e645ac6b833540627 100644 (file)
@@ -11,7 +11,7 @@
 
 use core::ops::RangeBounds;
 
-#[cfg(not(target_arch = "wasm32"))]
+#[cfg(any(not(target_arch = "wasm32"), target_os = "emscripten"))]
 #[lang = "eh_personality"]
 extern fn eh_personality() {}
 
index 1fa30882067703202d13ad0bd53d630bc2c1de66..241fac0e3933063fa48a1a01f5d577e40af12e4d 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 1fa30882067703202d13ad0bd53d630bc2c1de66
+Subproject commit 241fac0e3933063fa48a1a01f5d577e40af12e4d
index a80bbd401ab43c70fcc305fea79db444e755069e..399f9f577edf5b8a08fefa295ac15129135cb8f2 100644 (file)
@@ -1870,11 +1870,9 @@ fn make_run_args(&self) -> ProcArgs {
             } else {
                 self.fatal("no NodeJS binary found (--nodejs)");
             }
-        }
-
-        // If this is otherwise wasm , then run tests under nodejs with our
+        // If this is otherwise wasm, then run tests under nodejs with our
         // shim
-        if self.config.target.contains("wasm32") {
+        } else if self.config.target.contains("wasm32") {
             if let Some(ref p) = self.config.nodejs {
                 args.push(p.clone());
             } else {
index ee14c62df30720138da3b28cd029f5b02b162d37..f2b08f8e0bbdd4bd840e6ba53c440602036d2717 100644 (file)
@@ -59,4 +59,4 @@ openssl = { version = "0.10.12", optional = true }
 
 
 [features]
-all-static = ['openssl/vendored', 'curl-sys/static-curl']
+all-static = ['openssl/vendored', 'curl-sys/static-curl', 'curl-sys/force-system-lib-on-osx']