]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #54362 - tromey:travis-gdb-batch-mode, r=nikomatsakis
authorkennytm <kennytm@gmail.com>
Thu, 20 Sep 2018 13:36:35 +0000 (21:36 +0800)
committerkennytm <kennytm@gmail.com>
Thu, 20 Sep 2018 15:28:05 +0000 (23:28 +0800)
Pass --batch to gdb

In one of my travis builds, I was surprised to find that the gdb
pager was in use and caused travis to time out.  Adding `--batch`
to the gdb invocation will disable the pager.  Note that the
`-ex q` is retained, to make sure gdb exits with status 0, just in
case `set -e` is in effect somehow.

63 files changed:
src/Cargo.lock
src/doc/book
src/libcore/time.rs
src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs
src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs
src/librustc/middle/liveness.rs
src/librustc/session/mod.rs
src/librustc/traits/auto_trait.rs
src/librustc/traits/codegen/mod.rs
src/librustc/traits/coherence.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/fulfill.rs
src/librustc/traits/mod.rs
src/librustc/traits/object_safety.rs
src/librustc/traits/on_unimplemented.rs
src/librustc/traits/project.rs
src/librustc/traits/query/dropck_outlives.rs
src/librustc/traits/query/normalize.rs
src/librustc/traits/select.rs
src/librustc/traits/specialize/mod.rs
src/librustc/traits/specialize/specialization_graph.rs
src/librustc/traits/structural_impls.rs
src/librustc/traits/util.rs
src/librustc/ty/trait_def.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_codegen_llvm/back/linker.rs
src/librustc_codegen_llvm/debuginfo/metadata.rs
src/librustc_codegen_llvm/llvm/ffi.rs
src/librustc_errors/diagnostic.rs
src/librustc_errors/diagnostic_builder.rs
src/librustc_metadata/locator.rs
src/librustc_mir/borrow_check/error_reporting.rs
src/librustc_mir/borrow_check/move_errors.rs
src/librustc_mir/borrow_check/mutability_errors.rs
src/librustc_mir/dataflow/move_paths/mod.rs
src/librustc_mir/interpret/place.rs
src/librustc_passes/ast_validation.rs
src/librustc_passes/loops.rs
src/librustc_resolve/lib.rs
src/librustc_target/spec/aarch64_pc_windows_msvc.rs
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/demand.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/op.rs
src/librustdoc/test.rs
src/libstd/sys/wasm/cmath.rs
src/libstd/thread/mod.rs
src/libsyntax/config.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/parse/parser.rs
src/libsyntax_ext/format.rs
src/llvm
src/rustllvm/llvm-rebuild-trigger
src/test/ui/issues/issue-53712.rs [new file with mode: 0644]
src/test/ui/issues/issue-53712.stderr [new file with mode: 0644]
src/test/ui/nll/issue-52669.rs [new file with mode: 0644]
src/test/ui/nll/issue-52669.stderr [new file with mode: 0644]
src/test/ui/nll/move-subpaths-moves-root.rs [new file with mode: 0644]
src/test/ui/nll/move-subpaths-moves-root.stderr [new file with mode: 0644]

index b7d36929f54fb5e79c3c0bd65fdd6a6b18de3916..5ac838cadc2a4bdfe501bb8e18cf845ca28d5eae 100644 (file)
@@ -20,7 +20,7 @@ name = "alloc_jemalloc"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.0.0",
  "core 0.0.0",
  "libc 0.0.0",
@@ -112,7 +112,7 @@ name = "backtrace-sys"
 version = "0.1.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -131,7 +131,7 @@ name = "bootstrap"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -198,7 +198,7 @@ dependencies = [
  "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "libgit2-sys 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libgit2-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -240,7 +240,7 @@ version = "0.1.0"
 
 [[package]]
 name = "cc"
-version = "1.0.22"
+version = "1.0.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -356,7 +356,7 @@ name = "cmake"
 version = "0.1.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -387,7 +387,7 @@ dependencies = [
 name = "compiler_builtins"
 version = "0.0.0"
 dependencies = [
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -549,7 +549,7 @@ name = "curl"
 version = "0.4.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "curl-sys 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl-sys 0.4.10 (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)",
@@ -561,12 +561,12 @@ dependencies = [
 
 [[package]]
 name = "curl-sys"
-version = "0.4.8"
+version = "0.4.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "libz-sys 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libz-sys 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -825,7 +825,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "libgit2-sys 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libgit2-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.35 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1073,27 +1073,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "libgit2-sys"
-version = "0.7.7"
+version = "0.7.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)",
- "curl-sys 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl-sys 0.4.10 (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.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "libz-sys 1.0.20 (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.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libssh2-sys"
-version = "0.2.10"
+version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "libz-sys 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libz-sys 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1101,10 +1100,10 @@ dependencies = [
 
 [[package]]
 name = "libz-sys"
-version = "1.0.20"
+version = "1.0.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1152,7 +1151,7 @@ name = "lzma-sys"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1256,7 +1255,7 @@ name = "miniz-sys"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1365,7 +1364,7 @@ name = "openssl-src"
 version = "110.0.7+1.1.0i"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1373,7 +1372,7 @@ name = "openssl-sys"
 version = "0.9.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-src 110.0.7+1.1.0i (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1580,7 +1579,7 @@ dependencies = [
 name = "profiler_builtins"
 version = "0.0.0"
 dependencies = [
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.0.0",
  "core 0.0.0",
 ]
@@ -2094,7 +2093,7 @@ dependencies = [
 name = "rustc_codegen_llvm"
 version = "0.0.0"
 dependencies = [
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2228,7 +2227,7 @@ name = "rustc_llvm"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2631,7 +2630,7 @@ dependencies = [
  "alloc_jemalloc 0.0.0",
  "alloc_system 0.0.0",
  "build_helper 0.1.0",
- "cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.0.0",
  "core 0.0.0",
  "libc 0.0.0",
@@ -3145,7 +3144,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32"
 "checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
 "checksum cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6809b327f87369e6f3651efd2c5a96c49847a3ed2559477ecba79014751ee1"
-"checksum cc 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "4a6007c146fdd28d4512a794b07ffe9d8e89e6bf86e2e0c4ddff2e1fb54a0007"
+"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
 "checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
 "checksum chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "25ce2f28f55ed544a2a3756b7acf41dd7d6f27acffb2086439950925506af7d0"
 "checksum chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "295635afd6853aa9f20baeb7f0204862440c0fe994c5a253d5f479dac41d047e"
@@ -3169,7 +3168,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "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.14 (registry+https://github.com/rust-lang/crates.io-index)" = "444c2f9e71458b34e75471ed8d756947a0bb920b8b8b9bfc56dfcc4fc6819a13"
-"checksum curl-sys 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "981bd902fcd8b8b999cf71b81447e27d66c3493a7f62f1372866fd32986c0c82"
+"checksum curl-sys 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2edeedbbd9c7cdccb14bfb5dfbcc108901f99d3411eb5bab3758789377c5bec4"
 "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"
@@ -3224,9 +3223,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7"
 "checksum lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d33a48d0365c96081958cc663eef834975cb1e8d8bea3378513fc72bdbf11e50"
 "checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
-"checksum libgit2-sys 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6ab62b46003ba97701554631fa570d9f7e7947e2480ae3d941e555a54a2c0f05"
-"checksum libssh2-sys 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "10dbc0957a27626444f5a3f523e6b97a70c3d702999bf1c7161cfbe7a25a9368"
-"checksum libz-sys 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "f5f9aba969b3c45fe9c94bec65895868a9ceca9a600699f4054b75747a19c7c6"
+"checksum libgit2-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "44b1900be992dd5698bd3bb422921e336306d413e2860e6ba3b50e62e6219c4c"
+"checksum libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "126a1f4078368b163bfdee65fbab072af08a1b374a5551b21e87ade27b1fbf9d"
+"checksum libz-sys 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "65ff614643d7635dfa2151913d95c4ee90ee1fe15d9e0980f4dcb1a7e5837c18"
 "checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54"
 "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
 "checksum log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cba860f648db8e6f269df990180c2217f333472b4a6e901e97446858487971e2"
index cff0930664b688f1dd22aefb3d16944eb4cdbfd5..fa91738b66367b6f70b078251868a071f1991ace 160000 (submodule)
@@ -1 +1 @@
-Subproject commit cff0930664b688f1dd22aefb3d16944eb4cdbfd5
+Subproject commit fa91738b66367b6f70b078251868a071f1991ace
index b58920224eb702217dd6009740fe5c11b0ea0ae7..1aed5a7b426fdd977f29f793ccc97e55a89fabd0 100644 (file)
@@ -21,7 +21,7 @@
 //! assert_eq!(Duration::new(5, 0), Duration::from_secs(5));
 //! ```
 
-use fmt;
+use {fmt, u64};
 use iter::Sum;
 use ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign};
 
@@ -30,6 +30,7 @@
 const NANOS_PER_MICRO: u32 = 1_000;
 const MILLIS_PER_SEC: u64 = 1_000;
 const MICROS_PER_SEC: u64 = 1_000_000;
+const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64;
 
 /// A `Duration` type to represent a span of time, typically used for system
 /// timeouts.
@@ -458,6 +459,115 @@ pub fn checked_div(self, rhs: u32) -> Option<Duration> {
             None
         }
     }
+
+    /// Returns the number of seconds contained by this `Duration` as `f64`.
+    ///
+    /// The returned value does include the fractional (nanosecond) part of the duration.
+    ///
+    /// # Examples
+    /// ```
+    /// #![feature(duration_float)]
+    /// use std::time::Duration;
+    ///
+    /// let dur = Duration::new(2, 700_000_000);
+    /// assert_eq!(dur.as_float_secs(), 2.7);
+    /// ```
+    #[unstable(feature = "duration_float", issue = "54361")]
+    #[inline]
+    pub fn as_float_secs(&self) -> f64 {
+        (self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64)
+    }
+
+    /// Creates a new `Duration` from the specified number of seconds.
+    ///
+    /// # Panics
+    /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`.
+    ///
+    /// # Examples
+    /// ```
+    /// #![feature(duration_float)]
+    /// use std::time::Duration;
+    ///
+    /// let dur = Duration::from_float_secs(2.7);
+    /// assert_eq!(dur, Duration::new(2, 700_000_000));
+    /// ```
+    #[unstable(feature = "duration_float", issue = "54361")]
+    #[inline]
+    pub fn from_float_secs(secs: f64) -> Duration {
+        let nanos =  secs * (NANOS_PER_SEC as f64);
+        if !nanos.is_finite() {
+            panic!("got non-finite value when converting float to duration");
+        }
+        if nanos >= MAX_NANOS_F64 {
+            panic!("overflow when converting float to duration");
+        }
+        if nanos < 0.0 {
+            panic!("underflow when converting float to duration");
+        }
+        let nanos =  nanos as u128;
+        Duration {
+            secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
+            nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
+        }
+    }
+
+    /// Multiply `Duration` by `f64`.
+    ///
+    /// # Panics
+    /// This method will panic if result is not finite, negative or overflows `Duration`.
+    ///
+    /// # Examples
+    /// ```
+    /// #![feature(duration_float)]
+    /// use std::time::Duration;
+    ///
+    /// let dur = Duration::new(2, 700_000_000);
+    /// assert_eq!(dur.mul_f64(3.14), Duration::new(8, 478_000_000));
+    /// assert_eq!(dur.mul_f64(3.14e5), Duration::new(847_800, 0));
+    /// ```
+    #[unstable(feature = "duration_float", issue = "54361")]
+    #[inline]
+    pub fn mul_f64(self, rhs: f64) -> Duration {
+        Duration::from_float_secs(rhs * self.as_float_secs())
+    }
+
+    /// Divide `Duration` by `f64`.
+    ///
+    /// # Panics
+    /// This method will panic if result is not finite, negative or overflows `Duration`.
+    ///
+    /// # Examples
+    /// ```
+    /// #![feature(duration_float)]
+    /// use std::time::Duration;
+    ///
+    /// let dur = Duration::new(2, 700_000_000);
+    /// assert_eq!(dur.div_f64(3.14), Duration::new(0, 859_872_611));
+    /// // note that truncation is used, not rounding
+    /// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_598));
+    /// ```
+    #[unstable(feature = "duration_float", issue = "54361")]
+    #[inline]
+    pub fn div_f64(self, rhs: f64) -> Duration {
+        Duration::from_float_secs(self.as_float_secs() / rhs)
+    }
+
+    /// Divide `Duration` by `Duration` and return `f64`.
+    ///
+    /// # Examples
+    /// ```
+    /// #![feature(duration_float)]
+    /// use std::time::Duration;
+    ///
+    /// let dur1 = Duration::new(2, 700_000_000);
+    /// let dur2 = Duration::new(5, 400_000_000);
+    /// assert_eq!(dur1.div_duration(dur2), 0.5);
+    /// ```
+    #[unstable(feature = "duration_float", issue = "54361")]
+    #[inline]
+    pub fn div_duration(self, rhs: Duration) -> f64 {
+        self.as_float_secs() / rhs.as_float_secs()
+    }
 }
 
 #[stable(feature = "duration", since = "1.3.0")]
@@ -501,6 +611,15 @@ fn mul(self, rhs: u32) -> Duration {
     }
 }
 
+#[stable(feature = "symmetric_u32_duration_mul", since = "1.31.0")]
+impl Mul<Duration> for u32 {
+    type Output = Duration;
+
+    fn mul(self, rhs: Duration) -> Duration {
+        rhs * self
+    }
+}
+
 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
 impl MulAssign<u32> for Duration {
     fn mul_assign(&mut self, rhs: u32) {
index 0eb634ea2cc8e4f3f11aa5ed74e63b3e47e427c5..6ff008919e52cab9a627165020d7a1b77ec92b22 100644 (file)
@@ -13,6 +13,7 @@
 use infer::error_reporting::nice_region_error::NiceRegionError;
 use ty;
 use util::common::ErrorReported;
+use errors::Applicability;
 
 impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
     /// When given a `ConcreteFailure` for a function with arguments containing a named region and
@@ -111,13 +112,14 @@ pub(super) fn try_report_named_anon_conflict(&self) -> Option<ErrorReported> {
             E0621,
             "explicit lifetime required in {}",
             error_var
-        ).span_suggestion(
+        ).span_suggestion_with_applicability(
             new_ty_span,
             &format!("add explicit lifetime `{}` to {}", named, span_label_var),
-            new_ty.to_string()
+            new_ty.to_string(),
+            Applicability::Unspecified,
         )
-            .span_label(span, format!("lifetime `{}` required", named))
-            .emit();
+        .span_label(span, format!("lifetime `{}` required", named))
+        .emit();
         return Some(ErrorReported);
     }
 
index 29ba23b58bc0ce8418d9f39a13f376bb7cff6599..3393eb65089c05a55e3b6cf337ff6cd98b0860c0 100644 (file)
@@ -14,6 +14,7 @@
 use infer::lexical_region_resolve::RegionResolutionError;
 use ty::{BoundRegion, FreeRegion, RegionKind};
 use util::common::ErrorReported;
+use errors::Applicability;
 
 impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
     /// Print the error message for lifetime errors when the return type is a static impl Trait.
@@ -61,7 +62,7 @@ pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
                             _ => "'_".to_owned(),
                         };
                         if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(return_sp) {
-                            err.span_suggestion(
+                            err.span_suggestion_with_applicability(
                                 return_sp,
                                 &format!(
                                     "you can add a constraint to the return type to make it last \
@@ -69,6 +70,7 @@ pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
                                     lifetime,
                                 ),
                                 format!("{} + {}", snippet, lifetime_name),
+                                Applicability::Unspecified,
                             );
                         }
                         err.emit();
index c34a0a654e6a9f7c1964b39b3fa0c4e411391010..13847fb48cee961e0d96e58006fee93c582dfc8d 100644 (file)
 //! methods.  It effectively does a reverse walk of the AST; whenever we
 //! reach a loop node, we iterate until a fixed point is reached.
 //!
-//! ## The `Users` struct
+//! ## The `users_*` fields
 //!
 //! At each live node `N`, we track three pieces of information for each
-//! variable `V` (these are encapsulated in the `Users` struct):
+//! variable `V` (these are in the `users_*` fields):
 //!
 //! - `reader`: the `LiveNode` ID of some node which will read the value
 //!    that `V` holds on entry to `N`.  Formally: a node `M` such
@@ -536,21 +536,6 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
 // Actually we compute just a bit more than just liveness, but we use
 // the same basic propagation framework in all cases.
 
-#[derive(Clone, Copy)]
-struct Users {
-    reader: LiveNode,
-    writer: LiveNode,
-    used: bool
-}
-
-fn invalid_users() -> Users {
-    Users {
-        reader: invalid_node(),
-        writer: invalid_node(),
-        used: false
-    }
-}
-
 #[derive(Copy, Clone)]
 struct Specials {
     exit_ln: LiveNode,
@@ -567,7 +552,14 @@ struct Liveness<'a, 'tcx: 'a> {
     tables: &'a ty::TypeckTables<'tcx>,
     s: Specials,
     successors: Vec<LiveNode>,
-    users: Vec<Users>,
+
+    // We used to have a single `users: Vec<Users>` field here, where `Users`
+    // had `reader`, `writer` and `used` fields. But the number of users can
+    // get very large, and it's more compact to store the data in three
+    // separate `Vec`s so that no space is wasted for padding.
+    users_reader: Vec<LiveNode>,
+    users_writer: Vec<LiveNode>,
+    users_used: Vec<bool>,
 
     // mappings from loop node ID to LiveNode
     // ("break" label should map to loop node ID,
@@ -592,13 +584,16 @@ fn new(ir: &'a mut IrMaps<'a, 'tcx>, body: hir::BodyId) -> Liveness<'a, 'tcx> {
 
         let num_live_nodes = ir.num_live_nodes;
         let num_vars = ir.num_vars;
+        let num_users = num_live_nodes * num_vars;
 
         Liveness {
             ir,
             tables,
             s: specials,
             successors: vec![invalid_node(); num_live_nodes],
-            users: vec![invalid_users(); num_live_nodes * num_vars],
+            users_reader: vec![invalid_node(); num_users],
+            users_writer: vec![invalid_node(); num_users],
+            users_used: vec![false; num_users],
             break_ln: NodeMap(),
             cont_ln: NodeMap(),
         }
@@ -665,7 +660,7 @@ fn idx(&self, ln: LiveNode, var: Variable) -> usize {
     fn live_on_entry(&self, ln: LiveNode, var: Variable)
                       -> Option<LiveNodeKind> {
         assert!(ln.is_valid());
-        let reader = self.users[self.idx(ln, var)].reader;
+        let reader = self.users_reader[self.idx(ln, var)];
         if reader.is_valid() {Some(self.ir.lnk(reader))} else {None}
     }
 
@@ -680,13 +675,13 @@ fn live_on_exit(&self, ln: LiveNode, var: Variable)
 
     fn used_on_entry(&self, ln: LiveNode, var: Variable) -> bool {
         assert!(ln.is_valid());
-        self.users[self.idx(ln, var)].used
+        self.users_used[self.idx(ln, var)]
     }
 
     fn assigned_on_entry(&self, ln: LiveNode, var: Variable)
                          -> Option<LiveNodeKind> {
         assert!(ln.is_valid());
-        let writer = self.users[self.idx(ln, var)].writer;
+        let writer = self.users_writer[self.idx(ln, var)];
         if writer.is_valid() {Some(self.ir.lnk(writer))} else {None}
     }
 
@@ -730,9 +725,9 @@ fn ln_str(&self, ln: LiveNode) -> String {
         {
             let wr = &mut wr as &mut dyn Write;
             write!(wr, "[ln({:?}) of kind {:?} reads", ln.get(), self.ir.lnk(ln));
-            self.write_vars(wr, ln, |idx| self.users[idx].reader);
+            self.write_vars(wr, ln, |idx| self.users_reader[idx]);
             write!(wr, "  writes");
-            self.write_vars(wr, ln, |idx| self.users[idx].writer);
+            self.write_vars(wr, ln, |idx| self.users_writer[idx]);
             write!(wr, "  precedes {:?}]", self.successors[ln.get()]);
         }
         String::from_utf8(wr).unwrap()
@@ -747,7 +742,9 @@ fn init_empty(&mut self, ln: LiveNode, succ_ln: LiveNode) {
         // only grow during iterations.
         //
         // self.indices(ln) { |idx|
-        //     self.users[idx] = invalid_users();
+        //     self.users_reader[idx] = invalid_node();
+        //     self.users_writer[idx] = invalid_node();
+        //     self.users_used[idx] = false;
         // }
     }
 
@@ -756,7 +753,9 @@ fn init_from_succ(&mut self, ln: LiveNode, succ_ln: LiveNode) {
         self.successors[ln.get()] = succ_ln;
 
         self.indices2(ln, succ_ln, |this, idx, succ_idx| {
-            this.users[idx] = this.users[succ_idx]
+            this.users_reader[idx] = this.users_reader[succ_idx];
+            this.users_writer[idx] = this.users_writer[succ_idx];
+            this.users_used[idx] = this.users_used[succ_idx];
         });
         debug!("init_from_succ(ln={}, succ={})",
                self.ln_str(ln), self.ln_str(succ_ln));
@@ -771,12 +770,10 @@ fn merge_from_succ(&mut self,
 
         let mut changed = false;
         self.indices2(ln, succ_ln, |this, idx, succ_idx| {
-            changed |= copy_if_invalid(this.users[succ_idx].reader,
-                                       &mut this.users[idx].reader);
-            changed |= copy_if_invalid(this.users[succ_idx].writer,
-                                       &mut this.users[idx].writer);
-            if this.users[succ_idx].used && !this.users[idx].used {
-                this.users[idx].used = true;
+            changed |= copy_if_invalid(this.users_reader[succ_idx], &mut this.users_reader[idx]);
+            changed |= copy_if_invalid(this.users_writer[succ_idx], &mut this.users_writer[idx]);
+            if this.users_used[succ_idx] && !this.users_used[idx] {
+                this.users_used[idx] = true;
                 changed = true;
             }
         });
@@ -800,8 +797,8 @@ fn copy_if_invalid(src: LiveNode, dst: &mut LiveNode) -> bool {
     // this) so we just clear out all the data.
     fn define(&mut self, writer: LiveNode, var: Variable) {
         let idx = self.idx(writer, var);
-        self.users[idx].reader = invalid_node();
-        self.users[idx].writer = invalid_node();
+        self.users_reader[idx] = invalid_node();
+        self.users_writer[idx] = invalid_node();
 
         debug!("{:?} defines {:?} (idx={}): {}", writer, var,
                idx, self.ln_str(writer));
@@ -813,21 +810,20 @@ fn acc(&mut self, ln: LiveNode, var: Variable, acc: u32) {
                ln, acc, var, self.ln_str(ln));
 
         let idx = self.idx(ln, var);
-        let user = &mut self.users[idx];
 
         if (acc & ACC_WRITE) != 0 {
-            user.reader = invalid_node();
-            user.writer = ln;
+            self.users_reader[idx] = invalid_node();
+            self.users_writer[idx] = ln;
         }
 
         // Important: if we both read/write, must do read second
         // or else the write will override.
         if (acc & ACC_READ) != 0 {
-            user.reader = ln;
+            self.users_reader[idx] = ln;
         }
 
         if (acc & ACC_USE) != 0 {
-            user.used = true;
+            self.users_used[idx] = true;
         }
     }
 
index 52e1ab477038d9b1906991f8dd285be0d7b7a9ab..7bf0d8ecec854264f4ee51fccb74b701c37b2897 100644 (file)
@@ -28,7 +28,7 @@
 use rustc_data_structures::sync::{self, Lrc, Lock, LockCell, OneThread, Once, RwLock};
 
 use syntax::ast::NodeId;
-use errors::{self, DiagnosticBuilder, DiagnosticId};
+use errors::{self, DiagnosticBuilder, DiagnosticId, Applicability};
 use errors::emitter::{Emitter, EmitterWriter};
 use syntax::edition::Edition;
 use syntax::json::JsonEmitter;
@@ -431,8 +431,13 @@ fn diag_once<'a, 'b>(
                     diag_builder.span_note(span, message);
                 }
                 DiagnosticBuilderMethod::SpanSuggestion(suggestion) => {
-                    let span = span_maybe.expect("span_suggestion needs a span");
-                    diag_builder.span_suggestion(span, message, suggestion);
+                    let span = span_maybe.expect("span_suggestion_* needs a span");
+                    diag_builder.span_suggestion_with_applicability(
+                        span,
+                        message,
+                        suggestion,
+                        Applicability::Unspecified,
+                    );
                 }
             }
         }
index ed95aa73078a92f5282e1137fd8a0b24d21fa969..4bed3c5935cd7829ec7111c6a5516cc9e608d018 100644 (file)
@@ -112,6 +112,7 @@ pub fn find_auto_trait_generics<A>(
                 orig_params,
                 trait_pred.to_poly_trait_predicate(),
             ));
+
             match result {
                 Ok(Some(Vtable::VtableImpl(_))) => {
                     debug!(
@@ -119,10 +120,10 @@ pub fn find_auto_trait_generics<A>(
                          manual impl found, bailing out",
                         did, trait_did, generics
                     );
-                    return true;
+                    true
                 }
-                _ => return false,
-            };
+                _ => false
+            }
         });
 
         // If an explicit impl exists, it always takes priority over an auto impl
@@ -426,6 +427,7 @@ fn add_user_pred<'c>(&self, user_computed_preds: &mut FxHashSet<ty::Predicate<'c
                     if new_trait.def_id() == old_trait.def_id() {
                         let new_substs = new_trait.skip_binder().trait_ref.substs;
                         let old_substs = old_trait.skip_binder().trait_ref.substs;
+
                         if !new_substs.types().eq(old_substs.types()) {
                             // We can't compare lifetimes if the types are different,
                             // so skip checking old_pred
@@ -489,12 +491,12 @@ pub fn region_name(&self, region: Region) -> Option<String> {
 
     pub fn get_lifetime(&self, region: Region, names_map: &FxHashMap<String, String>) -> String {
         self.region_name(region)
-            .map(|name| {
-                names_map.get(&name).unwrap_or_else(|| {
+            .map(|name|
+                names_map.get(&name).unwrap_or_else(||
                     panic!("Missing lifetime with name {:?} for {:?}", name, region)
-                })
-            })
-            .unwrap_or(&"'static".to_string())
+                )
+            )
+            .unwrap_or(&"'static".to_owned())
             .clone()
     }
 
index cf404202ac120830ff9da5309a4b4280136a3700..4e88150a18acc65b60325eefdf85238450b5cbb7 100644 (file)
@@ -39,7 +39,7 @@ pub fn codegen_fulfill_obligation<'a, 'tcx>(ty: TyCtxt<'a, 'tcx, 'tcx>,
     let trait_ref = ty.erase_regions(&trait_ref);
 
     debug!("codegen_fulfill_obligation(trait_ref={:?}, def_id={:?})",
-            (param_env, trait_ref), trait_ref.def_id());
+        (param_env, trait_ref), trait_ref.def_id());
 
     // Do the initial selection for the obligation. This yields the
     // shallow result we are looking for -- that is, what specific impl.
@@ -48,8 +48,8 @@ pub fn codegen_fulfill_obligation<'a, 'tcx>(ty: TyCtxt<'a, 'tcx, 'tcx>,
 
         let obligation_cause = ObligationCause::dummy();
         let obligation = Obligation::new(obligation_cause,
-                                            param_env,
-                                            trait_ref.to_poly_trait_predicate());
+                                         param_env,
+                                         trait_ref.to_poly_trait_predicate());
 
         let selection = match selcx.select(&obligation) {
             Ok(Some(selection)) => selection,
@@ -61,12 +61,11 @@ pub fn codegen_fulfill_obligation<'a, 'tcx>(ty: TyCtxt<'a, 'tcx, 'tcx>,
                 // overflow bug, since I believe this is the only case
                 // where ambiguity can result.
                 bug!("Encountered ambiguity selecting `{:?}` during codegen, \
-                        presuming due to overflow",
-                        trait_ref)
+                      presuming due to overflow",
+                      trait_ref)
             }
             Err(e) => {
-                bug!("Encountered error `{:?}` selecting `{:?}` during codegen",
-                            e, trait_ref)
+                bug!("Encountered error `{:?}` selecting `{:?}` during codegen", e, trait_ref)
             }
         };
 
@@ -163,22 +162,16 @@ fn drain_fulfillment_cx_or_panic<T>(&self,
         // In principle, we only need to do this so long as `result`
         // contains unbound type parameters. It could be a slight
         // optimization to stop iterating early.
-        match fulfill_cx.select_all_or_error(self) {
-            Ok(()) => { }
-            Err(errors) => {
-                span_bug!(span, "Encountered errors `{:?}` resolving bounds after type-checking",
-                          errors);
-            }
+        if let Err(errors) = fulfill_cx.select_all_or_error(self) {
+            span_bug!(span, "Encountered errors `{:?}` resolving bounds after type-checking",
+                      errors);
         }
 
         let result = self.resolve_type_vars_if_possible(result);
         let result = self.tcx.erase_regions(&result);
 
-        match self.tcx.lift_to_global(&result) {
-            Some(result) => result,
-            None => {
-                span_bug!(span, "Uninferred types/regions in `{:?}`", result);
-            }
-        }
+        self.tcx.lift_to_global(&result).unwrap_or_else(||
+            span_bug!(span, "Uninferred types/regions in `{:?}`", result)
+        )
     }
 }
index b8dd2a12fb58d3129d2437bbb7091e98792c3e21..251743b0d3bb41a2477cad2f5d8bbbd9e9bee5b7 100644 (file)
@@ -115,9 +115,7 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
                             b_def_id: DefId)
                             -> Option<OverlapResult<'tcx>>
 {
-    debug!("overlap(a_def_id={:?}, b_def_id={:?})",
-           a_def_id,
-           b_def_id);
+    debug!("overlap(a_def_id={:?}, b_def_id={:?})", a_def_id, b_def_id);
 
     // For the purposes of this check, we don't bring any skolemized
     // types into scope; instead, we replace the generic types with
@@ -133,10 +131,9 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
 
     // Do `a` and `b` unify? If not, no overlap.
     let obligations = match selcx.infcx().at(&ObligationCause::dummy(), param_env)
-                                         .eq_impl_headers(&a_impl_header, &b_impl_header) {
-        Ok(InferOk { obligations, value: () }) => {
-            obligations
-        }
+                                         .eq_impl_headers(&a_impl_header, &b_impl_header)
+    {
+        Ok(InferOk { obligations, value: () }) => obligations,
         Err(_) => return None
     };
 
@@ -164,7 +161,7 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
         return None
     }
 
-    let impl_header =  selcx.infcx().resolve_type_vars_if_possible(&a_impl_header);
+    let impl_header = selcx.infcx().resolve_type_vars_if_possible(&a_impl_header);
     let intercrate_ambiguity_causes = selcx.take_intercrate_ambiguity_causes();
     debug!("overlap: intercrate_ambiguity_causes={:#?}", intercrate_ambiguity_causes);
     Some(OverlapResult { impl_header, intercrate_ambiguity_causes })
@@ -471,14 +468,12 @@ fn ty_is_local_constructor(ty: Ty, in_crate: InCrate) -> bool {
         ty::Foreign(did) => def_id_is_local(did, in_crate),
 
         ty::Dynamic(ref tt, ..) => {
-            tt.principal().map_or(false, |p| {
+            tt.principal().map_or(false, |p|
                 def_id_is_local(p.def_id(), in_crate)
-            })
+            )
         }
 
-        ty::Error => {
-            true
-        }
+        ty::Error => true,
 
         ty::Closure(..) |
         ty::Generator(..) |
index 466d472cca338a92734ff8ee93dcc121a4a23c02..6fb5acde72c49735d7280e8e9f39c8782c9a16f7 100644 (file)
@@ -34,6 +34,7 @@
 use infer::{self, InferCtxt};
 use infer::type_variable::TypeVariableOrigin;
 use std::fmt;
+use std::iter;
 use syntax::ast;
 use session::DiagnosticMessageId;
 use ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
@@ -58,7 +59,7 @@ struct ErrorDescriptor<'tcx> {
             index: Option<usize>, // None if this is an old error
         }
 
-        let mut error_map : FxHashMap<_, Vec<_>> =
+        let mut error_map: FxHashMap<_, Vec<_>> =
             self.reported_trait_errors.borrow().iter().map(|(&span, predicates)| {
                 (span, predicates.iter().map(|predicate| ErrorDescriptor {
                     predicate: predicate.clone(),
@@ -80,7 +81,7 @@ struct ErrorDescriptor<'tcx> {
 
         // We do this in 2 passes because we want to display errors in order, tho
         // maybe it *is* better to sort errors by span or something.
-        let mut is_suppressed: Vec<bool> = errors.iter().map(|_| false).collect();
+        let mut is_suppressed = vec![false; errors.len()];
         for (_, error_set) in error_map.iter() {
             // We want to suppress "duplicate" errors with the same span.
             for error in error_set {
@@ -349,7 +350,7 @@ fn on_unimplemented_note(
             _ => {
                 // this is a "direct", user-specified, rather than derived,
                 // obligation.
-                flags.push(("direct".to_string(), None));
+                flags.push(("direct".to_owned(), None));
             }
         }
 
@@ -361,24 +362,24 @@ fn on_unimplemented_note(
             // Currently I'm leaving it for what I need for `try`.
             if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) {
                 let method = self.tcx.item_name(item);
-                flags.push(("from_method".to_string(), None));
-                flags.push(("from_method".to_string(), Some(method.to_string())));
+                flags.push(("from_method".to_owned(), None));
+                flags.push(("from_method".to_owned(), Some(method.to_string())));
             }
         }
 
         if let Some(k) = obligation.cause.span.compiler_desugaring_kind() {
-            flags.push(("from_desugaring".to_string(), None));
-            flags.push(("from_desugaring".to_string(), Some(k.name().to_string())));
+            flags.push(("from_desugaring".to_owned(), None));
+            flags.push(("from_desugaring".to_owned(), Some(k.name().to_string())));
         }
         let generics = self.tcx.generics_of(def_id);
         let self_ty = trait_ref.self_ty();
         // This is also included through the generics list as `Self`,
         // but the parser won't allow you to use it
-        flags.push(("_Self".to_string(), Some(self_ty.to_string())));
+        flags.push(("_Self".to_owned(), Some(self_ty.to_string())));
         if let Some(def) = self_ty.ty_adt_def() {
             // We also want to be able to select self's original
             // signature with no type arguments resolved
-            flags.push(("_Self".to_string(), Some(self.tcx.type_of(def.did).to_string())));
+            flags.push(("_Self".to_owned(), Some(self.tcx.type_of(def.did).to_string())));
         }
 
         for param in generics.params.iter() {
@@ -393,7 +394,7 @@ fn on_unimplemented_note(
         }
 
         if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) {
-            flags.push(("crate_local".to_string(), None));
+            flags.push(("crate_local".to_owned(), None));
         }
 
         if let Ok(Some(command)) = OnUnimplementedDirective::of_item(
@@ -412,27 +413,26 @@ fn find_similar_impl_candidates(&self,
         let simp = fast_reject::simplify_type(self.tcx,
                                               trait_ref.skip_binder().self_ty(),
                                               true);
-        let mut impl_candidates = Vec::new();
+        let all_impls = self.tcx.all_impls(trait_ref.def_id());
 
         match simp {
-            Some(simp) => self.tcx.for_each_impl(trait_ref.def_id(), |def_id| {
+            Some(simp) => all_impls.iter().filter_map(|&def_id| {
                 let imp = self.tcx.impl_trait_ref(def_id).unwrap();
                 let imp_simp = fast_reject::simplify_type(self.tcx,
                                                           imp.self_ty(),
                                                           true);
                 if let Some(imp_simp) = imp_simp {
                     if simp != imp_simp {
-                        return;
+                        return None
                     }
                 }
-                impl_candidates.push(imp);
-            }),
-            None => self.tcx.for_each_impl(trait_ref.def_id(), |def_id| {
-                impl_candidates.push(
-                    self.tcx.impl_trait_ref(def_id).unwrap());
-            })
-        };
-        impl_candidates
+
+                Some(imp)
+            }).collect(),
+            None => all_impls.iter().map(|&def_id|
+                self.tcx.impl_trait_ref(def_id).unwrap()
+            ).collect()
+        }
     }
 
     fn report_similar_impl_candidates(&self,
@@ -603,10 +603,10 @@ pub fn report_selection_error(&self,
                             span,
                             E0277,
                             "{}",
-                            message.unwrap_or_else(|| {
+                            message.unwrap_or_else(||
                                 format!("the trait bound `{}` is not satisfied{}",
                                          trait_ref.to_predicate(), post_message)
-                            }));
+                            ));
 
                         let explanation =
                             if obligation.cause.code == ObligationCauseCode::MainFunctionType {
@@ -645,7 +645,7 @@ pub fn report_selection_error(&self,
                             //     "the type `T` can't be frobnicated"
                             // which is somewhat confusing.
                             err.help(&format!("consider adding a `where {}` bound",
-                                                trait_ref.to_predicate()));
+                                              trait_ref.to_predicate()));
                         } else if !have_alt_message {
                             // Can't show anything else useful, try to find similar impls.
                             let impl_candidates = self.find_similar_impl_candidates(trait_ref);
@@ -693,7 +693,7 @@ pub fn report_selection_error(&self,
                     ty::Predicate::RegionOutlives(ref predicate) => {
                         let predicate = self.resolve_type_vars_if_possible(predicate);
                         let err = self.region_outlives_predicate(&obligation.cause,
-                                                                    &predicate).err().unwrap();
+                                                                 &predicate).err().unwrap();
                         struct_span_err!(self.tcx.sess, span, E0279,
                             "the requirement `{}` is not satisfied (`{}`)",
                             predicate, err)
@@ -722,7 +722,7 @@ pub fn report_selection_error(&self,
                         let mut err = struct_span_err!(
                             self.tcx.sess, closure_span, E0525,
                             "expected a closure that implements the `{}` trait, \
-                                but this closure only implements `{}`",
+                             but this closure only implements `{}`",
                             kind,
                             found_kind);
 
@@ -779,40 +779,34 @@ pub fn report_selection_error(&self,
             OutputTypeParameterMismatch(ref found_trait_ref, ref expected_trait_ref, _) => {
                 let found_trait_ref = self.resolve_type_vars_if_possible(&*found_trait_ref);
                 let expected_trait_ref = self.resolve_type_vars_if_possible(&*expected_trait_ref);
+
                 if expected_trait_ref.self_ty().references_error() {
                     return;
                 }
+
                 let found_trait_ty = found_trait_ref.self_ty();
 
                 let found_did = match found_trait_ty.sty {
-                    ty::Closure(did, _) |
-                    ty::Foreign(did) |
-                    ty::FnDef(did, _) => Some(did),
+                    ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did),
                     ty::Adt(def, _) => Some(def.did),
                     _ => None,
                 };
-                let found_span = found_did.and_then(|did| {
+
+                let found_span = found_did.and_then(|did|
                     self.tcx.hir.span_if_local(did)
-                }).map(|sp| self.tcx.sess.source_map().def_span(sp)); // the sp could be an fn def
+                ).map(|sp| self.tcx.sess.source_map().def_span(sp)); // the sp could be an fn def
 
                 let found = match found_trait_ref.skip_binder().substs.type_at(1).sty {
-                    ty::Tuple(ref tys) => tys.iter()
-                        .map(|_| ArgKind::empty()).collect::<Vec<_>>(),
+                    ty::Tuple(ref tys) => vec![ArgKind::empty(); tys.len()],
                     _ => vec![ArgKind::empty()],
                 };
+
                 let expected = match expected_trait_ref.skip_binder().substs.type_at(1).sty {
                     ty::Tuple(ref tys) => tys.iter()
-                        .map(|t| match t.sty {
-                            ty::Tuple(ref tys) => ArgKind::Tuple(
-                                Some(span),
-                                tys.iter()
-                                    .map(|ty| ("_".to_owned(), ty.sty.to_string()))
-                                    .collect::<Vec<_>>()
-                            ),
-                            _ => ArgKind::Arg("_".to_owned(), t.sty.to_string()),
-                        }).collect(),
+                        .map(|t| ArgKind::from_expected_ty(t, Some(span))).collect(),
                     ref sty => vec![ArgKind::Arg("_".to_owned(), sty.to_string())],
                 };
+
                 if found.len() == expected.len() {
                     self.report_closure_arg_mismatch(span,
                                                      found_span,
@@ -836,8 +830,7 @@ pub fn report_selection_error(&self,
 
             TraitNotObjectSafe(did) => {
                 let violations = self.tcx.object_safety_violations(did);
-                self.tcx.report_object_safety_error(span, did,
-                                                    violations)
+                self.tcx.report_object_safety_error(span, did, violations)
             }
 
             ConstEvalFailure(ref err) => {
@@ -846,7 +839,11 @@ pub fn report_selection_error(&self,
                     "could not evaluate constant expression",
                 ) {
                     Some(err) => err,
-                    None => return,
+                    None => {
+                        self.tcx.sess.delay_span_bug(span,
+                            &format!("constant in type had an ignored error: {:?}", err));
+                        return;
+                    }
                 }
             }
 
@@ -981,11 +978,9 @@ pub fn get_fn_like_arguments(&self, node: Node) -> (Span, Vec<ArgKind>) {
                         .map(|arg| match arg.clone().node {
                     hir::TyKind::Tup(ref tys) => ArgKind::Tuple(
                         Some(arg.span),
-                        tys.iter()
-                            .map(|_| ("_".to_owned(), "_".to_owned()))
-                            .collect::<Vec<_>>(),
+                        vec![("_".to_owned(), "_".to_owned()); tys.len()]
                     ),
-                    _ => ArgKind::Arg("_".to_owned(), "_".to_owned())
+                    _ => ArgKind::empty()
                 }).collect::<Vec<ArgKind>>())
             }
             Node::Variant(&hir::Variant {
@@ -997,15 +992,13 @@ pub fn get_fn_like_arguments(&self, node: Node) -> (Span, Vec<ArgKind>) {
                 ..
             }) => {
                 (self.tcx.sess.source_map().def_span(span),
-                 fields.iter().map(|field| {
+                 fields.iter().map(|field|
                      ArgKind::Arg(field.ident.to_string(), "_".to_string())
-                 }).collect::<Vec<_>>())
+                 ).collect::<Vec<_>>())
             }
             Node::StructCtor(ref variant_data) => {
                 (self.tcx.sess.source_map().def_span(self.tcx.hir.span(variant_data.id())),
-                 variant_data.fields()
-                    .iter().map(|_| ArgKind::Arg("_".to_owned(), "_".to_owned()))
-                    .collect())
+                 vec![ArgKind::empty(); variant_data.fields().len()])
             }
             _ => panic!("non-FnLike node found: {:?}", node),
         }
@@ -1054,7 +1047,7 @@ pub fn report_arg_count_mismatch(
             found_str,
         );
 
-        err.span_label(span, format!( "expected {} that takes {}", kind, expected_str));
+        err.span_label(span, format!("expected {} that takes {}", kind, expected_str));
 
         if let Some(found_span) = found_span {
             err.span_label(found_span, format!("takes {}", found_str));
@@ -1063,9 +1056,8 @@ pub fn report_arg_count_mismatch(
             // found arguments is empty (assume the user just wants to ignore args in this case).
             // For example, if `expected_args_length` is 2, suggest `|_, _|`.
             if found_args.is_empty() && is_closure {
-                let underscores = "_".repeat(expected_args.len())
-                                      .split("")
-                                      .filter(|s| !s.is_empty())
+                let underscores = iter::repeat("_")
+                                      .take(expected_args.len())
                                       .collect::<Vec<_>>()
                                       .join(", ");
                 err.span_suggestion_with_applicability(
@@ -1087,7 +1079,8 @@ pub fn report_arg_count_mismatch(
                 if fields.len() == expected_args.len() {
                     let sugg = fields.iter()
                         .map(|(name, _)| name.to_owned())
-                        .collect::<Vec<String>>().join(", ");
+                        .collect::<Vec<String>>()
+                        .join(", ");
                     err.span_suggestion_with_applicability(found_span,
                                                            "change the closure to take multiple \
                                                             arguments instead of a single tuple",
@@ -1146,7 +1139,7 @@ fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>,
             let inputs = trait_ref.substs.type_at(1);
             let sig = if let ty::Tuple(inputs) = inputs.sty {
                 tcx.mk_fn_sig(
-                    inputs.iter().map(|&x| x),
+                    inputs.iter().cloned(),
                     tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
                     false,
                     hir::Unsafety::Normal,
@@ -1220,10 +1213,9 @@ pub fn report_object_safety_error(self,
 
         let mut reported_violations = FxHashSet();
         for violation in violations {
-            if !reported_violations.insert(violation.clone()) {
-                continue;
+            if reported_violations.insert(violation.clone()) {
+                err.note(&violation.error_msg());
             }
-            err.note(&violation.error_msg());
         }
         err
     }
@@ -1289,10 +1281,10 @@ fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>,
                         self.need_type_info_err(body_id, span, self_ty).emit();
                     } else {
                         let mut err = struct_span_err!(self.tcx.sess,
-                                                        span, E0283,
-                                                        "type annotations required: \
+                                                       span, E0283,
+                                                       "type annotations required: \
                                                         cannot resolve `{}`",
-                                                        predicate);
+                                                       predicate);
                         self.note_obligation_cause(&mut err, obligation);
                         err.emit();
                     }
@@ -1438,6 +1430,7 @@ fn note_obligation_cause_code<T>(&self,
             ObligationCauseCode::ItemObligation(item_def_id) => {
                 let item_name = tcx.item_path_str(item_def_id);
                 let msg = format!("required by `{}`", item_name);
+
                 if let Some(sp) = tcx.hir.span_if_local(item_def_id) {
                     let sp = tcx.sess.source_map().def_span(sp);
                     err.span_note(sp, &msg);
@@ -1529,9 +1522,9 @@ fn note_obligation_cause_code<T>(&self,
                              parent_trait_ref.skip_binder().self_ty()));
                 let parent_predicate = parent_trait_ref.to_predicate();
                 self.note_obligation_cause_code(err,
-                                            &parent_predicate,
-                                            &data.parent_code,
-                                            obligated_types);
+                                                &parent_predicate,
+                                                &data.parent_code,
+                                                obligated_types);
             }
             ObligationCauseCode::CompareImplMethodObligation { .. } => {
                 err.note(
@@ -1560,21 +1553,21 @@ fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder) {
     }
 
     fn is_recursive_obligation(&self,
-                                   obligated_types: &mut Vec<&ty::TyS<'tcx>>,
-                                   cause_code: &ObligationCauseCode<'tcx>) -> bool {
+                               obligated_types: &mut Vec<&ty::TyS<'tcx>>,
+                               cause_code: &ObligationCauseCode<'tcx>) -> bool {
         if let ObligationCauseCode::BuiltinDerivedObligation(ref data) = cause_code {
             let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
-            for obligated_type in obligated_types {
-                if obligated_type == &parent_trait_ref.skip_binder().self_ty() {
-                    return true;
-                }
+
+            if obligated_types.iter().any(|ot| ot == &parent_trait_ref.skip_binder().self_ty()) {
+                return true;
             }
         }
-        return false;
+        false
     }
 }
 
 /// Summarizes information
+#[derive(Clone)]
 pub enum ArgKind {
     /// An argument of non-tuple type. Parameters are (name, ty)
     Arg(String, String),
@@ -1592,11 +1585,11 @@ fn empty() -> ArgKind {
     }
 
     /// Creates an `ArgKind` from the expected type of an
-    /// argument. This has no name (`_`) and no source spans..
-    pub fn from_expected_ty(t: Ty<'_>) -> ArgKind {
+    /// argument. It has no name (`_`) and an optional source span.
+    pub fn from_expected_ty(t: Ty<'_>, span: Option<Span>) -> ArgKind {
         match t.sty {
             ty::Tuple(ref tys) => ArgKind::Tuple(
-                None,
+                span,
                 tys.iter()
                    .map(|ty| ("_".to_owned(), ty.sty.to_string()))
                    .collect::<Vec<_>>()
index 9998db4ad1d48569f8ce45bd488d949a5f3b2467..707af02acbf4757f4253ee5d34e662ec3b2fd33f 100644 (file)
@@ -526,7 +526,7 @@ fn process_backedge<'c, I>(&mut self, cycle: I,
         if self.selcx.coinductive_match(cycle.clone().map(|s| s.obligation.predicate)) {
             debug!("process_child_obligations: coinductive match");
         } else {
-            let cycle : Vec<_> = cycle.map(|c| c.obligation.clone()).collect();
+            let cycle: Vec<_> = cycle.map(|c| c.obligation.clone()).collect();
             self.selcx.infcx().report_overflow_error_cycle(&cycle);
         }
     }
index e2dbe88354060b2221957de9398ed8696e392ecd..edf7772f2f78ef76f907275f62fd7700fce9da06 100644 (file)
@@ -661,7 +661,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     let predicates: Vec<_> =
         util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.to_vec())
-        .collect();
+            .collect();
 
     debug!("normalize_param_env_or_error: elaborated-predicates={:?}",
            predicates);
@@ -707,7 +707,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         };
 
         debug!("normalize_param_env_or_error: normalized predicates={:?}",
-            predicates);
+               predicates);
 
         let region_scope_tree = region::ScopeTree::default();
 
@@ -851,16 +851,16 @@ fn vtable_methods<'a, 'tcx>(
 
                 // the method may have some early-bound lifetimes, add
                 // regions for those
-                let substs = trait_ref.map_bound(|trait_ref| {
-                    Substs::for_item(tcx, def_id, |param, _| {
+                let substs = trait_ref.map_bound(|trait_ref|
+                    Substs::for_item(tcx, def_id, |param, _|
                         match param.kind {
                             GenericParamDefKind::Lifetime => tcx.types.re_erased.into(),
                             GenericParamDefKind::Type {..} => {
                                 trait_ref.substs[param.index as usize]
                             }
                         }
-                    })
-                });
+                    )
+                );
 
                 // the trait type may have higher-ranked lifetimes in it;
                 // so erase them if they appear, so that we get the type
index 17d55b77625b2c5cc347cbec2229b5c4d9a9978d..0046a23a085e70cf308b1db304f7f6f1997cbba6 100644 (file)
@@ -124,20 +124,21 @@ fn object_safety_violations_for_trait(self, trait_def_id: DefId)
         // Check methods for violations.
         let mut violations: Vec<_> = self.associated_items(trait_def_id)
             .filter(|item| item.kind == ty::AssociatedKind::Method)
-            .filter_map(|item| {
+            .filter_map(|item|
                 self.object_safety_violation_for_method(trait_def_id, &item)
                     .map(|code| ObjectSafetyViolation::Method(item.ident.name, code))
-            }).filter(|violation| {
+            ).filter(|violation| {
                 if let ObjectSafetyViolation::Method(_,
-                                MethodViolationCode::WhereClauseReferencesSelf(span)) = violation {
-                    // Using`CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
+                    MethodViolationCode::WhereClauseReferencesSelf(span)) = violation
+                {
+                    // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
                     // It's also hard to get a use site span, so we use the method definition span.
                     self.lint_node_note(
                         lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY,
                         ast::CRATE_NODE_ID,
                         *span,
                         &format!("the trait `{}` cannot be made into an object",
-                                self.item_path_str(trait_def_id)),
+                                 self.item_path_str(trait_def_id)),
                         &violation.error_msg());
                     false
                 } else {
@@ -213,24 +214,23 @@ fn generics_require_sized_self(self, def_id: DefId) -> bool {
         let predicates = self.predicates_of(def_id);
         let predicates = predicates.instantiate_identity(self).predicates;
         elaborate_predicates(self, predicates)
-            .any(|predicate| {
-                match predicate {
-                    ty::Predicate::Trait(ref trait_pred) if trait_pred.def_id() == sized_def_id => {
-                        trait_pred.skip_binder().self_ty().is_self()
-                    }
-                    ty::Predicate::Projection(..) |
-                    ty::Predicate::Trait(..) |
-                    ty::Predicate::Subtype(..) |
-                    ty::Predicate::RegionOutlives(..) |
-                    ty::Predicate::WellFormed(..) |
-                    ty::Predicate::ObjectSafe(..) |
-                    ty::Predicate::ClosureKind(..) |
-                    ty::Predicate::TypeOutlives(..) |
-                    ty::Predicate::ConstEvaluatable(..) => {
-                        false
-                    }
+            .any(|predicate| match predicate {
+                ty::Predicate::Trait(ref trait_pred) if trait_pred.def_id() == sized_def_id => {
+                    trait_pred.skip_binder().self_ty().is_self()
                 }
-            })
+                ty::Predicate::Projection(..) |
+                ty::Predicate::Trait(..) |
+                ty::Predicate::Subtype(..) |
+                ty::Predicate::RegionOutlives(..) |
+                ty::Predicate::WellFormed(..) |
+                ty::Predicate::ObjectSafe(..) |
+                ty::Predicate::ClosureKind(..) |
+                ty::Predicate::TypeOutlives(..) |
+                ty::Predicate::ConstEvaluatable(..) => {
+                    false
+                }
+            }
+        )
     }
 
     /// Returns `Some(_)` if this method makes the containing trait not object safe.
index 280ce75720bcfef8d309c0caefbc6197b6648102..f59812c0eea984f4212a3367aa585a35bf9df4c0 100644 (file)
@@ -74,17 +74,17 @@ pub fn parse(tcx: TyCtxt<'a, 'gcx, 'tcx>,
         let condition = if is_root {
             None
         } else {
-            let cond = item_iter.next().ok_or_else(|| {
+            let cond = item_iter.next().ok_or_else(||
                 parse_error(tcx, span,
                             "empty `on`-clause in `#[rustc_on_unimplemented]`",
                             "empty on-clause here",
                             None)
-            })?.meta_item().ok_or_else(|| {
+            )?.meta_item().ok_or_else(||
                 parse_error(tcx, span,
                             "invalid `on`-clause in `#[rustc_on_unimplemented]`",
                             "invalid on-clause here",
                             None)
-            })?;
+            )?;
             attr::eval_condition(cond, &tcx.sess.parse_sess, &mut |_| true);
             Some(cond.clone())
         };
@@ -259,9 +259,9 @@ fn verify(&self,
                     // `{from_desugaring}` is allowed
                     Position::ArgumentNamed(s) if s == "from_desugaring" => (),
                     // So is `{A}` if A is a type parameter
-                    Position::ArgumentNamed(s) => match generics.params.iter().find(|param| {
+                    Position::ArgumentNamed(s) => match generics.params.iter().find(|param|
                         param.name == s
-                    }) {
+                    ) {
                         Some(_) => (),
                         None => {
                             span_err!(tcx.sess, span, E0230,
@@ -304,7 +304,7 @@ pub fn format(&self,
         let empty_string = String::new();
 
         let parser = Parser::new(&self.0, None);
-        parser.map(|p| {
+        parser.map(|p|
             match p {
                 Piece::String(s) => s,
                 Piece::NextArgument(a) => match a.position {
@@ -326,11 +326,9 @@ pub fn format(&self,
                             }
                         }
                     },
-                    _ => {
-                        bug!("broken on_unimplemented {:?} - bad format arg", self.0)
-                    }
+                    _ => bug!("broken on_unimplemented {:?} - bad format arg", self.0)
                 }
             }
-        }).collect()
+        ).collect()
     }
 }
index e50f59cbc82c1b03476c9cff3b5e422c58d02f3b..5ea936f750e2e24398963263b4b46a649defc494 100644 (file)
@@ -171,7 +171,7 @@ fn push_candidate(&mut self, candidate: ProjectionTyCandidate<'tcx>) -> bool {
                 match (current, candidate) {
                     (ParamEnv(..), ParamEnv(..)) => convert_to_ambiguous = (),
                     (ParamEnv(..), _) => return false,
-                    (_, ParamEnv(..)) => { unreachable!(); }
+                    (_, ParamEnv(..)) => unreachable!(),
                     (_, _) => convert_to_ambiguous = (),
                 }
             }
@@ -419,9 +419,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                 normalized_ty
             }
 
-            _ => {
-                ty
-            }
+            _ => ty
         }
     }
 
@@ -437,12 +435,9 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc
                             instance,
                             promoted: None
                         };
-                        match tcx.const_eval(param_env.and(cid)) {
-                            Ok(evaluated) => {
-                                let evaluated = evaluated.subst(self.tcx(), substs);
-                                return self.fold_const(evaluated);
-                            }
-                            Err(_) => {}
+                        if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
+                            let evaluated = evaluated.subst(self.tcx(), substs);
+                            return self.fold_const(evaluated);
                         }
                     }
                 } else {
@@ -453,9 +448,8 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc
                                 instance,
                                 promoted: None
                             };
-                            match tcx.const_eval(param_env.and(cid)) {
-                                Ok(evaluated) => return self.fold_const(evaluated),
-                                Err(_) => {}
+                            if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
+                                return self.fold_const(evaluated)
                             }
                         }
                     }
@@ -993,7 +987,7 @@ fn assemble_candidates_from_trait_def<'cx, 'gcx, 'tcx>(
             candidate_set.mark_ambiguous();
             return;
         }
-        _ => { return; }
+        _ => return
     };
 
     // If so, extract what we know from the trait and try to come up with a good answer.
@@ -1023,33 +1017,30 @@ fn assemble_candidates_from_predicates<'cx, 'gcx, 'tcx, I>(
     for predicate in env_predicates {
         debug!("assemble_candidates_from_predicates: predicate={:?}",
                predicate);
-        match predicate {
-            ty::Predicate::Projection(data) => {
-                let same_def_id = data.projection_def_id() == obligation.predicate.item_def_id;
-
-                let is_match = same_def_id && infcx.probe(|_| {
-                    let data_poly_trait_ref =
-                        data.to_poly_trait_ref(infcx.tcx);
-                    let obligation_poly_trait_ref =
-                        obligation_trait_ref.to_poly_trait_ref();
-                    infcx.at(&obligation.cause, obligation.param_env)
-                         .sup(obligation_poly_trait_ref, data_poly_trait_ref)
-                         .map(|InferOk { obligations: _, value: () }| {
-                             // FIXME(#32730) -- do we need to take obligations
-                             // into account in any way? At the moment, no.
-                         })
-                         .is_ok()
-                });
-
-                debug!("assemble_candidates_from_predicates: candidate={:?} \
-                                                             is_match={} same_def_id={}",
-                       data, is_match, same_def_id);
-
-                if is_match {
-                    candidate_set.push_candidate(ctor(data));
-                }
+        if let ty::Predicate::Projection(data) = predicate {
+            let same_def_id = data.projection_def_id() == obligation.predicate.item_def_id;
+
+            let is_match = same_def_id && infcx.probe(|_| {
+                let data_poly_trait_ref =
+                    data.to_poly_trait_ref(infcx.tcx);
+                let obligation_poly_trait_ref =
+                    obligation_trait_ref.to_poly_trait_ref();
+                infcx.at(&obligation.cause, obligation.param_env)
+                     .sup(obligation_poly_trait_ref, data_poly_trait_ref)
+                     .map(|InferOk { obligations: _, value: () }| {
+                         // FIXME(#32730) -- do we need to take obligations
+                         // into account in any way? At the moment, no.
+                     })
+                     .is_ok()
+            });
+
+            debug!("assemble_candidates_from_predicates: candidate={:?} \
+                    is_match={} same_def_id={}",
+                   data, is_match, same_def_id);
+
+            if is_match {
+                candidate_set.push_candidate(ctor(data));
             }
-            _ => {}
         }
     }
 }
@@ -1072,8 +1063,7 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
                 return Err(());
             }
             Err(e) => {
-                debug!("assemble_candidates_from_impls: selection error {:?}",
-                       e);
+                debug!("assemble_candidates_from_impls: selection error {:?}", e);
                 candidate_set.mark_error(e);
                 return Err(());
             }
@@ -1295,11 +1285,11 @@ fn confirm_object_candidate<'cx, 'gcx, 'tcx>(
         let mut env_predicates = env_predicates.filter(|data| {
             let data_poly_trait_ref = data.to_poly_trait_ref(selcx.tcx());
             let obligation_poly_trait_ref = obligation_trait_ref.to_poly_trait_ref();
-            selcx.infcx().probe(|_| {
+            selcx.infcx().probe(|_|
                 selcx.infcx().at(&obligation.cause, obligation.param_env)
                              .sup(obligation_poly_trait_ref, data_poly_trait_ref)
                              .is_ok()
-            })
+            )
         });
 
         // select the first matching one; there really ought to be one or
@@ -1447,7 +1437,7 @@ fn confirm_callable_candidate<'cx, 'gcx, 'tcx>(
                                               obligation.predicate.self_ty(),
                                               fn_sig,
                                               flag)
-        .map_bound(|(trait_ref, ret_type)| {
+        .map_bound(|(trait_ref, ret_type)|
             ty::ProjectionPredicate {
                 projection_ty: ty::ProjectionTy::from_ref_and_name(
                     tcx,
@@ -1456,7 +1446,7 @@ fn confirm_callable_candidate<'cx, 'gcx, 'tcx>(
                 ),
                 ty: ret_type
             }
-        });
+        );
 
     confirm_param_env_candidate(selcx, obligation, predicate)
 }
index fd8898dffd4f2da428494386eead02f528c62179..f5fb183ec1a5d2d36873515861c93b7a9e9ba677 100644 (file)
@@ -57,22 +57,19 @@ pub fn dropck_outlives(&self, ty: Ty<'tcx>) -> InferOk<'tcx, Vec<Kind<'tcx>>> {
         debug!("c_ty = {:?}", c_ty);
         match &gcx.dropck_outlives(c_ty) {
             Ok(result) if result.is_proven() => {
-                match self.infcx.instantiate_query_result_and_region_obligations(
+                if let Ok(InferOk { value, obligations }) =
+                    self.infcx.instantiate_query_result_and_region_obligations(
                     self.cause,
                     self.param_env,
                     &orig_values,
-                    result,
-                ) {
-                    Ok(InferOk { value, obligations }) => {
-                        let ty = self.infcx.resolve_type_vars_if_possible(&ty);
-                        let kinds = value.into_kinds_reporting_overflows(tcx, span, ty);
-                        return InferOk {
-                            value: kinds,
-                            obligations,
-                        };
-                    }
-
-                    Err(_) => { /* fallthrough to error-handling code below */ }
+                    result)
+                {
+                    let ty = self.infcx.resolve_type_vars_if_possible(&ty);
+                    let kinds = value.into_kinds_reporting_overflows(tcx, span, ty);
+                    return InferOk {
+                        value: kinds,
+                        obligations,
+                    };
                 }
             }
 
@@ -161,12 +158,7 @@ impl<'tcx> FromIterator<DtorckConstraint<'tcx>> for DtorckConstraint<'tcx> {
     fn from_iter<I: IntoIterator<Item = DtorckConstraint<'tcx>>>(iter: I) -> Self {
         let mut result = Self::empty();
 
-        for DtorckConstraint {
-            outlives,
-            dtorck_types,
-            overflows,
-        } in iter
-        {
+        for DtorckConstraint { outlives, dtorck_types, overflows } in iter {
             result.outlives.extend(outlives);
             result.dtorck_types.extend(dtorck_types);
             result.overflows.extend(overflows);
@@ -254,7 +246,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) ->
             }
         }
 
-        // The following *might* require a destructor: it would deeper inspection to tell.
+        // The following *might* require a destructor: needs deeper inspection.
         ty::Dynamic(..)
         | ty::Projection(..)
         | ty::Param(_)
index ea8bc3b20aae94d4a61203e91bedfd83776d115e..9b9643aab97d596d1d098e5fd25578297fc16ede 100644 (file)
@@ -48,6 +48,13 @@ pub fn normalize<T>(&self, value: &T) -> Result<Normalized<'tcx, T>, NoSolution>
             value,
             self.param_env,
         );
+        if !value.has_projections() {
+            return Ok(Normalized {
+                value: value.clone(),
+                obligations: vec![],
+            });
+        }
+
         let mut normalizer = QueryNormalizer {
             infcx: self.infcx,
             cause: self.cause,
@@ -56,12 +63,6 @@ pub fn normalize<T>(&self, value: &T) -> Result<Normalized<'tcx, T>, NoSolution>
             error: false,
             anon_depth: 0,
         };
-        if !value.has_projections() {
-            return Ok(Normalized {
-                value: value.clone(),
-                obligations: vec![],
-            });
-        }
 
         let value1 = value.fold_with(&mut normalizer);
         if normalizer.error {
@@ -154,8 +155,8 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                 let gcx = self.infcx.tcx.global_tcx();
 
                 let mut orig_values = SmallVec::new();
-                let c_data = self.infcx
-                    .canonicalize_query(&self.param_env.and(*data), &mut orig_values);
+                let c_data = self.infcx.canonicalize_query(
+                    &self.param_env.and(*data), &mut orig_values);
                 debug!("QueryNormalizer: c_data = {:#?}", c_data);
                 debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
                 match gcx.normalize_projection_ty(c_data) {
@@ -170,12 +171,9 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                             self.cause,
                             self.param_env,
                             &orig_values,
-                            &result,
-                        ) {
-                            Ok(InferOk {
-                                value: result,
-                                obligations,
-                            }) => {
+                            &result)
+                        {
+                            Ok(InferOk { value: result, obligations }) => {
                                 debug!("QueryNormalizer: result = {:#?}", result);
                                 debug!("QueryNormalizer: obligations = {:#?}", obligations);
                                 self.obligations.extend(obligations);
@@ -212,12 +210,9 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc
                             instance,
                             promoted: None,
                         };
-                        match tcx.const_eval(param_env.and(cid)) {
-                            Ok(evaluated) => {
-                                let evaluated = evaluated.subst(self.tcx(), substs);
-                                return self.fold_const(evaluated);
-                            }
-                            Err(_) => {}
+                        if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
+                            let evaluated = evaluated.subst(self.tcx(), substs);
+                            return self.fold_const(evaluated);
                         }
                     }
                 } else {
@@ -228,9 +223,8 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc
                                 instance,
                                 promoted: None,
                             };
-                            match tcx.const_eval(param_env.and(cid)) {
-                                Ok(evaluated) => return self.fold_const(evaluated),
-                                Err(_) => {}
+                            if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
+                                return self.fold_const(evaluated)
                             }
                         }
                     }
index 85e7368bfdd1042f04b5be0e86804920081e1f7c..c6099e15f8bb587d45dc3eec530d00d978b7e906 100644 (file)
@@ -55,7 +55,6 @@
 use hir;
 use util::nodemap::{FxHashMap, FxHashSet};
 
-
 pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
     infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
 
@@ -149,7 +148,7 @@ struct TraitObligationStack<'prev, 'tcx: 'prev> {
 #[derive(Clone)]
 pub struct SelectionCache<'tcx> {
     hashmap: Lock<FxHashMap<ty::TraitRef<'tcx>,
-                               WithDepNode<SelectionResult<'tcx, SelectionCandidate<'tcx>>>>>,
+                            WithDepNode<SelectionResult<'tcx, SelectionCandidate<'tcx>>>>>,
 }
 
 /// The selection process begins by considering all impls, where
@@ -623,9 +622,9 @@ pub fn evaluate_obligation_recursively(&mut self,
                                            obligation: &PredicateObligation<'tcx>)
                                            -> Result<EvaluationResult, OverflowError>
     {
-        self.probe(|this, _| {
+        self.probe(|this, _|
             this.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation)
-        })
+        )
     }
 
     /// Evaluates the predicates in `predicates` recursively. Note that
@@ -717,13 +716,9 @@ fn evaluate_predicate_recursively<'o>(&mut self,
                             self.infcx.projection_cache.borrow_mut().complete(key);
                         }
                         result
-                    }
-                    Ok(None) => {
-                        Ok(EvaluatedToAmbig)
-                    }
-                    Err(_) => {
-                        Ok(EvaluatedToErr)
-                    }
+                    },
+                    Ok(None) => Ok(EvaluatedToAmbig),
+                    Err(_) => Ok(EvaluatedToErr)
                 }
             }
 
@@ -735,10 +730,8 @@ fn evaluate_predicate_recursively<'o>(&mut self,
                         } else {
                             Ok(EvaluatedToErr)
                         }
-                    }
-                    None => {
-                        Ok(EvaluatedToAmbig)
-                    }
+                    },
+                    None => Ok(EvaluatedToAmbig)
                 }
             }
 
@@ -901,13 +894,13 @@ fn evaluate_stack<'o>(&mut self,
         // same unbound type variable.
         if let Some(rec_index) =
             stack.iter()
-            .skip(1) // skip top-most frame
-            .position(|prev| stack.obligation.param_env == prev.obligation.param_env &&
-                      stack.fresh_trait_ref == prev.fresh_trait_ref)
+                 .skip(1) // skip top-most frame
+                 .position(|prev| stack.obligation.param_env == prev.obligation.param_env &&
+                                  stack.fresh_trait_ref == prev.fresh_trait_ref)
         {
             debug!("evaluate_stack({:?}) --> recursive",
                    stack.fresh_trait_ref);
-            let cycle = stack.iter().skip(1).take(rec_index+1);
+            let cycle = stack.iter().skip(1).take(rec_index + 1);
             let cycle = cycle.map(|stack| ty::Predicate::Trait(stack.obligation.predicate));
             if self.coinductive_match(cycle) {
                 debug!("evaluate_stack({:?}) --> recursive, coinductive",
@@ -947,10 +940,8 @@ fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool {
         let result = match predicate {
             ty::Predicate::Trait(ref data) => {
                 self.tcx().trait_is_auto(data.def_id())
-            }
-            _ => {
-                false
-            }
+            },
+            _ => false
         };
         debug!("coinductive_predicate({:?}) = {:?}", predicate, result);
         result
@@ -1088,9 +1079,9 @@ fn candidate_from_obligation<'o>(&mut self,
         }
 
         // If no match, compute result and insert into cache.
-        let (candidate, dep_node) = self.in_task(|this| {
+        let (candidate, dep_node) = self.in_task(|this|
             this.candidate_from_obligation_no_cache(stack)
-        });
+        );
 
         debug!("CACHE MISS: SELECT({:?})={:?}",
                cache_fresh_trait_pred, candidate);
@@ -1104,9 +1095,9 @@ fn candidate_from_obligation<'o>(&mut self,
     fn in_task<OP, R>(&mut self, op: OP) -> (R, DepNodeIndex)
         where OP: FnOnce(&mut Self) -> R
     {
-        let (result, dep_node) = self.tcx().dep_graph.with_anon_task(DepKind::TraitSelect, || {
+        let (result, dep_node) = self.tcx().dep_graph.with_anon_task(DepKind::TraitSelect, ||
             op(self)
-        });
+        );
         self.tcx().dep_graph.read_index(dep_node);
         (result, dep_node)
     }
@@ -1138,46 +1129,53 @@ fn candidate_from_obligation_no_cache<'o>(&mut self,
             return Ok(None);
         }
 
-        match self.is_knowable(stack) {
-            None => {}
-            Some(conflict) => {
-                debug!("coherence stage: not knowable");
-                if self.intercrate_ambiguity_causes.is_some() {
-                    debug!("evaluate_stack: intercrate_ambiguity_causes is some");
-                    // Heuristics: show the diagnostics when there are no candidates in crate.
-                    if let Ok(candidate_set) = self.assemble_candidates(stack) {
-                        let no_candidates_apply =
-                            candidate_set
-                            .vec
-                            .iter()
-                            .map(|c| self.evaluate_candidate(stack, &c))
-                            .collect::<Result<Vec<_>, OverflowError>>()?
-                            .iter()
-                            .all(|r| !r.may_apply());
-                        if !candidate_set.ambiguous && no_candidates_apply {
-                            let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
-                            let self_ty = trait_ref.self_ty();
-                            let trait_desc = trait_ref.to_string();
-                            let self_desc = if self_ty.has_concrete_skeleton() {
-                                Some(self_ty.to_string())
-                            } else {
-                                None
-                            };
-                            let cause = if let Conflict::Upstream = conflict {
-                                IntercrateAmbiguityCause::UpstreamCrateUpdate {
-                                    trait_desc,
-                                    self_desc,
-                                }
-                            } else {
-                                IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
-                            };
-                            debug!("evaluate_stack: pushing cause = {:?}", cause);
-                            self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause);
+        if let Some(conflict) = self.is_knowable(stack) {
+            debug!("coherence stage: not knowable");
+            if self.intercrate_ambiguity_causes.is_some() {
+                debug!("evaluate_stack: intercrate_ambiguity_causes is some");
+                // Heuristics: show the diagnostics when there are no candidates in crate.
+                if let Ok(candidate_set) = self.assemble_candidates(stack) {
+                    let mut no_candidates_apply = true;
+                    {
+                        let evaluated_candidates = candidate_set.vec.iter().map(|c|
+                            self.evaluate_candidate(stack, &c));
+
+                        for ec in evaluated_candidates {
+                            match ec {
+                                Ok(c) => {
+                                    if c.may_apply() {
+                                        no_candidates_apply = false;
+                                        break
+                                    }
+                                },
+                                Err(e) => return Err(e.into())
+                            }
                         }
                     }
+
+                    if !candidate_set.ambiguous && no_candidates_apply {
+                        let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
+                        let self_ty = trait_ref.self_ty();
+                        let trait_desc = trait_ref.to_string();
+                        let self_desc = if self_ty.has_concrete_skeleton() {
+                            Some(self_ty.to_string())
+                        } else {
+                            None
+                        };
+                        let cause = if let Conflict::Upstream = conflict {
+                            IntercrateAmbiguityCause::UpstreamCrateUpdate {
+                                trait_desc,
+                                self_desc,
+                            }
+                        } else {
+                            IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
+                        };
+                        debug!("evaluate_stack: pushing cause = {:?}", cause);
+                        self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause);
+                    }
                 }
-                return Ok(None);
             }
+            return Ok(None);
         }
 
         let candidate_set = self.assemble_candidates(stack)?;
@@ -1434,9 +1432,9 @@ fn assemble_candidates<'o>(&mut self,
 
         // Other bounds. Consider both in-scope bounds from fn decl
         // and applicable impls. There is a certain set of precedence rules here.
-
         let def_id = obligation.predicate.def_id();
         let lang_items = self.tcx().lang_items();
+
         if lang_items.copy_trait() == Some(def_id) {
             debug!("obligation self ty is {:?}",
                    obligation.predicate.skip_binder().self_ty());
@@ -1495,15 +1493,15 @@ fn assemble_candidates_from_projected_tys(&mut self,
             ty::Projection(_) | ty::Opaque(..) => {}
             ty::Infer(ty::TyVar(_)) => {
                 span_bug!(obligation.cause.span,
-                    "Self=_ should have been handled by assemble_candidates");
+                          "Self=_ should have been handled by assemble_candidates");
             }
             _ => return
         }
 
-        let result = self.probe(|this, snapshot| {
+        let result = self.probe(|this, snapshot|
             this.match_projection_obligation_against_definition_bounds(obligation,
                                                                        snapshot)
-        });
+        );
 
         if result {
             candidates.vec.push(ProjectionCandidate);
@@ -1533,7 +1531,7 @@ fn match_projection_obligation_against_definition_bounds(
                 span_bug!(
                     obligation.cause.span,
                     "match_projection_obligation_against_definition_bounds() called \
-                     but self-ty not a projection: {:?}",
+                     but self-ty is not a projection: {:?}",
                     skol_trait_predicate.trait_ref.self_ty());
             }
         };
@@ -1637,14 +1635,14 @@ fn evaluate_where_clause<'o>(&mut self,
                                  where_clause_trait_ref: ty::PolyTraitRef<'tcx>)
                                  -> Result<EvaluationResult, OverflowError>
     {
-        self.probe(move |this, _| {
+        self.probe(move |this, _|
             match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) {
                 Ok(obligations) => {
                     this.evaluate_predicates_recursively(stack.list(), obligations.iter())
                 }
                 Err(()) => Ok(EvaluatedToErr)
             }
-        })
+        )
     }
 
     fn assemble_generator_candidates(&mut self,
@@ -1667,15 +1665,15 @@ fn assemble_generator_candidates(&mut self,
                        obligation);
 
                 candidates.vec.push(GeneratorCandidate);
-                Ok(())
             }
             ty::Infer(ty::TyVar(_)) => {
                 debug!("assemble_generator_candidates: ambiguous self-type");
                 candidates.ambiguous = true;
-                return Ok(());
             }
-            _ => { return Ok(()); }
+            _ => {}
         }
+
+        Ok(())
     }
 
     /// Check for the artificial impl that the compiler will create for an obligation like `X :
@@ -1712,16 +1710,16 @@ fn assemble_closure_candidates(&mut self,
                         debug!("assemble_unboxed_candidates: closure_kind not yet known");
                         candidates.vec.push(ClosureCandidate);
                     }
-                };
-                Ok(())
+                }
             }
             ty::Infer(ty::TyVar(_)) => {
                 debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
                 candidates.ambiguous = true;
-                return Ok(());
             }
-            _ => { return Ok(()); }
+            _ => {}
         }
+
+        Ok(())
     }
 
     /// Implement one of the `Fn()` family for a fn pointer.
@@ -1742,7 +1740,6 @@ fn assemble_fn_pointer_candidates(&mut self,
                 debug!("assemble_fn_pointer_candidates: ambiguous self-type");
                 candidates.ambiguous = true; // could wind up being a fn() type
             }
-
             // provide an impl, but only for suitable `fn` pointers
             ty::FnDef(..) | ty::FnPtr(_) => {
                 if let ty::FnSig {
@@ -1754,8 +1751,7 @@ fn assemble_fn_pointer_candidates(&mut self,
                     candidates.vec.push(FnPointerCandidate);
                 }
             }
-
-            _ => { }
+            _ => {}
         }
 
         Ok(())
@@ -1773,18 +1769,15 @@ fn assemble_candidates_from_impls(&mut self,
             obligation.predicate.def_id(),
             obligation.predicate.skip_binder().trait_ref.self_ty(),
             |impl_def_id| {
-                self.probe(|this, snapshot| { /* [1] */
-                    match this.match_impl(impl_def_id, obligation, snapshot) {
-                        Ok(skol_map) => {
-                            candidates.vec.push(ImplCandidate(impl_def_id));
-
-                            // NB: we can safely drop the skol map
-                            // since we are in a probe [1]
-                            mem::drop(skol_map);
-                        }
-                        Err(_) => { }
+                self.probe(|this, snapshot| /* [1] */
+                    if let Ok(skol_map) = this.match_impl(impl_def_id, obligation, snapshot) {
+                        candidates.vec.push(ImplCandidate(impl_def_id));
+
+                        // NB: we can safely drop the skol map
+                        // since we are in a probe [1]
+                        mem::drop(skol_map);
                     }
-                });
+                );
             }
         );
 
@@ -1874,7 +1867,7 @@ fn assemble_candidates_from_object_ty(&mut self,
                 ty::Dynamic(ref data, ..) => {
                     if data.auto_traits().any(|did| did == obligation.predicate.def_id()) {
                         debug!("assemble_candidates_from_object_ty: matched builtin bound, \
-                                    pushing candidate");
+                                pushing candidate");
                         candidates.vec.push(BuiltinObjectCandidate);
                         return;
                     }
@@ -1889,9 +1882,7 @@ fn assemble_candidates_from_object_ty(&mut self,
                     candidates.ambiguous = true; // could wind up being an object type
                     return;
                 }
-                _ => {
-                    return;
-                }
+                _ => return
             };
 
             debug!("assemble_candidates_from_object_ty: poly_trait_ref={:?}",
@@ -1904,12 +1895,12 @@ fn assemble_candidates_from_object_ty(&mut self,
             // but `Foo` is declared as `trait Foo : Bar<u32>`.
             let upcast_trait_refs =
                 util::supertraits(this.tcx(), poly_trait_ref)
-                .filter(|upcast_trait_ref| {
+                .filter(|upcast_trait_ref|
                     this.probe(|this, _| {
                         let upcast_trait_ref = upcast_trait_ref.clone();
                         this.match_poly_trait_ref(obligation, upcast_trait_ref).is_ok()
                     })
-                })
+                )
                 .count();
 
             if upcast_trait_refs > 1 {
@@ -2028,6 +2019,10 @@ fn candidate_should_be_dropped_in_favor_of<'o>(
         other: &EvaluatedCandidate<'tcx>)
         -> bool
     {
+        if victim.candidate == other.candidate {
+            return true;
+        }
+
         // Check if a bound would previously have been removed when normalizing
         // the param_env so that it can be given the lowest priority. See
         // #50825 for the motivation for this.
@@ -2035,10 +2030,6 @@ fn candidate_should_be_dropped_in_favor_of<'o>(
             cand.is_global() && !cand.has_late_bound_regions()
         };
 
-        if victim.candidate == other.candidate {
-            return true;
-        }
-
         match other.candidate {
             // Prefer BuiltinCandidate { has_nested: false } to anything else.
             // This is a fix for #53123 and prevents winnowing from accidentally extending the
@@ -2046,9 +2037,8 @@ fn candidate_should_be_dropped_in_favor_of<'o>(
             BuiltinCandidate { has_nested: false } => true,
             ParamCandidate(ref cand) => match victim.candidate {
                 AutoImplCandidate(..) => {
-                    bug!(
-                        "default implementations shouldn't be recorded \
-                         when there are other valid candidates");
+                    bug!("default implementations shouldn't be recorded \
+                          when there are other valid candidates");
                 }
                 // Prefer BuiltinCandidate { has_nested: false } to anything else.
                 // This is a fix for #53123 and prevents winnowing from accidentally extending the
@@ -2077,9 +2067,8 @@ fn candidate_should_be_dropped_in_favor_of<'o>(
             ObjectCandidate |
             ProjectionCandidate => match victim.candidate {
                 AutoImplCandidate(..) => {
-                    bug!(
-                        "default implementations shouldn't be recorded \
-                         when there are other valid candidates");
+                    bug!("default implementations shouldn't be recorded \
+                          when there are other valid candidates");
                 }
                 // Prefer BuiltinCandidate { has_nested: false } to anything else.
                 // This is a fix for #53123 and prevents winnowing from accidentally extending the
@@ -2151,7 +2140,7 @@ fn candidate_should_be_dropped_in_favor_of<'o>(
     fn assemble_builtin_bound_candidates<'o>(&mut self,
                                              conditions: BuiltinImplConditions<'tcx>,
                                              candidates: &mut SelectionCandidateSet<'tcx>)
-                                             -> Result<(),SelectionError<'tcx>>
+                                             -> Result<(), SelectionError<'tcx>>
     {
         match conditions {
             BuiltinImplConditions::Where(nested) => {
@@ -2159,18 +2148,20 @@ fn assemble_builtin_bound_candidates<'o>(&mut self,
                 candidates.vec.push(BuiltinCandidate {
                     has_nested: nested.skip_binder().len() > 0
                 });
-                Ok(())
             }
-            BuiltinImplConditions::None => { Ok(()) }
+            BuiltinImplConditions::None => {}
             BuiltinImplConditions::Ambiguous => {
                 debug!("assemble_builtin_bound_candidates: ambiguous builtin");
-                Ok(candidates.ambiguous = true)
+                candidates.ambiguous = true;
             }
         }
+
+        Ok(())
     }
 
-    fn sized_conditions(&mut self, obligation: &TraitObligation<'tcx>)
-                     -> BuiltinImplConditions<'tcx>
+    fn sized_conditions(&mut self,
+                        obligation: &TraitObligation<'tcx>)
+                        -> BuiltinImplConditions<'tcx>
     {
         use self::BuiltinImplConditions::{Ambiguous, None, Where};
 
@@ -2216,8 +2207,9 @@ fn sized_conditions(&mut self, obligation: &TraitObligation<'tcx>)
         }
     }
 
-    fn copy_clone_conditions(&mut self, obligation: &TraitObligation<'tcx>)
-                     -> BuiltinImplConditions<'tcx>
+    fn copy_clone_conditions(&mut self,
+                             obligation: &TraitObligation<'tcx>)
+                             -> BuiltinImplConditions<'tcx>
     {
         // NOTE: binder moved to (*)
         let self_ty = self.infcx.shallow_resolve(
@@ -2551,17 +2543,15 @@ fn confirm_builtin_candidate(&mut self,
         let lang_items = self.tcx().lang_items();
         let obligations = if has_nested {
             let trait_def = obligation.predicate.def_id();
-            let conditions = match trait_def {
-                _ if Some(trait_def) == lang_items.sized_trait() => {
+            let conditions =
+                if Some(trait_def) == lang_items.sized_trait() {
                     self.sized_conditions(obligation)
-                }
-                _ if Some(trait_def) == lang_items.copy_trait() => {
+                } else if Some(trait_def) == lang_items.copy_trait() {
                     self.copy_clone_conditions(obligation)
-                }
-                _ if Some(trait_def) == lang_items.clone_trait() => {
+                } else if Some(trait_def) == lang_items.clone_trait() {
                     self.copy_clone_conditions(obligation)
-                }
-                _ => bug!("unexpected builtin trait {:?}", trait_def)
+                } else {
+                    bug!("unexpected builtin trait {:?}", trait_def)
             };
             let nested = match conditions {
                 BuiltinImplConditions::Where(nested) => nested,
@@ -2608,10 +2598,10 @@ fn confirm_auto_impl_candidate(&mut self,
 
     /// See `confirm_auto_impl_candidate`
     fn vtable_auto_impl(&mut self,
-                           obligation: &TraitObligation<'tcx>,
-                           trait_def_id: DefId,
-                           nested: ty::Binder<Vec<Ty<'tcx>>>)
-                           -> VtableAutoImplData<PredicateObligation<'tcx>>
+                        obligation: &TraitObligation<'tcx>,
+                        trait_def_id: DefId,
+                        nested: ty::Binder<Vec<Ty<'tcx>>>)
+                        -> VtableAutoImplData<PredicateObligation<'tcx>>
     {
         debug!("vtable_auto_impl: nested={:?}", nested);
 
@@ -2731,10 +2721,8 @@ fn confirm_object_candidate(&mut self,
             ty::Dynamic(ref data, ..) => {
                 data.principal().unwrap().with_self_ty(self.tcx(), self_ty)
             }
-            _ => {
-                span_bug!(obligation.cause.span,
-                          "object candidate with non-object");
-            }
+            _ => span_bug!(obligation.cause.span,
+                           "object candidate with non-object")
         };
 
         let mut upcast_trait_ref = None;
@@ -2752,10 +2740,9 @@ fn confirm_object_candidate(&mut self,
             // record it for later.)
             let nonmatching =
                 util::supertraits(tcx, poly_trait_ref)
-                .take_while(|&t| {
-                    match
-                        self.commit_if_ok(
-                            |this, _| this.match_poly_trait_ref(obligation, t))
+                .take_while(|&t|
+                    match self.commit_if_ok(|this, _|
+                        this.match_poly_trait_ref(obligation, t))
                     {
                         Ok(obligations) => {
                             upcast_trait_ref = Some(t);
@@ -2764,16 +2751,13 @@ fn confirm_object_candidate(&mut self,
                         }
                         Err(_) => { true }
                     }
-                });
+                );
 
             // Additionally, for each of the nonmatching predicates that
             // we pass over, we sum up the set of number of vtable
             // entries, so that we can compute the offset for the selected
             // trait.
-            vtable_base =
-                nonmatching.map(|t| tcx.count_own_vtable_entries(t))
-                           .sum();
-
+            vtable_base = nonmatching.map(|t| tcx.count_own_vtable_entries(t)).sum();
         }
 
         VtableObjectData {
@@ -2816,7 +2800,7 @@ fn confirm_fn_pointer_candidate(&mut self, obligation: &TraitObligation<'tcx>)
     fn confirm_generator_candidate(&mut self,
                                    obligation: &TraitObligation<'tcx>)
                                    -> Result<VtableGeneratorData<'tcx, PredicateObligation<'tcx>>,
-                                           SelectionError<'tcx>>
+                                             SelectionError<'tcx>>
     {
         // ok to skip binder because the substs on generator types never
         // touch bound regions, they just capture the in-scope
@@ -2869,10 +2853,11 @@ fn confirm_closure_candidate(&mut self,
     {
         debug!("confirm_closure_candidate({:?})", obligation);
 
-        let kind = match self.tcx().lang_items().fn_trait_kind(obligation.predicate.def_id()) {
-            Some(k) => k,
-            None => bug!("closure candidate for non-fn trait {:?}", obligation)
-        };
+        let kind = self.tcx()
+                       .lang_items()
+                       .fn_trait_kind(obligation.predicate.def_id())
+                       .unwrap_or_else(|| bug!("closure candidate for non-fn trait {:?}",
+                                               obligation));
 
         // ok to skip binder because the substs on closure types never
         // touch bound regions, they just capture the in-scope
@@ -2901,9 +2886,9 @@ fn confirm_closure_candidate(&mut self,
 
         obligations.extend(
             self.confirm_poly_trait_refs(obligation.cause.clone(),
-                                        obligation.param_env,
-                                        obligation.predicate.to_poly_trait_ref(),
-                                        trait_ref)?);
+                                         obligation.param_env,
+                                         obligation.predicate.to_poly_trait_ref(),
+                                         trait_ref)?);
 
         obligations.push(Obligation::new(
             obligation.cause.clone(),
@@ -3008,20 +2993,19 @@ fn confirm_builtin_unsize_candidate(&mut self,
             (_, &ty::Dynamic(ref data, r)) => {
                 let mut object_dids =
                     data.auto_traits().chain(data.principal().map(|p| p.def_id()));
-                if let Some(did) = object_dids.find(|did| {
-                    !tcx.is_object_safe(*did)
-                }) {
+                if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) {
                     return Err(TraitNotObjectSafe(did))
                 }
 
                 let cause = ObligationCause::new(obligation.cause.span,
                                                  obligation.cause.body_id,
                                                  ObjectCastObligation(target));
-                let mut push = |predicate| {
-                    nested.push(Obligation::with_depth(cause.clone(),
-                                                       obligation.recursion_depth + 1,
-                                                       obligation.param_env,
-                                                       predicate));
+
+                let predicate_to_obligation = |predicate| {
+                    Obligation::with_depth(cause.clone(),
+                                           obligation.recursion_depth + 1,
+                                           obligation.param_env,
+                                           predicate)
                 };
 
                 // Create obligations:
@@ -3030,21 +3014,22 @@ fn confirm_builtin_unsize_candidate(&mut self,
                 //  words, if the object type is Foo+Send, this would create an obligation for the
                 //  Send check.)
                 //  - Projection predicates
-                for predicate in data.iter() {
-                    push(predicate.with_self_ty(tcx, source));
-                }
+                nested.extend(data.iter().map(|d|
+                    predicate_to_obligation(d.with_self_ty(tcx, source))
+                ));
 
                 // We can only make objects from sized types.
                 let tr = ty::TraitRef {
                     def_id: tcx.require_lang_item(lang_items::SizedTraitLangItem),
                     substs: tcx.mk_substs_trait(source, &[]),
                 };
-                push(tr.to_predicate());
+                nested.push(predicate_to_obligation(tr.to_predicate()));
 
                 // If the type is `Foo+'a`, ensures that the type
                 // being cast to `Foo+'a` outlives `'a`:
                 let outlives = ty::OutlivesPredicate(source, r);
-                push(ty::Binder::dummy(outlives).to_predicate());
+                nested.push(predicate_to_obligation(
+                    ty::Binder::dummy(outlives).to_predicate()));
             }
 
             // [T; n] -> [T].
@@ -3105,13 +3090,13 @@ fn confirm_builtin_unsize_candidate(&mut self,
 
                 // Check that the source struct with the target's
                 // unsized parameters is equal to the target.
-                let params = substs_a.iter().enumerate().map(|(i, &k)| {
+                let params = substs_a.iter().enumerate().map(|(i, &k)|
                     if ty_params.contains(i) {
                         substs_b.type_at(i).into()
                     } else {
                         k
                     }
-                });
+                );
                 let new_struct = tcx.mk_adt(def, tcx.mk_substs(params));
                 let InferOk { obligations, .. } =
                     self.infcx.at(&obligation.cause, obligation.param_env)
@@ -3236,10 +3221,9 @@ fn match_impl(&mut self,
         let InferOk { obligations, .. } =
             self.infcx.at(&obligation.cause, obligation.param_env)
                       .eq(skol_obligation_trait_ref, impl_trait_ref)
-                      .map_err(|e| {
-                          debug!("match_impl: failed eq_trait_refs due to `{}`", e);
-                          ()
-                      })?;
+                      .map_err(|e|
+                          debug!("match_impl: failed eq_trait_refs due to `{}`", e)
+                      )?;
         nested_obligations.extend(obligations);
 
         if let Err(e) = self.infcx.leak_check(false,
@@ -3288,7 +3272,7 @@ fn fast_reject_trait_refs(&mut self,
     fn match_where_clause_trait_ref(&mut self,
                                     obligation: &TraitObligation<'tcx>,
                                     where_clause_trait_ref: ty::PolyTraitRef<'tcx>)
-                                    -> Result<Vec<PredicateObligation<'tcx>>,()>
+                                    -> Result<Vec<PredicateObligation<'tcx>>, ()>
     {
         self.match_poly_trait_ref(obligation, where_clause_trait_ref)
     }
@@ -3298,7 +3282,7 @@ fn match_where_clause_trait_ref(&mut self,
     fn match_poly_trait_ref(&mut self,
                             obligation: &TraitObligation<'tcx>,
                             poly_trait_ref: ty::PolyTraitRef<'tcx>)
-                            -> Result<Vec<PredicateObligation<'tcx>>,()>
+                            -> Result<Vec<PredicateObligation<'tcx>>, ()>
     {
         debug!("match_poly_trait_ref: obligation={:?} poly_trait_ref={:?}",
                obligation,
@@ -3350,20 +3334,20 @@ fn closure_trait_ref_unnormalized(&mut self,
         // in fact unparameterized (or at least does not reference any
         // regions bound in the obligation). Still probably some
         // refactoring could make this nicer.
-
         self.tcx().closure_trait_ref_and_return_type(obligation.predicate.def_id(),
                                                      obligation.predicate
-                                                         .skip_binder().self_ty(), // (1)
+                                                               .skip_binder()
+                                                               .self_ty(), // (1)
                                                      closure_type,
                                                      util::TupleArgumentsFlag::No)
             .map_bound(|(trait_ref, _)| trait_ref)
     }
 
     fn generator_trait_ref_unnormalized(&mut self,
-                                      obligation: &TraitObligation<'tcx>,
-                                      closure_def_id: DefId,
-                                      substs: ty::GeneratorSubsts<'tcx>)
-                                      -> ty::PolyTraitRef<'tcx>
+                                        obligation: &TraitObligation<'tcx>,
+                                        closure_def_id: DefId,
+                                        substs: ty::GeneratorSubsts<'tcx>)
+                                        -> ty::PolyTraitRef<'tcx>
     {
         let gen_sig = substs.poly_sig(closure_def_id, self.tcx());
 
@@ -3375,7 +3359,8 @@ fn generator_trait_ref_unnormalized(&mut self,
 
         self.tcx().generator_trait_ref_and_outputs(obligation.predicate.def_id(),
                                                    obligation.predicate
-                                                       .skip_binder().self_ty(), // (1)
+                                                             .skip_binder()
+                                                             .self_ty(), // (1)
                                                    gen_sig)
             .map_bound(|(trait_ref, ..)| trait_ref)
     }
@@ -3453,8 +3438,8 @@ fn impl_or_trait_obligations(&mut self,
 impl<'tcx> TraitObligation<'tcx> {
     #[allow(unused_comparisons)]
     pub fn derived_cause(&self,
-                        variant: fn(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>)
-                        -> ObligationCause<'tcx>
+                         variant: fn(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>)
+                         -> ObligationCause<'tcx>
     {
         /*!
          * Creates a cause for obligations that are derived from
index 9343eff9e79b4f2f43407ade6b09ea0e74d85a8e..dbd84397b597d37542a038d9ff1675a9f98b2863 100644 (file)
@@ -100,10 +100,10 @@ pub fn translate_substs<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
             }
 
             fulfill_implication(infcx, param_env, source_trait_ref, target_impl)
-                .unwrap_or_else(|_| {
+                .unwrap_or_else(|_|
                     bug!("When translating substitutions for specialization, the expected \
                           specialization failed to hold")
-                })
+                )
         }
         specialization_graph::Node::Trait(..) => source_trait_ref.substs,
     };
@@ -137,17 +137,15 @@ pub fn find_associated_item<'a, 'tcx>(
                 let substs = translate_substs(&infcx, param_env, impl_data.impl_def_id,
                                               substs, node_item.node);
                 let substs = infcx.tcx.erase_regions(&substs);
-                tcx.lift(&substs).unwrap_or_else(|| {
+                tcx.lift(&substs).unwrap_or_else(||
                     bug!("find_method: translate_substs \
                           returned {:?} which contains inference types/regions",
-                         substs);
-                })
+                         substs)
+                )
             });
             (node_item.item.def_id, substs)
         }
-        None => {
-            bug!("{:?} not found in {:?}", item, impl_data.impl_def_id)
-        }
+        None => bug!("{:?} not found in {:?}", item, impl_data.impl_def_id)
     }
 }
 
@@ -312,8 +310,7 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx
                                                       -> Lrc<specialization_graph::Graph> {
     let mut sg = specialization_graph::Graph::new();
 
-    let mut trait_impls = Vec::new();
-    tcx.for_each_impl(trait_id, |impl_did| trait_impls.push(impl_did));
+    let mut trait_impls = tcx.all_impls(trait_id);
 
     // The coherence checking implementation seems to rely on impls being
     // iterated over (roughly) in definition order, so we are sorting by
@@ -367,9 +364,9 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx
                                        "first implementation here".to_string());
                         err.span_label(impl_span,
                                        format!("conflicting implementation{}",
-                                                overlap.self_desc
-                                                    .map_or(String::new(),
-                                                            |ty| format!(" for `{}`", ty))));
+                                               overlap.self_desc
+                                                      .map_or(String::new(),
+                                                          |ty| format!(" for `{}`", ty))));
                     }
                     Err(cname) => {
                         let msg = match to_pretty_impl_header(tcx, overlap.with_impl) {
@@ -428,7 +425,9 @@ fn to_pretty_impl_header(tcx: TyCtxt, impl_def_id: DefId) -> Option<String> {
     // The predicates will contain default bounds like `T: Sized`. We need to
     // remove these bounds, and add `T: ?Sized` to any untouched type parameters.
     let predicates = tcx.predicates_of(impl_def_id).predicates;
-    let mut pretty_predicates = Vec::with_capacity(predicates.len());
+    let mut pretty_predicates = Vec::with_capacity(
+        predicates.len() + types_without_default_bounds.len());
+
     for p in predicates {
         if let Some(poly_trait_ref) = p.to_opt_poly_trait_ref() {
             if Some(poly_trait_ref.def_id()) == sized_trait {
@@ -438,9 +437,11 @@ fn to_pretty_impl_header(tcx: TyCtxt, impl_def_id: DefId) -> Option<String> {
         }
         pretty_predicates.push(p.to_string());
     }
+
     pretty_predicates.extend(
         types_without_default_bounds.iter().map(|ty| format!("{}: ?Sized", ty))
     );
+
     if !pretty_predicates.is_empty() {
         write!(w, "\n  where {}", pretty_predicates.join(", ")).unwrap();
     }
index a7652574c1a2e9cb855f20234febb849be7c3d00..756f55545bc45a87090a52085df7588197cbf1a8 100644 (file)
@@ -390,11 +390,12 @@ fn next(&mut self) -> Option<Node> {
         let cur = self.current_source.take();
         if let Some(Node::Impl(cur_impl)) = cur {
             let parent = self.specialization_graph.parent(cur_impl);
-            if parent == self.trait_def_id {
-                self.current_source = Some(Node::Trait(parent));
+
+            self.current_source = if parent == self.trait_def_id {
+                Some(Node::Trait(parent))
             } else {
-                self.current_source = Some(Node::Impl(parent));
-            }
+                Some(Node::Impl(parent))
+            };
         }
         cur
     }
index 10e930d1c92d9a58b3f08632f86b97a27db9aa06..a4230707b70cae5b449760c5812d58bdc5195111 100644 (file)
@@ -166,10 +166,10 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
         match *self {
             super::Unimplemented => Some(super::Unimplemented),
             super::OutputTypeParameterMismatch(a, b, ref err) => {
-                tcx.lift(&(a, b)).and_then(|(a, b)| {
+                tcx.lift(&(a, b)).and_then(|(a, b)|
                     tcx.lift(err)
                         .map(|err| super::OutputTypeParameterMismatch(a, b, err))
-                })
+                )
             }
             super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)),
             super::ConstEvalFailure(ref err) => tcx.lift(&**err).map(|err| super::ConstEvalFailure(
@@ -193,10 +193,10 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
             super::ReferenceOutlivesReferent(ty) => {
                 tcx.lift(&ty).map(super::ReferenceOutlivesReferent)
             }
-            super::ObjectTypeBound(ty, r) => tcx.lift(&ty).and_then(|ty| {
+            super::ObjectTypeBound(ty, r) => tcx.lift(&ty).and_then(|ty|
                 tcx.lift(&r)
-                    .and_then(|r| Some(super::ObjectTypeBound(ty, r)))
-            }),
+                   .and_then(|r| Some(super::ObjectTypeBound(ty, r)))
+            ),
             super::ObjectCastObligation(ty) => tcx.lift(&ty).map(super::ObjectCastObligation),
             super::AssignmentLhsSized => Some(super::AssignmentLhsSized),
             super::TupleInitializerSized => Some(super::TupleInitializerSized),
@@ -245,13 +245,13 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
 impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> {
     type Lifted = traits::DerivedObligationCause<'tcx>;
     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| {
+        tcx.lift(&self.parent_trait_ref).and_then(|trait_ref|
             tcx.lift(&*self.parent_code)
-                .map(|code| traits::DerivedObligationCause {
-                    parent_trait_ref: trait_ref,
-                    parent_code: Rc::new(code),
-                })
-        })
+               .map(|code| traits::DerivedObligationCause {
+                   parent_trait_ref: trait_ref,
+                   parent_code: Rc::new(code),
+               })
+        )
     }
 }
 
@@ -275,40 +275,40 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
                 impl_def_id,
                 substs,
                 nested,
-            }) => tcx.lift(&substs).map(|substs| {
+            }) => tcx.lift(&substs).map(|substs|
                 traits::VtableImpl(traits::VtableImplData {
                     impl_def_id,
                     substs,
                     nested,
                 })
-            }),
+            ),
             traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)),
             traits::VtableGenerator(traits::VtableGeneratorData {
                 generator_def_id,
                 substs,
                 nested,
-            }) => tcx.lift(&substs).map(|substs| {
+            }) => tcx.lift(&substs).map(|substs|
                 traits::VtableGenerator(traits::VtableGeneratorData {
                     generator_def_id: generator_def_id,
                     substs: substs,
                     nested: nested,
                 })
-            }),
+            ),
             traits::VtableClosure(traits::VtableClosureData {
                 closure_def_id,
                 substs,
                 nested,
-            }) => tcx.lift(&substs).map(|substs| {
+            }) => tcx.lift(&substs).map(|substs|
                 traits::VtableClosure(traits::VtableClosureData {
                     closure_def_id,
                     substs,
                     nested,
                 })
-            }),
+            ),
             traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => {
-                tcx.lift(&fn_ty).map(|fn_ty| {
+                tcx.lift(&fn_ty).map(|fn_ty|
                     traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested })
-                })
+                )
             }
             traits::VtableParam(n) => Some(traits::VtableParam(n)),
             traits::VtableBuiltin(n) => Some(traits::VtableBuiltin(n)),
@@ -316,13 +316,13 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
                 upcast_trait_ref,
                 vtable_base,
                 nested,
-            }) => tcx.lift(&upcast_trait_ref).map(|trait_ref| {
+            }) => tcx.lift(&upcast_trait_ref).map(|trait_ref|
                 traits::VtableObject(traits::VtableObjectData {
                     upcast_trait_ref: trait_ref,
                     vtable_base,
                     nested,
                 })
-            }),
+            ),
         }
     }
 }
index 40f13ac06f56fbed1439d69e2df4f9793004bafc..2ca8214daf768cd829550a99e5184a63f4c46a7f 100644 (file)
@@ -346,8 +346,7 @@ fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
                 Some(ty::Predicate::Trait(data)) => {
                     return Some(data.to_poly_trait_ref());
                 }
-                Some(_) => {
-                }
+                Some(_) => {}
             }
         }
     }
index 6332080a1836c427f8308a5a0843c6cd288de1d2..fd3f7a12376d8440724f85d2e21c0b9fbfe0ca8a 100644 (file)
@@ -138,6 +138,15 @@ pub fn for_each_relevant_impl<F: FnMut(DefId)>(self,
             }
         }
     }
+
+    /// Return a vector containing all impls
+    pub fn all_impls(self, def_id: DefId) -> Vec<DefId> {
+        let impls = self.trait_impls_of(def_id);
+
+        impls.blanket_impls.iter().chain(
+            impls.non_blanket_impls.values().flatten()
+        ).cloned().collect()
+    }
 }
 
 // Query provider for `trait_impls_of`.
index 56187c09b4fe8f5fbd83953bd5d4ca85820c9cc0..fb8744e4d96d6ecb1d2685c3ed8ec9dcaad8bf03 100644 (file)
@@ -867,10 +867,20 @@ fn report_bckerr(&self, err: &BckError<'a, 'tcx>) {
                                         }) = cmt.cat {
                                             db.note(fn_closure_msg);
                                         } else {
-                                            db.span_suggestion(sp, msg, suggestion);
+                                            db.span_suggestion_with_applicability(
+                                                sp,
+                                                msg,
+                                                suggestion,
+                                                Applicability::Unspecified,
+                                            );
                                         }
                                     } else {
-                                        db.span_suggestion(sp, msg, suggestion);
+                                        db.span_suggestion_with_applicability(
+                                            sp,
+                                            msg,
+                                            suggestion,
+                                            Applicability::Unspecified,
+                                        );
                                     }
                                 }
                                 _ => {
@@ -1236,10 +1246,16 @@ fn note_immutability_blame(&self,
                         let let_span = self.tcx.hir.span(node_id);
                         let suggestion = suggest_ref_mut(self.tcx, let_span);
                         if let Some(replace_str) = suggestion {
-                            db.span_suggestion(
+                            db.span_suggestion_with_applicability(
                                 let_span,
                                 "use a mutable reference instead",
                                 replace_str,
+                                // I believe this can be machine applicable,
+                                // but if there are multiple attempted uses of an immutable
+                                // reference, I don't know how rustfix handles it, it might
+                                // attempt fixing them multiple times.
+                                //                              @estebank
+                                Applicability::Unspecified,
                             );
                         }
                     }
@@ -1292,11 +1308,12 @@ fn note_immutable_local(&self,
                 )) = ty.map(|t| &t.node)
                 {
                     let borrow_expr_id = self.tcx.hir.get_parent_node(borrowed_node_id);
-                    db.span_suggestion(
+                    db.span_suggestion_with_applicability(
                         self.tcx.hir.span(borrow_expr_id),
                         "consider removing the `&mut`, as it is an \
                         immutable binding to a mutable reference",
-                        snippet
+                        snippet,
+                        Applicability::MachineApplicable,
                     );
                 } else {
                     db.span_suggestion_with_applicability(
@@ -1326,12 +1343,15 @@ fn report_out_of_scope_escaping_closure_capture(&self,
                                                   &cmt_path_or_string,
                                                   capture_span,
                                                   Origin::Ast)
-            .span_suggestion(err.span,
-                             &format!("to force the closure to take ownership of {} \
-                                       (and any other referenced variables), \
-                                       use the `move` keyword",
-                                       cmt_path_or_string),
-                             suggestion)
+            .span_suggestion_with_applicability(
+                 err.span,
+                 &format!("to force the closure to take ownership of {} \
+                           (and any other referenced variables), \
+                           use the `move` keyword",
+                           cmt_path_or_string),
+                 suggestion,
+                 Applicability::MachineApplicable,
+            )
             .emit();
         self.signal_error();
     }
index 95be2d82123a7c619be090ffabb789dbc4973235..c03180c02fe634f5d1c6b5c62a304cd2eb40fcb4 100644 (file)
@@ -1071,6 +1071,10 @@ fn finalize(&mut self) -> Command {
         // Make the default table accessible
         self.cmd.arg("--export-table");
 
+        // Rust code should never have warnings, and warnings are often
+        // indicative of bugs, let's prevent them.
+        self.cmd.arg("--fatal-warnings");
+
         let mut cmd = Command::new("");
         ::std::mem::swap(&mut cmd, &mut self.cmd);
         cmd
index 0221cfd9b2c28c3601eea39627cf22260f52b3e3..706568b544661cadde5156ff0409fa95323f78b5 100644 (file)
@@ -1803,13 +1803,7 @@ pub fn create_vtable_metadata(
         llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
                                                     NO_SCOPE_METADATA,
                                                     name.as_ptr(),
-                                                    // LLVM 3.9
-                                                    // doesn't accept
-                                                    // null here, so
-                                                    // pass the name
-                                                    // as the linkage
-                                                    // name.
-                                                    name.as_ptr(),
+                                                    ptr::null(),
                                                     unknown_file_metadata(cx),
                                                     UNKNOWN_LINE_NUMBER,
                                                     vtable_type,
index 6c2601bf1ef1255ec229b6533da9b8290bbd55dc..a5f4137c62b14e6e30c0bf3d7c91807ed602b243 100644 (file)
@@ -8,16 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// FIXME: Rename 'DIGlobalVariable' to 'DIGlobalVariableExpression'
-// once support for LLVM 3.9 is dropped.
-//
-// This method was changed in this LLVM patch:
-// https://reviews.llvm.org/D26769
-
 use super::debuginfo::{
     DIBuilder, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType,
     DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable,
-    DIGlobalVariable, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator,
+    DIGlobalVariableExpression, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator,
     DINameSpace, DIFlags,
 };
 
@@ -447,7 +441,7 @@ pub mod debuginfo {
     pub type DIDerivedType = DIType;
     pub type DICompositeType = DIDerivedType;
     pub type DIVariable = DIDescriptor;
-    pub type DIGlobalVariable = DIDescriptor;
+    pub type DIGlobalVariableExpression = DIDescriptor;
     pub type DIArray = DIDescriptor;
     pub type DISubrange = DIDescriptor;
     pub type DIEnumerator = DIDescriptor;
@@ -1330,7 +1324,7 @@ pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: &DIBuilder<'a>,
                                                  Val: &'a Value,
                                                  Decl: Option<&'a DIDescriptor>,
                                                  AlignInBits: u32)
-                                                 -> &'a DIGlobalVariable;
+                                                 -> &'a DIGlobalVariableExpression;
 
     pub fn LLVMRustDIBuilderCreateVariable(Builder: &DIBuilder<'a>,
                                            Tag: c_uint,
index 825e31539c8bedfe511056858a3182fc10836e3c..2799f2cc81f5ab0648d078f0d19d6fdc387356ce 100644 (file)
@@ -232,6 +232,7 @@ pub fn span_help<S: Into<MultiSpan>>(&mut self,
     /// inline it will only show the text message and not the text.
     ///
     /// See `CodeSuggestion` for more information.
+    #[deprecated(note = "Use `span_suggestion_short_with_applicability`")]
     pub fn span_suggestion_short(&mut self, sp: Span, msg: &str, suggestion: String) -> &mut Self {
         self.suggestions.push(CodeSuggestion {
             substitutions: vec![Substitution {
@@ -263,6 +264,7 @@ pub fn span_suggestion_short(&mut self, sp: Span, msg: &str, suggestion: String)
     /// * may contain a name of a function, variable or type, but not whole expressions
     ///
     /// See `CodeSuggestion` for more information.
+    #[deprecated(note = "Use `span_suggestion_with_applicability`")]
     pub fn span_suggestion(&mut self, sp: Span, msg: &str, suggestion: String) -> &mut Self {
         self.suggestions.push(CodeSuggestion {
             substitutions: vec![Substitution {
@@ -278,10 +280,11 @@ pub fn span_suggestion(&mut self, sp: Span, msg: &str, suggestion: String) -> &m
         self
     }
 
-    pub fn multipart_suggestion(
+    pub fn multipart_suggestion_with_applicability(
         &mut self,
         msg: &str,
         suggestion: Vec<(Span, String)>,
+        applicability: Applicability,
     ) -> &mut Self {
         self.suggestions.push(CodeSuggestion {
             substitutions: vec![Substitution {
@@ -292,12 +295,26 @@ pub fn multipart_suggestion(
             }],
             msg: msg.to_owned(),
             show_code_when_inline: true,
-            applicability: Applicability::Unspecified,
+            applicability,
         });
         self
     }
 
+    #[deprecated(note = "Use `multipart_suggestion_with_applicability`")]
+    pub fn multipart_suggestion(
+        &mut self,
+        msg: &str,
+        suggestion: Vec<(Span, String)>,
+    ) -> &mut Self {
+        self.multipart_suggestion_with_applicability(
+            msg,
+            suggestion,
+            Applicability::Unspecified,
+        )
+    }
+
     /// Prints out a message with multiple suggested edits of the code.
+    #[deprecated(note = "Use `span_suggestions_with_applicability`")]
     pub fn span_suggestions(&mut self, sp: Span, msg: &str, suggestions: Vec<String>) -> &mut Self {
         self.suggestions.push(CodeSuggestion {
             substitutions: suggestions.into_iter().map(|snippet| Substitution {
index a4b5b000f8776f1d3a8c1b09c835528b8dc1563f..60a68b1e496620a64106ff82659a8a90ebf1867e 100644 (file)
@@ -43,16 +43,18 @@ pub struct DiagnosticBuilder<'a> {
 /// it easy to declare such methods on the builder.
 macro_rules! forward {
     // Forward pattern for &self -> &Self
-    (pub fn $n:ident(&self, $($name:ident: $ty:ty),*) -> &Self) => {
+    (pub fn $n:ident(&self, $($name:ident: $ty:ty),* $(,)*) -> &Self) => {
         pub fn $n(&self, $($name: $ty),*) -> &Self {
+            #[allow(deprecated)]
             self.diagnostic.$n($($name),*);
             self
         }
     };
 
     // Forward pattern for &mut self -> &mut Self
-    (pub fn $n:ident(&mut self, $($name:ident: $ty:ty),*) -> &mut Self) => {
+    (pub fn $n:ident(&mut self, $($name:ident: $ty:ty),* $(,)*) -> &mut Self) => {
         pub fn $n(&mut self, $($name: $ty),*) -> &mut Self {
+            #[allow(deprecated)]
             self.diagnostic.$n($($name),*);
             self
         }
@@ -60,8 +62,12 @@ pub fn $n(&mut self, $($name: $ty),*) -> &mut Self {
 
     // Forward pattern for &mut self -> &mut Self, with S: Into<MultiSpan>
     // type parameter. No obvious way to make this more generic.
-    (pub fn $n:ident<S: Into<MultiSpan>>(&mut self, $($name:ident: $ty:ty),*) -> &mut Self) => {
+    (pub fn $n:ident<S: Into<MultiSpan>>(
+                    &mut self,
+                    $($name:ident: $ty:ty),*
+                    $(,)*) -> &mut Self) => {
         pub fn $n<S: Into<MultiSpan>>(&mut self, $($name: $ty),*) -> &mut Self {
+            #[allow(deprecated)]
             self.diagnostic.$n($($name),*);
             self
         }
@@ -157,49 +163,75 @@ pub fn span_label<T: Into<String>>(&mut self, span: Span, label: T) -> &mut Self
     forward!(pub fn note_expected_found(&mut self,
                                         label: &dyn fmt::Display,
                                         expected: DiagnosticStyledString,
-                                        found: DiagnosticStyledString)
-                                        -> &mut Self);
+                                        found: DiagnosticStyledString,
+                                        -> &mut Self);
 
     forward!(pub fn note_expected_found_extra(&mut self,
                                               label: &dyn fmt::Display,
                                               expected: DiagnosticStyledString,
                                               found: DiagnosticStyledString,
                                               expected_extra: &dyn fmt::Display,
-                                              found_extra: &dyn fmt::Display)
-                                              -> &mut Self);
+                                              found_extra: &dyn fmt::Display,
+                                              -> &mut Self);
 
     forward!(pub fn note(&mut self, msg: &str) -> &mut Self);
     forward!(pub fn span_note<S: Into<MultiSpan>>(&mut self,
                                                   sp: S,
-                                                  msg: &str)
-                                                  -> &mut Self);
+                                                  msg: &str,
+                                                  -> &mut Self);
     forward!(pub fn warn(&mut self, msg: &str) -> &mut Self);
     forward!(pub fn span_warn<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) -> &mut Self);
     forward!(pub fn help(&mut self , msg: &str) -> &mut Self);
     forward!(pub fn span_help<S: Into<MultiSpan>>(&mut self,
                                                   sp: S,
-                                                  msg: &str)
-                                                  -> &mut Self);
-    forward!(pub fn span_suggestion_short(&mut self,
-                                          sp: Span,
-                                          msg: &str,
-                                          suggestion: String)
-                                          -> &mut Self);
+                                                  msg: &str,
+                                                  ) -> &mut Self);
+
+    #[deprecated(note = "Use `span_suggestion_short_with_applicability`")]
+    forward!(pub fn span_suggestion_short(
+                                      &mut self,
+                                      sp: Span,
+                                      msg: &str,
+                                      suggestion: String,
+                                      ) -> &mut Self);
+
+    #[deprecated(note = "Use `multipart_suggestion_with_applicability`")]
     forward!(pub fn multipart_suggestion(
         &mut self,
         msg: &str,
-        suggestion: Vec<(Span, String)>
+        suggestion: Vec<(Span, String)>,
     ) -> &mut Self);
+
+    #[deprecated(note = "Use `span_suggestion_with_applicability`")]
     forward!(pub fn span_suggestion(&mut self,
                                     sp: Span,
                                     msg: &str,
-                                    suggestion: String)
-                                    -> &mut Self);
+                                    suggestion: String,
+                                    ) -> &mut Self);
+
+    #[deprecated(note = "Use `span_suggestions_with_applicability`")]
     forward!(pub fn span_suggestions(&mut self,
                                      sp: Span,
                                      msg: &str,
-                                     suggestions: Vec<String>)
-                                     -> &mut Self);
+                                     suggestions: Vec<String>,
+                                     ) -> &mut Self);
+
+    pub fn multipart_suggestion_with_applicability(&mut self,
+                                              msg: &str,
+                                              suggestion: Vec<(Span, String)>,
+                                              applicability: Applicability,
+                                              ) -> &mut Self {
+        if !self.allow_suggestions {
+            return self
+        }
+        self.diagnostic.multipart_suggestion_with_applicability(
+            msg,
+            suggestion,
+            applicability,
+        );
+        self
+    }
+
     pub fn span_suggestion_with_applicability(&mut self,
                                               sp: Span,
                                               msg: &str,
index 02207c63b34642ae7522391ffdda27ce2039db9b..adff34af61ed8e9bd98a0566409d185849f55408 100644 (file)
@@ -622,7 +622,7 @@ fn extract_one(&mut self,
                         }
                     }
                     Err(err) => {
-                        info!("no metadata found: {}", err);
+                        warn!("no metadata found: {}", err);
                         continue;
                     }
                 };
index fda6b34971625a63cca1c69e1538659c04c7da80..9187cb97e69e52f387e37605ae3df7a00b780aa1 100644 (file)
@@ -584,9 +584,20 @@ fn get_moved_indexes(&mut self, context: Context, mpi: MovePathIndex) -> Vec<Mov
                 // created by `StorageDead` and at the beginning
                 // of a function.
             } else {
+                // If we are found a use of a.b.c which was in error, then we want to look for
+                // moves not only of a.b.c but also a.b and a.
+                //
+                // Note that the moves data already includes "parent" paths, so we don't have to
+                // worry about the other case: that is, if there is a move of a.b.c, it is already
+                // marked as a move of a.b and a as well, so we will generate the correct errors
+                // there.
+                let mut mpis = vec![mpi];
+                let move_paths = &self.move_data.move_paths;
+                mpis.extend(move_paths[mpi].parents(move_paths));
+
                 for moi in &self.move_data.loc_map[l] {
                     debug!("report_use_of_moved_or_uninitialized: moi={:?}", moi);
-                    if self.move_data.moves[*moi].path == mpi {
+                    if mpis.contains(&self.move_data.moves[*moi].path) {
                         debug!("report_use_of_moved_or_uninitialized: found");
                         result.push(*moi);
 
index 290c7032388053f0b1376b35e1d22295e8a4ae58..52d051ebe7ba0cf13ce648519b26b13ef9c0e97c 100644 (file)
@@ -11,7 +11,7 @@
 use core::unicode::property::Pattern_White_Space;
 use rustc::mir::*;
 use rustc::ty;
-use rustc_errors::DiagnosticBuilder;
+use rustc_errors::{DiagnosticBuilder,Applicability};
 use syntax_pos::Span;
 
 use borrow_check::MirBorrowckCtxt;
@@ -350,16 +350,18 @@ fn add_move_hints(
                     // expressions `a[b]`, which roughly desugar to
                     // `*Index::index(&a, b)` or
                     // `*IndexMut::index_mut(&mut a, b)`.
-                    err.span_suggestion(
+                    err.span_suggestion_with_applicability(
                         span,
                         "consider removing the `*`",
                         snippet[1..].to_owned(),
+                        Applicability::Unspecified,
                     );
                 } else {
-                    err.span_suggestion(
+                    err.span_suggestion_with_applicability(
                         span,
                         "consider borrowing here",
                         format!("&{}", snippet),
+                        Applicability::Unspecified,
                     );
                 }
 
@@ -420,10 +422,11 @@ fn add_move_error_suggestions(
         suggestions.sort_unstable_by_key(|&(span, _, _)| span);
         suggestions.dedup_by_key(|&mut (span, _, _)| span);
         for (span, to_remove, suggestion) in suggestions {
-            err.span_suggestion(
+            err.span_suggestion_with_applicability(
                 span,
                 &format!("consider removing the `{}`", to_remove),
-                suggestion
+                suggestion,
+                Applicability::MachineApplicable,
             );
         }
     }
index 78ab772d9ad5b2f3ed5fd9cbd2cbf26d62f53c50..a078aa59a7d5b4bf37624ba5eaa2735d1c69b253 100644 (file)
@@ -22,6 +22,7 @@
 use util::borrowck_errors::{BorrowckErrors, Origin};
 use util::collect_writes::FindAssignments;
 use util::suggest_ref_mut;
+use rustc_errors::Applicability;
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub(super) enum AccessKind {
@@ -227,10 +228,11 @@ pub(super) fn report_mutability_error(
                 assert_eq!(local_decl.mutability, Mutability::Not);
 
                 err.span_label(span, format!("cannot {ACT}", ACT = act));
-                err.span_suggestion(
+                err.span_suggestion_with_applicability(
                     local_decl.source_info.span,
                     "consider changing this to be mutable",
                     format!("mut {}", local_decl.name.unwrap()),
+                    Applicability::MachineApplicable,
                 );
             }
 
@@ -257,10 +259,11 @@ pub(super) fn report_mutability_error(
                         _,
                     ) = pat.node
                     {
-                        err.span_suggestion(
+                        err.span_suggestion_with_applicability(
                             upvar_ident.span,
                             "consider changing this to be mutable",
                             format!("mut {}", upvar_ident.name),
+                            Applicability::MachineApplicable,
                         );
                     }
                 }
@@ -351,10 +354,11 @@ pub(super) fn report_mutability_error(
                 };
 
                 if let Some((err_help_span, suggested_code)) = suggestion {
-                    err.span_suggestion(
+                    err.span_suggestion_with_applicability(
                         err_help_span,
                         &format!("consider changing this to be a mutable {}", pointer_desc),
                         suggested_code,
+                        Applicability::MachineApplicable,
                     );
                 }
 
index 7d7da6c96e8699fe3976836d544b743d783d6f77..58a2b9361032e579ac3767cf5ecab10ab11762ee 100644 (file)
@@ -97,6 +97,20 @@ pub struct MovePath<'tcx> {
     pub place: Place<'tcx>,
 }
 
+impl<'tcx> MovePath<'tcx> {
+    pub fn parents(&self, move_paths: &IndexVec<MovePathIndex, MovePath>) -> Vec<MovePathIndex> {
+        let mut parents = Vec::new();
+
+        let mut curr_parent = self.parent;
+        while let Some(parent_mpi) = curr_parent {
+            parents.push(parent_mpi);
+            curr_parent = move_paths[parent_mpi].parent;
+        }
+
+        parents
+    }
+}
+
 impl<'tcx> fmt::Debug for MovePath<'tcx> {
     fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
         write!(w, "MovePath {{")?;
index e3f7f26f53efda786f55b8045ed9015dca092228..0f03aa097c9dfdb64ff8e0fef412f01e8a566fed 100644 (file)
@@ -316,7 +316,10 @@ pub fn mplace_field(
         };
 
         let ptr = base.ptr.ptr_offset(offset, self)?;
-        let align = base.align.min(field_layout.align); // only use static information
+        let align = base.align
+            // We do not look at `base.layout.align` nor `field_layout.align`, unlike
+            // codegen -- mostly to see if we can get away with that
+            .restrict_for_offset(offset); // must be last thing that happens
 
         Ok(MPlaceTy { mplace: MemPlace { ptr, align, extra }, layout: field_layout })
     }
index 2ee5415018f934ece32799bb45f132a1139caac5..f6ace57f5e0fb52b36a93ac795cdc23426f2a53a 100644 (file)
@@ -182,8 +182,9 @@ fn while_if_let_ambiguity(&self, expr: &P<Expr>) {
             );
 
             if let Ok(snippet) = self.session.source_map().span_to_snippet(span) {
-                err.span_suggestion(
+                err.span_suggestion_with_applicability(
                     span, "consider adding parentheses", format!("({})", snippet),
+                    Applicability::MachineApplicable,
                 );
             }
 
index 61c2ac161bb08096d35fa7d930246940f0436d34..a87e86aee0cf0d395c8b87503d1903096c7f0d84 100644 (file)
@@ -16,6 +16,7 @@
 use rustc::hir::{self, Node, Destination};
 use syntax::ast;
 use syntax_pos::Span;
+use errors::Applicability;
 
 #[derive(Clone, Copy, Debug, PartialEq)]
 enum LoopKind {
@@ -140,11 +141,16 @@ fn visit_expr(&mut self, e: &'hir hir::Expr) {
                                 .span_label(e.span,
                                             "can only break with a value inside \
                                             `loop` or breakable block")
-                                .span_suggestion(e.span,
-                                                 &format!("instead, use `break` on its own \
-                                                           without a value inside this `{}` loop",
-                                                          kind.name()),
-                                                 "break".to_string())
+                                .span_suggestion_with_applicability(
+                                    e.span,
+                                    &format!(
+                                        "instead, use `break` on its own \
+                                        without a value inside this `{}` loop",
+                                        kind.name()
+                                    ),
+                                    "break".to_string(),
+                                    Applicability::MaybeIncorrect,
+                                )
                                 .emit();
                         }
                     }
index 3f9c15209578c04b227187c00b256d061315ed99..343ef067a6ce86aac59e251bb1e3dd7d58dd8ec8 100644 (file)
@@ -3292,9 +3292,12 @@ fn type_ascription_suggestion(&self,
                         err.span_label(base_span,
                                        "expecting a type here because of type ascription");
                         if line_sp != line_base_sp {
-                            err.span_suggestion_short(sp,
-                                                      "did you mean to use `;` here instead?",
-                                                      ";".to_string());
+                            err.span_suggestion_short_with_applicability(
+                                sp,
+                                "did you mean to use `;` here instead?",
+                                ";".to_string(),
+                                Applicability::MaybeIncorrect,
+                            );
                         }
                         break;
                     } else if snippet.trim().len() != 0  {
@@ -4818,7 +4821,12 @@ fn show_candidates(err: &mut DiagnosticBuilder,
             *candidate = format!("use {};\n{}", candidate, additional_newline);
         }
 
-        err.span_suggestions(span, &msg, path_strings);
+        err.span_suggestions_with_applicability(
+            span,
+            &msg,
+            path_strings,
+            Applicability::Unspecified,
+        );
     } else {
         let mut msg = msg;
         msg.push(':');
index 8747f239d3418885b9bbc3f1b1a2e1f0212a9d53..c71ad5ff21da03a885500ff0897cb48f4c8955d7 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use spec::{LinkerFlavor, Target, TargetResult, PanicStrategy, LldFlavor};
+use spec::{LinkerFlavor, Target, TargetResult, PanicStrategy};
 
 pub fn target() -> TargetResult {
     let mut base = super::windows_msvc_base::opts();
@@ -17,7 +17,6 @@ pub fn target() -> TargetResult {
 
     // FIXME: this shouldn't be panic=abort, it should be panic=unwind
     base.panic_strategy = PanicStrategy::Abort;
-    base.linker = Some("rust-lld".to_owned());
 
     Ok(Target {
         llvm_target: "aarch64-pc-windows-msvc".to_string(),
@@ -29,7 +28,7 @@ pub fn target() -> TargetResult {
         target_os: "windows".to_string(),
         target_env: "msvc".to_string(),
         target_vendor: "pc".to_string(),
-        linker_flavor: LinkerFlavor::Lld(LldFlavor::Link),
+        linker_flavor: LinkerFlavor::Msvc,
         options: base,
     })
 }
index ebe0c279aafab51304754c3b7b21b9499169d52e..85641854e6e2d1d7275f9f12aa110c9b9791692c 100644 (file)
@@ -40,7 +40,7 @@
 
 use super::FnCtxt;
 
-use errors::DiagnosticBuilder;
+use errors::{DiagnosticBuilder,Applicability};
 use hir::def_id::DefId;
 use lint;
 use rustc::hir;
@@ -299,9 +299,12 @@ fn report_cast_error(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, e: CastError) {
                 err.note("The type information given here is insufficient to check whether \
                           the pointer cast is valid");
                 if unknown_cast_to {
-                    err.span_suggestion_short(self.cast_span,
-                                              "consider giving more type information",
-                                              String::new());
+                    err.span_suggestion_short_with_applicability(
+                        self.cast_span,
+                        "consider giving more type information",
+                        String::new(),
+                        Applicability::Unspecified,
+                    );
                 }
                 err.emit();
             }
@@ -327,9 +330,12 @@ fn report_cast_to_unsized_type(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
                 if self.cast_ty.is_trait() {
                     match fcx.tcx.sess.source_map().span_to_snippet(self.cast_span) {
                         Ok(s) => {
-                            err.span_suggestion(self.cast_span,
-                                                "try casting to a reference instead",
-                                                format!("&{}{}", mtstr, s));
+                            err.span_suggestion_with_applicability(
+                                self.cast_span,
+                                "try casting to a reference instead",
+                                format!("&{}{}", mtstr, s),
+                                Applicability::MachineApplicable,
+                            );
                         }
                         Err(_) => {
                             span_help!(err, self.cast_span, "did you mean `&{}{}`?", mtstr, tstr)
@@ -346,9 +352,12 @@ fn report_cast_to_unsized_type(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
             ty::Adt(def, ..) if def.is_box() => {
                 match fcx.tcx.sess.source_map().span_to_snippet(self.cast_span) {
                     Ok(s) => {
-                        err.span_suggestion(self.cast_span,
-                                            "try casting to a `Box` instead",
-                                            format!("Box<{}>", s));
+                        err.span_suggestion_with_applicability(
+                            self.cast_span,
+                            "try casting to a `Box` instead",
+                            format!("Box<{}>", s),
+                            Applicability::MachineApplicable,
+                        );
                     }
                     Err(_) => span_help!(err, self.cast_span, "did you mean `Box<{}>`?", tstr),
                 }
index a283e032e0e023a11654a66d81575c0300a236bf..f2c20238734e63b2f54ff89be711a240e8679c06 100644 (file)
@@ -504,7 +504,7 @@ fn sig_of_closure_with_mismatched_number_of_arguments(
             .sig
             .inputs()
             .iter()
-            .map(|ty| ArgKind::from_expected_ty(ty))
+            .map(|ty| ArgKind::from_expected_ty(ty, None))
             .collect();
         let (closure_span, found_args) = self.get_fn_like_arguments(expr_map_node);
         let expected_span = expected_sig.cause_span.unwrap_or(closure_span);
index 9aa2ba363ed7ab41870188de93b2d8bf101ab303..a192068d28f202c5fa4f321d83f0e455cfdc9836 100644 (file)
@@ -16,6 +16,7 @@
 use rustc::ty::error::{ExpectedFound, TypeError};
 use rustc::ty::subst::{Subst, Substs};
 use rustc::util::common::ErrorReported;
+use errors::Applicability;
 
 use syntax_pos::Span;
 
@@ -321,10 +322,11 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 if let Some(trait_err_span) = trait_err_span {
                     if let Ok(trait_err_str) = tcx.sess.source_map().
                                                span_to_snippet(trait_err_span) {
-                        diag.span_suggestion(
+                        diag.span_suggestion_with_applicability(
                             impl_err_span,
                             "consider change the type to match the mutability in trait",
                             format!("{}", trait_err_str),
+                            Applicability::MachineApplicable,
                         );
                     }
                 }
@@ -799,7 +801,7 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             .span_to_snippet(trait_m.generics.span)
                             .ok()?;
 
-                        err.multipart_suggestion(
+                        err.multipart_suggestion_with_applicability(
                             "try changing the `impl Trait` argument to a generic parameter",
                             vec![
                                 // replace `impl Trait` with `T`
@@ -809,6 +811,7 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                 // of the generics, but it works for the common case
                                 (generics_span, new_generics),
                             ],
+                            Applicability::MaybeIncorrect,
                         );
                         Some(())
                     })();
@@ -870,7 +873,7 @@ fn nested_visit_map<'this>(
                             .span_to_snippet(bounds)
                             .ok()?;
 
-                        err.multipart_suggestion(
+                        err.multipart_suggestion_with_applicability(
                             "try removing the generic parameter and using `impl Trait` instead",
                             vec![
                                 // delete generic parameters
@@ -878,6 +881,7 @@ fn nested_visit_map<'this>(
                                 // replace param usage with `impl Trait`
                                 (span, format!("impl {}", bounds)),
                             ],
+                            Applicability::MaybeIncorrect,
                         );
                         Some(())
                     })();
index e78cd4891a5ea99fa4004b55a02b508b29c74a9e..ee19574dc4e95b2a9308291b9b625dd37a7c491b 100644 (file)
@@ -132,9 +132,12 @@ pub fn demand_coerce_diag(&self,
                 let expr_text = print::to_string(print::NO_ANN, |s| s.print_expr(expr));
                 let suggestions = compatible_variants.iter()
                     .map(|v| format!("{}({})", v, expr_text)).collect::<Vec<_>>();
-                err.span_suggestions(expr.span,
-                                     "try using a variant of the expected type",
-                                     suggestions);
+                err.span_suggestions_with_applicability(
+                     expr.span,
+                     "try using a variant of the expected type",
+                     suggestions,
+                     Applicability::MaybeIncorrect,
+                );
             }
         }
 
index 85a437283fa681e66c18de97c7cb2d5f959f958d..499daccf5e80f101e20e294c60979ed028502219 100644 (file)
@@ -1064,7 +1064,8 @@ fn emit_unstable_name_collision_hint(
             "a method with this name may be added to the standard library in the future",
         );
 
-        // FIXME: This should be a `span_suggestion` instead of `help`. However `self.span` only
+        // FIXME: This should be a `span_suggestion_with_applicability` instead of `help`
+        // However `self.span` only
         // highlights the method name, so we can't use it. Also consider reusing the code from
         // `report_method_error()`.
         diag.help(&format!(
index abc32ed2ea0433d2576dac7fd5e86d0f2f0f029e..fe5128a695845fb65555dc0260858de620667729 100644 (file)
@@ -251,13 +251,16 @@ pub fn report_method_error(&self,
                                 let snippet = tcx.sess.source_map().span_to_snippet(lit.span)
                                     .unwrap_or("<numeric literal>".to_string());
 
-                                err.span_suggestion(lit.span,
+                                err.span_suggestion_with_applicability(
+                                                    lit.span,
                                                     &format!("you must specify a concrete type for \
                                                               this numeric value, like `{}`",
                                                              concrete_type),
                                                     format!("{}_{}",
                                                             snippet,
-                                                            concrete_type));
+                                                            concrete_type),
+                                                    Applicability::MaybeIncorrect,
+                                );
                             }
                             hir::ExprKind::Path(ref qpath) => {  // local binding
                                 if let &hir::QPath::Resolved(_, ref path) = &qpath {
@@ -281,13 +284,14 @@ pub fn report_method_error(&self,
                                                 ty,
                                                 ..
                                             })) => {
-                                                err.span_suggestion(
+                                                err.span_suggestion_with_applicability(
                                                     // account for `let x: _ = 42;`
                                                     //                  ^^^^
                                                     span.to(ty.as_ref().map(|ty| ty.span)
                                                         .unwrap_or(span)),
                                                     &msg,
                                                     format!("{}: {}", snippet, concrete_type),
+                                                    Applicability::MaybeIncorrect,
                                                 );
                                             }
                                             _ => {
@@ -516,7 +520,12 @@ fn suggest_use_candidates(&self,
                 format!("use {};\n{}", self.tcx.item_path_str(*did), additional_newline)
             }).collect();
 
-            err.span_suggestions(span, &msg, path_strings);
+            err.span_suggestions_with_applicability(
+                                                    span,
+                                                    &msg,
+                                                    path_strings,
+                                                    Applicability::MaybeIncorrect,
+            );
         } else {
             let limit = if candidates.len() == 5 { 5 } else { 4 };
             for (i, trait_did) in candidates.iter().take(limit).enumerate() {
index db0c4fdb03ae61e20829b3f1695184496106cbe2..0dc7bc75c3d40673be192692c7fac144c19dfe6e 100644 (file)
@@ -3347,11 +3347,34 @@ fn check_field(&self,
                                 }
                             };
                     }
+                    ty::Array(_, len) => {
+                        if let (Some(len), Ok(user_index)) = (
+                            len.assert_usize(self.tcx),
+                            field.as_str().parse::<u64>()
+                        ) {
+                            let base = self.tcx.hir.node_to_pretty_string(base.id);
+                            let help = "instead of using tuple indexing, use array indexing";
+                            let suggestion = format!("{}[{}]", base, field);
+                            let applicability = if len < user_index {
+                                Applicability::MachineApplicable
+                            } else {
+                                Applicability::MaybeIncorrect
+                            };
+                            err.span_suggestion_with_applicability(
+                                expr.span, help, suggestion, applicability
+                            );
+                        }
+                    }
                     ty::RawPtr(..) => {
                         let base = self.tcx.hir.node_to_pretty_string(base.id);
                         let msg = format!("`{}` is a native pointer; try dereferencing it", base);
                         let suggestion = format!("(*{}).{}", base, field);
-                        err.span_suggestion(field.span, &msg, suggestion);
+                        err.span_suggestion_with_applicability(
+                            field.span,
+                            &msg,
+                            suggestion,
+                            Applicability::MaybeIncorrect,
+                        );
                     }
                     _ => {}
                 }
@@ -4719,7 +4742,12 @@ pub fn suggest_ref_or_into(
         found: Ty<'tcx>,
     ) {
         if let Some((sp, msg, suggestion)) = self.check_ref(expr, found, expected) {
-            err.span_suggestion(sp, msg, suggestion);
+            err.span_suggestion_with_applicability(
+                sp,
+                msg,
+                suggestion,
+                Applicability::MachineApplicable,
+            );
         } else if !self.check_for_cast(err, expr, found, expected) {
             let methods = self.get_conversion_methods(expr.span, expected, found);
             if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
@@ -4749,7 +4777,12 @@ pub fn suggest_ref_or_into(
                         }
                     }) .collect::<Vec<_>>();
                 if !suggestions.is_empty() {
-                    err.span_suggestions(expr.span, "try using a conversion method", suggestions);
+                    err.span_suggestions_with_applicability(
+                        expr.span,
+                        "try using a conversion method",
+                        suggestions,
+                        Applicability::MaybeIncorrect,
+                    );
                 }
             }
         }
index 5004880ce47b8bb1967176633a8600a43c4e9e9b..5969f288d732070ade1260148782dce99c3897fb 100644 (file)
@@ -16,7 +16,7 @@
 use rustc::ty::TyKind::{Ref, Adt, Str, Uint, Never, Tuple, Char, Array};
 use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc::infer::type_variable::TypeVariableOrigin;
-use errors;
+use errors::{self,Applicability};
 use syntax_pos::Span;
 use syntax::ast::Ident;
 use rustc::hir;
@@ -444,9 +444,12 @@ fn check_str_addition(
                     err.span_label(expr.span,
                                    "`+` can't be used to concatenate two `&str` strings");
                     match source_map.span_to_snippet(lhs_expr.span) {
-                        Ok(lstring) => err.span_suggestion(lhs_expr.span,
-                                                           msg,
-                                                           format!("{}.to_owned()", lstring)),
+                        Ok(lstring) => err.span_suggestion_with_applicability(
+                            lhs_expr.span,
+                            msg,
+                            format!("{}.to_owned()", lstring),
+                            Applicability::MachineApplicable,
+                        ),
                         _ => err.help(msg),
                     };
                 }
@@ -462,10 +465,14 @@ fn check_str_addition(
                     is_assign,
                 ) {
                     (Ok(l), Ok(r), false) => {
-                        err.multipart_suggestion(msg, vec![
-                            (lhs_expr.span, format!("{}.to_owned()", l)),
-                            (rhs_expr.span, format!("&{}", r)),
-                        ]);
+                        err.multipart_suggestion_with_applicability(
+                            msg,
+                            vec![
+                                (lhs_expr.span, format!("{}.to_owned()", l)),
+                                (rhs_expr.span, format!("&{}", r)),
+                            ],
+                            Applicability::MachineApplicable,
+                        );
                     }
                     _ => {
                         err.help(msg);
index 3b07a2ccdde09379e8e10fd706d8db6b733f80ca..8a9ca924ee1ab997e06c3f74c55890c3a7553ec5 100644 (file)
@@ -775,7 +775,7 @@ fn main() {
 assert_eq!(2+2, 4);
 }".to_string();
         let output = make_test(input, None, false, &opts);
-        assert_eq!(output, (expected.clone(), 2));
+        assert_eq!(output, (expected, 2));
     }
 
     #[test]
@@ -973,7 +973,7 @@ fn main() {
 assert_eq!(2+2, 4);
 }".to_string();
         let output = make_test(input, None, false, &opts);
-        assert_eq!(output, (expected.clone(), 2));
+        assert_eq!(output, (expected, 2));
     }
 
     #[test]
@@ -988,7 +988,7 @@ fn make_test_dont_insert_main() {
 //Ceci n'est pas une `fn main`
 assert_eq!(2+2, 4);".to_string();
         let output = make_test(input, None, true, &opts);
-        assert_eq!(output, (expected.clone(), 1));
+        assert_eq!(output, (expected, 1));
     }
 
     #[test]
@@ -1003,6 +1003,6 @@ fn make_test_display_warnings() {
 assert_eq!(2+2, 4);
 }".to_string();
         let output = make_test(input, None, false, &opts);
-        assert_eq!(output, (expected.clone(), 1));
+        assert_eq!(output, (expected, 1));
     }
 }
index 87ac2091cad41f44a5523370273b24fce39b7029..64fc14d42d9b77f0884c5a4749bb336ca0c237e1 100644 (file)
@@ -74,46 +74,19 @@ pub unsafe fn tanhf(n: f32) -> f32 {
     f64::tanh(n as f64) as f32
 }
 
-// Right now all these functions, the f64 version of the functions above, all
-// shell out to random names. These names aren't actually defined anywhere, per
-// se, but we need this to compile somehow.
-//
-// The idea with this is that when you're using wasm then, for now, we have no
-// way of providing an implementation of these which delegates to a "correct"
-// implementation. For example most wasm applications probably just want to
-// delegate to the javascript `Math` object and its related functions, but wasm
-// doesn't currently have the ability to seamlessly do that (when you
-// instantiate a module you have to set that up).
-//
-// As a result these are just defined here with "hopefully helpful" names. The
-// symbols won't ever be needed or show up unless these functions are called,
-// and hopefully when they're called the errors are self-explanatory enough to
-// figure out what's going on.
-
+// These symbols are all defined in `compiler-builtins`
 extern {
-    #[link_name = "Math_acos"]
     pub fn acos(n: f64) -> f64;
-    #[link_name = "Math_asin"]
     pub fn asin(n: f64) -> f64;
-    #[link_name = "Math_atan"]
     pub fn atan(n: f64) -> f64;
-    #[link_name = "Math_atan2"]
     pub fn atan2(a: f64, b: f64) -> f64;
-    #[link_name = "Math_cbrt"]
     pub fn cbrt(n: f64) -> f64;
-    #[link_name = "Math_cosh"]
     pub fn cosh(n: f64) -> f64;
-    #[link_name = "Math_expm1"]
     pub fn expm1(n: f64) -> f64;
     pub fn fdim(a: f64, b: f64) -> f64;
-    #[link_name = "Math_log1p"]
     pub fn log1p(n: f64) -> f64;
-    #[link_name = "Math_sinh"]
     pub fn sinh(n: f64) -> f64;
-    #[link_name = "Math_tan"]
     pub fn tan(n: f64) -> f64;
-    #[link_name = "Math_tanh"]
     pub fn tanh(n: f64) -> f64;
-    #[link_name = "Math_hypot"]
     pub fn hypot(x: f64, y: f64) -> f64;
 }
index a7c7dbb1b402762b9c59fae8304070a51ce823cb..3987ae83866e5c472fe6cebb13f1730c4e7d3768 100644 (file)
@@ -800,7 +800,14 @@ pub fn park() {
     match thread.inner.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {
         Ok(_) => {}
         Err(NOTIFIED) => {
-            thread.inner.state.store(EMPTY, SeqCst);
+            // We must read here, even though we know it will be `NOTIFIED`.
+            // This is because `unpark` may have been called again since we read
+            // `NOTIFIED` in the `compare_exchange` above. We must perform an
+            // acquire operation that synchronizes with that `unpark` to observe
+            // any writes it made before the call to unpark. To do that we must
+            // read from the write it made to `state`.
+            let old = thread.inner.state.swap(EMPTY, SeqCst);
+            assert_eq!(old, NOTIFIED, "park state changed unexpectedly");
             return;
         } // should consume this notification, so prohibit spurious wakeups in next park.
         Err(_) => panic!("inconsistent park state"),
@@ -889,7 +896,9 @@ pub fn park_timeout(dur: Duration) {
     match thread.inner.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {
         Ok(_) => {}
         Err(NOTIFIED) => {
-            thread.inner.state.store(EMPTY, SeqCst);
+            // We must read again here, see `park`.
+            let old = thread.inner.state.swap(EMPTY, SeqCst);
+            assert_eq!(old, NOTIFIED, "park state changed unexpectedly");
             return;
         } // should consume this notification, so prohibit spurious wakeups in next park.
         Err(_) => panic!("inconsistent park_timeout state"),
@@ -1058,23 +1067,22 @@ pub(crate) fn new(name: Option<String>) -> Thread {
     /// [park]: fn.park.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn unpark(&self) {
-        loop {
-            match self.inner.state.compare_exchange(EMPTY, NOTIFIED, SeqCst, SeqCst) {
-                Ok(_) => return, // no one was waiting
-                Err(NOTIFIED) => return, // already unparked
-                Err(PARKED) => {} // gotta go wake someone up
-                _ => panic!("inconsistent state in unpark"),
-            }
-
-            // Coordinate wakeup through the mutex and a condvar notification
-            let _lock = self.inner.lock.lock().unwrap();
-            match self.inner.state.compare_exchange(PARKED, NOTIFIED, SeqCst, SeqCst) {
-                Ok(_) => return self.inner.cvar.notify_one(),
-                Err(NOTIFIED) => return, // a different thread unparked
-                Err(EMPTY) => {} // parked thread went away, try again
-                _ => panic!("inconsistent state in unpark"),
-            }
+        // To ensure the unparked thread will observe any writes we made
+        // before this call, we must perform a release operation that `park`
+        // can synchronize with. To do that we must write `NOTIFIED` even if
+        // `state` is already `NOTIFIED`. That is why this must be a swap
+        // rather than a compare-and-swap that returns if it reads `NOTIFIED`
+        // on failure.
+        match self.inner.state.swap(NOTIFIED, SeqCst) {
+            EMPTY => return, // no one was waiting
+            NOTIFIED => return, // already unparked
+            PARKED => {} // gotta go wake someone up
+            _ => panic!("inconsistent state in unpark"),
         }
+
+        // Coordinate wakeup through the mutex and a condvar notification
+        let _lock = self.inner.lock.lock().unwrap();
+        self.inner.cvar.notify_one()
     }
 
     /// Gets the thread's unique identifier.
index 63b70b1224840a6afb70c42754e0bec111d7feda..5d978b6b9e6623789db80d537d430b5ecda880fd 100644 (file)
@@ -16,6 +16,7 @@
 use edition::Edition;
 use parse::{token, ParseSess};
 use OneVector;
+use errors::Applicability;
 
 use ptr::P;
 
@@ -123,7 +124,12 @@ pub fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool {
             let error = |span, msg, suggestion: &str| {
                 let mut err = self.sess.span_diagnostic.struct_span_err(span, msg);
                 if !suggestion.is_empty() {
-                    err.span_suggestion(span, "expected syntax is", suggestion.into());
+                    err.span_suggestion_with_applicability(
+                        span,
+                        "expected syntax is",
+                        suggestion.into(),
+                        Applicability::MaybeIncorrect,
+                    );
                 }
                 err.emit();
                 true
index 86247745c4116b6eedb3d1cdda9f38aadf05fca0..214bc9cffc4836ece1530718ef2c5730aa9a659e 100644 (file)
@@ -32,6 +32,7 @@
 use std::collections::hash_map::Entry;
 
 use rustc_data_structures::sync::Lrc;
+use errors::Applicability;
 
 pub struct ParserAnyMacro<'a> {
     parser: Parser<'a>,
@@ -187,10 +188,11 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt,
                     if comma_span == DUMMY_SP {
                         err.note("you might be missing a comma");
                     } else {
-                        err.span_suggestion_short(
+                        err.span_suggestion_short_with_applicability(
                             comma_span,
                             "missing comma here",
                             ", ".to_string(),
+                            Applicability::MachineApplicable,
                         );
                     }
                 }
index 48e034b117f187857dc3334c4b8cbece92b75aaf..6ec1ad969ee708de179210966587bbf46c6bc006 100644 (file)
@@ -3882,7 +3882,12 @@ fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<source_map::Spanned<ast::Fiel
                 if self.token == token::CloseDelim(token::Brace) {
                     // If the struct looks otherwise well formed, recover and continue.
                     if let Some(sp) = comma_sp {
-                        err.span_suggestion_short(sp, "remove this comma", String::new());
+                        err.span_suggestion_short_with_applicability(
+                            sp,
+                            "remove this comma",
+                            String::new(),
+                            Applicability::MachineApplicable,
+                        );
                     }
                     err.emit();
                     break;
index efe9c2cefdebe93b3e1e4f646e2b2093061ae5b3..31e608de1f840d282eb777af314db5b3acfe097f 100644 (file)
@@ -996,9 +996,10 @@ macro_rules! check_foreign {
                         ));
                     }
                     if suggestions.len() > 0 {
-                        diag.multipart_suggestion(
+                        diag.multipart_suggestion_with_applicability(
                             "format specifiers use curly braces",
                             suggestions,
+                            Applicability::MachineApplicable,
                         );
                     }
                 }};
index 5a081f0363340dd895d0958955d0c84661f60f05..caddcd9b9dc9479a20908d93c3e47c49b021379e 160000 (submodule)
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit 5a081f0363340dd895d0958955d0c84661f60f05
+Subproject commit caddcd9b9dc9479a20908d93c3e47c49b021379e
index 29b7d508f1c1e5aa0f3bf53f02a7cc4ec1f6fc72..f8ff3d37fd23e6b657a9920f23f786bdb241ff73 100644 (file)
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be (optionally) cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2018-09-11
+2018-09-16
diff --git a/src/test/ui/issues/issue-53712.rs b/src/test/ui/issues/issue-53712.rs
new file mode 100644 (file)
index 0000000..2353904
--- /dev/null
@@ -0,0 +1,9 @@
+// issue #53712: make the error generated by using tuple indexing on an array more specific
+
+fn main() {
+    let arr = [10, 20, 30, 40, 50];
+    arr.0;
+    //~^ ERROR no field `0` on type `[{integer}; 5]` [E0609]
+    //~| HELP instead of using tuple indexing, use array indexing
+    //~| SUGGESTION arr[0]
+}
diff --git a/src/test/ui/issues/issue-53712.stderr b/src/test/ui/issues/issue-53712.stderr
new file mode 100644 (file)
index 0000000..db85919
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0609]: no field `0` on type `[{integer}; 5]`
+  --> $DIR/issue-53712.rs:5:9
+   |
+LL |     arr.0;
+   |     ----^
+   |     |
+   |     help: instead of using tuple indexing, use array indexing: `arr[0]`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0609`.
diff --git a/src/test/ui/nll/issue-52669.rs b/src/test/ui/nll/issue-52669.rs
new file mode 100644 (file)
index 0000000..17a5999
--- /dev/null
@@ -0,0 +1,28 @@
+// 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(nll)]
+
+struct A {
+    b: B,
+}
+
+#[derive(Clone)]
+struct B;
+
+fn foo(_: A) {}
+
+fn bar(mut a: A) -> B {
+    a.b = B;
+    foo(a);
+    a.b.clone()
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/issue-52669.stderr b/src/test/ui/nll/issue-52669.stderr
new file mode 100644 (file)
index 0000000..ca1576f
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0382]: borrow of moved value: `a.b`
+  --> $DIR/issue-52669.rs:25:5
+   |
+LL |     foo(a);
+   |         - value moved here
+LL |     a.b.clone()
+   |     ^^^ value borrowed here after move
+   |
+   = note: move occurs because `a` has type `A`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/nll/move-subpaths-moves-root.rs b/src/test/ui/nll/move-subpaths-moves-root.rs
new file mode 100644 (file)
index 0000000..7a4e518
--- /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(nll)]
+
+fn main() {
+    let x = (vec![1, 2, 3], );
+    drop(x.0);
+    drop(x);
+}
diff --git a/src/test/ui/nll/move-subpaths-moves-root.stderr b/src/test/ui/nll/move-subpaths-moves-root.stderr
new file mode 100644 (file)
index 0000000..76a1279
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0382]: use of moved value: `x`
+  --> $DIR/move-subpaths-moves-root.rs:16:10
+   |
+LL |     drop(x.0);
+   |          --- value moved here
+LL |     drop(x);
+   |          ^ value used here after move
+   |
+   = note: move occurs because `x.0` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.