]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #55802 - wesleywiser:inlined_calls_2_electric_boogaloo, r=nagisa
authorPietro Albini <pietro@pietroalbini.org>
Sat, 10 Nov 2018 23:21:19 +0000 (00:21 +0100)
committerGitHub <noreply@github.com>
Sat, 10 Nov 2018 23:21:19 +0000 (00:21 +0100)
Don't inline virtual calls (take 2)

When I fixed the previous mis-optimizations, I didn't realize there were
actually two different places where we mutate `callsites` and both of
them should have the same behavior.

As a result, if a function was inlined and that function contained
virtual function calls, they were incorrectly being inlined. I also
added a test case which covers this.

94 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/liballoc/rc.rs
src/liballoc/sync.rs
src/libcore/alloc.rs
src/libcore/intrinsics.rs
src/libcore/num/mod.rs
src/librustc/diagnostics.rs
src/librustc/hir/mod.rs
src/librustc/infer/opaque_types/mod.rs
src/librustc/infer/outlives/obligations.rs
src/librustc/infer/outlives/verify.rs
src/librustc/lint/builtin.rs
src/librustc/mir/tcx.rs
src/librustc/traits/mod.rs
src/librustc/traits/project.rs
src/librustc/traits/util.rs
src/librustc/ty/context.rs
src/librustc/ty/mod.rs
src/librustc/ty/outlives.rs
src/librustc/ty/sty.rs
src/librustc/ty/subst.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_util.rs
src/librustc_codegen_llvm/mir/mod.rs
src/librustc_codegen_utils/symbol_export.rs
src/librustc_lint/lib.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/interpret/intrinsics.rs
src/librustc_mir/transform/cleanup_post_borrowck.rs
src/librustc_mir/transform/const_prop.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_traits/implied_outlives_bounds.rs
src/librustc_traits/type_op.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/intrinsic.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/diagnostics.rs
src/librustc_typeck/outlives/utils.rs
src/llvm-emscripten
src/rustllvm/PassWrapper.cpp
src/test/run-fail/mir_drop_panics.rs
src/test/run-fail/panic-set-handler.rs
src/test/run-pass/associated-types/associated-types-from-supertrait.rs [new file with mode: 0644]
src/test/run-pass/consts/const-endianess.rs
src/test/run-pass/issues/issue-24010.rs [new file with mode: 0644]
src/test/run-pass/traits/trait-alias-object-type.rs [deleted file]
src/test/run-pass/traits/trait-alias-object.rs [new file with mode: 0644]
src/test/ui/associated-types/associated-types-overridden-binding-2.rs [new file with mode: 0644]
src/test/ui/associated-types/associated-types-overridden-binding-2.stderr [new file with mode: 0644]
src/test/ui/associated-types/associated-types-overridden-binding.rs [new file with mode: 0644]
src/test/ui/associated-types/associated-types-overridden-binding.stderr [new file with mode: 0644]
src/test/ui/borrowck/borrowck-box-insensitivity.ast.stderr [new file with mode: 0644]
src/test/ui/borrowck/borrowck-box-insensitivity.mir.stderr [new file with mode: 0644]
src/test/ui/borrowck/borrowck-box-insensitivity.rs
src/test/ui/borrowck/borrowck-box-insensitivity.stderr [deleted file]
src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs [new file with mode: 0644]
src/test/ui/consts/const-prop-ice.rs [new file with mode: 0644]
src/test/ui/consts/const-prop-ice.stderr [new file with mode: 0644]
src/test/ui/consts/const-prop-ice2.rs [new file with mode: 0644]
src/test/ui/consts/const-prop-ice2.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0191.rs
src/test/ui/error-codes/E0719.rs [new file with mode: 0644]
src/test/ui/error-codes/E0719.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/issue-51947.rs [deleted file]
src/test/ui/issues/issue-23122-2.stderr
src/test/ui/issues/issue-49579.rs
src/test/ui/issues/issue-51947.rs [new file with mode: 0644]
src/test/ui/issues/issue-55796.rs [new file with mode: 0644]
src/test/ui/issues/issue-55796.stderr [new file with mode: 0644]
src/test/ui/lint/issue-50589-multiple-associated-types.rs [deleted file]
src/test/ui/lint/issue-50589-multiple-associated-types.stderr [deleted file]
src/test/ui/lint/lint-unused-mut-variables.lexical.stderr [deleted file]
src/test/ui/lint/lint-unused-mut-variables.nll.stderr [deleted file]
src/test/ui/lint/lint-unused-mut-variables.rs
src/test/ui/lint/lint-unused-mut-variables.stderr [new file with mode: 0644]
src/test/ui/range/issue-54505-no-std.rs
src/test/ui/traits/trait-alias-object.rs [new file with mode: 0644]
src/test/ui/traits/trait-alias-object.stderr [new file with mode: 0644]
src/test/ui/traits/trait-alias-objects.rs [deleted file]
src/test/ui/traits/trait-alias-objects.stderr [deleted file]
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 45f035ad04f8ff812de4c3bd4e1862bb5d47c65a..bb52d7990ff5772fdc27c821ee3c730896af9630 100644 (file)
@@ -672,14 +672,16 @@ unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox<T> {
         // Previously, layout was calculated on the expression
         // `&*(ptr as *const RcBox<T>)`, but this created a misaligned
         // reference (see #54908).
-        let (layout, _) = Layout::new::<RcBox<()>>()
-            .extend(Layout::for_value(&*ptr)).unwrap();
+        let layout = Layout::new::<RcBox<()>>()
+            .extend(Layout::for_value(&*ptr)).unwrap().0
+            .pad_to_align().unwrap();
 
         let mem = Global.alloc(layout)
             .unwrap_or_else(|_| handle_alloc_error(layout));
 
         // Initialize the RcBox
         let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut RcBox<T>;
+        debug_assert_eq!(Layout::for_value(&*inner), layout);
 
         ptr::write(&mut (*inner).strong, Cell::new(1));
         ptr::write(&mut (*inner).weak, Cell::new(1));
index 2c396b3b06bda34351046554a73a3f41e79844c9..b63b3684964bb64038366cf6d12365614a99c2a9 100644 (file)
@@ -575,14 +575,16 @@ unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner<T> {
         // Previously, layout was calculated on the expression
         // `&*(ptr as *const ArcInner<T>)`, but this created a misaligned
         // reference (see #54908).
-        let (layout, _) = Layout::new::<ArcInner<()>>()
-            .extend(Layout::for_value(&*ptr)).unwrap();
+        let layout = Layout::new::<ArcInner<()>>()
+            .extend(Layout::for_value(&*ptr)).unwrap().0
+            .pad_to_align().unwrap();
 
         let mem = Global.alloc(layout)
             .unwrap_or_else(|_| handle_alloc_error(layout));
 
         // Initialize the ArcInner
         let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut ArcInner<T>;
+        debug_assert_eq!(Layout::for_value(&*inner), layout);
 
         ptr::write(&mut (*inner).strong, atomic::AtomicUsize::new(1));
         ptr::write(&mut (*inner).weak, atomic::AtomicUsize::new(1));
index 113a85abecbef4613163b79d0056cde77513faf8..dd3e8da18a9661e26ed4669593ee9a03f13a11fe 100644 (file)
@@ -218,6 +218,23 @@ pub fn padding_needed_for(&self, align: usize) -> usize {
         len_rounded_up.wrapping_sub(len)
     }
 
+    /// Creates a layout by rounding the size of this layout up to a multiple
+    /// of the layout's alignment.
+    ///
+    /// Returns `Err` if the padded size would overflow.
+    ///
+    /// This is equivalent to adding the result of `padding_needed_for`
+    /// to the layout's current size.
+    #[unstable(feature = "alloc_layout_extra", issue = "55724")]
+    #[inline]
+    pub fn pad_to_align(&self) -> Result<Layout, LayoutErr> {
+        let pad = self.padding_needed_for(self.align());
+        let new_size = self.size().checked_add(pad)
+            .ok_or(LayoutErr { private: () })?;
+
+        Layout::from_size_align(new_size, self.align())
+    }
+
     /// Creates a layout describing the record for `n` instances of
     /// `self`, with a suitable amount of padding between each to
     /// ensure that each instance is given its requested size and
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 1d21a5cf79d107b13e1e417016d88ffcddd84beb..96590c1fc72d400c8724e663dd39598da5fad024 100644 (file)
@@ -2134,7 +2134,7 @@ trait Foo { }
 
 
 register_diagnostics! {
-//  E0006 // merged with E0005
+//  E0006, // merged with E0005
 //  E0101, // replaced with E0282
 //  E0102, // replaced with E0282
 //  E0134,
@@ -2183,9 +2183,7 @@ trait Foo { }
     E0657, // `impl Trait` can only capture lifetimes bound at the fn level
     E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
     E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
-
     E0697, // closures cannot be static
-
     E0707, // multiple elided lifetimes used in arguments of `async fn`
     E0708, // `async` non-`move` closures with arguments are not currently supported
     E0709, // multiple different lifetimes used in arguments of `async fn`
index a2095ff40c0402da70feed0d958ee80d406e2d1d..f57e3ff913b38dd407a7b856fde7093c2281edc4 100644 (file)
@@ -506,9 +506,9 @@ pub enum TraitBoundModifier {
 }
 
 /// The AST represents all type param bounds as types.
-/// typeck::collect::compute_bounds matches these against
-/// the "special" built-in traits (see middle::lang_items) and
-/// detects Copy, Send and Sync.
+/// `typeck::collect::compute_bounds` matches these against
+/// the "special" built-in traits (see `middle::lang_items`) and
+/// detects `Copy`, `Send` and `Sync`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum GenericBound {
     Trait(PolyTraitRef, TraitBoundModifier),
index 49858972416d8f1c025b18e4fbd256d9a47bf87a..cc73dd63816aa466b4b75c1eaab89f59e65c120f 100644 (file)
@@ -366,7 +366,8 @@ pub fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
         let mut types = vec![concrete_ty];
         let bound_region = |r| self.sub_regions(infer::CallReturn(span), least_region, r);
         while let Some(ty) = types.pop() {
-            let mut components = self.tcx.outlives_components(ty);
+            let mut components = smallvec![];
+            self.tcx.push_outlives_components(ty, &mut components);
             while let Some(component) = components.pop() {
                 match component {
                     Component::Region(r) => {
index 523f03c2cfc4773afc81f9c008a0fa7294bb5f92..f2825887f36e2d28dae70de54776647af151f6ee 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 //! Code that handles "type-outlives" constraints like `T: 'a`. This
-//! is based on the `outlives_components` function defined on the tcx,
+//! is based on the `push_outlives_components` function defined on the tcx,
 //! but it adds a bit of heuristics on top, in particular to deal with
 //! associated types and projections.
 //!
@@ -307,17 +307,18 @@ pub fn type_must_outlive(
 
         assert!(!ty.has_escaping_bound_vars());
 
-        let components = self.tcx.outlives_components(ty);
-        self.components_must_outlive(origin, components, region);
+        let mut components = smallvec![];
+        self.tcx.push_outlives_components(ty, &mut components);
+        self.components_must_outlive(origin, &components, region);
     }
 
     fn components_must_outlive(
         &mut self,
         origin: infer::SubregionOrigin<'tcx>,
-        components: Vec<Component<'tcx>>,
+        components: &[Component<'tcx>],
         region: ty::Region<'tcx>,
     ) {
-        for component in components {
+        for component in components.iter() {
             let origin = origin.clone();
             match component {
                 Component::Region(region1) => {
@@ -325,13 +326,13 @@ fn components_must_outlive(
                         .push_sub_region_constraint(origin, region, region1);
                 }
                 Component::Param(param_ty) => {
-                    self.param_ty_must_outlive(origin, region, param_ty);
+                    self.param_ty_must_outlive(origin, region, *param_ty);
                 }
                 Component::Projection(projection_ty) => {
-                    self.projection_must_outlive(origin, region, projection_ty);
+                    self.projection_must_outlive(origin, region, *projection_ty);
                 }
                 Component::EscapingProjection(subcomponents) => {
-                    self.components_must_outlive(origin, subcomponents, region);
+                    self.components_must_outlive(origin, &subcomponents, region);
                 }
                 Component::UnresolvedInferenceVariable(v) => {
                     // ignore this, we presume it will yield an error
index 88d45671b9afdfab86538d6a1b6d6345cfeed3ba..a7a79dd2e6560e6113407cfdb3c1fef2dc9f5971 100644 (file)
@@ -155,7 +155,8 @@ fn recursive_type_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
             .map(|subty| self.type_bound(subty))
             .collect::<Vec<_>>();
 
-        let mut regions = ty.regions();
+        let mut regions = smallvec![];
+        ty.push_regions(&mut regions);
         regions.retain(|r| !r.is_late_bound()); // ignore late-bound regions
         bounds.push(VerifyBound::AllBounds(
             regions
index 266b1c4d4a084dc83dd058713a3397f5371ecf0f..01d87bdbf63374ff4b38e86f077bd8444c38fdfd 100644 (file)
     "detects labels that are never used"
 }
 
-declare_lint! {
-    pub DUPLICATE_ASSOCIATED_TYPE_BINDINGS,
-    Warn,
-    "warns about duplicate associated type bindings in generics"
-}
-
 declare_lint! {
     pub DUPLICATE_MACRO_EXPORTS,
     Deny,
@@ -418,7 +412,6 @@ fn get_lints(&self) -> LintArray {
             ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
             UNSTABLE_NAME_COLLISIONS,
             IRREFUTABLE_LET_PATTERNS,
-            DUPLICATE_ASSOCIATED_TYPE_BINDINGS,
             DUPLICATE_MACRO_EXPORTS,
             INTRA_DOC_LINK_RESOLUTION_FAILURE,
             MISSING_DOC_CODE_EXAMPLES,
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 b7512790bfb6913414c2e4d34c618b56c9012f19..33b689c60a1188dad35d27597bbe23a67b77ce53 100644 (file)
 pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
 pub use self::specialize::find_associated_item;
 pub use self::engine::{TraitEngine, TraitEngineExt};
-pub use self::util::elaborate_predicates;
-pub use self::util::supertraits;
-pub use self::util::Supertraits;
-pub use self::util::supertrait_def_ids;
-pub use self::util::SupertraitDefIds;
+pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
+pub use self::util::{supertraits, supertrait_def_ids, Supertraits, SupertraitDefIds};
 pub use self::util::transitive_bounds;
 
 #[allow(dead_code)]
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 74f8d67ce04846a97c309a0573037530a4b98225..3a882506b41d6520e90921c0267f3752f75705b4 100644 (file)
@@ -200,8 +200,10 @@ fn push(&mut self, predicate: &ty::Predicate<'tcx>) {
                 }
 
                 let visited = &mut self.visited;
+                let mut components = smallvec![];
+                tcx.push_outlives_components(ty_max, &mut components);
                 self.stack.extend(
-                    tcx.outlives_components(ty_max)
+                    components
                        .into_iter()
                        .filter_map(|component| match component {
                            Component::Region(r) => if r.is_late_bound() {
@@ -333,7 +335,7 @@ fn new(base: I) -> FilterToTraits<I> {
     }
 }
 
-impl<'tcx,I:Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
+impl<'tcx, I: Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
     type Item = ty::PolyTraitRef<'tcx>;
 
     fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
index 05d9d4bc37d79f540e3c887feb5fcc82ae099be7..82095a2f5b01de7cc6031f5e068ee7db5e8c4395 100644 (file)
@@ -17,7 +17,7 @@
 use session::config::{BorrowckMode, OutputFilenames};
 use session::config::CrateType;
 use middle;
-use hir::{TraitCandidate, HirId, ItemLocalId, Node};
+use hir::{TraitCandidate, HirId, ItemKind, ItemLocalId, Node};
 use hir::def::{Def, Export};
 use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
 use hir::map as hir_map;
@@ -1602,6 +1602,20 @@ pub fn return_type_impl_trait(
         &self,
         scope_def_id: DefId,
     ) -> Option<Ty<'tcx>> {
+        // HACK: `type_of_def_id()` will fail on these (#55796), so return None
+        let node_id = self.hir.as_local_node_id(scope_def_id).unwrap();
+        match self.hir.get(node_id) {
+            Node::Item(item) => {
+                match item.node {
+                    ItemKind::Fn(..) => { /* type_of_def_id() will work */ }
+                    _ => {
+                        return None;
+                    }
+                }
+            }
+            _ => { /* type_of_def_id() will work or panic */ }
+        }
+
         let ret_ty = self.type_of(scope_def_id);
         match ret_ty.sty {
             ty::FnDef(_, _) => {
index c7c197d11c03beb112b95d85933d45b9d6acc1ef..ef9b3e3efab275f3421c3ea5eb9bcede113efa92 100644 (file)
@@ -294,7 +294,7 @@ pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt<'_, '_, '_
         }
     }
 
-    /// Returns true if an item with this visibility is accessible from the given block.
+    /// Returns `true` if an item with this visibility is accessible from the given block.
     pub fn is_accessible_from<T: DefIdTree>(self, module: DefId, tree: T) -> bool {
         let restriction = match self {
             // Public items are visible everywhere.
@@ -309,7 +309,7 @@ pub fn is_accessible_from<T: DefIdTree>(self, module: DefId, tree: T) -> bool {
         tree.is_descendant_of(module, restriction)
     }
 
-    /// Returns true if this visibility is at least as accessible as the given visibility
+    /// Returns `true` if this visibility is at least as accessible as the given visibility
     pub fn is_at_least<T: DefIdTree>(self, vis: Visibility, tree: T) -> bool {
         let vis_restriction = match vis {
             Visibility::Public => return self == Visibility::Public,
@@ -320,7 +320,7 @@ pub fn is_at_least<T: DefIdTree>(self, vis: Visibility, tree: T) -> bool {
         self.is_accessible_from(vis_restriction, tree)
     }
 
-    // Returns true if this item is visible anywhere in the local crate.
+    // Returns `true` if this item is visible anywhere in the local crate.
     pub fn is_visible_locally(self) -> bool {
         match self {
             Visibility::Public => true,
@@ -451,7 +451,7 @@ pub struct TypeFlags: u32 {
         // FIXME: Rename this to the actual property since it's used for generators too
         const HAS_TY_CLOSURE     = 1 << 9;
 
-        // true if there are "names" of types and regions and so forth
+        // `true` if there are "names" of types and regions and so forth
         // that are local to a particular fn
         const HAS_FREE_LOCAL_NAMES    = 1 << 10;
 
@@ -544,14 +544,14 @@ impl<'tcx> TyS<'tcx> {
     pub fn is_primitive_ty(&self) -> bool {
         match self.sty {
             TyKind::Bool |
-                TyKind::Char |
-                TyKind::Int(_) |
-                TyKind::Uint(_) |
-                TyKind::Float(_) |
-                TyKind::Infer(InferTy::IntVar(_)) |
-                TyKind::Infer(InferTy::FloatVar(_)) |
-                TyKind::Infer(InferTy::FreshIntTy(_)) |
-                TyKind::Infer(InferTy::FreshFloatTy(_)) => true,
+            TyKind::Char |
+            TyKind::Int(_) |
+            TyKind::Uint(_) |
+            TyKind::Float(_) |
+            TyKind::Infer(InferTy::IntVar(_)) |
+            TyKind::Infer(InferTy::FloatVar(_)) |
+            TyKind::Infer(InferTy::FreshIntTy(_)) |
+            TyKind::Infer(InferTy::FreshFloatTy(_)) => true,
             TyKind::Ref(_, x, _) => x.is_primitive_ty(),
             _ => false,
         }
@@ -953,7 +953,7 @@ pub fn region_param(&'tcx self,
                 _ => bug!("expected lifetime parameter, but found another generic parameter")
             }
         } else {
-            tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
+            tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
                .region_param(param, tcx)
         }
     }
@@ -970,7 +970,7 @@ pub fn type_param(&'tcx self,
                 _ => bug!("expected type parameter, but found another generic parameter")
             }
         } else {
-            tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
+            tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
                .type_param(param, tcx)
         }
     }
@@ -993,6 +993,7 @@ pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
         self.instantiate_into(tcx, &mut instantiated, substs);
         instantiated
     }
+
     pub fn instantiate_own(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
                            -> InstantiatedPredicates<'tcx> {
         InstantiatedPredicates {
@@ -1041,15 +1042,15 @@ pub fn instantiate_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub enum Predicate<'tcx> {
-    /// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
+    /// Corresponds to `where Foo: Bar<A,B,C>`. `Foo` here would be
     /// the `Self` type of the trait reference and `A`, `B`, and `C`
     /// would be the type parameters.
     Trait(PolyTraitPredicate<'tcx>),
 
-    /// where `'a : 'b`
+    /// where `'a: 'b`
     RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
 
-    /// where `T : 'a`
+    /// where `T: 'a`
     TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
 
     /// where `<T as TraitRef>::Name == X`, approximately.
@@ -1062,7 +1063,7 @@ pub enum Predicate<'tcx> {
     /// trait must be object-safe
     ObjectSafe(DefId),
 
-    /// No direct syntax. May be thought of as `where T : FnFoo<...>`
+    /// No direct syntax. May be thought of as `where T: FnFoo<...>`
     /// for some substitutions `...` and `T` being a closure type.
     /// Satisfied (or refuted) once we know the closure's kind.
     ClosureKind(DefId, ClosureSubsts<'tcx>, ClosureKind),
@@ -1111,11 +1112,11 @@ pub fn subst_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
         //
         // Let's start with an easy case. Consider two traits:
         //
-        //     trait Foo<'a> : Bar<'a,'a> { }
+        //     trait Foo<'a>: Bar<'a,'a> { }
         //     trait Bar<'b,'c> { }
         //
-        // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
-        // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
+        // Now, if we have a trait reference `for<'x> T: Foo<'x>`, then
+        // we can deduce that `for<'x> T: Bar<'x,'x>`. Basically, if we
         // knew that `Foo<'x>` (for any 'x) then we also know that
         // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
         // normal substitution.
@@ -1128,21 +1129,21 @@ pub fn subst_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
         //
         // Another example to be careful of is this:
         //
-        //     trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
+        //     trait Foo1<'a>: for<'b> Bar1<'a,'b> { }
         //     trait Bar1<'b,'c> { }
         //
-        // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
-        // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
+        // Here, if we have `for<'x> T: Foo1<'x>`, then what do we know?
+        // The answer is that we know `for<'x,'b> T: Bar1<'x,'b>`. The
         // reason is similar to the previous example: any impl of
-        // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`.  So
+        // `T:Foo1<'x>` must show that `for<'b> T: Bar1<'x, 'b>`.  So
         // basically we would want to collapse the bound lifetimes from
         // the input (`trait_ref`) and the supertraits.
         //
         // To achieve this in practice is fairly straightforward. Let's
         // consider the more complicated scenario:
         //
-        // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
-        //   has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
+        // - We start out with `for<'x> T: Foo1<'x>`. In this case, `'x`
+        //   has a De Bruijn index of 1. We want to produce `for<'x,'b> T: Bar1<'x,'b>`,
         //   where both `'x` and `'b` would have a DB index of 1.
         //   The substitution from the input trait-ref is therefore going to be
         //   `'a => 'x` (where `'x` has a DB index of 1).
@@ -1194,6 +1195,7 @@ pub fn subst_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
 pub struct TraitPredicate<'tcx> {
     pub trait_ref: TraitRef<'tcx>
 }
+
 pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
 
 impl<'tcx> TraitPredicate<'tcx> {
@@ -1218,7 +1220,7 @@ pub fn def_id(&self) -> DefId {
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
-pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
+pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A: B`
 pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
 pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>,
                                                            ty::Region<'tcx>>;
@@ -1238,11 +1240,11 @@ pub struct SubtypePredicate<'tcx> {
 /// This kind of predicate has no *direct* correspondent in the
 /// syntax, but it roughly corresponds to the syntactic forms:
 ///
-/// 1. `T : TraitRef<..., Item=Type>`
+/// 1. `T: TraitRef<..., Item=Type>`
 /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
 ///
 /// In particular, form #1 is "desugared" to the combination of a
-/// normal trait predicate (`T : TraitRef<...>`) and one of these
+/// normal trait predicate (`T: TraitRef<...>`) and one of these
 /// predicates. Form #2 is a broader form in that it also permits
 /// equality between arbitrary types. Processing an instance of
 /// Form #2 eventually yields one of these `ProjectionPredicate`
@@ -1256,14 +1258,14 @@ pub struct ProjectionPredicate<'tcx> {
 pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
 
 impl<'tcx> PolyProjectionPredicate<'tcx> {
-    /// Returns the def-id of the associated item being projected.
+    /// Returns the `DefId` of the associated item being projected.
     pub fn item_def_id(&self) -> DefId {
         self.skip_binder().projection_ty.item_def_id
     }
 
     pub fn to_poly_trait_ref(&self, tcx: TyCtxt<'_, '_, '_>) -> PolyTraitRef<'tcx> {
-        // Note: unlike with TraitRef::to_poly_trait_ref(),
-        // self.0.trait_ref is permitted to have escaping regions.
+        // Note: unlike with `TraitRef::to_poly_trait_ref()`,
+        // `self.0.trait_ref` is permitted to have escaping regions.
         // This is because here `self` has a `Binder` and so does our
         // return value, so we are preserving the number of binding
         // levels.
@@ -1274,12 +1276,12 @@ pub fn ty(&self) -> Binder<Ty<'tcx>> {
         self.map_bound(|predicate| predicate.ty)
     }
 
-    /// The DefId of the TraitItem for the associated type.
+    /// The `DefId` of the `TraitItem` for the associated type.
     ///
-    /// Note that this is not the DefId of the TraitRef containing this
-    /// associated type, which is in tcx.associated_item(projection_def_id()).container.
+    /// Note that this is not the `DefId` of the `TraitRef` containing this
+    /// associated type, which is in `tcx.associated_item(projection_def_id()).container`.
     pub fn projection_def_id(&self) -> DefId {
-        // ok to skip binder since trait def-id does not care about regions
+        // okay to skip binder since trait def-id does not care about regions
         self.skip_binder().projection_ty.item_def_id
     }
 }
@@ -1515,14 +1517,14 @@ pub fn next_universe(self) -> UniverseIndex {
         UniverseIndex::from_u32(self.private.checked_add(1).unwrap())
     }
 
-    /// True if `self` can name a name from `other` -- in other words,
+    /// Returns `true` if `self` can name a name from `other` -- in other words,
     /// if the set of names in `self` is a superset of those in
     /// `other` (`self >= other`).
     pub fn can_name(self, other: UniverseIndex) -> bool {
         self.private >= other.private
     }
 
-    /// True if `self` cannot name some names from `other` -- in other
+    /// Returns `true` if `self` cannot name some names from `other` -- in other
     /// words, if the set of names in `self` is a strict subset of
     /// those in `other` (`self < other`).
     pub fn cannot_name(self, other: UniverseIndex) -> bool {
@@ -1574,7 +1576,7 @@ pub fn empty() -> Self {
     /// are revealed. This is suitable for monomorphized, post-typeck
     /// environments like codegen or doing optimizations.
     ///
-    /// NB. If you want to have predicates in scope, use `ParamEnv::new`,
+    /// N.B. If you want to have predicates in scope, use `ParamEnv::new`,
     /// or invoke `param_env.with_reveal_all()`.
     pub fn reveal_all() -> Self {
         Self::new(List::empty(), Reveal::All)
@@ -1979,14 +1981,14 @@ pub fn discr_type(&self) -> attr::IntType {
         self.int.unwrap_or(attr::SignedInt(ast::IntTy::Isize))
     }
 
-    /// Returns true if this `#[repr()]` should inhabit "smart enum
+    /// Returns `true` if this `#[repr()]` should inhabit "smart enum
     /// layout" optimizations, such as representing `Foo<&T>` as a
     /// single pointer.
     pub fn inhibit_enum_layout_opt(&self) -> bool {
         self.c() || self.int.is_some()
     }
 
-    /// Returns true if this `#[repr()]` should inhibit struct field reordering
+    /// Returns `true` if this `#[repr()]` should inhibit struct field reordering
     /// optimizations, such as with repr(C) or repr(packed(1)).
     pub fn inhibit_struct_field_reordering_opt(&self) -> bool {
         !(self.flags & ReprFlags::IS_UNOPTIMISABLE).is_empty() || (self.pack == 1)
@@ -2089,7 +2091,7 @@ pub fn is_fundamental(&self) -> bool {
         self.flags.intersects(AdtFlags::IS_FUNDAMENTAL)
     }
 
-    /// Returns true if this is PhantomData<T>.
+    /// Returns `true` if this is PhantomData<T>.
     #[inline]
     pub fn is_phantom_data(&self) -> bool {
         self.flags.intersects(AdtFlags::IS_PHANTOM_DATA)
@@ -2105,7 +2107,7 @@ pub fn is_rc(&self) -> bool {
         self.flags.intersects(AdtFlags::IS_RC)
     }
 
-    /// Returns true if this is Box<T>.
+    /// Returns `true` if this is Box<T>.
     #[inline]
     pub fn is_box(&self) -> bool {
         self.flags.intersects(AdtFlags::IS_BOX)
@@ -2422,7 +2424,7 @@ pub fn trait_did(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> DefId {
         }
     }
 
-    /// True if this a type that impls this closure kind
+    /// Returns `true` if this a type that impls this closure kind
     /// must also implement `other`.
     pub fn extends(self, other: ty::ClosureKind) -> bool {
         match (self, other) {
@@ -2475,7 +2477,7 @@ pub fn walk_shallow(&'tcx self) -> smallvec::IntoIter<walk::TypeWalkerArray<'tcx
     ///
     /// Note: prefer `ty.walk()` where possible.
     pub fn maybe_walk<F>(&'tcx self, mut f: F)
-        where F : FnMut(Ty<'tcx>) -> bool
+        where F: FnMut(Ty<'tcx>) -> bool
     {
         let mut walker = self.walk();
         while let Some(ty) = walker.next() {
@@ -2678,7 +2680,7 @@ pub fn associated_items(
             as Box<dyn Iterator<Item = AssociatedItem> + 'a>
     }
 
-    /// Returns true if the impls are the same polarity and the trait either
+    /// Returns `true` if the impls are the same polarity and the trait either
     /// has no items or is annotated #[marker] and prevents item overrides.
     pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId) -> bool {
         if self.features().overlapping_marker_traits {
@@ -2802,7 +2804,7 @@ pub fn has_attr(self, did: DefId, attr: &str) -> bool {
         attr::contains_name(&self.get_attrs(did), attr)
     }
 
-    /// Returns true if this is an `auto trait`.
+    /// Returns `true` if this is an `auto trait`.
     pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
         self.trait_def(trait_def_id).has_auto_impl
     }
index 449730c9d0601d6c991e7705131b3eb71ed122fe..7fac88a3d78f1855b97371e8dd793adf88572625 100644 (file)
@@ -12,6 +12,7 @@
 // refers to rules defined in RFC 1214 (`OutlivesFooBar`), so see that
 // RFC for reference.
 
+use smallvec::SmallVec;
 use ty::{self, Ty, TyCtxt, TypeFoldable};
 
 #[derive(Debug)]
@@ -55,17 +56,15 @@ pub enum Component<'tcx> {
 }
 
 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
-    /// Returns all the things that must outlive `'a` for the condition
+    /// Push onto `out` all the things that must outlive `'a` for the condition
     /// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**.
-    pub fn outlives_components(&self, ty0: Ty<'tcx>)
-                               -> Vec<Component<'tcx>> {
-        let mut components = vec![];
-        self.compute_components(ty0, &mut components);
-        debug!("components({:?}) = {:?}", ty0, components);
-        components
+    pub fn push_outlives_components(&self, ty0: Ty<'tcx>,
+                                    out: &mut SmallVec<[Component<'tcx>; 4]>) {
+        self.compute_components(ty0, out);
+        debug!("components({:?}) = {:?}", ty0, out);
     }
 
-    fn compute_components(&self, ty: Ty<'tcx>, out: &mut Vec<Component<'tcx>>) {
+    fn compute_components(&self, ty: Ty<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>) {
         // Descend through the types, looking for the various "base"
         // components and collecting them into `out`. This is not written
         // with `collect()` because of the need to sometimes skip subtrees
@@ -164,7 +163,7 @@ fn compute_components(&self, ty: Ty<'tcx>, out: &mut Vec<Component<'tcx>>) {
                 // list is maintained explicitly, because bound regions
                 // themselves can be readily identified.
 
-                push_region_constraints(out, ty.regions());
+                push_region_constraints(ty, out);
                 for subty in ty.walk_shallow() {
                     self.compute_components(subty, out);
                 }
@@ -173,15 +172,17 @@ fn compute_components(&self, ty: Ty<'tcx>, out: &mut Vec<Component<'tcx>>) {
     }
 
     fn capture_components(&self, ty: Ty<'tcx>) -> Vec<Component<'tcx>> {
-        let mut temp = vec![];
-        push_region_constraints(&mut temp, ty.regions());
+        let mut temp = smallvec![];
+        push_region_constraints(ty, &mut temp);
         for subty in ty.walk_shallow() {
             self.compute_components(subty, &mut temp);
         }
-        temp
+        temp.into_iter().collect()
     }
 }
 
-fn push_region_constraints<'tcx>(out: &mut Vec<Component<'tcx>>, regions: Vec<ty::Region<'tcx>>) {
+fn push_region_constraints<'tcx>(ty: Ty<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>) {
+    let mut regions = smallvec![];
+    ty.push_regions(&mut regions);
     out.extend(regions.iter().filter(|&r| !r.is_late_bound()).map(|r| Component::Region(r)));
 }
index 28b58d62175bc21f270ef57a38d478c2df832c54..a4130bf15cb8272f2bd726ae061b5f758a03a042 100644 (file)
@@ -22,6 +22,7 @@
 use util::captures::Captures;
 use mir::interpret::{Scalar, Pointer};
 
+use smallvec::SmallVec;
 use std::iter;
 use std::cmp::Ordering;
 use rustc_target::spec::abi;
@@ -627,7 +628,7 @@ pub fn iter<'a>(&'a self)
 /// A complete reference to a trait. These take numerous guises in syntax,
 /// but perhaps the most recognizable form is in a where clause:
 ///
-///     T : Foo<U>
+///     T: Foo<U>
 ///
 /// This would be represented by a trait-reference where the def-id is the
 /// def-id for the trait `Foo` and the substs define `T` as parameter 0,
@@ -637,8 +638,8 @@ pub fn iter<'a>(&'a self)
 /// that case the `Self` parameter is absent from the substitutions.
 ///
 /// Note that a `TraitRef` introduces a level of region binding, to
-/// account for higher-ranked trait bounds like `T : for<'a> Foo<&'a
-/// U>` or higher-ranked object types.
+/// account for higher-ranked trait bounds like `T: for<'a> Foo<&'a U>`
+/// or higher-ranked object types.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub struct TraitRef<'tcx> {
     pub def_id: DefId,
@@ -663,7 +664,7 @@ pub fn self_ty(&self) -> Ty<'tcx> {
         self.substs.type_at(0)
     }
 
-    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
+    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a {
         // Select only the "input types" from a trait-reference. For
         // now this is all the types that appear in the
         // trait-reference, but it should eventually exclude
@@ -886,16 +887,16 @@ pub struct ProjectionTy<'tcx> {
     /// The parameters of the associated item.
     pub substs: &'tcx Substs<'tcx>,
 
-    /// The DefId of the TraitItem for the associated type N.
+    /// The `DefId` of the `TraitItem` for the associated type `N`.
     ///
-    /// Note that this is not the DefId of the TraitRef containing this
-    /// associated type, which is in tcx.associated_item(item_def_id).container.
+    /// Note that this is not the `DefId` of the `TraitRef` containing this
+    /// associated type, which is in `tcx.associated_item(item_def_id).container`.
     pub item_def_id: DefId,
 }
 
 impl<'a, 'tcx> ProjectionTy<'tcx> {
-    /// Construct a ProjectionTy by searching the trait from trait_ref for the
-    /// associated item named item_name.
+    /// Construct a `ProjectionTy` by searching the trait from `trait_ref` for the
+    /// associated item named `item_name`.
     pub fn from_ref_and_name(
         tcx: TyCtxt<'_, '_, '_>, trait_ref: ty::TraitRef<'tcx>, item_name: Ident
     ) -> ProjectionTy<'tcx> {
@@ -1846,28 +1847,27 @@ pub fn ty_adt_def(&self) -> Option<&'tcx AdtDef> {
         }
     }
 
-    /// Returns the regions directly referenced from this type (but
-    /// not types reachable from this type via `walk_tys`). This
-    /// ignores late-bound regions binders.
-    pub fn regions(&self) -> Vec<ty::Region<'tcx>> {
+    /// Push onto `out` the regions directly referenced from this type (but not
+    /// types reachable from this type via `walk_tys`). This ignores late-bound
+    /// regions binders.
+    pub fn push_regions(&self, out: &mut SmallVec<[ty::Region<'tcx>; 4]>) {
         match self.sty {
             Ref(region, _, _) => {
-                vec![region]
+                out.push(region);
             }
             Dynamic(ref obj, region) => {
-                let mut v = vec![region];
-                v.extend(obj.principal().skip_binder().substs.regions());
-                v
+                out.push(region);
+                out.extend(obj.principal().skip_binder().substs.regions());
             }
             Adt(_, substs) | Opaque(_, substs) => {
-                substs.regions().collect()
+                out.extend(substs.regions())
             }
             Closure(_, ClosureSubsts { ref substs }) |
             Generator(_, GeneratorSubsts { ref substs }, _) => {
-                substs.regions().collect()
+                out.extend(substs.regions())
             }
             Projection(ref data) | UnnormalizedProjection(ref data) => {
-                data.substs.regions().collect()
+                out.extend(data.substs.regions())
             }
             FnDef(..) |
             FnPtr(_) |
@@ -1887,9 +1887,7 @@ pub fn regions(&self) -> Vec<ty::Region<'tcx>> {
             Param(_) |
             Bound(..) |
             Infer(_) |
-            Error => {
-                vec![]
-            }
+            Error => {}
         }
     }
 
index c1aed36c92ddf3bfd60170781ea85bf88ff9bb82..b28e7c9fb199be7daaacce299e889784c7375078 100644 (file)
@@ -27,7 +27,7 @@
 use std::mem;
 use std::num::NonZeroUsize;
 
-/// An entity in the Rust typesystem, which can be one of
+/// An entity in the Rust type system, which can be one of
 /// several kinds (only types and lifetimes for now).
 /// To reduce memory usage, a `Kind` is a interned pointer,
 /// with the lowest 2 bits being reserved for a tag to
@@ -171,7 +171,7 @@ fn decode<D: Decoder>(d: &mut D) -> Result<Kind<'tcx>, D::Error> {
 pub type Substs<'tcx> = List<Kind<'tcx>>;
 
 impl<'a, 'gcx, 'tcx> Substs<'tcx> {
-    /// Creates a Substs that maps each generic parameter to itself.
+    /// Creates a `Substs` that maps each generic parameter to itself.
     pub fn identity_for_item(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId)
                              -> &'tcx Substs<'tcx> {
         Substs::for_item(tcx, def_id, |param, _| {
@@ -179,9 +179,9 @@ pub fn identity_for_item(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId)
         })
     }
 
-    /// Creates a Substs for generic parameter definitions,
+    /// Creates a `Substs` for generic parameter definitions,
     /// by calling closures to obtain each kind.
-    /// The closures get to observe the Substs as they're
+    /// The closures get to observe the `Substs` as they're
     /// being built, which can be used to correctly
     /// substitute defaults of generic parameters.
     pub fn for_item<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
@@ -242,7 +242,7 @@ pub fn is_noop(&self) -> bool {
     }
 
     #[inline]
-    pub fn types(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
+    pub fn types(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a {
         self.iter().filter_map(|k| {
             if let UnpackedKind::Type(ty) = k.unpack() {
                 Some(ty)
@@ -253,7 +253,7 @@ pub fn types(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
     }
 
     #[inline]
-    pub fn regions(&'a self) -> impl DoubleEndedIterator<Item=ty::Region<'tcx>> + 'a {
+    pub fn regions(&'a self) -> impl DoubleEndedIterator<Item = ty::Region<'tcx>> + 'a {
         self.iter().filter_map(|k| {
             if let UnpackedKind::Lifetime(lt) = k.unpack() {
                 Some(lt)
@@ -332,7 +332,7 @@ impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Substs<'tcx> {}
 // `foo`. Or use `foo.subst_spanned(tcx, substs, Some(span))` when
 // there is more information available (for better errors).
 
-pub trait Subst<'tcx> : Sized {
+pub trait Subst<'tcx>: Sized {
     fn subst<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
                        substs: &[Kind<'tcx>]) -> Self {
         self.subst_spanned(tcx, substs, None)
index 555e4012c3add7c54d5e331c7e7aa372c22e645c..81d615b5ad70a3505ba53819730a29fa6d1227f6 100644 (file)
@@ -720,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 a4401cf96d9deed201aa62a27f7031172ab1df0a..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};
@@ -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 => {
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 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 2d650f7f18d6f5654b7da9ceb4f353365b0a24be..6c40296b2ef374c7380c7e5bc480862dc4e6a98e 100644 (file)
@@ -388,6 +388,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 f289acc032be8fd5cca2a547d18c253cf1ba1558..8c0e9bd11a173da5813c13157f8244af22204632 100644 (file)
@@ -317,11 +317,6 @@ macro_rules! add_lint_group {
             reference: "issue #51443 <https://github.com/rust-lang/rust/issues/51443>",
             edition: None,
         },
-        FutureIncompatibleInfo {
-            id: LintId::of(DUPLICATE_ASSOCIATED_TYPE_BINDINGS),
-            reference: "issue #50589 <https://github.com/rust-lang/rust/issues/50589>",
-            edition: None,
-        },
         FutureIncompatibleInfo {
             id: LintId::of(PROC_MACRO_DERIVE_RESOLUTION_FALLBACK),
             reference: "issue #50504 <https://github.com/rust-lang/rust/issues/50504>",
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 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 4d3b422ab28171770a340aa99bfead908262e78e..98311444e28718d3b24aef07a04d92ba9a221e22 100644 (file)
@@ -37,6 +37,7 @@
 use rustc::mir::{Rvalue, Statement, StatementKind};
 use rustc::mir::visit::{MutVisitor, Visitor, TyContext};
 use rustc::ty::{Ty, RegionKind, TyCtxt};
+use smallvec::smallvec;
 use transform::{MirPass, MirSource};
 
 pub struct CleanEndRegions;
@@ -80,7 +81,11 @@ fn visit_rvalue(&mut self,
 
     fn visit_ty(&mut self, ty: &Ty<'tcx>, _: TyContext) {
         // Gather regions that occur in types
-        for re in ty.walk().flat_map(|t| t.regions()) {
+        let mut regions = smallvec![];
+        for t in ty.walk() {
+            t.push_regions(&mut regions);
+        }
+        for re in regions {
             match *re {
                 RegionKind::ReScope(ce) => { self.seen_regions.insert(ce); }
                 _ => {},
index 4f92ba400481bfc2759e4f1fab4ba40cb3efd934..885d70dc4304dee3e3cd02c3118df7555aab58b6 100644 (file)
@@ -591,8 +591,8 @@ fn visit_terminator_kind(
         if let TerminatorKind::Assert { expected, msg, cond, .. } = kind {
             if let Some(value) = self.eval_operand(cond, source_info) {
                 trace!("assertion on {:?} should be {:?}", value, expected);
-                let expected = Immediate::Scalar(Scalar::from_bool(*expected).into());
-                if expected != value.0.to_immediate() {
+                let expected = ScalarMaybeUndef::from(Scalar::from_bool(*expected));
+                if expected != self.ecx.read_scalar(value.0).unwrap() {
                     // poison all places this operand references so that further code
                     // doesn't use the invalid value
                     match cond {
@@ -628,20 +628,20 @@ fn visit_terminator_kind(
                             let len = self
                                 .eval_operand(len, source_info)
                                 .expect("len must be const");
-                            let len = match len.0.to_immediate() {
-                                Immediate::Scalar(ScalarMaybeUndef::Scalar(Scalar::Bits {
+                            let len = match self.ecx.read_scalar(len.0) {
+                                Ok(ScalarMaybeUndef::Scalar(Scalar::Bits {
                                     bits, ..
                                 })) => bits,
-                                _ => bug!("const len not primitive: {:?}", len),
+                                other => bug!("const len not primitive: {:?}", other),
                             };
                             let index = self
                                 .eval_operand(index, source_info)
                                 .expect("index must be const");
-                            let index = match index.0.to_immediate() {
-                                Immediate::Scalar(ScalarMaybeUndef::Scalar(Scalar::Bits {
+                            let index = match self.ecx.read_scalar(index.0) {
+                                Ok(ScalarMaybeUndef::Scalar(Scalar::Bits {
                                     bits, ..
                                 })) => bits,
-                                _ => bug!("const index not primitive: {:?}", index),
+                                other => bug!("const index not primitive: {:?}", other),
                             };
                             format!(
                                 "index out of bounds: \
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 7cc064f9c3d3d81906ad96caaa92a9e4c5e79a23..7514c2c18e7ca8f77aec0fbe7fcd15be28e12c8a 100644 (file)
@@ -20,6 +20,7 @@
 use rustc::ty::outlives::Component;
 use rustc::ty::query::Providers;
 use rustc::ty::wf;
+use smallvec::{SmallVec, smallvec};
 use syntax::ast::DUMMY_NODE_ID;
 use syntax::source_map::DUMMY_SP;
 use rustc::traits::FulfillmentContext;
@@ -133,7 +134,8 @@ fn compute_implied_outlives_bounds<'tcx>(
                     None => vec![],
                     Some(ty::OutlivesPredicate(ty_a, r_b)) => {
                         let ty_a = infcx.resolve_type_vars_if_possible(&ty_a);
-                        let components = tcx.outlives_components(ty_a);
+                        let mut components = smallvec![];
+                        tcx.push_outlives_components(ty_a, &mut components);
                         implied_bounds_from_components(r_b, components)
                     }
                 },
@@ -155,7 +157,7 @@ fn compute_implied_outlives_bounds<'tcx>(
 /// those relationships.
 fn implied_bounds_from_components(
     sub_region: ty::Region<'tcx>,
-    sup_components: Vec<Component<'tcx>>,
+    sup_components: SmallVec<[Component<'tcx>; 4]>,
 ) -> Vec<OutlivesBound<'tcx>> {
     sup_components
         .into_iter()
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 18f8473b5b56d7d88fb600878aaa16ff8fbbe0b3..572e79407a10be41586bc8b9d38d5aeb33de66a6 100644 (file)
@@ -37,7 +37,7 @@
 use syntax::ast;
 use syntax::ptr::P;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
-use syntax_pos::{Span, MultiSpan};
+use syntax_pos::{DUMMY_SP, Span, MultiSpan};
 
 pub trait AstConv<'gcx, 'tcx> {
     fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>;
@@ -451,7 +451,7 @@ pub fn create_substs_for_generic_args<'a, 'b>(
         }
 
         // We manually build up the substitution, rather than using convenience
-        // methods in subst.rs so that we can iterate over the arguments and
+        // methods in `subst.rs` so that we can iterate over the arguments and
         // parameters in lock-step linearly, rather than trying to match each pair.
         let mut substs: SmallVec<[Kind<'tcx>; 8]> = SmallVec::with_capacity(count);
 
@@ -469,7 +469,7 @@ pub fn create_substs_for_generic_args<'a, 'b>(
                 }
             }
 
-            // (Unless it's been handled in `parent_substs`) `Self` is handled first.
+            // `Self` is handled first, unless it's been handled in `parent_substs`.
             if has_self {
                 if let Some(&param) = params.peek() {
                     if param.index == 0 {
@@ -698,7 +698,7 @@ pub fn instantiate_mono_trait_ref(&self,
                                         trait_ref.path.segments.last().unwrap())
     }
 
-    /// Get the DefId of the given trait ref. It _must_ actually be a trait.
+    /// Get the `DefId` of the given trait ref. It _must_ actually be a trait.
     fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId {
         let path = &trait_ref.path;
         match path.def {
@@ -711,7 +711,7 @@ fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId {
         }
     }
 
-    /// The given `trait_ref` must actually be trait.
+    /// The given trait ref must actually be a trait.
     pub(super) fn instantiate_poly_trait_ref_inner(&self,
         trait_ref: &hir::TraitRef,
         self_ty: Ty<'tcx>,
@@ -738,7 +738,7 @@ pub(super) fn instantiate_poly_trait_ref_inner(&self,
             let predicate: Result<_, ErrorReported> =
                 self.ast_type_binding_to_poly_projection_predicate(
                     trait_ref.ref_id, poly_trait_ref, binding, speculative, &mut dup_bindings);
-            // ok to ignore Err because ErrorReported (see above)
+            // okay to ignore Err because of ErrorReported (see above)
             Some((predicate.ok()?, binding.span))
         }));
 
@@ -831,7 +831,7 @@ fn ast_type_binding_to_poly_projection_predicate(
         let tcx = self.tcx();
 
         if !speculative {
-            // Given something like `U : SomeTrait<T=X>`, we want to produce a
+            // Given something like `U: SomeTrait<T = X>`, we want to produce a
             // predicate like `<U as SomeTrait>::T = X`. This is somewhat
             // subtle in the event that `T` is defined in a supertrait of
             // `SomeTrait`, because in that case we need to upcast.
@@ -839,7 +839,7 @@ fn ast_type_binding_to_poly_projection_predicate(
             // That is, consider this case:
             //
             // ```
-            // trait SubTrait : SuperTrait<int> { }
+            // trait SubTrait: SuperTrait<int> { }
             // trait SuperTrait<A> { type T; }
             //
             // ... B : SubTrait<T=foo> ...
@@ -908,16 +908,14 @@ fn ast_type_binding_to_poly_projection_predicate(
         if !speculative {
             dup_bindings.entry(assoc_ty.def_id)
                 .and_modify(|prev_span| {
-                    let mut err = self.tcx().struct_span_lint_node(
-                        ::rustc::lint::builtin::DUPLICATE_ASSOCIATED_TYPE_BINDINGS,
-                        ref_id,
-                        binding.span,
-                        &format!("associated type binding `{}` specified more than once",
-                                 binding.item_name)
-                    );
-                    err.span_label(binding.span, "used more than once");
-                    err.span_label(*prev_span, format!("first use of `{}`", binding.item_name));
-                    err.emit();
+                    struct_span_err!(self.tcx().sess, binding.span, E0719,
+                                     "the value of the associated type `{}` (from the trait `{}`) \
+                                      is already specified",
+                                     binding.item_name,
+                                     tcx.item_path_str(assoc_ty.container.id()))
+                        .span_label(binding.span, "re-bound here")
+                        .span_label(*prev_span, format!("`{}` bound here first", binding.item_name))
+                        .emit();
                 })
                 .or_insert(binding.span);
         }
@@ -969,7 +967,7 @@ fn conv_object_ty_poly_trait_ref(&self,
             return tcx.types.err;
         }
 
-        let mut projection_bounds = vec![];
+        let mut projection_bounds = Vec::new();
         let dummy_self = tcx.mk_ty(TRAIT_OBJECT_DUMMY_SELF);
         let principal = self.instantiate_poly_trait_ref(&trait_bounds[0],
                                                         dummy_self,
@@ -994,23 +992,8 @@ fn conv_object_ty_poly_trait_ref(&self,
                 .emit();
         }
 
-        // Erase the dummy_self (TRAIT_OBJECT_DUMMY_SELF) used above.
-        let existential_principal = principal.map_bound(|trait_ref| {
-            self.trait_ref_to_existential(trait_ref)
-        });
-        let existential_projections = projection_bounds.iter().map(|(bound, _)| {
-            bound.map_bound(|b| {
-                let trait_ref = self.trait_ref_to_existential(b.projection_ty.trait_ref(tcx));
-                ty::ExistentialProjection {
-                    ty: b.ty,
-                    item_def_id: b.projection_ty.item_def_id,
-                    substs: trait_ref.substs,
-                }
-            })
-        });
-
         // Check that there are no gross object safety violations;
-        // most importantly, that the supertraits don't contain Self,
+        // most importantly, that the supertraits don't contain `Self`,
         // to avoid ICEs.
         let object_safety_violations =
             tcx.global_tcx().astconv_object_safety_violations(principal.def_id());
@@ -1021,13 +1004,22 @@ fn conv_object_ty_poly_trait_ref(&self,
             return tcx.types.err;
         }
 
-        // Use a BTreeSet to keep output in a more consistent order.
+        // Use a `BTreeSet` to keep output in a more consistent order.
         let mut associated_types = BTreeSet::default();
 
-        for tr in traits::supertraits(tcx, principal) {
-            associated_types.extend(tcx.associated_items(tr.def_id())
-                .filter(|item| item.kind == ty::AssociatedKind::Type)
-                .map(|item| item.def_id));
+        for tr in traits::elaborate_trait_ref(tcx, principal) {
+            match tr {
+                ty::Predicate::Trait(pred) => {
+                    associated_types.extend(tcx.associated_items(pred.def_id())
+                                    .filter(|item| item.kind == ty::AssociatedKind::Type)
+                                    .map(|item| item.def_id));
+                }
+                ty::Predicate::Projection(pred) => {
+                    // Include projections defined on supertraits.
+                    projection_bounds.push((pred, DUMMY_SP))
+                }
+                _ => ()
+            }
         }
 
         for (projection_bound, _) in &projection_bounds {
@@ -1046,11 +1038,26 @@ fn conv_object_ty_poly_trait_ref(&self,
                 .emit();
         }
 
+        // Erase the `dummy_self` (`TRAIT_OBJECT_DUMMY_SELF`) used above.
+        let existential_principal = principal.map_bound(|trait_ref| {
+            self.trait_ref_to_existential(trait_ref)
+        });
+        let existential_projections = projection_bounds.iter().map(|(bound, _)| {
+            bound.map_bound(|b| {
+                let trait_ref = self.trait_ref_to_existential(b.projection_ty.trait_ref(tcx));
+                ty::ExistentialProjection {
+                    ty: b.ty,
+                    item_def_id: b.projection_ty.item_def_id,
+                    substs: trait_ref.substs,
+                }
+            })
+        });
+
         // Dedup auto traits so that `dyn Trait + Send + Send` is the same as `dyn Trait + Send`.
         auto_traits.sort();
         auto_traits.dedup();
 
-        // skip_binder is okay, because the predicates are re-bound.
+        // Calling `skip_binder` is okay, because the predicates are re-bound.
         let mut v =
             iter::once(ty::ExistentialPredicate::Trait(*existential_principal.skip_binder()))
             .chain(auto_traits.into_iter().map(ty::ExistentialPredicate::AutoTrait))
@@ -1128,8 +1135,7 @@ fn find_bound_for_assoc_item(&self,
                                       span)
     }
 
-
-    // Checks that bounds contains exactly one element and reports appropriate
+    // Checks that `bounds` contains exactly one element and reports appropriate
     // errors otherwise.
     fn one_bound_for_assoc_type<I>(&self,
                                    mut bounds: I,
@@ -1186,11 +1192,11 @@ fn one_bound_for_assoc_type<I>(&self,
     }
 
     // Create a type from a path to an associated type.
-    // For a path A::B::C::D, ty and ty_path_def are the type and def for A::B::C
-    // and item_segment is the path segment for D. We return a type and a def for
+    // For a path `A::B::C::D`, `ty` and `ty_path_def` are the type and def for `A::B::C`
+    // and item_segment is the path segment for `D`. We return a type and a def for
     // the whole path.
-    // Will fail except for T::A and Self::A; i.e., if ty/ty_path_def are not a type
-    // parameter or Self.
+    // Will fail except for `T::A` and `Self::A`; i.e., if `ty`/`ty_path_def` are not a type
+    // parameter or `Self`.
     pub fn associated_path_def_to_ty(&self,
                                      ref_id: ast::NodeId,
                                      span: Span,
@@ -1210,7 +1216,7 @@ pub fn associated_path_def_to_ty(&self,
         // item is declared.
         let bound = match (&ty.sty, ty_path_def) {
             (_, Def::SelfTy(Some(_), Some(impl_def_id))) => {
-                // `Self` in an impl of a trait - we have a concrete self type and a
+                // `Self` in an impl of a trait - we have a concrete `self` type and a
                 // trait reference.
                 let trait_ref = match tcx.impl_trait_ref(impl_def_id) {
                     Some(trait_ref) => trait_ref,
@@ -1361,7 +1367,7 @@ pub fn def_to_ty(&self,
         let span = path.span;
         match path.def {
             Def::Existential(did) => {
-                // check for desugared impl trait
+                // Check for desugared impl trait.
                 assert!(ty::is_impl_trait_defn(tcx, did).is_none());
                 let item_segment = path.segments.split_last().unwrap();
                 self.prohibit_generics(item_segment.1);
@@ -1398,7 +1404,7 @@ pub fn def_to_ty(&self,
                 tcx.mk_ty_param(index, tcx.hir.name(node_id).as_interned_str())
             }
             Def::SelfTy(_, Some(def_id)) => {
-                // Self in impl (we know the concrete type).
+                // `Self` in impl (we know the concrete type)
 
                 assert_eq!(opt_self_ty, None);
                 self.prohibit_generics(&path.segments);
@@ -1406,7 +1412,7 @@ pub fn def_to_ty(&self,
                 tcx.at(span).type_of(def_id)
             }
             Def::SelfTy(Some(_), None) => {
-                // Self in trait.
+                // `Self` in trait
                 assert_eq!(opt_self_ty, None);
                 self.prohibit_generics(&path.segments);
                 tcx.mk_self_type()
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 266b9e3c0abad33bf63ff5b9f455e98907d1c2dc..8574443190d7c7a2d6a70f8737e3b1b7565de272 100644 (file)
@@ -28,9 +28,9 @@
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::hir;
 
-/// Helper type of a temporary returned by .for_item(...).
+/// Helper type of a temporary returned by `.for_item(...)`.
 /// Necessary because we can't write the following bound:
-/// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>).
+/// `F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>)`.
 struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     inherited: super::InheritedBuilder<'a, 'gcx, 'tcx>,
     id: ast::NodeId,
@@ -186,6 +186,8 @@ fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                    item_id: ast::NodeId,
                                    span: Span,
                                    sig_if_method: Option<&hir::MethodSig>) {
+    debug!("check_associated_item: {:?}", item_id);
+
     let code = ObligationCauseCode::MiscObligation;
     for_id(tcx, item_id, span).with_fcx(|fcx, tcx| {
         let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id));
@@ -311,6 +313,8 @@ fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
+    debug!("check_trait: {:?}", item.id);
+
     let trait_def_id = tcx.hir.local_def_id(item.id);
 
     let trait_def = tcx.trait_def(trait_def_id);
@@ -1012,7 +1016,7 @@ fn impl_implied_bounds(&self, impl_def_id: DefId, span: Span) -> Vec<Ty<'tcx>> {
             }
 
             None => {
-                // Inherent impl: take implied bounds from the self type.
+                // Inherent impl: take implied bounds from the `self` type.
                 let self_ty = self.tcx.type_of(impl_def_id);
                 let self_ty = self.normalize_associated_types_in(span, &self_ty);
                 vec![self_ty]
index be09cfce8cae6424ad9dc1fbde3ba554e211f3db..d5f5cbb562e78514581bea80c91fc6e1237add51 100644 (file)
@@ -1978,9 +1978,9 @@ pub enum SizedByDefault {
     No,
 }
 
-/// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
-/// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
-/// built-in trait (formerly known as kind): Send.
+/// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped `Ty`
+/// or a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
+/// built-in trait `Send`.
 pub fn compute_bounds<'gcx: 'tcx, 'tcx>(
     astconv: &dyn AstConv<'gcx, 'tcx>,
     param_ty: Ty<'tcx>,
@@ -1988,8 +1988,8 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(
     sized_by_default: SizedByDefault,
     span: Span,
 ) -> Bounds<'tcx> {
-    let mut region_bounds = vec![];
-    let mut trait_bounds = vec![];
+    let mut region_bounds = Vec::new();
+    let mut trait_bounds = Vec::new();
 
     for ast_bound in ast_bounds {
         match *ast_bound {
@@ -1999,7 +1999,7 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(
         }
     }
 
-    let mut projection_bounds = vec![];
+    let mut projection_bounds = Vec::new();
 
     let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
         (astconv.instantiate_poly_trait_ref(bound, param_ty, &mut projection_bounds), bound.span)
index c81aea2465b7be40b39d5840be6c07bbeb915061..a985c3e9fdf449bfc8b57664c867ef065d1025f6 100644 (file)
@@ -4909,4 +4909,5 @@ fn is_null(self: *const Self) -> bool {
     E0641, // cannot cast to/from a pointer with an unknown kind
     E0645, // trait aliases not finished
     E0698, // type inside generator must be known in this context
+    E0719, // duplicate values for associated type binding
 }
index d748d93d8988e63470b142ac6381cf7f01f9285b..6ed59837eb49a2c23a709491a25918c5e49d4c03 100644 (file)
@@ -11,6 +11,7 @@
 use rustc::ty::outlives::Component;
 use rustc::ty::subst::{Kind, UnpackedKind};
 use rustc::ty::{self, Region, RegionKind, Ty, TyCtxt};
+use smallvec::smallvec;
 use std::collections::BTreeSet;
 
 /// Tracks the `T: 'a` or `'a: 'a` predicates that we have inferred
@@ -40,7 +41,9 @@ pub fn insert_outlives_predicate<'tcx>(
             //
             // Or if within `struct Foo<U>` you had `T = Vec<U>`, then
             // we would want to add `U: 'outlived_region`
-            for component in tcx.outlives_components(ty) {
+            let mut components = smallvec![];
+            tcx.push_outlives_components(ty, &mut components);
+            for component in components {
                 match component {
                     Component::Region(r) => {
                         // This would arise from something like:
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 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");
 }
diff --git a/src/test/run-pass/associated-types/associated-types-from-supertrait.rs b/src/test/run-pass/associated-types/associated-types-from-supertrait.rs
new file mode 100644 (file)
index 0000000..e69c0af
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2018 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.
+
+trait Foo: Iterator<Item = i32> {}
+trait Bar: Foo {}
+
+fn main() {
+    let _: &dyn Bar;
+}
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();
diff --git a/src/test/run-pass/issues/issue-24010.rs b/src/test/run-pass/issues/issue-24010.rs
new file mode 100644 (file)
index 0000000..cce8bb8
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+trait Foo: Fn(i32) -> i32 + Send {}
+
+impl<T: ?Sized + Fn(i32) -> i32 + Send> Foo for T {}
+
+fn wants_foo(f: Box<Foo>) -> i32 {
+    f(42)
+}
+
+fn main() {
+    let f = Box::new(|x| x);
+    assert_eq!(wants_foo(f), 42);
+}
diff --git a/src/test/run-pass/traits/trait-alias-object-type.rs b/src/test/run-pass/traits/trait-alias-object-type.rs
deleted file mode 100644 (file)
index 17e3092..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(trait_alias)]
-
-trait Foo = PartialEq<i32> + Send;
-trait Bar = Foo + Sync;
-
-trait I32Iterator = Iterator<Item = i32>;
-
-pub fn main() {
-    let a: &dyn Bar = &123;
-    assert!(*a == 123);
-    let b = Box::new(456) as Box<dyn Foo>;
-    assert!(*b == 456);
-
-    // FIXME(alexreg): associated type should be gotten from trait alias definition
-    // let c: &dyn I32Iterator = &vec![123].into_iter();
-    // assert_eq!(c.next(), Some(123));
-}
diff --git a/src/test/run-pass/traits/trait-alias-object.rs b/src/test/run-pass/traits/trait-alias-object.rs
new file mode 100644 (file)
index 0000000..adac28e
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(trait_alias)]
+
+trait Foo = PartialEq<i32> + Send;
+trait Bar = Foo + Sync;
+
+trait I32Iterator = Iterator<Item = i32>;
+
+pub fn main() {
+    let a: &dyn Bar = &123;
+    assert!(*a == 123);
+    let b = Box::new(456) as Box<dyn Foo>;
+    assert!(*b == 456);
+
+    let c: &mut dyn I32Iterator = &mut vec![123].into_iter();
+    assert_eq!(c.next(), Some(123));
+}
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding-2.rs b/src/test/ui/associated-types/associated-types-overridden-binding-2.rs
new file mode 100644 (file)
index 0000000..8d91561
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(trait_alias)]
+
+trait I32Iterator = Iterator<Item = i32>;
+
+fn main() {
+    let _: &I32Iterator<Item = u32> = &vec![42].into_iter();
+}
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr
new file mode 100644 (file)
index 0000000..536cd94
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as std::iter::Iterator>::Item == i32`
+  --> $DIR/associated-types-overridden-binding-2.rs:16:39
+   |
+LL |     let _: &I32Iterator<Item = u32> = &vec![42].into_iter();
+   |                                       ^^^^^^^^^^^^^^^^^^^^^ expected u32, found i32
+   |
+   = note: expected type `u32`
+              found type `i32`
+   = note: required for the cast to the object type `dyn I32Iterator<Item=u32, Item=i32>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.rs b/src/test/ui/associated-types/associated-types-overridden-binding.rs
new file mode 100644 (file)
index 0000000..ed2211e
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(trait_alias)]
+
+trait Foo: Iterator<Item = i32> {}
+trait Bar: Foo<Item = u32> {}
+
+trait I32Iterator = Iterator<Item = i32>;
+trait U32Iterator = I32Iterator<Item = u32>;
+
+fn main() {
+    let _: &I32Iterator<Item = u32>;
+}
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.stderr b/src/test/ui/associated-types/associated-types-overridden-binding.stderr
new file mode 100644 (file)
index 0000000..216aa09
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0284]: type annotations required: cannot resolve `<Self as std::iter::Iterator>::Item == i32`
+  --> $DIR/associated-types-overridden-binding.rs:14:1
+   |
+LL | trait Bar: Foo<Item = u32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: required by `Foo`
+  --> $DIR/associated-types-overridden-binding.rs:13:1
+   |
+LL | trait Foo: Iterator<Item = i32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0284`.
diff --git a/src/test/ui/borrowck/borrowck-box-insensitivity.ast.stderr b/src/test/ui/borrowck/borrowck-box-insensitivity.ast.stderr
new file mode 100644 (file)
index 0000000..95b26a5
--- /dev/null
@@ -0,0 +1,165 @@
+error[E0382]: use of moved value: `a`
+  --> $DIR/borrowck-box-insensitivity.rs:37:9
+   |
+LL |     let _x = a.x;
+   |         -- value moved here
+LL |     //[ast]~^ value moved here
+LL |     let _y = a.y; //[ast]~ ERROR use of moved
+   |         ^^ value used here after move
+   |
+   = note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
+
+error[E0382]: use of moved value: `a`
+  --> $DIR/borrowck-box-insensitivity.rs:46:9
+   |
+LL |     let _x = a.x;
+   |         -- value moved here
+LL |     //[ast]~^ value moved here
+LL |     let _y = a.y; //[ast]~ ERROR use of moved
+   |         ^^ value used here after move
+   |
+   = note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
+
+error[E0382]: use of moved value: `a`
+  --> $DIR/borrowck-box-insensitivity.rs:55:15
+   |
+LL |     let _x = a.x;
+   |         -- value moved here
+LL |     //[ast]~^ value moved here
+LL |     let _y = &a.y; //[ast]~ ERROR use of moved
+   |               ^^^ value used here after move
+   |
+   = note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
+
+error[E0505]: cannot move out of `a.y` because it is borrowed
+  --> $DIR/borrowck-box-insensitivity.rs:63:9
+   |
+LL |     let _x = &a.x;
+   |               --- borrow of `a.x` occurs here
+LL |     let _y = a.y;
+   |         ^^ move out of `a.y` occurs here
+
+error[E0503]: cannot use `a.y` because it was mutably borrowed
+  --> $DIR/borrowck-box-insensitivity.rs:71:9
+   |
+LL |     let _x = &mut a.x;
+   |                   --- borrow of `a.x` occurs here
+LL |     let _y = a.y; //[ast]~ ERROR cannot use
+   |         ^^ use of borrowed `a.x`
+
+error[E0505]: cannot move out of `a.y` because it is borrowed
+  --> $DIR/borrowck-box-insensitivity.rs:77:9
+   |
+LL |     let _x = &mut a.x;
+   |                   --- borrow of `a.x` occurs here
+LL |     let _y = a.y;
+   |         ^^ move out of `a.y` occurs here
+
+error[E0502]: cannot borrow `a` (via `a.y`) as immutable because `a` is also borrowed as mutable (via `a.x`)
+  --> $DIR/borrowck-box-insensitivity.rs:85:15
+   |
+LL |     let _x = &mut a.x;
+   |                   --- mutable borrow occurs here (via `a.x`)
+LL |     let _y = &a.y; //[ast]~ ERROR cannot borrow
+   |               ^^^ immutable borrow occurs here (via `a.y`)
+...
+LL | }
+   | - mutable borrow ends here
+
+error[E0502]: cannot borrow `a` (via `a.y`) as mutable because `a` is also borrowed as immutable (via `a.x`)
+  --> $DIR/borrowck-box-insensitivity.rs:92:19
+   |
+LL |     let _x = &a.x;
+   |               --- immutable borrow occurs here (via `a.x`)
+LL |     let _y = &mut a.y; //[ast]~ ERROR cannot borrow
+   |                   ^^^ mutable borrow occurs here (via `a.y`)
+...
+LL | }
+   | - immutable borrow ends here
+
+error[E0382]: use of collaterally moved value: `a.y`
+  --> $DIR/borrowck-box-insensitivity.rs:100:9
+   |
+LL |     let _x = a.x.x;
+   |         -- value moved here
+LL |     //[ast]~^ value moved here
+LL |     let _y = a.y; //[ast]~ ERROR use of collaterally moved
+   |         ^^ value used here after move
+   |
+   = note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
+
+error[E0382]: use of collaterally moved value: `a.y`
+  --> $DIR/borrowck-box-insensitivity.rs:108:9
+   |
+LL |     let _x = a.x.x;
+   |         -- value moved here
+LL |     //[ast]~^ value moved here
+LL |     let _y = a.y; //[ast]~ ERROR use of collaterally moved
+   |         ^^ value used here after move
+   |
+   = note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
+
+error[E0382]: use of collaterally moved value: `a.y`
+  --> $DIR/borrowck-box-insensitivity.rs:116:15
+   |
+LL |     let _x = a.x.x;
+   |         -- value moved here
+LL |     //[ast]~^ value moved here
+LL |     let _y = &a.y; //[ast]~ ERROR use of collaterally moved
+   |               ^^^ value used here after move
+   |
+   = note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
+
+error[E0505]: cannot move out of `a.y` because it is borrowed
+  --> $DIR/borrowck-box-insensitivity.rs:124:9
+   |
+LL |     let _x = &a.x.x;
+   |               ----- borrow of `a.x.x` occurs here
+LL |     //[ast]~^ borrow of `a.x.x` occurs here
+LL |     let _y = a.y;
+   |         ^^ move out of `a.y` occurs here
+
+error[E0503]: cannot use `a.y` because it was mutably borrowed
+  --> $DIR/borrowck-box-insensitivity.rs:132:9
+   |
+LL |     let _x = &mut a.x.x;
+   |                   ----- borrow of `a.x.x` occurs here
+LL |     let _y = a.y; //[ast]~ ERROR cannot use
+   |         ^^ use of borrowed `a.x.x`
+
+error[E0505]: cannot move out of `a.y` because it is borrowed
+  --> $DIR/borrowck-box-insensitivity.rs:138:9
+   |
+LL |     let _x = &mut a.x.x;
+   |                   ----- borrow of `a.x.x` occurs here
+LL |     let _y = a.y;
+   |         ^^ move out of `a.y` occurs here
+
+error[E0502]: cannot borrow `a.y` as immutable because `a.x.x` is also borrowed as mutable
+  --> $DIR/borrowck-box-insensitivity.rs:147:15
+   |
+LL |     let _x = &mut a.x.x;
+   |                   ----- mutable borrow occurs here
+LL |     //[ast]~^ mutable borrow occurs here
+LL |     let _y = &a.y; //[ast]~ ERROR cannot borrow
+   |               ^^^ immutable borrow occurs here
+...
+LL | }
+   | - mutable borrow ends here
+
+error[E0502]: cannot borrow `a.y` as mutable because `a.x.x` is also borrowed as immutable
+  --> $DIR/borrowck-box-insensitivity.rs:155:19
+   |
+LL |     let _x = &a.x.x;
+   |               ----- immutable borrow occurs here
+LL |     //[ast]~^ immutable borrow occurs here
+LL |     let _y = &mut a.y; //[ast]~ ERROR cannot borrow
+   |                   ^^^ mutable borrow occurs here
+...
+LL | }
+   | - immutable borrow ends here
+
+error: aborting due to 16 previous errors
+
+Some errors occurred: E0382, E0502, E0503, E0505.
+For more information about an error, try `rustc --explain E0382`.
diff --git a/src/test/ui/borrowck/borrowck-box-insensitivity.mir.stderr b/src/test/ui/borrowck/borrowck-box-insensitivity.mir.stderr
new file mode 100644 (file)
index 0000000..171e992
--- /dev/null
@@ -0,0 +1,14 @@
+error: compilation successful
+  --> $DIR/borrowck-box-insensitivity.rs:160:1
+   |
+LL | / fn main() { //[mir]~ ERROR compilation successful
+LL | |     copy_after_move();
+LL | |     move_after_move();
+LL | |     borrow_after_move();
+...  |
+LL | |     mut_borrow_after_borrow_nested();
+LL | | }
+   | |_^
+
+error: aborting due to previous error
+
index eabb8d7bca3fae511c73da3e4edd2f5d393e4041..2af97a9fc1d58718ed3e92eefa80f0549adbe68e 100644 (file)
@@ -1,13 +1,13 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
+// This test is an artifact of the old policy that `Box<T>` should not
+// be treated specially by the AST-borrowck.
 //
-// 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.
+// NLL goes back to treating `Box<T>` specially (namely, knowing that
+// it uniquely owns the data it holds). See rust-lang/rfcs#130.
 
+// revisions: ast mir
+//[ast] compile-flags: -Z borrowck=ast
+//[mir] compile-flags: -Z borrowck=mir
+// ignore-compare-mode-nll
 #![feature(box_syntax, rustc_attrs)]
 
 struct A {
@@ -33,131 +33,131 @@ struct D {
 fn copy_after_move() {
     let a: Box<_> = box A { x: box 0, y: 1 };
     let _x = a.x;
-    //~^ value moved here
-    let _y = a.y; //~ ERROR use of moved
-    //~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
-    //~| value used here after move
+    //[ast]~^ value moved here
+    let _y = a.y; //[ast]~ ERROR use of moved
+    //[ast]~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
+    //[ast]~| value used here after move
 }
 
 fn move_after_move() {
     let a: Box<_> = box B { x: box 0, y: box 1 };
     let _x = a.x;
-    //~^ value moved here
-    let _y = a.y; //~ ERROR use of moved
-    //~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
-    //~| value used here after move
+    //[ast]~^ value moved here
+    let _y = a.y; //[ast]~ ERROR use of moved
+    //[ast]~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
+    //[ast]~| value used here after move
 }
 
 fn borrow_after_move() {
     let a: Box<_> = box A { x: box 0, y: 1 };
     let _x = a.x;
-    //~^ value moved here
-    let _y = &a.y; //~ ERROR use of moved
-    //~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
-    //~| value used here after move
+    //[ast]~^ value moved here
+    let _y = &a.y; //[ast]~ ERROR use of moved
+    //[ast]~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
+    //[ast]~| value used here after move
 }
 
 fn move_after_borrow() {
     let a: Box<_> = box B { x: box 0, y: box 1 };
     let _x = &a.x;
     let _y = a.y;
-    //~^ ERROR cannot move
-    //~| move out of
+    //[ast]~^ ERROR cannot move
+    //[ast]~| move out of
+    use_imm(_x);
 }
-
 fn copy_after_mut_borrow() {
     let mut a: Box<_> = box A { x: box 0, y: 1 };
     let _x = &mut a.x;
-    let _y = a.y; //~ ERROR cannot use
+    let _y = a.y; //[ast]~ ERROR cannot use
+    use_mut(_x);
 }
-
 fn move_after_mut_borrow() {
     let mut a: Box<_> = box B { x: box 0, y: box 1 };
     let _x = &mut a.x;
     let _y = a.y;
-    //~^ ERROR cannot move
-    //~| move out of
+    //[ast]~^ ERROR cannot move
+    //[ast]~| move out of
+    use_mut(_x);
 }
-
 fn borrow_after_mut_borrow() {
     let mut a: Box<_> = box A { x: box 0, y: 1 };
     let _x = &mut a.x;
-    let _y = &a.y; //~ ERROR cannot borrow
-    //~^ immutable borrow occurs here (via `a.y`)
+    let _y = &a.y; //[ast]~ ERROR cannot borrow
+    //[ast]~^ immutable borrow occurs here (via `a.y`)
+    use_mut(_x);
 }
-
 fn mut_borrow_after_borrow() {
     let mut a: Box<_> = box A { x: box 0, y: 1 };
     let _x = &a.x;
-    let _y = &mut a.y; //~ ERROR cannot borrow
-    //~^ mutable borrow occurs here (via `a.y`)
+    let _y = &mut a.y; //[ast]~ ERROR cannot borrow
+    //[ast]~^ mutable borrow occurs here (via `a.y`)
+    use_imm(_x);
 }
-
 fn copy_after_move_nested() {
     let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
     let _x = a.x.x;
-    //~^ value moved here
-    let _y = a.y; //~ ERROR use of collaterally moved
-    //~| value used here after move
+    //[ast]~^ value moved here
+    let _y = a.y; //[ast]~ ERROR use of collaterally moved
+    //[ast]~| value used here after move
 }
 
 fn move_after_move_nested() {
     let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
     let _x = a.x.x;
-    //~^ value moved here
-    let _y = a.y; //~ ERROR use of collaterally moved
-    //~| value used here after move
+    //[ast]~^ value moved here
+    let _y = a.y; //[ast]~ ERROR use of collaterally moved
+    //[ast]~| value used here after move
 }
 
 fn borrow_after_move_nested() {
     let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
     let _x = a.x.x;
-    //~^ value moved here
-    let _y = &a.y; //~ ERROR use of collaterally moved
-    //~| value used here after move
+    //[ast]~^ value moved here
+    let _y = &a.y; //[ast]~ ERROR use of collaterally moved
+    //[ast]~| value used here after move
 }
 
 fn move_after_borrow_nested() {
     let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
     let _x = &a.x.x;
-    //~^ borrow of `a.x.x` occurs here
+    //[ast]~^ borrow of `a.x.x` occurs here
     let _y = a.y;
-    //~^ ERROR cannot move
-    //~| move out of
+    //[ast]~^ ERROR cannot move
+    //[ast]~| move out of
+    use_imm(_x);
 }
-
 fn copy_after_mut_borrow_nested() {
     let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
     let _x = &mut a.x.x;
-    let _y = a.y; //~ ERROR cannot use
+    let _y = a.y; //[ast]~ ERROR cannot use
+    use_mut(_x);
 }
-
 fn move_after_mut_borrow_nested() {
     let mut a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
     let _x = &mut a.x.x;
     let _y = a.y;
-    //~^ ERROR cannot move
-    //~| move out of
+    //[ast]~^ ERROR cannot move
+    //[ast]~| move out of
+    use_mut(_x);
 }
-
 fn borrow_after_mut_borrow_nested() {
     let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
     let _x = &mut a.x.x;
-    //~^ mutable borrow occurs here
-    let _y = &a.y; //~ ERROR cannot borrow
-    //~^ immutable borrow occurs here
+    //[ast]~^ mutable borrow occurs here
+    let _y = &a.y; //[ast]~ ERROR cannot borrow
+    //[ast]~^ immutable borrow occurs here
+    use_mut(_x);
 }
-
 fn mut_borrow_after_borrow_nested() {
     let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
     let _x = &a.x.x;
-    //~^ immutable borrow occurs here
-    let _y = &mut a.y; //~ ERROR cannot borrow
-    //~^ mutable borrow occurs here
+    //[ast]~^ immutable borrow occurs here
+    let _y = &mut a.y; //[ast]~ ERROR cannot borrow
+    //[ast]~^ mutable borrow occurs here
+    use_imm(_x);
 }
-
 #[rustc_error]
-fn main() {
+fn main() { //[mir]~ ERROR compilation successful
     copy_after_move();
     move_after_move();
     borrow_after_move();
@@ -180,3 +180,6 @@ fn main() {
     borrow_after_mut_borrow_nested();
     mut_borrow_after_borrow_nested();
 }
+
+fn use_mut<T>(_: &mut T) { }
+fn use_imm<T>(_: &T) { }
diff --git a/src/test/ui/borrowck/borrowck-box-insensitivity.stderr b/src/test/ui/borrowck/borrowck-box-insensitivity.stderr
deleted file mode 100644 (file)
index 5bf1fc0..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-error[E0382]: use of moved value: `a`
-  --> $DIR/borrowck-box-insensitivity.rs:37:9
-   |
-LL |     let _x = a.x;
-   |         -- value moved here
-LL |     //~^ value moved here
-LL |     let _y = a.y; //~ ERROR use of moved
-   |         ^^ value used here after move
-   |
-   = note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
-
-error[E0382]: use of moved value: `a`
-  --> $DIR/borrowck-box-insensitivity.rs:46:9
-   |
-LL |     let _x = a.x;
-   |         -- value moved here
-LL |     //~^ value moved here
-LL |     let _y = a.y; //~ ERROR use of moved
-   |         ^^ value used here after move
-   |
-   = note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
-
-error[E0382]: use of moved value: `a`
-  --> $DIR/borrowck-box-insensitivity.rs:55:15
-   |
-LL |     let _x = a.x;
-   |         -- value moved here
-LL |     //~^ value moved here
-LL |     let _y = &a.y; //~ ERROR use of moved
-   |               ^^^ value used here after move
-   |
-   = note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
-
-error[E0505]: cannot move out of `a.y` because it is borrowed
-  --> $DIR/borrowck-box-insensitivity.rs:63:9
-   |
-LL |     let _x = &a.x;
-   |               --- borrow of `a.x` occurs here
-LL |     let _y = a.y;
-   |         ^^ move out of `a.y` occurs here
-
-error[E0503]: cannot use `a.y` because it was mutably borrowed
-  --> $DIR/borrowck-box-insensitivity.rs:71:9
-   |
-LL |     let _x = &mut a.x;
-   |                   --- borrow of `a.x` occurs here
-LL |     let _y = a.y; //~ ERROR cannot use
-   |         ^^ use of borrowed `a.x`
-
-error[E0505]: cannot move out of `a.y` because it is borrowed
-  --> $DIR/borrowck-box-insensitivity.rs:77:9
-   |
-LL |     let _x = &mut a.x;
-   |                   --- borrow of `a.x` occurs here
-LL |     let _y = a.y;
-   |         ^^ move out of `a.y` occurs here
-
-error[E0502]: cannot borrow `a` (via `a.y`) as immutable because `a` is also borrowed as mutable (via `a.x`)
-  --> $DIR/borrowck-box-insensitivity.rs:85:15
-   |
-LL |     let _x = &mut a.x;
-   |                   --- mutable borrow occurs here (via `a.x`)
-LL |     let _y = &a.y; //~ ERROR cannot borrow
-   |               ^^^ immutable borrow occurs here (via `a.y`)
-LL |     //~^ immutable borrow occurs here (via `a.y`)
-LL | }
-   | - mutable borrow ends here
-
-error[E0502]: cannot borrow `a` (via `a.y`) as mutable because `a` is also borrowed as immutable (via `a.x`)
-  --> $DIR/borrowck-box-insensitivity.rs:92:19
-   |
-LL |     let _x = &a.x;
-   |               --- immutable borrow occurs here (via `a.x`)
-LL |     let _y = &mut a.y; //~ ERROR cannot borrow
-   |                   ^^^ mutable borrow occurs here (via `a.y`)
-LL |     //~^ mutable borrow occurs here (via `a.y`)
-LL | }
-   | - immutable borrow ends here
-
-error[E0382]: use of collaterally moved value: `a.y`
-  --> $DIR/borrowck-box-insensitivity.rs:100:9
-   |
-LL |     let _x = a.x.x;
-   |         -- value moved here
-LL |     //~^ value moved here
-LL |     let _y = a.y; //~ ERROR use of collaterally moved
-   |         ^^ value used here after move
-   |
-   = note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
-
-error[E0382]: use of collaterally moved value: `a.y`
-  --> $DIR/borrowck-box-insensitivity.rs:108:9
-   |
-LL |     let _x = a.x.x;
-   |         -- value moved here
-LL |     //~^ value moved here
-LL |     let _y = a.y; //~ ERROR use of collaterally moved
-   |         ^^ value used here after move
-   |
-   = note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
-
-error[E0382]: use of collaterally moved value: `a.y`
-  --> $DIR/borrowck-box-insensitivity.rs:116:15
-   |
-LL |     let _x = a.x.x;
-   |         -- value moved here
-LL |     //~^ value moved here
-LL |     let _y = &a.y; //~ ERROR use of collaterally moved
-   |               ^^^ value used here after move
-   |
-   = note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
-
-error[E0505]: cannot move out of `a.y` because it is borrowed
-  --> $DIR/borrowck-box-insensitivity.rs:124:9
-   |
-LL |     let _x = &a.x.x;
-   |               ----- borrow of `a.x.x` occurs here
-LL |     //~^ borrow of `a.x.x` occurs here
-LL |     let _y = a.y;
-   |         ^^ move out of `a.y` occurs here
-
-error[E0503]: cannot use `a.y` because it was mutably borrowed
-  --> $DIR/borrowck-box-insensitivity.rs:132:9
-   |
-LL |     let _x = &mut a.x.x;
-   |                   ----- borrow of `a.x.x` occurs here
-LL |     let _y = a.y; //~ ERROR cannot use
-   |         ^^ use of borrowed `a.x.x`
-
-error[E0505]: cannot move out of `a.y` because it is borrowed
-  --> $DIR/borrowck-box-insensitivity.rs:138:9
-   |
-LL |     let _x = &mut a.x.x;
-   |                   ----- borrow of `a.x.x` occurs here
-LL |     let _y = a.y;
-   |         ^^ move out of `a.y` occurs here
-
-error[E0502]: cannot borrow `a.y` as immutable because `a.x.x` is also borrowed as mutable
-  --> $DIR/borrowck-box-insensitivity.rs:147:15
-   |
-LL |     let _x = &mut a.x.x;
-   |                   ----- mutable borrow occurs here
-LL |     //~^ mutable borrow occurs here
-LL |     let _y = &a.y; //~ ERROR cannot borrow
-   |               ^^^ immutable borrow occurs here
-LL |     //~^ immutable borrow occurs here
-LL | }
-   | - mutable borrow ends here
-
-error[E0502]: cannot borrow `a.y` as mutable because `a.x.x` is also borrowed as immutable
-  --> $DIR/borrowck-box-insensitivity.rs:155:19
-   |
-LL |     let _x = &a.x.x;
-   |               ----- immutable borrow occurs here
-LL |     //~^ immutable borrow occurs here
-LL |     let _y = &mut a.y; //~ ERROR cannot borrow
-   |                   ^^^ mutable borrow occurs here
-LL |     //~^ mutable borrow occurs here
-LL | }
-   | - immutable borrow ends here
-
-error: aborting due to 16 previous errors
-
-Some errors occurred: E0382, E0502, E0503, E0505.
-For more information about an error, try `rustc --explain E0382`.
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);
+}
diff --git a/src/test/ui/consts/const-prop-ice.rs b/src/test/ui/consts/const-prop-ice.rs
new file mode 100644 (file)
index 0000000..13309f9
--- /dev/null
@@ -0,0 +1,3 @@
+fn main() {
+    [0; 3][3u64 as usize]; //~ ERROR the len is 3 but the index is 3
+}
diff --git a/src/test/ui/consts/const-prop-ice.stderr b/src/test/ui/consts/const-prop-ice.stderr
new file mode 100644 (file)
index 0000000..749ef95
--- /dev/null
@@ -0,0 +1,10 @@
+error: index out of bounds: the len is 3 but the index is 3
+  --> $DIR/const-prop-ice.rs:2:5
+   |
+LL |     [0; 3][3u64 as usize]; //~ ERROR the len is 3 but the index is 3
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: #[deny(const_err)] on by default
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/consts/const-prop-ice2.rs b/src/test/ui/consts/const-prop-ice2.rs
new file mode 100644 (file)
index 0000000..e5fd79f
--- /dev/null
@@ -0,0 +1,5 @@
+fn main() {
+    enum Enum { One=1 }
+    let xs=[0;1 as usize];
+    println!("{}", xs[Enum::One as usize]); //~ ERROR the len is 1 but the index is 1
+}
diff --git a/src/test/ui/consts/const-prop-ice2.stderr b/src/test/ui/consts/const-prop-ice2.stderr
new file mode 100644 (file)
index 0000000..4febd0e
--- /dev/null
@@ -0,0 +1,10 @@
+error: index out of bounds: the len is 1 but the index is 1
+  --> $DIR/const-prop-ice2.rs:4:20
+   |
+LL |     println!("{}", xs[Enum::One as usize]); //~ ERROR the len is 1 but the index is 1
+   |                    ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: #[deny(const_err)] on by default
+
+error: aborting due to previous error
+
index 489ebb033f84e8133c98961750ff7530ba4878dc..c35c7e10f5a38500ab26cff4ab0cc8854964f397 100644 (file)
@@ -14,5 +14,4 @@ trait Trait {
 
 type Foo = Trait; //~ ERROR E0191
 
-fn main() {
-}
+fn main() {}
diff --git a/src/test/ui/error-codes/E0719.rs b/src/test/ui/error-codes/E0719.rs
new file mode 100644 (file)
index 0000000..c7bfa85
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+trait Foo: Iterator<Item = i32, Item = i32> {}
+
+type Unit = ();
+
+fn test() -> Box<Iterator<Item = (), Item = Unit>> {
+    Box::new(None.into_iter())
+}
+
+fn main() {
+    let _: &Iterator<Item = i32, Item = i32>;
+    test();
+}
diff --git a/src/test/ui/error-codes/E0719.stderr b/src/test/ui/error-codes/E0719.stderr
new file mode 100644 (file)
index 0000000..3a908fc
--- /dev/null
@@ -0,0 +1,19 @@
+error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
+  --> $DIR/E0719.rs:11:33
+   |
+LL | trait Foo: Iterator<Item = i32, Item = i32> {}
+   |                     ----------  ^^^^^^^^^^ re-bound here
+   |                     |
+   |                     `Item` bound here first
+
+error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
+  --> $DIR/E0719.rs:15:38
+   |
+LL | fn test() -> Box<Iterator<Item = (), Item = Unit>> {
+   |                           ---------  ^^^^^^^^^^^ re-bound here
+   |                           |
+   |                           `Item` bound here first
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0719`.
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
    |                                ^^^^^^^^^^^^^
diff --git a/src/test/ui/issue-51947.rs b/src/test/ui/issue-51947.rs
deleted file mode 100644 (file)
index 7b79807..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// compile-pass
-
-#![crate_type = "lib"]
-#![feature(linkage)]
-
-// MergeFunctions will merge these via an anonymous internal
-// backing function, which must be named if ThinLTO buffers are used
-
-#[linkage = "weak"]
-pub fn fn1(a: u32, b: u32, c: u32) -> u32 {
-    a + b + c
-}
-
-#[linkage = "weak"]
-pub fn fn2(a: u32, b: u32, c: u32) -> u32 {
-    a + b + c
-}
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/issues/issue-51947.rs b/src/test/ui/issues/issue-51947.rs
new file mode 100644 (file)
index 0000000..3e0c3c0
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2018 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
+
+#![crate_type = "lib"]
+#![feature(linkage)]
+
+// MergeFunctions will merge these via an anonymous internal
+// backing function, which must be named if ThinLTO buffers are used
+
+#[linkage = "weak"]
+pub fn fn1(a: u32, b: u32, c: u32) -> u32 {
+    a + b + c
+}
+
+#[linkage = "weak"]
+pub fn fn2(a: u32, b: u32, c: u32) -> u32 {
+    a + b + c
+}
diff --git a/src/test/ui/issues/issue-55796.rs b/src/test/ui/issues/issue-55796.rs
new file mode 100644 (file)
index 0000000..b48d4a9
--- /dev/null
@@ -0,0 +1,22 @@
+pub trait EdgeTrait<N> {
+    fn target(&self) -> N;
+}
+
+pub trait Graph<'a> {
+    type Node;
+    type Edge: EdgeTrait<Self::Node>;
+    type NodesIter: Iterator<Item = Self::Node> + 'a;
+    type EdgesIter: Iterator<Item = Self::Edge> + 'a;
+
+    fn nodes(&'a self) -> Self::NodesIter;
+    fn out_edges(&'a self, u: &Self::Node) -> Self::EdgesIter;
+    fn in_edges(&'a self, u: &Self::Node) -> Self::EdgesIter;
+
+    fn out_neighbors(&'a self, u: &Self::Node) -> Box<Iterator<Item = Self::Node>> {
+        Box::new(self.out_edges(u).map(|e| e.target()))
+    }
+
+    fn in_neighbors(&'a self, u: &Self::Node) -> Box<Iterator<Item = Self::Node>> {
+        Box::new(self.in_edges(u).map(|e| e.target()))
+    }
+}
diff --git a/src/test/ui/issues/issue-55796.stderr b/src/test/ui/issues/issue-55796.stderr
new file mode 100644 (file)
index 0000000..60ce829
--- /dev/null
@@ -0,0 +1,50 @@
+error[E0601]: `main` function not found in crate `issue_55796`
+   |
+   = note: consider adding a `main` function to `$DIR/issue-55796.rs`
+
+error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+  --> $DIR/issue-55796.rs:16:9
+   |
+LL |         Box::new(self.out_edges(u).map(|e| e.target()))
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: first, the lifetime cannot outlive the lifetime 'a as defined on the trait at 5:17...
+  --> $DIR/issue-55796.rs:5:17
+   |
+LL | pub trait Graph<'a> {
+   |                 ^^
+note: ...so that the type `std::iter::Map<<Self as Graph<'a>>::EdgesIter, [closure@$DIR/issue-55796.rs:16:40: 16:54]>` will meet its required lifetime bounds
+  --> $DIR/issue-55796.rs:16:9
+   |
+LL |         Box::new(self.out_edges(u).map(|e| e.target()))
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: but, the lifetime must be valid for the static lifetime...
+   = note: ...so that the expression is assignable:
+           expected std::boxed::Box<(dyn std::iter::Iterator<Item=<Self as Graph<'a>>::Node> + 'static)>
+              found std::boxed::Box<dyn std::iter::Iterator<Item=<Self as Graph<'a>>::Node>>
+
+error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+  --> $DIR/issue-55796.rs:20:9
+   |
+LL |         Box::new(self.in_edges(u).map(|e| e.target()))
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: first, the lifetime cannot outlive the lifetime 'a as defined on the trait at 5:17...
+  --> $DIR/issue-55796.rs:5:17
+   |
+LL | pub trait Graph<'a> {
+   |                 ^^
+note: ...so that the type `std::iter::Map<<Self as Graph<'a>>::EdgesIter, [closure@$DIR/issue-55796.rs:20:39: 20:53]>` will meet its required lifetime bounds
+  --> $DIR/issue-55796.rs:20:9
+   |
+LL |         Box::new(self.in_edges(u).map(|e| e.target()))
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: but, the lifetime must be valid for the static lifetime...
+   = note: ...so that the expression is assignable:
+           expected std::boxed::Box<(dyn std::iter::Iterator<Item=<Self as Graph<'a>>::Node> + 'static)>
+              found std::boxed::Box<dyn std::iter::Iterator<Item=<Self as Graph<'a>>::Node>>
+
+error: aborting due to 3 previous errors
+
+Some errors occurred: E0495, E0601.
+For more information about an error, try `rustc --explain E0495`.
diff --git a/src/test/ui/lint/issue-50589-multiple-associated-types.rs b/src/test/ui/lint/issue-50589-multiple-associated-types.rs
deleted file mode 100644 (file)
index 2c789a1..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018 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
-
-use std::iter::Iterator;
-
-type Unit = ();
-
-fn test() ->  Box<Iterator<Item = (), Item = Unit>> {
-    Box::new(None.into_iter())
-}
-
-fn main() {
-    test();
-}
diff --git a/src/test/ui/lint/issue-50589-multiple-associated-types.stderr b/src/test/ui/lint/issue-50589-multiple-associated-types.stderr
deleted file mode 100644 (file)
index 7f0a1ee..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-warning: associated type binding `Item` specified more than once
-  --> $DIR/issue-50589-multiple-associated-types.rs:17:39
-   |
-LL | fn test() ->  Box<Iterator<Item = (), Item = Unit>> {
-   |                            ---------  ^^^^^^^^^^^ used more than once
-   |                            |
-   |                            first use of `Item`
-   |
-   = note: #[warn(duplicate_associated_type_bindings)] on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #50589 <https://github.com/rust-lang/rust/issues/50589>
-
-warning: associated type binding `Item` specified more than once
-  --> $DIR/issue-50589-multiple-associated-types.rs:17:39
-   |
-LL | fn test() ->  Box<Iterator<Item = (), Item = Unit>> {
-   |                            ---------  ^^^^^^^^^^^ used more than once
-   |                            |
-   |                            first use of `Item`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #50589 <https://github.com/rust-lang/rust/issues/50589>
-
diff --git a/src/test/ui/lint/lint-unused-mut-variables.lexical.stderr b/src/test/ui/lint/lint-unused-mut-variables.lexical.stderr
deleted file mode 100644 (file)
index 40f68c6..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:59:14
-   |
-LL |     let x = |mut y: isize| 10; //[lexical]~ ERROR: variable does not need to be mutable
-   |              ----^
-   |              |
-   |              help: remove this `mut`
-   |
-note: lint level defined here
-  --> $DIR/lint-unused-mut-variables.rs:19:9
-   |
-LL | #![deny(unused_mut)]
-   |         ^^^^^^^^^^
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:24:9
-   |
-LL |     let mut a = 3; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:26:9
-   |
-LL |     let mut a = 2; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:28:9
-   |
-LL |     let mut b = 3; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:30:9
-   |
-LL |     let mut a = vec![3]; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:32:10
-   |
-LL |     let (mut a, b) = (1, 2); //[lexical]~ ERROR: variable does not need to be mutable
-   |          ----^
-   |          |
-   |          help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:34:9
-   |
-LL |     let mut a; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:38:9
-   |
-LL |     let mut b; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:47:9
-   |
-LL |         mut x => {} //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:51:8
-   |
-LL |       (mut x, 1) | //[lexical]~ ERROR: variable does not need to be mutable
-   |        ----^
-   |        |
-   |        help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:64:9
-   |
-LL |     let mut a = &mut 5; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:69:9
-   |
-LL |     let mut b = (&mut a,); //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:72:9
-   |
-LL |     let mut x = &mut 1; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:84:9
-   |
-LL |     let mut v : &mut Vec<()> = &mut vec![]; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:61:13
-   |
-LL |     fn what(mut foo: isize) {} //[lexical]~ ERROR: variable does not need to be mutable
-   |             ----^^^
-   |             |
-   |             help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:79:20
-   |
-LL |     fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
-   |                    ----^^^
-   |                    |
-   |                    help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:143:9
-   |
-LL |     let mut b = vec![2]; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-   |
-note: lint level defined here
-  --> $DIR/lint-unused-mut-variables.rs:139:8
-   |
-LL | #[deny(unused_mut)]
-   |        ^^^^^^^^^^
-
-error: aborting due to 17 previous errors
-
diff --git a/src/test/ui/lint/lint-unused-mut-variables.nll.stderr b/src/test/ui/lint/lint-unused-mut-variables.nll.stderr
deleted file mode 100644 (file)
index 40f68c6..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:59:14
-   |
-LL |     let x = |mut y: isize| 10; //[lexical]~ ERROR: variable does not need to be mutable
-   |              ----^
-   |              |
-   |              help: remove this `mut`
-   |
-note: lint level defined here
-  --> $DIR/lint-unused-mut-variables.rs:19:9
-   |
-LL | #![deny(unused_mut)]
-   |         ^^^^^^^^^^
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:24:9
-   |
-LL |     let mut a = 3; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:26:9
-   |
-LL |     let mut a = 2; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:28:9
-   |
-LL |     let mut b = 3; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:30:9
-   |
-LL |     let mut a = vec![3]; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:32:10
-   |
-LL |     let (mut a, b) = (1, 2); //[lexical]~ ERROR: variable does not need to be mutable
-   |          ----^
-   |          |
-   |          help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:34:9
-   |
-LL |     let mut a; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:38:9
-   |
-LL |     let mut b; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:47:9
-   |
-LL |         mut x => {} //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:51:8
-   |
-LL |       (mut x, 1) | //[lexical]~ ERROR: variable does not need to be mutable
-   |        ----^
-   |        |
-   |        help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:64:9
-   |
-LL |     let mut a = &mut 5; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:69:9
-   |
-LL |     let mut b = (&mut a,); //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:72:9
-   |
-LL |     let mut x = &mut 1; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:84:9
-   |
-LL |     let mut v : &mut Vec<()> = &mut vec![]; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:61:13
-   |
-LL |     fn what(mut foo: isize) {} //[lexical]~ ERROR: variable does not need to be mutable
-   |             ----^^^
-   |             |
-   |             help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:79:20
-   |
-LL |     fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
-   |                    ----^^^
-   |                    |
-   |                    help: remove this `mut`
-
-error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:143:9
-   |
-LL |     let mut b = vec![2]; //[lexical]~ ERROR: variable does not need to be mutable
-   |         ----^
-   |         |
-   |         help: remove this `mut`
-   |
-note: lint level defined here
-  --> $DIR/lint-unused-mut-variables.rs:139:8
-   |
-LL | #[deny(unused_mut)]
-   |        ^^^^^^^^^^
-
-error: aborting due to 17 previous errors
-
index 14d836074dca377123a891ccae19858d03dab41c..a2005ba9f72e02db8b82d3d3736c3d6756d9d9a2 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// revisions: lexical nll
-#![cfg_attr(nll, feature(nll))]
+
+
 
 // Exercise the unused_mut attribute in some positive and negative cases
 
 
 fn main() {
     // negative cases
-    let mut a = 3; //[lexical]~ ERROR: variable does not need to be mutable
-                   //[nll]~^ ERROR: variable does not need to be mutable
-    let mut a = 2; //[lexical]~ ERROR: variable does not need to be mutable
-                   //[nll]~^ ERROR: variable does not need to be mutable
-    let mut b = 3; //[lexical]~ ERROR: variable does not need to be mutable
-                   //[nll]~^ ERROR: variable does not need to be mutable
-    let mut a = vec![3]; //[lexical]~ ERROR: variable does not need to be mutable
-                         //[nll]~^ ERROR: variable does not need to be mutable
-    let (mut a, b) = (1, 2); //[lexical]~ ERROR: variable does not need to be mutable
-                             //[nll]~^ ERROR: variable does not need to be mutable
-    let mut a; //[lexical]~ ERROR: variable does not need to be mutable
-               //[nll]~^ ERROR: variable does not need to be mutable
+    let mut a = 3; //~ ERROR: variable does not need to be mutable
+
+    let mut a = 2; //~ ERROR: variable does not need to be mutable
+
+    let mut b = 3; //~ ERROR: variable does not need to be mutable
+
+    let mut a = vec![3]; //~ ERROR: variable does not need to be mutable
+
+    let (mut a, b) = (1, 2); //~ ERROR: variable does not need to be mutable
+
+    let mut a; //~ ERROR: variable does not need to be mutable
+
     a = 3;
 
-    let mut b; //[lexical]~ ERROR: variable does not need to be mutable
-               //[nll]~^ ERROR: variable does not need to be mutable
+    let mut b; //~ ERROR: variable does not need to be mutable
+
     if true {
         b = 3;
     } else {
@@ -44,45 +44,45 @@ fn main() {
     }
 
     match 30 {
-        mut x => {} //[lexical]~ ERROR: variable does not need to be mutable
-                    //[nll]~^ ERROR: variable does not need to be mutable
+        mut x => {} //~ ERROR: variable does not need to be mutable
+
     }
     match (30, 2) {
-      (mut x, 1) | //[lexical]~ ERROR: variable does not need to be mutable
-                   //[nll]~^ ERROR: variable does not need to be mutable
+      (mut x, 1) | //~ ERROR: variable does not need to be mutable
+
       (mut x, 2) |
       (mut x, 3) => {
       }
       _ => {}
     }
 
-    let x = |mut y: isize| 10; //[lexical]~ ERROR: variable does not need to be mutable
-                               //[nll]~^ ERROR: variable does not need to be mutable
-    fn what(mut foo: isize) {} //[lexical]~ ERROR: variable does not need to be mutable
-                               //[nll]~^ ERROR: variable does not need to be mutable
+    let x = |mut y: isize| 10; //~ ERROR: variable does not need to be mutable
+
+    fn what(mut foo: isize) {} //~ ERROR: variable does not need to be mutable
+
+
+    let mut a = &mut 5; //~ ERROR: variable does not need to be mutable
 
-    let mut a = &mut 5; //[lexical]~ ERROR: variable does not need to be mutable
-                        //[nll]~^ ERROR: variable does not need to be mutable
     *a = 4;
 
     let mut a = 5;
-    let mut b = (&mut a,); //[lexical]~ ERROR: variable does not need to be mutable
-    *b.0 = 4;              //[nll]~^ ERROR: variable does not need to be mutable
+    let mut b = (&mut a,); //~ ERROR: variable does not need to be mutable
+    *b.0 = 4;
+
+    let mut x = &mut 1; //~ ERROR: variable does not need to be mutable
 
-    let mut x = &mut 1; //[lexical]~ ERROR: variable does not need to be mutable
-                        //[nll]~^ ERROR: variable does not need to be mutable
     let mut f = || {
       *x += 1;
     };
     f();
 
     fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
-        &mut arg[..] //[lexical]~^ ERROR: variable does not need to be mutable
-                     //[nll]~^^ ERROR: variable does not need to be mutable
+        &mut arg[..] //~^ ERROR: variable does not need to be mutable
+
     }
 
-    let mut v : &mut Vec<()> = &mut vec![]; //[lexical]~ ERROR: variable does not need to be mutable
-                                            //[nll]~^ ERROR: variable does not need to be mutable
+    let mut v : &mut Vec<()> = &mut vec![]; //~ ERROR: variable does not need to be mutable
+
     v.push(());
 
     // positive cases
@@ -140,6 +140,6 @@ fn foo(mut a: isize) {
 fn bar() {
     #[allow(unused_mut)]
     let mut a = 3;
-    let mut b = vec![2]; //[lexical]~ ERROR: variable does not need to be mutable
-                         //[nll]~^ ERROR: variable does not need to be mutable
+    let mut b = vec![2]; //~ ERROR: variable does not need to be mutable
+
 }
diff --git a/src/test/ui/lint/lint-unused-mut-variables.stderr b/src/test/ui/lint/lint-unused-mut-variables.stderr
new file mode 100644 (file)
index 0000000..60e8400
--- /dev/null
@@ -0,0 +1,150 @@
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:59:14
+   |
+LL |     let x = |mut y: isize| 10; //~ ERROR: variable does not need to be mutable
+   |              ----^
+   |              |
+   |              help: remove this `mut`
+   |
+note: lint level defined here
+  --> $DIR/lint-unused-mut-variables.rs:19:9
+   |
+LL | #![deny(unused_mut)]
+   |         ^^^^^^^^^^
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:24:9
+   |
+LL |     let mut a = 3; //~ ERROR: variable does not need to be mutable
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:26:9
+   |
+LL |     let mut a = 2; //~ ERROR: variable does not need to be mutable
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:28:9
+   |
+LL |     let mut b = 3; //~ ERROR: variable does not need to be mutable
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:30:9
+   |
+LL |     let mut a = vec![3]; //~ ERROR: variable does not need to be mutable
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:32:10
+   |
+LL |     let (mut a, b) = (1, 2); //~ ERROR: variable does not need to be mutable
+   |          ----^
+   |          |
+   |          help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:34:9
+   |
+LL |     let mut a; //~ ERROR: variable does not need to be mutable
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:38:9
+   |
+LL |     let mut b; //~ ERROR: variable does not need to be mutable
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:47:9
+   |
+LL |         mut x => {} //~ ERROR: variable does not need to be mutable
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:51:8
+   |
+LL |       (mut x, 1) | //~ ERROR: variable does not need to be mutable
+   |        ----^
+   |        |
+   |        help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:64:9
+   |
+LL |     let mut a = &mut 5; //~ ERROR: variable does not need to be mutable
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:69:9
+   |
+LL |     let mut b = (&mut a,); //~ ERROR: variable does not need to be mutable
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:72:9
+   |
+LL |     let mut x = &mut 1; //~ ERROR: variable does not need to be mutable
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:84:9
+   |
+LL |     let mut v : &mut Vec<()> = &mut vec![]; //~ ERROR: variable does not need to be mutable
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:61:13
+   |
+LL |     fn what(mut foo: isize) {} //~ ERROR: variable does not need to be mutable
+   |             ----^^^
+   |             |
+   |             help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:79:20
+   |
+LL |     fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
+   |                    ----^^^
+   |                    |
+   |                    help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:143:9
+   |
+LL |     let mut b = vec![2]; //~ ERROR: variable does not need to be mutable
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+   |
+note: lint level defined here
+  --> $DIR/lint-unused-mut-variables.rs:139:8
+   |
+LL | #[deny(unused_mut)]
+   |        ^^^^^^^^^^
+
+error: aborting due to 17 previous errors
+
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() {}
 
diff --git a/src/test/ui/traits/trait-alias-object.rs b/src/test/ui/traits/trait-alias-object.rs
new file mode 100644 (file)
index 0000000..3adcd84
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(trait_alias)]
+
+trait EqAlias = Eq;
+trait IteratorAlias = Iterator;
+
+fn main() {
+    let _: &dyn EqAlias = &123;
+    let _: &dyn IteratorAlias = &vec![123].into_iter();
+}
diff --git a/src/test/ui/traits/trait-alias-object.stderr b/src/test/ui/traits/trait-alias-object.stderr
new file mode 100644 (file)
index 0000000..6b7b322
--- /dev/null
@@ -0,0 +1,18 @@
+error[E0038]: the trait `EqAlias` cannot be made into an object
+  --> $DIR/trait-alias-object.rs:17:13
+   |
+LL |     let _: &dyn EqAlias = &123;
+   |             ^^^^^^^^^^^ the trait `EqAlias` cannot be made into an object
+   |
+   = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses
+
+error[E0191]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified
+  --> $DIR/trait-alias-object.rs:18:13
+   |
+LL |     let _: &dyn IteratorAlias = &vec![123].into_iter();
+   |             ^^^^^^^^^^^^^^^^^ missing associated type `Item` value
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0038, E0191.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/src/test/ui/traits/trait-alias-objects.rs b/src/test/ui/traits/trait-alias-objects.rs
deleted file mode 100644 (file)
index 3adcd84..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(trait_alias)]
-
-trait EqAlias = Eq;
-trait IteratorAlias = Iterator;
-
-fn main() {
-    let _: &dyn EqAlias = &123;
-    let _: &dyn IteratorAlias = &vec![123].into_iter();
-}
diff --git a/src/test/ui/traits/trait-alias-objects.stderr b/src/test/ui/traits/trait-alias-objects.stderr
deleted file mode 100644 (file)
index 8f9681e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-error[E0038]: the trait `EqAlias` cannot be made into an object
-  --> $DIR/trait-alias-objects.rs:17:13
-   |
-LL |     let _: &dyn EqAlias = &123;
-   |             ^^^^^^^^^^^ the trait `EqAlias` cannot be made into an object
-   |
-   = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses
-
-error[E0191]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified
-  --> $DIR/trait-alias-objects.rs:18:13
-   |
-LL |     let _: &dyn IteratorAlias = &vec![123].into_iter();
-   |             ^^^^^^^^^^^^^^^^^ missing associated type `Item` value
-
-error: aborting due to 2 previous errors
-
-Some errors occurred: E0038, E0191.
-For more information about an error, try `rustc --explain E0038`.
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']