]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #49609 - abonander:attr-macro-stmt-expr, r=petrochenkov
authorkennytm <kennytm@gmail.com>
Wed, 4 Apr 2018 09:07:25 +0000 (11:07 +0200)
committerGitHub <noreply@github.com>
Wed, 4 Apr 2018 09:07:25 +0000 (11:07 +0200)
run-pass/attr-stmt-expr: expand test cases

Follow-up to https://github.com/rust-lang/rust/pull/49124#discussion_r178542587

r? @petrochenkov

127 files changed:
.travis.yml
appveyor.yml
src/Cargo.lock
src/bootstrap/bootstrap.py
src/bootstrap/builder.rs
src/bootstrap/channel.rs
src/bootstrap/compile.rs
src/bootstrap/config.rs
src/build_helper/Cargo.toml
src/build_helper/lib.rs
src/ci/docker/dist-various-1/Dockerfile
src/ci/docker/run.sh
src/ci/docker/scripts/sccache.sh
src/doc/rustdoc/src/unstable-features.md
src/doc/unstable-book/src/library-features/splice.md [deleted file]
src/grammar/parser-lalr.y
src/liballoc/arc.rs
src/liballoc/binary_heap.rs
src/liballoc/borrow.rs
src/liballoc/boxed.rs
src/liballoc/btree/node.rs
src/liballoc/lib.rs
src/liballoc/linked_list.rs
src/liballoc/raw_vec.rs
src/liballoc/rc.rs
src/liballoc/string.rs
src/liballoc/tests/binary_heap.rs
src/liballoc/tests/lib.rs
src/liballoc/tests/string.rs
src/liballoc/tests/vec.rs
src/liballoc/tests/vec_deque.rs
src/liballoc/vec.rs
src/liballoc/vec_deque.rs
src/liballoc_jemalloc/lib.rs
src/liballoc_system/lib.rs
src/libcore/clone.rs
src/libcore/heap.rs
src/libcore/iter/iterator.rs
src/libcore/iter/traits.rs
src/libcore/ops/drop.rs
src/libcore/ops/mod.rs
src/libcore/ops/place.rs [deleted file]
src/libcore/tests/iter.rs
src/libcore/tests/lib.rs
src/libproc_macro/lib.rs
src/librustc/cfg/construct.rs
src/librustc/hir/lowering.rs
src/librustc/ich/impls_syntax.rs
src/librustc/ich/impls_ty.rs
src/librustc/middle/stability.rs
src/librustc/ty/adjustment.rs
src/librustc/util/common.rs
src/librustc_data_structures/indexed_set.rs
src/librustc_driver/lib.rs
src/librustc_lint/unused.rs
src/librustc_mir/build/matches/test.rs
src/librustc_mir/build/mod.rs
src/librustc_mir/dataflow/impls/mod.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/lib.rs
src/librustc_typeck/check/callee.rs
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/demand.rs
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/op.rs
src/librustc_typeck/diagnostics.rs
src/librustdoc/clean/mod.rs
src/librustdoc/core.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/themes/dark.css
src/librustdoc/lib.rs
src/librustdoc/markdown.rs
src/librustdoc/test.rs
src/libstd/collections/hash/map.rs
src/libstd/collections/hash/table.rs
src/libstd/fs.rs
src/libstd/io/buffered.rs
src/libstd/lib.rs
src/libstd/net/ip.rs
src/libstd/process.rs
src/libstd/rt.rs
src/libstd/sys/cloudabi/thread.rs
src/libstd/sys/redox/thread.rs
src/libstd/sys/unix/thread.rs
src/libstd/sys/wasm/thread.rs
src/libstd/sys/windows/thread.rs
src/libstd/sys_common/thread_info.rs
src/libsyntax/ast.rs
src/libsyntax/edition.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/util/parser.rs
src/libsyntax/visit.rs
src/libsyntax_pos/hygiene.rs
src/rustc/rustc.rs
src/test/compile-fail-fulldeps/proc-macro/auxiliary/attributes-included.rs
src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs
src/test/compile-fail/deprecation-lint.rs
src/test/compile-fail/issue-14084.rs [deleted file]
src/test/compile-fail/move-guard-same-consts.rs [new file with mode: 0644]
src/test/compile-fail/placement-expr-unsafe.rs [deleted file]
src/test/compile-fail/placement-expr-unstable.rs [deleted file]
src/test/parse-fail/assoc-oddities-1.rs
src/test/pretty/stmt_expr_attributes.rs
src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs
src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs
src/test/run-pass-fulldeps/proc-macro/auxiliary/negative-token.rs [new file with mode: 0644]
src/test/run-pass-fulldeps/proc-macro/negative-token.rs [new file with mode: 0644]
src/test/run-pass/epoch-gate-feature.rs
src/test/run-pass/move-guard-const.rs [deleted file]
src/test/run-pass/new-box-syntax.rs
src/test/run-pass/placement-in-syntax.rs [deleted file]
src/test/rustdoc/default-trait-method-link.rs [new file with mode: 0644]
src/test/rustdoc/deprecated-future.rs [new file with mode: 0644]
src/test/rustdoc/issue-32556.rs [new file with mode: 0644]
src/test/rustdoc/struct-field.rs [new file with mode: 0644]
src/test/ui/borrowck/two-phase-method-receivers.rs [new file with mode: 0644]
src/test/ui/feature-gate-placement-expr.rs [deleted file]
src/test/ui/feature-gate-placement-expr.stderr [deleted file]
src/tools/clippy
src/tools/linkchecker/main.rs
src/tools/rustdoc/main.rs

index 091a5abdaa21653cd5cb30ce8ee8518b74804f6c..f465ba422817448bcaa8d98efc24c95b5c575a12 100644 (file)
@@ -30,7 +30,6 @@ matrix:
         SRC=.
         DEPLOY_ALT=1
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
-        SCCACHE_ERROR_LOG=/tmp/sccache.log
         MACOSX_DEPLOYMENT_TARGET=10.7
         NO_LLVM_ASSERTIONS=1
         NO_DEBUG_ASSERTIONS=1
@@ -50,7 +49,6 @@ matrix:
         RUST_CONFIGURE_ARGS="--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler"
         SRC=.
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
-        SCCACHE_ERROR_LOG=/tmp/sccache.log
         MACOSX_DEPLOYMENT_TARGET=10.8
         MACOSX_STD_DEPLOYMENT_TARGET=10.7
         NO_LLVM_ASSERTIONS=1
@@ -64,7 +62,6 @@ matrix:
         RUST_CONFIGURE_ARGS=--build=i686-apple-darwin
         SRC=.
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
-        SCCACHE_ERROR_LOG=/tmp/sccache.log
         MACOSX_DEPLOYMENT_TARGET=10.8
         MACOSX_STD_DEPLOYMENT_TARGET=10.7
         NO_LLVM_ASSERTIONS=1
@@ -85,7 +82,6 @@ matrix:
         SRC=.
         DEPLOY=1
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
-        SCCACHE_ERROR_LOG=/tmp/sccache.log
         MACOSX_DEPLOYMENT_TARGET=10.7
         NO_LLVM_ASSERTIONS=1
         NO_DEBUG_ASSERTIONS=1
@@ -99,7 +95,6 @@ matrix:
         SRC=.
         DEPLOY=1
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
-        SCCACHE_ERROR_LOG=/tmp/sccache.log
         MACOSX_DEPLOYMENT_TARGET=10.7
         NO_LLVM_ASSERTIONS=1
         NO_DEBUG_ASSERTIONS=1
@@ -227,7 +222,7 @@ install:
             travis_retry brew update &&
             travis_retry brew install xz;
           fi &&
-          travis_retry curl -fo /usr/local/bin/sccache https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2017-05-12-sccache-x86_64-apple-darwin &&
+          travis_retry curl -fo /usr/local/bin/sccache https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2018-04-02-sccache-x86_64-apple-darwin &&
             chmod +x /usr/local/bin/sccache &&
           travis_retry curl -fo /usr/local/bin/stamp https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2017-03-17-stamp-x86_64-apple-darwin &&
             chmod +x /usr/local/bin/stamp
@@ -268,12 +263,6 @@ after_failure:
       df -h;
       du . | sort -nr | head -n100
 
-  # One of these is the linux sccache log, one is the OSX sccache log. Instead
-  # of worrying about what system we are just cat both. One of these commands
-  # will fail but that's ok, they'll both get executed.
-  - cat obj/tmp/sccache.log
-  - cat /tmp/sccache.log
-
   # Random attempt at debugging currently. Just poking around in here to see if
   # anything shows up.
   - ls -lat $HOME/Library/Logs/DiagnosticReports/
index 54c15f662e13ee1b421aa86c9f25b0ff5f21a63d..09c6fca5d02afc8f3f46bf8b4ea46eb5c9f2a958 100644 (file)
@@ -152,8 +152,8 @@ install:
   - set PATH=C:\Python27;%PATH%
 
   # Download and install sccache
-  - appveyor-retry appveyor DownloadFile https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2017-05-12-sccache-x86_64-pc-windows-msvc
-  - mv 2017-05-12-sccache-x86_64-pc-windows-msvc sccache.exe
+  - appveyor-retry appveyor DownloadFile https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2018-04-02-sccache-x86_64-pc-windows-msvc
+  - mv 2018-04-02-sccache-x86_64-pc-windows-msvc sccache.exe
   - set PATH=%PATH%;%CD%
 
   # Download and install ninja
@@ -176,9 +176,6 @@ install:
   - set PATH=%PATH%;%CD%\handle
   - handle.exe -accepteula -help
 
-  # Attempt to debug sccache failures
-  - set SCCACHE_ERROR_LOG=%CD%/sccache.log
-
 test_script:
   - if not exist C:\cache\rustsrc\NUL mkdir C:\cache\rustsrc
   - sh src/ci/init_repo.sh . /c/cache/rustsrc
@@ -186,9 +183,6 @@ test_script:
   - set NO_CCACHE=1
   - sh src/ci/run.sh
 
-on_failure:
-  - cat %CD%\sccache.log || exit 0
-
 branches:
   only:
     - auto
index 1f7cf84cedbdaad30ee8954cbc95d237fe6c3914..e4c16b92ceba546d3ce17f9e64c8660b588cf1fd 100644 (file)
@@ -120,12 +120,12 @@ dependencies = [
  "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -144,21 +144,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 name = "build-manifest"
 version = "0.1.0"
 dependencies = [
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "build_helper"
 version = "0.1.0"
-dependencies = [
- "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
-]
 
 [[package]]
 name = "byteorder"
-version = "1.2.1"
+version = "1.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -195,11 +192,11 @@ dependencies = [
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -213,20 +210,20 @@ name = "cargo_metadata"
 version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cargo_metadata"
-version = "0.5.3"
+version = "0.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -246,10 +243,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "chrono"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -270,18 +268,18 @@ dependencies = [
 
 [[package]]
 name = "clippy"
-version = "0.0.189"
+version = "0.0.191"
 dependencies = [
- "cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "clippy-mini-macro-test 0.2.0",
- "clippy_lints 0.0.189",
- "compiletest_rs 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clippy_lints 0.0.191",
+ "compiletest_rs 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "derive-new 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -291,17 +289,37 @@ version = "0.2.0"
 [[package]]
 name = "clippy_lints"
 version = "0.0.189"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "clippy_lints"
+version = "0.0.191"
 dependencies = [
  "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex-syntax 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -346,32 +364,32 @@ dependencies = [
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "compiletest_rs"
-version = "0.3.8"
+version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempfile 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -409,8 +427,8 @@ version = "0.16.0"
 dependencies = [
  "curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -425,19 +443,19 @@ name = "crossbeam-deque"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "crossbeam-epoch 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "crossbeam-epoch"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -497,12 +515,12 @@ version = "0.1.0"
 
 [[package]]
 name = "derive-new"
-version = "0.5.1"
+version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -525,7 +543,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "either"
-version = "1.4.0"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -673,12 +691,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "futures"
-version = "0.1.17"
+version = "0.1.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "getopts"
-version = "0.2.15"
+version = "0.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -729,15 +747,16 @@ version = "0.0.0"
 
 [[package]]
 name = "handlebars"
-version = "0.29.1"
+version = "0.32.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pest_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -816,7 +835,7 @@ dependencies = [
  "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -830,10 +849,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "itertools"
-version = "0.7.6"
+version = "0.7.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -853,7 +872,7 @@ dependencies = [
 
 [[package]]
 name = "json"
-version = "0.11.12"
+version = "0.11.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -861,10 +880,10 @@ name = "jsonrpc-core"
 version = "8.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -883,8 +902,8 @@ version = "0.31.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1001,23 +1020,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "mdbook"
-version = "0.1.2"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "handlebars 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1060,9 +1079,9 @@ dependencies = [
 name = "miri"
 version = "0.1.0"
 dependencies = [
- "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiletest_rs 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiletest_rs 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1073,7 +1092,7 @@ version = "0.1.0"
 
 [[package]]
 name = "nibble_vec"
-version = "0.0.3"
+version = "0.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1081,16 +1100,6 @@ name = "nodrop"
 version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "num"
-version = "0.1.42"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "num-integer"
 version = "0.1.36"
@@ -1099,15 +1108,6 @@ dependencies = [
  "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "num-iter"
-version = "0.1.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "num-traits"
 version = "0.1.43"
@@ -1190,7 +1190,7 @@ dependencies = [
 
 [[package]]
 name = "parking_lot"
-version = "0.5.3"
+version = "0.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1215,9 +1215,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "pest"
-version = "0.3.3"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "pest_derive"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "pkg-config"
 version = "0.3.9"
@@ -1231,6 +1241,14 @@ dependencies = [
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "proc-macro2"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "proc_macro"
 version = "0.0.0"
@@ -1255,7 +1273,7 @@ version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1281,6 +1299,14 @@ dependencies = [
  "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "quote"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "racer"
 version = "2.0.13"
@@ -1297,11 +1323,11 @@ dependencies = [
 
 [[package]]
 name = "radix_trie"
-version = "0.1.2"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "endian-type 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "nibble_vec 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nibble_vec 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1316,10 +1342,10 @@ dependencies = [
 
 [[package]]
 name = "rayon"
-version = "1.0.0"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1397,27 +1423,27 @@ name = "rls"
 version = "0.126.0"
 dependencies = [
  "cargo 0.27.0",
- "cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "clippy_lints 0.0.189",
+ "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clippy_lints 0.0.189 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "languageserver-types 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "racer 2.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-analysis 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "rls-blacklist 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rls-blacklist 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-data 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-rustc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustfmt-nightly 0.4.1",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1427,9 +1453,9 @@ name = "rls-analysis"
 version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "derive-new 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "radix_trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "radix_trie 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-data 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1437,7 +1463,7 @@ dependencies = [
 
 [[package]]
 name = "rls-blacklist"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1447,8 +1473,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1462,8 +1488,8 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1480,7 +1506,7 @@ name = "rustbook"
 version = "0.1.0"
 dependencies = [
  "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "mdbook 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mdbook 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1490,7 +1516,7 @@ dependencies = [
  "arena 0.0.0",
  "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fmt_macros 0.0.0",
  "graphviz 0.0.0",
@@ -1526,7 +1552,7 @@ dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-serialize 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1674,7 +1700,7 @@ dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
  "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1795,7 +1821,7 @@ version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1999,19 +2025,19 @@ dependencies = [
 name = "rustfmt-nightly"
 version = "0.4.1"
 dependencies = [
- "cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "derive-new 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-syntax 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2052,7 +2078,7 @@ version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2062,27 +2088,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde"
-version = "1.0.35"
+version = "1.0.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde_derive"
-version = "1.0.35"
+version = "1.0.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive_internals 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_derive_internals"
-version = "0.22.1"
+version = "0.23.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2090,7 +2116,7 @@ name = "serde_ignored"
 version = "0.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2101,7 +2127,7 @@ dependencies = [
  "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2110,7 +2136,7 @@ version = "0.0.0"
 
 [[package]]
 name = "shell-escape"
-version = "0.1.3"
+version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -2185,7 +2211,7 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "0.12.14"
+version = "0.12.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2193,6 +2219,16 @@ dependencies = [
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "syn"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "synom"
 version = "0.11.3"
@@ -2332,7 +2368,7 @@ name = "term"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2358,7 +2394,7 @@ dependencies = [
 name = "test"
 version = "0.0.0"
 dependencies = [
- "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.0.0",
 ]
 
@@ -2383,8 +2419,8 @@ dependencies = [
 name = "tidy"
 version = "0.1.0"
 dependencies = [
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2411,7 +2447,7 @@ name = "toml"
 version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2508,7 +2544,7 @@ name = "url_serde"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2624,30 +2660,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
 "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
 "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32"
-"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
+"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87"
 "checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b"
-"checksum cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5caae26de3704081ef638f87f05a6891b04f2b7d5ce9429a3de21095528ae22"
+"checksum cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebd6272a2ca4fd39dbabbd6611eb03df45c2259b3b80b39a9ff8fbdcf42a4b3"
 "checksum cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc"
 "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
-"checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9"
+"checksum chrono 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ba5f60682a4c264e7f8d77b82e7788938a76befdf949d4a98026d19099c9d873"
 "checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
+"checksum clippy_lints 0.0.189 (registry+https://github.com/rust-lang/crates.io-index)" = "fef652630bbf8c5e89601220abd000f5057e8fa9db608484b5ebaad98e9bce53"
 "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb"
 "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007"
 "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2"
-"checksum compiletest_rs 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "d47ca9a69772587159e1c7e20ee1e43dfe5f184d59591eac70e7d3603bdfe57a"
+"checksum compiletest_rs 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "608d9d3ccc45b63bf337d2ff5e65def5a5a52c187122232509f6b72707f61b1b"
 "checksum core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980"
 "checksum core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa"
 "checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
 "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
-"checksum crossbeam-epoch 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "59796cc6cbbdc6bb319161349db0c3250ec73ec7fcb763a51065ec4e2e158552"
+"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
 "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
 "checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4"
 "checksum curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b70fd6394677d3c0e239ff4be6f2b3176e171ffd1c23ffdc541e78dea2b8bb5e"
 "checksum curl-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f46e49c7125131f5afaded06944d6888b55cbdf8eba05dae73c954019b907961"
-"checksum derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "92f8b8e1d6c8a5f5ea0849a0e4c55941576115c62d3fc425e96918bbbeb3d3c2"
+"checksum derive-new 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6fcb923bab47a948f1b01cec2f758fdebba95c9ebc255458654b2b88efe59d71"
 "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
-"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3"
+"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
 "checksum ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8b449f3b18c89d2dbe40548d2ee4fa58ea0a08b761992da6ecb9788e4688834"
 "checksum endian-type 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
 "checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180"
@@ -2663,13 +2700,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
 "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
-"checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1"
-"checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9"
+"checksum futures 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5a3176836efa0b37f0e321b86672dfada1564aeb516fbed67b7c24050a0263"
+"checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05"
 "checksum git2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f41c0035c37ec11ed3f1e1946a76070b0c740393687e9a9c7612f6a709036b3"
 "checksum git2-curl 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b502f6b1b467957403d168f0039e0c46fa6a1220efa2adaef25d5b267b5fe024"
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
 "checksum globset 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e96ab92362c06811385ae9a34d2698e8a1160745e0c78fbb434a44c8de3fabc"
-"checksum handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04af2006ea09d985fef82b81e0eb25337e51b691c76403332378a53d521edc"
+"checksum handlebars 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07af2ff31f66f39a5c8b8b8a5dc02734a453110146763e3a2323f4931a915a76"
 "checksum hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "459d3cf58137bb02ad4adeef5036377ff59f066dbb82517b7192e3a5462a2abc"
 "checksum home 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8f94f6fbdc000a6eba0c8cf08632b2091bb59141d36ac321a2a96d6365e5e4dc"
 "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
@@ -2677,10 +2714,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8"
 "checksum ignore 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "245bea0ba52531a3739cb8ba99f8689eda13d7faf8c36b6a73ce4421aab42588"
 "checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053"
-"checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394"
+"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
 "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682"
 "checksum jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "60af5f849e1981434e4a31d3d782c4774ae9b434ce55b101a96ecfd09147e8be"
-"checksum json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)" = "39ebf0fac977ee3a4a3242b6446004ff64514889e3e2730bbd4f764a67a2e483"
+"checksum json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9ad0485404155f45cce53a40d4b2d6ac356418300daed05273d9e26f91c390be"
 "checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
 "checksum languageserver-types 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d25086d59f44b80253d5ff96c66a692fb69de8485cf7a25b28677e89126de0d"
@@ -2696,16 +2733,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3d382732ea0fbc09790c4899db3255bdea0fc78b54bf234bd18a63bb603915b6"
 "checksum lzma-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c1b93b78f89e8737dac81837fc8f5521ac162abcba902e1a3db949d55346d1da"
 "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
-"checksum mdbook 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fef236caad7ba3b5b3944df946f19ab3e190bca53c111dd00fe05fa8d879f2fd"
+"checksum mdbook 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "326d0861da5681a13c19a00952a56c254dd04f00eb944e506fdb36e93ae6f1ca"
 "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
 "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
 "checksum miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9224c91f82b3c47cf53dcf78dfaa20d6888fbcc5d272d5f2fcdf8a697f3c987d"
-"checksum nibble_vec 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "62e678237a4c70c5f2b917cefd7d080dfbf800421f06e8a59d4e28ef5130fd9e"
+"checksum nibble_vec 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c8d77f3db4bce033f4d04db08079b2ef1c3d02b44e86f25d08886fafa7756ffa"
 "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
-"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
 "checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe"
-"checksum num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "4b226df12c5a59b63569dd57fafb926d91b385dfce33d8074a412411b689d593"
 "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
 "checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364"
 "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
@@ -2714,21 +2749,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
 "checksum openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdc5c4a02e69ce65046f1763a0181107038e02176233acb0b3351d7cc588f9"
 "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
-"checksum parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e7f7c9857874e54afeb950eebeae662b1e51a2493666d2ea4c0a5d91dcf0412"
+"checksum parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd9d732f2de194336fb02fe11f9eed13d9e76f13f4315b4d88a14ca411750cd"
 "checksum parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "538ef00b7317875071d5e00f603f24d16f0b474c1a5fc0ccb8b454ca72eafa79"
 "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
-"checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8"
+"checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc"
+"checksum pest_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ab94faafeb93f4c5e3ce81ca0e5a779529a602ad5d09ae6d21996bfb8b6a52bf"
 "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
 "checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0"
+"checksum proc-macro2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "388d7ea47318c5ccdeb9ba6312cee7d3f65dd2804be8580a170fce410d50b786"
 "checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
 "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4"
 "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
 "checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408"
+"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"
 "checksum racer 2.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "40d44bc30fc8d403b665286b2c9a83466ddbf69297668fb02b785c3e58eb8e0d"
-"checksum radix_trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "211c49b6a9995cac0fd1dd9ca60b42cf3a51e151a12eb954b3a9e75513426ee8"
+"checksum radix_trie 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "03d0d770481e8af620ca61d3d304bf014f965d7f78e923dc58545e6a545070a9"
 "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
-"checksum rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "485541959c8ecc49865526fe6c4de9653dd6e60d829d6edf0be228167b60372d"
+"checksum rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e811e76f1dbf68abf87a759083d34600017fc4e10b6bd5ad84a700f9dba4b1"
 "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
 "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
@@ -2736,7 +2774,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum regex-syntax 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b2550876c31dc914696a6c2e01cbce8afba79a93c8ae979d2fe051c0230b3756"
 "checksum remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfc5b3ce5d5ea144bb04ebd093a9e14e9765bcfec866aecda9b6dec43b3d1e24"
 "checksum rls-analysis 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4b9a3a3f2345854e39768e6425d1c893855da217183d1c0b3ff6f1664b6b6d"
-"checksum rls-blacklist 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56fb7b8e4850b988fbcf277fbdb1eff36879070d02fc1ca243b559273866973d"
+"checksum rls-blacklist 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "156cee9c1750b2e97d404dd0506c4780b7a2d615164f49874013807fb3cbfe5e"
 "checksum rls-data 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bea04462e94b5512a78499837eecb7db182ff082144cd1b4bc32ef5d43de6510"
 "checksum rls-rustc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "885f66b92757420572cbb02e033d4a9558c7413ca9b7ac206f28fd58ffdb44ea"
 "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a"
@@ -2755,19 +2793,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
 "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-"checksum serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "800fdb0a894572994f3970035a8a5f65d8ec2cd40e6cdf7d8cd9001d7b30648e"
-"checksum serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "90f1f8f7784452461db5b73dc5097c18f21011fbcc6d1178f1897bfa8e1cb4bd"
-"checksum serde_derive_internals 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f9525ada08124ee1a9b8b1e6f3bf035ffff6fc0c96d56ddda98d4506d3533e4"
+"checksum serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "d3bcee660dcde8f52c3765dd9ca5ee36b4bf35470a738eb0bd5a8752b0389645"
+"checksum serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "f1711ab8b208541fa8de00425f6a577d90f27bb60724d2bb5fd911314af9668f"
+"checksum serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "89b340a48245bc03ddba31d0ff1709c118df90edc6adabaca4aac77aea181cce"
 "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142"
 "checksum serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5c508584d9913df116b91505eec55610a2f5b16e9ed793c46e4d0152872b3e74"
-"checksum shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5cc96481d54583947bfe88bf30c23d53f883c6cd0145368b69989d97b84ef8"
+"checksum shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9"
 "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
 "checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
 "checksum socket2 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "71ebbe82fcdd697244ba7fe6e05e63b5c45910c3927e28469a04947494ff48d8"
 "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
 "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
-"checksum syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8c5bc2d6ff27891209efa5f63e9de78648d7801f085e4653701a692ce938d6fd"
+"checksum syn 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c97c05b8ebc34ddd6b967994d5c6e9852fa92f8b82b3858c39451f97346dcce5"
+"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
 "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
 "checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd"
 "checksum syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e52bffe6202cfb67587784cf23e0ec5bf26d331eef4922a16d5c42e12aa1e9b"
index b55a133501d8eefc126966df971bd848c830179b..eeac4436e6454f984edf3fe860d73989efffa1ac 100644 (file)
@@ -647,7 +647,7 @@ class RustBuild(object):
         if (not os.path.exists(os.path.join(self.rust_root, ".git"))) or \
                 self.get_toml('submodules') == "false":
             return
-        slow_submodules = self.get_toml('fast-submodule') == "false"
+        slow_submodules = self.get_toml('fast-submodules') == "false"
         start_time = time()
         if slow_submodules:
             print('Unconditionally updating all submodules')
index eb23236638b13047942fb30fac78730003c515b4..0464840c3e8187c89d195a47a1902bd446aa2ff1 100644 (file)
@@ -555,7 +555,9 @@ pub fn cargo(&self,
         let mut extra_args = env::var(&format!("RUSTFLAGS_STAGE_{}", stage)).unwrap_or_default();
         if stage != 0 {
             let s = env::var("RUSTFLAGS_STAGE_NOT_0").unwrap_or_default();
-            extra_args.push_str(" ");
+            if !extra_args.is_empty() {
+                extra_args.push_str(" ");
+            }
             extra_args.push_str(&s);
         }
 
index 72841cb0616c148db52831f38718c50e97e7af6d..3453933a9652c0881188919706c5db4799ab43e2 100644 (file)
@@ -24,7 +24,7 @@
 use config::Config;
 
 // The version number
-pub const CFG_RELEASE_NUM: &str = "1.26.0";
+pub const CFG_RELEASE_NUM: &str = "1.27.0";
 
 pub struct GitInfo {
     inner: Option<Info>,
index 9f33935b6e933834225aa250b408b2ecdc5e6561..e6aa78fba52ffd21209eef963e3cde30fdad6a72 100644 (file)
@@ -1120,7 +1120,7 @@ pub fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path, is_check: boo
     let max = max.unwrap();
     let max_path = max_path.unwrap();
     if stamp_contents == new_contents && max <= stamp_mtime {
-        build.verbose(&format!("not updating {:?}; contents equal and {} <= {}",
+        build.verbose(&format!("not updating {:?}; contents equal and {:?} <= {:?}",
                 stamp, max, stamp_mtime));
         return deps
     }
index 3ef4b0f8ae7ac0bf0d9c32f4c48f4340860f0806..33850debd3bdbff0056a5482642e2217a34dc08f 100644 (file)
@@ -45,6 +45,7 @@ pub struct Config {
     pub ninja: bool,
     pub verbose: usize,
     pub submodules: bool,
+    pub fast_submodules: bool,
     pub compiler_docs: bool,
     pub docs: bool,
     pub locked_deps: bool,
@@ -191,6 +192,7 @@ struct Build {
     compiler_docs: Option<bool>,
     docs: Option<bool>,
     submodules: Option<bool>,
+    fast_submodules: Option<bool>,
     gdb: Option<String>,
     locked_deps: Option<bool>,
     vendor: Option<bool>,
@@ -328,6 +330,7 @@ pub fn parse(args: &[String]) -> Config {
         config.rust_optimize = true;
         config.rust_optimize_tests = true;
         config.submodules = true;
+        config.fast_submodules = true;
         config.docs = true;
         config.rust_rpath = true;
         config.channel = "dev".to_string();
@@ -404,6 +407,7 @@ pub fn parse(args: &[String]) -> Config {
         set(&mut config.compiler_docs, build.compiler_docs);
         set(&mut config.docs, build.docs);
         set(&mut config.submodules, build.submodules);
+        set(&mut config.fast_submodules, build.fast_submodules);
         set(&mut config.locked_deps, build.locked_deps);
         set(&mut config.vendor, build.vendor);
         set(&mut config.full_bootstrap, build.full_bootstrap);
index f8ade0616a577a44f7bb0c970d855a99f3b58937..01d704f816bbc8fc00813d2636f3fe44a847db35 100644 (file)
@@ -6,6 +6,3 @@ authors = ["The Rust Project Developers"]
 [lib]
 name = "build_helper"
 path = "lib.rs"
-
-[dependencies]
-filetime = "0.1"
index 363bbd795442251c295a45cbfcfa998c4966bb1f..5a12afd03e13b820c891aec362d9b6f3c5683f70 100644 (file)
 
 #![deny(warnings)]
 
-extern crate filetime;
-
 use std::fs::File;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 use std::{fs, env};
-
-use filetime::FileTime;
+use std::time::{SystemTime, UNIX_EPOCH};
 
 /// A helper macro to `unwrap` a result except also print out details like:
 ///
@@ -137,10 +134,8 @@ pub fn rerun_if_changed_anything_in_dir(dir: &Path) {
 }
 
 /// Returns the last-modified time for `path`, or zero if it doesn't exist.
-pub fn mtime(path: &Path) -> FileTime {
-    fs::metadata(path).map(|f| {
-        FileTime::from_last_modification_time(&f)
-    }).unwrap_or(FileTime::zero())
+pub fn mtime(path: &Path) -> SystemTime {
+    fs::metadata(path).and_then(|f| f.modified()).unwrap_or(UNIX_EPOCH)
 }
 
 /// Returns whether `dst` is up to date given that the file or files in `src`
@@ -157,9 +152,9 @@ pub fn up_to_date(src: &Path, dst: &Path) -> bool {
         Err(e) => panic!("source {:?} failed to get metadata: {}", src, e),
     };
     if meta.is_dir() {
-        dir_up_to_date(src, &threshold)
+        dir_up_to_date(src, threshold)
     } else {
-        FileTime::from_last_modification_time(&meta) <= threshold
+        meta.modified().unwrap_or(UNIX_EPOCH) <= threshold
     }
 }
 
@@ -226,13 +221,13 @@ pub fn sanitizer_lib_boilerplate(sanitizer_name: &str) -> Result<NativeLibBoiler
                            search_path)
 }
 
-fn dir_up_to_date(src: &Path, threshold: &FileTime) -> bool {
+fn dir_up_to_date(src: &Path, threshold: SystemTime) -> bool {
     t!(fs::read_dir(src)).map(|e| t!(e)).all(|e| {
         let meta = t!(e.metadata());
         if meta.is_dir() {
             dir_up_to_date(&e.path(), threshold)
         } else {
-            FileTime::from_last_modification_time(&meta) < *threshold
+            meta.modified().unwrap_or(UNIX_EPOCH) < threshold
         }
     })
 }
index b398e9a3c92ef8dce5e5fced67cc12114a6f484c..1b6ee44d87afca025e01d26d8df660ac063061ca 100644 (file)
@@ -66,6 +66,14 @@ RUN env \
     bash musl.sh mipsel && \
     rm -rf /build/*
 
+# FIXME(mozilla/sccache#235) this shouldn't be necessary but is currently
+# necessary to disambiguate the mips compiler with the mipsel compiler. We want
+# to give these two wrapper scripts (currently identical ones) different hashes
+# to ensure that sccache understands that they're different compilers.
+RUN \
+  echo "# a" >> /usr/local/mips-linux-musl/bin/mips-openwrt-linux-musl-wrapper.sh && \
+  echo "# b" >> /usr/local/mipsel-linux-musl/bin/mipsel-openwrt-linux-musl-wrapper.sh
+
 ENV TARGETS=asmjs-unknown-emscripten
 ENV TARGETS=$TARGETS,wasm32-unknown-emscripten
 ENV TARGETS=$TARGETS,x86_64-rumprun-netbsd
index 2946cf7fc503fe314898f2f045321fb25cec4cf6..ea2387b67dbccf9379b5c017e383ef6f61b9c296 100755 (executable)
@@ -104,8 +104,6 @@ if [ "$SCCACHE_BUCKET" != "" ]; then
     args="$args --env SCCACHE_REGION"
     args="$args --env AWS_ACCESS_KEY_ID"
     args="$args --env AWS_SECRET_ACCESS_KEY"
-    args="$args --env SCCACHE_ERROR_LOG=/tmp/sccache/sccache.log"
-    args="$args --volume $objdir/tmp:/tmp/sccache"
 else
     mkdir -p $HOME/.cache/sccache
     args="$args --env SCCACHE_DIR=/sccache --volume $HOME/.cache/sccache:/sccache"
index ce2d45563f7b53d81d89766e5c6b9060eab59fe5..da52d08318115eb80a7cc39bb3ffde8e8439dad3 100644 (file)
@@ -13,6 +13,6 @@
 set -ex
 
 curl -fo /usr/local/bin/sccache \
-  https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl
+  https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2018-04-02-sccache-x86_64-unknown-linux-musl
 
 chmod +x /usr/local/bin/sccache
index 44b9145a8c2e58314913355e800b102816c02194..bf97fb4686180f981f7c9e4983606f9910455f1b 100644 (file)
@@ -348,6 +348,19 @@ details.
 
 [issue-display-warnings]: https://github.com/rust-lang/rust/issues/41574
 
+### `--edition`: control the edition of docs and doctests
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc src/lib.rs -Z unstable-options --edition 2018
+$ rustdoc --test src/lib.rs -Z unstable-options --edition 2018
+```
+
+This flag allows rustdoc to treat your rust code as the given edition. It will compile doctests with
+the given edition as well. As with `rustc`, the default edition that `rustdoc` will use is `2015`
+(the first edition).
+
 ### `-Z force-unstable-if-unmarked`
 
 Using this flag looks like this:
diff --git a/src/doc/unstable-book/src/library-features/splice.md b/src/doc/unstable-book/src/library-features/splice.md
deleted file mode 100644 (file)
index 2e4bb1a..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# `splice`
-
-The tracking issue for this feature is: [#44643]
-
-[#44643]: https://github.com/rust-lang/rust/issues/44643
-
-------------------------
-
-The `splice()` method on `String` allows you to replace a range
-of values in a string with another range of values.
-
-A simple example:
-
-```rust
-#![feature(splice)]
-let mut s = String::from("α is alpha, β is beta");
-let beta_offset = s.find('β').unwrap_or(s.len());
-
-// Replace the range up until the β from the string
-s.splice(..beta_offset, "Α is capital alpha; ");
-assert_eq!(s, "Α is capital alpha; β is beta");
-```
index de1f96aac504653db2d440a8426ea623143abc29..a7da69f65faf2b3532cdc6537cff92a167a139ac 100644 (file)
@@ -1400,7 +1400,6 @@ nonblock_expr
 | BREAK lifetime                                                { $$ = mk_node("ExprBreak", 1, $2); }
 | YIELD                                                         { $$ = mk_node("ExprYield", 0); }
 | YIELD expr                                                    { $$ = mk_node("ExprYield", 1, $2); }
-| nonblock_expr LARROW expr                                     { $$ = mk_node("ExprInPlace", 2, $1, $3); }
 | nonblock_expr '=' expr                                        { $$ = mk_node("ExprAssign", 2, $1, $3); }
 | nonblock_expr SHLEQ expr                                      { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
 | nonblock_expr SHREQ expr                                      { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
@@ -1463,7 +1462,6 @@ expr
 | BREAK ident                                         { $$ = mk_node("ExprBreak", 1, $2); }
 | YIELD                                               { $$ = mk_node("ExprYield", 0); }
 | YIELD expr                                          { $$ = mk_node("ExprYield", 1, $2); }
-| expr LARROW expr                                    { $$ = mk_node("ExprInPlace", 2, $1, $3); }
 | expr '=' expr                                       { $$ = mk_node("ExprAssign", 2, $1, $3); }
 | expr SHLEQ expr                                     { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
 | expr SHREQ expr                                     { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
@@ -1527,7 +1525,6 @@ expr_nostruct
 | BREAK ident                                         { $$ = mk_node("ExprBreak", 1, $2); }
 | YIELD                                               { $$ = mk_node("ExprYield", 0); }
 | YIELD expr                                          { $$ = mk_node("ExprYield", 1, $2); }
-| expr_nostruct LARROW expr_nostruct                  { $$ = mk_node("ExprInPlace", 2, $1, $3); }
 | expr_nostruct '=' expr_nostruct                     { $$ = mk_node("ExprAssign", 2, $1, $3); }
 | expr_nostruct SHLEQ expr_nostruct                   { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
 | expr_nostruct SHREQ expr_nostruct                   { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
index 6a77bf64baee5f9ffe5d9670ad5eab3405abade5..ccf2e2768d1a971d5362e49cd08aa4e67e1e2164 100644 (file)
@@ -21,6 +21,7 @@
 use core::borrow;
 use core::fmt;
 use core::cmp::Ordering;
+use core::heap::{Alloc, Layout};
 use core::intrinsics::abort;
 use core::mem::{self, align_of_val, size_of_val, uninitialized};
 use core::ops::Deref;
@@ -31,7 +32,7 @@
 use core::{isize, usize};
 use core::convert::From;
 
-use heap::{Heap, Alloc, Layout, box_free};
+use heap::{Heap, box_free};
 use boxed::Box;
 use string::String;
 use vec::Vec;
index f6a666b599b0984d0aa54b6f70a03d0ec5dfe650..668b61c51d8bc0f8e3a39e496ecc0c79b2d5ed4e 100644 (file)
 #![allow(missing_docs)]
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::ops::{Deref, DerefMut, Place, Placer, InPlace};
+use core::ops::{Deref, DerefMut};
 use core::iter::{FromIterator, FusedIterator};
 use core::mem::{swap, size_of};
 use core::ptr;
@@ -1195,67 +1195,3 @@ fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
         self.extend(iter.into_iter().cloned());
     }
 }
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-pub struct BinaryHeapPlace<'a, T: 'a>
-where T: Clone + Ord {
-    heap: *mut BinaryHeap<T>,
-    place: vec::PlaceBack<'a, T>,
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, T: Clone + Ord + fmt::Debug> fmt::Debug for BinaryHeapPlace<'a, T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_tuple("BinaryHeapPlace")
-         .field(&self.place)
-         .finish()
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, T: 'a> Placer<T> for &'a mut BinaryHeap<T>
-where T: Clone + Ord {
-    type Place = BinaryHeapPlace<'a, T>;
-
-    fn make_place(self) -> Self::Place {
-        let ptr = self as *mut BinaryHeap<T>;
-        let place = Placer::make_place(self.data.place_back());
-        BinaryHeapPlace {
-            heap: ptr,
-            place,
-        }
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-unsafe impl<'a, T> Place<T> for BinaryHeapPlace<'a, T>
-where T: Clone + Ord {
-    fn pointer(&mut self) -> *mut T {
-        self.place.pointer()
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, T> InPlace<T> for BinaryHeapPlace<'a, T>
-where T: Clone + Ord {
-    type Owner = &'a T;
-
-    unsafe fn finalize(self) -> &'a T {
-        self.place.finalize();
-
-        let heap: &mut BinaryHeap<T> = &mut *self.heap;
-        let len = heap.len();
-        let i = heap.sift_up(0, len - 1);
-        heap.data.get_unchecked(i)
-    }
-}
index acae0daa86b6bd30e30f12ce7f531594c3b7c233..c6741ddb822d5bb9114889bc71fdd2203f72e559 100644 (file)
@@ -59,6 +59,7 @@ pub trait ToOwned {
     /// let vv: Vec<i32> = v.to_owned();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use = "cloning is often expensive and is not expected to have side effects"]
     fn to_owned(&self) -> Self::Owned;
 
     /// Uses borrowed data to replace owned data, usually by cloning.
index fdc3ef4efb866b67c47673675a028fda03f871e5..4f9dc61ce196be1306884c2afca4c9b71cdabe31 100644 (file)
@@ -55,7 +55,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use heap::{Heap, Layout, Alloc};
 use raw_vec::RawVec;
 
 use core::any::Any;
 use core::fmt;
 use core::hash::{Hash, Hasher};
 use core::iter::FusedIterator;
-use core::marker::{self, Unpin, Unsize};
+use core::marker::{Unpin, Unsize};
 use core::mem::{self, Pin};
 use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
-use core::ops::{BoxPlace, Boxed, InPlace, Place, Placer};
 use core::ptr::{self, NonNull, Unique};
 use core::convert::From;
 use str::from_boxed_utf8_unchecked;
 
-/// A value that represents the heap. This is the default place that the `box`
-/// keyword allocates into when no place is supplied.
-///
-/// The following two examples are equivalent:
-///
-/// ```
-/// #![feature(box_heap)]
-///
-/// #![feature(box_syntax, placement_in_syntax)]
-/// use std::boxed::HEAP;
-///
-/// fn main() {
-///     let foo: Box<i32> = in HEAP { 5 };
-///     let foo = box 5;
-/// }
-/// ```
-#[unstable(feature = "box_heap",
-           reason = "may be renamed; uncertain about custom allocator design",
-           issue = "27779")]
-pub const HEAP: ExchangeHeapSingleton = ExchangeHeapSingleton { _force_singleton: () };
-
-/// This the singleton type used solely for `boxed::HEAP`.
-#[unstable(feature = "box_heap",
-           reason = "may be renamed; uncertain about custom allocator design",
-           issue = "27779")]
-#[allow(missing_debug_implementations)]
-#[derive(Copy, Clone)]
-pub struct ExchangeHeapSingleton {
-    _force_singleton: (),
-}
-
 /// A pointer type for heap allocation.
 ///
 /// See the [module-level documentation](../../std/boxed/index.html) for more.
@@ -111,121 +78,6 @@ pub struct ExchangeHeapSingleton {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Box<T: ?Sized>(Unique<T>);
 
-/// `IntermediateBox` represents uninitialized backing storage for `Box`.
-///
-/// FIXME (pnkfelix): Ideally we would just reuse `Box<T>` instead of
-/// introducing a separate `IntermediateBox<T>`; but then you hit
-/// issues when you e.g. attempt to destructure an instance of `Box`,
-/// since it is a lang item and so it gets special handling by the
-/// compiler.  Easier just to make this parallel type for now.
-///
-/// FIXME (pnkfelix): Currently the `box` protocol only supports
-/// creating instances of sized types. This IntermediateBox is
-/// designed to be forward-compatible with a future protocol that
-/// supports creating instances of unsized types; that is why the type
-/// parameter has the `?Sized` generalization marker, and is also why
-/// this carries an explicit size. However, it probably does not need
-/// to carry the explicit alignment; that is just a work-around for
-/// the fact that the `align_of` intrinsic currently requires the
-/// input type to be Sized (which I do not think is strictly
-/// necessary).
-#[unstable(feature = "placement_in",
-           reason = "placement box design is still being worked out.",
-           issue = "27779")]
-#[allow(missing_debug_implementations)]
-pub struct IntermediateBox<T: ?Sized> {
-    ptr: *mut u8,
-    layout: Layout,
-    marker: marker::PhantomData<*mut T>,
-}
-
-#[unstable(feature = "placement_in",
-           reason = "placement box design is still being worked out.",
-           issue = "27779")]
-unsafe impl<T> Place<T> for IntermediateBox<T> {
-    fn pointer(&mut self) -> *mut T {
-        self.ptr as *mut T
-    }
-}
-
-unsafe fn finalize<T>(b: IntermediateBox<T>) -> Box<T> {
-    let p = b.ptr as *mut T;
-    mem::forget(b);
-    Box::from_raw(p)
-}
-
-fn make_place<T>() -> IntermediateBox<T> {
-    let layout = Layout::new::<T>();
-
-    let p = if layout.size() == 0 {
-        mem::align_of::<T>() as *mut u8
-    } else {
-        unsafe {
-            Heap.alloc(layout.clone()).unwrap_or_else(|err| {
-                Heap.oom(err)
-            })
-        }
-    };
-
-    IntermediateBox {
-        ptr: p,
-        layout,
-        marker: marker::PhantomData,
-    }
-}
-
-#[unstable(feature = "placement_in",
-           reason = "placement box design is still being worked out.",
-           issue = "27779")]
-impl<T> BoxPlace<T> for IntermediateBox<T> {
-    fn make_place() -> IntermediateBox<T> {
-        make_place()
-    }
-}
-
-#[unstable(feature = "placement_in",
-           reason = "placement box design is still being worked out.",
-           issue = "27779")]
-impl<T> InPlace<T> for IntermediateBox<T> {
-    type Owner = Box<T>;
-    unsafe fn finalize(self) -> Box<T> {
-        finalize(self)
-    }
-}
-
-#[unstable(feature = "placement_new_protocol", issue = "27779")]
-impl<T> Boxed for Box<T> {
-    type Data = T;
-    type Place = IntermediateBox<T>;
-    unsafe fn finalize(b: IntermediateBox<T>) -> Box<T> {
-        finalize(b)
-    }
-}
-
-#[unstable(feature = "placement_in",
-           reason = "placement box design is still being worked out.",
-           issue = "27779")]
-impl<T> Placer<T> for ExchangeHeapSingleton {
-    type Place = IntermediateBox<T>;
-
-    fn make_place(self) -> IntermediateBox<T> {
-        make_place()
-    }
-}
-
-#[unstable(feature = "placement_in",
-           reason = "placement box design is still being worked out.",
-           issue = "27779")]
-impl<T: ?Sized> Drop for IntermediateBox<T> {
-    fn drop(&mut self) {
-        if self.layout.size() > 0 {
-            unsafe {
-                Heap.dealloc(self.ptr, self.layout.clone())
-            }
-        }
-    }
-}
-
 impl<T> Box<T> {
     /// Allocates memory on the heap and then places `x` into it.
     ///
index 464f8f2f4eced25d14eca2f3bfeb6c8b40f523c1..49109d522e9651bb8e47ee2ff546b7ee9af28479 100644 (file)
 // - A node of length `n` has `n` keys, `n` values, and (in an internal node) `n + 1` edges.
 //   This implies that even an empty internal node has at least one edge.
 
+use core::heap::{Alloc, Layout};
 use core::marker::PhantomData;
 use core::mem;
 use core::ptr::{self, Unique, NonNull};
 use core::slice;
 
 use boxed::Box;
-use heap::{Heap, Alloc, Layout};
+use heap::Heap;
 
 const B: usize = 6;
 pub const MIN_LEN: usize = B - 1;
index e6a311041f5446f7d83d52b7799a820f5dd3f1e9..51a7802540192967d0547ec09e9e7389a6bb6f79 100644 (file)
@@ -76,7 +76,6 @@
 #![deny(missing_debug_implementations)]
 
 #![cfg_attr(test, allow(deprecated))] // rand
-#![cfg_attr(test, feature(placement_in))]
 #![cfg_attr(not(test), feature(core_float))]
 #![cfg_attr(not(test), feature(exact_size_is_empty))]
 #![cfg_attr(not(test), feature(generator_trait))]
 #![feature(fundamental)]
 #![feature(generic_param_attrs)]
 #![cfg_attr(stage0, feature(i128_type))]
-#![feature(iter_rfold)]
 #![feature(lang_items)]
 #![feature(needs_allocator)]
 #![feature(nonzero)]
 #![feature(optin_builtin_traits)]
 #![feature(pattern)]
 #![feature(pin)]
-#![feature(placement_in_syntax)]
-#![feature(placement_new_protocol)]
 #![feature(ptr_internals)]
 #![feature(rustc_attrs)]
 #![feature(slice_get_slice)]
 #![feature(pointer_methods)]
 #![feature(inclusive_range_fields)]
 
-#![cfg_attr(not(test), feature(fn_traits, placement_new_protocol, swap_with_slice, i128))]
-#![cfg_attr(test, feature(test, box_heap))]
+#![cfg_attr(not(test), feature(fn_traits, swap_with_slice, i128))]
+#![cfg_attr(test, feature(test))]
 
 // Allow testing this library
 
 
 // Need to conditionally define the mod from `boxed.rs` to avoid
 // duplicating the lang-items when building in test cfg; but also need
-// to allow code to have `use boxed::HEAP;`
-// and `use boxed::Box;` declarations.
+// to allow code to have `use boxed::Box;` declarations.
 #[cfg(not(test))]
 pub mod boxed;
 #[cfg(test)]
 mod boxed {
-    pub use std::boxed::{Box, IntermediateBox, HEAP};
+    pub use std::boxed::Box;
 }
 #[cfg(test)]
 mod boxed_test;
index 097d2e414f5cc953fedd04808278f5637fc64abe..129b3bc676432f058912c01ae3e834467ff34b0d 100644 (file)
 use core::iter::{FromIterator, FusedIterator};
 use core::marker::PhantomData;
 use core::mem;
-use core::ops::{BoxPlace, InPlace, Place, Placer};
-use core::ptr::{self, NonNull};
+use core::ptr::NonNull;
 
-use boxed::{Box, IntermediateBox};
+use boxed::Box;
 use super::SpecExtend;
 
 /// A doubly-linked list with owned nodes.
@@ -786,62 +785,6 @@ pub fn drain_filter<F>(&mut self, filter: F) -> DrainFilter<T, F>
             old_len: old_len,
         }
     }
-
-    /// Returns a place for insertion at the front of the list.
-    ///
-    /// Using this method with placement syntax is equivalent to
-    /// [`push_front`](#method.push_front), but may be more efficient.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(collection_placement)]
-    /// #![feature(placement_in_syntax)]
-    ///
-    /// use std::collections::LinkedList;
-    ///
-    /// let mut list = LinkedList::new();
-    /// list.front_place() <- 2;
-    /// list.front_place() <- 4;
-    /// assert!(list.iter().eq(&[4, 2]));
-    /// ```
-    #[unstable(feature = "collection_placement",
-               reason = "method name and placement protocol are subject to change",
-               issue = "30172")]
-    pub fn front_place(&mut self) -> FrontPlace<T> {
-        FrontPlace {
-            list: self,
-            node: IntermediateBox::make_place(),
-        }
-    }
-
-    /// Returns a place for insertion at the back of the list.
-    ///
-    /// Using this method with placement syntax is equivalent to [`push_back`](#method.push_back),
-    /// but may be more efficient.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(collection_placement)]
-    /// #![feature(placement_in_syntax)]
-    ///
-    /// use std::collections::LinkedList;
-    ///
-    /// let mut list = LinkedList::new();
-    /// list.back_place() <- 2;
-    /// list.back_place() <- 4;
-    /// assert!(list.iter().eq(&[2, 4]));
-    /// ```
-    #[unstable(feature = "collection_placement",
-               reason = "method name and placement protocol are subject to change",
-               issue = "30172")]
-    pub fn back_place(&mut self) -> BackPlace<T> {
-        BackPlace {
-            list: self,
-            node: IntermediateBox::make_place(),
-        }
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1242,123 +1185,6 @@ fn hash<H: Hasher>(&self, state: &mut H) {
     }
 }
 
-unsafe fn finalize<T>(node: IntermediateBox<Node<T>>) -> Box<Node<T>> {
-    let mut node = node.finalize();
-    ptr::write(&mut node.next, None);
-    ptr::write(&mut node.prev, None);
-    node
-}
-
-/// A place for insertion at the front of a `LinkedList`.
-///
-/// See [`LinkedList::front_place`](struct.LinkedList.html#method.front_place) for details.
-#[must_use = "places do nothing unless written to with `<-` syntax"]
-#[unstable(feature = "collection_placement",
-           reason = "struct name and placement protocol are subject to change",
-           issue = "30172")]
-pub struct FrontPlace<'a, T: 'a> {
-    list: &'a mut LinkedList<T>,
-    node: IntermediateBox<Node<T>>,
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "struct name and placement protocol are subject to change",
-           issue = "30172")]
-impl<'a, T: 'a + fmt::Debug> fmt::Debug for FrontPlace<'a, T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_tuple("FrontPlace")
-         .field(&self.list)
-         .finish()
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, T> Placer<T> for FrontPlace<'a, T> {
-    type Place = Self;
-
-    fn make_place(self) -> Self {
-        self
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-unsafe impl<'a, T> Place<T> for FrontPlace<'a, T> {
-    fn pointer(&mut self) -> *mut T {
-        unsafe { &mut (*self.node.pointer()).element }
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, T> InPlace<T> for FrontPlace<'a, T> {
-    type Owner = ();
-
-    unsafe fn finalize(self) {
-        let FrontPlace { list, node } = self;
-        list.push_front_node(finalize(node));
-    }
-}
-
-/// A place for insertion at the back of a `LinkedList`.
-///
-/// See [`LinkedList::back_place`](struct.LinkedList.html#method.back_place) for details.
-#[must_use = "places do nothing unless written to with `<-` syntax"]
-#[unstable(feature = "collection_placement",
-           reason = "struct name and placement protocol are subject to change",
-           issue = "30172")]
-pub struct BackPlace<'a, T: 'a> {
-    list: &'a mut LinkedList<T>,
-    node: IntermediateBox<Node<T>>,
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "struct name and placement protocol are subject to change",
-           issue = "30172")]
-impl<'a, T: 'a + fmt::Debug> fmt::Debug for BackPlace<'a, T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_tuple("BackPlace")
-         .field(&self.list)
-         .finish()
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, T> Placer<T> for BackPlace<'a, T> {
-    type Place = Self;
-
-    fn make_place(self) -> Self {
-        self
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-unsafe impl<'a, T> Place<T> for BackPlace<'a, T> {
-    fn pointer(&mut self) -> *mut T {
-        unsafe { &mut (*self.node.pointer()).element }
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, T> InPlace<T> for BackPlace<'a, T> {
-    type Owner = ();
-
-    unsafe fn finalize(self) {
-        let BackPlace { list, node } = self;
-        list.push_back_node(finalize(node));
-    }
-}
-
 // Ensure that `LinkedList` and its read-only iterators are covariant in their type parameters.
 #[allow(dead_code)]
 fn assert_covariance() {
index 229ae54d7474adffd634883aa654b69b32518698..3edce8aebdf39fe5f1da4dc334cc029dd0ac5327 100644 (file)
@@ -9,11 +9,12 @@
 // except according to those terms.
 
 use core::cmp;
+use core::heap::{Alloc, Layout};
 use core::mem;
 use core::ops::Drop;
 use core::ptr::{self, Unique};
 use core::slice;
-use heap::{Alloc, Layout, Heap};
+use heap::Heap;
 use super::boxed::Box;
 use super::allocator::CollectionAllocErr;
 use super::allocator::CollectionAllocErr::*;
index 1fa5d34cb5787147091617c92c1499a0e1506cf5..8bdc57f96a6d5c7dda2f334ebe75987f74ec7771 100644 (file)
 use core::cmp::Ordering;
 use core::fmt;
 use core::hash::{Hash, Hasher};
+use core::heap::{Alloc, Layout};
 use core::intrinsics::abort;
 use core::marker;
 use core::marker::{Unsize, PhantomData};
 use core::ptr::{self, NonNull};
 use core::convert::From;
 
-use heap::{Heap, Alloc, Layout, box_free};
+use heap::{Heap, box_free};
 use string::String;
 use vec::Vec;
 
index aa202e23628922072c144409ede7c24d395ba2de..b95aae02894ed758e1ba8acb86b716daceeeb673 100644 (file)
@@ -1517,7 +1517,7 @@ pub fn drain<R>(&mut self, range: R) -> Drain
         }
     }
 
-    /// Creates a splicing iterator that removes the specified range in the string,
+    /// Removes the specified range in the string,
     /// and replaces it with the given string.
     /// The given string doesn't need to be the same length as the range.
     ///
@@ -1537,21 +1537,20 @@ pub fn drain<R>(&mut self, range: R) -> Drain
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(splice)]
     /// let mut s = String::from("α is alpha, β is beta");
     /// let beta_offset = s.find('β').unwrap_or(s.len());
     ///
     /// // Replace the range up until the β from the string
-    /// s.splice(..beta_offset, "Α is capital alpha; ");
+    /// s.replace_range(..beta_offset, "Α is capital alpha; ");
     /// assert_eq!(s, "Α is capital alpha; β is beta");
     /// ```
-    #[unstable(feature = "splice", reason = "recently added", issue = "44643")]
-    pub fn splice<R>(&mut self, range: R, replace_with: &str)
+    #[stable(feature = "splice", since = "1.27.0")]
+    pub fn replace_range<R>(&mut self, range: R, replace_with: &str)
         where R: RangeBounds<usize>
     {
         // Memory safety
         //
-        // The String version of Splice does not have the memory safety issues
+        // Replace_range does not have the memory safety issues of a vector Splice.
         // of the vector version. The data is just plain bytes.
 
         match range.start() {
index 5c979d82e55dc701cfbcf2f8ca0211349ea4b6c5..8494463463cb941fa7873097ede52783ba4c5910 100644 (file)
@@ -278,26 +278,6 @@ fn test_extend_specialization() {
     assert_eq!(a.into_sorted_vec(), [-20, -10, 1, 2, 3, 3, 5, 43]);
 }
 
-#[test]
-fn test_placement() {
-    let mut a = BinaryHeap::new();
-    &mut a <- 2;
-    &mut a <- 4;
-    &mut a <- 3;
-    assert_eq!(a.peek(), Some(&4));
-    assert_eq!(a.len(), 3);
-    &mut a <- 1;
-    assert_eq!(a.into_sorted_vec(), vec![1, 2, 3, 4]);
-}
-
-#[test]
-fn test_placement_panic() {
-    let mut heap = BinaryHeap::from(vec![1, 2, 3]);
-    fn mkpanic() -> usize { panic!() }
-    let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { &mut heap <- mkpanic(); }));
-    assert_eq!(heap.len(), 3);
-}
-
 #[allow(dead_code)]
 fn assert_covariance() {
     fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
index 0a7e9a8be94f91551560df82a74bda6826360167..1a49fb9964ad727ef7c765c185f8024c35e56764 100644 (file)
 #![feature(attr_literals)]
 #![feature(box_syntax)]
 #![cfg_attr(stage0, feature(inclusive_range_syntax))]
-#![feature(collection_placement)]
 #![feature(const_fn)]
 #![feature(drain_filter)]
 #![feature(exact_size_is_empty)]
 #![feature(iterator_step_by)]
 #![feature(pattern)]
-#![feature(placement_in_syntax)]
 #![feature(rand)]
 #![feature(slice_sort_by_cached_key)]
 #![feature(splice)]
index d1e746ea43b45516875e87f7d30f94f0e194556d..cb4a17a22d8a4aa867a2676ff55c53eb06f51d64 100644 (file)
@@ -443,53 +443,53 @@ fn test_drain() {
 }
 
 #[test]
-fn test_splice() {
+fn test_replace_range() {
     let mut s = "Hello, world!".to_owned();
-    s.splice(7..12, "世界");
+    s.replace_range(7..12, "世界");
     assert_eq!(s, "Hello, 世界!");
 }
 
 #[test]
 #[should_panic]
-fn test_splice_char_boundary() {
+fn test_replace_range_char_boundary() {
     let mut s = "Hello, 世界!".to_owned();
-    s.splice(..8, "");
+    s.replace_range(..8, "");
 }
 
 #[test]
-fn test_splice_inclusive_range() {
+fn test_replace_range_inclusive_range() {
     let mut v = String::from("12345");
-    v.splice(2..=3, "789");
+    v.replace_range(2..=3, "789");
     assert_eq!(v, "127895");
-    v.splice(1..=2, "A");
+    v.replace_range(1..=2, "A");
     assert_eq!(v, "1A895");
 }
 
 #[test]
 #[should_panic]
-fn test_splice_out_of_bounds() {
+fn test_replace_range_out_of_bounds() {
     let mut s = String::from("12345");
-    s.splice(5..6, "789");
+    s.replace_range(5..6, "789");
 }
 
 #[test]
 #[should_panic]
-fn test_splice_inclusive_out_of_bounds() {
+fn test_replace_range_inclusive_out_of_bounds() {
     let mut s = String::from("12345");
-    s.splice(5..=5, "789");
+    s.replace_range(5..=5, "789");
 }
 
 #[test]
-fn test_splice_empty() {
+fn test_replace_range_empty() {
     let mut s = String::from("12345");
-    s.splice(1..2, "");
+    s.replace_range(1..2, "");
     assert_eq!(s, "1345");
 }
 
 #[test]
-fn test_splice_unbounded() {
+fn test_replace_range_unbounded() {
     let mut s = String::from("12345");
-    s.splice(.., "");
+    s.replace_range(.., "");
     assert_eq!(s, "");
 }
 
index 3c17a401bbaf5793b4d63486d8ad3121b879c0a5..2895c53009d9ac9fae260e910bb5d148f34fc321 100644 (file)
@@ -10,7 +10,7 @@
 
 use std::borrow::Cow;
 use std::mem::size_of;
-use std::{usize, isize, panic};
+use std::{usize, isize};
 use std::vec::{Drain, IntoIter};
 use std::collections::CollectionAllocErr::*;
 
@@ -753,24 +753,6 @@ fn into_iter<'new>(i: IntoIter<&'static str>) -> IntoIter<&'new str> {
     }
 }
 
-#[test]
-fn test_placement() {
-    let mut vec = vec![1];
-    assert_eq!(vec.place_back() <- 2, &2);
-    assert_eq!(vec.len(), 2);
-    assert_eq!(vec.place_back() <- 3, &3);
-    assert_eq!(vec.len(), 3);
-    assert_eq!(&vec, &[1, 2, 3]);
-}
-
-#[test]
-fn test_placement_panic() {
-    let mut vec = vec![1, 2, 3];
-    fn mkpanic() -> usize { panic!() }
-    let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { vec.place_back() <- mkpanic(); }));
-    assert_eq!(vec.len(), 3);
-}
-
 #[test]
 fn from_into_inner() {
     let vec = vec![1, 2, 3];
index fc1a0b624a555eebde59edf875a7f459074800bc..75d3f01f8b601c0a930008dc42d92ef3dc75ac6c 100644 (file)
@@ -1004,28 +1004,6 @@ fn test_is_empty() {
     assert!(v.into_iter().is_empty());
 }
 
-#[test]
-fn test_placement_in() {
-    let mut buf: VecDeque<isize> = VecDeque::new();
-    buf.place_back() <- 1;
-    buf.place_back() <- 2;
-    assert_eq!(buf, [1,2]);
-
-    buf.place_front() <- 3;
-    buf.place_front() <- 4;
-    assert_eq!(buf, [4,3,1,2]);
-
-    {
-        let ptr_head = buf.place_front() <- 5;
-        assert_eq!(*ptr_head, 5);
-    }
-    {
-        let ptr_tail = buf.place_back() <- 6;
-        assert_eq!(*ptr_tail, 6);
-    }
-    assert_eq!(buf, [5,4,3,1,2,6]);
-}
-
 #[test]
 fn test_reserve_exact_2() {
     // This is all the same as test_reserve
index 2eedb964f88ba4f4792b45c45b87935467d8a02b..02008310b81613fe0b6e00c29d139e25f1d17315 100644 (file)
@@ -76,7 +76,7 @@
 #[cfg(not(test))]
 use core::num::Float;
 use core::ops::Bound::{Excluded, Included, Unbounded};
-use core::ops::{InPlace, Index, IndexMut, Place, Placer, RangeBounds};
+use core::ops::{Index, IndexMut, RangeBounds};
 use core::ops;
 use core::ptr;
 use core::ptr::NonNull;
@@ -1065,29 +1065,6 @@ pub fn push(&mut self, value: T) {
         }
     }
 
-    /// Returns a place for insertion at the back of the `Vec`.
-    ///
-    /// Using this method with placement syntax is equivalent to [`push`](#method.push),
-    /// but may be more efficient.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(collection_placement)]
-    /// #![feature(placement_in_syntax)]
-    ///
-    /// let mut vec = vec![1, 2];
-    /// vec.place_back() <- 3;
-    /// vec.place_back() <- 4;
-    /// assert_eq!(&vec, &[1, 2, 3, 4]);
-    /// ```
-    #[unstable(feature = "collection_placement",
-               reason = "placement protocol is subject to change",
-               issue = "30172")]
-    pub fn place_back(&mut self) -> PlaceBack<T> {
-        PlaceBack { vec: self }
-    }
-
     /// Removes the last element from a vector and returns it, or [`None`] if it
     /// is empty.
     ///
@@ -1306,6 +1283,49 @@ pub fn split_off(&mut self, at: usize) -> Self {
         }
         other
     }
+
+    /// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
+    ///
+    /// If `new_len` is greater than `len`, the `Vec` is extended by the
+    /// difference, with each additional slot filled with the result of
+    /// calling the closure `f`. The return values from `f` will end up
+    /// in the `Vec` in the order they have been generated.
+    ///
+    /// If `new_len` is less than `len`, the `Vec` is simply truncated.
+    ///
+    /// This method uses a closure to create new values on every push. If
+    /// you'd rather [`Clone`] a given value, use [`resize`]. If you want
+    /// to use the [`Default`] trait to generate values, you can pass
+    /// [`Default::default()`] as the second argument..
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(vec_resize_with)]
+    ///
+    /// let mut vec = vec![1, 2, 3];
+    /// vec.resize_with(5, Default::default);
+    /// assert_eq!(vec, [1, 2, 3, 0, 0]);
+    ///
+    /// let mut vec = vec![];
+    /// let mut p = 1;
+    /// vec.resize_with(4, || { p *= 2; p });
+    /// assert_eq!(vec, [2, 4, 8, 16]);
+    /// ```
+    ///
+    /// [`resize`]: #method.resize
+    /// [`Clone`]: ../../std/clone/trait.Clone.html
+    #[unstable(feature = "vec_resize_with", issue = "41758")]
+    pub fn resize_with<F>(&mut self, new_len: usize, f: F)
+        where F: FnMut() -> T
+    {
+        let len = self.len();
+        if new_len > len {
+            self.extend_with(new_len - len, ExtendFunc(f));
+        } else {
+            self.truncate(new_len);
+        }
+    }
 }
 
 impl<T: Clone> Vec<T> {
@@ -1316,8 +1336,8 @@ impl<T: Clone> Vec<T> {
     /// If `new_len` is less than `len`, the `Vec` is simply truncated.
     ///
     /// This method requires [`Clone`] to be able clone the passed value. If
-    /// you'd rather create a value with [`Default`] instead, see
-    /// [`resize_default`].
+    /// you need more flexibility (or want to rely on [`Default`] instead of
+    /// [`Clone`]), use [`resize_with`].
     ///
     /// # Examples
     ///
@@ -1333,7 +1353,7 @@ impl<T: Clone> Vec<T> {
     ///
     /// [`Clone`]: ../../std/clone/trait.Clone.html
     /// [`Default`]: ../../std/default/trait.Default.html
-    /// [`resize_default`]: #method.resize_default
+    /// [`resize_with`]: #method.resize_with
     #[stable(feature = "vec_resize", since = "1.5.0")]
     pub fn resize(&mut self, new_len: usize, value: T) {
         let len = self.len();
@@ -1412,24 +1432,31 @@ pub fn resize_default(&mut self, new_len: usize) {
 
 // This code generalises `extend_with_{element,default}`.
 trait ExtendWith<T> {
-    fn next(&self) -> T;
+    fn next(&mut self) -> T;
     fn last(self) -> T;
 }
 
 struct ExtendElement<T>(T);
 impl<T: Clone> ExtendWith<T> for ExtendElement<T> {
-    fn next(&self) -> T { self.0.clone() }
+    fn next(&mut self) -> T { self.0.clone() }
     fn last(self) -> T { self.0 }
 }
 
 struct ExtendDefault;
 impl<T: Default> ExtendWith<T> for ExtendDefault {
-    fn next(&self) -> T { Default::default() }
+    fn next(&mut self) -> T { Default::default() }
     fn last(self) -> T { Default::default() }
 }
+
+struct ExtendFunc<F>(F);
+impl<T, F: FnMut() -> T> ExtendWith<T> for ExtendFunc<F> {
+    fn next(&mut self) -> T { (self.0)() }
+    fn last(mut self) -> T { (self.0)() }
+}
+
 impl<T> Vec<T> {
     /// Extend the vector by `n` values, using the given generator.
-    fn extend_with<E: ExtendWith<T>>(&mut self, n: usize, value: E) {
+    fn extend_with<E: ExtendWith<T>>(&mut self, n: usize, mut value: E) {
         self.reserve(n);
 
         unsafe {
@@ -2492,57 +2519,6 @@ fn is_empty(&self) -> bool {
 #[stable(feature = "fused", since = "1.26.0")]
 impl<'a, T> FusedIterator for Drain<'a, T> {}
 
-/// A place for insertion at the back of a `Vec`.
-///
-/// See [`Vec::place_back`](struct.Vec.html#method.place_back) for details.
-#[must_use = "places do nothing unless written to with `<-` syntax"]
-#[unstable(feature = "collection_placement",
-           reason = "struct name and placement protocol are subject to change",
-           issue = "30172")]
-#[derive(Debug)]
-pub struct PlaceBack<'a, T: 'a> {
-    vec: &'a mut Vec<T>,
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, T> Placer<T> for PlaceBack<'a, T> {
-    type Place = PlaceBack<'a, T>;
-
-    fn make_place(self) -> Self {
-        // This will panic or abort if we would allocate > isize::MAX bytes
-        // or if the length increment would overflow for zero-sized types.
-        if self.vec.len == self.vec.buf.cap() {
-            self.vec.buf.double();
-        }
-        self
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-unsafe impl<'a, T> Place<T> for PlaceBack<'a, T> {
-    fn pointer(&mut self) -> *mut T {
-        unsafe { self.vec.as_mut_ptr().offset(self.vec.len as isize) }
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, T> InPlace<T> for PlaceBack<'a, T> {
-    type Owner = &'a mut T;
-
-    unsafe fn finalize(mut self) -> &'a mut T {
-        let ptr = self.pointer();
-        self.vec.len += 1;
-        &mut *ptr
-    }
-}
-
-
 /// A splicing iterator for `Vec`.
 ///
 /// This struct is created by the [`splice()`] method on [`Vec`]. See its
index 94d042a45aa3ebc809ec7aec2bf66e6afeb887f4..f28c8e389967f616e6cff139b74d81c2c03dd4f7 100644 (file)
@@ -22,7 +22,7 @@
 use core::iter::{repeat, FromIterator, FusedIterator};
 use core::mem;
 use core::ops::Bound::{Excluded, Included, Unbounded};
-use core::ops::{Index, IndexMut, Place, Placer, InPlace, RangeBounds};
+use core::ops::{Index, IndexMut, RangeBounds};
 use core::ptr;
 use core::ptr::NonNull;
 use core::slice;
@@ -1885,56 +1885,6 @@ fn grow_if_necessary(&mut self) {
             debug_assert!(!self.is_full());
         }
     }
-
-    /// Returns a place for insertion at the back of the `VecDeque`.
-    ///
-    /// Using this method with placement syntax is equivalent to [`push_back`](#method.push_back),
-    /// but may be more efficient.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(collection_placement)]
-    /// #![feature(placement_in_syntax)]
-    ///
-    /// use std::collections::VecDeque;
-    ///
-    /// let mut buf = VecDeque::new();
-    /// buf.place_back() <- 3;
-    /// buf.place_back() <- 4;
-    /// assert_eq!(&buf, &[3, 4]);
-    /// ```
-    #[unstable(feature = "collection_placement",
-               reason = "placement protocol is subject to change",
-               issue = "30172")]
-    pub fn place_back(&mut self) -> PlaceBack<T> {
-        PlaceBack { vec_deque: self }
-    }
-
-    /// Returns a place for insertion at the front of the `VecDeque`.
-    ///
-    /// Using this method with placement syntax is equivalent to [`push_front`](#method.push_front),
-    /// but may be more efficient.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(collection_placement)]
-    /// #![feature(placement_in_syntax)]
-    ///
-    /// use std::collections::VecDeque;
-    ///
-    /// let mut buf = VecDeque::new();
-    /// buf.place_front() <- 3;
-    /// buf.place_front() <- 4;
-    /// assert_eq!(&buf, &[4, 3]);
-    /// ```
-    #[unstable(feature = "collection_placement",
-               reason = "placement protocol is subject to change",
-               issue = "30172")]
-    pub fn place_front(&mut self) -> PlaceFront<T> {
-        PlaceFront { vec_deque: self }
-    }
 }
 
 impl<T: Clone> VecDeque<T> {
@@ -2662,98 +2612,6 @@ fn from(other: VecDeque<T>) -> Self {
     }
 }
 
-/// A place for insertion at the back of a `VecDeque`.
-///
-/// See [`VecDeque::place_back`](struct.VecDeque.html#method.place_back) for details.
-#[must_use = "places do nothing unless written to with `<-` syntax"]
-#[unstable(feature = "collection_placement",
-           reason = "struct name and placement protocol are subject to change",
-           issue = "30172")]
-#[derive(Debug)]
-pub struct PlaceBack<'a, T: 'a> {
-    vec_deque: &'a mut VecDeque<T>,
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, T> Placer<T> for PlaceBack<'a, T> {
-    type Place = PlaceBack<'a, T>;
-
-    fn make_place(self) -> Self {
-        self.vec_deque.grow_if_necessary();
-        self
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-unsafe impl<'a, T> Place<T> for PlaceBack<'a, T> {
-    fn pointer(&mut self) -> *mut T {
-        unsafe { self.vec_deque.ptr().offset(self.vec_deque.head as isize) }
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, T> InPlace<T> for PlaceBack<'a, T> {
-    type Owner = &'a mut T;
-
-    unsafe fn finalize(self) -> &'a mut T {
-        let head = self.vec_deque.head;
-        self.vec_deque.head = self.vec_deque.wrap_add(head, 1);
-        &mut *(self.vec_deque.ptr().offset(head as isize))
-    }
-}
-
-/// A place for insertion at the front of a `VecDeque`.
-///
-/// See [`VecDeque::place_front`](struct.VecDeque.html#method.place_front) for details.
-#[must_use = "places do nothing unless written to with `<-` syntax"]
-#[unstable(feature = "collection_placement",
-           reason = "struct name and placement protocol are subject to change",
-           issue = "30172")]
-#[derive(Debug)]
-pub struct PlaceFront<'a, T: 'a> {
-    vec_deque: &'a mut VecDeque<T>,
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, T> Placer<T> for PlaceFront<'a, T> {
-    type Place = PlaceFront<'a, T>;
-
-    fn make_place(self) -> Self {
-        self.vec_deque.grow_if_necessary();
-        self
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-unsafe impl<'a, T> Place<T> for PlaceFront<'a, T> {
-    fn pointer(&mut self) -> *mut T {
-        let tail = self.vec_deque.wrap_sub(self.vec_deque.tail, 1);
-        unsafe { self.vec_deque.ptr().offset(tail as isize) }
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, T> InPlace<T> for PlaceFront<'a, T> {
-    type Owner = &'a mut T;
-
-    unsafe fn finalize(self) -> &'a mut T {
-        self.vec_deque.tail = self.vec_deque.wrap_sub(self.vec_deque.tail, 1);
-        &mut *(self.vec_deque.ptr().offset(self.vec_deque.tail as isize))
-    }
-}
-
 #[cfg(test)]
 mod tests {
     use test;
index d7370ae400dac762d2e7a81771c9812606657cf9..7a8d01e4ef8b88f7dddea1adc63f0e1b852baa73 100644 (file)
@@ -15,7 +15,6 @@
                       form or name",
             issue = "27783")]
 #![deny(warnings)]
-#![feature(alloc)]
 #![feature(alloc_system)]
 #![feature(libc)]
 #![feature(linkage)]
@@ -25,7 +24,6 @@
 #![cfg_attr(not(dummy_jemalloc), feature(allocator_api))]
 #![rustc_alloc_kind = "exe"]
 
-extern crate alloc;
 extern crate alloc_system;
 extern crate libc;
 
@@ -35,7 +33,7 @@
 mod contents {
     use core::ptr;
 
-    use alloc::heap::{Alloc, AllocErr, Layout};
+    use core::heap::{Alloc, AllocErr, Layout};
     use alloc_system::System;
     use libc::{c_int, c_void, size_t};
 
index 1d5e7b73be557c17403377e9bbda5a35d47cdf01..d4404e564e0639960873fbacd4bf616130142a3e 100644 (file)
@@ -17,7 +17,6 @@
             issue = "32838")]
 #![feature(global_allocator)]
 #![feature(allocator_api)]
-#![feature(alloc)]
 #![feature(core_intrinsics)]
 #![feature(staged_api)]
 #![feature(rustc_attrs)]
@@ -43,9 +42,7 @@
 #[allow(dead_code)]
 const MIN_ALIGN: usize = 16;
 
-extern crate alloc;
-
-use self::alloc::heap::{Alloc, AllocErr, Layout, Excess, CannotReallocInPlace};
+use core::heap::{Alloc, AllocErr, Layout, Excess, CannotReallocInPlace};
 
 #[unstable(feature = "allocator_api", issue = "32838")]
 pub struct System;
@@ -125,7 +122,7 @@ mod platform {
 
     use MIN_ALIGN;
     use System;
-    use alloc::heap::{Alloc, AllocErr, Layout};
+    use core::heap::{Alloc, AllocErr, Layout};
 
     #[unstable(feature = "allocator_api", issue = "32838")]
     unsafe impl<'a> Alloc for &'a System {
@@ -134,6 +131,14 @@ unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
             let ptr = if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
                 libc::malloc(layout.size()) as *mut u8
             } else {
+                #[cfg(target_os = "macos")]
+                {
+                    if layout.align() > (1 << 31) {
+                        return Err(AllocErr::Unsupported {
+                            details: "requested alignment too large"
+                        })
+                    }
+                }
                 aligned_malloc(&layout)
             };
             if !ptr.is_null() {
@@ -279,7 +284,7 @@ mod platform {
 
     use MIN_ALIGN;
     use System;
-    use alloc::heap::{Alloc, AllocErr, Layout, CannotReallocInPlace};
+    use core::heap::{Alloc, AllocErr, Layout, CannotReallocInPlace};
 
     type LPVOID = *mut u8;
     type HANDLE = LPVOID;
@@ -491,7 +496,7 @@ fn write_str(&mut self, s: &str) -> fmt::Result {
 mod platform {
     extern crate dlmalloc;
 
-    use alloc::heap::{Alloc, AllocErr, Layout, Excess, CannotReallocInPlace};
+    use core::heap::{Alloc, AllocErr, Layout, Excess, CannotReallocInPlace};
     use System;
     use self::dlmalloc::GlobalDlmalloc;
 
index d25f498b99efea68c8eb8462028f8cdda6ecd0e1..c175ae15d28fe03636778725b23dbd370c24b684 100644 (file)
@@ -105,6 +105,7 @@ pub trait Clone : Sized {
     /// assert_eq!("Hello", hello.clone());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use = "cloning is often expensive and is not expected to have side effects"]
     fn clone(&self) -> Self;
 
     /// Performs copy-assignment from `source`.
index dae60b1647ff54f215510ec4fb369bada8d4712a..fe19c923a58d153d2add0d72ed39c72b1e7e6929 100644 (file)
@@ -65,13 +65,11 @@ pub struct Layout {
 
 impl Layout {
     /// Constructs a `Layout` from a given `size` and `align`,
-    /// or returns `None` if any of the following conditions
+    /// or returns `None` if either of the following conditions
     /// are not met:
     ///
     /// * `align` must be a power of two,
     ///
-    /// * `align` must not exceed 2<sup>31</sup> (i.e. `1 << 31`),
-    ///
     /// * `size`, when rounded up to the nearest multiple of `align`,
     ///    must not overflow (i.e. the rounded value must be less than
     ///    `usize::MAX`).
@@ -81,10 +79,6 @@ pub fn from_size_align(size: usize, align: usize) -> Option<Layout> {
             return None;
         }
 
-        if align > (1 << 31) {
-            return None;
-        }
-
         // (power-of-two implies align != 0.)
 
         // Rounded up size is:
@@ -113,9 +107,8 @@ pub fn from_size_align(size: usize, align: usize) -> Option<Layout> {
     /// # Safety
     ///
     /// This function is unsafe as it does not verify that `align` is
-    /// a power-of-two that is also less than or equal to 2<sup>31</sup>, nor
-    /// that `size` aligned to `align` fits within the address space
-    /// (i.e. the `Layout::from_size_align` preconditions).
+    /// a power-of-two nor `size` aligned to `align` fits within the
+    /// address space (i.e. the `Layout::from_size_align` preconditions).
     #[inline]
     pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Layout {
         Layout { size: size, align: align }
@@ -220,10 +213,10 @@ pub fn repeat(&self, n: usize) -> Option<(Self, usize)> {
         let padded_size = self.size.checked_add(self.padding_needed_for(self.align))?;
         let alloc_size = padded_size.checked_mul(n)?;
 
-        // We can assume that `self.align` is a power-of-two that does
-        // not exceed 2<sup>31</sup>. Furthermore, `alloc_size` has already been
-        // rounded up to a multiple of `self.align`; therefore, the
-        // call to `Layout::from_size_align` below should never panic.
+        // We can assume that `self.align` is a power-of-two.
+        // Furthermore, `alloc_size` has already been rounded up
+        // to a multiple of `self.align`; therefore, the call to
+        // `Layout::from_size_align` below should never panic.
         Some((Layout::from_size_align(alloc_size, self.align).unwrap(), padded_size))
     }
 
index 31f77f92435d83ff72a9f04582bb6717f1c1bedd..4ccf446aa6346f007655b95e50ebe30e60881c1a 100644 (file)
@@ -1368,6 +1368,7 @@ fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
     /// [`Result`]: ../../std/result/enum.Result.html
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]
     fn collect<B: FromIterator<Self::Item>>(self) -> B where Self: Sized {
         FromIterator::from_iter(self)
     }
@@ -1446,7 +1447,6 @@ fn partition<B, F>(self, mut f: F) -> (B, B) where
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(iterator_try_fold)]
     /// let a = [1, 2, 3];
     ///
     /// // the checked sum of all of the elements of the array
@@ -1458,7 +1458,6 @@ fn partition<B, F>(self, mut f: F) -> (B, B) where
     /// Short-circuiting:
     ///
     /// ```
-    /// #![feature(iterator_try_fold)]
     /// let a = [10, 20, 30, 100, 40, 50];
     /// let mut it = a.iter();
     ///
@@ -1472,7 +1471,7 @@ fn partition<B, F>(self, mut f: F) -> (B, B) where
     /// assert_eq!(it.next(), Some(&40));
     /// ```
     #[inline]
-    #[unstable(feature = "iterator_try_fold", issue = "45594")]
+    #[stable(feature = "iterator_try_fold", since = "1.27.0")]
     fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where
         Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
     {
@@ -1495,7 +1494,6 @@ fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where
     /// # Examples
     ///
     /// ```
-    /// #![feature(iterator_try_fold)]
     /// use std::fs::rename;
     /// use std::io::{stdout, Write};
     /// use std::path::Path;
@@ -1512,7 +1510,7 @@ fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where
     /// assert_eq!(it.next(), Some("stale_bread.json"));
     /// ```
     #[inline]
-    #[unstable(feature = "iterator_try_fold", issue = "45594")]
+    #[stable(feature = "iterator_try_fold", since = "1.27.0")]
     fn try_for_each<F, R>(&mut self, mut f: F) -> R where
         Self: Sized, F: FnMut(Self::Item) -> R, R: Try<Ok=()>
     {
@@ -1745,6 +1743,38 @@ fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
         }).break_value()
     }
 
+    /// Applies function to the elements of iterator and returns
+    /// the first non-none result.
+    ///
+    /// `iter.find_map(f)` is equivalent to `iter.filter_map(f).next()`.
+    ///
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(iterator_find_map)]
+    /// let a = ["lol", "NaN", "2", "5"];
+    ///
+    /// let mut first_number = a.iter().find_map(|s| s.parse().ok());
+    ///
+    /// assert_eq!(first_number, Some(2));
+    /// ```
+    #[inline]
+    #[unstable(feature = "iterator_find_map",
+               reason = "unstable new API",
+               issue = "49602")]
+    fn find_map<B, F>(&mut self, mut f: F) -> Option<B> where
+        Self: Sized,
+        F: FnMut(Self::Item) -> Option<B>,
+    {
+        self.try_for_each(move |x| {
+            match f(x) {
+                Some(x) => LoopState::Break(x),
+                None => LoopState::Continue(()),
+            }
+        }).break_value()
+    }
+
     /// Searches for an element in an iterator, returning its index.
     ///
     /// `position()` takes a closure that returns `true` or `false`. It applies
index c3aebc4fb23ce37eb8c4aaf63c65a4297d798889..ddbb59989424f11502b5c4b0f17e8f29498c571c 100644 (file)
@@ -427,7 +427,6 @@ pub trait DoubleEndedIterator: Iterator {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(iterator_try_fold)]
     /// let a = ["1", "2", "3"];
     /// let sum = a.iter()
     ///     .map(|&s| s.parse::<i32>())
@@ -438,7 +437,6 @@ pub trait DoubleEndedIterator: Iterator {
     /// Short-circuiting:
     ///
     /// ```
-    /// #![feature(iterator_try_fold)]
     /// let a = ["1", "rust", "3"];
     /// let mut it = a.iter();
     /// let sum = it
@@ -452,7 +450,7 @@ pub trait DoubleEndedIterator: Iterator {
     /// assert_eq!(it.next_back(), Some(&"1"));
     /// ```
     #[inline]
-    #[unstable(feature = "iterator_try_fold", issue = "45594")]
+    #[stable(feature = "iterator_try_fold", since = "1.27.0")]
     fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
         Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
     {
@@ -491,7 +489,6 @@ fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(iter_rfold)]
     /// let a = [1, 2, 3];
     ///
     /// // the sum of all of the elements of a
@@ -505,7 +502,6 @@ fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
     /// and continuing with each element from the back until the front:
     ///
     /// ```
-    /// #![feature(iter_rfold)]
     /// let numbers = [1, 2, 3, 4, 5];
     ///
     /// let zero = "0".to_string();
@@ -517,14 +513,14 @@ fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
     /// assert_eq!(result, "(1 + (2 + (3 + (4 + (5 + 0)))))");
     /// ```
     #[inline]
-    #[unstable(feature = "iter_rfold", issue = "44705")]
+    #[stable(feature = "iter_rfold", since = "1.27.0")]
     fn rfold<B, F>(mut self, accum: B, mut f: F) -> B where
         Self: Sized, F: FnMut(B, Self::Item) -> B,
     {
         self.try_rfold(accum, move |acc, x| AlwaysOk(f(acc, x))).0
     }
 
-    /// Searches for an element of an iterator from the right that satisfies a predicate.
+    /// Searches for an element of an iterator from the back that satisfies a predicate.
     ///
     /// `rfind()` takes a closure that returns `true` or `false`. It applies
     /// this closure to each element of the iterator, starting at the end, and if any
@@ -547,8 +543,6 @@ fn rfold<B, F>(mut self, accum: B, mut f: F) -> B where
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(iter_rfind)]
-    ///
     /// let a = [1, 2, 3];
     ///
     /// assert_eq!(a.iter().rfind(|&&x| x == 2), Some(&2));
@@ -559,8 +553,6 @@ fn rfold<B, F>(mut self, accum: B, mut f: F) -> B where
     /// Stopping at the first `true`:
     ///
     /// ```
-    /// #![feature(iter_rfind)]
-    ///
     /// let a = [1, 2, 3];
     ///
     /// let mut iter = a.iter();
@@ -571,7 +563,7 @@ fn rfold<B, F>(mut self, accum: B, mut f: F) -> B where
     /// assert_eq!(iter.next_back(), Some(&1));
     /// ```
     #[inline]
-    #[unstable(feature = "iter_rfind", issue = "39480")]
+    #[stable(feature = "iter_rfind", since = "1.27.0")]
     fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
         Self: Sized,
         P: FnMut(&Self::Item) -> bool
index 70ab7b2f3b7ec28aca515533266593be41af72ba..474f7e34c3470673e0def41a06f19a83fe568ab2 100644 (file)
@@ -95,7 +95,7 @@
 pub trait Drop {
     /// Executes the destructor for this type.
     ///
-    /// This method is called implilcitly when the value goes out of scope,
+    /// This method is called implicitly when the value goes out of scope,
     /// and cannot be called explicitly (this is compiler error [E0040]).
     /// However, the [`std::mem::drop`] function in the prelude can be
     /// used to call the argument's `Drop` implementation.
index 0b480b618fcb66469a3a254c709c133688a550bf..ce4f45762de48d3571a3f8e68660262c6d844a75 100644 (file)
 mod function;
 mod generator;
 mod index;
-mod place;
 mod range;
 mod try;
 mod unsize;
 #[unstable(feature = "generator_trait", issue = "43122")]
 pub use self::generator::{Generator, GeneratorState};
 
-#[unstable(feature = "placement_new_protocol", issue = "27779")]
-pub use self::place::{Place, Placer, InPlace, Boxed, BoxPlace};
-
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 pub use self::unsize::CoerceUnsized;
diff --git a/src/libcore/ops/place.rs b/src/libcore/ops/place.rs
deleted file mode 100644 (file)
index b3dcf4e..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2012 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.
-
-/// Both `PLACE <- EXPR` and `box EXPR` desugar into expressions
-/// that allocate an intermediate "place" that holds uninitialized
-/// state.  The desugaring evaluates EXPR, and writes the result at
-/// the address returned by the `pointer` method of this trait.
-///
-/// A `Place` can be thought of as a special representation for a
-/// hypothetical `&uninit` reference (which Rust cannot currently
-/// express directly). That is, it represents a pointer to
-/// uninitialized storage.
-///
-/// The client is responsible for two steps: First, initializing the
-/// payload (it can access its address via `pointer`). Second,
-/// converting the agent to an instance of the owning pointer, via the
-/// appropriate `finalize` method (see the `InPlace`.
-///
-/// If evaluating EXPR fails, then it is up to the destructor for the
-/// implementation of Place to clean up any intermediate state
-/// (e.g. deallocate box storage, pop a stack, etc).
-#[unstable(feature = "placement_new_protocol", issue = "27779")]
-pub unsafe trait Place<Data: ?Sized> {
-    /// Returns the address where the input value will be written.
-    /// Note that the data at this address is generally uninitialized,
-    /// and thus one should use `ptr::write` for initializing it.
-    ///
-    /// This function must return a pointer through which a value
-    /// of type `Data` can be written.
-    fn pointer(&mut self) -> *mut Data;
-}
-
-/// Interface to implementations of  `PLACE <- EXPR`.
-///
-/// `PLACE <- EXPR` effectively desugars into:
-///
-/// ```
-/// # #![feature(placement_new_protocol, box_heap)]
-/// # use std::ops::{Placer, Place, InPlace};
-/// # #[allow(non_snake_case)]
-/// # fn main() {
-/// # let PLACE = std::boxed::HEAP;
-/// # let EXPR = 1;
-/// let p = PLACE;
-/// let mut place = Placer::make_place(p);
-/// let raw_place = Place::pointer(&mut place);
-/// let value = EXPR;
-/// unsafe {
-///     std::ptr::write(raw_place, value);
-///     InPlace::finalize(place)
-/// }
-/// # ; }
-/// ```
-///
-/// The type of `PLACE <- EXPR` is derived from the type of `PLACE`;
-/// if the type of `PLACE` is `P`, then the final type of the whole
-/// expression is `P::Place::Owner` (see the `InPlace` and `Boxed`
-/// traits).
-///
-/// Values for types implementing this trait usually are transient
-/// intermediate values (e.g. the return value of `Vec::emplace_back`)
-/// or `Copy`, since the `make_place` method takes `self` by value.
-#[unstable(feature = "placement_new_protocol", issue = "27779")]
-pub trait Placer<Data: ?Sized> {
-    /// `Place` is the intermediate agent guarding the
-    /// uninitialized state for `Data`.
-    type Place: InPlace<Data>;
-
-    /// Creates a fresh place from `self`.
-    fn make_place(self) -> Self::Place;
-}
-
-/// Specialization of `Place` trait supporting `PLACE <- EXPR`.
-#[unstable(feature = "placement_new_protocol", issue = "27779")]
-pub trait InPlace<Data: ?Sized>: Place<Data> {
-    /// `Owner` is the type of the end value of `PLACE <- EXPR`
-    ///
-    /// Note that when `PLACE <- EXPR` is solely used for
-    /// side-effecting an existing data-structure,
-    /// e.g. `Vec::emplace_back`, then `Owner` need not carry any
-    /// information at all (e.g. it can be the unit type `()` in that
-    /// case).
-    type Owner;
-
-    /// Converts self into the final value, shifting
-    /// deallocation/cleanup responsibilities (if any remain), over to
-    /// the returned instance of `Owner` and forgetting self.
-    unsafe fn finalize(self) -> Self::Owner;
-}
-
-/// Core trait for the `box EXPR` form.
-///
-/// `box EXPR` effectively desugars into:
-///
-/// ```
-/// # #![feature(placement_new_protocol)]
-/// # use std::ops::{BoxPlace, Place, Boxed};
-/// # #[allow(non_snake_case)]
-/// # fn main() {
-/// # let EXPR = 1;
-/// let mut place = BoxPlace::make_place();
-/// let raw_place = Place::pointer(&mut place);
-/// let value = EXPR;
-/// # let _: Box<_> =
-/// unsafe {
-///     ::std::ptr::write(raw_place, value);
-///     Boxed::finalize(place)
-/// }
-/// # ; }
-/// ```
-///
-/// The type of `box EXPR` is supplied from its surrounding
-/// context; in the above expansion, the result type `T` is used
-/// to determine which implementation of `Boxed` to use, and that
-/// `<T as Boxed>` in turn dictates determines which
-/// implementation of `BoxPlace` to use, namely:
-/// `<<T as Boxed>::Place as BoxPlace>`.
-#[unstable(feature = "placement_new_protocol", issue = "27779")]
-pub trait Boxed {
-    /// The kind of data that is stored in this kind of box.
-    type Data;  /* (`Data` unused b/c cannot yet express below bound.) */
-    /// The place that will negotiate the storage of the data.
-    type Place: BoxPlace<Self::Data>;
-
-    /// Converts filled place into final owning value, shifting
-    /// deallocation/cleanup responsibilities (if any remain), over to
-    /// returned instance of `Self` and forgetting `filled`.
-    unsafe fn finalize(filled: Self::Place) -> Self;
-}
-
-/// Specialization of `Place` trait supporting `box EXPR`.
-#[unstable(feature = "placement_new_protocol", issue = "27779")]
-pub trait BoxPlace<Data: ?Sized> : Place<Data> {
-    /// Creates a globally fresh place.
-    fn make_place() -> Self;
-}
index a962efadd64e9aed3cca29088bd9cee74ec2823c..2abac0cf1d5b93bd01ca47407eb4e0b997e3ce69 100644 (file)
@@ -1146,6 +1146,33 @@ fn test_find() {
     assert!(v.iter().find(|&&x| x % 12 == 0).is_none());
 }
 
+#[test]
+fn test_find_map() {
+    let xs: &[isize] = &[];
+    assert_eq!(xs.iter().find_map(half_if_even), None);
+    let xs: &[isize] = &[3, 5];
+    assert_eq!(xs.iter().find_map(half_if_even), None);
+    let xs: &[isize] = &[4, 5];
+    assert_eq!(xs.iter().find_map(half_if_even), Some(2));
+    let xs: &[isize] = &[3, 6];
+    assert_eq!(xs.iter().find_map(half_if_even), Some(3));
+
+    let xs: &[isize] = &[1, 2, 3, 4, 5, 6, 7];
+    let mut iter = xs.iter();
+    assert_eq!(iter.find_map(half_if_even), Some(1));
+    assert_eq!(iter.find_map(half_if_even), Some(2));
+    assert_eq!(iter.find_map(half_if_even), Some(3));
+    assert_eq!(iter.next(), Some(&7));
+
+    fn half_if_even(x: &isize) -> Option<isize> {
+        if x % 2 == 0 {
+            Some(x / 2)
+        } else {
+            None
+        }
+    }
+}
+
 #[test]
 fn test_position() {
     let v = &[1, 3, 9, 27, 103, 14, 11];
index 1a68f04532d204a91a920d5d07b928936d051b65..de7211e718c9f20333b33a576cbf019f71cc1389 100644 (file)
 #![feature(iterator_step_by)]
 #![cfg_attr(stage0, feature(i128_type))]
 #![cfg_attr(stage0, feature(inclusive_range_syntax))]
-#![feature(iterator_try_fold)]
 #![feature(iterator_flatten)]
 #![cfg_attr(stage0, feature(conservative_impl_trait))]
-#![feature(iter_rfind)]
-#![feature(iter_rfold)]
 #![feature(iterator_repeat_with)]
 #![feature(nonzero)]
 #![feature(pattern)]
@@ -48,6 +45,7 @@
 #![feature(atomic_nand)]
 #![feature(reverse_bits)]
 #![feature(inclusive_range_fields)]
+#![feature(iterator_find_map)]
 
 extern crate core;
 extern crate test;
index 716a2cc6cbb11f24ff0a9fcdd7cf583a9a476330..007093981d3e19a6ee1ce62557b53627fc50c432 100644 (file)
@@ -40,7 +40,6 @@
 #![feature(lang_items)]
 #![feature(optin_builtin_traits)]
 
-#[macro_use]
 extern crate syntax;
 extern crate syntax_pos;
 extern crate rustc_errors;
@@ -156,7 +155,7 @@ impl IntoIterator for TokenStream {
     type IntoIter = TokenTreeIter;
 
     fn into_iter(self) -> TokenTreeIter {
-        TokenTreeIter { cursor: self.0.trees(), next: None }
+        TokenTreeIter { cursor: self.0.trees(), stack: Vec::new() }
     }
 }
 
@@ -554,7 +553,7 @@ pub fn byte_string(bytes: &[u8]) -> Literal {
 #[unstable(feature = "proc_macro", issue = "38356")]
 pub struct TokenTreeIter {
     cursor: tokenstream::Cursor,
-    next: Option<tokenstream::TokenStream>,
+    stack: Vec<TokenTree>,
 }
 
 #[unstable(feature = "proc_macro", issue = "38356")]
@@ -563,9 +562,10 @@ impl Iterator for TokenTreeIter {
 
     fn next(&mut self) -> Option<TokenTree> {
         loop {
-            let next =
-                unwrap_or!(self.next.take().or_else(|| self.cursor.next_as_stream()), return None);
-            let tree = TokenTree::from_internal(next, &mut self.next);
+            let tree = self.stack.pop().or_else(|| {
+                let next = self.cursor.next_as_stream()?;
+                Some(TokenTree::from_internal(next, &mut self.stack))
+            })?;
             if tree.span.0 == DUMMY_SP {
                 if let TokenNode::Group(Delimiter::None, stream) = tree.kind {
                     self.cursor.insert(stream.0);
@@ -598,12 +598,12 @@ fn to_internal(self) -> token::DelimToken {
 }
 
 impl TokenTree {
-    fn from_internal(stream: tokenstream::TokenStream, next: &mut Option<tokenstream::TokenStream>)
+    fn from_internal(stream: tokenstream::TokenStream, stack: &mut Vec<TokenTree>)
                 -> TokenTree {
         use syntax::parse::token::*;
 
         let (tree, is_joint) = stream.as_tree();
-        let (mut span, token) = match tree {
+        let (span, token) = match tree {
             tokenstream::TokenTree::Token(span, token) => (span, token),
             tokenstream::TokenTree::Delimited(span, delimed) => {
                 let delimiter = Delimiter::from_internal(delimed.delim);
@@ -615,34 +615,32 @@ fn from_internal(stream: tokenstream::TokenStream, next: &mut Option<tokenstream
         };
 
         let op_kind = if is_joint { Spacing::Joint } else { Spacing::Alone };
-        macro_rules! op {
-            ($op:expr) => { TokenNode::Op($op, op_kind) }
-        }
-
-        macro_rules! joint {
-            ($first:expr, $rest:expr) => { joint($first, $rest, is_joint, &mut span, next) }
+        macro_rules! tt {
+            ($e:expr) => (TokenTree { span: Span(span), kind: $e })
         }
-
-        fn joint(first: char, rest: Token, is_joint: bool, span: &mut syntax_pos::Span,
-                 next: &mut Option<tokenstream::TokenStream>)
-                 -> TokenNode {
-            let (first_span, rest_span) = (*span, *span);
-            *span = first_span;
-            let tree = tokenstream::TokenTree::Token(rest_span, rest);
-            *next = Some(if is_joint { tree.joint() } else { tree.into() });
-            TokenNode::Op(first, Spacing::Joint)
+        macro_rules! op {
+            ($a:expr) => (TokenNode::Op($a, op_kind));
+            ($a:expr, $b:expr) => ({
+                stack.push(tt!(TokenNode::Op($b, op_kind).into()));
+                TokenNode::Op($a, Spacing::Joint)
+            });
+            ($a:expr, $b:expr, $c:expr) => ({
+                stack.push(tt!(TokenNode::Op($c, op_kind)));
+                stack.push(tt!(TokenNode::Op($b, Spacing::Joint)));
+                TokenNode::Op($a, Spacing::Joint)
+            })
         }
 
         let kind = match token {
             Eq => op!('='),
             Lt => op!('<'),
-            Le => joint!('<', Eq),
-            EqEq => joint!('=', Eq),
-            Ne => joint!('!', Eq),
-            Ge => joint!('>', Eq),
+            Le => op!('<', '='),
+            EqEq => op!('=', '='),
+            Ne => op!('!', '='),
+            Ge => op!('>', '='),
             Gt => op!('>'),
-            AndAnd => joint!('&', BinOp(And)),
-            OrOr => joint!('|', BinOp(Or)),
+            AndAnd => op!('&', '&'),
+            OrOr => op!('|', '|'),
             Not => op!('!'),
             Tilde => op!('~'),
             BinOp(Plus) => op!('+'),
@@ -653,37 +651,46 @@ fn joint(first: char, rest: Token, is_joint: bool, span: &mut syntax_pos::Span,
             BinOp(Caret) => op!('^'),
             BinOp(And) => op!('&'),
             BinOp(Or) => op!('|'),
-            BinOp(Shl) => joint!('<', Lt),
-            BinOp(Shr) => joint!('>', Gt),
-            BinOpEq(Plus) => joint!('+', Eq),
-            BinOpEq(Minus) => joint!('-', Eq),
-            BinOpEq(Star) => joint!('*', Eq),
-            BinOpEq(Slash) => joint!('/', Eq),
-            BinOpEq(Percent) => joint!('%', Eq),
-            BinOpEq(Caret) => joint!('^', Eq),
-            BinOpEq(And) => joint!('&', Eq),
-            BinOpEq(Or) => joint!('|', Eq),
-            BinOpEq(Shl) => joint!('<', Le),
-            BinOpEq(Shr) => joint!('>', Ge),
+            BinOp(Shl) => op!('<', '<'),
+            BinOp(Shr) => op!('>', '>'),
+            BinOpEq(Plus) => op!('+', '='),
+            BinOpEq(Minus) => op!('-', '='),
+            BinOpEq(Star) => op!('*', '='),
+            BinOpEq(Slash) => op!('/', '='),
+            BinOpEq(Percent) => op!('%', '='),
+            BinOpEq(Caret) => op!('^', '='),
+            BinOpEq(And) => op!('&', '='),
+            BinOpEq(Or) => op!('|', '='),
+            BinOpEq(Shl) => op!('<', '<', '='),
+            BinOpEq(Shr) => op!('>', '>', '='),
             At => op!('@'),
             Dot => op!('.'),
-            DotDot => joint!('.', Dot),
-            DotDotDot => joint!('.', DotDot),
-            DotDotEq => joint!('.', DotEq),
+            DotDot => op!('.', '.'),
+            DotDotDot => op!('.', '.', '.'),
+            DotDotEq => op!('.', '.', '='),
             Comma => op!(','),
             Semi => op!(';'),
             Colon => op!(':'),
-            ModSep => joint!(':', Colon),
-            RArrow => joint!('-', Gt),
-            LArrow => joint!('<', BinOp(Minus)),
-            FatArrow => joint!('=', Gt),
+            ModSep => op!(':', ':'),
+            RArrow => op!('-', '>'),
+            LArrow => op!('<', '-'),
+            FatArrow => op!('=', '>'),
             Pound => op!('#'),
             Dollar => op!('$'),
             Question => op!('?'),
 
             Ident(ident, false) | Lifetime(ident) => TokenNode::Term(Term(ident.name)),
             Ident(ident, true) => TokenNode::Term(Term(Symbol::intern(&format!("r#{}", ident)))),
-            Literal(..) | DocComment(..) => TokenNode::Literal(self::Literal(token)),
+            Literal(..) => TokenNode::Literal(self::Literal(token)),
+            DocComment(c) => {
+                let stream = vec![
+                    tt!(TokenNode::Term(Term::intern("doc"))),
+                    tt!(op!('=')),
+                    tt!(TokenNode::Literal(self::Literal(Literal(Lit::Str_(c), None)))),
+                ].into_iter().collect();
+                stack.push(tt!(TokenNode::Group(Delimiter::Bracket, stream)));
+                op!('#')
+            }
 
             Interpolated(_) => {
                 __internal::with_sess(|(sess, _)| {
@@ -692,7 +699,7 @@ fn joint(first: char, rest: Token, is_joint: bool, span: &mut syntax_pos::Span,
                 })
             }
 
-            DotEq => joint!('.', Eq),
+            DotEq => op!('.', '='),
             OpenDelim(..) | CloseDelim(..) => unreachable!(),
             Whitespace | Comment | Shebang(..) | Eof => unreachable!(),
         };
@@ -724,7 +731,29 @@ fn to_internal(self) -> tokenstream::TokenStream {
                     } else { Ident(ident, false) };
                 return TokenTree::Token(self.span.0, token).into();
             }
-            TokenNode::Literal(token) => return TokenTree::Token(self.span.0, token.0).into(),
+            TokenNode::Literal(self::Literal(Literal(Lit::Integer(ref a), b)))
+                if a.as_str().starts_with("-") =>
+            {
+                let minus = BinOp(BinOpToken::Minus);
+                let integer = Symbol::intern(&a.as_str()[1..]);
+                let integer = Literal(Lit::Integer(integer), b);
+                let a = TokenTree::Token(self.span.0, minus);
+                let b = TokenTree::Token(self.span.0, integer);
+                return vec![a, b].into_iter().collect()
+            }
+            TokenNode::Literal(self::Literal(Literal(Lit::Float(ref a), b)))
+                if a.as_str().starts_with("-") =>
+            {
+                let minus = BinOp(BinOpToken::Minus);
+                let float = Symbol::intern(&a.as_str()[1..]);
+                let float = Literal(Lit::Float(float), b);
+                let a = TokenTree::Token(self.span.0, minus);
+                let b = TokenTree::Token(self.span.0, float);
+                return vec![a, b].into_iter().collect()
+            }
+            TokenNode::Literal(token) => {
+                return TokenTree::Token(self.span.0, token.0).into()
+            }
         };
 
         let token = match op {
index ff2c36416bfd208aaa10a830e5cc38e57120619b..1247db55f58506b0519a456a2137b88e3ce0ee0e 100644 (file)
@@ -473,8 +473,6 @@ fn match_(&mut self, id: hir::ItemLocalId, discr: &hir::Expr,
 
         // Keep track of the previous guard expressions
         let mut prev_guards = Vec::new();
-        // Track if the previous pattern contained bindings or wildcards
-        let mut prev_has_bindings = false;
 
         for arm in arms {
             // Add an exit node for when we've visited all the
@@ -493,40 +491,16 @@ fn match_(&mut self, id: hir::ItemLocalId, discr: &hir::Expr,
                     // Visit the guard expression
                     let guard_exit = self.expr(&guard, guard_start);
 
-                    let this_has_bindings = pat.contains_bindings_or_wild();
-
-                    // If both this pattern and the previous pattern
-                    // were free of bindings, they must consist only
-                    // of "constant" patterns. Note we cannot match an
-                    // all-constant pattern, fail the guard, and then
-                    // match *another* all-constant pattern. This is
-                    // because if the previous pattern matches, then
-                    // we *cannot* match this one, unless all the
-                    // constants are the same (which is rejected by
-                    // `check_match`).
-                    //
-                    // We can use this to be smarter about the flow
-                    // along guards. If the previous pattern matched,
-                    // then we know we will not visit the guard in
-                    // this one (whether or not the guard succeeded),
-                    // if the previous pattern failed, then we know
-                    // the guard for that pattern will not have been
-                    // visited. Thus, it is not possible to visit both
-                    // the previous guard and the current one when
-                    // both patterns consist only of constant
-                    // sub-patterns.
-                    //
-                    // However, if the above does not hold, then all
-                    // previous guards need to be wired to visit the
-                    // current guard pattern.
-                    if prev_has_bindings || this_has_bindings {
-                        while let Some(prev) = prev_guards.pop() {
-                            self.add_contained_edge(prev, guard_start);
-                        }
+                    // #47295: We used to have very special case code
+                    // here for when a pair of arms are both formed
+                    // solely from constants, and if so, not add these
+                    // edges.  But this was not actually sound without
+                    // other constraints that we stopped enforcing at
+                    // some point.
+                    while let Some(prev) = prev_guards.pop() {
+                        self.add_contained_edge(prev, guard_start);
                     }
 
-                    prev_has_bindings = this_has_bindings;
-
                     // Push the guard onto the list of previous guards
                     prev_guards.push(guard_exit);
 
index 536d682566a720c636359416d1d52887309b4052..5f9f37094f579a5bc01c546dcce43f066ba73de8 100644 (file)
@@ -2911,118 +2911,8 @@ fn lower_range_end(&mut self, e: &RangeEnd) -> hir::RangeEnd {
 
     fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
         let kind = match e.node {
-            // Issue #22181:
-            // Eventually a desugaring for `box EXPR`
-            // (similar to the desugaring above for `in PLACE BLOCK`)
-            // should go here, desugaring
-            //
-            // to:
-            //
-            // let mut place = BoxPlace::make_place();
-            // let raw_place = Place::pointer(&mut place);
-            // let value = $value;
-            // unsafe {
-            //     ::std::ptr::write(raw_place, value);
-            //     Boxed::finalize(place)
-            // }
-            //
-            // But for now there are type-inference issues doing that.
             ExprKind::Box(ref inner) => hir::ExprBox(P(self.lower_expr(inner))),
 
-            // Desugar ExprBox: `in (PLACE) EXPR`
-            ExprKind::InPlace(ref placer, ref value_expr) => {
-                // to:
-                //
-                // let p = PLACE;
-                // let mut place = Placer::make_place(p);
-                // let raw_place = Place::pointer(&mut place);
-                // push_unsafe!({
-                //     std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
-                //     InPlace::finalize(place)
-                // })
-                let placer_expr = P(self.lower_expr(placer));
-                let value_expr = P(self.lower_expr(value_expr));
-
-                let placer_ident = self.str_to_ident("placer");
-                let place_ident = self.str_to_ident("place");
-                let p_ptr_ident = self.str_to_ident("p_ptr");
-
-                let make_place = ["ops", "Placer", "make_place"];
-                let place_pointer = ["ops", "Place", "pointer"];
-                let move_val_init = ["intrinsics", "move_val_init"];
-                let inplace_finalize = ["ops", "InPlace", "finalize"];
-
-                let unstable_span =
-                    self.allow_internal_unstable(CompilerDesugaringKind::BackArrow, e.span);
-                let make_call = |this: &mut LoweringContext, p, args| {
-                    let path = P(this.expr_std_path(unstable_span, p, ThinVec::new()));
-                    P(this.expr_call(e.span, path, args))
-                };
-
-                let mk_stmt_let = |this: &mut LoweringContext, bind, expr| {
-                    this.stmt_let(e.span, false, bind, expr)
-                };
-
-                let mk_stmt_let_mut = |this: &mut LoweringContext, bind, expr| {
-                    this.stmt_let(e.span, true, bind, expr)
-                };
-
-                // let placer = <placer_expr> ;
-                let (s1, placer_binding) = { mk_stmt_let(self, placer_ident, placer_expr) };
-
-                // let mut place = Placer::make_place(placer);
-                let (s2, place_binding) = {
-                    let placer = self.expr_ident(e.span, placer_ident, placer_binding);
-                    let call = make_call(self, &make_place, hir_vec![placer]);
-                    mk_stmt_let_mut(self, place_ident, call)
-                };
-
-                // let p_ptr = Place::pointer(&mut place);
-                let (s3, p_ptr_binding) = {
-                    let agent = P(self.expr_ident(e.span, place_ident, place_binding));
-                    let args = hir_vec![self.expr_mut_addr_of(e.span, agent)];
-                    let call = make_call(self, &place_pointer, args);
-                    mk_stmt_let(self, p_ptr_ident, call)
-                };
-
-                // pop_unsafe!(EXPR));
-                let pop_unsafe_expr = {
-                    self.signal_block_expr(
-                        hir_vec![],
-                        value_expr,
-                        e.span,
-                        hir::PopUnsafeBlock(hir::CompilerGenerated),
-                        ThinVec::new(),
-                    )
-                };
-
-                // push_unsafe!({
-                //     std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
-                //     InPlace::finalize(place)
-                // })
-                let expr = {
-                    let ptr = self.expr_ident(e.span, p_ptr_ident, p_ptr_binding);
-                    let call_move_val_init = hir::StmtSemi(
-                        make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
-                        self.next_id().node_id,
-                    );
-                    let call_move_val_init = respan(e.span, call_move_val_init);
-
-                    let place = self.expr_ident(e.span, place_ident, place_binding);
-                    let call = make_call(self, &inplace_finalize, hir_vec![place]);
-                    P(self.signal_block_expr(
-                        hir_vec![call_move_val_init],
-                        call,
-                        e.span,
-                        hir::PushUnsafeBlock(hir::CompilerGenerated),
-                        ThinVec::new(),
-                    ))
-                };
-
-                let block = self.block_all(e.span, hir_vec![s1, s2, s3], Some(expr));
-                hir::ExprBlock(P(block))
-            }
-
             ExprKind::Array(ref exprs) => {
                 hir::ExprArray(exprs.iter().map(|x| self.lower_expr(x)).collect())
             }
@@ -4069,29 +3959,6 @@ fn std_path(&mut self, span: Span, components: &[&str], is_value: bool) -> hir::
             .resolve_str_path(span, self.crate_root, components, is_value)
     }
 
-    fn signal_block_expr(
-        &mut self,
-        stmts: hir::HirVec<hir::Stmt>,
-        expr: P<hir::Expr>,
-        span: Span,
-        rule: hir::BlockCheckMode,
-        attrs: ThinVec<Attribute>,
-    ) -> hir::Expr {
-        let LoweredNodeId { node_id, hir_id } = self.next_id();
-
-        let block = P(hir::Block {
-            rules: rule,
-            span,
-            id: node_id,
-            hir_id,
-            stmts,
-            expr: Some(expr),
-            targeted_by_break: false,
-            recovered: false,
-        });
-        self.expr_block(block, attrs)
-    }
-
     fn ty_path(&mut self, id: LoweredNodeId, span: Span, qpath: hir::QPath) -> P<hir::Ty> {
         let mut id = id;
         let node = match qpath {
index 0b037964981c936ff6604ecec4875af797b3d228..425459f448fad32b7fb6ac1ab26460f2a14c0cb9 100644 (file)
@@ -371,7 +371,6 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>(
 });
 
 impl_stable_hash_for!(enum ::syntax_pos::hygiene::CompilerDesugaringKind {
-    BackArrow,
     DotFill,
     QuestionMark
 });
index 3bcaef265f24b9f3b9302fdc2d19e1405a365d37..340dd32a237c01fa29240d207cd700435e35ebc6 100644 (file)
@@ -188,6 +188,10 @@ fn hash_stable<W: StableHasherResult>(&self,
 impl_stable_hash_for!(struct ty::adjustment::Adjustment<'tcx> { kind, target });
 impl_stable_hash_for!(struct ty::adjustment::OverloadedDeref<'tcx> { region, mutbl });
 impl_stable_hash_for!(struct ty::UpvarBorrow<'tcx> { kind, region });
+impl_stable_hash_for!(enum ty::adjustment::AllowTwoPhase {
+    Yes,
+    No
+});
 
 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::adjustment::AutoBorrowMutability {
     fn hash_stable<W: StableHasherResult>(&self,
index 29c8ac046b815f43b2ecdb8f8ea29d23350db124..328b2db2b58282ade9b5d6267842fb50af59aa29 100644 (file)
@@ -470,6 +470,30 @@ pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     tcx.hir.krate().visit_all_item_likes(&mut checker.as_deep_visitor());
 }
 
+/// Check whether an item marked with `deprecated(since="X")` is currently
+/// deprecated (i.e. whether X is not greater than the current rustc version).
+pub fn deprecation_in_effect(since: &str) -> bool {
+    fn parse_version(ver: &str) -> Vec<u32> {
+        // We ignore non-integer components of the version (e.g. "nightly").
+        ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect()
+    }
+
+    if let Some(rustc) = option_env!("CFG_RELEASE") {
+        let since: Vec<u32> = parse_version(since);
+        let rustc: Vec<u32> = parse_version(rustc);
+        // We simply treat invalid `since` attributes as relating to a previous
+        // Rust version, thus always displaying the warning.
+        if since.len() != 3 {
+            return true;
+        }
+        since <= rustc
+    } else {
+        // By default, a deprecation warning applies to
+        // the current version of the compiler.
+        true
+    }
+}
+
 struct Checker<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
@@ -559,9 +583,19 @@ pub fn eval_stability(self, def_id: DefId, id: Option<NodeId>, span: Span) -> Ev
         // Deprecated attributes apply in-crate and cross-crate.
         if let Some(id) = id {
             if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
+                // If the deprecation is scheduled for a future Rust
+                // version, then we should display no warning message.
+                let deprecated_in_future_version = if let Some(sym) = depr_entry.attr.since {
+                    let since = sym.as_str();
+                    !deprecation_in_effect(&since)
+                } else {
+                    false
+                };
+
                 let parent_def_id = self.hir.local_def_id(self.hir.get_parent(id));
-                let skip = self.lookup_deprecation_entry(parent_def_id)
-                    .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
+                let skip = deprecated_in_future_version ||
+                           self.lookup_deprecation_entry(parent_def_id)
+                               .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
                 if !skip {
                     lint_deprecated(def_id, id, depr_entry.attr.note);
                 }
index 7579d95a8fe6822f2a14818d8f93bcc9a6906272..a0c31e8b509239230c7b909d180bf3f86f9f224a 100644 (file)
@@ -119,9 +119,27 @@ pub fn method_call(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, source: Ty<'tcx>)
     }
 }
 
+/// At least for initial deployment, we want to limit two-phase borrows to
+/// only a few specific cases. Right now, those mostly "things that desugar"
+/// into method calls
+///     - using x.some_method() syntax, where some_method takes &mut self
+///     - using Foo::some_method(&mut x, ...) syntax
+///     - binary assignment operators (+=, -=, *=, etc.)
+/// Anything else should be rejected until generalized two phase borrow support
+/// is implemented. Right now, dataflow can't handle the general case where there
+/// is more than one use of a mutable borrow, and we don't want to accept too much
+/// new code via two-phase borrows, so we try to limit where we create two-phase
+/// capable mutable borrows.
+/// See #49434 for tracking.
+#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
+pub enum AllowTwoPhase {
+    Yes,
+    No
+}
+
 #[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
 pub enum AutoBorrowMutability {
-    Mutable { allow_two_phase_borrow: bool },
+    Mutable { allow_two_phase_borrow: AllowTwoPhase },
     Immutable,
 }
 
index 96b77d351e24cb38da56c030d7ceb22e8ef4a17e..6b896a889e3003112b33eee21e6ad1ee32afb9c7 100644 (file)
@@ -244,7 +244,8 @@ fn get_resident() -> Option<usize> {
     use std::fs;
 
     let field = 1;
-    let contents = fs::read_string("/proc/self/statm").ok()?;
+    let contents = fs::read("/proc/self/statm").ok()?;
+    let contents = String::from_utf8(contents).ok()?;
     let s = contents.split_whitespace().nth(field)?;
     let npages = s.parse::<usize>().ok()?;
     Some(npages * 4096)
index 7ab6a2691488ed148aa388b2478470ef7a1d89ff..c9495587c4687aa6e5d6119b77550b5ec230b095 100644 (file)
@@ -121,7 +121,9 @@ fn new(init: Word, universe_size: usize) -> Self {
 
     /// Creates set holding every element whose index falls in range 0..universe_size.
     pub fn new_filled(universe_size: usize) -> Self {
-        Self::new(!0, universe_size)
+        let mut result = Self::new(!0, universe_size);
+        result.trim_to(universe_size);
+        result
     }
 
     /// Creates set holding no elements.
@@ -168,6 +170,36 @@ pub fn clear(&mut self) {
         }
     }
 
+    /// Sets all elements up to `universe_size`
+    pub fn set_up_to(&mut self, universe_size: usize) {
+        for b in &mut self.bits {
+            *b = !0;
+        }
+        self.trim_to(universe_size);
+    }
+
+    /// Clear all elements above `universe_size`.
+    fn trim_to(&mut self, universe_size: usize) {
+        let word_bits = mem::size_of::<Word>() * 8;
+
+        // `trim_block` is the first block where some bits have
+        // to be cleared.
+        let trim_block = universe_size / word_bits;
+
+        // all the blocks above it have to be completely cleared.
+        if trim_block < self.bits.len() {
+            for b in &mut self.bits[trim_block+1..] {
+                *b = 0;
+            }
+
+            // at that block, the `universe_size % word_bits` lsbs
+            // should remain.
+            let remaining_bits = universe_size % word_bits;
+            let mask = (1<<remaining_bits)-1;
+            self.bits[trim_block] &= mask;
+        }
+    }
+
     /// Removes `elem` from the set `self`; returns true iff this changed `self`.
     pub fn remove(&mut self, elem: &T) -> bool {
         self.bits.clear_bit(elem.index())
@@ -252,3 +284,43 @@ fn next(&mut self) -> Option<T> {
         }
     }
 }
+
+#[test]
+fn test_trim_to() {
+    use std::cmp;
+
+    for i in 0..256 {
+        let mut idx_buf: IdxSetBuf<usize> = IdxSetBuf::new_filled(128);
+        idx_buf.trim_to(i);
+
+        let elems: Vec<usize> = idx_buf.iter().collect();
+        let expected: Vec<usize> = (0..cmp::min(i, 128)).collect();
+        assert_eq!(elems, expected);
+    }
+}
+
+#[test]
+fn test_set_up_to() {
+    for i in 0..128 {
+        for mut idx_buf in
+            vec![IdxSetBuf::new_empty(128), IdxSetBuf::new_filled(128)]
+            .into_iter()
+        {
+            idx_buf.set_up_to(i);
+
+            let elems: Vec<usize> = idx_buf.iter().collect();
+            let expected: Vec<usize> = (0..i).collect();
+            assert_eq!(elems, expected);
+        }
+    }
+}
+
+#[test]
+fn test_new_filled() {
+    for i in 0..128 {
+        let mut idx_buf = IdxSetBuf::new_filled(i);
+        let elems: Vec<usize> = idx_buf.iter().collect();
+        let expected: Vec<usize> = (0..i).collect();
+        assert_eq!(elems, expected);
+    }
+}
index b9bcbccb30ef37c16ef613b9687a6582a382a966..b461431c7bbbd74b6eb6a8d66f6ccf88910ebd11 100644 (file)
@@ -24,6 +24,7 @@
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(set_stdio)]
+#![feature(rustc_stack_internals)]
 
 extern crate arena;
 extern crate getopts;
@@ -1467,16 +1468,56 @@ pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<Any + Send>>
     // Temporarily have stack size set to 16MB to deal with nom-using crates failing
     const STACK_SIZE: usize = 16 * 1024 * 1024; // 16MB
 
-    let mut cfg = thread::Builder::new().name("rustc".to_string());
+    #[cfg(unix)]
+    let spawn_thread = unsafe {
+        // Fetch the current resource limits
+        let mut rlim = libc::rlimit {
+            rlim_cur: 0,
+            rlim_max: 0,
+        };
+        if libc::getrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 {
+            let err = io::Error::last_os_error();
+            error!("in_rustc_thread: error calling getrlimit: {}", err);
+            true
+        } else if rlim.rlim_max < STACK_SIZE as libc::rlim_t {
+            true
+        } else {
+            std::rt::deinit_stack_guard();
+            rlim.rlim_cur = STACK_SIZE as libc::rlim_t;
+            if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 {
+                let err = io::Error::last_os_error();
+                error!("in_rustc_thread: error calling setrlimit: {}", err);
+                std::rt::update_stack_guard();
+                true
+            } else {
+                std::rt::update_stack_guard();
+                false
+            }
+        }
+    };
 
-    // FIXME: Hacks on hacks. If the env is trying to override the stack size
-    // then *don't* set it explicitly.
-    if env::var_os("RUST_MIN_STACK").is_none() {
-        cfg = cfg.stack_size(STACK_SIZE);
-    }
+    // We set the stack size at link time. See src/rustc/rustc.rs.
+    #[cfg(windows)]
+    let spawn_thread = false;
+
+    #[cfg(not(any(windows,unix)))]
+    let spawn_thread = true;
 
-    let thread = cfg.spawn(f);
-    thread.unwrap().join()
+    // The or condition is added from backward compatibility.
+    if spawn_thread || env::var_os("RUST_MIN_STACK").is_some() {
+        let mut cfg = thread::Builder::new().name("rustc".to_string());
+
+        // FIXME: Hacks on hacks. If the env is trying to override the stack size
+        // then *don't* set it explicitly.
+        if env::var_os("RUST_MIN_STACK").is_none() {
+            cfg = cfg.stack_size(STACK_SIZE);
+        }
+
+        let thread = cfg.spawn(f);
+        thread.unwrap().join()
+    } else {
+        Ok(f())
+    }
 }
 
 /// Get a list of extra command-line flags provided by the user, as strings.
index 86f79c553c3917fc9249e7cd49a8c69a7445f55a..aa93b3098e046e8a0d8c0a433c28c50945e37a9c 100644 (file)
@@ -301,7 +301,6 @@ fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) {
             Ret(Some(ref value)) => (value, "`return` value", false),
             Assign(_, ref value) => (value, "assigned value", false),
             AssignOp(.., ref value) => (value, "assigned value", false),
-            InPlace(_, ref value) => (value, "emplacement value", false),
             // either function/method call, or something this lint doesn't care about
             ref call_or_other => {
                 let args_to_check;
index 09579eaecb2dee8160e538f922e0f6fc2bb2c0e9..c50d84c10d86ea8c4568565067148a65ce6f1bc7 100644 (file)
@@ -196,15 +196,16 @@ pub fn perform_test(&mut self,
                 let mut values = Vec::with_capacity(used_variants);
                 let tcx = self.hir.tcx();
                 for (idx, discr) in adt_def.discriminants(tcx).enumerate() {
-                    target_blocks.place_back() <- if variants.contains(idx) {
+                    target_blocks.push(if variants.contains(idx) {
                         values.push(discr.val);
-                        *(targets.place_back() <- self.cfg.start_new_block())
+                        targets.push(self.cfg.start_new_block());
+                        *targets.last().unwrap()
                     } else {
                         if otherwise_block.is_none() {
                             otherwise_block = Some(self.cfg.start_new_block());
                         }
                         otherwise_block.unwrap()
-                    };
+                    });
                 }
                 if let Some(otherwise_block) = otherwise_block {
                     targets.push(otherwise_block);
index 8494c043f90fcd28ef2e6ea3b3b20a0d0a1dceca..6f5fcc9e421cc115d780356092c1563455c30201 100644 (file)
@@ -317,7 +317,7 @@ struct CFG<'tcx> {
 /// macro (and methods below) makes working with `BlockAnd` much more
 /// convenient.
 
-#[must_use] // if you don't use one of these results, you're leaving a dangling edge
+#[must_use = "if you don't use one of these results, you're leaving a dangling edge"]
 struct BlockAnd<T>(BasicBlock, T);
 
 trait BlockAndExtension {
index c5f5492cd2c2c20cefc36c6c75e1ab5f6cbebee1..287640439c0e8f9ab39216066e8e64eb38bc64d6 100644 (file)
@@ -389,7 +389,7 @@ fn bits_per_block(&self) -> usize {
     // sets on_entry bits for Arg places
     fn start_block_effect(&self, entry_set: &mut IdxSet<MovePathIndex>) {
         // set all bits to 1 (uninit) before gathering counterevidence
-        for e in entry_set.words_mut() { *e = !0; }
+        entry_set.set_up_to(self.bits_per_block());
 
         drop_flag_effects_for_function_entry(
             self.tcx, self.mir, self.mdpe,
@@ -443,7 +443,7 @@ fn bits_per_block(&self) -> usize {
 
     // sets on_entry bits for Arg places
     fn start_block_effect(&self, entry_set: &mut IdxSet<MovePathIndex>) {
-        for e in entry_set.words_mut() { *e = 0; }
+        entry_set.clear();
 
         drop_flag_effects_for_function_entry(
             self.tcx, self.mir, self.mdpe,
index 62d1b43d625706a3cc262f4fbd5437f3b8e19c26..5b3739084801f093e80d25013dfc1228ae36bac4 100644 (file)
@@ -662,9 +662,13 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
 
 impl ToBorrowKind for AutoBorrowMutability {
     fn to_borrow_kind(&self) -> BorrowKind {
+        use rustc::ty::adjustment::AllowTwoPhase;
         match *self {
             AutoBorrowMutability::Mutable { allow_two_phase_borrow } =>
-                BorrowKind::Mut { allow_two_phase_borrow },
+                BorrowKind::Mut { allow_two_phase_borrow: match allow_two_phase_borrow {
+                    AllowTwoPhase::Yes => true,
+                    AllowTwoPhase::No => false
+                }},
             AutoBorrowMutability::Immutable =>
                 BorrowKind::Shared,
         }
index b8bfcd756cd231d711c9c5880e6af8a2947e9c0c..cf3241fe9be662d6938e7d551020cbee98db5a4d 100644 (file)
@@ -743,20 +743,29 @@ pub(super) fn eval_rvalue_into_place(
 
             Discriminant(ref place) => {
                 let ty = self.place_ty(place);
+                let layout = self.layout_of(ty)?;
                 let place = self.eval_place(place)?;
                 let discr_val = self.read_discriminant_value(place, ty)?;
-                if let ty::TyAdt(adt_def, _) = ty.sty {
-                    trace!("Read discriminant {}, valid discriminants {:?}", discr_val, adt_def.discriminants(*self.tcx).collect::<Vec<_>>());
-                    if adt_def.discriminants(*self.tcx).all(|v| {
-                        discr_val != v.val
-                    })
-                    {
-                        return err!(InvalidDiscriminant);
+                match layout.variants {
+                    layout::Variants::Single { index } => {
+                        assert_eq!(discr_val, index as u128);
+                    }
+                    layout::Variants::Tagged { .. } |
+                    layout::Variants::NicheFilling { .. } => {
+                        if let ty::TyAdt(adt_def, _) = ty.sty {
+                            trace!("Read discriminant {}, valid discriminants {:?}", discr_val, adt_def.discriminants(*self.tcx).collect::<Vec<_>>());
+                            if adt_def.discriminants(*self.tcx).all(|v| {
+                                discr_val != v.val
+                            })
+                            {
+                                return err!(InvalidDiscriminant);
+                            }
+                        } else {
+                            bug!("rustc only generates Rvalue::Discriminant for enums");
+                        }
                     }
-                    self.write_primval(dest, PrimVal::Bytes(discr_val), dest_ty)?;
-                } else {
-                    bug!("rustc only generates Rvalue::Discriminant for enums");
                 }
+                self.write_primval(dest, PrimVal::Bytes(discr_val), dest_ty)?;
             }
         }
 
index 7af3a397666e8cd5fa6959f3297dc4bdbfbdd80f..84baa8c541781f8f21240aa2dd07071f51f51c7c 100644 (file)
@@ -34,8 +34,6 @@
 #![feature(exhaustive_patterns)]
 #![feature(range_contains)]
 #![feature(rustc_diagnostic_macros)]
-#![feature(placement_in_syntax)]
-#![feature(collection_placement)]
 #![feature(nonzero)]
 #![cfg_attr(stage0, feature(underscore_lifetimes))]
 #![cfg_attr(stage0, feature(never_type))]
index 3d61ffe39336a5b7778948cb8b2d6c36cc32a539..b1fb0938698cbe3f5899fd750d9bae38c1245052 100644 (file)
@@ -16,7 +16,7 @@
 use hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::{infer, traits};
 use rustc::ty::{self, TyCtxt, TypeFoldable, Ty};
-use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability};
+use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use syntax::abi;
 use syntax::symbol::Symbol;
 use syntax_pos::Span;
@@ -182,7 +182,7 @@ fn try_overloaded_call_traits(&self,
                                     // For initial two-phase borrow
                                     // deployment, conservatively omit
                                     // overloaded function call ops.
-                                    allow_two_phase_borrow: false,
+                                    allow_two_phase_borrow: AllowTwoPhase::No,
                                 }
                             };
                             autoref = Some(Adjustment {
index e4bad8349ea2b5e39b5f2b1eeaa9cee8e411548a..8db8e52b10d4ab4dc048f64e6bb356663163673d 100644 (file)
@@ -47,6 +47,7 @@
 use rustc::session::Session;
 use rustc::traits;
 use rustc::ty::{self, Ty, TypeFoldable};
+use rustc::ty::adjustment::AllowTwoPhase;
 use rustc::ty::cast::{CastKind, CastTy};
 use rustc::ty::subst::Substs;
 use rustc::middle::lang_items;
@@ -434,7 +435,8 @@ fn do_check(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Result<CastKind, CastError>
                     let f = self.expr_ty.fn_sig(fcx.tcx);
                     let res = fcx.try_coerce(self.expr,
                                              self.expr_ty,
-                                             fcx.tcx.mk_fn_ptr(f));
+                                             fcx.tcx.mk_fn_ptr(f),
+                                             AllowTwoPhase::No);
                     if !res.is_ok() {
                         return Err(CastError::NonScalar);
                     }
@@ -616,7 +618,7 @@ fn check_addr_ptr_cast(&self,
     }
 
     fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> bool {
-        fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty).is_ok()
+        fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty, AllowTwoPhase::No).is_ok()
     }
 }
 
index bc8f107951b144c54ff4d9af452a4c9a285917cf..a8d1f69dfe84b1cdd3006570a22482f93e298ff4 100644 (file)
@@ -67,7 +67,7 @@
 use rustc::infer::{Coercion, InferResult, InferOk};
 use rustc::infer::type_variable::TypeVariableOrigin;
 use rustc::traits::{self, ObligationCause, ObligationCauseCode};
-use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability};
+use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc::ty::{self, TypeAndMut, Ty, ClosureSubsts};
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::error::TypeError;
@@ -84,6 +84,13 @@ struct Coerce<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
     fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
     cause: ObligationCause<'tcx>,
     use_lub: bool,
+    /// Determines whether or not allow_two_phase_borrow is set on any
+    /// autoref adjustments we create while coercing. We don't want to
+    /// allow deref coercions to create two-phase borrows, at least initially,
+    /// but we do need two-phase borrows for function argument reborrows.
+    /// See #47489 and #48598
+    /// See docs on the "AllowTwoPhase" type for a more detailed discussion
+    allow_two_phase: AllowTwoPhase,
 }
 
 impl<'a, 'gcx, 'tcx> Deref for Coerce<'a, 'gcx, 'tcx> {
@@ -123,10 +130,13 @@ fn success<'tcx>(adj: Vec<Adjustment<'tcx>>,
 }
 
 impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
-    fn new(fcx: &'f FnCtxt<'f, 'gcx, 'tcx>, cause: ObligationCause<'tcx>) -> Self {
+    fn new(fcx: &'f FnCtxt<'f, 'gcx, 'tcx>,
+           cause: ObligationCause<'tcx>,
+           allow_two_phase: AllowTwoPhase) -> Self {
         Coerce {
             fcx,
             cause,
+            allow_two_phase,
             use_lub: false,
         }
     }
@@ -423,10 +433,7 @@ fn coerce_borrowed_pointer(&self,
         let mutbl = match mt_b.mutbl {
             hir::MutImmutable => AutoBorrowMutability::Immutable,
             hir::MutMutable => AutoBorrowMutability::Mutable {
-                // Deref-coercion is a case where we deliberately
-                // disallow two-phase borrows in its initial
-                // deployment; see discussion on PR #47489.
-                allow_two_phase_borrow: false,
+                allow_two_phase_borrow: self.allow_two_phase,
             }
         };
         adjustments.push(Adjustment {
@@ -472,7 +479,10 @@ fn coerce_unsized(&self, source: Ty<'tcx>, target: Ty<'tcx>) -> CoerceResult<'tc
                 let mutbl = match mt_b.mutbl {
                     hir::MutImmutable => AutoBorrowMutability::Immutable,
                     hir::MutMutable => AutoBorrowMutability::Mutable {
-                        allow_two_phase_borrow: false,
+                        // We don't allow two-phase borrows here, at least for initial
+                        // implementation. If it happens that this coercion is a function argument,
+                        // the reborrow in coerce_borrowed_ptr will pick it up.
+                        allow_two_phase_borrow: AllowTwoPhase::No,
                     }
                 };
                 Some((Adjustment {
@@ -750,13 +760,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     pub fn try_coerce(&self,
                       expr: &hir::Expr,
                       expr_ty: Ty<'tcx>,
-                      target: Ty<'tcx>)
+                      target: Ty<'tcx>,
+                      allow_two_phase: AllowTwoPhase)
                       -> RelateResult<'tcx, Ty<'tcx>> {
         let source = self.resolve_type_vars_with_obligations(expr_ty);
         debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target);
 
         let cause = self.cause(expr.span, ObligationCauseCode::ExprAssignable);
-        let coerce = Coerce::new(self, cause);
+        let coerce = Coerce::new(self, cause, allow_two_phase);
         let ok = self.commit_if_ok(|_| coerce.coerce(source, target))?;
 
         let (adjustments, _) = self.register_infer_ok_obligations(ok);
@@ -770,7 +781,8 @@ pub fn can_coerce(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool {
         debug!("coercion::can({:?} -> {:?})", source, target);
 
         let cause = self.cause(syntax_pos::DUMMY_SP, ObligationCauseCode::ExprAssignable);
-        let coerce = Coerce::new(self, cause);
+        // We don't ever need two-phase here since we throw out the result of the coercion
+        let coerce = Coerce::new(self, cause, AllowTwoPhase::No);
         self.probe(|_| coerce.coerce(source, target)).is_ok()
     }
 
@@ -839,7 +851,12 @@ fn try_find_coercion_lub<E>(&self,
             return Ok(fn_ptr);
         }
 
-        let mut coerce = Coerce::new(self, cause.clone());
+        // Configure a Coerce instance to compute the LUB.
+        // We don't allow two-phase borrows on any autorefs this creates since we
+        // probably aren't processing function arguments here and even if we were,
+        // they're going to get autorefed again anyway and we can apply 2-phase borrows
+        // at that time.
+        let mut coerce = Coerce::new(self, cause.clone(), AllowTwoPhase::No);
         coerce.use_lub = true;
 
         // First try to coerce the new expression to the type of the previous ones,
@@ -1105,7 +1122,8 @@ fn coerce_inner<'a>(&mut self,
             if self.pushed == 0 {
                 // Special-case the first expression we are coercing.
                 // To be honest, I'm not entirely sure why we do this.
-                fcx.try_coerce(expression, expression_ty, self.expected_ty)
+                // We don't allow two-phase borrows, see comment in try_find_coercion_lub for why
+                fcx.try_coerce(expression, expression_ty, self.expected_ty, AllowTwoPhase::No)
             } else {
                 match self.expressions {
                     Expressions::Dynamic(ref exprs) =>
index e8b953d40d7a1ae7ee2664acfc9a719f7f155f30..ecfe1416050290b3277aa6fbf3da5b97de944fca 100644 (file)
@@ -22,6 +22,7 @@
 use rustc::hir::map::NodeItem;
 use rustc::hir::{Item, ItemConst, print};
 use rustc::ty::{self, Ty, AssociatedItem};
+use rustc::ty::adjustment::AllowTwoPhase;
 use errors::{DiagnosticBuilder, CodeMapper};
 
 use super::method::probe;
@@ -80,9 +81,10 @@ pub fn demand_eqtype_with_origin(&self,
     pub fn demand_coerce(&self,
                          expr: &hir::Expr,
                          checked_ty: Ty<'tcx>,
-                         expected: Ty<'tcx>)
+                         expected: Ty<'tcx>,
+                         allow_two_phase: AllowTwoPhase)
                          -> Ty<'tcx> {
-        let (ty, err) = self.demand_coerce_diag(expr, checked_ty, expected);
+        let (ty, err) = self.demand_coerce_diag(expr, checked_ty, expected, allow_two_phase);
         if let Some(mut err) = err {
             err.emit();
         }
@@ -97,11 +99,12 @@ pub fn demand_coerce(&self,
     pub fn demand_coerce_diag(&self,
                               expr: &hir::Expr,
                               checked_ty: Ty<'tcx>,
-                              expected: Ty<'tcx>)
+                              expected: Ty<'tcx>,
+                              allow_two_phase: AllowTwoPhase)
                               -> (Ty<'tcx>, Option<DiagnosticBuilder<'tcx>>) {
         let expected = self.resolve_type_vars_with_obligations(expected);
 
-        let e = match self.try_coerce(expr, checked_ty, expected) {
+        let e = match self.try_coerce(expr, checked_ty, expected, allow_two_phase) {
             Ok(ty) => return (ty, None),
             Err(e) => e
         };
index a3233c8d8659958b86161627cb164d88d9ea1906..19a1efc991d2bff5d968cf76545d2ce8438a4774 100644 (file)
@@ -17,7 +17,8 @@
 use rustc::traits;
 use rustc::ty::{self, Ty};
 use rustc::ty::subst::Subst;
-use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability, OverloadedDeref};
+use rustc::ty::adjustment::{Adjustment, Adjust, OverloadedDeref};
+use rustc::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc::ty::fold::TypeFoldable;
 use rustc::infer::{self, InferOk};
 use syntax_pos::Span;
@@ -170,7 +171,7 @@ fn adjust_self_ty(&mut self,
                 hir::MutMutable => AutoBorrowMutability::Mutable {
                     // Method call receivers are the primary use case
                     // for two-phase borrows.
-                    allow_two_phase_borrow: true,
+                    allow_two_phase_borrow: AllowTwoPhase::Yes,
                 }
             };
             adjustments.push(Adjustment {
@@ -544,7 +545,7 @@ fn convert_place_op_to_mutable(&self,
                             // For initial two-phase borrow
                             // deployment, conservatively omit
                             // overloaded operators.
-                            allow_two_phase_borrow: false,
+                            allow_two_phase_borrow: AllowTwoPhase::No,
                         }
                     };
                     adjustment.kind = Adjust::Borrow(AutoBorrow::Ref(region, mutbl));
index 187f220f7f830b5bb906a339f08c88be047af0e6..f1896be000f630c22d819aef0d6112699da50871 100644 (file)
@@ -97,7 +97,7 @@
 use rustc::ty::subst::{Kind, Subst, Substs};
 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
 use rustc::ty::{self, Ty, TyCtxt, Visibility, ToPredicate};
-use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
+use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::maps::Providers;
 use rustc::ty::util::{Representability, IntTypeExt, Discr};
@@ -2377,12 +2377,11 @@ fn try_index_step(&self,
                     let mutbl = match mt.mutbl {
                         hir::MutImmutable => AutoBorrowMutability::Immutable,
                         hir::MutMutable => AutoBorrowMutability::Mutable {
-                            // FIXME (#46747): arguably indexing is
-                            // "just another kind of call"; perhaps it
-                            // would be more consistent to allow
-                            // two-phase borrows for .index()
-                            // receivers here.
-                            allow_two_phase_borrow: false,
+                            // Indexing can be desugared to a method call,
+                            // so maybe we could use two-phase here.
+                            // See the documentation of AllowTwoPhase for why that's
+                            // not the case today.
+                            allow_two_phase_borrow: AllowTwoPhase::No,
                         }
                     };
                     adjustments.push(Adjustment {
@@ -2685,7 +2684,12 @@ fn parameter_count_error<'tcx>(sess: &Session,
                 //    to, which is `expected_ty` if `rvalue_hint` returns an
                 //    `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
                 let coerce_ty = expected.and_then(|e| e.only_has_type(self));
-                self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty));
+                // We're processing function arguments so we definitely want to use
+                // two-phase borrows.
+                self.demand_coerce(&arg,
+                                   checked_ty,
+                                   coerce_ty.unwrap_or(formal_ty),
+                                   AllowTwoPhase::Yes);
 
                 // 3. Relate the expected type and the formal one,
                 //    if the expected type was used for the coercion.
@@ -2847,7 +2851,8 @@ fn check_expr_coercable_to_type_with_needs(&self,
             expr,
             ExpectHasType(expected),
             needs);
-        self.demand_coerce(expr, ty, expected)
+        // checks don't need two phase
+        self.demand_coerce(expr, ty, expected, AllowTwoPhase::No)
     }
 
     fn check_expr_with_hint(&self, expr: &'gcx hir::Expr,
@@ -3674,7 +3679,7 @@ fn check_expr_kind(&self,
                                         // (It shouldn't actually matter for unary ops whether
                                         // we enable two-phase borrows or not, since a unary
                                         // op has no additional operands.)
-                                        allow_two_phase_borrow: false,
+                                        allow_two_phase_borrow: AllowTwoPhase::No,
                                     }
                                 };
                                 self.apply_adjustments(oprnd, vec![Adjustment {
@@ -4138,7 +4143,8 @@ fn check_expr_kind(&self,
                   let base_t = self.structurally_resolved_type(expr.span, base_t);
                   match self.lookup_indexing(expr, base, base_t, idx_t, needs) {
                       Some((index_ty, element_ty)) => {
-                          self.demand_coerce(idx, idx_t, index_ty);
+                          // two-phase not needed because index_ty is never mutable
+                          self.demand_coerce(idx, idx_t, index_ty, AllowTwoPhase::No);
                           element_ty
                       }
                       None => {
index faebb370a6c46eb5a07ff285c3c051d1a2c258c7..efc1e2a80cebef6062806fb667d407a750c1da59 100644 (file)
@@ -14,7 +14,7 @@
 use super::method::MethodCallee;
 use rustc::ty::{self, Ty, TypeFoldable, TypeVariants};
 use rustc::ty::TypeVariants::{TyStr, TyRef, TyAdt};
-use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability};
+use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc::infer::type_variable::TypeVariableOrigin;
 use errors;
 use syntax_pos::Span;
@@ -203,7 +203,7 @@ fn check_overloaded_binop(&self,
                             hir::MutMutable => AutoBorrowMutability::Mutable {
                                 // Allow two-phase borrows for binops in initial deployment
                                 // since they desugar to methods
-                                allow_two_phase_borrow: true,
+                                allow_two_phase_borrow: AllowTwoPhase::Yes,
                             }
                         };
                         let autoref = Adjustment {
@@ -220,7 +220,7 @@ fn check_overloaded_binop(&self,
                             hir::MutMutable => AutoBorrowMutability::Mutable {
                                 // Allow two-phase borrows for binops in initial deployment
                                 // since they desugar to methods
-                                allow_two_phase_borrow: true,
+                                allow_two_phase_borrow: AllowTwoPhase::Yes,
                             }
                         };
                         let autoref = Adjustment {
index 1f882676f61aa87ee64677f3ec5c2acc1d8c04c2..ca5858299c557f40249584e4023d4a9f12f4639d 100644 (file)
@@ -721,16 +721,6 @@ fn main() {
 ```
 "##,
 
-E0066: r##"
-Box placement expressions (like C++'s "placement new") do not yet support any
-place expression except the exchange heap (i.e. `std::boxed::HEAP`).
-Furthermore, the syntax is changing to use `in` instead of `box`. See [RFC 470]
-and [RFC 809] for more details.
-
-[RFC 470]: https://github.com/rust-lang/rfcs/pull/470
-[RFC 809]: https://github.com/rust-lang/rfcs/blob/master/text/0809-box-and-in-for-stdlib.md
-"##,
-
 E0067: r##"
 The left-hand side of a compound assignment expression must be a place
 expression. A place expression represents a memory location and includes
index e3ba482eecfeef90058febf1fe74a6a6ee6aaabc..6ada4ccfbddc265e13728ed41c3cf4882ecb3f2c 100644 (file)
@@ -1074,8 +1074,7 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option
         let ty = cx.resolver.borrow_mut()
                             .with_scope(*id,
             |resolver| {
-                resolver.resolve_str_path_error(DUMMY_SP,
-                                                &path, false)
+                resolver.resolve_str_path_error(DUMMY_SP, &path, false)
         })?;
         match ty.def {
             Def::Struct(did) | Def::Union(did) | Def::Enum(did) | Def::TyAlias(did) => {
@@ -1090,7 +1089,27 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option
                     };
                     Ok((ty.def, Some(format!("{}.{}", out, item_name))))
                 } else {
-                    Err(())
+                    let is_enum = match ty.def {
+                        Def::Enum(_) => true,
+                        _ => false,
+                    };
+                    let elem = if is_enum {
+                        cx.tcx.adt_def(did).all_fields().find(|item| item.name == item_name)
+                    } else {
+                        cx.tcx.adt_def(did)
+                              .non_enum_variant()
+                              .fields
+                              .iter()
+                              .find(|item| item.name == item_name)
+                    };
+                    if let Some(item) = elem {
+                        Ok((ty.def,
+                            Some(format!("{}.{}",
+                                         if is_enum { "variant" } else { "structfield" },
+                                         item.name))))
+                    } else {
+                        Err(())
+                    }
                 }
             }
             Def::Trait(did) => {
@@ -1101,7 +1120,13 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option
                     let kind = match item.kind {
                         ty::AssociatedKind::Const if is_val => "associatedconstant",
                         ty::AssociatedKind::Type if !is_val => "associatedtype",
-                        ty::AssociatedKind::Method if is_val => "tymethod",
+                        ty::AssociatedKind::Method if is_val => {
+                            if item.defaultness.has_value() {
+                                "method"
+                            } else {
+                                "tymethod"
+                            }
+                        }
                         _ => return Err(())
                     };
 
index 462866e05da49caed55bbc573a023049e73fb668..6e2be2610cec072a4001c72d5788ba8049643be8 100644 (file)
@@ -26,6 +26,7 @@
 
 use syntax::ast::NodeId;
 use syntax::codemap;
+use syntax::edition::Edition;
 use syntax::feature_gate::UnstableFeatures;
 use errors;
 use errors::emitter::ColorConfig;
@@ -123,7 +124,8 @@ pub fn run_core(search_paths: SearchPaths,
                 maybe_sysroot: Option<PathBuf>,
                 allow_warnings: bool,
                 crate_name: Option<String>,
-                force_unstable_if_unmarked: bool) -> (clean::Crate, RenderInfo)
+                force_unstable_if_unmarked: bool,
+                edition: Edition) -> (clean::Crate, RenderInfo)
 {
     // Parse, resolve, and typecheck the given crate.
 
@@ -148,6 +150,7 @@ pub fn run_core(search_paths: SearchPaths,
         actually_rustdoc: true,
         debugging_opts: config::DebuggingOptions {
             force_unstable_if_unmarked,
+            edition,
             ..config::basic_debugging_options()
         },
         ..config::basic_options().clone()
index ff6cc56e5b4f5c5ff2fc67ded3c4be1d62517472..8e6dcf8caf48481fb858d0ddd703612341bbb60d 100644 (file)
@@ -1067,7 +1067,7 @@ fn emit_source(&mut self, filename: &FileName) -> io::Result<()> {
             return Ok(());
         }
 
-        let contents = fs::read_string(&p)?;
+        let contents = fs::read_to_string(&p)?;
 
         // Remove the utf-8 BOM if any
         let contents = if contents.starts_with("\u{feff}") {
@@ -2113,9 +2113,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
             } else {
                 String::new()
             };
-            let text = format!("Deprecated{}{}",
-                               since,
-                               MarkdownHtml(&deprecated_reason));
+            let text = if stability::deprecation_in_effect(&stab.deprecated_since) {
+                format!("Deprecated{}{}",
+                        since,
+                        MarkdownHtml(&deprecated_reason))
+            } else {
+                format!("Deprecating in {}{}",
+                        Escape(&stab.deprecated_since),
+                        MarkdownHtml(&deprecated_reason))
+            };
             stability.push(format!("<div class='stab deprecated'>{}</div>", text))
         };
 
@@ -2165,7 +2171,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
             String::new()
         };
 
-        let text = format!("Deprecated{}{}", since, MarkdownHtml(&note));
+        let text = if stability::deprecation_in_effect(&depr.since) {
+            format!("Deprecated{}{}",
+                    since,
+                    MarkdownHtml(&note))
+        } else {
+            format!("Deprecating in {}{}",
+                    Escape(&depr.since),
+                    MarkdownHtml(&note))
+        };
         stability.push(format!("<div class='stab deprecated'>{}</div>", text))
     }
 
@@ -2801,10 +2815,15 @@ fn item_union(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
         write!(w, "<h2 id='fields' class='fields small-section-header'>
                    Fields<a href='#fields' class='anchor'></a></h2>")?;
         for (field, ty) in fields {
-            write!(w, "<span id='{shortty}.{name}' class=\"{shortty}\"><code>{name}: {ty}</code>
+            let name = field.name.as_ref().expect("union field name");
+            let id = format!("{}.{}", ItemType::StructField, name);
+            write!(w, "<span id=\"{id}\" class=\"{shortty} small-section-header\">\
+                           <a href=\"#{id}\" class=\"anchor field\"></a>\
+                           <span class='invisible'><code>{name}: {ty}</code></span>\
                        </span>",
+                   id = id,
+                   name = name,
                    shortty = ItemType::StructField,
-                   name = field.name.as_ref().unwrap(),
                    ty = ty)?;
             if let Some(stability_class) = field.stability_class() {
                 write!(w, "<span class='stab {stab}'></span>",
index 2d0fe55f70d265a039f973c9da82ab3fc860d1c0..09776569f80bf8cee1c4ab432fb598a9b43c44c4 100644 (file)
@@ -239,7 +239,7 @@ a.test-arrow:hover{
 }
 
 :target > code {
-       background: #FDFFD3;
+       background-color: #494a3d;
 }
 
 pre.compile_fail {
index 66369e860066df94db90e389563db72748401392..e31390f59e292cead33782f4d7dac0d2cc4ea70d 100644 (file)
@@ -61,6 +61,7 @@
 use std::process;
 use std::sync::mpsc::channel;
 
+use syntax::edition::Edition;
 use externalfiles::ExternalHtml;
 use rustc::session::search_paths::SearchPaths;
 use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options, Externs};
@@ -271,6 +272,11 @@ pub fn opts() -> Vec<RustcOptGroup> {
                       \"light-suffix.css\"",
                      "PATH")
         }),
+        unstable("edition", |o| {
+            o.optopt("", "edition",
+                     "edition to use when compiling rust code (default: 2015)",
+                     "EDITION")
+        }),
     ]
 }
 
@@ -429,14 +435,23 @@ pub fn main_args(args: &[String]) -> isize {
     let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance");
     let resource_suffix = matches.opt_str("resource-suffix");
 
+    let edition = matches.opt_str("edition").unwrap_or("2015".to_string());
+    let edition = match edition.parse() {
+        Ok(e) => e,
+        Err(_) => {
+            print_error("could not parse edition");
+            return 1;
+        }
+    };
+
     match (should_test, markdown_input) {
         (true, true) => {
             return markdown::test(input, cfgs, libs, externs, test_args, maybe_sysroot,
-                                  display_warnings, linker)
+                                  display_warnings, linker, edition)
         }
         (true, false) => {
             return test::run(Path::new(input), cfgs, libs, externs, test_args, crate_name,
-                             maybe_sysroot, display_warnings, linker)
+                             maybe_sysroot, display_warnings, linker, edition)
         }
         (false, true) => return markdown::render(Path::new(input),
                                                  output.unwrap_or(PathBuf::from("doc")),
@@ -446,7 +461,7 @@ pub fn main_args(args: &[String]) -> isize {
     }
 
     let output_format = matches.opt_str("w");
-    let res = acquire_input(PathBuf::from(input), externs, &matches, move |out| {
+    let res = acquire_input(PathBuf::from(input), externs, edition, &matches, move |out| {
         let Output { krate, passes, renderinfo } = out;
         info!("going to format");
         match output_format.as_ref().map(|s| &**s) {
@@ -487,14 +502,15 @@ fn print_error<T>(error_message: T) where T: Display {
 /// and files and then generates the necessary rustdoc output for formatting.
 fn acquire_input<R, F>(input: PathBuf,
                        externs: Externs,
+                       edition: Edition,
                        matches: &getopts::Matches,
                        f: F)
                        -> Result<R, String>
 where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R {
     match matches.opt_str("r").as_ref().map(|s| &**s) {
-        Some("rust") => Ok(rust_input(input, externs, matches, f)),
+        Some("rust") => Ok(rust_input(input, externs, edition, matches, f)),
         Some(s) => Err(format!("unknown input format: {}", s)),
-        None => Ok(rust_input(input, externs, matches, f))
+        None => Ok(rust_input(input, externs, edition, matches, f))
     }
 }
 
@@ -520,8 +536,14 @@ fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
 /// generated from the cleaned AST of the crate.
 ///
 /// This form of input will run all of the plug/cleaning passes
-fn rust_input<R, F>(cratefile: PathBuf, externs: Externs, matches: &getopts::Matches, f: F) -> R
-where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R {
+fn rust_input<R, F>(cratefile: PathBuf,
+                    externs: Externs,
+                    edition: Edition,
+                    matches: &getopts::Matches,
+                    f: F) -> R
+where R: 'static + Send,
+      F: 'static + Send + FnOnce(Output) -> R
+{
     let mut default_passes = !matches.opt_present("no-defaults");
     let mut passes = matches.opt_strs("passes");
     let mut plugins = matches.opt_strs("plugins");
@@ -570,7 +592,7 @@ fn rust_input<R, F>(cratefile: PathBuf, externs: Externs, matches: &getopts::Mat
         let (mut krate, renderinfo) =
             core::run_core(paths, cfgs, externs, Input::File(cratefile), triple, maybe_sysroot,
                            display_warnings, crate_name.clone(),
-                           force_unstable_if_unmarked);
+                           force_unstable_if_unmarked, edition);
 
         info!("finished with rustc");
 
index 3a55b279b5cc701914f4330513a1b53320976c65..daa8966b104e8d193c22925b9d426872b4d92eb1 100644 (file)
@@ -18,6 +18,7 @@
 use rustc::session::search_paths::SearchPaths;
 use rustc::session::config::Externs;
 use syntax::codemap::DUMMY_SP;
+use syntax::edition::Edition;
 
 use externalfiles::{ExternalHtml, LoadStringError, load_string};
 
@@ -139,7 +140,7 @@ pub fn render(input: &Path, mut output: PathBuf, matches: &getopts::Matches,
 /// Run any tests/code examples in the markdown file `input`.
 pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
             mut test_args: Vec<String>, maybe_sysroot: Option<PathBuf>,
-            display_warnings: bool, linker: Option<PathBuf>) -> isize {
+            display_warnings: bool, linker: Option<PathBuf>, edition: Edition) -> isize {
     let input_str = match load_string(input) {
         Ok(s) => s,
         Err(LoadStringError::ReadFail) => return 1,
@@ -151,7 +152,7 @@ pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
     let mut collector = Collector::new(input.to_owned(), cfgs, libs, externs,
                                        true, opts, maybe_sysroot, None,
                                        Some(PathBuf::from(input)),
-                                       linker);
+                                       linker, edition);
     find_testable_code(&input_str, &mut collector, DUMMY_SP, None);
     test_args.insert(0, "rustdoctest".to_string());
     testing::test_main(&test_args, collector.tests,
index 8ab9ca451871b930d2bf7496650d2e50736ebaf0..ab11b0d62e9f71055dec5ef63071aadd6ab554a3 100644 (file)
@@ -34,6 +34,7 @@
 use rustc_resolve::MakeGlobMap;
 use syntax::ast;
 use syntax::codemap::CodeMap;
+use syntax::edition::Edition;
 use syntax::feature_gate::UnstableFeatures;
 use syntax::with_globals;
 use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName};
@@ -57,7 +58,8 @@ pub fn run(input_path: &Path,
            crate_name: Option<String>,
            maybe_sysroot: Option<PathBuf>,
            display_warnings: bool,
-           linker: Option<PathBuf>)
+           linker: Option<PathBuf>,
+           edition: Edition)
            -> isize {
     let input = config::Input::File(input_path.to_owned());
 
@@ -70,6 +72,10 @@ pub fn run(input_path: &Path,
         unstable_features: UnstableFeatures::from_environment(),
         lint_cap: Some(::rustc::lint::Level::Allow),
         actually_rustdoc: true,
+        debugging_opts: config::DebuggingOptions {
+            edition,
+            ..config::basic_debugging_options()
+        },
         ..config::basic_options().clone()
     };
 
@@ -117,7 +123,8 @@ pub fn run(input_path: &Path,
                                        maybe_sysroot,
                                        Some(codemap),
                                        None,
-                                       linker);
+                                       linker,
+                                       edition);
 
     {
         let map = hir::map::map_crate(&sess, &cstore, &mut hir_forest, &defs);
@@ -177,8 +184,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
             externs: Externs,
             should_panic: bool, no_run: bool, as_test_harness: bool,
             compile_fail: bool, mut error_codes: Vec<String>, opts: &TestOptions,
-            maybe_sysroot: Option<PathBuf>,
-            linker: Option<PathBuf>) {
+            maybe_sysroot: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition) {
     // the test harness wants its own `main` & top level functions, so
     // never wrap the test in `fn main() { ... }`
     let (test, line_offset) = make_test(test, Some(cratename), as_test_harness, opts);
@@ -204,6 +210,10 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
         },
         test: as_test_harness,
         unstable_features: UnstableFeatures::from_environment(),
+        debugging_opts: config::DebuggingOptions {
+            edition,
+            ..config::basic_debugging_options()
+        },
         ..config::basic_options().clone()
     };
 
@@ -465,13 +475,14 @@ pub struct Collector {
     codemap: Option<Lrc<CodeMap>>,
     filename: Option<PathBuf>,
     linker: Option<PathBuf>,
+    edition: Edition,
 }
 
 impl Collector {
     pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
                use_headers: bool, opts: TestOptions, maybe_sysroot: Option<PathBuf>,
                codemap: Option<Lrc<CodeMap>>, filename: Option<PathBuf>,
-               linker: Option<PathBuf>) -> Collector {
+               linker: Option<PathBuf>, edition: Edition) -> Collector {
         Collector {
             tests: Vec::new(),
             names: Vec::new(),
@@ -486,6 +497,7 @@ pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Ext
             codemap,
             filename,
             linker,
+            edition,
         }
     }
 
@@ -505,6 +517,7 @@ pub fn add_test(&mut self, test: String,
         let opts = self.opts.clone();
         let maybe_sysroot = self.maybe_sysroot.clone();
         let linker = self.linker.clone();
+        let edition = self.edition;
         debug!("Creating test {}: {}", name, test);
         self.tests.push(testing::TestDescAndFn {
             desc: testing::TestDesc {
@@ -535,7 +548,8 @@ pub fn add_test(&mut self, test: String,
                                  error_codes,
                                  &opts,
                                  maybe_sysroot,
-                                 linker)
+                                 linker,
+                                 edition)
                     }))
                 } {
                     Ok(()) => (),
index 474999a6646df687cd91ec5c8566443feff5efd6..e0b48e565d02a8aadb3e0f13df8793cb214a82a1 100644 (file)
 use self::Entry::*;
 use self::VacantEntryState::*;
 
-use alloc::heap::{Heap, Alloc};
+use alloc::heap::Heap;
 use alloc::allocator::CollectionAllocErr;
 use cell::Cell;
+use core::heap::Alloc;
 use borrow::Borrow;
 use cmp::max;
 use fmt::{self, Debug};
@@ -21,8 +22,7 @@
 use hash::{Hash, Hasher, BuildHasher, SipHasher13};
 use iter::{FromIterator, FusedIterator};
 use mem::{self, replace};
-use ops::{Deref, Index, InPlace, Place, Placer};
-use ptr;
+use ops::{Deref, Index};
 use sys;
 
 use super::table::{self, Bucket, EmptyBucket, FullBucket, FullBucketMut, RawTable, SafeHash};
@@ -2042,80 +2042,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-/// A place for insertion to a `Entry`.
-///
-/// See [`HashMap::entry`](struct.HashMap.html#method.entry) for details.
-#[must_use = "places do nothing unless written to with `<-` syntax"]
-#[unstable(feature = "collection_placement",
-           reason = "struct name and placement protocol is subject to change",
-           issue = "30172")]
-pub struct EntryPlace<'a, K: 'a, V: 'a> {
-    bucket: FullBucketMut<'a, K, V>,
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "struct name and placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for EntryPlace<'a, K, V> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("EntryPlace")
-            .field("key", self.bucket.read().0)
-            .field("value", self.bucket.read().1)
-            .finish()
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "struct name and placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, K, V> Drop for EntryPlace<'a, K, V> {
-    fn drop(&mut self) {
-        // Inplacement insertion failed. Only key need to drop.
-        // The value is failed to insert into map.
-        unsafe { self.bucket.remove_key() };
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, K, V> Placer<V> for Entry<'a, K, V> {
-    type Place = EntryPlace<'a, K, V>;
-
-    fn make_place(self) -> EntryPlace<'a, K, V> {
-        let b = match self {
-            Occupied(mut o) => {
-                unsafe { ptr::drop_in_place(o.elem.read_mut().1); }
-                o.elem
-            }
-            Vacant(v) => {
-                unsafe { v.insert_key() }
-            }
-        };
-        EntryPlace { bucket: b }
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-unsafe impl<'a, K, V> Place<V> for EntryPlace<'a, K, V> {
-    fn pointer(&mut self) -> *mut V {
-        self.bucket.read_mut().1
-    }
-}
-
-#[unstable(feature = "collection_placement",
-           reason = "placement protocol is subject to change",
-           issue = "30172")]
-impl<'a, K, V> InPlace<V> for EntryPlace<'a, K, V> {
-    type Owner = ();
-
-    unsafe fn finalize(self) {
-        mem::forget(self);
-    }
-}
-
 impl<'a, K, V> Entry<'a, K, V> {
     #[stable(feature = "rust1", since = "1.0.0")]
     /// Ensures a value is in the entry by inserting the default if empty, and returns
@@ -2538,26 +2464,6 @@ pub fn insert(self, value: V) -> &'a mut V {
         };
         b.into_mut_refs().1
     }
-
-    // Only used for InPlacement insert. Avoid unnecessary value copy.
-    // The value remains uninitialized.
-    unsafe fn insert_key(self) -> FullBucketMut<'a, K, V> {
-        match self.elem {
-            NeqElem(mut bucket, disp) => {
-                if disp >= DISPLACEMENT_THRESHOLD {
-                    bucket.table_mut().set_tag(true);
-                }
-                let uninit = mem::uninitialized();
-                robin_hood(bucket, disp, self.hash, self.key, uninit)
-            },
-            NoElem(mut bucket, disp) => {
-                if disp >= DISPLACEMENT_THRESHOLD {
-                    bucket.table_mut().set_tag(true);
-                }
-                bucket.put_key(self.hash, self.key)
-            },
-        }
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2822,7 +2728,6 @@ mod test_map {
     use super::RandomState;
     use cell::RefCell;
     use rand::{thread_rng, Rng};
-    use panic;
     use realstd::collections::CollectionAllocErr::*;
     use realstd::mem::size_of;
     use realstd::usize;
@@ -3708,59 +3613,6 @@ fn test_adaptive() {
         panic!("Adaptive early resize failed");
     }
 
-    #[test]
-    fn test_placement_in() {
-        let mut map = HashMap::new();
-        map.extend((0..10).map(|i| (i, i)));
-
-        map.entry(100) <- 100;
-        assert_eq!(map[&100], 100);
-
-        map.entry(0) <- 10;
-        assert_eq!(map[&0], 10);
-
-        assert_eq!(map.len(), 11);
-    }
-
-    #[test]
-    fn test_placement_panic() {
-        let mut map = HashMap::new();
-        map.extend((0..10).map(|i| (i, i)));
-
-        fn mkpanic() -> usize { panic!() }
-
-        // modify existing key
-        // when panic happens, previous key is removed.
-        let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { map.entry(0) <- mkpanic(); }));
-        assert_eq!(map.len(), 9);
-        assert!(!map.contains_key(&0));
-
-        // add new key
-        let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { map.entry(100) <- mkpanic(); }));
-        assert_eq!(map.len(), 9);
-        assert!(!map.contains_key(&100));
-    }
-
-    #[test]
-    fn test_placement_drop() {
-        // correctly drop
-        struct TestV<'a>(&'a mut bool);
-        impl<'a> Drop for TestV<'a> {
-            fn drop(&mut self) {
-                if !*self.0 { panic!("value double drop!"); } // no double drop
-                *self.0 = false;
-            }
-        }
-
-        fn makepanic<'a>() -> TestV<'a> { panic!() }
-
-        let mut can_drop = true;
-        let mut hm = HashMap::new();
-        hm.insert(0, TestV(&mut can_drop));
-        let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { hm.entry(0) <- makepanic(); }));
-        assert_eq!(hm.len(), 0);
-    }
-
     #[test]
     fn test_try_reserve() {
 
index 8e78dc546c6c7de108f26eb57a412fa1ce323669..fa6053d3f6d8ea136029c2b15bd2208ae7995c70 100644 (file)
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use alloc::heap::{Heap, Alloc, Layout};
+use alloc::heap::Heap;
+use core::heap::{Alloc, Layout};
 
 use cmp;
 use hash::{BuildHasher, Hash, Hasher};
@@ -485,21 +486,6 @@ pub fn put(mut self, hash: SafeHash, key: K, value: V) -> FullBucket<K, V, M> {
             table: self.table,
         }
     }
-
-    /// Puts given key, remain value uninitialized.
-    /// It is only used for inplacement insertion.
-    pub unsafe fn put_key(mut self, hash: SafeHash, key: K) -> FullBucket<K, V, M> {
-        *self.raw.hash() = hash.inspect();
-        let pair_ptr = self.raw.pair();
-        ptr::write(&mut (*pair_ptr).0, key);
-
-        self.table.borrow_table_mut().size += 1;
-
-        FullBucket {
-            raw: self.raw,
-            table: self.table,
-        }
-    }
 }
 
 impl<K, V, M: Deref<Target = RawTable<K, V>>> FullBucket<K, V, M> {
@@ -575,17 +561,6 @@ pub fn take(self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) {
             v)
         }
     }
-
-    /// Remove this bucket's `key` from the hashtable.
-    /// Only used for inplacement insertion.
-    /// NOTE: `Value` is uninitialized when this function is called, don't try to drop the `Value`.
-    pub unsafe fn remove_key(&mut self) {
-        self.table.size -= 1;
-
-        *self.raw.hash() = EMPTY_BUCKET;
-        let pair_ptr = self.raw.pair();
-        ptr::drop_in_place(&mut (*pair_ptr).0); // only drop key
-    }
 }
 
 // This use of `Put` is misleading and restrictive, but safe and sufficient for our use cases
index 1b2ed2f6eb6cccf3eea044c2f383674e5e18fc9d..479e4d08f4b4d49b8fe111f591b3fc9972fd4acc 100644 (file)
@@ -297,12 +297,12 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
 /// use std::net::SocketAddr;
 ///
 /// fn main() -> Result<(), Box<std::error::Error + 'static>> {
-///     let foo: SocketAddr = fs::read_string("address.txt")?.parse()?;
+///     let foo: SocketAddr = fs::read_to_string("address.txt")?.parse()?;
 ///     Ok(())
 /// }
 /// ```
-#[unstable(feature = "fs_read_write", issue = "46588")]
-pub fn read_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
+#[stable(feature = "fs_read_write", since = "1.26.0")]
+pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
     let mut file = File::open(path)?;
     let mut string = String::with_capacity(initial_buffer_size(&file));
     file.read_to_string(&mut string)?;
@@ -3122,12 +3122,12 @@ fn write_then_read() {
         assert!(v == &bytes[..]);
 
         check!(fs::write(&tmpdir.join("not-utf8"), &[0xFF]));
-        error_contains!(fs::read_string(&tmpdir.join("not-utf8")),
+        error_contains!(fs::read_to_string(&tmpdir.join("not-utf8")),
                         "stream did not contain valid UTF-8");
 
         let s = "𐁁𐀓𐀠𐀴𐀍";
         check!(fs::write(&tmpdir.join("utf8"), s.as_bytes()));
-        let string = check!(fs::read_string(&tmpdir.join("utf8")));
+        let string = check!(fs::read_to_string(&tmpdir.join("utf8")));
         assert_eq!(string, s);
     }
 
index cefff2f143ce70f52a398f381ba2ab1e1286d349..3e9ae261ab64979f56b85896dee66a44144c2b38 100644 (file)
@@ -180,7 +180,7 @@ pub fn is_empty(&self) -> bool {
     ///
     /// # Examples
     ///
-    /// ```no_ru
+    /// ```no_run
     /// # #![feature(bufreader_buffer)]
     /// use std::io::{BufReader, BufRead};
     /// use std::fs::File;
index 68d3b946d9ef55af8b27318091d46915da396a9e..e18e055654bcb26e855066e5644692fa448361da 100644 (file)
 #![feature(panic_internals)]
 #![feature(panic_unwind)]
 #![feature(peek)]
-#![feature(placement_in_syntax)]
 #![feature(placement_new_protocol)]
 #![feature(prelude_import)]
 #![feature(ptr_internals)]
index 25fa9095536381c44179d228611603baaaffa619..fcec8d06853f67949c229d50b2e6807d8c3785c6 100644 (file)
@@ -778,7 +778,16 @@ fn from_inner(addr: c::in_addr) -> Ipv4Addr {
 
 #[stable(feature = "ip_u32", since = "1.1.0")]
 impl From<Ipv4Addr> for u32 {
-    /// It performs the conversion in network order (big-endian).
+    /// Convert an `Ipv4Addr` into a host byte order `u32`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::net::Ipv4Addr;
+    ///
+    /// let addr = Ipv4Addr::new(13, 12, 11, 10);
+    /// assert_eq!(0x0d0c0b0au32, u32::from(addr));
+    /// ```
     fn from(ip: Ipv4Addr) -> u32 {
         let ip = ip.octets();
         ((ip[0] as u32) << 24) + ((ip[1] as u32) << 16) + ((ip[2] as u32) << 8) + (ip[3] as u32)
@@ -787,7 +796,16 @@ fn from(ip: Ipv4Addr) -> u32 {
 
 #[stable(feature = "ip_u32", since = "1.1.0")]
 impl From<u32> for Ipv4Addr {
-    /// It performs the conversion in network order (big-endian).
+    /// Convert a host byte order `u32` into an `Ipv4Addr`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::net::Ipv4Addr;
+    ///
+    /// let addr = Ipv4Addr::from(0x0d0c0b0au32);
+    /// assert_eq!(Ipv4Addr::new(13, 12, 11, 10), addr);
+    /// ```
     fn from(ip: u32) -> Ipv4Addr {
         Ipv4Addr::new((ip >> 24) as u8, (ip >> 16) as u8, (ip >> 8) as u8, ip as u8)
     }
@@ -795,6 +813,14 @@ fn from(ip: u32) -> Ipv4Addr {
 
 #[stable(feature = "from_slice_v4", since = "1.9.0")]
 impl From<[u8; 4]> for Ipv4Addr {
+    /// # Examples
+    ///
+    /// ```
+    /// use std::net::Ipv4Addr;
+    ///
+    /// let addr = Ipv4Addr::from([13u8, 12u8, 11u8, 10u8]);
+    /// assert_eq!(Ipv4Addr::new(13, 12, 11, 10), addr);
+    /// ```
     fn from(octets: [u8; 4]) -> Ipv4Addr {
         Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3])
     }
@@ -802,6 +828,16 @@ fn from(ip: u32) -> Ipv4Addr {
 
 #[stable(feature = "ip_from_slice", since = "1.17.0")]
 impl From<[u8; 4]> for IpAddr {
+    /// Create an `IpAddr::V4` from a four element byte array.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::net::{IpAddr, Ipv4Addr};
+    ///
+    /// let addr = IpAddr::from([13u8, 12u8, 11u8, 10u8]);
+    /// assert_eq!(IpAddr::V4(Ipv4Addr::new(13, 12, 11, 10)), addr);
+    /// ```
     fn from(octets: [u8; 4]) -> IpAddr {
         IpAddr::V4(Ipv4Addr::from(octets))
     }
@@ -1395,6 +1431,27 @@ fn from(ip: u128) -> Ipv6Addr {
 
 #[stable(feature = "ip_from_slice", since = "1.17.0")]
 impl From<[u8; 16]> for IpAddr {
+    /// Create an `IpAddr::V6` from a sixteen element byte array.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::net::{IpAddr, Ipv6Addr};
+    ///
+    /// let addr = IpAddr::from([
+    ///     25u8, 24u8, 23u8, 22u8, 21u8, 20u8, 19u8, 18u8,
+    ///     17u8, 16u8, 15u8, 14u8, 13u8, 12u8, 11u8, 10u8,
+    /// ]);
+    /// assert_eq!(
+    ///     IpAddr::V6(Ipv6Addr::new(
+    ///         0x1918, 0x1716,
+    ///         0x1514, 0x1312,
+    ///         0x1110, 0x0f0e,
+    ///         0x0d0c, 0x0b0a
+    ///     )),
+    ///     addr
+    /// );
+    /// ```
     fn from(octets: [u8; 16]) -> IpAddr {
         IpAddr::V6(Ipv6Addr::from(octets))
     }
@@ -1402,6 +1459,27 @@ fn from(ip: u128) -> Ipv6Addr {
 
 #[stable(feature = "ip_from_slice", since = "1.17.0")]
 impl From<[u16; 8]> for IpAddr {
+    /// Create an `IpAddr::V6` from an eight element 16-bit array.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::net::{IpAddr, Ipv6Addr};
+    ///
+    /// let addr = IpAddr::from([
+    ///     525u16, 524u16, 523u16, 522u16,
+    ///     521u16, 520u16, 519u16, 518u16,
+    /// ]);
+    /// assert_eq!(
+    ///     IpAddr::V6(Ipv6Addr::new(
+    ///         0x20d, 0x20c,
+    ///         0x20b, 0x20a,
+    ///         0x209, 0x208,
+    ///         0x207, 0x206
+    ///     )),
+    ///     addr
+    /// );
+    /// ```
     fn from(segments: [u16; 8]) -> IpAddr {
         IpAddr::V6(Ipv6Addr::from(segments))
     }
index 92e9f48f7ebefe27ce5328f56a4e70a6770d068b..b463a6d88fe8e76a9cad34c0e3d09733ae7c8faa 100644 (file)
@@ -1420,14 +1420,13 @@ pub fn abort() -> ! {
 /// Basic usage:
 ///
 /// ```no_run
-/// #![feature(getpid)]
 /// use std::process;
 ///
 /// println!("My pid is {}", process::id());
 /// ```
 ///
 ///
-#[unstable(feature = "getpid", issue = "44971", reason = "recently added")]
+#[stable(feature = "getpid", since = "1.27.0")]
 pub fn id() -> u32 {
     ::sys::os::getpid()
 }
index e1392762a59dc7c76e5b73142b11b05a9702bae7..8f945470b7e94b25646f6336a14cfa7d3b84dd1f 100644 (file)
@@ -73,3 +73,18 @@ fn lang_start<T: ::process::Termination + 'static>
 {
     lang_start_internal(&move || main().report(), argc, argv)
 }
+
+/// Function used for reverting changes to the main stack before setrlimit().
+/// This is POSIX (non-Linux) specific and unlikely to be directly stabilized.
+#[unstable(feature = "rustc_stack_internals", issue = "0")]
+pub unsafe fn deinit_stack_guard() {
+    ::sys::thread::guard::deinit();
+}
+
+/// Function used for resetting the main stack guard address after setrlimit().
+/// This is POSIX specific and unlikely to be directly stabilized.
+#[unstable(feature = "rustc_stack_internals", issue = "0")]
+pub unsafe fn update_stack_guard() {
+    let main_guard = ::sys::thread::guard::init();
+    ::sys_common::thread_info::reset_guard(main_guard);
+}
index 78a3b82546e3a93258d753b810c6846f45ad1da9..a22d9053b6964a1721879a7b2f7d13ada2d7398d 100644 (file)
@@ -118,6 +118,7 @@ pub unsafe fn current() -> Option<Guard> {
     pub unsafe fn init() -> Option<Guard> {
         None
     }
+    pub unsafe fn deinit() {}
 }
 
 fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
index c4719a94c7e9dfa15252e216af2180c62b886a14..f20350269b7cf8a4fe8b3d5bd4d9fa928ded1ba1 100644 (file)
@@ -91,4 +91,5 @@ pub mod guard {
     pub type Guard = !;
     pub unsafe fn current() -> Option<Guard> { None }
     pub unsafe fn init() -> Option<Guard> { None }
+    pub unsafe fn deinit() {}
 }
index 72cdb9440b8e7e3bdae6a51ebf554f0268dbdf10..2db3d4a5744e7f145ef46af5164413c4fe76a1a1 100644 (file)
@@ -209,6 +209,7 @@ pub mod guard {
     pub type Guard = Range<usize>;
     pub unsafe fn current() -> Option<Guard> { None }
     pub unsafe fn init() -> Option<Guard> { None }
+    pub unsafe fn deinit() {}
 }
 
 
@@ -222,8 +223,8 @@ pub unsafe fn init() -> Option<Guard> { None }
 #[cfg_attr(test, allow(dead_code))]
 pub mod guard {
     use libc;
-    use libc::mmap;
-    use libc::{PROT_NONE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED};
+    use libc::{mmap, mprotect};
+    use libc::{PROT_NONE, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED};
     use ops::Range;
     use sys::os;
 
@@ -284,10 +285,10 @@ unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
         ret
     }
 
-    pub unsafe fn init() -> Option<Guard> {
-        PAGE_SIZE = os::page_size();
-
-        let mut stackaddr = get_stack_start()?;
+    // Precondition: PAGE_SIZE is initialized.
+    unsafe fn get_stack_start_aligned() -> Option<*mut libc::c_void> {
+        assert!(PAGE_SIZE != 0);
+        let stackaddr = get_stack_start()?;
 
         // Ensure stackaddr is page aligned! A parent process might
         // have reset RLIMIT_STACK to be non-page aligned. The
@@ -296,10 +297,17 @@ pub unsafe fn init() -> Option<Guard> {
         // page-aligned, calculate the fix such that stackaddr <
         // new_page_aligned_stackaddr < stackaddr + stacksize
         let remainder = (stackaddr as usize) % PAGE_SIZE;
-        if remainder != 0 {
-            stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder)
-                as *mut libc::c_void;
-        }
+        Some(if remainder == 0 {
+            stackaddr
+        } else {
+            ((stackaddr as usize) + PAGE_SIZE - remainder) as *mut libc::c_void
+        })
+    }
+
+    pub unsafe fn init() -> Option<Guard> {
+        PAGE_SIZE = os::page_size();
+
+        let stackaddr = get_stack_start_aligned()?;
 
         if cfg!(target_os = "linux") {
             // Linux doesn't allocate the whole stack right away, and
@@ -336,6 +344,26 @@ pub unsafe fn init() -> Option<Guard> {
         }
     }
 
+    pub unsafe fn deinit() {
+        if !cfg!(target_os = "linux") {
+            if let Some(stackaddr) = get_stack_start_aligned() {
+                // Remove the protection on the guard page.
+                // FIXME: we cannot unmap the page, because when we mmap()
+                // above it may be already mapped by the OS, which we can't
+                // detect from mmap()'s return value. If we unmap this page,
+                // it will lead to failure growing stack size on platforms like
+                // macOS. Instead, just restore the page to a writable state.
+                // This ain't Linux, so we probably don't need to care about
+                // execstack.
+                let result = mprotect(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE);
+
+                if result != 0 {
+                    panic!("unable to reset the guard page");
+                }
+            }
+        }
+    }
+
     #[cfg(any(target_os = "macos",
               target_os = "bitrig",
               target_os = "openbsd",
index 6a066509b492a6c1adac441367f233e1ed7c2726..7345843b975e4b8cd5b66c05d440b0b5a5174ad7 100644 (file)
@@ -46,4 +46,5 @@ pub mod guard {
     pub type Guard = !;
     pub unsafe fn current() -> Option<Guard> { None }
     pub unsafe fn init() -> Option<Guard> { None }
+    pub unsafe fn deinit() {}
 }
index 43abfbb1f645e9852974df82d7a26f2dc706787d..4b3d1b586b5701cc0776f9ec8855669dde063a4d 100644 (file)
@@ -96,4 +96,5 @@ pub mod guard {
     pub type Guard = !;
     pub unsafe fn current() -> Option<Guard> { None }
     pub unsafe fn init() -> Option<Guard> { None }
+    pub unsafe fn deinit() {}
 }
index 6a2b6742367a5b4ce6032cfe943b9708fb9b9da9..d75cbded7347b2936d03b0ac571b93e2902d63e2 100644 (file)
@@ -50,3 +50,7 @@ pub fn set(stack_guard: Option<Guard>, thread: Thread) {
         thread,
     }));
 }
+
+pub fn reset_guard(stack_guard: Option<Guard>) {
+    THREAD_INFO.with(move |c| c.borrow_mut().as_mut().unwrap().stack_guard = stack_guard);
+}
index c90b0aecfc04459b53eb666b78eb36570eefb24f..31bb1c88b8712486b6d7ab00f497198a1801a5d9 100644 (file)
@@ -1011,7 +1011,6 @@ pub(super) fn to_ty(&self) -> Option<P<Ty>> {
     pub fn precedence(&self) -> ExprPrecedence {
         match self.node {
             ExprKind::Box(_) => ExprPrecedence::Box,
-            ExprKind::InPlace(..) => ExprPrecedence::InPlace,
             ExprKind::Array(_) => ExprPrecedence::Array,
             ExprKind::Call(..) => ExprPrecedence::Call,
             ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
@@ -1071,8 +1070,6 @@ pub enum RangeLimits {
 pub enum ExprKind {
     /// A `box x` expression.
     Box(P<Expr>),
-    /// First expr is the place; second expr is the value.
-    InPlace(P<Expr>, P<Expr>),
     /// An array (`[a, b, c, d]`)
     Array(Vec<P<Expr>>),
     /// A function call
index 61246d4493ca387810f5004941ba1f5324061dbd..e579fc74b42661753386440869b2bc0ac16c213d 100644 (file)
@@ -55,6 +55,13 @@ pub fn lint_name(&self) -> &'static str {
             Edition::Edition2018 => "edition_2018",
         }
     }
+
+    pub fn feature_name(&self) -> &'static str {
+        match *self {
+            Edition::Edition2015 => "rust_2015_preview",
+            Edition::Edition2018 => "rust_2018_preview",
+        }
+    }
 }
 
 impl FromStr for Edition {
index 71609af803e09664716fbef37d7c21b02c261ded..e734a4e3735342ff5895290d14780c16a7e1885f 100644 (file)
@@ -28,7 +28,7 @@
 use abi::Abi;
 use ast::{self, NodeId, PatKind, RangeEnd};
 use attr;
-use edition::Edition;
+use edition::{ALL_EDITIONS, Edition};
 use codemap::Spanned;
 use syntax_pos::{Span, DUMMY_SP};
 use errors::{DiagnosticBuilder, Handler, FatalError};
@@ -146,7 +146,6 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     (active, rustc_diagnostic_macros, "1.0.0", None, None),
     (active, rustc_const_unstable, "1.0.0", None, None),
     (active, box_syntax, "1.0.0", Some(27779), None),
-    (active, placement_in_syntax, "1.0.0", Some(27779), None),
     (active, unboxed_closures, "1.0.0", Some(29625), None),
 
     (active, fundamental, "1.0.0", Some(29635), None),
@@ -1287,9 +1286,6 @@ fn leveled_feature_err<'a>(sess: &'a ParseSess, feature: &str, span: Span, issue
 pub const EXPLAIN_LIFETIME_MATCHER: &'static str =
     ":lifetime fragment specifier is experimental and subject to change";
 
-pub const EXPLAIN_PLACEMENT_IN: &'static str =
-    "placement-in expression syntax is experimental and subject to change.";
-
 pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &'static str =
     "Unsized tuple coercion is not stable enough for use and is subject to change";
 
@@ -1636,9 +1632,6 @@ fn visit_expr(&mut self, e: &'a ast::Expr) {
                 gate_feature_post!(&self, type_ascription, e.span,
                                   "type ascription is experimental");
             }
-            ast::ExprKind::InPlace(..) => {
-                gate_feature_post!(&self, placement_in_syntax, e.span, EXPLAIN_PLACEMENT_IN);
-            }
             ast::ExprKind::Yield(..) => {
                 gate_feature_post!(&self, generators,
                                   e.span,
@@ -1800,21 +1793,15 @@ fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
 }
 
 pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
-                    edition: Edition) -> Features {
+                    crate_edition: Edition) -> Features {
+    fn feature_removed(span_handler: &Handler, span: Span) {
+        span_err!(span_handler, span, E0557, "feature has been removed");
+    }
+
     let mut features = Features::new();
 
     let mut feature_checker = FeatureChecker::default();
 
-    for &(.., f_edition, set) in ACTIVE_FEATURES.iter() {
-        if let Some(f_edition) = f_edition {
-            if edition >= f_edition {
-                // FIXME(Manishearth) there is currently no way to set
-                // lang features by edition
-                set(&mut features, DUMMY_SP);
-            }
-        }
-    }
-
     for attr in krate_attrs {
         if !attr.check_name("feature") {
             continue
@@ -1827,6 +1814,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
             }
             Some(list) => {
                 for mi in list {
+
                     let name = if let Some(word) = mi.word() {
                         word.name()
                     } else {
@@ -1844,11 +1832,26 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
                             .find(|& &(n, _, _)| name == n)
                         .or_else(|| STABLE_REMOVED_FEATURES.iter()
                             .find(|& &(n, _, _)| name == n)) {
-                        span_err!(span_handler, mi.span, E0557, "feature has been removed");
+                        feature_removed(span_handler, mi.span);
                     }
                     else if let Some(&(_, _, _)) = ACCEPTED_FEATURES.iter()
                         .find(|& &(n, _, _)| name == n) {
                         features.declared_stable_lang_features.push((name, mi.span));
+                    } else if let Some(&edition) = ALL_EDITIONS.iter()
+                                                              .find(|e| name == e.feature_name()) {
+                        if edition <= crate_edition {
+                            feature_removed(span_handler, mi.span);
+                        } else {
+                            for &(.., f_edition, set) in ACTIVE_FEATURES.iter() {
+                                if let Some(f_edition) = f_edition {
+                                    if edition >= f_edition {
+                                        // FIXME(Manishearth) there is currently no way to set
+                                        // lib features by edition
+                                        set(&mut features, DUMMY_SP);
+                                    }
+                                }
+                            }
+                        }
                     } else {
                         features.declared_lib_features.push((name, mi.span));
                     }
index 05a3150c139c92a753fbe87cf67b08372f150e01..e702bf56e7f83faf69b0cbcfbcfcf52faf1169ca 100644 (file)
@@ -1167,9 +1167,6 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
             ExprKind::Box(e) => {
                 ExprKind::Box(folder.fold_expr(e))
             }
-            ExprKind::InPlace(p, e) => {
-                ExprKind::InPlace(folder.fold_expr(p), folder.fold_expr(e))
-            }
             ExprKind::Array(exprs) => {
                 ExprKind::Array(folder.fold_exprs(exprs))
             }
index 262198b6b15accff9289931ce11ad6cc72b55ce7..f5ab023b30e8f0fa4ff8cf12163c43b09dce6c7b 100644 (file)
@@ -455,7 +455,7 @@ pub fn span_err<S: Into<MultiSpan>>(self,
                                            ref dir_path } => {
                 let mut err = struct_span_err!(handler, sp, E0583,
                                                "file not found for module `{}`", mod_name);
-                err.help(&format!("name the file either {} or {} inside the directory {:?}",
+                err.help(&format!("name the file either {} or {} inside the directory \"{}\"",
                                   default_path,
                                   secondary_path,
                                   dir_path));
@@ -2850,17 +2850,6 @@ pub fn parse_prefix_expr(&mut self,
                 let (span, e) = self.interpolated_or_expr_span(e)?;
                 (lo.to(span), ExprKind::AddrOf(m, e))
             }
-            token::Ident(..) if self.token.is_keyword(keywords::In) => {
-                self.bump();
-                let place = self.parse_expr_res(
-                    Restrictions::NO_STRUCT_LITERAL,
-                    None,
-                )?;
-                let blk = self.parse_block()?;
-                let span = blk.span;
-                let blk_expr = self.mk_expr(span, ExprKind::Block(blk), ThinVec::new());
-                (lo.to(span), ExprKind::InPlace(place, blk_expr))
-            }
             token::Ident(..) if self.token.is_keyword(keywords::Box) => {
                 self.bump();
                 let e = self.parse_prefix_expr(None);
@@ -3023,8 +3012,6 @@ pub fn parse_assoc_expr_with(&mut self,
                 }
                 AssocOp::Assign =>
                     self.mk_expr(span, ExprKind::Assign(lhs, rhs), ThinVec::new()),
-                AssocOp::Inplace =>
-                    self.mk_expr(span, ExprKind::InPlace(lhs, rhs), ThinVec::new()),
                 AssocOp::AssignOp(k) => {
                     let aop = match k {
                         token::Plus =>    BinOpKind::Add,
index ae045fc095a5067bb1331fd65da16580433b3f61..c3785c10f6905bd6f941284ebd3a416e1998b8df 100644 (file)
@@ -1877,16 +1877,6 @@ pub fn print_expr_as_cond(&mut self, expr: &ast::Expr) -> io::Result<()> {
         Ok(())
     }
 
-    fn print_expr_in_place(&mut self,
-                           place: &ast::Expr,
-                           expr: &ast::Expr) -> io::Result<()> {
-        let prec = AssocOp::Inplace.precedence() as i8;
-        self.print_expr_maybe_paren(place, prec + 1)?;
-        self.s.space()?;
-        self.word_space("<-")?;
-        self.print_expr_maybe_paren(expr, prec)
-    }
-
     fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>],
                       attrs: &[Attribute]) -> io::Result<()> {
         self.ibox(INDENT_UNIT)?;
@@ -2056,9 +2046,6 @@ fn print_expr_outer_attr_style(&mut self,
                 self.word_space("box")?;
                 self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)?;
             }
-            ast::ExprKind::InPlace(ref place, ref expr) => {
-                self.print_expr_in_place(place, expr)?;
-            }
             ast::ExprKind::Array(ref exprs) => {
                 self.print_expr_vec(&exprs[..], attrs)?;
             }
index 86963c4000bd16c84e40a6c77a24e4f13b54b196..4770273e8c4a71583050ecef2b135324f4c34962 100644 (file)
@@ -56,8 +56,6 @@ pub enum AssocOp {
     GreaterEqual,
     /// `=`
     Assign,
-    /// `<-`
-    Inplace,
     /// `?=` where ? is one of the BinOpToken
     AssignOp(BinOpToken),
     /// `as`
@@ -86,7 +84,6 @@ pub fn from_token(t: &Token) -> Option<AssocOp> {
         use self::AssocOp::*;
         match *t {
             Token::BinOpEq(k) => Some(AssignOp(k)),
-            Token::LArrow => Some(Inplace),
             Token::Eq => Some(Assign),
             Token::BinOp(BinOpToken::Star) => Some(Multiply),
             Token::BinOp(BinOpToken::Slash) => Some(Divide),
@@ -156,7 +153,6 @@ pub fn precedence(&self) -> usize {
             LAnd => 6,
             LOr => 5,
             DotDot | DotDotEq => 4,
-            Inplace => 3,
             Assign | AssignOp(_) => 2,
         }
     }
@@ -166,7 +162,7 @@ pub fn fixity(&self) -> Fixity {
         use self::AssocOp::*;
         // NOTE: it is a bug to have an operators that has same precedence but different fixities!
         match *self {
-            Inplace | Assign | AssignOp(_) => Fixity::Right,
+            Assign | AssignOp(_) => Fixity::Right,
             As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd |
             BitXor | BitOr | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual |
             LAnd | LOr | Colon => Fixity::Left,
@@ -178,7 +174,7 @@ pub fn is_comparison(&self) -> bool {
         use self::AssocOp::*;
         match *self {
             Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => true,
-            Inplace | Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add | Subtract |
+            Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add | Subtract |
             ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr |
             DotDot | DotDotEq | Colon => false
         }
@@ -187,7 +183,7 @@ pub fn is_comparison(&self) -> bool {
     pub fn is_assign_like(&self) -> bool {
         use self::AssocOp::*;
         match *self {
-            Assign | AssignOp(_) | Inplace => true,
+            Assign | AssignOp(_) => true,
             Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply | Divide |
             Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd |
             LOr | DotDot | DotDotEq | Colon => false
@@ -215,7 +211,7 @@ pub fn to_ast_binop(&self) -> Option<BinOpKind> {
             BitOr => Some(BinOpKind::BitOr),
             LAnd => Some(BinOpKind::And),
             LOr => Some(BinOpKind::Or),
-            Inplace | Assign | AssignOp(_) | As | DotDot | DotDotEq | Colon => None
+            Assign | AssignOp(_) | As | DotDot | DotDotEq | Colon => None
         }
     }
 }
@@ -242,7 +238,6 @@ pub enum ExprPrecedence {
 
     Binary(BinOpKind),
 
-    InPlace,
     Cast,
     Type,
 
@@ -310,7 +305,6 @@ pub fn order(self) -> i8 {
 
             // Binop-like expr kinds, handled by `AssocOp`.
             ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8,
-            ExprPrecedence::InPlace => AssocOp::Inplace.precedence() as i8,
             ExprPrecedence::Cast => AssocOp::As.precedence() as i8,
             ExprPrecedence::Type => AssocOp::Colon.precedence() as i8,
 
index bbf1fe124f1ba3f4f4b29fe124873bc3dab25bc6..d8de78054ab6f4ecce75f663503a2572abb5489f 100644 (file)
@@ -654,10 +654,6 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
         ExprKind::Box(ref subexpression) => {
             visitor.visit_expr(subexpression)
         }
-        ExprKind::InPlace(ref place, ref subexpression) => {
-            visitor.visit_expr(place);
-            visitor.visit_expr(subexpression)
-        }
         ExprKind::Array(ref subexpressions) => {
             walk_list!(visitor, visit_expr, subexpressions);
         }
index 85a2940ec442e0c80658ed1ffaa6bece9bf8a82c..aba71bd0468311cb67c2aa99db7f47052ed0287e 100644 (file)
@@ -430,7 +430,6 @@ pub enum ExpnFormat {
 /// The kind of compiler desugaring.
 #[derive(Clone, Hash, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub enum CompilerDesugaringKind {
-    BackArrow,
     DotFill,
     QuestionMark,
 }
@@ -439,7 +438,6 @@ impl CompilerDesugaringKind {
     pub fn as_symbol(&self) -> Symbol {
         use CompilerDesugaringKind::*;
         let s = match *self {
-            BackArrow => "<-",
             DotFill => "...",
             QuestionMark => "?",
         };
index bfd01146d2c4644eda47b5490b0789b424dd53f3..9fa33f911a1686f8118a3f31bbf6dde38578d653 100644 (file)
@@ -9,6 +9,16 @@
 // except according to those terms.
 
 #![feature(rustc_private)]
+#![feature(link_args)]
+
+// Set the stack size at link time on Windows. See rustc_driver::in_rustc_thread
+// for the rationale.
+#[cfg_attr(all(windows, target_env = "msvc"), link_args = "/STACK:16777216")]
+// We only build for msvc and gnu now, but we use a exhaustive condition here
+// so we can expect either the stack size to be set or the build fails.
+#[cfg_attr(all(windows, not(target_env = "msvc")), link_args = "-Wl,--stack,16777216")]
+// Also, don't forget to set this for rustdoc.
+extern {}
 
 extern crate rustc_driver;
 
index a1efbb88a4d2e26dc1e9c1ef274452a259e9cb59..d725adfec7544a6950ea29a1a7b13b71c902fcc1 100644 (file)
@@ -16,7 +16,7 @@
 
 extern crate proc_macro;
 
-use proc_macro::{TokenStream, TokenTree, TokenNode, Delimiter, Literal};
+use proc_macro::{TokenStream, TokenTree, TokenNode, Delimiter, Literal, Spacing};
 
 #[proc_macro_attribute]
 pub fn foo(attr: TokenStream, input: TokenStream) -> TokenStream {
@@ -65,10 +65,34 @@ fn assert_inline(slice: &mut &[TokenTree]) {
 
 fn assert_doc(slice: &mut &[TokenTree]) {
     match slice[0].kind {
+        TokenNode::Op('#', Spacing::Alone) => {}
+        _ => panic!("expected #"),
+    }
+    let inner = match slice[1].kind {
+        TokenNode::Group(Delimiter::Bracket, ref s) => s.clone(),
+        _ => panic!("expected brackets"),
+    };
+    let tokens = inner.into_iter().collect::<Vec<_>>();
+    let tokens = &tokens[..];
+
+    if tokens.len() != 3 {
+        panic!("expected three tokens in doc")
+    }
+
+    match tokens[0].kind {
+        TokenNode::Term(ref t) => assert_eq!("doc", t.as_str()),
+        _ => panic!("expected `doc`"),
+    }
+    match tokens[1].kind {
+        TokenNode::Op('=', Spacing::Alone) => {}
+        _ => panic!("expected equals"),
+    }
+    match tokens[2].kind {
         TokenNode::Literal(_) => {}
-        _ => panic!("expected literal doc comment got other"),
+        _ => panic!("expected literal"),
     }
-    *slice = &slice[1..];
+
+    *slice = &slice[2..];
 }
 
 fn assert_invoc(slice: &mut &[TokenTree]) {
index bf8e02adb1ae6580ae5d9cdaf93fbf9ea4f7bded..ef39fabda10e62f744b4eb186615c49c036f86da 100644 (file)
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// revisions: lxl nll
+// revisions: ast lxl nll
+//[ast]compile-flags:
 //[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows
 //[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll
 
 
 use std::ops::{Index, IndexMut};
 
-// This is case outlined by Niko that we want to ensure we reject
-// (at least initially).
-
 fn foo(x: &mut u32, y: u32) {
     *x += y;
 }
 
 fn deref_coercion(x: &mut u32) {
     foo(x, *x);
-    //[lxl]~^ ERROR cannot use `*x` because it was mutably borrowed [E0503]
-    //[nll]~^^ ERROR cannot use `*x` because it was mutably borrowed [E0503]
+    //[ast]~^ ERROR cannot use `*x` because it was mutably borrowed [E0503]
+    // Above error is a known limitation of AST borrowck
 }
 
 // While adding a flag to adjustments (indicating whether they
@@ -74,22 +72,25 @@ fn twice_ten_sm<F: FnMut(i32) -> i32>(f: &mut F) {
         //[lxl]~^     ERROR cannot borrow `*f` as mutable more than once at a time
         //[nll]~^^   ERROR cannot borrow `*f` as mutable more than once at a time
         //[g2p]~^^^ ERROR cannot borrow `*f` as mutable more than once at a time
+        //[ast]~^^^^ ERROR cannot borrow `*f` as mutable more than once at a time
     }
     fn twice_ten_si<F: Fn(i32) -> i32>(f: &mut F) {
         f(f(10));
     }
     fn twice_ten_so<F: FnOnce(i32) -> i32>(f: Box<F>) {
         f(f(10));
-        //[lxl]~^   ERROR use of moved value: `*f`
-        //[nll]~^^  ERROR use of moved value: `*f`
-        //[g2p]~^^^ ERROR use of moved value: `*f`
+        //[lxl]~^    ERROR use of moved value: `*f`
+        //[nll]~^^   ERROR use of moved value: `*f`
+        //[g2p]~^^^  ERROR use of moved value: `*f`
+        //[ast]~^^^^ ERROR use of moved value: `*f`
     }
 
     fn twice_ten_om(f: &mut FnMut(i32) -> i32) {
         f(f(10));
-        //[lxl]~^     ERROR cannot borrow `*f` as mutable more than once at a time
+        //[lxl]~^    ERROR cannot borrow `*f` as mutable more than once at a time
         //[nll]~^^   ERROR cannot borrow `*f` as mutable more than once at a time
-        //[g2p]~^^^ ERROR cannot borrow `*f` as mutable more than once at a time
+        //[g2p]~^^^  ERROR cannot borrow `*f` as mutable more than once at a time
+        //[ast]~^^^^ ERROR cannot borrow `*f` as mutable more than once at a time
     }
     fn twice_ten_oi(f: &mut Fn(i32) -> i32) {
         f(f(10));
@@ -105,6 +106,7 @@ fn twice_ten_oo(f: Box<FnOnce(i32) -> i32>) {
         //[g2p]~^^^^^^^       ERROR cannot move a value of type
         //[g2p]~^^^^^^^^      ERROR cannot move a value of type
         //[g2p]~^^^^^^^^^     ERROR use of moved value: `*f`
+        //[ast]~^^^^^^^^^^    ERROR use of moved value: `*f`
     }
 
     twice_ten_sm(&mut |x| x + 1);
@@ -142,12 +144,15 @@ fn coerce_unsized() {
 
     // This is not okay.
     double_access(&mut a, &a);
-    //[lxl]~^   ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
-    //[nll]~^^  ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
-    //[g2p]~^^^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
+    //[lxl]~^    ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
+    //[nll]~^^   ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
+    //[g2p]~^^^  ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
+    //[ast]~^^^^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
 
     // But this is okay.
     a.m(a.i(10));
+    //[ast]~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
+    // Above error is an expected limitation of AST borrowck
 }
 
 struct I(i32);
@@ -168,14 +173,16 @@ fn index_mut(&mut self, _: i32) -> &mut i32 {
 fn coerce_index_op() {
     let mut i = I(10);
     i[i[3]] = 4;
-    //[lxl]~^  ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
-    //[nll]~^^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
+    //[lxl]~^   ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
+    //[nll]~^^  ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
+    //[ast]~^^^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
 
     i[3] = i[4];
 
     i[i[3]] = i[4];
-    //[lxl]~^  ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
-    //[nll]~^^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
+    //[lxl]~^   ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
+    //[nll]~^^  ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
+    //[ast]~^^^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
 }
 
 fn main() {
@@ -183,6 +190,8 @@ fn main() {
     // As a reminder, this is the basic case we want to ensure we handle.
     let mut v = vec![1, 2, 3];
     v.push(v.len());
+    //[ast]~^ ERROR cannot borrow `v` as immutable because it is also borrowed as mutable [E0502]
+    // Error above is an expected limitation of AST borrowck
 
     // (as a rule, pnkfelix does not like to write tests with dead code.)
 
@@ -192,9 +201,13 @@ fn main() {
 
     let mut s = S;
     s.m(s.i(10));
+    //[ast]~^ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable [E0502]
+    // Error above is an expected limitation of AST borrowck
 
     let mut t = T;
     t.m(t.i(10));
+    //[ast]~^ ERROR cannot borrow `t` as immutable because it is also borrowed as mutable [E0502]
+    // Error above is an expected limitation of AST borrowck
 
     coerce_unsized();
     coerce_index_op();
index a058234a64921c33c5c143514f6554bf6f3a514f..93eb6b6b11544b0b9c6ec7ad4efc3b0c96d5196a 100644 (file)
@@ -180,6 +180,11 @@ pub fn deprecated() {}
     #[deprecated(since = "1.0.0", note = "text")]
     pub fn deprecated_text() {}
 
+    #[deprecated(since = "99.99.99", note = "text")]
+    pub fn deprecated_future() {}
+    #[deprecated(since = "99.99.99", note = "text")]
+    pub fn deprecated_future_text() {}
+
     pub struct MethodTester;
 
     impl MethodTester {
@@ -266,6 +271,9 @@ fn test() {
         <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
         <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
 
+        deprecated_future(); // Fine; no error.
+        deprecated_future_text(); // Fine; no error.
+
         let _ = DeprecatedStruct {
             //~^ ERROR use of deprecated item 'this_crate::DeprecatedStruct': text
             i: 0 //~ ERROR use of deprecated item 'this_crate::DeprecatedStruct::i': text
diff --git a/src/test/compile-fail/issue-14084.rs b/src/test/compile-fail/issue-14084.rs
deleted file mode 100644 (file)
index 446514c..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(box_syntax)]
-#![feature(placement_in_syntax)]
-
-fn main() {
-    () <- 0;
-    //~^ ERROR: `(): std::ops::Placer<_>` is not satisfied
-}
diff --git a/src/test/compile-fail/move-guard-same-consts.rs b/src/test/compile-fail/move-guard-same-consts.rs
new file mode 100644 (file)
index 0000000..05fe48e
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// #47295: We used to have a hack of special-casing adjacent amtch
+// arms whose patterns were composed solely of constants to not have
+// them linked in the cfg.
+//
+// THis was broken for various reasons. In particular, that hack was
+// originally authored under the assunption that other checks
+// elsewhere would ensure that the two patterns did not overlap.  But
+// that assumption did not hold, at least not in the long run (namely,
+// overlapping patterns were turned into warnings rather than errors).
+
+#![feature(box_syntax)]
+
+fn main() {
+    let x: Box<_> = box 1;
+
+    let v = (1, 2);
+
+    match v {
+        (1, 2) if take(x) => (),
+        (1, 2) if take(x) => (), //~ ERROR use of moved value: `x`
+        _ => (),
+    }
+}
+
+fn take<T>(_: T) -> bool { false }
diff --git a/src/test/compile-fail/placement-expr-unsafe.rs b/src/test/compile-fail/placement-expr-unsafe.rs
deleted file mode 100644 (file)
index bf6f4c5..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Check that placement in respects unsafe code checks.
-
-#![feature(box_heap)]
-#![feature(placement_in_syntax)]
-
-fn main() {
-    use std::boxed::HEAP;
-
-    let p: *const i32 = &42;
-    let _ = HEAP <- *p; //~ ERROR requires unsafe
-
-    let p: *const _ = &HEAP;
-    let _ = *p <- 42; //~ ERROR requires unsafe
-}
diff --git a/src/test/compile-fail/placement-expr-unstable.rs b/src/test/compile-fail/placement-expr-unstable.rs
deleted file mode 100644 (file)
index 35695ef..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Check that placement in respects unstable code checks.
-
-#![feature(placement_in_syntax)]
-
-fn main() {
-    use std::boxed::HEAP; //~ ERROR use of unstable library feature
-
-    let _ = HEAP <- { //~ ERROR use of unstable library feature
-        HEAP //~ ERROR use of unstable library feature
-    };
-}
index 5c0c47de58aed71c916bb1ccd0d9bbedb048e2b3..63408b76b153e3095843dfaa176939fd981565dd 100644 (file)
 fn that_odd_parse() {
     // following lines below parse and must not fail
     x = if c { a } else { b }();
-    x <- if c { a } else { b }[n];
     x = if true { 1 } else { 0 } as *mut _;
     // however this does not parse and probably should fail to retain compat?
-    // NB: `..` here is arbitrary, failure happens/should happen ∀ops that aren’t `=` or `<-`
+    // NB: `..` here is arbitrary, failure happens/should happen ∀ops that aren’t `=`
     // see assoc-oddities-2 and assoc-oddities-3
     ..if c { a } else { b }[n]; //~ ERROR expected one of
 }
index 17e6119f968aca0ea1778a096e35ee2c969743e1..b34e18520793a3f5c4b62f06cfb617268db07d44 100644 (file)
@@ -12,7 +12,6 @@
 
 #![feature(custom_attribute)]
 #![feature(box_syntax)]
-#![feature(placement_in_syntax)]
 #![feature(stmt_expr_attributes)]
 
 fn main() { }
index f3f7777d8d40427fd8d6f1d5b46ad415e96714a6..62cb870c7bb47b0010fb23397423bfb86b31b72b 100644 (file)
@@ -126,16 +126,6 @@ fn run() {
     check_expr_attrs("#[attr] box 0", outer);
     reject_expr_parse("box #![attr] 0");
 
-    check_expr_attrs("#[attr] 0 <- #[attr] 0", none);
-    check_expr_attrs("#[attr] (0 <- 0)", outer);
-    reject_expr_parse("0 #[attr] <- 0");
-    reject_expr_parse("0 <- #![attr] 0");
-
-    check_expr_attrs("in #[attr] 0 {#[attr] 0}", none);
-    check_expr_attrs("#[attr] (in 0 {0})", outer);
-    reject_expr_parse("in 0 #[attr] {0}");
-    reject_expr_parse("in 0 {#![attr] 0}");
-
     check_expr_attrs("#[attr] [#![attr]]", both);
     check_expr_attrs("#[attr] [#![attr] 0]", both);
     check_expr_attrs("#[attr] [#![attr] 0; 0]", both);
index 05fe274c49f35166fd13539106ca79348fef2a96..920760cd34ac8d0ecd3eb1ad6f94ed6a1ae38b6c 100644 (file)
@@ -84,18 +84,11 @@ fn iter_exprs(depth: usize, f: &mut FnMut(P<Expr>)) {
 
     let mut g = |e| f(expr(e));
 
-    for kind in 0 .. 17 {
+    for kind in 0 .. 16 {
         match kind {
             0 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Box(e))),
-            1 => {
-                // Note that for binary expressions, we explore each side separately.  The
-                // parenthesization decisions for the LHS and RHS should be independent, and this
-                // way produces `O(n)` results instead of `O(n^2)`.
-                iter_exprs(depth - 1, &mut |e| g(ExprKind::InPlace(e, make_x())));
-                iter_exprs(depth - 1, &mut |e| g(ExprKind::InPlace(make_x(), e)));
-            },
-            2 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Call(e, vec![]))),
-            3 => {
+            1 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Call(e, vec![]))),
+            2 => {
                 let seg = PathSegment {
                     identifier: Ident::from_str("x"),
                     span: DUMMY_SP,
@@ -107,25 +100,25 @@ fn iter_exprs(depth: usize, f: &mut FnMut(P<Expr>)) {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall(
                             seg.clone(), vec![make_x(), e])));
             },
-            4 => {
+            3 => {
                 let op = Spanned { span: DUMMY_SP, node: BinOpKind::Add };
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, e, make_x())));
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, make_x(), e)));
             },
-            5 => {
+            4 => {
                 let op = Spanned { span: DUMMY_SP, node: BinOpKind::Mul };
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, e, make_x())));
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, make_x(), e)));
             },
-            6 => {
+            5 => {
                 let op = Spanned { span: DUMMY_SP, node: BinOpKind::Shl };
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, e, make_x())));
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, make_x(), e)));
             },
-            7 => {
+            6 => {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Unary(UnOp::Deref, e)));
             },
-            8 => {
+            7 => {
                 let block = P(Block {
                     stmts: Vec::new(),
                     id: DUMMY_NODE_ID,
@@ -135,7 +128,7 @@ fn iter_exprs(depth: usize, f: &mut FnMut(P<Expr>)) {
                 });
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None)));
             },
-            9 => {
+            8 => {
                 let decl = P(FnDecl {
                     inputs: vec![],
                     output: FunctionRetTy::Default(DUMMY_SP),
@@ -148,28 +141,28 @@ fn iter_exprs(depth: usize, f: &mut FnMut(P<Expr>)) {
                                           e,
                                           DUMMY_SP)));
             },
-            10 => {
+            9 => {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(e, make_x())));
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(make_x(), e)));
             },
-            11 => {
+            10 => {
                 let ident = Spanned { span: DUMMY_SP, node: Ident::from_str("f") };
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Field(e, ident)));
             },
-            12 => {
+            11 => {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Range(
                             Some(e), Some(make_x()), RangeLimits::HalfOpen)));
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Range(
                             Some(make_x()), Some(e), RangeLimits::HalfOpen)));
             },
-            13 => {
+            12 => {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::AddrOf(Mutability::Immutable, e)));
             },
-            14 => {
+            13 => {
                 g(ExprKind::Ret(None));
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Ret(Some(e))));
             },
-            15 => {
+            14 => {
                 let seg = PathSegment {
                     identifier: Ident::from_str("S"),
                     span: DUMMY_SP,
@@ -181,7 +174,7 @@ fn iter_exprs(depth: usize, f: &mut FnMut(P<Expr>)) {
                 };
                 g(ExprKind::Struct(path, vec![], Some(make_x())));
             },
-            16 => {
+            15 => {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Try(e)));
             },
             _ => panic!("bad counter value in iter_exprs"),
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/negative-token.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/negative-token.rs
new file mode 100644 (file)
index 0000000..e5ebb7c
--- /dev/null
@@ -0,0 +1,34 @@
+// 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.
+
+// no-prefer-dynamic
+
+#![feature(proc_macro)]
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::*;
+
+#[proc_macro]
+pub fn neg_one(_input: TokenStream) -> TokenStream {
+    TokenTree {
+        span: Span::call_site(),
+        kind: TokenNode::Literal(Literal::i32(-1)),
+    }.into()
+}
+
+#[proc_macro]
+pub fn neg_one_float(_input: TokenStream) -> TokenStream {
+    TokenTree {
+        span: Span::call_site(),
+        kind: TokenNode::Literal(Literal::f32(-1.0)),
+    }.into()
+}
diff --git a/src/test/run-pass-fulldeps/proc-macro/negative-token.rs b/src/test/run-pass-fulldeps/proc-macro/negative-token.rs
new file mode 100644 (file)
index 0000000..418e692
--- /dev/null
@@ -0,0 +1,23 @@
+// 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.
+
+// aux-build:negative-token.rs
+// ignore-stage1
+
+#![feature(proc_macro)]
+
+extern crate negative_token;
+
+use negative_token::*;
+
+fn main() {
+    assert_eq!(-1, neg_one!());
+    assert_eq!(-1.0, neg_one_float!());
+}
index f3d8f216e1132e7edc3cbe9ffef27a15daef610d..e3cd1edd20987786dfa1cf891d42203885d77387 100644 (file)
@@ -11,7 +11,7 @@
 // Checks if the correct registers are being used to pass arguments
 // when the sysv64 ABI is specified.
 
-// compile-flags: -Zedition=2018
+#![feature(rust_2018_preview)]
 
 pub trait Foo {}
 
diff --git a/src/test/run-pass/move-guard-const.rs b/src/test/run-pass/move-guard-const.rs
deleted file mode 100644 (file)
index 6e49538..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// pretty-expanded FIXME #23616
-
-#![feature(box_syntax)]
-
-fn main() {
-    let x: Box<_> = box 1;
-
-    let v = (1, 2);
-
-    match v {
-        (2, 1) if take(x) => (),
-        (1, 2) if take(x) => (),
-        _ => (),
-    }
-}
-
-fn take<T>(_: T) -> bool { false }
index 34687c6ca1de31b40b56b9e5011d62ca476a7355..6598b70b3d5cdc8119edfadfe1d06798b69ce7bd 100644 (file)
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 #![allow(dead_code, unused_variables)]
-#![feature(box_syntax, box_heap)]
-#![feature(placement_in_syntax)]
-
-// during check-pretty, the expanded code needs to opt into these
-// features
-#![feature(placement_new_protocol, core_intrinsics)]
+#![feature(box_syntax)]
 
 // Tests that the new `box` syntax works with unique pointers.
 
-use std::boxed::{Box, HEAP};
+use std::boxed::Box;
 
 struct Structure {
     x: isize,
@@ -31,7 +26,6 @@ struct Structure {
 }
 
 pub fn main() {
-    let x: Box<isize> = in HEAP { 2 };
     let y: Box<isize> = box 2;
     let b: Box<isize> = box (1 + 2);
     let c = box (3 + 4);
diff --git a/src/test/run-pass/placement-in-syntax.rs b/src/test/run-pass/placement-in-syntax.rs
deleted file mode 100644 (file)
index 7bda9ae..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(dead_code, unused_variables)]
-#![feature(box_heap)]
-#![feature(placement_in_syntax)]
-
-// Tests that the new `in` syntax works with unique pointers.
-//
-// Compare with new-box-syntax.rs
-
-use std::boxed::{Box, HEAP};
-
-struct Structure {
-    x: isize,
-    y: isize,
-}
-
-pub fn main() {
-    let x: Box<isize> = in HEAP { 2 };
-    let b: Box<isize> = in HEAP { 1 + 2 };
-    let c = in HEAP { 3 + 4 };
-
-    let s: Box<Structure> = in HEAP {
-        Structure {
-            x: 3,
-            y: 4,
-        }
-    };
-}
diff --git a/src/test/rustdoc/default-trait-method-link.rs b/src/test/rustdoc/default-trait-method-link.rs
new file mode 100644 (file)
index 0000000..9cde446
--- /dev/null
@@ -0,0 +1,25 @@
+// 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.
+
+#![crate_name = "foo"]
+
+// @has foo/trait.Foo.html '//a[@href="../foo/trait.Foo.html#tymethod.req"]' 'req'
+// @has foo/trait.Foo.html '//a[@href="../foo/trait.Foo.html#method.prov"]' 'prov'
+
+/// Always make sure to implement [`req`], but you don't have to implement [`prov`].
+///
+/// [`req`]: Foo::req
+/// [`prov`]: Foo::prov
+pub trait Foo {
+    /// Required
+    fn req();
+    /// Provided
+    fn prov() {}
+}
diff --git a/src/test/rustdoc/deprecated-future.rs b/src/test/rustdoc/deprecated-future.rs
new file mode 100644 (file)
index 0000000..6feb98d
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(deprecated)]
+
+// @has deprecated_future/struct.S.html '//*[@class="stab deprecated"]' \
+//      'Deprecating in 99.99.99: effectively never'
+#[deprecated(since = "99.99.99", note = "effectively never")]
+pub struct S;
diff --git a/src/test/rustdoc/issue-32556.rs b/src/test/rustdoc/issue-32556.rs
new file mode 100644 (file)
index 0000000..3ab1380
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+
+/// Blah blah blah
+/// ```ignore (testing rustdoc's handling of ignore)
+/// bad_assert!();
+/// ```
+pub fn foo() {}
diff --git a/src/test/rustdoc/struct-field.rs b/src/test/rustdoc/struct-field.rs
new file mode 100644 (file)
index 0000000..c5016ba
--- /dev/null
@@ -0,0 +1,33 @@
+// 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.
+
+#![crate_name = "foo"]
+
+// ignore-tidy-linelength
+
+// @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/struct.Foo.html#structfield.bar"]' 'Foo::bar'
+// @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/union.Bar.html#structfield.foo"]' 'Bar::foo'
+// @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/enum.Uniooon.html#X.v"]' 'Uniooon::X'
+
+//! Test with [Foo::bar], [Bar::foo], [Uniooon::X]
+
+pub struct Foo {
+    pub bar: usize,
+}
+
+pub union Bar {
+    pub foo: u32,
+}
+
+pub enum Uniooon {
+    F,
+    X,
+    Y,
+}
diff --git a/src/test/ui/borrowck/two-phase-method-receivers.rs b/src/test/ui/borrowck/two-phase-method-receivers.rs
new file mode 100644 (file)
index 0000000..e690263
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// revisions: lxl nll
+//[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows
+//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll
+
+// run-pass
+
+struct Foo<'a> {
+    x: &'a i32
+}
+
+impl<'a> Foo<'a> {
+    fn method(&mut self, _: &i32) {
+    }
+}
+
+fn main() {
+    let a = &mut Foo { x: &22 };
+    Foo::method(a, a.x);
+}
diff --git a/src/test/ui/feature-gate-placement-expr.rs b/src/test/ui/feature-gate-placement-expr.rs
deleted file mode 100644 (file)
index e347887..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// gate-test-placement_in_syntax
-
-// Check that `in PLACE { EXPR }` is feature-gated.
-//
-// See also feature-gate-box-expr.rs
-//
-// (Note that the two tests are separated since the checks appear to
-// be performed at distinct phases, with an abort_if_errors call
-// separating them.)
-
-fn main() {
-    use std::boxed::HEAP;
-
-    let x = HEAP <- 'c'; //~ ERROR placement-in expression syntax is experimental
-    println!("x: {}", x);
-}
diff --git a/src/test/ui/feature-gate-placement-expr.stderr b/src/test/ui/feature-gate-placement-expr.stderr
deleted file mode 100644 (file)
index b5c0917..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: placement-in expression syntax is experimental and subject to change. (see issue #27779)
-  --> $DIR/feature-gate-placement-expr.rs:24:13
-   |
-LL |     let x = HEAP <- 'c'; //~ ERROR placement-in expression syntax is experimental
-   |             ^^^^^^^^^^^
-   |
-   = help: add #![feature(placement_in_syntax)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
index b75618206cec71bd87ff7b07f0a8698ee854a2d1..b45801ff192e6f1bd3504c05e612a1004f52a24e 160000 (submodule)
@@ -1 +1 @@
-Subproject commit b75618206cec71bd87ff7b07f0a8698ee854a2d1
+Subproject commit b45801ff192e6f1bd3504c05e612a1004f52a24e
index 17e336f471c4cfa0f995623db74718af63416db9..41ad4e7180e60607325e8defde310eeb08b00300 100644 (file)
@@ -257,6 +257,11 @@ fn check(cache: &mut Cache,
                     return;
                 }
 
+                // These appear to be broken in mdbook right now?
+                if fragment.starts_with("-") {
+                    return;
+                }
+
                 let entry = &mut cache.get_mut(&pretty_path).unwrap();
                 entry.parse_ids(&pretty_path, &contents, errors);
 
index 9c37e249ba8cc9bdf0f674a6152ee3160c21382a..e726dea84f103d65d97e0f8503abde4a0111e1ab 100644 (file)
@@ -8,6 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(link_args)]
+// Set the stack size at link time on Windows. See rustc_driver::in_rustc_thread
+// for the rationale.
+#[cfg_attr(all(windows, target_env = "msvc"), link_args = "/STACK:16777216")]
+// We only build for msvc and gnu now, but we use a exhaustive condition here
+// so we can expect either the stack size to be set or the build fails.
+#[cfg_attr(all(windows, not(target_env = "msvc")), link_args = "-Wl,--stack,16777216")]
+// See src/rustc/rustc.rs for the corresponding rustc settings.
+extern {}
+
 extern crate rustdoc;
 
 fn main() { rustdoc::main() }