]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #52019 - michaelwoerister:cross-lto-auto-plugin, r=alexcrichton
authorkennytm <kennytm@gmail.com>
Thu, 5 Jul 2018 23:07:17 +0000 (07:07 +0800)
committerkennytm <kennytm@gmail.com>
Fri, 6 Jul 2018 00:49:20 +0000 (08:49 +0800)
[cross-lang-lto] Allow the linker to choose the LTO-plugin (which is useful when using LLD)

This PR allows for not specifying an LTO-linker plugin but still let `rustc` invoke the linker with the correct plugin arguments. This is useful when using LLD which does not need the `-plugin` argument. Since LLD is the best linker for this scenario anyway, this change should improve ergonomics quite a bit.

r? @alexcrichton

183 files changed:
.travis.yml
RELEASES.md
src/Cargo.lock
src/bootstrap/bootstrap.py
src/bootstrap/builder.rs
src/bootstrap/check.rs
src/bootstrap/compile.rs
src/bootstrap/config.rs
src/bootstrap/dist.rs
src/bootstrap/doc.rs
src/bootstrap/install.rs
src/bootstrap/lib.rs
src/bootstrap/native.rs
src/bootstrap/test.rs
src/bootstrap/tool.rs
src/ci/docker/x86_64-gnu-tools/checktools.sh
src/doc/rustdoc/src/documentation-tests.md
src/etc/wasm32-shim.js
src/liballoc/boxed.rs
src/liballoc/collections/btree/map.rs
src/libcore/cell.rs
src/libcore/future.rs [deleted file]
src/libcore/future/future.rs [new file with mode: 0644]
src/libcore/future/future_obj.rs [new file with mode: 0644]
src/libcore/future/mod.rs [new file with mode: 0644]
src/libcore/iter/range.rs
src/libcore/lib.rs
src/libcore/marker.rs
src/libcore/mem.rs
src/libcore/nonzero.rs
src/libcore/num/mod.rs
src/libcore/ptr.rs
src/libcore/task/executor.rs
src/libcore/task/mod.rs
src/libcore/task/task.rs [deleted file]
src/libcore/task/wake.rs
src/libcore/tests/num/mod.rs
src/librustc/dep_graph/dep_node.rs
src/librustc/hir/intravisit.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/definitions.rs
src/librustc/hir/mod.rs
src/librustc/hir/print.rs
src/librustc/ich/fingerprint.rs
src/librustc/ich/impls_hir.rs
src/librustc/infer/error_reporting/mod.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/mir/mod.rs
src/librustc/session/config.rs
src/librustc/traits/object_safety.rs
src/librustc/traits/select.rs
src/librustc/ty/layout.rs
src/librustc/ty/mod.rs
src/librustc/ty/query/mod.rs
src/librustc/ty/query/plumbing.rs
src/librustc/ty/sty.rs
src/librustc/ty/util.rs
src/librustc_borrowck/borrowck/check_loans.rs
src/librustc_borrowck/borrowck/gather_loans/mod.rs
src/librustc_borrowck/borrowck/gather_loans/move_error.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_borrowck/borrowck/unused.rs
src/librustc_codegen_llvm/debuginfo/source_loc.rs
src/librustc_codegen_llvm/mono_item.rs
src/librustc_data_structures/indexed_set.rs
src/librustc_data_structures/lib.rs
src/librustc_data_structures/work_queue.rs [new file with mode: 0644]
src/librustc_lint/builtin.rs
src/librustc_lint/lib.rs
src/librustc_llvm/lib.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/schema.rs
src/librustc_mir/borrow_check/error_reporting.rs
src/librustc_mir/borrow_check/mod.rs
src/librustc_mir/borrow_check/nll/constraint_generation.rs
src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs [new file with mode: 0644]
src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
src/librustc_mir/borrow_check/nll/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/error_reporting.rs
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/values.rs
src/librustc_mir/borrow_check/nll/type_check/liveness.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/build/expr/as_rvalue.rs
src/librustc_mir/build/mod.rs
src/librustc_mir/build/scope.rs
src/librustc_mir/dataflow/mod.rs
src/librustc_mir/hair/pattern/check_match.rs
src/librustc_mir/hair/pattern/mod.rs
src/librustc_mir/interpret/const_eval.rs
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/memory.rs
src/librustc_mir/interpret/traits.rs
src/librustc_mir/monomorphize/collector.rs
src/librustc_mir/util/liveness.rs
src/librustc_mir/util/pretty.rs
src/librustc_passes/loops.rs
src/librustc_privacy/lib.rs
src/librustc_target/spec/mod.rs
src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs [new file with mode: 0644]
src/librustc_target/spec/wasm32_unknown_unknown.rs
src/librustc_traits/lowering.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/demand.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/collect.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/main.js
src/librustdoc/html/static/themes/dark.css
src/librustdoc/visit_ast.rs
src/libstd/io/cursor.rs
src/libstd/io/stdio.rs
src/libstd/sys/unix/ext/fs.rs
src/libstd/sys_common/remutex.rs
src/libsyntax/attr.rs [deleted file]
src/libsyntax/attr/builtin.rs [new file with mode: 0644]
src/libsyntax/attr/mod.rs [new file with mode: 0644]
src/llvm
src/stdsimd
src/test/compile-fail/deprecation-sanity.rs [deleted file]
src/test/compile-fail/immut-function-arguments.rs
src/test/compile-fail/issue-14227.rs
src/test/compile-fail/issue-28324.rs
src/test/mir-opt/end_region_7.rs
src/test/mir-opt/end_region_8.rs
src/test/mir-opt/nll/liveness-call-subtlety.rs
src/test/mir-opt/nll/liveness-drop-intra-block.rs
src/test/mir-opt/nll/liveness-interblock.rs
src/test/mir-opt/nll/region-liveness-basic.rs
src/test/run-pass/async-await.rs
src/test/run-pass/futures-api.rs
src/test/rustdoc/cross-crate-links.rs
src/test/rustdoc/inline_cross/auxiliary/macro-vis.rs [new file with mode: 0644]
src/test/rustdoc/inline_cross/macro-vis.rs [new file with mode: 0644]
src/test/rustdoc/pub-use-extern-macros.rs
src/test/ui/array-break-length.rs [new file with mode: 0644]
src/test/ui/array-break-length.stderr [new file with mode: 0644]
src/test/ui/chalkify/lower_env1.stderr
src/test/ui/closure-array-break-length.rs
src/test/ui/closure-array-break-length.stderr
src/test/ui/command-line-diagnostics.nll.stderr
src/test/ui/const-eval/index_out_of_bounds.rs
src/test/ui/const-eval/index_out_of_bounds.stderr
src/test/ui/deprecation-sanity.rs [new file with mode: 0644]
src/test/ui/deprecation-sanity.stderr [new file with mode: 0644]
src/test/ui/did_you_mean/issue-35937.nll.stderr
src/test/ui/generator/borrowing.nll.stderr
src/test/ui/generator/ref-escapes-but-not-over-yield.nll.stderr
src/test/ui/issue-47646.stderr
src/test/ui/issue-51632-try-desugar-incompatible-types.fixed [new file with mode: 0644]
src/test/ui/issue-51632-try-desugar-incompatible-types.rs [new file with mode: 0644]
src/test/ui/issue-51632-try-desugar-incompatible-types.stderr [new file with mode: 0644]
src/test/ui/issue-51714.rs
src/test/ui/issue-51714.stderr
src/test/ui/lint/test-inner-fn.rs [new file with mode: 0644]
src/test/ui/lint/test-inner-fn.stderr [new file with mode: 0644]
src/test/ui/nll/capture-mut-ref.rs [new file with mode: 0644]
src/test/ui/nll/capture-mut-ref.stderr [new file with mode: 0644]
src/test/ui/nll/extra-unused-mut.rs [new file with mode: 0644]
src/test/ui/nll/generator-upvar-mutability.rs [new file with mode: 0644]
src/test/ui/nll/generator-upvar-mutability.stderr [new file with mode: 0644]
src/test/ui/return-match-array-const.rs [new file with mode: 0644]
src/test/ui/return-match-array-const.stderr [new file with mode: 0644]
src/test/ui/span/destructor-restrictions.nll.stderr
src/test/ui/span/issue-23338-locals-die-before-temps-of-body.nll.stderr
src/test/ui/suggestions/issue-48364.rs [new file with mode: 0644]
src/test/ui/suggestions/issue-48364.stderr [new file with mode: 0644]
src/test/ui/type-check-defaults.stderr
src/tools/build-manifest/src/main.rs
src/tools/clippy
src/tools/miri
src/tools/rustdoc-js/tester.js

index 2e6722cf85563926a0297da1cfed8ee4959d169b..ba8a39f355c4ba0544643f7dd9900471bd98f81e 100644 (file)
@@ -169,7 +169,7 @@ matrix:
     - env: IMAGE=x86_64-gnu-aux
       if: branch = auto
     - env: IMAGE=x86_64-gnu-tools
-      if: branch = auto
+      if: branch = auto OR (type = pull_request AND commit_message =~ /(?i:^update.*\b(rls|rustfmt|clippy|miri)\b)/)
     - env: IMAGE=x86_64-gnu-debug
       if: branch = auto
     - env: IMAGE=x86_64-gnu-nopt
index fba68ce043e261883846d6c76a5ee581bc68c064..9d922f493d08ba7d2017956ea9ccd0f120b906a6 100644 (file)
@@ -65,6 +65,7 @@ Cargo
 -----
 - [`cargo-metadata` now includes `authors`, `categories`, `keywords`,
   `readme`, and `repository` fields.][cargo/5386]
+- [`cargo-metadata` now includes a package's `metadata` table.][cargo/5360]
 - [Added the `--target-dir` optional argument.][cargo/5393] This allows you to specify
   a different directory than `target` for placing compilation artifacts.
 - [Cargo will be adding automatic target inference for binaries, benchmarks,
@@ -114,6 +115,7 @@ Compatibility Notes
 [cargo/5203]: https://github.com/rust-lang/cargo/pull/5203/
 [cargo/5335]: https://github.com/rust-lang/cargo/pull/5335/
 [cargo/5359]: https://github.com/rust-lang/cargo/pull/5359/
+[cargo/5360]: https://github.com/rust-lang/cargo/pull/5360/
 [cargo/5386]: https://github.com/rust-lang/cargo/pull/5386/
 [cargo/5393]: https://github.com/rust-lang/cargo/pull/5393/
 [`DoubleEndedIterator::rfind`]: https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#method.rfind
index 5d09507c41bf143423152d8c70d744251f4aa76c..dc032e2d3f1e542702afa16dcee150de941bef94 100644 (file)
@@ -1,6 +1,6 @@
 [[package]]
 name = "aho-corasick"
-version = "0.6.4"
+version = "0.6.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -20,7 +20,7 @@ name = "alloc_jemalloc"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.0.0",
  "core 0.0.0",
  "libc 0.0.0",
@@ -41,8 +41,8 @@ name = "ammonia"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "html5ever 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -54,7 +54,7 @@ name = "ansi_term"
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -79,7 +79,7 @@ dependencies = [
 
 [[package]]
 name = "assert_cli"
-version = "0.6.0"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -87,39 +87,38 @@ dependencies = [
  "environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "atty"
-version = "0.2.8"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "backtrace"
-version = "0.3.6"
+version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace-sys 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "backtrace-sys"
-version = "0.1.22"
+version = "0.1.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -138,7 +137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "bitflags"
-version = "1.0.1"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -146,19 +145,19 @@ name = "bootstrap"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "cmake 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cmake 0.1.31 (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.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)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -175,8 +174,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 name = "build-manifest"
 version = "0.1.0"
 dependencies = [
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -186,67 +185,67 @@ version = "0.1.0"
 
 [[package]]
 name = "byteorder"
-version = "1.2.2"
+version = "1.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "cargo"
 version = "0.30.0"
 dependencies = [
- "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "crates-io 0.18.0",
  "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "filetime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "git2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "git2 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "git2-curl 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "home 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "ignore 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ignore 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libgit2-sys 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "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.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (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.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (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.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 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)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cargo_metadata"
-version = "0.5.4"
+version = "0.5.8"
 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.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -255,12 +254,12 @@ version = "0.1.0"
 
 [[package]]
 name = "cc"
-version = "1.0.15"
+version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "cfg-if"
-version = "0.1.2"
+version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -282,45 +281,48 @@ dependencies = [
 
 [[package]]
 name = "chrono"
-version = "0.4.1"
+version = "0.4.4"
 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)",
- "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "clap"
-version = "2.31.2"
+version = "2.32.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "clippy"
-version = "0.0.202"
+version = "0.0.211"
 dependencies = [
  "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "clippy-mini-macro-test 0.2.0",
- "clippy_lints 0.0.202",
- "compiletest_rs 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clippy_lints 0.0.211",
+ "compiletest_rs 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_version 0.2.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.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -329,51 +331,51 @@ version = "0.2.0"
 
 [[package]]
 name = "clippy_lints"
-version = "0.0.202"
+version = "0.0.205"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
+ "lazy_static 1.0.1 (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.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.1 (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.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-normalization 0.1.7 (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.205"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "0.0.211"
 dependencies = [
- "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
+ "lazy_static 1.0.1 (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.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.1 (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.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cmake"
-version = "0.1.30"
+version = "0.1.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -397,14 +399,14 @@ name = "commoncrypto-sys"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "compiler_builtins"
 version = "0.0.0"
 dependencies = [
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -413,37 +415,37 @@ name = "compiletest"
 version = "0.0.0"
 dependencies = [
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.10 (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.17 (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)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (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)",
+ "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustfix 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "compiletest_rs"
-version = "0.3.9"
+version = "0.3.11"
 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)",
+ "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "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)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (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.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -463,7 +465,7 @@ version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "core-foundation-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -477,9 +479,9 @@ version = "0.18.0"
 dependencies = [
  "curl 0.4.12 (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.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -503,9 +505,9 @@ 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)",
+ "cfg-if 0.1.4 (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 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (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)",
@@ -516,7 +518,7 @@ name = "crossbeam-utils"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -525,9 +527,9 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -537,11 +539,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "curl-sys 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "schannel 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "socket2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "schannel 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "socket2 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -550,13 +552,13 @@ name = "curl-sys"
 version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vcpkg 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -564,14 +566,6 @@ name = "datafrog"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "debug_unreachable"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "deglob"
 version = "0.1.0"
@@ -581,9 +575,9 @@ name = "derive-new"
 version = "0.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -616,16 +610,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "elasticlunr-rs"
-version = "2.2.0"
+version = "2.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "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)",
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "strum 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "strum_macros 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "strum_macros 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -633,7 +627,7 @@ name = "ena"
 version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -651,13 +645,13 @@ dependencies = [
 
 [[package]]
 name = "env_logger"
-version = "0.5.8"
+version = "0.5.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "humantime 1.1.1 (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)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -671,7 +665,7 @@ name = "error-chain"
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -686,7 +680,7 @@ name = "failure"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -709,19 +703,19 @@ name = "filetime"
 version = "0.1.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "filetime"
-version = "0.2.0"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -742,7 +736,7 @@ name = "flate2"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -773,8 +767,8 @@ name = "fs2"
 version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -782,7 +776,7 @@ name = "fuchsia-zircon"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -793,16 +787,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "futf"
-version = "0.1.3"
+version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "futures"
-version = "0.1.20"
+version = "0.1.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -812,15 +806,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "git2"
-version = "0.7.1"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libgit2-sys 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -830,8 +824,8 @@ version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "git2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "git2 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -842,14 +836,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "globset"
-version = "0.3.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -858,22 +852,22 @@ version = "0.0.0"
 
 [[package]]
 name = "handlebars"
-version = "0.32.0"
+version = "0.32.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "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)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (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.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "hex"
-version = "0.3.1"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -883,19 +877,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "userenv-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "html5ever"
-version = "0.22.0"
+version = "0.22.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "markup5ever 0.7.2 (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)",
+ "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -903,7 +898,7 @@ name = "humantime"
 version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -913,7 +908,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -923,19 +918,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "ignore"
-version = "0.4.1"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "globset 0.3.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)",
+ "globset 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.5 (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)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -954,15 +949,15 @@ version = "0.1.0"
 name = "installer"
 version = "0.0.0"
 dependencies = [
- "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
+ "lazy_static 1.0.1 (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.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tar 0.4.16 (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)",
- "xz2 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "xz2 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -975,9 +970,9 @@ name = "isatty"
 version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -998,8 +993,8 @@ name = "jobserver"
 version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "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)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1013,11 +1008,11 @@ name = "jsonrpc-core"
 version = "8.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "futures 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.21 (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.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1034,11 +1029,11 @@ name = "languageserver-types"
 version = "0.41.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (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)",
 ]
@@ -1050,7 +1045,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "lazy_static"
-version = "1.0.0"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1068,34 +1063,35 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.40"
+version = "0.2.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "libgit2-sys"
-version = "0.7.1"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "cmake 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
  "curl-sys 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libssh2-sys 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libssh2-sys"
-version = "0.2.6"
+version = "0.2.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cmake 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vcpkg 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1103,10 +1099,10 @@ name = "libz-sys"
 version = "1.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vcpkg 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1118,23 +1114,23 @@ name = "log"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "log"
-version = "0.4.1"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "log_settings"
-version = "0.1.1"
+version = "0.1.2"
 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)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1142,10 +1138,10 @@ name = "lzma-sys"
 version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1163,13 +1159,13 @@ name = "markup5ever"
 version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1184,22 +1180,22 @@ version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ammonia 1.1.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)",
- "elasticlunr-rs 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "elasticlunr-rs 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.10 (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.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "handlebars 0.32.4 (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)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (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.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1211,7 +1207,7 @@ name = "memchr"
 version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1224,7 +1220,7 @@ name = "minifier"
 version = "0.0.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1232,8 +1228,8 @@ name = "miniz-sys"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1241,27 +1237,35 @@ name = "miow"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "socket2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "socket2 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "miri"
 version = "0.1.0"
 dependencies = [
- "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiletest_rs 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.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)",
- "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiletest_rs 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "multiple_bins"
 version = "0.1.0"
 
+[[package]]
+name = "new_debug_unreachable"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "nibble_vec"
 version = "0.0.4"
@@ -1274,10 +1278,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "num-integer"
-version = "0.1.36"
+version = "0.1.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1285,12 +1289,12 @@ name = "num-traits"
 version = "0.1.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "num-traits"
-version = "0.2.2"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1298,7 +1302,7 @@ name = "num_cpus"
 version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1308,14 +1312,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "openssl"
-version = "0.10.6"
+version = "0.10.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "foreign-types 0.3.2 (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)",
- "openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.33 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1325,13 +1330,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.28"
+version = "0.9.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vcpkg 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1344,7 +1349,7 @@ name = "owning_ref"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1381,10 +1386,10 @@ name = "parking_lot_core"
 version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1418,33 +1423,33 @@ dependencies = [
 
 [[package]]
 name = "phf"
-version = "0.7.21"
+version = "0.7.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "phf_codegen"
-version = "0.7.21"
+version = "0.7.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "phf_generator"
-version = "0.7.21"
+version = "0.7.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "phf_shared"
-version = "0.7.21"
+version = "0.7.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1452,7 +1457,7 @@ dependencies = [
 
 [[package]]
 name = "pkg-config"
-version = "0.3.9"
+version = "0.3.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1461,7 +1466,7 @@ version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1481,7 +1486,15 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "0.3.6"
+version = "0.3.8"
+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-macro2"
+version = "0.4.6"
 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)",
@@ -1501,7 +1514,7 @@ dependencies = [
 name = "profiler_builtins"
 version = "0.0.0"
 dependencies = [
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.0.0",
  "core 0.0.0",
 ]
@@ -1517,7 +1530,7 @@ dependencies = [
 
 [[package]]
 name = "quick-error"
-version = "1.2.1"
+version = "1.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1532,10 +1545,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "quote"
-version = "0.5.1"
+version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "quote"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1543,11 +1564,11 @@ name = "racer"
 version = "2.0.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "humantime 1.1.1 (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)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1562,24 +1583,14 @@ dependencies = [
  "nibble_vec 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "rand"
-version = "0.3.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "rand"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1597,15 +1608,15 @@ version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "crossbeam-deque 0.2.0 (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)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "redox_syscall"
-version = "0.1.37"
+version = "0.1.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1613,7 +1624,7 @@ name = "redox_termios"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1626,31 +1637,31 @@ version = "0.1.0"
 
 [[package]]
 name = "regex"
-version = "0.2.10"
+version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "regex"
-version = "1.0.0"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.5.5"
+version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1658,7 +1669,7 @@ dependencies = [
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.0"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1677,7 +1688,7 @@ name = "remove_dir_all"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1685,16 +1696,16 @@ name = "rls"
 version = "0.128.0"
 dependencies = [
  "cargo 0.30.0",
- "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "clippy_lints 0.0.205 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.8 (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.41.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)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (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.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1705,9 +1716,9 @@ dependencies = [
  "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.8.2 (git+https://github.com/rust-lang-nursery/rustfmt?rev=f3906267)",
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1718,7 +1729,7 @@ version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (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.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1737,8 +1748,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.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1752,8 +1763,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.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1769,7 +1780,7 @@ dependencies = [
 name = "rustbook"
 version = "0.1.0"
 dependencies = [
- "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "mdbook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1778,16 +1789,16 @@ name = "rustc"
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "backtrace 0.3.6 (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.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "chalk-engine 0.6.0 (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",
  "jobserver 0.1.11 (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)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc_macro 0.0.0",
@@ -1797,7 +1808,7 @@ dependencies = [
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_target 0.0.0",
- "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
@@ -1825,8 +1836,8 @@ name = "rustc-ap-rustc_cratesio_shim"
 version = "149.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1834,8 +1845,8 @@ name = "rustc-ap-rustc_cratesio_shim"
 version = "164.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1843,16 +1854,16 @@ name = "rustc-ap-rustc_data_structures"
 version = "149.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_cratesio_shim 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-serialize 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1860,9 +1871,9 @@ name = "rustc-ap-rustc_data_structures"
 version = "164.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_cratesio_shim 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1870,7 +1881,7 @@ dependencies = [
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1878,7 +1889,7 @@ name = "rustc-ap-rustc_errors"
 version = "149.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_data_structures 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-serialize 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-syntax_pos 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1891,7 +1902,7 @@ name = "rustc-ap-rustc_errors"
 version = "164.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_data_structures 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-serialize 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-syntax_pos 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1904,8 +1915,8 @@ name = "rustc-ap-rustc_target"
 version = "149.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_cratesio_shim 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-serialize 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1915,8 +1926,8 @@ name = "rustc-ap-rustc_target"
 version = "164.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_cratesio_shim 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-serialize 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1936,14 +1947,14 @@ name = "rustc-ap-syntax"
 version = "149.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_data_structures 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_errors 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_target 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-serialize 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-syntax_pos 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1951,14 +1962,14 @@ name = "rustc-ap-syntax"
 version = "164.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_data_structures 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_errors 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_target 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-serialize 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-syntax_pos 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1969,7 +1980,7 @@ dependencies = [
  "rustc-ap-arena 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_data_structures 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-serialize 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1981,13 +1992,13 @@ dependencies = [
  "rustc-ap-arena 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_data_structures 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-serialize 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-demangle"
-version = "0.1.7"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1995,7 +2006,7 @@ name = "rustc-hash"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2021,8 +2032,8 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "crossbeam-deque 0.2.0 (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)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2036,7 +2047,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 name = "rustc_allocator"
 version = "0.0.0"
 dependencies = [
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_target 0.0.0",
@@ -2048,7 +2059,7 @@ dependencies = [
 name = "rustc_apfloat"
 version = "0.0.0"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_cratesio_shim 0.0.0",
 ]
 
@@ -2059,7 +2070,7 @@ dependencies = [
  "alloc 0.0.0",
  "alloc_system 0.0.0",
  "build_helper 0.1.0",
- "cmake 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.0.0",
  "core 0.0.0",
 ]
@@ -2069,7 +2080,7 @@ name = "rustc_borrowck"
 version = "0.0.0"
 dependencies = [
  "graphviz 0.0.0",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
@@ -2082,16 +2093,16 @@ dependencies = [
 name = "rustc_codegen_llvm"
 version = "0.0.0"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "jobserver 0.1.11 (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)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
- "rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_allocator 0.0.0",
  "rustc_apfloat 0.0.0",
  "rustc_codegen_utils 0.0.0",
@@ -2114,7 +2125,7 @@ version = "0.0.0"
 dependencies = [
  "ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_incremental 0.0.0",
@@ -2128,17 +2139,17 @@ dependencies = [
 name = "rustc_cratesio_shim"
 version = "0.0.0"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc_data_structures"
 version = "0.0.0"
 dependencies = [
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2146,7 +2157,7 @@ dependencies = [
  "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_cratesio_shim 0.0.0",
  "serialize 0.0.0",
- "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2155,9 +2166,9 @@ version = "0.0.0"
 dependencies = [
  "ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "arena 0.0.0",
- "env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.10 (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 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_allocator 0.0.0",
@@ -2177,7 +2188,7 @@ dependencies = [
  "rustc_target 0.0.0",
  "rustc_traits 0.0.0",
  "rustc_typeck 0.0.0",
- "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
  "syntax 0.0.0",
  "syntax_ext 0.0.0",
@@ -2188,7 +2199,7 @@ dependencies = [
 name = "rustc_errors"
 version = "0.0.0"
 dependencies = [
- "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_data_structures 0.0.0",
  "serialize 0.0.0",
  "syntax_pos 0.0.0",
@@ -2201,7 +2212,7 @@ name = "rustc_incremental"
 version = "0.0.0"
 dependencies = [
  "graphviz 0.0.0",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
@@ -2214,7 +2225,7 @@ dependencies = [
 name = "rustc_lint"
 version = "0.0.0"
 dependencies = [
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_mir 0.0.0",
  "rustc_target 0.0.0",
@@ -2226,10 +2237,10 @@ dependencies = [
 name = "rustc_llvm"
 version = "0.0.0"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "build_helper 0.1.0",
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_cratesio_shim 0.0.0",
 ]
 
@@ -2240,7 +2251,7 @@ dependencies = [
  "alloc 0.0.0",
  "alloc_system 0.0.0",
  "build_helper 0.1.0",
- "cmake 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.0.0",
  "core 0.0.0",
 ]
@@ -2250,7 +2261,7 @@ name = "rustc_metadata"
 version = "0.0.0"
 dependencies = [
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc_macro 0.0.0",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
@@ -2267,12 +2278,12 @@ name = "rustc_mir"
 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.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "either 1.5.0 (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)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_apfloat 0.0.0",
@@ -2291,7 +2302,7 @@ dependencies = [
  "alloc 0.0.0",
  "alloc_system 0.0.0",
  "build_helper 0.1.0",
- "cmake 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.0.0",
  "core 0.0.0",
 ]
@@ -2300,7 +2311,7 @@ dependencies = [
 name = "rustc_passes"
 version = "0.0.0"
 dependencies = [
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
@@ -2340,7 +2351,7 @@ name = "rustc_resolve"
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
@@ -2352,7 +2363,7 @@ dependencies = [
 name = "rustc_save_analysis"
 version = "0.0.0"
 dependencies = [
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-data 0.16.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 0.0.0",
@@ -2368,8 +2379,8 @@ dependencies = [
 name = "rustc_target"
 version = "0.0.0"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_cratesio_shim 0.0.0",
  "serialize 0.0.0",
 ]
@@ -2378,10 +2389,10 @@ dependencies = [
 name = "rustc_traits"
 version = "0.0.0"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "chalk-engine 0.6.0 (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 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "syntax 0.0.0",
@@ -2395,7 +2406,7 @@ dependencies = [
  "alloc 0.0.0",
  "alloc_system 0.0.0",
  "build_helper 0.1.0",
- "cmake 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.0.0",
  "core 0.0.0",
 ]
@@ -2405,7 +2416,7 @@ name = "rustc_typeck"
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
@@ -2449,10 +2460,10 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2460,50 +2471,50 @@ name = "rustfmt-nightly"
 version = "0.8.2"
 source = "git+https://github.com/rust-lang-nursery/rustfmt?rev=f3906267#f390626778c1bbb13911556d585850eb2fa67923"
 dependencies = [
- "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive-new 0.5.4 (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.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "isatty 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_target 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-syntax 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (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.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustfmt-nightly"
 version = "0.8.2"
 dependencies = [
- "assert_cli 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "assert_cli 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive-new 0.5.4 (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.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "isatty 0.1.8 (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)",
- "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_target 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-syntax 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (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.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2511,21 +2522,21 @@ name = "same-file"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "schannel"
-version = "0.1.12"
+version = "0.1.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "scoped-tls"
-version = "0.1.1"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -2539,7 +2550,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.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2549,27 +2560,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde"
-version = "1.0.40"
+version = "1.0.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde_derive"
-version = "1.0.40"
+version = "1.0.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.3.6 (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.1 (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.23.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2577,18 +2578,17 @@ name = "serde_ignored"
 version = "0.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.15"
+version = "1.0.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 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.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2612,22 +2612,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "smallvec"
-version = "0.6.0"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "socket2"
-version = "0.3.5"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "stable_deref_trait"
-version = "1.0.0"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -2638,7 +2639,7 @@ dependencies = [
  "alloc_jemalloc 0.0.0",
  "alloc_system 0.0.0",
  "build_helper 0.1.0",
- "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.0.0",
  "core 0.0.0",
  "libc 0.0.0",
@@ -2664,26 +2665,27 @@ dependencies = [
 
 [[package]]
 name = "string_cache"
-version = "0.7.1"
+version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "string_cache_codegen"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2704,11 +2706,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "strum_macros"
-version = "0.9.0"
+version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "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)",
+ "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2723,11 +2726,21 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "0.13.1"
+version = "0.13.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.5.2 (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 = "syn"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2752,12 +2765,12 @@ dependencies = [
 name = "syntax"
 version = "0.0.0"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_target 0.0.0",
- "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
  "syntax_pos 0.0.0",
 ]
@@ -2780,9 +2793,9 @@ name = "syntax_pos"
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_data_structures 0.0.0",
- "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2792,7 +2805,7 @@ name = "syntex_errors"
 version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2814,7 +2827,7 @@ version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2825,12 +2838,12 @@ dependencies = [
 
 [[package]]
 name = "tar"
-version = "0.4.15"
+version = "0.4.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "filetime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "xattr 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2839,11 +2852,11 @@ name = "tempfile"
 version = "3.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2851,7 +2864,7 @@ name = "tendril"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2874,8 +2887,8 @@ name = "term"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "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)",
+ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2891,8 +2904,8 @@ name = "termion"
 version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2906,7 +2919,7 @@ dependencies = [
 
 [[package]]
 name = "textwrap"
-version = "0.9.0"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2917,7 +2930,7 @@ name = "thread_local"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2925,19 +2938,19 @@ dependencies = [
 name = "tidy"
 version = "0.1.0"
 dependencies = [
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "time"
-version = "0.1.39"
+version = "0.1.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2945,7 +2958,7 @@ name = "toml"
 version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2955,8 +2968,8 @@ 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)",
  "is-match 0.1.0 (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)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2975,12 +2988,12 @@ dependencies = [
 
 [[package]]
 name = "unicode-normalization"
-version = "0.1.5"
+version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "unicode-segmentation"
-version = "1.2.0"
+version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -3003,14 +3016,6 @@ name = "unicode-xid"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "unreachable"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "unreachable"
 version = "1.0.0"
@@ -3023,7 +3028,7 @@ dependencies = [
 name = "unstable-book-gen"
 version = "0.1.0"
 dependencies = [
- "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "tidy 0.1.0",
 ]
 
@@ -3051,7 +3056,7 @@ name = "url_serde"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -3076,12 +3081,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "vcpkg"
-version = "0.2.3"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "vec_map"
-version = "0.8.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -3095,7 +3100,7 @@ version = "2.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3105,7 +3110,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "winapi"
-version = "0.3.4"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3132,7 +3137,7 @@ name = "wincolor"
 version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3144,12 +3149,12 @@ name = "xattr"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "xz2"
-version = "0.1.4"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lzma-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3161,33 +3166,33 @@ version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [metadata]
-"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
+"checksum aho-corasick 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0ba20154ea1f47ce2793322f049c5646cc6d0fa9759d5f333f286e507bf8080"
 "checksum ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4c682378117e4186a492b2252b9537990e1617f44aed9788b9a1149de45477"
 "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
 "checksum ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35c7a5669cb64f085739387e1308b74e6d44022464b7f1b63bbd4ceb6379ec31"
 "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
-"checksum assert_cli 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5da59dbd8df54562665b925b427221ceda9b771408cb8a6cbd2125d3b001330b"
-"checksum atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "af80143d6f7608d746df1520709e5d141c96f240b0e62b0aa41bdfb53374d9d4"
-"checksum backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe525f66f42d207968308ee86bc2dd60aa5fab535b22e616323a173d097d8e"
-"checksum backtrace-sys 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5fd343a2466c4603f76f38de264bc0526cffc7fa38ba52fb9f13237eccc1ced2"
+"checksum assert_cli 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98589b0e465a6c510d95fceebd365bb79bedece7f6e18a480897f2015f85ec51"
+"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1"
+"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
+"checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e"
 "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
 "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 bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
 "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32"
-"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87"
-"checksum cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebd6272a2ca4fd39dbabbd6611eb03df45c2259b3b80b39a9ff8fbdcf42a4b3"
-"checksum cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0ebb87d1116151416c0cf66a0e3fb6430cccd120fd6300794b4dfaa050ac40ba"
-"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
+"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
+"checksum cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1efca0b863ca03ed4c109fb1c55e0bc4bbeb221d3e103d86251046b06a526bd0"
+"checksum cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "49ec142f5768efb5b7622aebc3fdbdbb8950a4b9ba996393cb76ef7466e8747d"
+"checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e"
 "checksum chalk-engine 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a146c19172c7eea48ea55a7123ac95da786639bc665097f1e14034ee5f1d8699"
 "checksum chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "295635afd6853aa9f20baeb7f0204862440c0fe994c5a253d5f479dac41d047e"
-"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 chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6962c635d530328acc53ac6a955e83093fedc91c5809dfac1fa60fa470830a37"
+"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
 "checksum clippy_lints 0.0.205 (registry+https://github.com/rust-lang/crates.io-index)" = "1dcb837d7510bf9e4e3b6f470c450c6d25e61116db5503a6f565bb6283860622"
-"checksum cmake 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "5cf678ceebedde428000cb3a34465cf3606d1a48da17014948a916deac39da7c"
+"checksum cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "95470235c31c726d72bf2e1f421adc1e65b9d561bf5529612cbe1a72da1467b3"
 "checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc"
 "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.9 (registry+https://github.com/rust-lang/crates.io-index)" = "608d9d3ccc45b63bf337d2ff5e65def5a5a52c187122232509f6b72707f61b1b"
+"checksum compiletest_rs 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "04cea0fe8b8aaca8143af607ad69076866c9f08b83c4b7faca0e993e5486831b"
 "checksum core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7caa6cb9e76ddddbea09a03266d6b3bc98cd41e9fb9b017c473e7cca593ec25"
 "checksum core-foundation-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b2a53cce0ddcf7e7e1f998738d757d5a3bf08bf799a180e50ebe50d298f52f5a"
 "checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
@@ -3198,23 +3203,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf20bbe084f285f215eef2165feed70d6b75ba29cad24469badb853a4a287d0"
 "checksum curl-sys 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71c63a540a9ee4e15e56c3ed9b11a2f121239b9f6d7b7fe30f616e048148df9a"
 "checksum datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16d724bf4ffe77cdceeecd461009b5f8d9e23c5d645d68bedb4586bf43e7e142"
-"checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3"
 "checksum derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ceed73957c449214f8440eec8ad7fa282b67dc9eacbb24a3085b15d60397a17a"
 "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
 "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
-"checksum elasticlunr-rs 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4511b63d69dd5d31e8e29aed2c132c413f87acea8035d0584801feaab9dd1f0f"
+"checksum elasticlunr-rs 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4837d77a1e157489a3933b743fd774ae75074e0e390b2b7f071530048a0d87ee"
 "checksum ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dc8393b3c7352f94092497f6b52019643e493b6b890eb417cdb7c46117e621"
 "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"
-"checksum env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "be27f8ea102a7182093a80d98f0b78623b580eda8791cbe8e2345fe6e57567a6"
+"checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a"
 "checksum environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4b14e20978669064c33b4c1e0fb4083412e40fe56cbea2eae80fd7591503ee"
 "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
 "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82"
 "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b"
 "checksum filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "714653f3e34871534de23771ac7b26e999651a0a228f47beb324dfdf1dd4b10f"
-"checksum filetime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08530a39af0bd442c40aabb9e854f442a83bd2403feb1ed58fbe982dec2385f3"
+"checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f"
 "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
 "checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909"
 "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
@@ -3223,21 +3227,21 @@ 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 futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3"
-"checksum futures 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5a3176836efa0b37f0e321b86672dfada1564aeb516fbed67b7c24050a0263"
+"checksum futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b"
+"checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c"
 "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 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "910a2df52d2354e4eb27aa12f3803ea86bf461a93e17028908ec0e356572aa7b"
 "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.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 globset 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "142754da2c9b3722affd909f9e27f2a6700a7a303f362971e0a74c652005a43d"
+"checksum handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d89ec99d1594f285d4590fc32bac5f75cdab383f1123d504d27862c644a807dd"
+"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
 "checksum home 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8f94f6fbdc000a6eba0c8cf08632b2091bb59141d36ac321a2a96d6365e5e4dc"
-"checksum html5ever 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e579ac8647178ab915d400d7d22938bda5cd351c6c62e1c294d56884ccfc75fe"
+"checksum html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b04478cf718862650a0bf66acaf8f2f8c906fbc703f35c916c1f4211b069a364"
 "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
 "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
 "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 ignore 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "787a5940ab88e0f2f3b2cad3687060bddcf67520f3b761abc31065c9c495d088"
 "checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053"
 "checksum isatty 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6c324313540cd4d7ba008d43dc6606a32a5579f13cc17b2804c13096f0a5c522"
 "checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
@@ -3248,15 +3252,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
 "checksum languageserver-types 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "017cf5ade4be5ebeb06277ccd281c268dbd2e0801128d3992b4b4057f34dd432"
 "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
-"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
+"checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739"
 "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef"
-"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b"
-"checksum libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecbd6428006c321c29b6c8a895f0d90152f1cf4fd8faab69fc436a3d9594f63"
-"checksum libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0db4ec23611747ef772db1c4d650f8bd762f07b461727ec998f953c614024b75"
+"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1"
+"checksum libgit2-sys 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7adce4cc6db027611f537837a7c404319b6314dae49c5db80ad5332229894751"
+"checksum libssh2-sys 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5afcb36f9a2012ab8d3a9ba5186ee2d1c4587acf199cb47879a73c5fe1b731a4"
 "checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16"
 "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
-"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2"
-"checksum log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3d382732ea0fbc09790c4899db3255bdea0fc78b54bf234bd18a63bb603915b6"
+"checksum log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "61bd98ae7f7b754bc53dca7d44b604f733c6bba044ea6f41bc8d89272d8161d2"
+"checksum log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19af41f0565d7c19b2058153ad0b42d4d5ce89ec4dbf06ed6741114a8b63e7cd"
 "checksum lzma-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c1b93b78f89e8737dac81837fc8f5521ac162abcba902e1a3db949d55346d1da"
 "checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
 "checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
@@ -3268,16 +3272,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum minifier 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "78cb57f9a385530d60f2d67f6e108050b478b7a0ffd0bb9c350803e1356535dd"
 "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 new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"
 "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-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe"
+"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
 "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-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
 "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
 "checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113"
-"checksum openssl 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)" = "63246f69962e8d5ef865f82a65241d6483c8a2905a1801e2f7feb5d187d51320"
+"checksum openssl 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ed18a0f40ec4e9a8a81f8865033d823b7195d16a0a5721e10963ee1b0c2980ca"
 "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
-"checksum openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)" = "0bbd90640b148b46305c1691eed6039b5c8509bed16991e3562a01eeb76902a3"
+"checksum openssl-sys 0.9.33 (registry+https://github.com/rust-lang/crates.io-index)" = "d8abc04833dcedef24221a91852931df2f63e3369ae003134e70aff3645775cc"
 "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
 "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
 "checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac"
@@ -3286,32 +3291,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "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 petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8b30dc85588cd02b9b76f5e386535db546d21dc68506cff2abebee0b6445e8e4"
-"checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc"
-"checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f"
-"checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
-"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
-"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
+"checksum phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "7d37a244c75a9748e049225155f56dbcb98fe71b192fd25fd23cb914b5ad62f2"
+"checksum phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4048fe7dd7a06b8127ecd6d3803149126e9b33c7558879846da3a63f734f2b"
+"checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998"
+"checksum phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c2261d544c2bb6aa3b10022b0be371b9c7c64f762ef28c6f5d4f1ef6d97b5930"
+"checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f"
 "checksum polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b6b0a7f5f4278b991ffd14abce1d01b013121ad297460237ef0a2f08d43201"
 "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6"
-"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"
+"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
+"checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"
 "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 quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
 "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.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"
+"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
+"checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035"
 "checksum racer 2.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "e713729f45f12df5c5e182d39506766f76c09133fb661d3622e0ddf8078911c2"
 "checksum radix_trie 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "03d0d770481e8af620ca61d3d304bf014f965d7f78e923dc58545e6a545070a9"
-"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
 "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
 "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_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
-"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb"
-"checksum regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75ecf88252dce580404a22444fc7d626c01815debba56a7f4f536772a5ff19d3"
-"checksum regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bd90079345f4a4c3409214734ae220fd773c6f2e8a543d07370c6c1c369cfbfb"
-"checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b"
+"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
+"checksum regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13c93d55961981ba9226a213b385216f83ab43bd6ac53ab16b2eeb47e337cf4e"
+"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
+"checksum regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05b06a75f5217880fc5e905952a42750bf44787e56a6c6d6852ed0992f5e1d54"
 "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
 "checksum rls-analysis 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da9794cd1f80f2cb888c00641a32f9855d0226c954ee31cef145784914c7142e"
 "checksum rls-blacklist 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e4a9cc2545ccb7e05b355bfe047b8039a6ec12270d5f3c996b766b340a50f7d2"
@@ -3335,7 +3341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rustc-ap-syntax 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab8f97532dabc3713ac3e8d11a85f1a5b154486e79a0c2643d62078f0f948ce2"
 "checksum rustc-ap-syntax_pos 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe5d24a137d6e202cd6eb96cb74f8cb4a2b257c42b74dd624e136b4e19f0a47d"
 "checksum rustc-ap-syntax_pos 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e098adae207a4b8d470bc5e9565904cfe65dca799ba4c9efc872e7436eb5a67"
-"checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb"
+"checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649"
 "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
 "checksum rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c6d5a683c6ba4ed37959097e88d71c9e8e26659a3cb5be8b389078e7ad45306"
 "checksum rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40f06724db71e18d68b3b946fdf890ca8c921d9edccc1404fdfdb537b0d12649"
@@ -3344,72 +3350,71 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rustfix 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9da3cf9b79dc889a2c9879643f26d7a53e37e9361c7566b7d2787d5ace0d8396"
 "checksum rustfmt-nightly 0.8.2 (git+https://github.com/rust-lang-nursery/rustfmt?rev=f3906267)" = "<none>"
 "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
-"checksum schannel 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "85fd9df495640643ad2d00443b3d78aae69802ad488debab4f1dd52fc1806ade"
-"checksum scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8674d439c964889e2476f474a3bf198cc9e199e77499960893bac5de7e9218a4"
+"checksum schannel 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1fabf2a7b6483a141426e1afd09ad543520a77ac49bd03c286e7696ccfd77f"
+"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28"
 "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.40 (registry+https://github.com/rust-lang/crates.io-index)" = "29465552c9b767d0cb44be3ddf4c3214be15d34975a7750f6cf4f409835f0248"
-"checksum serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "fb88f3c93214390ed9ef3ad15ce303c36684a915a97a30883ac6ca261bf67dc7"
-"checksum serde_derive_internals 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d30c4596450fd7bbda79ef15559683f9a79ac0193ea819db90000d7e1cae794"
+"checksum serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)" = "210e5a3b159c566d7527e9b22e44be73f2e0fcc330bb78fef4dbccb56d2e74c8"
+"checksum serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)" = "dd724d68017ae3a7e63600ee4b2fdb3cad2158ffd1821d44aff4580f63e2b593"
 "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142"
-"checksum serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7bf1cbb1387028a13739cb018ee0d9b3db534f22ca3c84a5904f7eadfde14e75"
+"checksum serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "84b8035cabe9b35878adec8ac5fe03d5f6bc97ff6edd7ccb96b44c1276ba390e"
 "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 siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
-"checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
-"checksum socket2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ff606e0486e88f5fc6cfeb3966e434fb409abbc7a3ab495238f70a1ca97f789d"
-"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
-"checksum string_cache 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39cb4173bcbd1319da31faa5468a7e3870683d7a237150b0b0aaafd546f6ad12"
-"checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7"
+"checksum smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "312a7df010092e73d6bbaf141957e868d4f30efd2bfd9bb1028ad91abec58514"
+"checksum socket2 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "962a516af4d3a7c272cb3a1d50a8cc4e5b41802e4ad54cfb7bee8ba61d37d703"
+"checksum stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa"
+"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
+"checksum string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35293b05cf1494e8ddd042a7df6756bf18d07f42d234f32e71dce8a7aabb0191"
 "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
 "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
 "checksum strum 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "099e21b5dd6dd07b5adcf8c4b723a7c0b7efd7a9359bf963d58c0caae8532545"
-"checksum strum_macros 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0dd9bd569e88028750e3ae5c25616b8278ac16a8e61aba4339195c72396d49e1"
+"checksum strum_macros 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1292d85e688e4696ecb69b2db2648994fb8af266974e89be53cefdf003861a5d"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
-"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
+"checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b"
+"checksum syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2beff8ebc3658f07512a413866875adddd20f4fd47b2a4e6c9da65cd281baaea"
 "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"
 "checksum syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "955ef4b16af4c468e4680d1497f873ff288f557d338180649e18f915af5e15ac"
 "checksum syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76a302e717e348aa372ff577791c3832395650073b8d8432f8b3cb170b34afde"
-"checksum tar 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "6af6b94659f9a571bf769a5b71f54079393585ee0bfdd71b691be22d7d6b1d18"
+"checksum tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f41ca4a5689f06998f0247fcb60da6c760f1950cc9df2a10d71575ad0b062a"
 "checksum tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "47776f63b85777d984a50ce49d6b9e58826b6a3766a449fc95bc66cd5663c15b"
 "checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
 "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
 "checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561"
 "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
-"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
+"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
 "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
-"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
+"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
 "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9"
 "checksum toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6854664bfc6df0360c695480836ee90e2d0c965f06db291d10be9344792d43e8"
 "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
 "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
-"checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f"
-"checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946"
+"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
+"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
 "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
 "checksum unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "36dff09cafb4ec7c8cf0023eb0b686cb6ce65499116a12201c9e11840ca01beb"
 "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
 "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
-"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
 "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
 "checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7"
 "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea"
 "checksum userenv-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d28ea36bbd9192d75bd9fa9b39f96ddb986eaee824adae5d53b6e51919b2f3"
 "checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c"
 "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
-"checksum vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ed0f6789c8a85ca41bbc1c9d175422116a9869bd1cf31bb08e1493ecce60380"
-"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
+"checksum vcpkg 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cbe533e138811704c0e3cbde65a818b35d3240409b4346256c5ede403e082474"
+"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 "checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
-"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
+"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
 "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 "checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767"
 "checksum xattr 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "abb373b92de38a4301d66bec009929b4fb83120ea1c4a401be89dbe0b9777443"
-"checksum xz2 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "98df591c3504d014dd791d998123ed00a476c7e26dc6b2e873cb55c6ac9e59fa"
+"checksum xz2 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "df8bf41d3030c3577c9458fd6640a05afbf43b150d0b531b16bd77d3f794f27a"
 "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992"
index 28f5192f2cdf455d9e6730f64ce324ab679a8af5..512d4d8c5b792ce0e1958574ff59e0168996793c 100644 (file)
@@ -815,6 +815,9 @@ def bootstrap(help_triggered):
     env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
     env["BOOTSTRAP_PYTHON"] = sys.executable
     env["BUILD_DIR"] = build.build_dir
+    env["RUSTC_BOOTSTRAP"] = '1'
+    env["CARGO"] = build.cargo()
+    env["RUSTC"] = build.rustc()
     run(args, env=env, verbose=build.verbose)
 
 
index fa2440e27d06aba4f8125f480e619420a33e04be..fad0a553802a27e200faad6983ffa18835e29cea 100644 (file)
@@ -769,6 +769,22 @@ pub fn cargo(
 
         let want_rustdoc = self.doc_tests != DocTests::No;
 
+        // We synthetically interpret a stage0 compiler used to build tools as a
+        // "raw" compiler in that it's the exact snapshot we download. Normally
+        // the stage0 build means it uses libraries build by the stage0
+        // compiler, but for tools we just use the precompiled libraries that
+        // we've downloaded
+        let use_snapshot = mode == Mode::ToolBootstrap;
+        assert!(!use_snapshot || stage == 0);
+
+        let maybe_sysroot = self.sysroot(compiler);
+        let sysroot = if use_snapshot {
+            self.rustc_snapshot_sysroot()
+        } else {
+            &maybe_sysroot
+        };
+        let libdir = sysroot.join(libdir(&compiler.host));
+
         // Customize the compiler we're running. Specify the compiler to cargo
         // as our shim and then pass it some various options used to configure
         // how the actual compiler itself is called.
@@ -784,8 +800,8 @@ pub fn cargo(
                 "RUSTC_DEBUG_ASSERTIONS",
                 self.config.rust_debug_assertions.to_string(),
             )
-            .env("RUSTC_SYSROOT", self.sysroot(compiler))
-            .env("RUSTC_LIBDIR", self.rustc_libdir(compiler))
+            .env("RUSTC_SYSROOT", &sysroot)
+            .env("RUSTC_LIBDIR", &libdir)
             .env("RUSTC_RPATH", self.config.rust_rpath.to_string())
             .env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc"))
             .env(
@@ -809,7 +825,7 @@ pub fn cargo(
             cargo.env("RUSTC_ERROR_FORMAT", error_format);
         }
         if cmd != "build" && cmd != "check" && want_rustdoc {
-            cargo.env("RUSTDOC_LIBDIR", self.sysroot_libdir(compiler, self.config.build));
+            cargo.env("RUSTDOC_LIBDIR", &libdir);
         }
 
         if mode.is_tool() {
index b3ccb3cc3c926ca29dc823aed9a212e32ac4aec7..39c5c8328315a860617a46d04f93ed215dbac6fd 100644 (file)
@@ -273,5 +273,6 @@ fn codegen_backend_stamp(builder: &Builder,
 /// Cargo's output path for rustdoc in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn rustdoc_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::ToolRustc, target).join(".rustdoc-check.stamp")
+    builder.cargo_out(compiler, Mode::ToolRustc, target)
+        .join(".rustdoc-check.stamp")
 }
index 642f22b11ade36aac997d5d2266624f16f5344d7..298bd58c6cdfe0545fc55271b948d46134e9e6a0 100644 (file)
@@ -24,7 +24,6 @@
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 use std::str;
-use std::cmp::min;
 
 use build_helper::{output, mtime, up_to_date};
 use filetime::FileTime;
@@ -68,6 +67,18 @@ fn run(self, builder: &Builder) {
         let target = self.target;
         let compiler = self.compiler;
 
+        if let Some(keep_stage) = builder.config.keep_stage {
+            if keep_stage <= compiler.stage {
+                println!("Warning: Using a potentially old libstd. This may not behave well.");
+                builder.ensure(StdLink {
+                    compiler: compiler,
+                    target_compiler: compiler,
+                    target,
+                });
+                return;
+            }
+        }
+
         builder.ensure(StartupObjects { compiler, target });
 
         if builder.force_use_stage1(compiler, target) {
@@ -351,6 +362,18 @@ fn run(self, builder: &Builder) {
         let target = self.target;
         let compiler = self.compiler;
 
+        if let Some(keep_stage) = builder.config.keep_stage {
+            if keep_stage <= compiler.stage {
+                println!("Warning: Using a potentially old libtest. This may not behave well.");
+                builder.ensure(TestLink {
+                    compiler: compiler,
+                    target_compiler: compiler,
+                    target,
+                });
+                return;
+            }
+        }
+
         builder.ensure(Std { compiler, target });
 
         if builder.force_use_stage1(compiler, target) {
@@ -467,6 +490,18 @@ fn run(self, builder: &Builder) {
         let compiler = self.compiler;
         let target = self.target;
 
+        if let Some(keep_stage) = builder.config.keep_stage {
+            if keep_stage <= compiler.stage {
+                println!("Warning: Using a potentially old librustc. This may not behave well.");
+                builder.ensure(RustcLink {
+                    compiler: compiler,
+                    target_compiler: compiler,
+                    target,
+                });
+                return;
+            }
+        }
+
         builder.ensure(Test { compiler, target });
 
         if builder.force_use_stage1(compiler, target) {
@@ -786,8 +821,11 @@ fn copy_lld_to_sysroot(builder: &Builder,
         .join("bin");
     t!(fs::create_dir_all(&dst));
 
-    let exe = exe("lld", &target);
-    builder.copy(&lld_install_root.join("bin").join(&exe), &dst.join(&exe));
+    let src_exe = exe("lld", &target);
+    let dst_exe = exe("rust-lld", &target);
+    // we prepend this bin directory to the user PATH when linking Rust binaries. To
+    // avoid shadowing the system LLD we rename the LLD we provide to `rust-lld`.
+    builder.copy(&lld_install_root.join("bin").join(&src_exe), &dst.join(&dst_exe));
 }
 
 /// Cargo's output path for the standard library in a given stage, compiled
@@ -873,7 +911,7 @@ impl Step for Assemble {
     type Output = Compiler;
 
     fn should_run(run: ShouldRun) -> ShouldRun {
-        run.all_krates("rustc-main")
+        run.never()
     }
 
     /// Prepare a new compiler from the artifacts in `stage`
@@ -915,28 +953,16 @@ fn run(self, builder: &Builder) -> Compiler {
         // link to these. (FIXME: Is that correct? It seems to be correct most
         // of the time but I think we do link to these for stage2/bin compilers
         // when not performing a full bootstrap).
-        if builder.config.keep_stage.map_or(false, |s| target_compiler.stage <= s) {
-            builder.verbose("skipping compilation of compiler due to --keep-stage");
-            let compiler = build_compiler;
-            for stage in 0..min(target_compiler.stage, builder.config.keep_stage.unwrap()) {
-                let target_compiler = builder.compiler(stage, target_compiler.host);
-                let target = target_compiler.host;
-                builder.ensure(StdLink { compiler, target_compiler, target });
-                builder.ensure(TestLink { compiler, target_compiler, target });
-                builder.ensure(RustcLink { compiler, target_compiler, target });
-            }
-        } else {
-            builder.ensure(Rustc {
+        builder.ensure(Rustc {
+            compiler: build_compiler,
+            target: target_compiler.host,
+        });
+        for &backend in builder.config.rust_codegen_backends.iter() {
+            builder.ensure(CodegenBackend {
                 compiler: build_compiler,
                 target: target_compiler.host,
+                backend,
             });
-            for &backend in builder.config.rust_codegen_backends.iter() {
-                builder.ensure(CodegenBackend {
-                    compiler: build_compiler,
-                    target: target_compiler.host,
-                    backend,
-                });
-            }
         }
 
         let lld_install = if builder.config.lld_enabled {
index e4d467c9272458b17813452ac9a8ec466cdba9c0..b3ed10257bdacf2d3c11256b45f7959df593b646 100644 (file)
@@ -23,7 +23,6 @@
 
 use num_cpus;
 use toml;
-use util::exe;
 use cache::{INTERNER, Interned};
 use flags::Flags;
 pub use flags::Subcommand;
@@ -367,9 +366,8 @@ pub fn default_opts() -> Config {
         config.src = Config::path_from_python("SRC");
         config.out = Config::path_from_python("BUILD_DIR");
 
-        let stage0_root = config.out.join(&config.build).join("stage0/bin");
-        config.initial_rustc = stage0_root.join(exe("rustc", &config.build));
-        config.initial_cargo = stage0_root.join(exe("cargo", &config.build));
+        config.initial_rustc = Config::path_from_python("RUSTC");
+        config.initial_cargo = Config::path_from_python("CARGO");
 
         config
     }
index b5f34cdf336db67a18e38438d6a06e752c2f7d6c..0587dc8896d15a34546e21e34d19e1dbacf51a1e 100644 (file)
@@ -41,6 +41,8 @@ pub fn pkgname(builder: &Builder, component: &str) -> String {
         format!("{}-{}", component, builder.cargo_package_vers())
     } else if component == "rls" {
         format!("{}-{}", component, builder.rls_package_vers())
+    } else if component == "clippy" {
+        format!("{}-{}", component, builder.clippy_package_vers())
     } else if component == "rustfmt" {
         format!("{}-{}", component, builder.rustfmt_package_vers())
     } else if component == "llvm-tools" {
@@ -491,12 +493,13 @@ fn prepare_image(builder: &Builder, compiler: Compiler, image: &Path) {
 
             // Copy over lld if it's there
             if builder.config.lld_enabled {
-                let exe = exe("lld", &compiler.host);
+                let exe = exe("rust-lld", &compiler.host);
                 let src = builder.sysroot_libdir(compiler, host)
                     .parent()
                     .unwrap()
                     .join("bin")
                     .join(&exe);
+                // for the rationale about this rename check `compile::copy_lld_to_sysroot`
                 let dst = image.join("lib/rustlib")
                     .join(&*host)
                     .join("bin")
@@ -955,7 +958,7 @@ fn run(self, builder: &Builder) -> PathBuf {
             if !has_cargo_vendor {
                 let mut cmd = builder.cargo(
                     builder.compiler(0, builder.config.build),
-                    Mode::ToolRustc,
+                    Mode::ToolBootstrap,
                     builder.config.build,
                     "install"
                 );
@@ -1183,6 +1186,82 @@ fn run(self, builder: &Builder) -> Option<PathBuf> {
     }
 }
 
+#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct Clippy {
+    pub stage: u32,
+    pub target: Interned<String>,
+}
+
+impl Step for Clippy {
+    type Output = Option<PathBuf>;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun) -> ShouldRun {
+        run.path("clippy")
+    }
+
+    fn make_run(run: RunConfig) {
+        run.builder.ensure(Clippy {
+            stage: run.builder.top_stage,
+            target: run.target,
+        });
+    }
+
+    fn run(self, builder: &Builder) -> Option<PathBuf> {
+        let stage = self.stage;
+        let target = self.target;
+        assert!(builder.config.extended);
+
+        builder.info(&format!("Dist clippy stage{} ({})", stage, target));
+        let src = builder.src.join("src/tools/clippy");
+        let release_num = builder.release_num("clippy");
+        let name = pkgname(builder, "clippy");
+        let version = builder.clippy_info.version(builder, &release_num);
+
+        let tmp = tmpdir(builder);
+        let image = tmp.join("clippy-image");
+        drop(fs::remove_dir_all(&image));
+        t!(fs::create_dir_all(&image));
+
+        // Prepare the image directory
+        // We expect clippy to build, because we've exited this step above if tool
+        // state for clippy isn't testing.
+        let clippy = builder.ensure(tool::Clippy {
+            compiler: builder.compiler(stage, builder.config.build),
+            target, extra_features: Vec::new()
+        }).or_else(|| { println!("Unable to build clippy, skipping dist"); None })?;
+
+        builder.install(&clippy, &image.join("bin"), 0o755);
+        let doc = image.join("share/doc/clippy");
+        builder.install(&src.join("README.md"), &doc, 0o644);
+        builder.install(&src.join("LICENSE"), &doc, 0o644);
+
+        // Prepare the overlay
+        let overlay = tmp.join("clippy-overlay");
+        drop(fs::remove_dir_all(&overlay));
+        t!(fs::create_dir_all(&overlay));
+        builder.install(&src.join("README.md"), &overlay, 0o644);
+        builder.install(&src.join("LICENSE"), &doc, 0o644);
+        builder.create(&overlay.join("version"), &version);
+
+        // Generate the installer tarball
+        let mut cmd = rust_installer(builder);
+        cmd.arg("generate")
+           .arg("--product-name=Rust")
+           .arg("--rel-manifest-dir=rustlib")
+           .arg("--success-message=clippy-ready-to-serve.")
+           .arg("--image-dir").arg(&image)
+           .arg("--work-dir").arg(&tmpdir(builder))
+           .arg("--output-dir").arg(&distdir(builder))
+           .arg("--non-installed-overlay").arg(&overlay)
+           .arg(format!("--package-name={}-{}", name, target))
+           .arg("--legacy-manifest-dirs=rustlib,cargo")
+           .arg("--component-name=clippy-preview");
+
+        builder.run(&mut cmd);
+        Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
+    }
+}
 
 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct Rustfmt {
@@ -1304,6 +1383,7 @@ fn run(self, builder: &Builder) {
         let rustfmt_installer = builder.ensure(Rustfmt { stage, target });
         let rls_installer = builder.ensure(Rls { stage, target });
         let llvm_tools_installer = builder.ensure(LlvmTools { stage, target });
+        let clippy_installer = builder.ensure(Clippy { stage, target });
         let mingw_installer = builder.ensure(Mingw { host: target });
         let analysis_installer = builder.ensure(Analysis {
             compiler: builder.compiler(stage, self.host),
@@ -1340,6 +1420,7 @@ fn run(self, builder: &Builder) {
         tarballs.push(rustc_installer);
         tarballs.push(cargo_installer);
         tarballs.extend(rls_installer.clone());
+        tarballs.extend(clippy_installer.clone());
         tarballs.extend(rustfmt_installer.clone());
         tarballs.extend(llvm_tools_installer.clone());
         tarballs.push(analysis_installer);
@@ -1409,6 +1490,9 @@ fn filter(contents: &str, marker: &str) -> String {
             if rls_installer.is_none() {
                 contents = filter(&contents, "rls");
             }
+            if clippy_installer.is_none() {
+                contents = filter(&contents, "clippy");
+            }
             if rustfmt_installer.is_none() {
                 contents = filter(&contents, "rustfmt");
             }
@@ -1446,6 +1530,9 @@ fn filter(contents: &str, marker: &str) -> String {
             if rls_installer.is_some() {
                 prepare("rls");
             }
+            if clippy_installer.is_some() {
+                prepare("clippy");
+            }
 
             // create an 'uninstall' package
             builder.install(&etc.join("pkg/postinstall"), &pkg.join("uninstall"), 0o755);
@@ -1474,6 +1561,8 @@ fn filter(contents: &str, marker: &str) -> String {
                     format!("{}-{}", name, target)
                 } else if name == "rls" {
                     "rls-preview".to_string()
+                } else if name == "clippy" {
+                    "clippy-preview".to_string()
                 } else {
                     name.to_string()
                 };
@@ -1490,6 +1579,9 @@ fn filter(contents: &str, marker: &str) -> String {
             if rls_installer.is_some() {
                 prepare("rls");
             }
+            if clippy_installer.is_some() {
+                prepare("clippy");
+            }
             if target.contains("windows-gnu") {
                 prepare("rust-mingw");
             }
@@ -1570,6 +1662,18 @@ fn filter(contents: &str, marker: &str) -> String {
                                 .arg("-out").arg(exe.join("RlsGroup.wxs"))
                                 .arg("-t").arg(etc.join("msi/remove-duplicates.xsl")));
             }
+            if clippy_installer.is_some() {
+                builder.run(Command::new(&heat)
+                                .current_dir(&exe)
+                                .arg("dir")
+                                .arg("clippy")
+                                .args(&heat_flags)
+                                .arg("-cg").arg("ClippyGroup")
+                                .arg("-dr").arg("Clippy")
+                                .arg("-var").arg("var.ClippyDir")
+                                .arg("-out").arg(exe.join("ClippyGroup.wxs"))
+                                .arg("-t").arg(etc.join("msi/remove-duplicates.xsl")));
+            }
             builder.run(Command::new(&heat)
                             .current_dir(&exe)
                             .arg("dir")
@@ -1612,6 +1716,9 @@ fn filter(contents: &str, marker: &str) -> String {
                 if rls_installer.is_some() {
                     cmd.arg("-dRlsDir=rls");
                 }
+                if clippy_installer.is_some() {
+                    cmd.arg("-dClippyDir=clippy");
+                }
                 if target.contains("windows-gnu") {
                     cmd.arg("-dGccDir=rust-mingw");
                 }
@@ -1627,6 +1734,9 @@ fn filter(contents: &str, marker: &str) -> String {
             if rls_installer.is_some() {
                 candle("RlsGroup.wxs".as_ref());
             }
+            if clippy_installer.is_some() {
+                candle("ClippyGroup.wxs".as_ref());
+            }
             candle("AnalysisGroup.wxs".as_ref());
 
             if target.contains("windows-gnu") {
@@ -1656,6 +1766,9 @@ fn filter(contents: &str, marker: &str) -> String {
             if rls_installer.is_some() {
                 cmd.arg("RlsGroup.wixobj");
             }
+            if clippy_installer.is_some() {
+                cmd.arg("ClippyGroup.wixobj");
+            }
 
             if target.contains("windows-gnu") {
                 cmd.arg("GccGroup.wixobj");
@@ -1741,6 +1854,7 @@ fn run(self, builder: &Builder) {
         cmd.arg(builder.rust_package_vers());
         cmd.arg(builder.package_vers(&builder.release_num("cargo")));
         cmd.arg(builder.package_vers(&builder.release_num("rls")));
+        cmd.arg(builder.package_vers(&builder.release_num("clippy")));
         cmd.arg(builder.package_vers(&builder.release_num("rustfmt")));
         cmd.arg(builder.llvm_tools_package_vers());
         cmd.arg(addr);
index 19599b33ebe261d942156450ea2e4f2e2e1b3448..f71cb119b77fea2dcb1be6b6ac819ed2503d3f33 100644 (file)
@@ -799,14 +799,22 @@ fn run(self, builder: &Builder) {
         builder.ensure(tool::Rustdoc { host: compiler.host });
 
         // Symlink compiler docs to the output directory of rustdoc documentation.
-        let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target).join("doc");
+        let out_dir = builder.stage_out(compiler, Mode::ToolRustc)
+            .join(target)
+            .join("doc");
         t!(fs::create_dir_all(&out_dir));
         builder.clear_if_dirty(&out, &rustdoc);
         t!(symlink_dir_force(&builder.config, &out, &out_dir));
 
         // Build cargo command.
         let mut cargo = prepare_tool_cargo(
-            builder, compiler, Mode::ToolRustc, target, "doc", "src/tools/rustdoc");
+            builder,
+            compiler,
+            Mode::ToolRustc,
+            target,
+            "doc",
+            "src/tools/rustdoc",
+        );
 
         cargo.env("RUSTDOCFLAGS", "--document-private-items");
         builder.run(&mut cargo);
index b37a007e86390249fec901326a0220ddd6ab11ba..97fd6f77646637a68c1b9fed02d8181b1d96bc56 100644 (file)
@@ -39,6 +39,9 @@ pub fn install_cargo(builder: &Builder, stage: u32, host: Interned<String>) {
 pub fn install_rls(builder: &Builder, stage: u32, host: Interned<String>) {
     install_sh(builder, "rls", "rls", stage, Some(host));
 }
+pub fn install_clippy(builder: &Builder, stage: u32, host: Interned<String>) {
+    install_sh(builder, "clippy", "clippy", stage, Some(host));
+}
 
 pub fn install_rustfmt(builder: &Builder, stage: u32, host: Interned<String>) {
     install_sh(builder, "rustfmt", "rustfmt", stage, Some(host));
@@ -216,6 +219,14 @@ fn run($sel, $builder: &Builder) {
             builder.info(&format!("skipping Install RLS stage{} ({})", self.stage, self.target));
         }
     };
+    Clippy, "clippy", Self::should_build(_config), only_hosts: true, {
+        if builder.ensure(dist::Clippy { stage: self.stage, target: self.target }).is_some() ||
+            Self::should_install(builder) {
+            install_clippy(builder, self.stage, self.target);
+        } else {
+            builder.info(&format!("skipping Install clippy stage{} ({})", self.stage, self.target));
+        }
+    };
     Rustfmt, "rustfmt", Self::should_build(_config), only_hosts: true, {
         if builder.ensure(dist::Rustfmt { stage: self.stage, target: self.target }).is_some() ||
             Self::should_install(builder) {
index b5d450b88392d0d8bd1c575f72bd4fe0cbc5f5bd..c885c842e40e4e1843768808347f2f9c0725d8d6 100644 (file)
@@ -248,6 +248,7 @@ pub struct Build {
     rust_info: channel::GitInfo,
     cargo_info: channel::GitInfo,
     rls_info: channel::GitInfo,
+    clippy_info: channel::GitInfo,
     rustfmt_info: channel::GitInfo,
     local_rebuild: bool,
     fail_fast: bool,
@@ -327,16 +328,23 @@ pub enum Mode {
     /// Build codegen libraries, placing output in the "stageN-codegen" directory
     Codegen,
 
-    /// Build some tools, placing output in the "stageN-tools" directory.
+    /// Build some tools, placing output in the "stageN-tools" directory. The
+    /// "other" here is for miscellaneous sets of tools that are built using the
+    /// bootstrap compiler in its entirety (target libraries and all).
+    /// Typically these tools compile with stable Rust.
+    ToolBootstrap,
+
+    /// Compile a tool which uses all libraries we compile (up to rustc).
+    /// Doesn't use the stage0 compiler libraries like "other", and includes
+    /// tools like rustdoc, cargo, rls, etc.
     ToolStd,
-    ToolTest,
     ToolRustc,
 }
 
 impl Mode {
     pub fn is_tool(&self) -> bool {
         match self {
-            Mode::ToolStd | Mode::ToolTest | Mode::ToolRustc => true,
+            Mode::ToolBootstrap | Mode::ToolRustc | Mode::ToolStd => true,
             _ => false
         }
     }
@@ -363,6 +371,7 @@ pub fn new(config: Config) -> Build {
         let rust_info = channel::GitInfo::new(&config, &src);
         let cargo_info = channel::GitInfo::new(&config, &src.join("src/tools/cargo"));
         let rls_info = channel::GitInfo::new(&config, &src.join("src/tools/rls"));
+        let clippy_info = channel::GitInfo::new(&config, &src.join("src/tools/clippy"));
         let rustfmt_info = channel::GitInfo::new(&config, &src.join("src/tools/rustfmt"));
 
         let mut build = Build {
@@ -384,6 +393,7 @@ pub fn new(config: Config) -> Build {
             rust_info,
             cargo_info,
             rls_info,
+            clippy_info,
             rustfmt_info,
             cc: HashMap::new(),
             cxx: HashMap::new(),
@@ -544,7 +554,9 @@ fn stage_out(&self, compiler: Compiler, mode: Mode) -> PathBuf {
             Mode::Test => "-test",
             Mode::Codegen => "-rustc",
             Mode::Rustc => "-rustc",
-            Mode::ToolStd | Mode::ToolTest | Mode::ToolRustc => "-tools",
+            Mode::ToolBootstrap => "-bootstrap-tools",
+            Mode::ToolStd => "-tools",
+            Mode::ToolRustc => "-tools",
         };
         self.out.join(&*compiler.host)
                 .join(format!("stage{}{}", compiler.stage, suffix))
@@ -653,8 +665,12 @@ fn add_rust_test_threads(&self, cmd: &mut Command) {
 
     /// Returns the libdir of the snapshot compiler.
     fn rustc_snapshot_libdir(&self) -> PathBuf {
+        self.rustc_snapshot_sysroot().join(libdir(&self.config.build))
+    }
+
+    /// Returns the sysroot of the snapshot compiler.
+    fn rustc_snapshot_sysroot(&self) -> &Path {
         self.initial_rustc.parent().unwrap().parent().unwrap()
-            .join(libdir(&self.config.build))
     }
 
     /// Runs a command, printing out nice contextual information if it fails.
@@ -968,6 +984,11 @@ fn rls_package_vers(&self) -> String {
         self.package_vers(&self.release_num("rls"))
     }
 
+    /// Returns the value of `package_vers` above for clippy
+    fn clippy_package_vers(&self) -> String {
+        self.package_vers(&self.release_num("clippy"))
+    }
+
     /// Returns the value of `package_vers` above for rustfmt
     fn rustfmt_package_vers(&self) -> String {
         self.package_vers(&self.release_num("rustfmt"))
index 7dcdbe9c931cf23984fa9816759f51ddac79b098..93b8880a900ef5539378d457d8f51fe73666f8dc 100644 (file)
@@ -631,6 +631,7 @@ fn run(self, builder: &Builder) {
             "powerpc-unknown-netbsd" => "BSD-generic32",
             "powerpc64-unknown-linux-gnu" => "linux-ppc64",
             "powerpc64le-unknown-linux-gnu" => "linux-ppc64le",
+            "powerpc64le-unknown-linux-musl" => "linux-ppc64le",
             "s390x-unknown-linux-gnu" => "linux64-s390x",
             "sparc-unknown-linux-gnu" => "linux-sparcv9",
             "sparc64-unknown-linux-gnu" => "linux64-sparcv9",
index 90688b1c0e181e095aa73c6ff814879e1fcf8f53..6254f98165665630550f7c68dbf88be360cb6dab 100644 (file)
@@ -1269,17 +1269,15 @@ fn run(self, builder: &Builder) {
 
         files.sort();
 
+        let mut toolstate = ToolState::TestPass;
         for file in files {
-            let test_result = markdown_test(builder, compiler, &file);
-            if self.is_ext_doc {
-                let toolstate = if test_result {
-                    ToolState::TestPass
-                } else {
-                    ToolState::TestFail
-                };
-                builder.save_toolstate(self.name, toolstate);
+            if !markdown_test(builder, compiler, &file) {
+                toolstate = ToolState::TestFail;
             }
         }
+        if self.is_ext_doc {
+            builder.save_toolstate(self.name, toolstate);
+        }
     }
 }
 
@@ -1808,7 +1806,10 @@ fn run(self, builder: &Builder) {
         builder.info(&format!("REMOTE copy libs to emulator ({})", target));
         t!(fs::create_dir_all(builder.out.join("tmp")));
 
-        let server = builder.ensure(tool::RemoteTestServer { compiler, target });
+        let server = builder.ensure(tool::RemoteTestServer {
+            compiler: compiler.with_stage(0),
+            target,
+        });
 
         // Spawn the emulator and wait for it to come online
         let tool = builder.tool_exe(Tool::RemoteTestClient);
index 0a428a61d120299354400223834a0eacfa0e1501..32d1e428e7607686dac8862110a930349b9d056b 100644 (file)
@@ -104,9 +104,13 @@ fn run(self, builder: &Builder) -> Option<PathBuf> {
         let is_ext_tool = self.is_ext_tool;
 
         match self.mode {
-            Mode::ToolStd => builder.ensure(compile::Std { compiler, target }),
-            Mode::ToolTest => builder.ensure(compile::Test { compiler, target }),
-            Mode::ToolRustc => builder.ensure(compile::Rustc { compiler, target }),
+            Mode::ToolRustc => {
+                builder.ensure(compile::Rustc { compiler, target })
+            }
+            Mode::ToolStd => {
+                builder.ensure(compile::Std { compiler, target })
+            }
+            Mode::ToolBootstrap => {} // uses downloaded stage0 compiler libs
             _ => panic!("unexpected Mode for tool build")
         }
 
@@ -118,7 +122,7 @@ fn run(self, builder: &Builder) -> Option<PathBuf> {
         let mut duplicates = Vec::new();
         let is_expected = compile::stream_cargo(builder, &mut cargo, &mut |msg| {
             // Only care about big things like the RLS/Cargo for now
-            if tool != "rls" && tool != "cargo" {
+            if tool != "rls" && tool != "cargo" && tool != "clippy-driver" {
                 return
             }
             let (id, features, filenames) = match msg {
@@ -341,17 +345,17 @@ fn run(self, builder: &Builder) -> PathBuf {
 }
 
 tool!(
-    Rustbook, "src/tools/rustbook", "rustbook", Mode::ToolRustc;
+    Rustbook, "src/tools/rustbook", "rustbook", Mode::ToolBootstrap;
     ErrorIndex, "src/tools/error_index_generator", "error_index_generator", Mode::ToolRustc;
-    UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen", Mode::ToolStd;
-    Tidy, "src/tools/tidy", "tidy", Mode::ToolStd;
-    Linkchecker, "src/tools/linkchecker", "linkchecker", Mode::ToolStd;
-    CargoTest, "src/tools/cargotest", "cargotest", Mode::ToolStd;
-    Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolTest, llvm_tools = true;
-    BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::ToolStd;
-    RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::ToolStd;
-    RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolStd;
-    RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes", Mode::ToolStd;
+    UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen", Mode::ToolBootstrap;
+    Tidy, "src/tools/tidy", "tidy", Mode::ToolBootstrap;
+    Linkchecker, "src/tools/linkchecker", "linkchecker", Mode::ToolBootstrap;
+    CargoTest, "src/tools/cargotest", "cargotest", Mode::ToolBootstrap;
+    Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolBootstrap, llvm_tools = true;
+    BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::ToolBootstrap;
+    RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::ToolBootstrap;
+    RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolBootstrap;
+    RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes", Mode::ToolBootstrap;
 );
 
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
@@ -604,7 +608,11 @@ pub fn tool_cmd(&self, tool: Tool) -> Command {
     fn prepare_tool_cmd(&self, compiler: Compiler, tool: Tool, cmd: &mut Command) {
         let host = &compiler.host;
         let mut lib_paths: Vec<PathBuf> = vec![
-            PathBuf::from(&self.sysroot_libdir(compiler, compiler.host)),
+            if compiler.stage == 0 {
+                self.build.rustc_snapshot_libdir()
+            } else {
+                PathBuf::from(&self.sysroot_libdir(compiler, compiler.host))
+            },
             self.cargo_out(compiler, tool.get_mode(), *host).join("deps"),
         ];
 
index 56e637249f5ca824418b1f20b734f450aad90d4a..e8197e9085182accd4e53aa2c43f9e7c95ac5fb1 100755 (executable)
@@ -79,11 +79,11 @@ status_check() {
     check_dispatch $1 beta nomicon src/doc/nomicon
     check_dispatch $1 beta reference src/doc/reference
     check_dispatch $1 beta rust-by-example src/doc/rust-by-example
-    check_dispatch $1 beta rls src/tool/rls
-    check_dispatch $1 beta rustfmt src/tool/rustfmt
+    check_dispatch $1 beta rls src/tools/rls
+    check_dispatch $1 beta rustfmt src/tools/rustfmt
     # these tools are not required for beta to successfully branch
-    check_dispatch $1 nightly clippy-driver src/tool/clippy
-    check_dispatch $1 nightly miri src/tool/miri
+    check_dispatch $1 nightly clippy-driver src/tools/clippy
+    check_dispatch $1 nightly miri src/tools/miri
 }
 
 # If this PR is intended to update one of these tools, do not let the build pass
index 7639537fc553539055e976c897388d278221fce1..e4af122d0cb98d55938994581144f0803faa0f33 100644 (file)
@@ -170,6 +170,23 @@ By repeating all parts of the example, you can ensure that your example still
 compiles, while only showing the parts that are relevant to that part of your
 explanation.
 
+The `#`-hiding of lines can be prevented by using two consecutive hashes
+`##`. This only needs to be done with with the first `#` which would've
+otherwise caused hiding. If we have a string literal like the following,
+which has a line that starts with a `#`:
+
+```rust
+let s = "foo
+## bar # baz";
+```
+
+We can document it by escaping the initial `#`:
+
+```text
+/// let s = "foo
+/// ## bar # baz";
+```
+
 
 ## Using `?` in doc tests
 
index 98d6202a63fbf75468bcf71206a540329d8efa9b..378aae597331600acfbf5e42f1242c6e46c10870 100644 (file)
@@ -107,6 +107,10 @@ imports.env = {
   exp2f: function(x) { return Math.pow(2, x); },
   ldexp: function(x, y) { return x * Math.pow(2, y); },
   ldexpf: function(x, y) { return x * Math.pow(2, y); },
+  sin: Math.sin,
+  sinf: Math.sin,
+  cos: Math.cos,
+  cosf: Math.cos,
   log: Math.log,
   log2: Math.log2,
   log10: Math.log10,
index 6a05ef680889aeb4d12ba634a4234e164f6a2523..fb16bdf0ab43ae4d4872b87f4c44d5bb6aabb081 100644 (file)
 use core::any::Any;
 use core::borrow;
 use core::cmp::Ordering;
+use core::convert::From;
 use core::fmt;
-use core::future::Future;
+use core::future::{Future, FutureObj, LocalFutureObj, UnsafeFutureObj};
 use core::hash::{Hash, Hasher};
 use core::iter::FusedIterator;
 use core::marker::{Unpin, Unsize};
 use core::mem::{self, PinMut};
 use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
 use core::ptr::{self, NonNull, Unique};
-use core::task::{Context, Poll, UnsafeTask, TaskObj, LocalTaskObj};
-use core::convert::From;
+use core::task::{Context, Poll};
 
 use raw_vec::RawVec;
 use str::from_boxed_utf8_unchecked;
@@ -915,7 +915,7 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinBox<U>> for PinBox<T> {}
 impl<T: ?Sized> Unpin for PinBox<T> {}
 
 #[unstable(feature = "futures_api", issue = "50547")]
-impl<'a, F: ?Sized + Future + Unpin> Future for Box<F> {
+impl<F: ?Sized + Future + Unpin> Future for Box<F> {
     type Output = F::Output;
 
     fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
@@ -924,7 +924,7 @@ fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
 }
 
 #[unstable(feature = "futures_api", issue = "50547")]
-impl<'a, F: ?Sized + Future> Future for PinBox<F> {
+impl<F: ?Sized + Future> Future for PinBox<F> {
     type Output = F::Output;
 
     fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
@@ -933,46 +933,67 @@ fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
 }
 
 #[unstable(feature = "futures_api", issue = "50547")]
-unsafe impl<F: Future<Output = ()> + 'static> UnsafeTask for PinBox<F> {
+unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Box<F>
+    where F: Future<Output = T> + 'a
+{
+    fn into_raw(self) -> *mut () {
+        Box::into_raw(self) as *mut ()
+    }
+
+    unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T> {
+        let ptr = ptr as *mut F;
+        let pin: PinMut<F> = PinMut::new_unchecked(&mut *ptr);
+        pin.poll(cx)
+    }
+
+    unsafe fn drop(ptr: *mut ()) {
+        drop(Box::from_raw(ptr as *mut F))
+    }
+}
+
+#[unstable(feature = "futures_api", issue = "50547")]
+unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for PinBox<F>
+    where F: Future<Output = T> + 'a
+{
     fn into_raw(self) -> *mut () {
         PinBox::into_raw(self) as *mut ()
     }
 
-    unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<()> {
-        let ptr = task as *mut F;
+    unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T> {
+        let ptr = ptr as *mut F;
         let pin: PinMut<F> = PinMut::new_unchecked(&mut *ptr);
         pin.poll(cx)
     }
 
-    unsafe fn drop(task: *mut ()) {
-        drop(PinBox::from_raw(task as *mut F))
+    unsafe fn drop(ptr: *mut ()) {
+        drop(PinBox::from_raw(ptr as *mut F))
     }
 }
 
 #[unstable(feature = "futures_api", issue = "50547")]
-impl<F: Future<Output = ()> + Send + 'static> From<PinBox<F>> for TaskObj {
+impl<'a, F: Future<Output = ()> + Send + 'a> From<PinBox<F>> for FutureObj<'a, ()> {
     fn from(boxed: PinBox<F>) -> Self {
-        TaskObj::new(boxed)
+        FutureObj::new(boxed)
     }
 }
 
 #[unstable(feature = "futures_api", issue = "50547")]
-impl<F: Future<Output = ()> + Send + 'static> From<Box<F>> for TaskObj {
+impl<'a, F: Future<Output = ()> + Send + 'a> From<Box<F>> for FutureObj<'a, ()> {
     fn from(boxed: Box<F>) -> Self {
-        TaskObj::new(PinBox::from(boxed))
+        FutureObj::new(boxed)
     }
 }
 
 #[unstable(feature = "futures_api", issue = "50547")]
-impl<F: Future<Output = ()> + 'static> From<PinBox<F>> for LocalTaskObj {
+impl<'a, F: Future<Output = ()> + 'a> From<PinBox<F>> for LocalFutureObj<'a, ()> {
     fn from(boxed: PinBox<F>) -> Self {
-        LocalTaskObj::new(boxed)
+        LocalFutureObj::new(boxed)
     }
 }
 
 #[unstable(feature = "futures_api", issue = "50547")]
-impl<F: Future<Output = ()> + 'static> From<Box<F>> for LocalTaskObj {
+impl<'a, F: Future<Output = ()> + 'a> From<Box<F>> for LocalFutureObj<'a, ()> {
     fn from(boxed: Box<F>) -> Self {
-        LocalTaskObj::new(PinBox::from(boxed))
+        LocalFutureObj::new(boxed)
     }
 }
index e6e454446e232de826fe5a77a4837d4d5a2679e1..8c950cd06d9e385373f56175d5253060c4e8390a 100644 (file)
@@ -149,12 +149,11 @@ fn drop(&mut self) {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
     fn clone(&self) -> BTreeMap<K, V> {
-        fn clone_subtree<K: Clone, V: Clone>(node: node::NodeRef<marker::Immut,
-                                                                 K,
-                                                                 V,
-                                                                 marker::LeafOrInternal>)
-                                             -> BTreeMap<K, V> {
-
+        fn clone_subtree<'a, K: Clone, V: Clone>(
+            node: node::NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>
+        ) -> BTreeMap<K, V>
+        where K: 'a, V: 'a,
+        {
             match node.force() {
                 Leaf(leaf) => {
                     let mut out_tree = BTreeMap {
@@ -213,7 +212,16 @@ fn clone_subtree<K: Clone, V: Clone>(node: node::NodeRef<marker::Immut,
             }
         }
 
-        clone_subtree(self.root.as_ref())
+        if self.len() == 0 {
+            // Ideally we'd call `BTreeMap::new` here, but that has the `K:
+            // Ord` constraint, which this method lacks.
+            BTreeMap {
+                root: node::Root::shared_empty_root(),
+                length: 0,
+            }
+        } else {
+            clone_subtree(self.root.as_ref())
+        }
     }
 }
 
@@ -1071,7 +1079,11 @@ pub fn split_off<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self
 
     /// Calculates the number of elements if it is incorrect.
     fn recalc_length(&mut self) {
-        fn dfs<K, V>(node: NodeRef<marker::Immut, K, V, marker::LeafOrInternal>) -> usize {
+        fn dfs<'a, K, V>(
+            node: NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>
+        ) -> usize
+        where K: 'a, V: 'a
+        {
             let mut res = node.len();
 
             if let Internal(node) = node.force() {
index 21edc6dfee4e591677ff8f4eed37e317032c2a63..2292617f51e6b62ae33ae25b3f68d379ccecf403 100644 (file)
 ///
 /// See the [module-level documentation](index.html) for more.
 #[stable(feature = "rust1", since = "1.0.0")]
+#[repr(transparent)]
 pub struct Cell<T> {
     value: UnsafeCell<T>,
 }
@@ -1395,6 +1396,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// ```
 #[lang = "unsafe_cell"]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[repr(transparent)]
 pub struct UnsafeCell<T: ?Sized> {
     value: T,
 }
diff --git a/src/libcore/future.rs b/src/libcore/future.rs
deleted file mode 100644 (file)
index 153cd6c..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![unstable(feature = "futures_api",
-            reason = "futures in libcore are unstable",
-            issue = "50547")]
-
-//! Asynchronous values.
-
-use mem::PinMut;
-use marker::Unpin;
-use task::{self, Poll};
-
-/// A future represents an asychronous computation.
-///
-/// A future is a value that may not have finished computing yet. This kind of
-/// "asynchronous value" makes it possible for a thread to continue doing useful
-/// work while it waits for the value to become available.
-///
-/// # The `poll` method
-///
-/// The core method of future, `poll`, *attempts* to resolve the future into a
-/// final value. This method does not block if the value is not ready. Instead,
-/// the current task is scheduled to be woken up when it's possible to make
-/// further progress by `poll`ing again. The wake up is performed using
-/// `cx.waker()`, a handle for waking up the current task.
-///
-/// When using a future, you generally won't call `poll` directly, but instead
-/// `await!` the value.
-pub trait Future {
-    /// The result of the `Future`.
-    type Output;
-
-    /// Attempt to resolve the future to a final value, registering
-    /// the current task for wakeup if the value is not yet available.
-    ///
-    /// # Return value
-    ///
-    /// This function returns:
-    ///
-    /// - [`Poll::Pending`] if the future is not ready yet
-    /// - [`Poll::Ready(val)`] with the result `val` of this future if it
-    ///   finished successfully.
-    ///
-    /// Once a future has finished, clients should not `poll` it again.
-    ///
-    /// When a future is not ready yet, `poll` returns
-    /// `Poll::Pending`. The future will *also* register the
-    /// interest of the current task in the value being produced. For example,
-    /// if the future represents the availability of data on a socket, then the
-    /// task is recorded so that when data arrives, it is woken up (via
-    /// [`cx.waker()`]). Once a task has been woken up,
-    /// it should attempt to `poll` the future again, which may or may not
-    /// produce a final value.
-    ///
-    /// Note that if `Pending` is returned it only means that the *current* task
-    /// (represented by the argument `cx`) will receive a notification. Tasks
-    /// from previous calls to `poll` will *not* receive notifications.
-    ///
-    /// # Runtime characteristics
-    ///
-    /// Futures alone are *inert*; they must be *actively* `poll`ed to make
-    /// progress, meaning that each time the current task is woken up, it should
-    /// actively re-`poll` pending futures that it still has an interest in.
-    ///
-    /// The `poll` function is not called repeatedly in a tight loop for
-    /// futures, but only whenever the future itself is ready, as signaled via
-    /// the `Waker` inside `task::Context`. If you're familiar with the
-    /// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
-    /// typically do *not* suffer the same problems of "all wakeups must poll
-    /// all events"; they are more like `epoll(4)`.
-    ///
-    /// An implementation of `poll` should strive to return quickly, and must
-    /// *never* block. Returning quickly prevents unnecessarily clogging up
-    /// threads or event loops. If it is known ahead of time that a call to
-    /// `poll` may end up taking awhile, the work should be offloaded to a
-    /// thread pool (or something similar) to ensure that `poll` can return
-    /// quickly.
-    ///
-    /// # Panics
-    ///
-    /// Once a future has completed (returned `Ready` from `poll`),
-    /// then any future calls to `poll` may panic, block forever, or otherwise
-    /// cause bad behavior. The `Future` trait itself provides no guarantees
-    /// about the behavior of `poll` after a future has completed.
-    ///
-    /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending
-    /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready
-    /// [`cx.waker()`]: ../task/struct.Context.html#method.waker
-    fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output>;
-}
-
-impl<'a, F: ?Sized + Future + Unpin> Future for &'a mut F {
-    type Output = F::Output;
-
-    fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
-        F::poll(PinMut::new(&mut **self), cx)
-    }
-}
-
-impl<'a, F: ?Sized + Future> Future for PinMut<'a, F> {
-    type Output = F::Output;
-
-    fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
-        F::poll((*self).reborrow(), cx)
-    }
-}
diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs
new file mode 100644 (file)
index 0000000..10b4ca9
--- /dev/null
@@ -0,0 +1,112 @@
+// 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.
+
+#![unstable(feature = "futures_api",
+            reason = "futures in libcore are unstable",
+            issue = "50547")]
+
+use mem::PinMut;
+use marker::Unpin;
+use task::{self, Poll};
+
+/// A future represents an asychronous computation.
+///
+/// A future is a value that may not have finished computing yet. This kind of
+/// "asynchronous value" makes it possible for a thread to continue doing useful
+/// work while it waits for the value to become available.
+///
+/// # The `poll` method
+///
+/// The core method of future, `poll`, *attempts* to resolve the future into a
+/// final value. This method does not block if the value is not ready. Instead,
+/// the current task is scheduled to be woken up when it's possible to make
+/// further progress by `poll`ing again. The wake up is performed using
+/// `cx.waker()`, a handle for waking up the current task.
+///
+/// When using a future, you generally won't call `poll` directly, but instead
+/// `await!` the value.
+pub trait Future {
+    /// The result of the `Future`.
+    type Output;
+
+    /// Attempt to resolve the future to a final value, registering
+    /// the current task for wakeup if the value is not yet available.
+    ///
+    /// # Return value
+    ///
+    /// This function returns:
+    ///
+    /// - [`Poll::Pending`] if the future is not ready yet
+    /// - [`Poll::Ready(val)`] with the result `val` of this future if it
+    ///   finished successfully.
+    ///
+    /// Once a future has finished, clients should not `poll` it again.
+    ///
+    /// When a future is not ready yet, `poll` returns
+    /// `Poll::Pending`. The future will *also* register the
+    /// interest of the current task in the value being produced. For example,
+    /// if the future represents the availability of data on a socket, then the
+    /// task is recorded so that when data arrives, it is woken up (via
+    /// [`cx.waker()`]). Once a task has been woken up,
+    /// it should attempt to `poll` the future again, which may or may not
+    /// produce a final value.
+    ///
+    /// Note that if `Pending` is returned it only means that the *current* task
+    /// (represented by the argument `cx`) will receive a notification. Tasks
+    /// from previous calls to `poll` will *not* receive notifications.
+    ///
+    /// # Runtime characteristics
+    ///
+    /// Futures alone are *inert*; they must be *actively* `poll`ed to make
+    /// progress, meaning that each time the current task is woken up, it should
+    /// actively re-`poll` pending futures that it still has an interest in.
+    ///
+    /// The `poll` function is not called repeatedly in a tight loop for
+    /// futures, but only whenever the future itself is ready, as signaled via
+    /// the `Waker` inside `task::Context`. If you're familiar with the
+    /// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
+    /// typically do *not* suffer the same problems of "all wakeups must poll
+    /// all events"; they are more like `epoll(4)`.
+    ///
+    /// An implementation of `poll` should strive to return quickly, and must
+    /// *never* block. Returning quickly prevents unnecessarily clogging up
+    /// threads or event loops. If it is known ahead of time that a call to
+    /// `poll` may end up taking awhile, the work should be offloaded to a
+    /// thread pool (or something similar) to ensure that `poll` can return
+    /// quickly.
+    ///
+    /// # Panics
+    ///
+    /// Once a future has completed (returned `Ready` from `poll`),
+    /// then any future calls to `poll` may panic, block forever, or otherwise
+    /// cause bad behavior. The `Future` trait itself provides no guarantees
+    /// about the behavior of `poll` after a future has completed.
+    ///
+    /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending
+    /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready
+    /// [`cx.waker()`]: ../task/struct.Context.html#method.waker
+    fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output>;
+}
+
+impl<'a, F: ?Sized + Future + Unpin> Future for &'a mut F {
+    type Output = F::Output;
+
+    fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
+        F::poll(PinMut::new(&mut **self), cx)
+    }
+}
+
+impl<'a, F: ?Sized + Future> Future for PinMut<'a, F> {
+    type Output = F::Output;
+
+    fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
+        F::poll((*self).reborrow(), cx)
+    }
+}
diff --git a/src/libcore/future/future_obj.rs b/src/libcore/future/future_obj.rs
new file mode 100644 (file)
index 0000000..98c504a
--- /dev/null
@@ -0,0 +1,179 @@
+// 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.
+
+#![unstable(feature = "futures_api",
+            reason = "futures in libcore are unstable",
+            issue = "50547")]
+
+use fmt;
+use future::Future;
+use marker::{PhantomData, Unpin};
+use mem::PinMut;
+use task::{Context, Poll};
+
+/// A custom trait object for polling futures, roughly akin to
+/// `Box<dyn Future<Output = T> + 'a>`.
+///
+/// This custom trait object was introduced for two reasons:
+/// - Currently it is not possible to take `dyn Trait` by value and
+///   `Box<dyn Trait>` is not available in no_std contexts.
+/// - The `Future` trait is currently not object safe: The `Future::poll`
+///   method makes uses the arbitrary self types feature and traits in which
+///   this feature is used are currently not object safe due to current compiler
+///   limitations. (See tracking issue for arbitray self types for more
+///   information #44874)
+pub struct LocalFutureObj<'a, T> {
+    ptr: *mut (),
+    poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<T>,
+    drop_fn: unsafe fn(*mut ()),
+    _marker: PhantomData<&'a ()>,
+}
+
+impl<'a, T> LocalFutureObj<'a, T> {
+    /// Create a `LocalFutureObj` from a custom trait object representation.
+    #[inline]
+    pub fn new<F: UnsafeFutureObj<'a, T> + 'a>(f: F) -> LocalFutureObj<'a, T> {
+        LocalFutureObj {
+            ptr: f.into_raw(),
+            poll_fn: F::poll,
+            drop_fn: F::drop,
+            _marker: PhantomData,
+        }
+    }
+
+    /// Converts the `LocalFutureObj` into a `FutureObj`
+    /// To make this operation safe one has to ensure that the `UnsafeFutureObj`
+    /// instance from which this `LocalFutureObj` was created actually
+    /// implements `Send`.
+    #[inline]
+    pub unsafe fn into_future_obj(self) -> FutureObj<'a, T> {
+        FutureObj(self)
+    }
+}
+
+impl<'a, T> fmt::Debug for LocalFutureObj<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("LocalFutureObj")
+            .finish()
+    }
+}
+
+impl<'a, T> From<FutureObj<'a, T>> for LocalFutureObj<'a, T> {
+    #[inline]
+    fn from(f: FutureObj<'a, T>) -> LocalFutureObj<'a, T> {
+        f.0
+    }
+}
+
+impl<'a, T> Future for LocalFutureObj<'a, T> {
+    type Output = T;
+
+    #[inline]
+    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
+        unsafe {
+            (self.poll_fn)(self.ptr, cx)
+        }
+    }
+}
+
+impl<'a, T> Drop for LocalFutureObj<'a, T> {
+    fn drop(&mut self) {
+        unsafe {
+            (self.drop_fn)(self.ptr)
+        }
+    }
+}
+
+/// A custom trait object for polling futures, roughly akin to
+/// `Box<dyn Future<Output = T> + Send + 'a>`.
+///
+/// This custom trait object was introduced for two reasons:
+/// - Currently it is not possible to take `dyn Trait` by value and
+///   `Box<dyn Trait>` is not available in no_std contexts.
+/// - The `Future` trait is currently not object safe: The `Future::poll`
+///   method makes uses the arbitrary self types feature and traits in which
+///   this feature is used are currently not object safe due to current compiler
+///   limitations. (See tracking issue for arbitray self types for more
+///   information #44874)
+pub struct FutureObj<'a, T>(LocalFutureObj<'a, T>);
+
+unsafe impl<'a, T> Send for FutureObj<'a, T> {}
+
+impl<'a, T> FutureObj<'a, T> {
+    /// Create a `FutureObj` from a custom trait object representation.
+    #[inline]
+    pub fn new<F: UnsafeFutureObj<'a, T> + Send>(f: F) -> FutureObj<'a, T> {
+        FutureObj(LocalFutureObj::new(f))
+    }
+}
+
+impl<'a, T> fmt::Debug for FutureObj<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("FutureObj")
+            .finish()
+    }
+}
+
+impl<'a, T> Future for FutureObj<'a, T> {
+    type Output = T;
+
+    #[inline]
+    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
+        let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
+        pinned_field.poll(cx)
+    }
+}
+
+/// A custom implementation of a future trait object for `FutureObj`, providing
+/// a hand-rolled vtable.
+///
+/// This custom representation is typically used only in `no_std` contexts,
+/// where the default `Box`-based implementation is not available.
+///
+/// The implementor must guarantee that it is safe to call `poll` repeatedly (in
+/// a non-concurrent fashion) with the result of `into_raw` until `drop` is
+/// called.
+pub unsafe trait UnsafeFutureObj<'a, T>: 'a {
+    /// Convert an owned instance into a (conceptually owned) void pointer.
+    fn into_raw(self) -> *mut ();
+
+    /// Poll the future represented by the given void pointer.
+    ///
+    /// # Safety
+    ///
+    /// The trait implementor must guarantee that it is safe to repeatedly call
+    /// `poll` with the result of `into_raw` until `drop` is called; such calls
+    /// are not, however, allowed to race with each other or with calls to
+    /// `drop`.
+    unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T>;
+
+    /// Drops the future represented by the given void pointer.
+    ///
+    /// # Safety
+    ///
+    /// The trait implementor must guarantee that it is safe to call this
+    /// function once per `into_raw` invocation; that call cannot race with
+    /// other calls to `drop` or `poll`.
+    unsafe fn drop(ptr: *mut ());
+}
+
+unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for &'a mut F
+    where F: Future<Output = T> + Unpin + 'a
+{
+    fn into_raw(self) -> *mut () {
+        self as *mut F as *mut ()
+    }
+
+    unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T> {
+        PinMut::new_unchecked(&mut *(ptr as *mut F)).poll(cx)
+    }
+
+    unsafe fn drop(_ptr: *mut ()) {}
+}
diff --git a/src/libcore/future/mod.rs b/src/libcore/future/mod.rs
new file mode 100644 (file)
index 0000000..f9361a0
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![unstable(feature = "futures_api",
+            reason = "futures in libcore are unstable",
+            issue = "50547")]
+
+//! Asynchronous values.
+
+mod future;
+pub use self::future::Future;
+
+mod future_obj;
+pub use self::future_obj::{FutureObj, LocalFutureObj, UnsafeFutureObj};
index 5896322f111f8e16e494719c0613488a8268efab..0b279f66b88d6e31ef5e7aa038bac239eb6369c9 100644 (file)
@@ -91,7 +91,7 @@ fn steps_between(start: &$t, end: &$t) -> Option<usize> {
             #[inline]
             #[allow(unreachable_patterns)]
             fn add_usize(&self, n: usize) -> Option<Self> {
-                match <$t>::private_try_from(n) {
+                match <$t>::try_from(n) {
                     Ok(n_as_t) => self.checked_add(n_as_t),
                     Err(_) => None,
                 }
@@ -123,7 +123,7 @@ fn steps_between(start: &$t, end: &$t) -> Option<usize> {
             #[inline]
             #[allow(unreachable_patterns)]
             fn add_usize(&self, n: usize) -> Option<Self> {
-                match <$unsigned>::private_try_from(n) {
+                match <$unsigned>::try_from(n) {
                     Ok(n_as_unsigned) => {
                         // Wrapping in unsigned space handles cases like
                         // `-120_i8.add_usize(200) == Some(80_i8)`,
@@ -461,74 +461,3 @@ fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
 
 #[stable(feature = "fused", since = "1.26.0")]
 impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}
-
-/// Compensate removal of some impls per
-/// https://github.com/rust-lang/rust/pull/49305#issuecomment-376293243
-trait PrivateTryFromUsize: Sized {
-    fn private_try_from(n: usize) -> Result<Self, ()>;
-}
-
-impl<T> PrivateTryFromUsize for T where T: TryFrom<usize> {
-    #[inline]
-    fn private_try_from(n: usize) -> Result<Self, ()> {
-        T::try_from(n).map_err(|_| ())
-    }
-}
-
-// no possible bounds violation
-macro_rules! try_from_unbounded {
-    ($($target:ty),*) => {$(
-        impl PrivateTryFromUsize for $target {
-            #[inline]
-            fn private_try_from(value: usize) -> Result<Self, ()> {
-                Ok(value as $target)
-            }
-        }
-    )*}
-}
-
-// unsigned to signed (only positive bound)
-#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
-macro_rules! try_from_upper_bounded {
-    ($($target:ty),*) => {$(
-        impl PrivateTryFromUsize for $target {
-            #[inline]
-            fn private_try_from(u: usize) -> Result<$target, ()> {
-                if u > (<$target>::max_value() as usize) {
-                    Err(())
-                } else {
-                    Ok(u as $target)
-                }
-            }
-        }
-    )*}
-}
-
-
-#[cfg(target_pointer_width = "16")]
-mod ptr_try_from_impls {
-    use super::PrivateTryFromUsize;
-
-    try_from_unbounded!(u16, u32, u64, u128);
-    try_from_unbounded!(i32, i64, i128);
-}
-
-#[cfg(target_pointer_width = "32")]
-mod ptr_try_from_impls {
-    use super::PrivateTryFromUsize;
-
-    try_from_upper_bounded!(u16);
-    try_from_unbounded!(u32, u64, u128);
-    try_from_upper_bounded!(i32);
-    try_from_unbounded!(i64, i128);
-}
-
-#[cfg(target_pointer_width = "64")]
-mod ptr_try_from_impls {
-    use super::PrivateTryFromUsize;
-
-    try_from_upper_bounded!(u16, u32);
-    try_from_unbounded!(u64, u128);
-    try_from_upper_bounded!(i32, i64);
-    try_from_unbounded!(i128);
-}
index bbe6ae8619fec5bd27a154fe61afb5794b0a3664..b2b38820a89ccd2982cbb8664410a744c41dbfeb 100644 (file)
 #![feature(const_slice_len)]
 #![feature(const_str_as_bytes)]
 #![feature(const_str_len)]
+#![cfg_attr(stage0, feature(repr_transparent))]
 
 #[prelude_import]
 #[allow(unused)]
index 5db5d88d4a5ff9bc2e3036ba5e9d1ecb46ed7c7b..4a54ebce0a313564f62cf4fd4b72606dda1136fc 100644 (file)
@@ -625,6 +625,12 @@ unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {}
 #[unstable(feature = "pin", issue = "49150")]
 impl !Unpin for Pinned {}
 
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized + 'a> Unpin for &'a T {}
+
+#[unstable(feature = "pin", issue = "49150")]
+impl<'a, T: ?Sized + 'a> Unpin for &'a mut T {}
+
 /// Implementations of `Copy` for primitive types.
 ///
 /// Implementations that cannot be described in Rust
index 08bd9289ab48758559b14030151c36e343fbb078..84173654655ebbe28f496e5ebbe11b040fec1835 100644 (file)
 use clone;
 use cmp;
 use fmt;
+use future::{Future, UnsafeFutureObj};
 use hash;
 use intrinsics;
 use marker::{Copy, PhantomData, Sized, Unpin, Unsize};
 use ptr;
+use task::{Context, Poll};
 use ops::{Deref, DerefMut, CoerceUnsized};
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1227,3 +1229,18 @@ impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinMut<'a, U>> for PinM
 
 #[unstable(feature = "pin", issue = "49150")]
 impl<'a, T: ?Sized> Unpin for PinMut<'a, T> {}
+
+#[unstable(feature = "futures_api", issue = "50547")]
+unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for PinMut<'a, F>
+    where F: Future<Output = T> + 'a
+{
+    fn into_raw(self) -> *mut () {
+        unsafe { PinMut::get_mut_unchecked(self) as *mut F as *mut () }
+    }
+
+    unsafe fn poll(ptr: *mut (), cx: &mut Context) -> Poll<T> {
+        PinMut::new_unchecked(&mut *(ptr as *mut F)).poll(cx)
+    }
+
+    unsafe fn drop(_ptr: *mut ()) {}
+}
index ee5230cef8dd9597d89809ec0451bd0397d78fd6..cc36ea7f71391ed99f9eabf697c9475c97b126bd 100644 (file)
@@ -16,6 +16,7 @@
 /// NULL or 0 that might allow certain optimizations.
 #[lang = "non_zero"]
 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[repr(transparent)]
 pub(crate) struct NonZero<T>(pub(crate) T);
 
 impl<T: CoerceUnsized<U>, U> CoerceUnsized<NonZero<U>> for NonZero<T> {}
index e0d267a6ce0ecf46bebfb584945a33fbe955f496..0b8f8f0703df79739414df45ad0b4670a8851897 100644 (file)
@@ -48,6 +48,7 @@ macro_rules! nonzero_integers {
             /// ```
             #[stable(feature = "nonzero", since = "1.28.0")]
             #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+            #[repr(transparent)]
             pub struct $Ty(NonZero<$Int>);
 
             impl $Ty {
@@ -123,6 +124,7 @@ pub fn get(self) -> $Int {
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
+#[repr(transparent)]
 pub struct Wrapping<T>(#[stable(feature = "rust1", since = "1.0.0")]
                        pub T);
 
@@ -4213,6 +4215,21 @@ fn from(never: !) -> TryFromIntError {
     }
 }
 
+// no possible bounds violation
+macro_rules! try_from_unbounded {
+    ($source:ty, $($target:ty),*) => {$(
+        #[unstable(feature = "try_from", issue = "33417")]
+        impl TryFrom<$source> for $target {
+            type Error = TryFromIntError;
+
+            #[inline]
+            fn try_from(value: $source) -> Result<Self, Self::Error> {
+                Ok(value as $target)
+            }
+        }
+    )*}
+}
+
 // only negative bounds
 macro_rules! try_from_lower_bounded {
     ($source:ty, $($target:ty),*) => {$(
@@ -4311,20 +4328,27 @@ macro_rules! rev {
 try_from_upper_bounded!(usize, isize);
 try_from_lower_bounded!(isize, usize);
 
-try_from_upper_bounded!(usize, u8);
-try_from_upper_bounded!(usize, i8, i16);
-try_from_both_bounded!(isize, u8);
-try_from_both_bounded!(isize, i8);
-
 #[cfg(target_pointer_width = "16")]
 mod ptr_try_from_impls {
     use super::TryFromIntError;
     use convert::TryFrom;
 
-    // Fallible across platfoms, only implementation differs
+    try_from_upper_bounded!(usize, u8);
+    try_from_unbounded!(usize, u16, u32, u64, u128);
+    try_from_upper_bounded!(usize, i8, i16);
+    try_from_unbounded!(usize, i32, i64, i128);
+
+    try_from_both_bounded!(isize, u8);
     try_from_lower_bounded!(isize, u16, u32, u64, u128);
+    try_from_both_bounded!(isize, i8);
+    try_from_unbounded!(isize, i16, i32, i64, i128);
+
+    rev!(try_from_upper_bounded, usize, u32, u64, u128);
     rev!(try_from_lower_bounded, usize, i8, i16);
     rev!(try_from_both_bounded, usize, i32, i64, i128);
+
+    rev!(try_from_upper_bounded, isize, u16, u32, u64, u128);
+    rev!(try_from_both_bounded, isize, i32, i64, i128);
 }
 
 #[cfg(target_pointer_width = "32")]
@@ -4332,11 +4356,25 @@ mod ptr_try_from_impls {
     use super::TryFromIntError;
     use convert::TryFrom;
 
-    // Fallible across platfoms, only implementation differs
-    try_from_both_bounded!(isize, u16);
+    try_from_upper_bounded!(usize, u8, u16);
+    try_from_unbounded!(usize, u32, u64, u128);
+    try_from_upper_bounded!(usize, i8, i16, i32);
+    try_from_unbounded!(usize, i64, i128);
+
+    try_from_both_bounded!(isize, u8, u16);
     try_from_lower_bounded!(isize, u32, u64, u128);
+    try_from_both_bounded!(isize, i8, i16);
+    try_from_unbounded!(isize, i32, i64, i128);
+
+    rev!(try_from_unbounded, usize, u32);
+    rev!(try_from_upper_bounded, usize, u64, u128);
     rev!(try_from_lower_bounded, usize, i8, i16, i32);
     rev!(try_from_both_bounded, usize, i64, i128);
+
+    rev!(try_from_unbounded, isize, u16);
+    rev!(try_from_upper_bounded, isize, u32, u64, u128);
+    rev!(try_from_unbounded, isize, i32);
+    rev!(try_from_both_bounded, isize, i64, i128);
 }
 
 #[cfg(target_pointer_width = "64")]
@@ -4344,11 +4382,25 @@ mod ptr_try_from_impls {
     use super::TryFromIntError;
     use convert::TryFrom;
 
-    // Fallible across platfoms, only implementation differs
-    try_from_both_bounded!(isize, u16, u32);
+    try_from_upper_bounded!(usize, u8, u16, u32);
+    try_from_unbounded!(usize, u64, u128);
+    try_from_upper_bounded!(usize, i8, i16, i32, i64);
+    try_from_unbounded!(usize, i128);
+
+    try_from_both_bounded!(isize, u8, u16, u32);
     try_from_lower_bounded!(isize, u64, u128);
+    try_from_both_bounded!(isize, i8, i16, i32);
+    try_from_unbounded!(isize, i64, i128);
+
+    rev!(try_from_unbounded, usize, u32, u64);
+    rev!(try_from_upper_bounded, usize, u128);
     rev!(try_from_lower_bounded, usize, i8, i16, i32, i64);
     rev!(try_from_both_bounded, usize, i128);
+
+    rev!(try_from_unbounded, isize, u16, u32);
+    rev!(try_from_upper_bounded, isize, u64, u128);
+    rev!(try_from_unbounded, isize, i32, i64);
+    rev!(try_from_both_bounded, isize, i128);
 }
 
 #[doc(hidden)]
index 164b29d35159bcd32f2e033f67174cd6dc49b7ee..0af642258c2776157cf3496f106c24c65b765011 100644 (file)
@@ -2665,6 +2665,7 @@ fn ge(&self, other: &*mut T) -> bool { *self >= *other }
            reason = "use NonNull instead and consider PhantomData<T> \
                      (if you also use #[may_dangle]), Send, and/or Sync")]
 #[doc(hidden)]
+#[repr(transparent)]
 pub struct Unique<T: ?Sized> {
     pointer: NonZero<*const T>,
     // NOTE: this marker has no consequences for variance, but is necessary
@@ -2813,6 +2814,7 @@ fn from(p: NonNull<T>) -> Self {
 /// such as Box, Rc, Arc, Vec, and LinkedList. This is the case because they
 /// provide a public API that follows the normal shared XOR mutable rules of Rust.
 #[stable(feature = "nonnull", since = "1.25.0")]
+#[repr(transparent)]
 pub struct NonNull<T: ?Sized> {
     pointer: NonZero<*const T>,
 }
index 73bf80d2f9997782ab3c5324f77d82685d8eed10..f1db5093e9880ab84fe4940c455bbd893700d073 100644 (file)
@@ -13,7 +13,7 @@
             issue = "50547")]
 
 use fmt;
-use super::{TaskObj, LocalTaskObj};
+use future::{FutureObj, LocalFutureObj};
 
 /// A task executor.
 ///
@@ -29,7 +29,7 @@ pub trait Executor {
     ///
     /// The executor may be unable to spawn tasks, either because it has
     /// been shut down or is resource-constrained.
-    fn spawn_obj(&mut self, task: TaskObj) -> Result<(), SpawnObjError>;
+    fn spawn_obj(&mut self, task: FutureObj<'static, ()>) -> Result<(), SpawnObjError>;
 
     /// Determine whether the executor is able to spawn new tasks.
     ///
@@ -76,7 +76,7 @@ pub struct SpawnObjError {
     pub kind: SpawnErrorKind,
 
     /// The task for which spawning was attempted
-    pub task: TaskObj,
+    pub task: FutureObj<'static, ()>,
 }
 
 /// The result of a failed spawn
@@ -86,5 +86,5 @@ pub struct SpawnLocalObjError {
     pub kind: SpawnErrorKind,
 
     /// The task for which spawning was attempted
-    pub task: LocalTaskObj,
+    pub task: LocalFutureObj<'static, ()>,
 }
index d167a37410553081101572465c41fc625583d1ec..c4f075361640f1b887e099b8c797b0ded7082265 100644 (file)
@@ -25,8 +25,5 @@
 mod poll;
 pub use self::poll::Poll;
 
-mod task;
-pub use self::task::{TaskObj, LocalTaskObj, UnsafeTask};
-
 mod wake;
 pub use self::wake::{Waker, LocalWaker, UnsafeWake};
diff --git a/src/libcore/task/task.rs b/src/libcore/task/task.rs
deleted file mode 100644 (file)
index c5a4187..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![unstable(feature = "futures_api",
-            reason = "futures in libcore are unstable",
-            issue = "50547")]
-
-use fmt;
-use future::Future;
-use mem::PinMut;
-use super::{Context, Poll};
-
-/// A custom trait object for polling tasks, roughly akin to
-/// `Box<Future<Output = ()>>`.
-/// Contrary to `TaskObj`, `LocalTaskObj` does not have a `Send` bound.
-pub struct LocalTaskObj {
-    ptr: *mut (),
-    poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<()>,
-    drop_fn: unsafe fn(*mut ()),
-}
-
-impl LocalTaskObj {
-    /// Create a `LocalTaskObj` from a custom trait object representation.
-    #[inline]
-    pub fn new<T: UnsafeTask>(t: T) -> LocalTaskObj {
-        LocalTaskObj {
-            ptr: t.into_raw(),
-            poll_fn: T::poll,
-            drop_fn: T::drop,
-        }
-    }
-
-    /// Converts the `LocalTaskObj` into a `TaskObj`
-    /// To make this operation safe one has to ensure that the `UnsafeTask`
-    /// instance from which this `LocalTaskObj` was created actually implements
-    /// `Send`.
-    pub unsafe fn as_task_obj(self) -> TaskObj {
-        TaskObj(self)
-    }
-}
-
-impl fmt::Debug for LocalTaskObj {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("LocalTaskObj")
-            .finish()
-    }
-}
-
-impl From<TaskObj> for LocalTaskObj {
-    fn from(task: TaskObj) -> LocalTaskObj {
-        task.0
-    }
-}
-
-impl Future for LocalTaskObj {
-    type Output = ();
-
-    #[inline]
-    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
-        unsafe {
-            (self.poll_fn)(self.ptr, cx)
-        }
-    }
-}
-
-impl Drop for LocalTaskObj {
-    fn drop(&mut self) {
-        unsafe {
-            (self.drop_fn)(self.ptr)
-        }
-    }
-}
-
-/// A custom trait object for polling tasks, roughly akin to
-/// `Box<Future<Output = ()> + Send>`.
-pub struct TaskObj(LocalTaskObj);
-
-unsafe impl Send for TaskObj {}
-
-impl TaskObj {
-    /// Create a `TaskObj` from a custom trait object representation.
-    #[inline]
-    pub fn new<T: UnsafeTask + Send>(t: T) -> TaskObj {
-        TaskObj(LocalTaskObj::new(t))
-    }
-}
-
-impl fmt::Debug for TaskObj {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("TaskObj")
-            .finish()
-    }
-}
-
-impl Future for TaskObj {
-    type Output = ();
-
-    #[inline]
-    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
-        let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
-        pinned_field.poll(cx)
-    }
-}
-
-/// A custom implementation of a task trait object for `TaskObj`, providing
-/// a hand-rolled vtable.
-///
-/// This custom representation is typically used only in `no_std` contexts,
-/// where the default `Box`-based implementation is not available.
-///
-/// The implementor must guarantee that it is safe to call `poll` repeatedly (in
-/// a non-concurrent fashion) with the result of `into_raw` until `drop` is
-/// called.
-pub unsafe trait UnsafeTask: 'static {
-    /// Convert a owned instance into a (conceptually owned) void pointer.
-    fn into_raw(self) -> *mut ();
-
-    /// Poll the task represented by the given void pointer.
-    ///
-    /// # Safety
-    ///
-    /// The trait implementor must guarantee that it is safe to repeatedly call
-    /// `poll` with the result of `into_raw` until `drop` is called; such calls
-    /// are not, however, allowed to race with each other or with calls to `drop`.
-    unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<()>;
-
-    /// Drops the task represented by the given void pointer.
-    ///
-    /// # Safety
-    ///
-    /// The trait implementor must guarantee that it is safe to call this
-    /// function once per `into_raw` invocation; that call cannot race with
-    /// other calls to `drop` or `poll`.
-    unsafe fn drop(task: *mut ());
-}
index 4fd45be56fbfb8d092102732da0347fbe26f2bef..418d5af006f74c299f638734b5e53f95fcb7f37c 100644 (file)
@@ -13,6 +13,7 @@
             issue = "50547")]
 
 use fmt;
+use marker::Unpin;
 use ptr::NonNull;
 
 /// A `Waker` is a handle for waking up a task by notifying its executor that it
@@ -25,6 +26,7 @@ pub struct Waker {
     inner: NonNull<UnsafeWake>,
 }
 
+impl Unpin for Waker {}
 unsafe impl Send for Waker {}
 unsafe impl Sync for Waker {}
 
@@ -99,6 +101,7 @@ pub struct LocalWaker {
     inner: NonNull<UnsafeWake>,
 }
 
+impl Unpin for LocalWaker {}
 impl !Send for LocalWaker {}
 impl !Sync for LocalWaker {}
 
index 24fe96a2b82559313605802cdcba06bd6ea01b34..ab96d3126bb22f003829dec2ad19d7f1a9a92711 100644 (file)
 mod dec2flt;
 mod bignum;
 
+
+/// Adds the attribute to all items in the block.
+macro_rules! cfg_block {
+    ($(#[$attr:meta]{$($it:item)*})*) => {$($(
+        #[$attr]
+        $it
+    )*)*}
+}
+
 /// Groups items that assume the pointer width is either 16/32/64, and has to be altered if
 /// support for larger/smaller pointer widths are added in the future.
 macro_rules! assume_usize_width {
@@ -330,6 +339,42 @@ fn $fn_name() {
 
     test_impl_try_from_always_ok! { test_try_u16usize, u16, usize }
     test_impl_try_from_always_ok! { test_try_i16isize, i16, isize }
+
+    test_impl_try_from_always_ok! { test_try_usizeu64, usize, u64 }
+    test_impl_try_from_always_ok! { test_try_usizeu128, usize, u128 }
+    test_impl_try_from_always_ok! { test_try_usizei128, usize, i128 }
+
+    test_impl_try_from_always_ok! { test_try_isizei64, isize, i64 }
+    test_impl_try_from_always_ok! { test_try_isizei128, isize, i128 }
+
+    cfg_block!(
+        #[cfg(target_pointer_width = "16")] {
+            test_impl_try_from_always_ok! { test_try_usizeu16, usize, u16 }
+            test_impl_try_from_always_ok! { test_try_isizei16, isize, i16 }
+            test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 }
+            test_impl_try_from_always_ok! { test_try_usizei32, usize, i32 }
+            test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 }
+            test_impl_try_from_always_ok! { test_try_usizei64, usize, i64 }
+        }
+
+        #[cfg(target_pointer_width = "32")] {
+            test_impl_try_from_always_ok! { test_try_u16isize, u16, isize }
+            test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 }
+            test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 }
+            test_impl_try_from_always_ok! { test_try_u32usize, u32, usize }
+            test_impl_try_from_always_ok! { test_try_i32isize, i32, isize }
+            test_impl_try_from_always_ok! { test_try_usizei64, usize, i64 }
+        }
+
+        #[cfg(target_pointer_width = "64")] {
+            test_impl_try_from_always_ok! { test_try_u16isize, u16, isize }
+            test_impl_try_from_always_ok! { test_try_u32usize, u32, usize }
+            test_impl_try_from_always_ok! { test_try_u32isize, u32, isize }
+            test_impl_try_from_always_ok! { test_try_i32isize, i32, isize }
+            test_impl_try_from_always_ok! { test_try_u64usize, u64, usize }
+            test_impl_try_from_always_ok! { test_try_i64isize, i64, isize }
+        }
+    );
 }
 
 /// Conversions where max of $source can be represented as $target,
@@ -378,6 +423,24 @@ fn $fn_name() {
     test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu64, isize, u64 }
     test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu128, isize, u128 }
     test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeusize, isize, usize }
+
+    cfg_block!(
+        #[cfg(target_pointer_width = "16")] {
+            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu16, isize, u16 }
+            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu32, isize, u32 }
+        }
+
+        #[cfg(target_pointer_width = "32")] {
+            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu32, isize, u32 }
+
+            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32usize, i32, usize }
+        }
+
+        #[cfg(target_pointer_width = "64")] {
+            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32usize, i32, usize }
+            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64usize, i64, usize }
+        }
+    );
 }
 
 /// Conversions where max of $source can not be represented as $target,
@@ -419,9 +482,29 @@ fn $fn_name() {
 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i128, u128, i128 }
 
 assume_usize_width! {
+    test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64isize, u64, isize }
+    test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128isize, u128, isize }
+
     test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei8, usize, i8 }
     test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei16, usize, i16 }
     test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizeisize, usize, isize }
+
+    cfg_block!(
+        #[cfg(target_pointer_width = "16")] {
+            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16isize, u16, isize }
+            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize }
+        }
+
+        #[cfg(target_pointer_width = "32")] {
+            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize }
+            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei32, usize, i32 }
+        }
+
+        #[cfg(target_pointer_width = "64")] {
+            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei32, usize, i32 }
+            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei64, usize, i64 }
+        }
+    );
 }
 
 /// Conversions where min/max of $source can not be represented as $target.
@@ -481,6 +564,34 @@ fn $fn_name() {
 
 assume_usize_width! {
     test_impl_try_from_same_sign_err! { test_try_usizeu8, usize, u8 }
+    test_impl_try_from_same_sign_err! { test_try_u128usize, u128, usize }
+    test_impl_try_from_same_sign_err! { test_try_i128isize, i128, isize }
+
+    cfg_block!(
+        #[cfg(target_pointer_width = "16")] {
+            test_impl_try_from_same_sign_err! { test_try_u32usize, u32, usize }
+            test_impl_try_from_same_sign_err! { test_try_u64usize, u64, usize }
+
+            test_impl_try_from_same_sign_err! { test_try_i32isize, i32, isize }
+            test_impl_try_from_same_sign_err! { test_try_i64isize, i64, isize }
+        }
+
+        #[cfg(target_pointer_width = "32")] {
+            test_impl_try_from_same_sign_err! { test_try_u64usize, u64, usize }
+            test_impl_try_from_same_sign_err! { test_try_usizeu16, usize, u16 }
+
+            test_impl_try_from_same_sign_err! { test_try_i64isize, i64, isize }
+            test_impl_try_from_same_sign_err! { test_try_isizei16, isize, i16 }
+        }
+
+        #[cfg(target_pointer_width = "64")] {
+            test_impl_try_from_same_sign_err! { test_try_usizeu16, usize, u16 }
+            test_impl_try_from_same_sign_err! { test_try_usizeu32, usize, u32 }
+
+            test_impl_try_from_same_sign_err! { test_try_isizei16, isize, i16 }
+            test_impl_try_from_same_sign_err! { test_try_isizei32, isize, i32 }
+        }
+    );
 }
 
 /// Conversions where neither the min nor the max of $source can be represented by
@@ -525,6 +636,22 @@ fn $fn_name() {
 assume_usize_width! {
     test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu8, isize, u8 }
     test_impl_try_from_signed_to_unsigned_err! { test_try_i128usize, i128, usize }
+
+    cfg_block! {
+        #[cfg(target_pointer_width = "16")] {
+            test_impl_try_from_signed_to_unsigned_err! { test_try_i32usize, i32, usize }
+            test_impl_try_from_signed_to_unsigned_err! { test_try_i64usize, i64, usize }
+        }
+        #[cfg(target_pointer_width = "32")] {
+            test_impl_try_from_signed_to_unsigned_err! { test_try_i64usize, i64, usize }
+
+            test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu16, isize, u16 }
+        }
+        #[cfg(target_pointer_width = "64")] {
+            test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu16, isize, u16 }
+            test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu32, isize, u32 }
+        }
+    }
 }
 
 macro_rules! test_float {
index 6cc61d748001a191f9bf4428080f1881dc2f285e..3c4472aef6bed3157d8013bb3d4b28696903724b 100644 (file)
@@ -504,6 +504,7 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool {
     [] GenericsOfItem(DefId),
     [] PredicatesOfItem(DefId),
     [] ExplicitPredicatesOfItem(DefId),
+    [] PredicatesDefinedOnItem(DefId),
     [] InferredOutlivesOf(DefId),
     [] InferredOutlivesCrate(CrateNum),
     [] SuperPredicatesOfItem(DefId),
index 60e944e5affc3c7ed32bd822f5a14c7304d72620..a7ed854d016494584fe4009e89b83af3fcc83a26 100644 (file)
@@ -607,13 +607,6 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
             }
             visitor.visit_lifetime(lifetime);
         }
-        TyImplTraitExistential(_, def_id, ref lifetimes) => {
-            // we are not recursing into the `existential` item, because it is already being visited
-            // as part of the surrounding module. The `NodeId` just exists so we don't have to look
-            // it up everywhere else in the compiler
-            visitor.visit_def_mention(Def::Existential(def_id));
-            walk_list!(visitor, visit_lifetime, lifetimes);
-        }
         TyTypeof(ref expression) => {
             visitor.visit_anon_const(expression)
         }
index e59e50ae9e698ff03f53b72ca1651b610bfbecb2..56df95336072ac6772656100516236eb316ba9f6 100644 (file)
@@ -103,6 +103,7 @@ pub struct LoweringContext<'a> {
     loop_scopes: Vec<NodeId>,
     is_in_loop_condition: bool,
     is_in_trait_impl: bool,
+    is_in_anon_const: bool,
 
     /// What to do when we encounter either an "anonymous lifetime
     /// reference". The term "anonymous" is meant to encompass both
@@ -230,6 +231,7 @@ pub fn lower_crate(
         node_id_to_hir_id: IndexVec::new(),
         is_generator: false,
         is_in_trait_impl: false,
+        is_in_anon_const: false,
         lifetimes_to_define: Vec::new(),
         is_collecting_in_band_lifetimes: false,
         in_scope_lifetimes: Vec::new(),
@@ -968,31 +970,30 @@ fn lower_label(&mut self, label: Option<Label>) -> Option<hir::Label> {
     }
 
     fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination {
-        match destination {
-            Some((id, label)) => {
-                let target_id = if let Def::Label(loop_id) = self.expect_full_def(id) {
-                    Ok(self.lower_node_id(loop_id).node_id)
-                } else {
-                    Err(hir::LoopIdError::UnresolvedLabel)
-                };
-                hir::Destination {
-                    label: self.lower_label(Some(label)),
-                    target_id,
+        let target_id = if self.is_in_anon_const {
+            Err(hir::LoopIdError::OutsideLoopScope)
+        } else {
+            match destination {
+                Some((id, _)) => {
+                    if let Def::Label(loop_id) = self.expect_full_def(id) {
+                        Ok(self.lower_node_id(loop_id).node_id)
+                    } else {
+                        Err(hir::LoopIdError::UnresolvedLabel)
+                    }
                 }
-            }
-            None => {
-                let target_id = self.loop_scopes
-                    .last()
-                    .map(|innermost_loop_id| *innermost_loop_id)
-                    .map(|id| Ok(self.lower_node_id(id).node_id))
-                    .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
-                    .into();
-
-                hir::Destination {
-                    label: None,
-                    target_id,
+                None => {
+                    self.loop_scopes
+                        .last()
+                        .map(|innermost_loop_id| *innermost_loop_id)
+                        .map(|id| Ok(self.lower_node_id(id).node_id))
+                        .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
+                        .into()
                 }
             }
+        };
+        hir::Destination {
+            label: self.lower_label(destination.map(|(_, label)| label)),
+            target_id,
         }
     }
 
@@ -1306,13 +1307,20 @@ fn lower_existential_impl_trait(
             lctx.items.insert(exist_ty_id.node_id, exist_ty_item);
 
             // `impl Trait` now just becomes `Foo<'a, 'b, ..>`
-            hir::TyImplTraitExistential(
-                hir::ItemId {
-                    id: exist_ty_id.node_id
-                },
-                DefId::local(exist_ty_def_index),
-                lifetimes,
-            )
+            let path = P(hir::Path {
+                span: exist_ty_span,
+                def: Def::Existential(DefId::local(exist_ty_def_index)),
+                segments: hir_vec![hir::PathSegment {
+                    infer_types: false,
+                    ident: Ident::new(keywords::Invalid.name(), exist_ty_span),
+                    args: Some(P(hir::GenericArgs {
+                        parenthesized: false,
+                        bindings: HirVec::new(),
+                        args: lifetimes,
+                    }))
+                }],
+            });
+            hir::TyPath(hir::QPath::Resolved(None, path))
         })
     }
 
@@ -1321,7 +1329,7 @@ fn lifetimes_from_impl_trait_bounds(
         exist_ty_id: NodeId,
         parent_index: DefIndex,
         bounds: &hir::GenericBounds,
-    ) -> (HirVec<hir::Lifetime>, HirVec<hir::GenericParam>) {
+    ) -> (HirVec<hir::GenericArg>, HirVec<hir::GenericParam>) {
         // This visitor walks over impl trait bounds and creates defs for all lifetimes which
         // appear in the bounds, excluding lifetimes that are created within the bounds.
         // e.g. 'a, 'b, but not 'c in `impl for<'c> SomeTrait<'a, 'b, 'c>`
@@ -1332,7 +1340,7 @@ struct ImplTraitLifetimeCollector<'r, 'a: 'r> {
             collect_elided_lifetimes: bool,
             currently_bound_lifetimes: Vec<hir::LifetimeName>,
             already_defined_lifetimes: HashSet<hir::LifetimeName>,
-            output_lifetimes: Vec<hir::Lifetime>,
+            output_lifetimes: Vec<hir::GenericArg>,
             output_lifetime_params: Vec<hir::GenericParam>,
         }
 
@@ -1416,11 +1424,11 @@ fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
                     && !self.already_defined_lifetimes.contains(&name) {
                     self.already_defined_lifetimes.insert(name);
 
-                    self.output_lifetimes.push(hir::Lifetime {
+                    self.output_lifetimes.push(hir::GenericArg::Lifetime(hir::Lifetime {
                         id: self.context.next_id().node_id,
                         span: lifetime.span,
                         name,
-                    });
+                    }));
 
                     // We need to manually create the ids here, because the
                     // definitions will go into the explicit `existential type`
@@ -3440,13 +3448,22 @@ fn lower_range_end(&mut self, e: &RangeEnd) -> hir::RangeEnd {
     }
 
     fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
-        let LoweredNodeId { node_id, hir_id } = self.lower_node_id(c.id);
+        let was_in_loop_condition = self.is_in_loop_condition;
+        self.is_in_loop_condition = false;
+        let was_in_anon_const = self.is_in_anon_const;
+        self.is_in_anon_const = true;
 
-        hir::AnonConst {
+        let LoweredNodeId { node_id, hir_id } = self.lower_node_id(c.id);
+        let anon_const = hir::AnonConst {
             id: node_id,
             hir_id,
             body: self.lower_body(None, |this| this.lower_expr(&c.value)),
-        }
+        };
+
+        self.is_in_anon_const = was_in_anon_const;
+        self.is_in_loop_condition = was_in_loop_condition;
+
+        anon_const
     }
 
     fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
index fa01a1ccca59baf0998c4bc8840e780251440839..328cb8225478bdc159c503a1b678203e580d6aaa 100644 (file)
@@ -23,6 +23,7 @@
 use rustc_data_structures::stable_hasher::StableHasher;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 use session::CrateDisambiguator;
+use std::borrow::Borrow;
 use std::fmt::Write;
 use std::hash::Hash;
 use syntax::ast;
@@ -389,6 +390,13 @@ pub enum DefPathData {
 
 impl_stable_hash_for!(tuple_struct DefPathHash { fingerprint });
 
+impl Borrow<Fingerprint> for DefPathHash {
+    #[inline]
+    fn borrow(&self) -> &Fingerprint {
+        &self.0
+    }
+}
+
 impl Definitions {
     /// Create new empty definition map.
     pub fn new() -> Definitions {
index b0b81316148ea47c97acd99ca6493df4a9ffcd07..8d83dd3279c64d4b690c33608b3258128856e7b6 100644 (file)
@@ -1692,18 +1692,6 @@ pub enum Ty_ {
     /// A trait object type `Bound1 + Bound2 + Bound3`
     /// where `Bound` is a trait or a lifetime.
     TyTraitObject(HirVec<PolyTraitRef>, Lifetime),
-    /// An existentially quantified (there exists a type satisfying) `impl
-    /// Bound1 + Bound2 + Bound3` type where `Bound` is a trait or a lifetime.
-    ///
-    /// The `Item` is the generated
-    /// `existential type Foo<'a, 'b>: MyTrait<'a, 'b>;`.
-    ///
-    /// The `HirVec<Lifetime>` is the list of lifetimes applied as parameters
-    /// to the `abstract type`, e.g. the `'c` and `'d` in `-> Foo<'c, 'd>`.
-    /// This list is only a list of lifetimes and not type parameters
-    /// because all in-scope type parameters are captured by `impl Trait`,
-    /// so they are resolved directly through the parent `Generics`.
-    TyImplTraitExistential(ItemId, DefId, HirVec<Lifetime>),
     /// Unused for now
     TyTypeof(AnonConst),
     /// TyInfer means the type should be inferred instead of it having been
index 255009c94c6abc6e06454302da7445929891a1b2..4d0969d898e91434b7a92ad72a81fef79444f073 100644 (file)
@@ -420,15 +420,6 @@ pub fn print_type(&mut self, ty: &hir::Ty) -> io::Result<()> {
                     self.print_lifetime(lifetime)?;
                 }
             }
-            hir::TyImplTraitExistential(hir_id, _def_id, ref _lifetimes) => {
-                match self.ann.try_fetch_item(hir_id.id).map(|it| &it.node) {
-                    None => self.word_space("impl {{Trait}}")?,
-                    Some(&hir::ItemExistential(ref exist_ty)) => {
-                        self.print_bounds("impl", &exist_ty.bounds)?;
-                    },
-                    other => bug!("impl Trait pointed to {:#?}", other),
-                }
-            }
             hir::TyArray(ref ty, ref length) => {
                 self.s.word("[")?;
                 self.print_type(&ty)?;
index 2a3b1ce6a36a5075fcf33ff85b6224cfe705baf0..a6e35d78dcb5aaef76b09a3ed1cb7c9f03cd4b76 100644 (file)
@@ -45,6 +45,18 @@ pub fn combine(self, other: Fingerprint) -> Fingerprint {
         )
     }
 
+    // Combines two hashes in an order independent way. Make sure this is what
+    // you want.
+    #[inline]
+    pub fn combine_commutative(self, other: Fingerprint) -> Fingerprint {
+        let a = (self.1 as u128) << 64 | self.0 as u128;
+        let b = (other.1 as u128) << 64 | other.0 as u128;
+
+        let c = a.wrapping_add(b);
+
+        Fingerprint((c >> 64) as u64, c as u64)
+    }
+
     pub fn to_hex(&self) -> String {
         format!("{:x}{:x}", self.0, self.1)
     }
index 0c7baea85ad8f63d33ea0589c0eba599e725729a..8b62ba119ebb8feadb334100d8b5006a773856f6 100644 (file)
@@ -14,7 +14,7 @@
 use hir;
 use hir::map::DefPathHash;
 use hir::def_id::{DefId, LocalDefId, CrateNum, CRATE_DEF_INDEX};
-use ich::{StableHashingContext, NodeIdHashingMode};
+use ich::{StableHashingContext, NodeIdHashingMode, Fingerprint};
 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
                                            StableHasher, StableHasherResult};
 use std::mem;
@@ -340,7 +340,6 @@ fn hash_stable<W: StableHasherResult>(&self,
     TyTup(ts),
     TyPath(qpath),
     TyTraitObject(trait_refs, lifetime),
-    TyImplTraitExistential(existty, def_id, lifetimes),
     TyTypeof(body_id),
     TyErr,
     TyInfer
@@ -756,13 +755,34 @@ fn hash_stable<W: StableHasherResult>(&self,
     Negative
 });
 
-impl_stable_hash_for!(struct hir::Mod {
-    inner,
-    // We are not hashing the IDs of the items contained in the module.
-    // This is harmless and matches the current behavior but it's not
-    // actually correct. See issue #40876.
-    item_ids -> _,
-});
+impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a>,
+                                          hasher: &mut StableHasher<W>) {
+        let hir::Mod {
+            inner: ref inner_span,
+            ref item_ids,
+        } = *self;
+
+        inner_span.hash_stable(hcx, hasher);
+
+        // Combining the DefPathHashes directly is faster than feeding them
+        // into the hasher. Because we use a commutative combine, we also don't
+        // have to sort the array.
+        let item_ids_hash = item_ids
+            .iter()
+            .map(|id| {
+                let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
+                debug_assert_eq!(local_id, hir::ItemLocalId(0));
+                def_path_hash.0
+            }).fold(Fingerprint::ZERO, |a, b| {
+                a.combine_commutative(b)
+            });
+
+        item_ids.len().hash_stable(hcx, hasher);
+        item_ids_hash.hash_stable(hcx, hasher);
+    }
+}
 
 impl_stable_hash_for!(struct hir::ForeignMod {
     abi,
index afc83771fe1c7e4e8ed53476ad1c8ff5ecd6911e..1377176bc7fb8a6a09e3d5cf86cd6ea8ac3fb2ba 100644 (file)
@@ -518,7 +518,17 @@ fn note_error_origin(&self, err: &mut DiagnosticBuilder<'tcx>, cause: &Obligatio
                     } else {
                         err.span_label(arm_span, msg);
                     }
-                }
+                },
+                hir::MatchSource::TryDesugar => { // Issue #51632
+                    if let Ok(try_snippet) = self.tcx.sess.codemap().span_to_snippet(arm_span) {
+                        err.span_suggestion_with_applicability(
+                            arm_span,
+                            "try wrapping with a success variant",
+                            format!("Ok({})", try_snippet),
+                            Applicability::MachineApplicable
+                        );
+                    }
+                },
                 _ => {
                     let msg = "match arm with an incompatible type";
                     if self.tcx.sess.codemap().is_multiline(arm_span) {
@@ -1312,7 +1322,12 @@ fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode {
         match self.code {
             CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"),
             MatchExpressionArm { source, .. } => Error0308(match source {
-                hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have incompatible types",
+                hir::MatchSource::IfLetDesugar { .. } => {
+                    "`if let` arms have incompatible types"
+                },
+                hir::MatchSource::TryDesugar => {
+                    "try expression alternatives have incompatible types"
+                },
                 _ => "match arms have incompatible types",
             }),
             IfExpression => Error0308("if and else have incompatible types"),
index 718445bd3563e2908dc97ad53042a7122f7e56c1..a83aa47fd4f13ff2826715f7a0e46f19ee38488c 100644 (file)
@@ -319,7 +319,7 @@ pub fn consume_body(&mut self, body: &hir::Body) {
             let fn_body_scope_r =
                 self.tcx().mk_region(ty::ReScope(region::Scope::Node(body.value.hir_id.local_id)));
             let arg_cmt = Rc::new(self.mc.cat_rvalue(
-                arg.id,
+                arg.hir_id,
                 arg.pat.span,
                 fn_body_scope_r, // Args live only as long as the fn body.
                 arg_ty));
@@ -840,6 +840,7 @@ fn determine_pat_move_mode(&mut self,
     fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: MatchMode) {
         debug!("walk_pat(cmt_discr={:?}, pat={:?})", cmt_discr, pat);
 
+        let tcx = self.tcx();
         let ExprUseVisitor { ref mc, ref mut delegate, param_env } = *self;
         return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| {
             if let PatKind::Binding(_, canonical_id, ..) = pat.node {
@@ -849,34 +850,36 @@ fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: Mat
                     pat,
                     match_mode,
                 );
-                let bm = *mc.tables.pat_binding_modes().get(pat.hir_id)
-                                                     .expect("missing binding mode");
-                debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
-
-                // pat_ty: the type of the binding being produced.
-                let pat_ty = return_if_err!(mc.node_ty(pat.hir_id));
-                debug!("walk_pat: pat_ty={:?}", pat_ty);
-
-                // Each match binding is effectively an assignment to the
-                // binding being produced.
-                let def = Def::Local(canonical_id);
-                if let Ok(ref binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty, def) {
-                    delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
-                }
+                if let Some(&bm) = mc.tables.pat_binding_modes().get(pat.hir_id) {
+                    debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
+
+                    // pat_ty: the type of the binding being produced.
+                    let pat_ty = return_if_err!(mc.node_ty(pat.hir_id));
+                    debug!("walk_pat: pat_ty={:?}", pat_ty);
+
+                    // Each match binding is effectively an assignment to the
+                    // binding being produced.
+                    let def = Def::Local(canonical_id);
+                    if let Ok(ref binding_cmt) = mc.cat_def(pat.hir_id, pat.span, pat_ty, def) {
+                        delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
+                    }
 
-                // It is also a borrow or copy/move of the value being matched.
-                match bm {
-                    ty::BindByReference(m) => {
-                        if let ty::TyRef(r, _, _) = pat_ty.sty {
-                            let bk = ty::BorrowKind::from_mutbl(m);
-                            delegate.borrow(pat.id, pat.span, &cmt_pat, r, bk, RefBinding);
+                    // It is also a borrow or copy/move of the value being matched.
+                    match bm {
+                        ty::BindByReference(m) => {
+                            if let ty::TyRef(r, _, _) = pat_ty.sty {
+                                let bk = ty::BorrowKind::from_mutbl(m);
+                                delegate.borrow(pat.id, pat.span, &cmt_pat, r, bk, RefBinding);
+                            }
+                        }
+                        ty::BindByValue(..) => {
+                            let mode = copy_or_move(mc, param_env, &cmt_pat, PatBindingMove);
+                            debug!("walk_pat binding consuming pat");
+                            delegate.consume_pat(pat, &cmt_pat, mode);
                         }
                     }
-                    ty::BindByValue(..) => {
-                        let mode = copy_or_move(mc, param_env, &cmt_pat, PatBindingMove);
-                        debug!("walk_pat binding consuming pat");
-                        delegate.consume_pat(pat, &cmt_pat, mode);
-                    }
+                } else {
+                    tcx.sess.delay_span_bug(pat.span, "missing binding mode");
                 }
             }
         }));
@@ -923,7 +926,7 @@ fn walk_captures(&mut self, closure_expr: &hir::Expr, fn_decl_span: Span) {
                     closure_expr_id: closure_def_id.to_local(),
                 };
                 let upvar_capture = self.mc.tables.upvar_capture(upvar_id);
-                let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
+                let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.hir_id,
                                                                    fn_decl_span,
                                                                    freevar));
                 match upvar_capture {
@@ -948,7 +951,7 @@ fn walk_captures(&mut self, closure_expr: &hir::Expr, fn_decl_span: Span) {
     }
 
     fn cat_captured_var(&mut self,
-                        closure_id: ast::NodeId,
+                        closure_hir_id: hir::HirId,
                         closure_span: Span,
                         upvar: &hir::Freevar)
                         -> mc::McResult<mc::cmt_<'tcx>> {
@@ -956,7 +959,7 @@ fn cat_captured_var(&mut self,
         // caller's perspective
         let var_hir_id = self.tcx().hir.node_to_hir_id(upvar.var_id());
         let var_ty = self.mc.node_ty(var_hir_id)?;
-        self.mc.cat_def(closure_id, closure_span, var_ty, upvar.def)
+        self.mc.cat_def(closure_hir_id, closure_span, var_ty, upvar.def)
     }
 }
 
index 6d4e9a1b767a9524e29b771c40d4d0d0a70e349e..c3a2d3ce0c27f6d48df22fed89cb2034f187bb47 100644 (file)
@@ -179,17 +179,21 @@ pub enum Note {
 // and how it is located, as well as the mutability of the memory in
 // which the value is stored.
 //
-// *WARNING* The field `cmt.ty` is NOT necessarily the same as the
-// result of `node_id_to_type(cmt.id)`. This is because the `id` is
-// always the `id` of the node producing the type; in an expression
-// like `*x`, the type of this deref node is the deref'd type (`T`),
-// but in a pattern like `@x`, the `@x` pattern is again a
-// dereference, but its type is the type *before* the dereference
-// (`@T`). So use `cmt.ty` to find the type of the value in a consistent
-// fashion. For more details, see the method `cat_pattern`
+// *WARNING* The field `cmt.type` is NOT necessarily the same as the
+// result of `node_id_to_type(cmt.id)`.
+//
+// (FIXME: rewrite the following comment given that `@x` managed
+// pointers have been obsolete for quite some time.)
+//
+// This is because the `id` is always the `id` of the node producing the
+// type; in an expression like `*x`, the type of this deref node is the
+// deref'd type (`T`), but in a pattern like `@x`, the `@x` pattern is
+// again a dereference, but its type is the type *before* the
+// dereference (`@T`). So use `cmt.ty` to find the type of the value in
+// a consistent fashion. For more details, see the method `cat_pattern`
 #[derive(Clone, Debug, PartialEq)]
 pub struct cmt_<'tcx> {
-    pub id: ast::NodeId,           // id of expr/pat producing this value
+    pub hir_id: hir::HirId,        // HIR id of expr/pat producing this value
     pub span: Span,                // span of same expr/pat
     pub cat: Categorization<'tcx>, // categorization of expr
     pub mutbl: MutabilityCategory, // mutability of expr as place
@@ -271,18 +275,18 @@ pub fn immutability_blame(&self) -> Option<ImmutabilityBlame<'tcx>> {
     }
 }
 
-pub trait ast_node {
-    fn id(&self) -> ast::NodeId;
+pub trait HirNode {
+    fn hir_id(&self) -> hir::HirId;
     fn span(&self) -> Span;
 }
 
-impl ast_node for hir::Expr {
-    fn id(&self) -> ast::NodeId { self.id }
+impl HirNode for hir::Expr {
+    fn hir_id(&self) -> hir::HirId { self.hir_id }
     fn span(&self) -> Span { self.span }
 }
 
-impl ast_node for hir::Pat {
-    fn id(&self) -> ast::NodeId { self.id }
+impl HirNode for hir::Pat {
+    fn hir_id(&self) -> hir::HirId { self.hir_id }
     fn span(&self) -> Span { self.span }
 }
 
@@ -610,7 +614,7 @@ fn cat_expr_adjusted_with<F>(&self, expr: &hir::Expr,
                         ty: target,
                         mutbl: deref.mutbl,
                     });
-                    self.cat_rvalue_node(expr.id, expr.span, ref_ty)
+                    self.cat_rvalue_node(expr.hir_id, expr.span, ref_ty)
                 } else {
                     previous()?
                 });
@@ -625,7 +629,7 @@ fn cat_expr_adjusted_with<F>(&self, expr: &hir::Expr,
             adjustment::Adjust::Borrow(_) |
             adjustment::Adjust::Unsize => {
                 // Result is an rvalue.
-                Ok(self.cat_rvalue_node(expr.id, expr.span, target))
+                Ok(self.cat_rvalue_node(expr.hir_id, expr.span, target))
             }
         }
     }
@@ -669,8 +673,8 @@ pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt_<'tcx>> {
           }
 
           hir::ExprPath(ref qpath) => {
-            let def = self.tables.qpath_def(qpath, expr.hir_id);
-            self.cat_def(expr.id, expr.span, expr_ty, def)
+              let def = self.tables.qpath_def(qpath, expr.hir_id);
+              self.cat_def(expr.hir_id, expr.span, expr_ty, def)
           }
 
           hir::ExprType(ref e, _) => {
@@ -688,35 +692,35 @@ pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt_<'tcx>> {
           hir::ExprLit(..) | hir::ExprBreak(..) |
           hir::ExprContinue(..) | hir::ExprStruct(..) | hir::ExprRepeat(..) |
           hir::ExprInlineAsm(..) | hir::ExprBox(..) => {
-            Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
+            Ok(self.cat_rvalue_node(expr.hir_id, expr.span, expr_ty))
           }
         }
     }
 
     pub fn cat_def(&self,
-                   id: ast::NodeId,
+                   hir_id: hir::HirId,
                    span: Span,
                    expr_ty: Ty<'tcx>,
                    def: Def)
                    -> McResult<cmt_<'tcx>> {
-        debug!("cat_def: id={} expr={:?} def={:?}",
-               id, expr_ty, def);
+        debug!("cat_def: id={:?} expr={:?} def={:?}",
+               hir_id, expr_ty, def);
 
         match def {
           Def::StructCtor(..) | Def::VariantCtor(..) | Def::Const(..) |
           Def::AssociatedConst(..) | Def::Fn(..) | Def::Method(..) => {
-                Ok(self.cat_rvalue_node(id, span, expr_ty))
+                Ok(self.cat_rvalue_node(hir_id, span, expr_ty))
           }
 
           Def::Static(def_id, mutbl) => {
             // `#[thread_local]` statics may not outlive the current function.
             for attr in &self.tcx.get_attrs(def_id)[..] {
                 if attr.check_name("thread_local") {
-                    return Ok(self.cat_rvalue_node(id, span, expr_ty));
+                    return Ok(self.cat_rvalue_node(hir_id, span, expr_ty));
                 }
             }
               Ok(cmt_ {
-                  id:id,
+                  hir_id,
                   span:span,
                   cat:Categorization::StaticItem,
                   mutbl: if mutbl { McDeclared } else { McImmutable},
@@ -726,12 +730,12 @@ pub fn cat_def(&self,
           }
 
           Def::Upvar(var_id, _, fn_node_id) => {
-              self.cat_upvar(id, span, var_id, fn_node_id)
+              self.cat_upvar(hir_id, span, var_id, fn_node_id)
           }
 
           Def::Local(vid) => {
             Ok(cmt_ {
-                id,
+                hir_id,
                 span,
                 cat: Categorization::Local(vid),
                 mutbl: MutabilityCategory::from_local(self.tcx, self.tables, vid),
@@ -747,7 +751,7 @@ pub fn cat_def(&self,
     // Categorize an upvar, complete with invisible derefs of closure
     // environment and upvar reference as appropriate.
     fn cat_upvar(&self,
-                 id: ast::NodeId,
+                 hir_id: hir::HirId,
                  span: Span,
                  var_id: ast::NodeId,
                  fn_node_id: ast::NodeId)
@@ -814,7 +818,7 @@ fn cat_upvar(&self,
         // from the environment (perhaps we should eventually desugar
         // this field further, but it will do for now).
         let cmt_result = cmt_ {
-            id,
+            hir_id,
             span,
             cat: Categorization::Upvar(Upvar {id: upvar_id, kind: kind}),
             mutbl: var_mutbl,
@@ -830,10 +834,10 @@ fn cat_upvar(&self,
                 cmt_result
             }
             ty::ClosureKind::FnMut => {
-                self.env_deref(id, span, upvar_id, var_mutbl, ty::MutBorrow, cmt_result)
+                self.env_deref(hir_id, span, upvar_id, var_mutbl, ty::MutBorrow, cmt_result)
             }
             ty::ClosureKind::Fn => {
-                self.env_deref(id, span, upvar_id, var_mutbl, ty::ImmBorrow, cmt_result)
+                self.env_deref(hir_id, span, upvar_id, var_mutbl, ty::ImmBorrow, cmt_result)
             }
         };
 
@@ -848,7 +852,7 @@ fn cat_upvar(&self,
             ty::UpvarCapture::ByRef(upvar_borrow) => {
                 let ptr = BorrowedPtr(upvar_borrow.kind, upvar_borrow.region);
                 cmt_ {
-                    id,
+                    hir_id,
                     span,
                     cat: Categorization::Deref(Rc::new(cmt_result), ptr),
                     mutbl: MutabilityCategory::from_borrow_kind(upvar_borrow.kind),
@@ -864,7 +868,7 @@ fn cat_upvar(&self,
     }
 
     fn env_deref(&self,
-                 id: ast::NodeId,
+                 hir_id: hir::HirId,
                  span: Span,
                  upvar_id: ty::UpvarId,
                  upvar_mutbl: MutabilityCategory,
@@ -908,7 +912,7 @@ fn env_deref(&self,
         }
 
         let ret = cmt_ {
-            id,
+            hir_id,
             span,
             cat: Categorization::Deref(Rc::new(cmt_result), env_ptr),
             mutbl: deref_mutbl,
@@ -932,17 +936,16 @@ pub fn temporary_scope(&self, id: hir::ItemLocalId) -> ty::Region<'tcx> {
     }
 
     pub fn cat_rvalue_node(&self,
-                           id: ast::NodeId,
+                           hir_id: hir::HirId,
                            span: Span,
                            expr_ty: Ty<'tcx>)
                            -> cmt_<'tcx> {
         debug!(
             "cat_rvalue_node(id={:?}, span={:?}, expr_ty={:?})",
-            id,
+            hir_id,
             span,
             expr_ty,
         );
-        let hir_id = self.tcx.hir.node_to_hir_id(id);
         let promotable = self.rvalue_promotable_map.as_ref().map(|m| m.contains(&hir_id.local_id))
                                                             .unwrap_or(false);
 
@@ -970,18 +973,18 @@ pub fn cat_rvalue_node(&self,
         } else {
             self.temporary_scope(hir_id.local_id)
         };
-        let ret = self.cat_rvalue(id, span, re, expr_ty);
+        let ret = self.cat_rvalue(hir_id, span, re, expr_ty);
         debug!("cat_rvalue_node ret {:?}", ret);
         ret
     }
 
     pub fn cat_rvalue(&self,
-                      cmt_id: ast::NodeId,
+                      cmt_hir_id: hir::HirId,
                       span: Span,
                       temp_scope: ty::Region<'tcx>,
                       expr_ty: Ty<'tcx>) -> cmt_<'tcx> {
         let ret = cmt_ {
-            id:cmt_id,
+            hir_id: cmt_hir_id,
             span:span,
             cat:Categorization::Rvalue(temp_scope),
             mutbl:McDeclared,
@@ -992,7 +995,7 @@ pub fn cat_rvalue(&self,
         ret
     }
 
-    pub fn cat_field<N:ast_node>(&self,
+    pub fn cat_field<N: HirNode>(&self,
                                  node: &N,
                                  base_cmt: cmt<'tcx>,
                                  f_index: usize,
@@ -1000,7 +1003,7 @@ pub fn cat_field<N:ast_node>(&self,
                                  f_ty: Ty<'tcx>)
                                  -> cmt_<'tcx> {
         let ret = cmt_ {
-            id: node.id(),
+            hir_id: node.hir_id(),
             span: node.span(),
             mutbl: base_cmt.mutbl.inherit(),
             cat: Categorization::Interior(base_cmt,
@@ -1042,13 +1045,13 @@ fn cat_overloaded_place(
             mutbl,
         });
 
-        let base_cmt = Rc::new(self.cat_rvalue_node(expr.id, expr.span, ref_ty));
+        let base_cmt = Rc::new(self.cat_rvalue_node(expr.hir_id, expr.span, ref_ty));
         self.cat_deref(expr, base_cmt, note)
     }
 
     pub fn cat_deref(
         &self,
-        node: &impl ast_node,
+        node: &impl HirNode,
         base_cmt: cmt<'tcx>,
         note: Note,
     ) -> McResult<cmt_<'tcx>> {
@@ -1074,7 +1077,7 @@ pub fn cat_deref(
             ref ty => bug!("unexpected type in cat_deref: {:?}", ty)
         };
         let ret = cmt_ {
-            id: node.id(),
+            hir_id: node.hir_id(),
             span: node.span(),
             // For unique ptrs, we inherit mutability from the owning reference.
             mutbl: MutabilityCategory::from_pointer_kind(base_cmt.mutbl, ptr),
@@ -1086,7 +1089,7 @@ pub fn cat_deref(
         Ok(ret)
     }
 
-    fn cat_index<N:ast_node>(&self,
+    fn cat_index<N: HirNode>(&self,
                              elt: &N,
                              base_cmt: cmt<'tcx>,
                              element_ty: Ty<'tcx>,
@@ -1106,7 +1109,7 @@ fn cat_index<N:ast_node>(&self,
         //! presuming that `base_cmt` is not of fixed-length type.
         //!
         //! # Parameters
-        //! - `elt`: the AST node being indexed
+        //! - `elt`: the HIR node being indexed
         //! - `base_cmt`: the cmt of `elt`
 
         let interior_elem = InteriorElement(context);
@@ -1115,14 +1118,14 @@ fn cat_index<N:ast_node>(&self,
         return Ok(ret);
     }
 
-    pub fn cat_imm_interior<N:ast_node>(&self,
+    pub fn cat_imm_interior<N:HirNode>(&self,
                                         node: &N,
                                         base_cmt: cmt<'tcx>,
                                         interior_ty: Ty<'tcx>,
                                         interior: InteriorKind)
                                         -> cmt_<'tcx> {
         let ret = cmt_ {
-            id: node.id(),
+            hir_id: node.hir_id(),
             span: node.span(),
             mutbl: base_cmt.mutbl.inherit(),
             cat: Categorization::Interior(base_cmt, interior),
@@ -1133,7 +1136,7 @@ pub fn cat_imm_interior<N:ast_node>(&self,
         ret
     }
 
-    pub fn cat_downcast_if_needed<N:ast_node>(&self,
+    pub fn cat_downcast_if_needed<N:HirNode>(&self,
                                               node: &N,
                                               base_cmt: cmt<'tcx>,
                                               variant_did: DefId)
@@ -1143,7 +1146,7 @@ pub fn cat_downcast_if_needed<N:ast_node>(&self,
         if self.tcx.adt_def(base_did).variants.len() != 1 {
             let base_ty = base_cmt.ty;
             let ret = Rc::new(cmt_ {
-                id: node.id(),
+                hir_id: node.hir_id(),
                 span: node.span(),
                 mutbl: base_cmt.mutbl.inherit(),
                 cat: Categorization::Downcast(base_cmt, variant_did),
@@ -1193,6 +1196,8 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR
         // value, and I consider them to produce the value that was
         // matched. So if you have something like:
         //
+        // (FIXME: `@@3` is not legal code anymore!)
+        //
         //     let x = @@3;
         //     match x {
         //       @@y { ... }
index c7249c0aa20c881ce5fb87cc113bc17d8720b928..a11c8f5dc044d8514d8e1ee2cc54d880d5f2d055 100644 (file)
@@ -459,7 +459,7 @@ struct RegionResolutionVisitor<'a, 'tcx: 'a> {
 }
 
 struct ExprLocatorVisitor {
-    id: ast::NodeId,
+    hir_id: hir::HirId,
     result: Option<usize>,
     expr_and_pat_count: usize,
 }
@@ -476,7 +476,7 @@ fn visit_pat(&mut self, pat: &'tcx Pat) {
 
         self.expr_and_pat_count += 1;
 
-        if pat.id == self.id {
+        if pat.hir_id == self.hir_id {
             self.result = Some(self.expr_and_pat_count);
         }
     }
@@ -494,7 +494,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr) {
                self.expr_and_pat_count,
                expr);
 
-        if expr.id == self.id {
+        if expr.hir_id == self.hir_id {
             self.result = Some(self.expr_and_pat_count);
         }
     }
@@ -778,11 +778,11 @@ pub fn yield_in_scope(&self, scope: Scope) -> Option<(Span, usize)> {
     /// `scope` must be inside the body.
     pub fn yield_in_scope_for_expr(&self,
                                    scope: Scope,
-                                   expr: ast::NodeId,
+                                   expr_hir_id: hir::HirId,
                                    body: &'tcx hir::Body) -> Option<Span> {
         self.yield_in_scope(scope).and_then(|(span, count)| {
             let mut visitor = ExprLocatorVisitor {
-                id: expr,
+                hir_id: expr_hir_id,
                 result: None,
                 expr_and_pat_count: 0,
             };
index ed2b9c5068929c49a720f2b78be98730423e2acc..369f65c214aa107cc30cf51fcfa5476419722a1e 100644 (file)
@@ -625,122 +625,131 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
                 };
                 self.with(scope, |_, this| this.visit_ty(&mt.ty));
             }
-            hir::TyImplTraitExistential(item_id, _, ref lifetimes) => {
-                // Resolve the lifetimes that are applied to the existential type.
-                // These are resolved in the current scope.
-                // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
-                // `fn foo<'a>() -> MyAnonTy<'a> { ... }`
-                //          ^                 ^this gets resolved in the current scope
-                for lifetime in lifetimes {
-                    self.visit_lifetime(lifetime);
-
-                    // Check for predicates like `impl for<'a> SomeTrait<impl OtherTrait<'a>>`
-                    // and ban them. Type variables instantiated inside binders aren't
-                    // well-supported at the moment, so this doesn't work.
-                    // In the future, this should be fixed and this error should be removed.
-                    let def = self.map.defs.get(&lifetime.id).cloned();
-                    if let Some(Region::LateBound(_, def_id, _)) = def {
-                        if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
-                            // Ensure that the parent of the def is an item, not HRTB
-                            let parent_id = self.tcx.hir.get_parent_node(node_id);
-                            let parent_impl_id = hir::ImplItemId { node_id: parent_id };
-                            let parent_trait_id = hir::TraitItemId { node_id: parent_id };
-                            let krate = self.tcx.hir.forest.krate();
-                            if !(krate.items.contains_key(&parent_id)
-                                || krate.impl_items.contains_key(&parent_impl_id)
-                                || krate.trait_items.contains_key(&parent_trait_id))
-                            {
-                                span_err!(
-                                    self.tcx.sess,
-                                    lifetime.span,
-                                    E0657,
-                                    "`impl Trait` can only capture lifetimes \
-                                     bound at the fn or impl level"
-                                );
-                                self.uninsert_lifetime_on_error(lifetime, def.unwrap());
+            hir::TyPath(hir::QPath::Resolved(None, ref path)) => {
+                if let Def::Existential(exist_ty_did) = path.def {
+                    assert!(exist_ty_did.is_local());
+                    // Resolve the lifetimes that are applied to the existential type.
+                    // These are resolved in the current scope.
+                    // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
+                    // `fn foo<'a>() -> MyAnonTy<'a> { ... }`
+                    //          ^                 ^this gets resolved in the current scope
+                    for lifetime in &path.segments[0].args.as_ref().unwrap().args {
+                        if let hir::GenericArg::Lifetime(lifetime) = lifetime {
+                            self.visit_lifetime(lifetime);
+
+                            // Check for predicates like `impl for<'a> Trait<impl OtherTrait<'a>>`
+                            // and ban them. Type variables instantiated inside binders aren't
+                            // well-supported at the moment, so this doesn't work.
+                            // In the future, this should be fixed and this error should be removed.
+                            let def = self.map.defs.get(&lifetime.id).cloned();
+                            if let Some(Region::LateBound(_, def_id, _)) = def {
+                                if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
+                                    // Ensure that the parent of the def is an item, not HRTB
+                                    let parent_id = self.tcx.hir.get_parent_node(node_id);
+                                    let parent_impl_id = hir::ImplItemId { node_id: parent_id };
+                                    let parent_trait_id = hir::TraitItemId { node_id: parent_id };
+                                    let krate = self.tcx.hir.forest.krate();
+                                    if !(krate.items.contains_key(&parent_id)
+                                        || krate.impl_items.contains_key(&parent_impl_id)
+                                        || krate.trait_items.contains_key(&parent_trait_id))
+                                    {
+                                        span_err!(
+                                            self.tcx.sess,
+                                            lifetime.span,
+                                            E0657,
+                                            "`impl Trait` can only capture lifetimes \
+                                            bound at the fn or impl level"
+                                        );
+                                        self.uninsert_lifetime_on_error(lifetime, def.unwrap());
+                                    }
+                                }
                             }
                         }
                     }
-                }
 
-                // Resolve the lifetimes in the bounds to the lifetime defs in the generics.
-                // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
-                // `abstract type MyAnonTy<'b>: MyTrait<'b>;`
-                //                          ^            ^ this gets resolved in the scope of
-                //                                         the exist_ty generics
-                let (generics, bounds) = match self.tcx.hir.expect_item(item_id.id).node {
-                    hir::ItemExistential(hir::ExistTy{ ref generics, ref bounds, .. }) => (
-                        generics,
-                        bounds,
-                    ),
-                    ref i => bug!("impl Trait pointed to non-existential type?? {:#?}", i),
-                };
+                    let id = self.tcx.hir.as_local_node_id(exist_ty_did).unwrap();
+
+                    // Resolve the lifetimes in the bounds to the lifetime defs in the generics.
+                    // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
+                    // `abstract type MyAnonTy<'b>: MyTrait<'b>;`
+                    //                          ^            ^ this gets resolved in the scope of
+                    //                                         the exist_ty generics
+                    let (generics, bounds) = match self.tcx.hir.expect_item(id).node {
+                        hir::ItemExistential(hir::ExistTy{ ref generics, ref bounds, .. }) => (
+                            generics,
+                            bounds,
+                        ),
+                        ref i => bug!("impl Trait pointed to non-existential type?? {:#?}", i),
+                    };
 
-                // We want to start our early-bound indices at the end of the parent scope,
-                // not including any parent `impl Trait`s.
-                let mut index = self.next_early_index_for_abstract_type();
-                debug!("visit_ty: index = {}", index);
+                    // We want to start our early-bound indices at the end of the parent scope,
+                    // not including any parent `impl Trait`s.
+                    let mut index = self.next_early_index_for_abstract_type();
+                    debug!("visit_ty: index = {}", index);
 
-                let mut elision = None;
-                let mut lifetimes = FxHashMap();
-                let mut type_count = 0;
-                for param in &generics.params {
-                    match param.kind {
-                        GenericParamKind::Lifetime { .. } => {
-                            let (name, reg) = Region::early(&self.tcx.hir, &mut index, &param);
-                            if let hir::ParamName::Plain(param_name) = name {
-                                if param_name.name == keywords::UnderscoreLifetime.name() {
-                                    // Pick the elided lifetime "definition" if one exists
-                                    // and use it to make an elision scope.
-                                    elision = Some(reg);
+                    let mut elision = None;
+                    let mut lifetimes = FxHashMap();
+                    let mut type_count = 0;
+                    for param in &generics.params {
+                        match param.kind {
+                            GenericParamKind::Lifetime { .. } => {
+                                let (name, reg) = Region::early(&self.tcx.hir, &mut index, &param);
+                                if let hir::ParamName::Plain(param_name) = name {
+                                    if param_name.name == keywords::UnderscoreLifetime.name() {
+                                        // Pick the elided lifetime "definition" if one exists
+                                        // and use it to make an elision scope.
+                                        elision = Some(reg);
+                                    } else {
+                                        lifetimes.insert(name, reg);
+                                    }
                                 } else {
                                     lifetimes.insert(name, reg);
                                 }
-                            } else {
-                                lifetimes.insert(name, reg);
                             }
-                        }
-                        GenericParamKind::Type { .. } => {
-                            type_count += 1;
+                            GenericParamKind::Type { .. } => {
+                                type_count += 1;
+                            }
                         }
                     }
-                }
-                let next_early_index = index + type_count;
+                    let next_early_index = index + type_count;
 
-                if let Some(elision_region) = elision {
-                    let scope = Scope::Elision {
-                        elide: Elide::Exact(elision_region),
-                        s: self.scope,
-                    };
-                    self.with(scope, |_old_scope, this| {
+                    if let Some(elision_region) = elision {
+                        let scope = Scope::Elision {
+                            elide: Elide::Exact(elision_region),
+                            s: self.scope,
+                        };
+                        self.with(scope, |_old_scope, this| {
+                            let scope = Scope::Binder {
+                                lifetimes,
+                                next_early_index,
+                                s: this.scope,
+                                track_lifetime_uses: true,
+                                abstract_type_parent: false,
+                            };
+                            this.with(scope, |_old_scope, this| {
+                                this.visit_generics(generics);
+                                for bound in bounds {
+                                    this.visit_param_bound(bound);
+                                }
+                            });
+                        });
+                    } else {
                         let scope = Scope::Binder {
                             lifetimes,
                             next_early_index,
-                            s: this.scope,
+                            s: self.scope,
                             track_lifetime_uses: true,
                             abstract_type_parent: false,
                         };
-                        this.with(scope, |_old_scope, this| {
+                        self.with(scope, |_old_scope, this| {
                             this.visit_generics(generics);
                             for bound in bounds {
                                 this.visit_param_bound(bound);
                             }
                         });
-                    });
+                    }
                 } else {
-                    let scope = Scope::Binder {
-                        lifetimes,
-                        next_early_index,
-                        s: self.scope,
-                        track_lifetime_uses: true,
-                        abstract_type_parent: false,
-                    };
-                    self.with(scope, |_old_scope, this| {
-                        this.visit_generics(generics);
-                        for bound in bounds {
-                            this.visit_param_bound(bound);
-                        }
-                    });
+                    intravisit::walk_ty(self, ty)
                 }
             }
             _ => intravisit::walk_ty(self, ty),
index dec37bdf7195d6c911cfc53339017ac345353d98..dca0d4f442a4cbf0971e759cc30fdddfdc7c69a7 100644 (file)
@@ -1000,6 +1000,10 @@ pub fn successors_mut(&mut self) -> SuccessorsMut {
         self.kind.successors_mut()
     }
 
+    pub fn unwind(&self) -> Option<&Option<BasicBlock>> {
+        self.kind.unwind()
+    }
+
     pub fn unwind_mut(&mut self) -> Option<&mut Option<BasicBlock>> {
         self.kind.unwind_mut()
     }
@@ -1195,6 +1199,31 @@ pub fn successors_mut(&mut self) -> SuccessorsMut {
         }
     }
 
+    pub fn unwind(&self) -> Option<&Option<BasicBlock>> {
+        match *self {
+            TerminatorKind::Goto { .. }
+            | TerminatorKind::Resume
+            | TerminatorKind::Abort
+            | TerminatorKind::Return
+            | TerminatorKind::Unreachable
+            | TerminatorKind::GeneratorDrop
+            | TerminatorKind::Yield { .. }
+            | TerminatorKind::SwitchInt { .. }
+            | TerminatorKind::FalseEdges { .. } => None,
+            TerminatorKind::Call {
+                cleanup: ref unwind,
+                ..
+            }
+            | TerminatorKind::Assert {
+                cleanup: ref unwind,
+                ..
+            }
+            | TerminatorKind::DropAndReplace { ref unwind, .. }
+            | TerminatorKind::Drop { ref unwind, .. }
+            | TerminatorKind::FalseUnwind { ref unwind, .. } => Some(unwind),
+        }
+    }
+
     pub fn unwind_mut(&mut self) -> Option<&mut Option<BasicBlock>> {
         match *self {
             TerminatorKind::Goto { .. }
index c349def865af672e75a3aa9580002bac20d9d8b2..fdd791c5edac5844a9c8a91f5abe9acfa5a97a04 100644 (file)
@@ -1972,6 +1972,13 @@ pub fn build_session_options_and_crate_config(
         );
     }
 
+    if debugging_opts.profile && incremental.is_some() {
+        early_error(
+            error_format,
+            "can't instrument with gcov profiling when compiling incrementally",
+        );
+    }
+
     let mut prints = Vec::<PrintRequest>::new();
     if cg.target_cpu.as_ref().map_or(false, |s| s == "help") {
         prints.push(PrintRequest::TargetCPUs);
index fe2965146cb7f80be1762f2657dedfa2aae4f4a1..83128ba75d5827e25ef060703e1ffc20b02b2a15 100644 (file)
@@ -23,7 +23,6 @@
 use lint;
 use traits;
 use ty::{self, Ty, TyCtxt, TypeFoldable};
-use ty::subst::Substs;
 use ty::util::ExplicitSelf;
 use std::borrow::Cow;
 use syntax::ast;
@@ -173,10 +172,7 @@ fn predicates_reference_self(
         trait_def_id: DefId,
         supertraits_only: bool) -> bool
     {
-        let trait_ref = ty::Binder::dummy(ty::TraitRef {
-            def_id: trait_def_id,
-            substs: Substs::identity_for_item(self, trait_def_id)
-        });
+        let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(self, trait_def_id));
         let predicates = if supertraits_only {
             self.super_predicates_of(trait_def_id)
         } else {
@@ -391,10 +387,9 @@ fn contains_illegal_self_type_reference(self,
 
                     // Compute supertraits of current trait lazily.
                     if supertraits.is_none() {
-                        let trait_ref = ty::Binder::bind(ty::TraitRef {
-                            def_id: trait_def_id,
-                            substs: Substs::identity_for_item(self, trait_def_id)
-                        });
+                        let trait_ref = ty::Binder::bind(
+                            ty::TraitRef::identity(self, trait_def_id),
+                        );
                         supertraits = Some(traits::supertraits(self, trait_ref).collect());
                     }
 
index fe30b6a2f88b7be9e4ccc8bb73a2b819bd1c00a8..40171345f558b6b2210364c22cbb582fe1454815 100644 (file)
@@ -1237,6 +1237,11 @@ fn candidate_from_obligation_no_cache<'o>(&mut self,
         let mut candidates: Vec<EvaluatedCandidate> =
             candidates?.into_iter().filter_map(|c| c).collect();
 
+        debug!("winnowed to {} candidates for {:?}: {:?}",
+               candidates.len(),
+               stack,
+               candidates);
+
         // If there are STILL multiple candidate, we can further
         // reduce the list by dropping duplicates -- including
         // resolving specializations.
index f5c2a0c3f9f05f504c09026d9ec714749b7e8fff..a32fdbb285d12cdae128c30dcf4a80077589893b 100644 (file)
@@ -1115,12 +1115,12 @@ enum StructKind {
                 }
                 tcx.layout_raw(param_env.and(normalized))?
             }
-            ty::TyParam(_) => {
-                return Err(LayoutError::Unknown(ty));
-            }
-            ty::TyGeneratorWitness(..) | ty::TyInfer(_) | ty::TyError => {
+            ty::TyGeneratorWitness(..) | ty::TyInfer(_) => {
                 bug!("LayoutDetails::compute: unexpected type `{}`", ty)
             }
+            ty::TyParam(_) | ty::TyError => {
+                return Err(LayoutError::Unknown(ty));
+            }
         })
     }
 
index 54afd795fc0f13de0e2a7cfcb4168200d560b304..98042f6389db6c9ba5e9332d3fa3b034c5f84038 100644 (file)
@@ -2862,8 +2862,8 @@ fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
     // Compute the bounds on Self and the type parameters.
 
-    let bounds = tcx.predicates_of(def_id).instantiate_identity(tcx);
-    let predicates = bounds.predicates;
+    let InstantiatedPredicates { predicates } =
+        tcx.predicates_of(def_id).instantiate_identity(tcx);
 
     // Finally, we have to normalize the bounds in the environment, in
     // case they contain any associated type projections. This process
index 77644cdf02b116d63e173a9d5c9f97916da3941c..9ad93b4d5e233117ade9d905014c6f4c490c65e6 100644 (file)
     [] fn type_of: TypeOfItem(DefId) -> Ty<'tcx>,
 
     /// Maps from the def-id of an item (trait/struct/enum/fn) to its
-    /// associated generics and predicates.
+    /// associated generics.
     [] fn generics_of: GenericsOfItem(DefId) -> &'tcx ty::Generics,
+
+    /// Maps from the def-id of an item (trait/struct/enum/fn) to the
+    /// predicates (where clauses) that must be proven true in order
+    /// to reference it. This is almost always the "predicates query"
+    /// that you want.
+    ///
+    /// `predicates_of` builds on `predicates_defined_on` -- in fact,
+    /// it is almost always the same as that query, except for the
+    /// case of traits. For traits, `predicates_of` contains
+    /// an additional `Self: Trait<...>` predicate that users don't
+    /// actually write. This reflects the fact that to invoke the
+    /// trait (e.g., via `Default::default`) you must supply types
+    /// that actually implement the trait. (However, this extra
+    /// predicate gets in the way of some checks, which are intended
+    /// to operate over only the actual where-clauses written by the
+    /// user.)
     [] fn predicates_of: PredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
+
+    /// Maps from the def-id of an item (trait/struct/enum/fn) to the
+    /// predicates (where clauses) directly defined on it. This is
+    /// equal to the `explicit_predicates_of` predicates plus the
+    /// `inferred_outlives_of` predicates.
+    [] fn predicates_defined_on: PredicatesDefinedOnItem(DefId) -> ty::GenericPredicates<'tcx>,
+
+    /// Returns the predicates written explicit by the user.
     [] fn explicit_predicates_of: ExplicitPredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
 
+    /// Returns the inferred outlives predicates (e.g., for `struct
+    /// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
+    [] fn inferred_outlives_of: InferredOutlivesOf(DefId) -> Lrc<Vec<ty::Predicate<'tcx>>>,
+
     /// Maps from the def-id of a trait to the list of
     /// super-predicates. This is a subset of the full list of
     /// predicates. We store these in a separate map because we must
     /// (inferred) variance.
     [] fn variances_of: ItemVariances(DefId) -> Lrc<Vec<ty::Variance>>,
 
-    /// Maps from def-id of a type to its (inferred) outlives.
-    [] fn inferred_outlives_of: InferredOutlivesOf(DefId) -> Lrc<Vec<ty::Predicate<'tcx>>>,
-
     /// Maps from def-id of a type to its (inferred) outlives.
     [] fn inferred_outlives_crate: InferredOutlivesCrate(CrateNum)
         -> Lrc<ty::CratePredicatesMap<'tcx>>,
index d783b9574efb2fdbe21bcbd1d22d23fbf369a286..9f802f7fdcd4241c4c6512c4861d789ccb41de27 100644 (file)
@@ -1074,6 +1074,7 @@ macro_rules! force {
         DepKind::TypeOfItem => { force!(type_of, def_id!()); }
         DepKind::GenericsOfItem => { force!(generics_of, def_id!()); }
         DepKind::PredicatesOfItem => { force!(predicates_of, def_id!()); }
+        DepKind::PredicatesDefinedOnItem => { force!(predicates_defined_on, def_id!()); }
         DepKind::ExplicitPredicatesOfItem => { force!(explicit_predicates_of, def_id!()); }
         DepKind::InferredOutlivesOf => { force!(inferred_outlives_of, def_id!()); }
         DepKind::InferredOutlivesCrate => { force!(inferred_outlives_crate, LOCAL_CRATE); }
index 996ebd722fd4d3bf4393a72b1bf7442a45e1dab9..f93da53e0436d16f69f8ee23e76ebc737793f98d 100644 (file)
@@ -614,6 +614,15 @@ pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>) -> TraitRef<'tcx> {
         TraitRef { def_id: def_id, substs: substs }
     }
 
+    /// Returns a TraitRef of the form `P0: Foo<P1..Pn>` where `Pi`
+    /// are the parameters defined on trait.
+    pub fn identity<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> TraitRef<'tcx> {
+        TraitRef {
+            def_id,
+            substs: Substs::identity_for_item(tcx, def_id),
+        }
+    }
+
     pub fn self_ty(&self) -> Ty<'tcx> {
         self.substs.type_at(0)
     }
index 4e281231a4105ef258fbf451b68856e5e6967bef..f118d22c54d3fcff49c5f993f483b5d6e8a01c8c 100644 (file)
@@ -518,10 +518,25 @@ pub fn destructor_constraints(self, def: &'tcx ty::AdtDef)
         result
     }
 
+    /// True if `def_id` refers to a closure (e.g., `|x| x * 2`). Note
+    /// that closures have a def-id, but the closure *expression* also
+    /// has a `HirId` that is located within the context where the
+    /// closure appears (and, sadly, a corresponding `NodeId`, since
+    /// those are not yet phased out). The parent of the closure's
+    /// def-id will also be the context where it appears.
     pub fn is_closure(self, def_id: DefId) -> bool {
         self.def_key(def_id).disambiguated_data.data == DefPathData::ClosureExpr
     }
 
+    /// True if `def_id` refers to a trait (e.g., `trait Foo { ... }`).
+    pub fn is_trait(self, def_id: DefId) -> bool {
+        if let DefPathData::Trait(_) = self.def_key(def_id).disambiguated_data.data {
+            true
+        } else {
+            false
+        }
+    }
+
     /// True if this def-id refers to the implicit constructor for
     /// a tuple struct like `struct Foo(u32)`.
     pub fn is_struct_constructor(self, def_id: DefId) -> bool {
index 79baf0ec15178299d10b17b186fff0c7dabdc17f..046318b3619c30133de43540e025cf258b761484 100644 (file)
@@ -168,8 +168,7 @@ fn mutate(&mut self,
                     // have to be *FULLY* initialized, but we still
                     // must be careful lest it contains derefs of
                     // pointers.
-                    let hir_id = self.tcx().hir.node_to_hir_id(assignee_cmt.id);
-                    self.check_if_assigned_path_is_moved(hir_id.local_id,
+                    self.check_if_assigned_path_is_moved(assignee_cmt.hir_id.local_id,
                                                          assignment_span,
                                                          MovedInUse,
                                                          &lp);
@@ -178,8 +177,7 @@ fn mutate(&mut self,
                     // In a case like `path += 1`, then path must be
                     // fully initialized, since we will read it before
                     // we write it.
-                    let hir_id = self.tcx().hir.node_to_hir_id(assignee_cmt.id);
-                    self.check_if_path_is_moved(hir_id.local_id,
+                    self.check_if_path_is_moved(assignee_cmt.hir_id.local_id,
                                                 assignment_span,
                                                 MovedInUse,
                                                 &lp);
@@ -448,7 +446,7 @@ pub fn borrow_of_local_data<'tcx>(cmt: &mc::cmt_<'tcx>) -> bool {
         if let Some(yield_span) = self.bccx
                                       .region_scope_tree
                                       .yield_in_scope_for_expr(scope,
-                                                               cmt.id,
+                                                               cmt.hir_id,
                                                                self.bccx.body) {
             self.bccx.cannot_borrow_across_generator_yield(borrow_span,
                                                            yield_span,
index a74eba3995518b5d149f480f118c9de4e45a670c..d08814138719a370e1c97e1faf74751db12d69ae 100644 (file)
@@ -283,7 +283,7 @@ fn guarantee_assignment_valid(&mut self,
                                                     .local_id,
                                                 assignment_span,
                                                 lp,
-                                                self.bccx.tcx.hir.node_to_hir_id(cmt.id).local_id,
+                                                cmt.hir_id.local_id,
                                                 mode);
             }
             None => {
index 84931907964354acdd54a91f82643373f75dbe95..f221565c7f39124afc001be0819ed538f86c84f4 100644 (file)
@@ -112,15 +112,15 @@ fn group_errors_with_same_origin<'tcx>(errors: &Vec<MoveError<'tcx>>)
 
     fn append_to_grouped_errors<'tcx>(grouped_errors: &mut Vec<GroupedMoveErrors<'tcx>>,
                                       error: &MoveError<'tcx>) {
-        let move_from_id = error.move_from.id;
-        debug!("append_to_grouped_errors(move_from_id={})", move_from_id);
+        let move_from_id = error.move_from.hir_id;
+        debug!("append_to_grouped_errors(move_from_id={:?})", move_from_id);
         let move_to = if error.move_to.is_some() {
             vec![error.move_to.clone().unwrap()]
         } else {
             Vec::new()
         };
         for ge in &mut *grouped_errors {
-            if move_from_id == ge.move_from.id && error.move_to.is_some() {
+            if move_from_id == ge.move_from.hir_id && error.move_to.is_some() {
                 debug!("appending move_to to list");
                 ge.move_to_places.extend(move_to);
                 return
index 500903c1c3b5ed22831e476e8cc2075ca78b08a5..4bd8e6afa76e3da07fb6b9b776205d0bd5d60583 100644 (file)
@@ -899,7 +899,11 @@ fn report_bckerr(&self, err: &BckError<'a, 'tcx>) {
                 };
 
                 self.note_and_explain_mutbl_error(&mut db, &err, &error_span);
-                self.note_immutability_blame(&mut db, err.cmt.immutability_blame(), err.cmt.id);
+                self.note_immutability_blame(
+                    &mut db,
+                    err.cmt.immutability_blame(),
+                    self.tcx.hir.hir_to_node_id(err.cmt.hir_id)
+                );
                 db.emit();
             }
             err_out_of_scope(super_scope, sub_scope, cause) => {
@@ -1105,7 +1109,11 @@ pub fn report_aliasability_violation(&self,
                                                             Origin::Ast)
             }
         };
-        self.note_immutability_blame(&mut err, blame, cmt.id);
+        self.note_immutability_blame(
+            &mut err,
+            blame,
+            self.tcx.hir.hir_to_node_id(cmt.hir_id)
+        );
 
         if is_closure {
             err.help("closures behind references must be called via `&mut`");
index 294ae1e63a9ee6f922b836ee6d2d46faa18c4d4e..475ff0b744349abfb01cd4ef6f959705fe0f864f 100644 (file)
@@ -54,16 +54,16 @@ fn check_unused_mut_pat(&self, pats: &[P<hir::Pat>]) {
 
                 // Skip anything that looks like `&foo` or `&mut foo`, only look
                 // for by-value bindings
-                let bm = match self.bccx.tables.pat_binding_modes().get(hir_id) {
-                    Some(&bm) => bm,
-                    None => span_bug!(span, "missing binding mode"),
-                };
-                match bm {
-                    ty::BindByValue(hir::MutMutable) => {}
-                    _ => return,
+                if let Some(&bm) = self.bccx.tables.pat_binding_modes().get(hir_id) {
+                    match bm {
+                        ty::BindByValue(hir::MutMutable) => {}
+                        _ => return,
+                    }
+
+                    mutables.entry(ident.name).or_insert(Vec::new()).push((hir_id, span));
+                } else {
+                    tcx.sess.delay_span_bug(span, "missing binding mode");
                 }
-
-                mutables.entry(ident.name).or_insert(Vec::new()).push((hir_id, span));
             });
         }
 
index eb37e7f931cc3023228377f9208a549bf0ad5fa2..958d09413edfaed93b4ec343fd3977a62c161243 100644 (file)
@@ -81,16 +81,22 @@ pub fn new(scope: DIScope, line: usize, col: usize) -> InternalDebugLocation {
 
 pub fn set_debug_location(bx: &Builder, debug_location: InternalDebugLocation) {
     let metadata_node = match debug_location {
-        KnownLocation { scope, line, .. } => {
-            // Always set the column to zero like Clang and GCC
-            let col = UNKNOWN_COLUMN_NUMBER;
+        KnownLocation { scope, line, col } => {
+            // For MSVC, set the column number to zero.
+            // Otherwise, emit it. This mimics clang behaviour.
+            // See discussion in https://github.com/rust-lang/rust/issues/42921
+            let col_used =  if bx.cx.sess().target.target.options.is_like_msvc {
+                UNKNOWN_COLUMN_NUMBER
+            } else {
+                col as c_uint
+            };
             debug!("setting debug location to {} {}", line, col);
 
             unsafe {
                 llvm::LLVMRustDIBuilderCreateDebugLocation(
                     debug_context(bx.cx).llcontext,
                     line as c_uint,
-                    col as c_uint,
+                    col_used,
                     scope,
                     ptr::null_mut())
             }
index 6ba3582f0143bf3af42e40c77f3e2791e8adbef2..c4a23ac653ca009a57c8458ce009f7f2b0426352 100644 (file)
 use type_of::LayoutLlvmExt;
 use rustc::hir;
 use rustc::hir::def::Def;
-use rustc::hir::def_id::DefId;
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::mir::mono::{Linkage, Visibility};
 use rustc::ty::TypeFoldable;
 use rustc::ty::layout::LayoutOf;
-use syntax::attr;
 use std::fmt;
 
 pub use rustc::mir::mono::MonoItem;
@@ -173,7 +172,7 @@ fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
     // visibility as we're going to link this object all over the place but
     // don't want the symbols to get exported.
     if linkage != Linkage::Internal && linkage != Linkage::Private &&
-       attr::contains_name(cx.tcx.hir.krate_attrs(), "compiler_builtins") {
+       cx.tcx.is_compiler_builtins(LOCAL_CRATE) {
         unsafe {
             llvm::LLVMRustSetVisibility(lldecl, llvm::Visibility::Hidden);
         }
index 30b87c0390a7ed3032914e135266e74de0a36d57..2e95a45479c4f966fd0feb956eaa538780d0f944 100644 (file)
@@ -239,14 +239,20 @@ pub fn overwrite(&mut self, other: &IdxSet<T>) {
         self.words_mut().clone_from_slice(other.words());
     }
 
+    /// Set `self = self | other` and return true if `self` changed
+    /// (i.e., if new bits were added).
     pub fn union(&mut self, other: &IdxSet<T>) -> bool {
         bitwise(self.words_mut(), other.words(), &Union)
     }
 
+    /// Set `self = self - other` and return true if `self` changed.
+    /// (i.e., if any bits were removed).
     pub fn subtract(&mut self, other: &IdxSet<T>) -> bool {
         bitwise(self.words_mut(), other.words(), &Subtract)
     }
 
+    /// Set `self = self & other` and return true if `self` changed.
+    /// (i.e., if any bits were removed).
     pub fn intersect(&mut self, other: &IdxSet<T>) -> bool {
         bitwise(self.words_mut(), other.words(), &Intersect)
     }
index 5844edf000a8b7837ea8a1d781fd63fa0677e667..e4d0bc596cba6fb11a41fda148c4939771466377 100644 (file)
@@ -77,6 +77,7 @@
 pub mod owning_ref;
 pub mod tiny_list;
 pub mod sorted_map;
+pub mod work_queue;
 
 pub struct OnDrop<F: Fn()>(pub F);
 
diff --git a/src/librustc_data_structures/work_queue.rs b/src/librustc_data_structures/work_queue.rs
new file mode 100644 (file)
index 0000000..b8e8b24
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexed_set::IdxSetBuf;
+use indexed_vec::Idx;
+use std::collections::VecDeque;
+
+/// A work queue is a handy data structure for tracking work left to
+/// do. (For example, basic blocks left to process.) It is basically a
+/// de-duplicating queue; so attempting to insert X if X is already
+/// enqueued has no effect. This implementation assumes that the
+/// elements are dense indices, so it can allocate the queue to size
+/// and also use a bit set to track occupancy.
+pub struct WorkQueue<T: Idx> {
+    deque: VecDeque<T>,
+    set: IdxSetBuf<T>,
+}
+
+impl<T: Idx> WorkQueue<T> {
+    /// Create a new work queue with all the elements from (0..len).
+    #[inline]
+    pub fn with_all(len: usize) -> Self {
+        WorkQueue {
+            deque: (0..len).map(T::new).collect(),
+            set: IdxSetBuf::new_filled(len),
+        }
+    }
+
+    /// Create a new work queue that starts empty, where elements range from (0..len).
+    #[inline]
+    pub fn with_none(len: usize) -> Self {
+        WorkQueue {
+            deque: VecDeque::with_capacity(len),
+            set: IdxSetBuf::new_empty(len),
+        }
+    }
+
+    /// Attempt to enqueue `element` in the work queue. Returns false if it was already present.
+    #[inline]
+    pub fn insert(&mut self, element: T) -> bool {
+        if self.set.add(&element) {
+            self.deque.push_back(element);
+            true
+        } else {
+            false
+        }
+    }
+
+    /// Attempt to enqueue `element` in the work queue. Returns false if it was already present.
+    #[inline]
+    pub fn pop(&mut self) -> Option<T> {
+        if let Some(element) = self.deque.pop_front() {
+            self.set.remove(&element);
+            Some(element)
+        } else {
+            None
+        }
+    }
+
+    /// True if nothing is enqueued.
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        self.deque.is_empty()
+    }
+}
index f1f5e3ef6e10583d01c492d69b986e4972432fc2..c5f3b45950ed7f86faf1e8631a6d65a0a75574fb 100644 (file)
@@ -1709,7 +1709,6 @@ fn get_lints(&self) -> LintArray {
     }
 }
 
-
 declare_lint! {
     pub ELLIPSIS_INCLUSIVE_RANGE_PATTERNS,
     Allow,
@@ -1744,3 +1743,44 @@ fn check_pat(&mut self, cx: &EarlyContext, pat: &ast::Pat) {
         }
     }
 }
+
+declare_lint! {
+    UNNAMEABLE_TEST_FUNCTIONS,
+    Warn,
+    "detects an function that cannot be named being marked as #[test]"
+}
+
+pub struct UnnameableTestFunctions;
+
+impl LintPass for UnnameableTestFunctions {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(UNNAMEABLE_TEST_FUNCTIONS)
+    }
+}
+
+impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestFunctions {
+    fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
+        match it.node {
+            hir::ItemFn(..) => {
+                for attr in &it.attrs {
+                    if attr.name() == "test" {
+                        let parent = cx.tcx.hir.get_parent(it.id);
+                        match cx.tcx.hir.find(parent) {
+                            Some(hir_map::NodeItem(hir::Item {node: hir::ItemMod(_), ..})) |
+                            None => {}
+                            _ => {
+                                cx.struct_span_lint(
+                                    UNNAMEABLE_TEST_FUNCTIONS,
+                                    attr.span,
+                                    "cannot test inner function",
+                                ).emit();
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
+            _ => return,
+        };
+    }
+}
index 13e97a9d3e5914b3d36fce41ccbdb01da6bdc8f0..adc700506ffc0bc15f271a2b3b365edca9711021 100644 (file)
@@ -130,6 +130,7 @@ macro_rules! add_lint_group {
         MutableTransmutes: MutableTransmutes,
         UnionsWithDropFields: UnionsWithDropFields,
         UnreachablePub: UnreachablePub,
+        UnnameableTestFunctions: UnnameableTestFunctions,
         TypeAliasBounds: TypeAliasBounds,
         UnusedBrokenConst: UnusedBrokenConst,
         TrivialConstraints: TrivialConstraints,
index 07830d54d0c9e1bc83555caa297fbf178bfe3d51..741758cb954ba4b38e644c4644ddf57f2546e9cb 100644 (file)
@@ -331,6 +331,12 @@ fn init() { }
                  LLVMInitializeAArch64TargetMC,
                  LLVMInitializeAArch64AsmPrinter,
                  LLVMInitializeAArch64AsmParser);
+    init_target!(llvm_component = "amdgpu",
+                 LLVMInitializeAMDGPUTargetInfo,
+                 LLVMInitializeAMDGPUTarget,
+                 LLVMInitializeAMDGPUTargetMC,
+                 LLVMInitializeAMDGPUAsmPrinter,
+                 LLVMInitializeAMDGPUAsmParser);
     init_target!(llvm_component = "mips",
                  LLVMInitializeMipsTargetInfo,
                  LLVMInitializeMipsTarget,
index 23da82f5a4514241ca5fc56fed10f80fef37bd6d..20d9121668ba0b40893d6ad2f7f51897a5a24176 100644 (file)
@@ -107,6 +107,7 @@ fn into_args(self) -> (DefId, DefId) { (self.0.as_def_id(), self.1) }
         tcx.alloc_generics(cdata.get_generics(def_id.index, tcx.sess))
     }
     predicates_of => { cdata.get_predicates(def_id.index, tcx) }
+    predicates_defined_on => { cdata.get_predicates_defined_on(def_id.index, tcx) }
     super_predicates_of => { cdata.get_super_predicates(def_id.index, tcx) }
     trait_def => {
         tcx.alloc_trait_def(cdata.get_trait_def(def_id.index, tcx.sess))
index 1985900b3e1170b05e03e4ae8bf48207997807a2..d604ac819b83b6af6a1b123075a01a4b1ac227a9 100644 (file)
@@ -563,6 +563,13 @@ pub fn get_predicates(&self,
         self.entry(item_id).predicates.unwrap().decode((self, tcx))
     }
 
+    pub fn get_predicates_defined_on(&self,
+                                   item_id: DefIndex,
+                                   tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                                   -> ty::GenericPredicates<'tcx> {
+        self.entry(item_id).predicates_defined_on.unwrap().decode((self, tcx))
+    }
+
     pub fn get_super_predicates(&self,
                                 item_id: DefIndex,
                                 tcx: TyCtxt<'a, 'tcx, 'tcx>)
index 3cfde7a8297f97c957bf73542124fbeb36bc7df5..36f053e5aa9759e0cadcdd92e6bf502f57006621 100644 (file)
@@ -629,6 +629,7 @@ fn encode_enum_variant_info(&mut self,
             },
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
+            predicates_defined_on: None,
 
             mir: self.encode_optimized_mir(def_id),
         }
@@ -666,6 +667,7 @@ fn encode_info_for_mod(&mut self,
             variances: LazySeq::empty(),
             generics: None,
             predicates: None,
+            predicates_defined_on: None,
 
             mir: None
         }
@@ -706,6 +708,7 @@ fn encode_field(&mut self,
             variances: LazySeq::empty(),
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
+            predicates_defined_on: None,
 
             mir: None,
         }
@@ -763,6 +766,7 @@ fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<
             },
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
+            predicates_defined_on: None,
 
             mir: self.encode_optimized_mir(def_id),
         }
@@ -780,6 +784,12 @@ fn encode_predicates(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tc
         self.lazy(&tcx.predicates_of(def_id))
     }
 
+    fn encode_predicates_defined_on(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> {
+        debug!("IsolatedEncoder::encode_predicates_defined_on({:?})", def_id);
+        let tcx = self.tcx;
+        self.lazy(&tcx.predicates_defined_on(def_id))
+    }
+
     fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
         debug!("IsolatedEncoder::encode_info_for_trait_item({:?})", def_id);
         let tcx = self.tcx;
@@ -869,6 +879,7 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
             },
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
+            predicates_defined_on: None,
 
             mir: self.encode_optimized_mir(def_id),
         }
@@ -965,6 +976,7 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
             },
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
+            predicates_defined_on: None,
 
             mir: if mir { self.encode_optimized_mir(def_id) } else { None },
         }
@@ -1228,6 +1240,16 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                 _ => None,
             },
 
+            // The only time that `predicates_defined_on` is used (on
+            // an external item) is for traits, during chalk lowering,
+            // so only encode it in that case as an efficiency
+            // hack. (No reason not to expand it in the future if
+            // necessary.)
+            predicates_defined_on: match item.node {
+                hir::ItemTrait(..) => Some(self.encode_predicates_defined_on(def_id)),
+                _ => None, // not *wrong* for other kinds of items, but not needed
+            },
+
             mir: match item.node {
                 hir::ItemStatic(..) => {
                     self.encode_optimized_mir(def_id)
@@ -1278,6 +1300,7 @@ fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef) -> Entry<'tcx
             variances: LazySeq::empty(),
             generics: None,
             predicates: None,
+            predicates_defined_on: None,
             mir: None,
         }
     }
@@ -1305,6 +1328,7 @@ fn encode_info_for_ty_param(&mut self,
             variances: LazySeq::empty(),
             generics: None,
             predicates: None,
+            predicates_defined_on: None,
 
             mir: None,
         }
@@ -1349,6 +1373,7 @@ fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> {
             variances: LazySeq::empty(),
             generics: Some(self.encode_generics(def_id)),
             predicates: None,
+            predicates_defined_on: None,
 
             mir: self.encode_optimized_mir(def_id),
         }
@@ -1376,6 +1401,7 @@ fn encode_info_for_anon_const(&mut self, def_id: DefId) -> Entry<'tcx> {
             variances: LazySeq::empty(),
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
+            predicates_defined_on: None,
 
             mir: self.encode_optimized_mir(def_id),
         }
@@ -1577,6 +1603,7 @@ fn encode_info_for_foreign_item(&mut self,
             },
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
+            predicates_defined_on: None,
 
             mir: None,
         }
index 21d6d15457aa0252a4ac51f14e6f61af78e3b913..a0b21e63ac560278af6995c962e70f777287bbc5 100644 (file)
@@ -273,6 +273,7 @@ pub struct Entry<'tcx> {
     pub variances: LazySeq<ty::Variance>,
     pub generics: Option<Lazy<ty::Generics>>,
     pub predicates: Option<Lazy<ty::GenericPredicates<'tcx>>>,
+    pub predicates_defined_on: Option<Lazy<ty::GenericPredicates<'tcx>>>,
 
     pub mir: Option<Lazy<mir::Mir<'tcx>>>,
 }
@@ -290,6 +291,7 @@ pub struct Entry<'tcx> {
     variances,
     generics,
     predicates,
+    predicates_defined_on,
     mir
 });
 
index 44fc67dfa437959e869863a4c244db732cf81069..f903dbd97a814bb1a9effde20547c82379e5e85b 100644 (file)
 
 use borrow_check::WriteKind;
 use rustc::middle::region::ScopeTree;
-use rustc::mir::{BorrowKind, Field, Local, LocalKind, Location, Operand};
-use rustc::mir::{Place, ProjectionElem, Rvalue, Statement, StatementKind};
+use rustc::mir::{BindingForm, BorrowKind, ClearCrossCrate, Field, Local};
+use rustc::mir::{LocalDecl, LocalKind, Location, Operand, Place};
+use rustc::mir::{ProjectionElem, Rvalue, Statement, StatementKind};
+use rustc::mir::VarBindingForm;
 use rustc::ty::{self, RegionKind};
 use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::sync::Lrc;
@@ -622,42 +624,55 @@ pub(super) fn report_illegal_reassignment(
         assigned_span: Span,
         err_place: &Place<'tcx>,
     ) {
-        let is_arg = if let Place::Local(local) = place {
-            if let LocalKind::Arg = self.mir.local_kind(*local) {
-                true
+        let (from_arg, local_decl) = if let Place::Local(local) = *err_place {
+            if let LocalKind::Arg = self.mir.local_kind(local) {
+                (true, Some(&self.mir.local_decls[local]))
             } else {
-                false
+                (false, Some(&self.mir.local_decls[local]))
             }
         } else {
-            false
+            (false, None)
+        };
+
+        // If root local is initialized immediately (everything apart from let
+        // PATTERN;) then make the error refer to that local, rather than the
+        // place being assigned later.
+        let (place_description, assigned_span) = match local_decl {
+            Some(LocalDecl { is_user_variable: Some(ClearCrossCrate::Clear), .. })
+            | Some(LocalDecl { is_user_variable: Some(ClearCrossCrate::Set(
+                BindingForm::Var(VarBindingForm {
+                    opt_match_place: None, ..
+            }))), ..})
+            | Some(LocalDecl { is_user_variable: None, .. })
+            | None => (self.describe_place(place), assigned_span),
+            Some(decl) => (self.describe_place(err_place), decl.source_info.span),
         };
 
         let mut err = self.tcx.cannot_reassign_immutable(
             span,
-            &self.describe_place(place).unwrap_or("_".to_owned()),
-            is_arg,
+            place_description.as_ref().map(AsRef::as_ref).unwrap_or("_"),
+            from_arg,
             Origin::Mir,
         );
-        let msg = if is_arg {
+        let msg = if from_arg {
             "cannot assign to immutable argument"
         } else {
             "cannot assign twice to immutable variable"
         };
         if span != assigned_span {
-            if !is_arg {
-                let value_msg = match self.describe_place(place) {
+            if !from_arg {
+                let value_msg = match place_description {
                     Some(name) => format!("`{}`", name),
                     None => "value".to_owned(),
                 };
                 err.span_label(assigned_span, format!("first assignment to {}", value_msg));
             }
         }
-        if let Place::Local(local) = err_place {
-            let local_decl = &self.mir.local_decls[*local];
-            if let Some(name) = local_decl.name {
-                if local_decl.can_be_made_mutable() {
+        if let Some(decl) = local_decl {
+            if let Some(name) = decl.name {
+                if decl.can_be_made_mutable() {
                     err.span_label(
-                        local_decl.source_info.span,
+                        decl.source_info.span,
                         format!("consider changing this to `mut {}`", name),
                     );
                 }
index 3aaa3378bb0052fe93c0ea3c82bd4a4215e489dd..83738d4ffd5cb16c957761ea991e22df6ae59517 100644 (file)
@@ -1182,26 +1182,37 @@ fn consume_rvalue(
                 // We need to report back the list of mutable upvars that were
                 // moved into the closure and subsequently used by the closure,
                 // in order to populate our used_mut set.
-                if let AggregateKind::Closure(def_id, _) = &**aggregate_kind {
-                    let BorrowCheckResult {
-                        used_mut_upvars, ..
-                    } = self.tcx.mir_borrowck(*def_id);
-                    debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars);
-                    for field in used_mut_upvars {
-                        match operands[field.index()] {
-                            Operand::Move(Place::Local(local)) => {
-                                self.used_mut.insert(local);
-                            }
-                            Operand::Move(ref place @ Place::Projection(_)) => {
-                                if let Some(field) = self.is_upvar_field_projection(place) {
-                                    self.used_mut_upvars.push(field);
+                match **aggregate_kind {
+                    AggregateKind::Closure(def_id, _)
+                    | AggregateKind::Generator(def_id, _, _) => {
+                        let BorrowCheckResult {
+                            used_mut_upvars, ..
+                        } = self.tcx.mir_borrowck(def_id);
+                        debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars);
+                        for field in used_mut_upvars {
+                            // This relies on the current way that by-value
+                            // captures of a closure are copied/moved directly
+                            // when generating MIR.
+                            match operands[field.index()] {
+                                Operand::Move(Place::Local(local))
+                                | Operand::Copy(Place::Local(local)) => {
+                                    self.used_mut.insert(local);
+                                }
+                                Operand::Move(ref place @ Place::Projection(_))
+                                | Operand::Copy(ref place @ Place::Projection(_)) => {
+                                    if let Some(field) = self.is_upvar_field_projection(place) {
+                                        self.used_mut_upvars.push(field);
+                                    }
                                 }
+                                Operand::Move(Place::Static(..))
+                                | Operand::Copy(Place::Static(..))
+                                | Operand::Constant(..) => {}
                             }
-                            Operand::Move(Place::Static(..))
-                            | Operand::Copy(..)
-                            | Operand::Constant(..) => {}
                         }
                     }
+                    AggregateKind::Adt(..)
+                    | AggregateKind::Array(..)
+                    | AggregateKind::Tuple { .. } => (),
                 }
 
                 for operand in operands {
@@ -1940,6 +1951,10 @@ fn add_used_mut<'d>(
                     }
                 }
             }
+            RootPlace {
+                place: _,
+                is_local_mutation_allowed: LocalMutationIsAllowed::Yes,
+            } => {}
             RootPlace {
                 place: place @ Place::Projection(_),
                 is_local_mutation_allowed: _,
@@ -2115,13 +2130,9 @@ fn is_upvar_field_projection(&self, place: &Place<'tcx>) -> Option<Field> {
         match *place {
             Place::Projection(ref proj) => match proj.elem {
                 ProjectionElem::Field(field, _ty) => {
-                    let is_projection_from_ty_closure = proj
-                        .base
-                        .ty(self.mir, self.tcx)
-                        .to_ty(self.tcx)
-                        .is_closure();
+                    let base_ty = proj.base.ty(self.mir, self.tcx).to_ty(self.tcx);
 
-                    if is_projection_from_ty_closure {
+                    if  base_ty.is_closure() || base_ty.is_generator() {
                         Some(field)
                     } else {
                         None
index 68aa9aeabf811ae75a2bcd3429edd8947f5ef4ec..25a0123755f2c586e540d18fd7bbecf34f1f388d 100644 (file)
@@ -12,7 +12,7 @@
 use borrow_check::location::LocationTable;
 use borrow_check::nll::ToRegionVid;
 use borrow_check::nll::facts::AllFacts;
-use borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
+use borrow_check::nll::region_infer::RegionInferenceContext;
 use borrow_check::nll::type_check::AtLocation;
 use rustc::hir;
 use rustc::infer::InferCtxt;
@@ -33,7 +33,7 @@ pub(super) fn generate_constraints<'cx, 'gcx, 'tcx>(
     location_table: &LocationTable,
     mir: &Mir<'tcx>,
     borrow_set: &BorrowSet<'tcx>,
-    liveness_set_from_typeck: &[(ty::Region<'tcx>, Location, Cause)],
+    liveness_set_from_typeck: &[(ty::Region<'tcx>, Location)],
 ) {
     let mut cg = ConstraintGeneration {
         borrow_set,
@@ -69,14 +69,14 @@ fn visit_basic_block_data(&mut self, bb: BasicBlock, data: &BasicBlockData<'tcx>
     /// We sometimes have `substs` within an rvalue, or within a
     /// call. Make them live at the location where they appear.
     fn visit_substs(&mut self, substs: &&'tcx Substs<'tcx>, location: Location) {
-        self.add_regular_live_constraint(*substs, location, Cause::LiveOther(location));
+        self.add_regular_live_constraint(*substs, location);
         self.super_substs(substs);
     }
 
     /// We sometimes have `region` within an rvalue, or within a
     /// call. Make them live at the location where they appear.
     fn visit_region(&mut self, region: &ty::Region<'tcx>, location: Location) {
-        self.add_regular_live_constraint(*region, location, Cause::LiveOther(location));
+        self.add_regular_live_constraint(*region, location);
         self.super_region(region);
     }
 
@@ -94,7 +94,7 @@ fn visit_ty(&mut self, ty: &ty::Ty<'tcx>, ty_context: TyContext) {
                 );
             }
             TyContext::Location(location) => {
-                self.add_regular_live_constraint(*ty, location, Cause::LiveOther(location));
+                self.add_regular_live_constraint(*ty, location);
             }
         }
 
@@ -104,14 +104,14 @@ fn visit_ty(&mut self, ty: &ty::Ty<'tcx>, ty_context: TyContext) {
     /// We sometimes have `generator_substs` within an rvalue, or within a
     /// call. Make them live at the location where they appear.
     fn visit_generator_substs(&mut self, substs: &GeneratorSubsts<'tcx>, location: Location) {
-        self.add_regular_live_constraint(*substs, location, Cause::LiveOther(location));
+        self.add_regular_live_constraint(*substs, location);
         self.super_generator_substs(substs);
     }
 
     /// We sometimes have `closure_substs` within an rvalue, or within a
     /// call. Make them live at the location where they appear.
     fn visit_closure_substs(&mut self, substs: &ClosureSubsts<'tcx>, location: Location) {
-        self.add_regular_live_constraint(*substs, location, Cause::LiveOther(location));
+        self.add_regular_live_constraint(*substs, location);
         self.super_closure_substs(substs);
     }
 
@@ -233,7 +233,7 @@ impl<'cx, 'cg, 'gcx, 'tcx> ConstraintGeneration<'cx, 'cg, 'gcx, 'tcx> {
     /// that we also have to respect.
     fn add_region_liveness_constraints_from_type_check(
         &mut self,
-        liveness_set: &[(ty::Region<'tcx>, Location, Cause)],
+        liveness_set: &[(ty::Region<'tcx>, Location)],
     ) {
         debug!(
             "add_region_liveness_constraints_from_type_check(liveness_set={} items)",
@@ -247,16 +247,16 @@ fn add_region_liveness_constraints_from_type_check(
             ..
         } = self;
 
-        for (region, location, cause) in liveness_set {
+        for (region, location) in liveness_set {
             debug!("generate: {:#?} is live at {:#?}", region, location);
             let region_vid = regioncx.to_region_vid(region);
-            regioncx.add_live_point(region_vid, *location, &cause);
+            regioncx.add_live_point(region_vid, *location);
         }
 
         if let Some(all_facts) = all_facts {
             all_facts
                 .region_live_at
-                .extend(liveness_set.into_iter().flat_map(|(region, location, _)| {
+                .extend(liveness_set.into_iter().flat_map(|(region, location)| {
                     let r = regioncx.to_region_vid(region);
                     let p1 = location_table.start_index(*location);
                     let p2 = location_table.mid_index(*location);
@@ -269,7 +269,7 @@ fn add_region_liveness_constraints_from_type_check(
     /// `location` -- i.e., it may be used later. This means that all
     /// regions appearing in the type `live_ty` must be live at
     /// `location`.
-    fn add_regular_live_constraint<T>(&mut self, live_ty: T, location: Location, cause: Cause)
+    fn add_regular_live_constraint<T>(&mut self, live_ty: T, location: Location)
     where
         T: TypeFoldable<'tcx>,
     {
@@ -282,7 +282,7 @@ fn add_regular_live_constraint<T>(&mut self, live_ty: T, location: Location, cau
             .tcx
             .for_each_free_region(&live_ty, |live_region| {
                 let vid = live_region.to_region_vid();
-                self.regioncx.add_live_point(vid, location, &cause);
+                self.regioncx.add_live_point(vid, location);
             });
     }
 
diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs
new file mode 100644 (file)
index 0000000..a650196
--- /dev/null
@@ -0,0 +1,168 @@
+// 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.
+
+use std::collections::VecDeque;
+use std::rc::Rc;
+
+use borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
+use borrow_check::nll::ToRegionVid;
+use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor};
+use rustc::mir::{Local, Location, Mir};
+use rustc::ty::{RegionVid, TyCtxt};
+use rustc_data_structures::fx::FxHashSet;
+use util::liveness::{self, DefUse, LivenessMode};
+
+crate fn find<'cx, 'gcx: 'tcx, 'tcx: 'cx>(
+    mir: &'cx Mir<'tcx>,
+    regioncx: &'cx Rc<RegionInferenceContext<'tcx>>,
+    tcx: TyCtxt<'cx, 'gcx, 'tcx>,
+    region_vid: RegionVid,
+    start_point: Location,
+) -> Option<Cause> {
+    let mut uf = UseFinder {
+        mir,
+        regioncx,
+        tcx,
+        region_vid,
+        start_point,
+        liveness_mode: LivenessMode {
+            include_regular_use: true,
+            include_drops: true,
+        },
+    };
+
+    uf.find()
+}
+
+struct UseFinder<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
+    mir: &'cx Mir<'tcx>,
+    regioncx: &'cx Rc<RegionInferenceContext<'tcx>>,
+    tcx: TyCtxt<'cx, 'gcx, 'tcx>,
+    region_vid: RegionVid,
+    start_point: Location,
+    liveness_mode: LivenessMode,
+}
+
+impl<'cx, 'gcx, 'tcx> UseFinder<'cx, 'gcx, 'tcx> {
+    fn find(&mut self) -> Option<Cause> {
+        let mut queue = VecDeque::new();
+        let mut visited = FxHashSet();
+
+        queue.push_back(self.start_point);
+        while let Some(p) = queue.pop_front() {
+            if !self.regioncx.region_contains_point(self.region_vid, p) {
+                continue;
+            }
+
+            if !visited.insert(p) {
+                continue;
+            }
+
+            let block_data = &self.mir[p.block];
+
+            match self.def_use(p, block_data.visitable(p.statement_index)) {
+                Some(DefUseResult::Def) => {}
+
+                Some(DefUseResult::UseLive { local }) => {
+                    return Some(Cause::LiveVar(local, p));
+                }
+
+                Some(DefUseResult::UseDrop { local }) => {
+                    return Some(Cause::DropVar(local, p));
+                }
+
+                None => {
+                    if p.statement_index < block_data.statements.len() {
+                        queue.push_back(Location {
+                            statement_index: p.statement_index + 1,
+                            ..p
+                        });
+                    } else {
+                        queue.extend(
+                            block_data
+                                .terminator()
+                                .successors()
+                                .filter(|&bb| Some(&Some(*bb)) != block_data.terminator().unwind())
+                                .map(|&bb| Location {
+                                    statement_index: 0,
+                                    block: bb,
+                                }),
+                        );
+                    }
+                }
+            }
+        }
+
+        None
+    }
+
+    fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> Option<DefUseResult> {
+        let mut visitor = DefUseVisitor {
+            mir: self.mir,
+            tcx: self.tcx,
+            region_vid: self.region_vid,
+            liveness_mode: self.liveness_mode,
+            def_use_result: None,
+        };
+
+        thing.apply(location, &mut visitor);
+
+        visitor.def_use_result
+    }
+}
+
+struct DefUseVisitor<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
+    mir: &'cx Mir<'tcx>,
+    tcx: TyCtxt<'cx, 'gcx, 'tcx>,
+    region_vid: RegionVid,
+    liveness_mode: LivenessMode,
+    def_use_result: Option<DefUseResult>,
+}
+
+enum DefUseResult {
+    Def,
+
+    UseLive { local: Local },
+
+    UseDrop { local: Local },
+}
+
+impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for DefUseVisitor<'cx, 'gcx, 'tcx> {
+    fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
+        let local_ty = self.mir.local_decls[local].ty;
+
+        let mut found_it = false;
+        self.tcx.for_each_free_region(&local_ty, |r| {
+            if r.to_region_vid() == self.region_vid {
+                found_it = true;
+            }
+        });
+
+        if found_it {
+            match liveness::categorize(context, self.liveness_mode) {
+                Some(DefUse::Def) => {
+                    self.def_use_result = Some(DefUseResult::Def);
+                }
+
+                Some(DefUse::Use) => {
+                    self.def_use_result = if context.is_drop() {
+                        Some(DefUseResult::UseDrop { local })
+                    } else {
+                        Some(DefUseResult::UseLive { local })
+                    };
+                }
+
+                None => {
+                    self.def_use_result = None;
+                }
+            }
+        }
+    }
+}
index 4f37b338e92b66e08323649868f901fb2b48b552..bc4646b7c789a1724cdc51d0e89589a9cf2c8d0c 100644 (file)
@@ -9,13 +9,12 @@
 // except according to those terms.
 
 use borrow_check::borrow_set::BorrowData;
-use borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
+use borrow_check::nll::region_infer::Cause;
 use borrow_check::{Context, MirBorrowckCtxt, WriteKind};
-use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor};
-use rustc::mir::{Local, Location, Mir, Place};
-use rustc_data_structures::fx::FxHashSet;
+use rustc::mir::Place;
 use rustc_errors::DiagnosticBuilder;
-use util::liveness::{self, DefUse, LivenessMode};
+
+mod find_use;
 
 impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
     /// Adds annotations to `err` explaining *why* the borrow contains the
@@ -39,214 +38,73 @@ pub(in borrow_check) fn explain_why_borrow_contains_point(
         kind_place: Option<(WriteKind, &Place<'tcx>)>,
         err: &mut DiagnosticBuilder<'_>,
     ) {
-        let regioncx = &&self.nonlexical_regioncx;
+        debug!(
+            "explain_why_borrow_contains_point(context={:?}, borrow={:?}, kind_place={:?})",
+            context, borrow, kind_place,
+        );
+
+        let regioncx = &self.nonlexical_regioncx;
         let mir = self.mir;
+        let tcx = self.tcx;
 
         let borrow_region_vid = regioncx.to_region_vid(borrow.region);
-        if let Some(cause) = regioncx.why_region_contains_point(borrow_region_vid, context.loc) {
-            match cause {
-                Cause::LiveVar(local, location) => match find_regular_use(
-                    mir, regioncx, borrow, location, local,
-                ) {
-                    Some(p) => {
-                        err.span_label(mir.source_info(p).span, format!("borrow later used here"));
-                    }
 
-                    None => {
-                        span_bug!(
-                            mir.source_info(context.loc).span,
-                            "Cause should end in a LiveVar"
-                        );
-                    }
-                },
+        debug!(
+            "explain_why_borrow_contains_point: borrow_region_vid={:?}",
+            borrow_region_vid
+        );
 
-                Cause::DropVar(local, location) => match find_drop_use(
-                    mir, regioncx, borrow, location, local,
-                ) {
-                    Some(p) => match &mir.local_decls[local].name {
-                        Some(local_name) => {
-                            err.span_label(
-                                mir.source_info(p).span,
-                                format!("borrow later used here, when `{}` is dropped", local_name),
-                            );
+        let region_sub = regioncx.find_constraint(borrow_region_vid, context.loc);
 
-                            if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place {
-                                if let Place::Local(borrowed_local) = place {
-                                    let dropped_local_scope =
-                                        mir.local_decls[local].visibility_scope;
-                                    let borrowed_local_scope =
-                                        mir.local_decls[*borrowed_local].visibility_scope;
+        debug!(
+            "explain_why_borrow_contains_point: region_sub={:?}",
+            region_sub
+        );
 
-                                    if mir.is_sub_scope(borrowed_local_scope, dropped_local_scope) {
-                                        err.note(
-                                            "values in a scope are dropped \
-                                             in the opposite order they are defined",
-                                        );
-                                    }
-                                }
-                            }
-                        }
-                        None => {
-                            err.span_label(
-                                mir.local_decls[local].source_info.span,
-                                "borrow may end up in a temporary, created here",
-                            );
+        match find_use::find(mir, regioncx, tcx, region_sub, context.loc) {
+            Some(Cause::LiveVar(_local, location)) => {
+                err.span_label(
+                    mir.source_info(location).span,
+                    format!("borrow later used here"),
+                );
+            }
 
-                            err.span_label(
-                                mir.source_info(p).span,
-                                "temporary later dropped here, \
-                                 potentially using the reference",
-                            );
+            Some(Cause::DropVar(local, location)) => match &mir.local_decls[local].name {
+                Some(local_name) => {
+                    err.span_label(
+                        mir.source_info(location).span,
+                        format!("borrow later used here, when `{}` is dropped", local_name),
+                    );
+
+                    if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place {
+                        if let Place::Local(borrowed_local) = place {
+                            let dropped_local_scope = mir.local_decls[local].visibility_scope;
+                            let borrowed_local_scope =
+                                mir.local_decls[*borrowed_local].visibility_scope;
+
+                            if mir.is_sub_scope(borrowed_local_scope, dropped_local_scope) {
+                                err.note(
+                                    "values in a scope are dropped \
+                                     in the opposite order they are defined",
+                                );
+                            }
                         }
-                    },
-
-                    None => {
-                        span_bug!(
-                            mir.source_info(context.loc).span,
-                            "Cause should end in a DropVar"
-                        );
-                    }
-                },
-
-                Cause::UniversalRegion(region_vid) => {
-                    if let Some(region) = regioncx.to_error_region(region_vid) {
-                        self.tcx.note_and_explain_free_region(
-                            err,
-                            "borrowed value must be valid for ",
-                            region,
-                            "...",
-                        );
                     }
                 }
 
-                _ => {}
-            }
-        }
-    }
-}
-
-fn find_regular_use<'gcx, 'tcx>(
-    mir: &'gcx Mir,
-    regioncx: &'tcx RegionInferenceContext,
-    borrow: &'tcx BorrowData,
-    start_point: Location,
-    local: Local,
-) -> Option<Location> {
-    let mut uf = UseFinder {
-        mir,
-        regioncx,
-        borrow,
-        start_point,
-        local,
-        liveness_mode: LivenessMode {
-            include_regular_use: true,
-            include_drops: false,
-        },
-    };
-
-    uf.find()
-}
-
-fn find_drop_use<'gcx, 'tcx>(
-    mir: &'gcx Mir,
-    regioncx: &'tcx RegionInferenceContext,
-    borrow: &'tcx BorrowData,
-    start_point: Location,
-    local: Local,
-) -> Option<Location> {
-    let mut uf = UseFinder {
-        mir,
-        regioncx,
-        borrow,
-        start_point,
-        local,
-        liveness_mode: LivenessMode {
-            include_regular_use: false,
-            include_drops: true,
-        },
-    };
-
-    uf.find()
-}
-
-struct UseFinder<'gcx, 'tcx> {
-    mir: &'gcx Mir<'gcx>,
-    regioncx: &'tcx RegionInferenceContext<'tcx>,
-    borrow: &'tcx BorrowData<'tcx>,
-    start_point: Location,
-    local: Local,
-    liveness_mode: LivenessMode,
-}
-
-impl<'gcx, 'tcx> UseFinder<'gcx, 'tcx> {
-    fn find(&mut self) -> Option<Location> {
-        let mut stack = vec![];
-        let mut visited = FxHashSet();
-
-        stack.push(self.start_point);
-        while let Some(p) = stack.pop() {
-            if !self.regioncx.region_contains_point(self.borrow.region, p) {
-                continue;
-            }
-
-            if !visited.insert(p) {
-                continue;
-            }
-
-            let block_data = &self.mir[p.block];
-            let (defined, used) = self.def_use(p, block_data.visitable(p.statement_index));
-
-            if used {
-                return Some(p);
-            } else if !defined {
-                if p.statement_index < block_data.statements.len() {
-                    stack.push(Location {
-                        statement_index: p.statement_index + 1,
-                        ..p
-                    });
-                } else {
-                    stack.extend(block_data.terminator().successors().map(|&basic_block| {
-                        Location {
-                            statement_index: 0,
-                            block: basic_block,
-                        }
-                    }));
+                None => {}
+            },
+
+            None => {
+                if let Some(region) = regioncx.to_error_region(region_sub) {
+                    self.tcx.note_and_explain_free_region(
+                        err,
+                        "borrowed value must be valid for ",
+                        region,
+                        "...",
+                    );
                 }
             }
         }
-
-        None
-    }
-
-    fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> (bool, bool) {
-        let mut visitor = DefUseVisitor {
-            defined: false,
-            used: false,
-            local: self.local,
-            liveness_mode: self.liveness_mode,
-        };
-
-        thing.apply(location, &mut visitor);
-
-        (visitor.defined, visitor.used)
-    }
-}
-
-struct DefUseVisitor {
-    defined: bool,
-    used: bool,
-    local: Local,
-    liveness_mode: LivenessMode,
-}
-
-impl<'tcx> Visitor<'tcx> for DefUseVisitor {
-    fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
-        if local == self.local {
-            match liveness::categorize(context, self.liveness_mode) {
-                Some(DefUse::Def) => self.defined = true,
-                Some(DefUse::Use) => self.used = true,
-                None => (),
-            }
-        }
     }
 }
index 07b160ed66f8ac9da1573dbdb7aacdbb23e75459..16506800c9e16025f63d81db5b3e0e42fe76f24e 100644 (file)
@@ -263,13 +263,6 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
                     }
                 }
 
-                // Before each basic block, dump out the values
-                // that are live on entry to the basic block.
-                PassWhere::BeforeBlock(bb) => {
-                    let s = live_variable_set(&liveness.regular.ins[bb], &liveness.drop.ins[bb]);
-                    writeln!(out, "    | Live variables on entry to {:?}: {}", bb, s)?;
-                }
-
                 PassWhere::BeforeLocation(location) => {
                     let s = live_variable_set(
                         &regular_liveness_per_location[&location],
@@ -285,7 +278,14 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
                     )?;
                 }
 
-                PassWhere::AfterLocation(_) | PassWhere::AfterCFG => {}
+                // After each basic block, dump out the values
+                // that are live on exit from the basic block.
+                PassWhere::AfterTerminator(bb) => {
+                    let s = live_variable_set(&liveness.regular.outs[bb], &liveness.drop.outs[bb]);
+                    writeln!(out, "    | Live variables on exit from {:?}: {}", bb, s)?;
+                }
+
+                PassWhere::BeforeBlock(_) | PassWhere::AfterLocation(_) | PassWhere::AfterCFG => {}
             }
             Ok(())
         },
index 970652d8872cd71f4b4b220487fa1a90136f6249..6543516b9c2c642e75c7b9e8382eebfd5693470f 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use std::fmt;
-use borrow_check::nll::region_infer::{Cause, ConstraintIndex, RegionInferenceContext};
+use borrow_check::nll::region_infer::{ConstraintIndex, RegionInferenceContext};
 use borrow_check::nll::region_infer::values::ToElementIndex;
 use borrow_check::nll::type_check::Locations;
 use rustc::hir::def_id::DefId;
@@ -259,15 +259,12 @@ pub(super) fn report_error(
         }
     }
 
-    crate fn why_region_contains_point(&self, fr1: RegionVid, elem: Location) -> Option<Cause> {
-        // Find some constraint `X: Y` where:
-        // - `fr1: X` transitively
-        // - and `Y` is live at `elem`
+    // Find some constraint `X: Y` where:
+    // - `fr1: X` transitively
+    // - and `Y` is live at `elem`
+    crate fn find_constraint(&self, fr1: RegionVid, elem: Location) -> RegionVid {
         let index = self.blame_constraint(fr1, elem);
-        let region_sub = self.constraints[index].sub;
-
-        // then return why `Y` was live at `elem`
-        self.liveness_constraints.cause(region_sub, elem)
+        self.constraints[index].sub
     }
 
     /// Tries to finds a good span to blame for the fact that `fr1`
index 09e425ff55508c7c7179badce5f2849499f86c22..13cc0c0419eab1673e0064fd9ab637f209161e71 100644 (file)
@@ -19,7 +19,7 @@
 use rustc::infer::RegionVariableOrigin;
 use rustc::mir::{
     ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements, Local, Location,
-    Mir
+    Mir,
 };
 use rustc::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable};
 use rustc::util::common;
@@ -75,8 +75,6 @@ pub struct RegionInferenceContext<'tcx> {
     universal_regions: UniversalRegions<'tcx>,
 }
 
-struct TrackCauses(bool);
-
 struct RegionDefinition<'tcx> {
     /// Why we created this variable. Mostly these will be
     /// `RegionVariableOrigin::NLL`, but some variables get created
@@ -105,13 +103,6 @@ pub(crate) enum Cause {
 
     /// point inserted because Local was dropped at the given Location
     DropVar(Local, Location),
-
-    /// point inserted because the type was live at the given Location,
-    /// but not as part of some local variable
-    LiveOther(Location),
-
-    /// part of the initial set of values for a universally quantified region
-    UniversalRegion(RegionVid),
 }
 
 /// A "type test" corresponds to an outlives constraint between a type
@@ -280,19 +271,11 @@ fn init_universal_regions(&mut self) {
 
             // Add all nodes in the CFG to liveness constraints
             for point_index in self.elements.all_point_indices() {
-                self.liveness_constraints.add_element(
-                    variable,
-                    point_index,
-                    &Cause::UniversalRegion(variable),
-                );
+                self.liveness_constraints.add_element(variable, point_index);
             }
 
             // Add `end(X)` into the set for X.
-            self.liveness_constraints.add_element(
-                variable,
-                variable,
-                &Cause::UniversalRegion(variable),
-            );
+            self.liveness_constraints.add_element(variable, variable);
         }
     }
 
@@ -337,26 +320,16 @@ pub fn region_contains_point<R>(&self, r: R, p: Location) -> bool
     ///
     /// Returns `true` if this constraint is new and `false` is the
     /// constraint was already present.
-    pub(super) fn add_live_point(&mut self, v: RegionVid, point: Location, cause: &Cause) -> bool {
+    pub(super) fn add_live_point(&mut self, v: RegionVid, point: Location) -> bool {
         debug!("add_live_point({:?}, {:?})", v, point);
         assert!(self.inferred_values.is_none(), "values already inferred");
-        debug!("add_live_point: @{:?} Adding cause {:?}", point, cause);
 
         let element = self.elements.index(point);
-        if self.liveness_constraints.add_element(v, element, &cause) {
-            true
-        } else {
-            false
-        }
+        self.liveness_constraints.add_element(v, element)
     }
 
     /// Indicates that the region variable `sup` must outlive `sub` is live at the point `point`.
-    pub(super) fn add_outlives(
-        &mut self,
-        locations: Locations,
-        sup: RegionVid,
-        sub: RegionVid,
-    ) {
+    pub(super) fn add_outlives(&mut self, locations: Locations, sup: RegionVid, sub: RegionVid) {
         assert!(self.inferred_values.is_none(), "values already inferred");
         self.constraints.push(OutlivesConstraint {
             locations,
@@ -440,7 +413,7 @@ fn compute_region_values(&self, _mir: &Mir<'tcx>) -> RegionValues {
 
         // The initial values for each region are derived from the liveness
         // constraints we have accumulated.
-        let mut inferred_values = self.liveness_constraints.duplicate(TrackCauses(false));
+        let mut inferred_values = self.liveness_constraints.clone();
 
         let dependency_map = self.dependency_map.as_ref().unwrap();
 
@@ -461,11 +434,14 @@ fn compute_region_values(&self, _mir: &Mir<'tcx>) -> RegionValues {
                 debug!("propagate_constraints:   sub={:?}", constraint.sub);
                 debug!("propagate_constraints:   sup={:?}", constraint.sup);
 
-                self.constraints.each_affected_by_dirty(dependency_map[constraint.sup], |dep_idx| {
-                    if clean_bit_vec.remove(dep_idx.index()) {
-                        dirty_list.push(dep_idx);
-                    }
-                });
+                self.constraints.each_affected_by_dirty(
+                    dependency_map[constraint.sup],
+                    |dep_idx| {
+                        if clean_bit_vec.remove(dep_idx.index()) {
+                            dirty_list.push(dep_idx);
+                        }
+                    },
+                );
             }
 
             debug!("\n");
@@ -503,8 +479,12 @@ fn check_type_tests<'gcx>(
             }
 
             if let Some(propagated_outlives_requirements) = &mut propagated_outlives_requirements {
-                if self.try_promote_type_test(infcx, mir, type_test,
-                                              propagated_outlives_requirements) {
+                if self.try_promote_type_test(
+                    infcx,
+                    mir,
+                    type_test,
+                    propagated_outlives_requirements,
+                ) {
                     continue;
                 }
             }
@@ -760,12 +740,7 @@ fn universal_upper_bound(&self, r: RegionVid) -> RegionVid {
 
     /// Test if `test` is true when applied to `lower_bound` at
     /// `point`, and returns true or false.
-    fn eval_region_test(
-        &self,
-        mir: &Mir<'tcx>,
-        lower_bound: RegionVid,
-        test: &RegionTest,
-    ) -> bool {
+    fn eval_region_test(&self, mir: &Mir<'tcx>, lower_bound: RegionVid, test: &RegionTest) -> bool {
         debug!(
             "eval_region_test(lower_bound={:?}, test={:?})",
             lower_bound, test
@@ -797,10 +772,7 @@ fn eval_outlives(
         sup_region: RegionVid,
         sub_region: RegionVid,
     ) -> bool {
-        debug!(
-            "eval_outlives({:?}: {:?})",
-            sup_region, sub_region
-        );
+        debug!("eval_outlives({:?}: {:?})", sup_region, sub_region);
 
         let inferred_values = self
             .inferred_values
index e914be52db08c83776f95e929b1b950d77d4dda7..1039e6d7b972cbcc1acda41f8303b100775e47c6 100644 (file)
@@ -8,18 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use borrow_check::nll::region_infer::TrackCauses;
 use rustc::mir::{BasicBlock, Location, Mir};
 use rustc::ty::RegionVid;
 use rustc_data_structures::bitvec::SparseBitMatrix;
-use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::indexed_vec::IndexVec;
 use std::fmt::Debug;
 use std::rc::Rc;
 
-use super::Cause;
-
 /// Maps between the various kinds of elements of a region value to
 /// the internal indices that w use.
 pub(super) struct RegionValueElements {
@@ -32,7 +28,8 @@ pub(super) struct RegionValueElements {
 impl RegionValueElements {
     pub(super) fn new(mir: &Mir<'_>, num_universal_regions: usize) -> Self {
         let mut num_points = 0;
-        let statements_before_block = mir.basic_blocks()
+        let statements_before_block = mir
+            .basic_blocks()
             .iter()
             .map(|block_data| {
                 let v = num_points;
@@ -100,7 +97,8 @@ pub(super) fn to_element(&self, i: RegionElementIndex) -> RegionElement {
             // be (BB2, 20).
             //
             // Nit: we could do a binary search here but I'm too lazy.
-            let (block, &first_index) = self.statements_before_block
+            let (block, &first_index) = self
+                .statements_before_block
                 .iter_enumerated()
                 .filter(|(_, first_index)| **first_index <= point_index)
                 .last()
@@ -180,19 +178,12 @@ fn to_element_index(self, _elements: &RegionValueElements) -> RegionElementIndex
 /// compact `SparseBitMatrix` representation, with one row per region
 /// variable. The columns consist of either universal regions or
 /// points in the CFG.
+#[derive(Clone)]
 pub(super) struct RegionValues {
     elements: Rc<RegionValueElements>,
     matrix: SparseBitMatrix<RegionVid, RegionElementIndex>,
-
-    /// If cause tracking is enabled, maps from a pair (r, e)
-    /// consisting of a region `r` that contains some element `e` to
-    /// the reason that the element is contained. There should be an
-    /// entry for every bit set to 1 in `SparseBitMatrix`.
-    causes: Option<CauseMap>,
 }
 
-type CauseMap = FxHashMap<(RegionVid, RegionElementIndex), Cause>;
-
 impl RegionValues {
     /// Creates a new set of "region values" that tracks causal information.
     /// Each of the regions in num_region_variables will be initialized with an
@@ -209,38 +200,15 @@ pub(super) fn new(elements: &Rc<RegionValueElements>, num_region_variables: usiz
                 RegionVid::new(num_region_variables),
                 RegionElementIndex::new(elements.num_elements()),
             ),
-            causes: Some(CauseMap::default()),
-        }
-    }
-
-    /// Duplicates the region values. If track_causes is false, then the
-    /// resulting value will not track causal information (and any existing
-    /// causal information is dropped). Otherwise, the causal information is
-    /// preserved and maintained. Tracking the causal information makes region
-    /// propagation significantly slower, so we prefer not to do it until an
-    /// error is reported.
-    pub(super) fn duplicate(&self, track_causes: TrackCauses) -> Self {
-        Self {
-            elements: self.elements.clone(),
-            matrix: self.matrix.clone(),
-            causes: if track_causes.0 {
-                self.causes.clone()
-            } else {
-                None
-            },
         }
     }
 
     /// Adds the given element to the value for the given region. Returns true if
     /// the element is newly added (i.e., was not already present).
-    pub(super) fn add_element<E: ToElementIndex>(
-        &mut self,
-        r: RegionVid,
-        elem: E,
-        cause: &Cause,
-    ) -> bool {
+    pub(super) fn add_element<E: ToElementIndex>(&mut self, r: RegionVid, elem: E) -> bool {
         let i = self.elements.index(elem);
-        self.add_internal(r, i, |_| cause.clone())
+        debug!("add(r={:?}, elem={:?})", r, elem);
+        self.matrix.add(r, i)
     }
 
     /// Add all elements in `r_from` to `r_to` (because e.g. `r_to:
@@ -249,40 +217,6 @@ pub(super) fn add_region(&mut self, r_to: RegionVid, r_from: RegionVid) -> bool
         self.matrix.merge(r_from, r_to)
     }
 
-    /// Internal method to add an element to a region.
-    ///
-    /// Takes a "lazy" cause -- this function will return the cause, but it will only
-    /// be invoked if cause tracking is enabled.
-    fn add_internal<F>(&mut self, r: RegionVid, i: RegionElementIndex, make_cause: F) -> bool
-    where
-        F: FnOnce(&CauseMap) -> Cause,
-    {
-        if self.matrix.add(r, i) {
-            debug!("add(r={:?}, i={:?})", r, self.elements.to_element(i));
-
-            if let Some(causes) = &mut self.causes {
-                let cause = make_cause(causes);
-                causes.insert((r, i), cause);
-            }
-
-            true
-        } else {
-            if let Some(causes) = &mut self.causes {
-                let cause = make_cause(causes);
-                let old_cause = causes.get_mut(&(r, i)).unwrap();
-                // #49998: compare using root cause alone to avoid
-                // useless traffic from similar outlives chains.
-
-                if cause < *old_cause {
-                    *old_cause = cause;
-                    return true;
-                }
-            }
-
-            false
-        }
-    }
-
     /// True if the region `r` contains the given element.
     pub(super) fn contains<E: ToElementIndex>(&self, r: RegionVid, elem: E) -> bool {
         let i = self.elements.index(elem);
@@ -398,18 +332,4 @@ fn push_location_range(str: &mut String, location1: Location, location2: Locatio
             ));
         }
     }
-
-    /// Given a region `r` that contains the element `elem`, returns the `Cause`
-    /// that tells us *why* `elem` is found in that region.
-    ///
-    /// Returns None if cause tracking is disabled or `elem` is not
-    /// actually found in `r`.
-    pub(super) fn cause<T: ToElementIndex>(&self, r: RegionVid, elem: T) -> Option<Cause> {
-        let index = self.elements.index(elem);
-        if let Some(causes) = &self.causes {
-            causes.get(&(r, index)).cloned()
-        } else {
-            None
-        }
-    }
 }
index d84dcc5678279a918a545e914832c2c989e59454..91025e3f4afc016e13e7d2048f1fd19baaccc06a 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use borrow_check::nll::region_infer::Cause;
 use borrow_check::nll::type_check::AtLocation;
 use dataflow::move_paths::{HasMoveData, MoveData};
 use dataflow::MaybeInitializedPlaces;
@@ -88,8 +87,7 @@ fn add_liveness_constraints(&mut self, bb: BasicBlock) {
             .simulate_block(self.mir, bb, |location, live_locals| {
                 for live_local in live_locals.iter() {
                     let live_local_ty = self.mir.local_decls[live_local].ty;
-                    let cause = Cause::LiveVar(live_local, location);
-                    Self::push_type_live_constraint(&mut self.cx, live_local_ty, location, cause);
+                    Self::push_type_live_constraint(&mut self.cx, live_local_ty, location);
                 }
             });
 
@@ -161,7 +159,6 @@ fn push_type_live_constraint<T>(
         cx: &mut TypeChecker<'_, 'gcx, 'tcx>,
         value: T,
         location: Location,
-        cause: Cause,
     ) where
         T: TypeFoldable<'tcx>,
     {
@@ -171,9 +168,7 @@ fn push_type_live_constraint<T>(
         );
 
         cx.tcx().for_each_free_region(&value, |live_region| {
-            cx.constraints
-                .liveness_set
-                .push((live_region, location, cause.clone()));
+            cx.constraints.liveness_set.push((live_region, location));
         });
     }
 
@@ -210,9 +205,8 @@ fn add_drop_live_constraint(
 
         // All things in the `outlives` array may be touched by
         // the destructor and must be live at this point.
-        let cause = Cause::DropVar(dropped_local, location);
         for &kind in &drop_data.dropck_result.kinds {
-            Self::push_type_live_constraint(&mut self.cx, kind, location, cause);
+            Self::push_type_live_constraint(&mut self.cx, kind, location);
         }
     }
 
index e3d20d9a8dbcbe812a44b0fb3326bc3e41bccdc2..2b47d50b4c2c7a2d29ee5796cbedc5603d6e5435 100644 (file)
@@ -14,7 +14,6 @@
 use borrow_check::location::LocationTable;
 use borrow_check::nll::constraint_set::ConstraintSet;
 use borrow_check::nll::facts::AllFacts;
-use borrow_check::nll::region_infer::Cause;
 use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest};
 use borrow_check::nll::universal_regions::UniversalRegions;
 use dataflow::move_paths::MoveData;
@@ -312,7 +311,10 @@ fn sanitize_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
 
         debug!("sanitize_constant: expected_ty={:?}", expected_ty);
 
-        if let Err(terr) = self.cx.eq_types(expected_ty, constant.ty, location.boring()) {
+        if let Err(terr) = self
+            .cx
+            .eq_types(expected_ty, constant.ty, location.boring())
+        {
             span_mirbug!(
                 self,
                 constant,
@@ -615,7 +617,7 @@ struct BorrowCheckContext<'a, 'tcx: 'a> {
     /// not otherwise appear in the MIR -- in particular, the
     /// late-bound regions that it instantiates at call-sites -- and
     /// hence it must report on their liveness constraints.
-    crate liveness_set: Vec<(ty::Region<'tcx>, Location, Cause)>,
+    crate liveness_set: Vec<(ty::Region<'tcx>, Location)>,
 
     crate outlives_constraints: ConstraintSet,
 
@@ -771,12 +773,7 @@ fn push_region_constraints(
         }
     }
 
-    fn sub_types(
-        &mut self,
-        sub: Ty<'tcx>,
-        sup: Ty<'tcx>,
-        locations: Locations,
-    ) -> Fallible<()> {
+    fn sub_types(&mut self, sub: Ty<'tcx>, sup: Ty<'tcx>, locations: Locations) -> Fallible<()> {
         let param_env = self.param_env;
         self.fully_perform_op(
             locations,
@@ -808,7 +805,11 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca
                     false
                 };
 
-                let locations = if is_temp { location.boring() } else { location.interesting() };
+                let locations = if is_temp {
+                    location.boring()
+                } else {
+                    location.interesting()
+                };
 
                 let place_ty = place.ty(mir, tcx).to_ty(tcx);
                 let rv_ty = rv.ty(mir, tcx);
@@ -983,11 +984,9 @@ fn check_terminator(
                 // output) types in the signature must be live, since
                 // all the inputs that fed into it were live.
                 for &late_bound_region in map.values() {
-                    self.constraints.liveness_set.push((
-                        late_bound_region,
-                        term_location,
-                        Cause::LiveOther(term_location),
-                    ));
+                    self.constraints
+                        .liveness_set
+                        .push((late_bound_region, term_location));
                 }
 
                 self.check_call_inputs(mir, term, &sig, args, term_location);
@@ -1507,10 +1506,7 @@ fn prove_aggregate_predicates(
                     );
 
                     // Hmm, are these constraints *really* boring?
-                    self.push_region_constraints(
-                        location.boring(),
-                        &closure_constraints,
-                    );
+                    self.push_region_constraints(location.boring(), &closure_constraints);
                 }
 
                 tcx.predicates_of(*def_id).instantiate(tcx, substs.substs)
index d660b40e9cb128bdc3c2f8eadaa063e75df11e69..9a756cdfb418e1dc49938a3a53e2c3d26937bd14 100644 (file)
@@ -186,10 +186,29 @@ fn expr_as_rvalue(&mut self,
             }
             ExprKind::Closure { closure_id, substs, upvars, movability } => {
                 // see (*) above
-                let mut operands: Vec<_> =
-                    upvars.into_iter()
-                          .map(|upvar| unpack!(block = this.as_operand(block, scope, upvar)))
-                          .collect();
+                let mut operands: Vec<_> = upvars
+                    .into_iter()
+                    .map(|upvar| {
+                        let upvar = this.hir.mirror(upvar);
+                        match Category::of(&upvar.kind) {
+                            // Use as_place to avoid creating a temporary when
+                            // moving a variable into a closure, so that
+                            // borrowck knows which variables to mark as being
+                            // used as mut. This is OK here because the upvar
+                            // expressions have no side effects and act on
+                            // disjoint places.
+                            // This occurs when capturing by copy/move, while
+                            // by reference captures use as_operand
+                            Some(Category::Place) => {
+                                let place = unpack!(block = this.as_place(block, upvar));
+                                this.consume_by_copy_or_move(place)
+                            }
+                            _ => {
+                                unpack!(block = this.as_operand(block, scope, upvar))
+                            }
+                        }
+                    })
+                    .collect();
                 let result = match substs {
                     UpvarSubsts::Generator(substs) => {
                         let movability = movability.unwrap();
index 4db5c8e9278e5e19e0c7c52385e202bf0edb0642..8fb5b5c0fa4188e10450d6dfd689beb4722ed2d3 100644 (file)
@@ -541,13 +541,14 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
                 if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
                     decl.debug_name = ident.name;
 
-                    let bm = *hir.tables.pat_binding_modes()
-                                        .get(pat.hir_id)
-                                        .expect("missing binding mode");
-                    if bm == ty::BindByValue(hir::MutMutable) {
-                        decl.mutability = Mutability::Mut;
+                    if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
+                        if bm == ty::BindByValue(hir::MutMutable) {
+                            decl.mutability = Mutability::Mut;
+                        } else {
+                            decl.mutability = Mutability::Not;
+                        }
                     } else {
-                        decl.mutability = Mutability::Not;
+                        tcx.sess.delay_span_bug(pat.span, "missing binding mode");
                     }
                 }
             }
@@ -672,11 +673,18 @@ fn args_and_body(&mut self,
     {
         // Allocate locals for the function arguments
         for &ArgInfo(ty, _, pattern, _) in arguments.iter() {
-            // If this is a simple binding pattern, give the local a nice name for debuginfo.
+            // If this is a simple binding pattern, give the local a name for
+            // debuginfo and so that error reporting knows that this is a user
+            // variable. For any other pattern the pattern introduces new
+            // variables which will be named instead.
             let mut name = None;
             if let Some(pat) = pattern {
-                if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
-                    name = Some(ident.name);
+                match pat.node {
+                    hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, _)
+                    | hir::PatKind::Binding(hir::BindingAnnotation::Mutable, _, ident, _) => {
+                        name = Some(ident.name);
+                    }
+                    _ => (),
                 }
             }
 
index b9d6486d9174a9117ca38c11d7aed88c4567fb17..502091e5192012872f41b15386ca76ae26ae4eba 100644 (file)
@@ -541,9 +541,9 @@ pub fn new_source_scope(&mut self,
     /// Finds the breakable scope for a given label. This is used for
     /// resolving `break` and `continue`.
     pub fn find_breakable_scope(&self,
-                           span: Span,
-                           label: region::Scope)
-                           -> &BreakableScope<'tcx> {
+                                span: Span,
+                                label: region::Scope)
+                                -> &BreakableScope<'tcx> {
         // find the loop-scope with the correct id
         self.breakable_scopes.iter()
             .rev()
index 98cd9c35d8809ec9e66a11c9f7c91023ef27381e..e4cae5fe6c8266c2d2f1d2eb639061f7536009e7 100644 (file)
@@ -13,6 +13,7 @@
 use rustc_data_structures::indexed_set::{IdxSet, IdxSetBuf};
 use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::bitslice::{bitwise, BitwiseOperator};
+use rustc_data_structures::work_queue::WorkQueue;
 
 use rustc::ty::{self, TyCtxt};
 use rustc::mir::{self, Mir, BasicBlock, BasicBlockData, Location, Statement, Terminator};
@@ -176,7 +177,6 @@ pub(crate) fn run<P>(self,
 struct PropagationContext<'b, 'a: 'b, 'tcx: 'a, O> where O: 'b + BitDenotation
 {
     builder: &'b mut DataflowAnalysis<'a, 'tcx, O>,
-    changed: bool,
 }
 
 impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation
@@ -185,12 +185,9 @@ fn propagate(&mut self) {
         let mut temp = IdxSetBuf::new_empty(self.flow_state.sets.bits_per_block);
         let mut propcx = PropagationContext {
             builder: self,
-            changed: true,
         };
-        while propcx.changed {
-            propcx.changed = false;
-            propcx.walk_cfg(&mut temp);
-        }
+        propcx.walk_cfg(&mut temp);
+
     }
 
     fn build_sets(&mut self) {
@@ -236,18 +233,20 @@ fn build_sets(&mut self) {
 impl<'b, 'a: 'b, 'tcx: 'a, BD> PropagationContext<'b, 'a, 'tcx, BD> where BD: BitDenotation
 {
     fn walk_cfg(&mut self, in_out: &mut IdxSet<BD::Idx>) {
+        let mut dirty_queue: WorkQueue<mir::BasicBlock> =
+            WorkQueue::with_all(self.builder.mir.basic_blocks().len());
         let mir = self.builder.mir;
-        for (bb_idx, bb_data) in mir.basic_blocks().iter().enumerate() {
-            let builder = &mut self.builder;
+        while let Some(bb) = dirty_queue.pop() {
+            let bb_data = &mir[bb];
             {
-                let sets = builder.flow_state.sets.for_block(bb_idx);
+                let sets = self.builder.flow_state.sets.for_block(bb.index());
                 debug_assert!(in_out.words().len() == sets.on_entry.words().len());
                 in_out.overwrite(sets.on_entry);
                 in_out.union(sets.gen_set);
                 in_out.subtract(sets.kill_set);
             }
-            builder.propagate_bits_into_graph_successors_of(
-                in_out, &mut self.changed, (mir::BasicBlock::new(bb_idx), bb_data));
+            self.builder.propagate_bits_into_graph_successors_of(
+                in_out, (bb, bb_data), &mut dirty_queue);
         }
     }
 }
@@ -806,8 +805,8 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
     fn propagate_bits_into_graph_successors_of(
         &mut self,
         in_out: &mut IdxSet<D::Idx>,
-        changed: &mut bool,
-        (bb, bb_data): (mir::BasicBlock, &mir::BasicBlockData))
+        (bb, bb_data): (mir::BasicBlock, &mir::BasicBlockData),
+        dirty_list: &mut WorkQueue<mir::BasicBlock>)
     {
         match bb_data.terminator().kind {
             mir::TerminatorKind::Return |
@@ -815,59 +814,59 @@ fn propagate_bits_into_graph_successors_of(
             mir::TerminatorKind::Abort |
             mir::TerminatorKind::GeneratorDrop |
             mir::TerminatorKind::Unreachable => {}
-            mir::TerminatorKind::Goto { ref target } |
-            mir::TerminatorKind::Assert { ref target, cleanup: None, .. } |
-            mir::TerminatorKind::Yield { resume: ref target, drop: None, .. } |
-            mir::TerminatorKind::Drop { ref target, location: _, unwind: None } |
+            mir::TerminatorKind::Goto { target } |
+            mir::TerminatorKind::Assert { target, cleanup: None, .. } |
+            mir::TerminatorKind::Yield { resume: target, drop: None, .. } |
+            mir::TerminatorKind::Drop { target, location: _, unwind: None } |
             mir::TerminatorKind::DropAndReplace {
-                ref target, value: _, location: _, unwind: None
+                target, value: _, location: _, unwind: None
             } => {
-                self.propagate_bits_into_entry_set_for(in_out, changed, target);
+                self.propagate_bits_into_entry_set_for(in_out, target, dirty_list);
             }
-            mir::TerminatorKind::Yield { resume: ref target, drop: Some(ref drop), .. } => {
-                self.propagate_bits_into_entry_set_for(in_out, changed, target);
-                self.propagate_bits_into_entry_set_for(in_out, changed, drop);
+            mir::TerminatorKind::Yield { resume: target, drop: Some(drop), .. } => {
+                self.propagate_bits_into_entry_set_for(in_out, target, dirty_list);
+                self.propagate_bits_into_entry_set_for(in_out, drop, dirty_list);
             }
-            mir::TerminatorKind::Assert { ref target, cleanup: Some(ref unwind), .. } |
-            mir::TerminatorKind::Drop { ref target, location: _, unwind: Some(ref unwind) } |
+            mir::TerminatorKind::Assert { target, cleanup: Some(unwind), .. } |
+            mir::TerminatorKind::Drop { target, location: _, unwind: Some(unwind) } |
             mir::TerminatorKind::DropAndReplace {
-                ref target, value: _, location: _, unwind: Some(ref unwind)
+                target, value: _, location: _, unwind: Some(unwind)
             } => {
-                self.propagate_bits_into_entry_set_for(in_out, changed, target);
+                self.propagate_bits_into_entry_set_for(in_out, target, dirty_list);
                 if !self.dead_unwinds.contains(&bb) {
-                    self.propagate_bits_into_entry_set_for(in_out, changed, unwind);
+                    self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list);
                 }
             }
             mir::TerminatorKind::SwitchInt { ref targets, .. } => {
                 for target in targets {
-                    self.propagate_bits_into_entry_set_for(in_out, changed, target);
+                    self.propagate_bits_into_entry_set_for(in_out, *target, dirty_list);
                 }
             }
-            mir::TerminatorKind::Call { ref cleanup, ref destination, func: _, args: _ } => {
-                if let Some(ref unwind) = *cleanup {
+            mir::TerminatorKind::Call { cleanup, ref destination, func: _, args: _ } => {
+                if let Some(unwind) = cleanup {
                     if !self.dead_unwinds.contains(&bb) {
-                        self.propagate_bits_into_entry_set_for(in_out, changed, unwind);
+                        self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list);
                     }
                 }
-                if let Some((ref dest_place, ref dest_bb)) = *destination {
+                if let Some((ref dest_place, dest_bb)) = *destination {
                     // N.B.: This must be done *last*, after all other
                     // propagation, as documented in comment above.
                     self.flow_state.operator.propagate_call_return(
-                        in_out, bb, *dest_bb, dest_place);
-                    self.propagate_bits_into_entry_set_for(in_out, changed, dest_bb);
+                        in_out, bb, dest_bb, dest_place);
+                    self.propagate_bits_into_entry_set_for(in_out, dest_bb, dirty_list);
                 }
             }
-            mir::TerminatorKind::FalseEdges { ref real_target, ref imaginary_targets } => {
-                self.propagate_bits_into_entry_set_for(in_out, changed, real_target);
+            mir::TerminatorKind::FalseEdges { real_target, ref imaginary_targets } => {
+                self.propagate_bits_into_entry_set_for(in_out, real_target, dirty_list);
                 for target in imaginary_targets {
-                    self.propagate_bits_into_entry_set_for(in_out, changed, target);
+                    self.propagate_bits_into_entry_set_for(in_out, *target, dirty_list);
                 }
             }
-            mir::TerminatorKind::FalseUnwind { ref real_target, unwind } => {
-                self.propagate_bits_into_entry_set_for(in_out, changed, real_target);
-                if let Some(ref unwind) = unwind {
+            mir::TerminatorKind::FalseUnwind { real_target, unwind } => {
+                self.propagate_bits_into_entry_set_for(in_out, real_target, dirty_list);
+                if let Some(unwind) = unwind {
                     if !self.dead_unwinds.contains(&bb) {
-                        self.propagate_bits_into_entry_set_for(in_out, changed, unwind);
+                        self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list);
                     }
                 }
             }
@@ -876,14 +875,15 @@ fn propagate_bits_into_graph_successors_of(
 
     fn propagate_bits_into_entry_set_for(&mut self,
                                          in_out: &IdxSet<D::Idx>,
-                                         changed: &mut bool,
-                                         bb: &mir::BasicBlock) {
+                                         bb: mir::BasicBlock,
+                                         dirty_queue: &mut WorkQueue<mir::BasicBlock>) {
         let entry_set = self.flow_state.sets.for_block(bb.index()).on_entry;
         let set_changed = bitwise(entry_set.words_mut(),
                                   in_out.words(),
                                   &self.flow_state.operator);
         if set_changed {
-            *changed = true;
+            dirty_queue.insert(bb);
         }
     }
+
 }
index e04cdcfa02773f520d4d0c1c06b78b133f78b775..18ae7c7745915ad4bab2c9cffceee4566089dc64 100644 (file)
@@ -309,33 +309,32 @@ fn check_irrefutable(&self, pat: &'tcx Pat, origin: &str) {
 fn check_for_bindings_named_the_same_as_variants(cx: &MatchVisitor, pat: &Pat) {
     pat.walk(|p| {
         if let PatKind::Binding(_, _, ident, None) = p.node {
-            let bm = *cx.tables
-                        .pat_binding_modes()
-                        .get(p.hir_id)
-                        .expect("missing binding mode");
-
-            if bm != ty::BindByValue(hir::MutImmutable) {
-                // Nothing to check.
-                return true;
-            }
-            let pat_ty = cx.tables.pat_ty(p);
-            if let ty::TyAdt(edef, _) = pat_ty.sty {
-                if edef.is_enum() && edef.variants.iter().any(|variant| {
-                    variant.name == ident.name && variant.ctor_kind == CtorKind::Const
-                }) {
-                    let ty_path = cx.tcx.item_path_str(edef.did);
-                    let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170,
-                        "pattern binding `{}` is named the same as one \
-                         of the variants of the type `{}`",
-                        ident, ty_path);
-                    err.span_suggestion_with_applicability(
-                        p.span,
-                        "to match on the variant, qualify the path",
-                        format!("{}::{}", ty_path, ident),
-                        Applicability::MachineApplicable
-                    );
-                    err.emit();
+            if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) {
+                if bm != ty::BindByValue(hir::MutImmutable) {
+                    // Nothing to check.
+                    return true;
                 }
+                let pat_ty = cx.tables.pat_ty(p);
+                if let ty::TyAdt(edef, _) = pat_ty.sty {
+                    if edef.is_enum() && edef.variants.iter().any(|variant| {
+                        variant.name == ident.name && variant.ctor_kind == CtorKind::Const
+                    }) {
+                        let ty_path = cx.tcx.item_path_str(edef.did);
+                        let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170,
+                            "pattern binding `{}` is named the same as one \
+                            of the variants of the type `{}`",
+                            ident, ty_path);
+                        err.span_suggestion_with_applicability(
+                            p.span,
+                            "to match on the variant, qualify the path",
+                            format!("{}::{}", ty_path, ident),
+                            Applicability::MachineApplicable
+                        );
+                        err.emit();
+                    }
+                }
+            } else {
+                cx.tcx.sess.delay_span_bug(p.span, "missing binding mode");
             }
         }
         true
@@ -517,12 +516,12 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
     let mut by_ref_span = None;
     for pat in pats {
         pat.each_binding(|_, hir_id, span, _path| {
-            let bm = *cx.tables
-                        .pat_binding_modes()
-                        .get(hir_id)
-                        .expect("missing binding mode");
-            if let ty::BindByReference(..) = bm {
-                by_ref_span = Some(span);
+            if let Some(&bm) = cx.tables.pat_binding_modes().get(hir_id) {
+                if let ty::BindByReference(..) = bm {
+                    by_ref_span = Some(span);
+                }
+            } else {
+                cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode");
             }
         })
     }
@@ -553,18 +552,18 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
     for pat in pats {
         pat.walk(|p| {
             if let PatKind::Binding(_, _, _, ref sub) = p.node {
-                let bm = *cx.tables
-                            .pat_binding_modes()
-                            .get(p.hir_id)
-                            .expect("missing binding mode");
-                match bm {
-                    ty::BindByValue(..) => {
-                        let pat_ty = cx.tables.node_id_to_type(p.hir_id);
-                        if pat_ty.moves_by_default(cx.tcx, cx.param_env, pat.span) {
-                            check_move(p, sub.as_ref().map(|p| &**p));
+                if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) {
+                    match bm {
+                        ty::BindByValue(..) => {
+                            let pat_ty = cx.tables.node_id_to_type(p.hir_id);
+                            if pat_ty.moves_by_default(cx.tcx, cx.param_env, pat.span) {
+                                check_move(p, sub.as_ref().map(|p| &**p));
+                            }
                         }
+                        _ => {}
                     }
-                    _ => {}
+                } else {
+                    cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode");
                 }
             }
             true
index 4d0e3e826e8789f01efa54b5c2328aea90093929..636969e263222d81e942aa9ea847babf0a062343 100644 (file)
@@ -743,8 +743,10 @@ fn lower_lit(&mut self, expr: &'tcx hir::Expr) -> PatternKind<'tcx> {
                         );
                         *self.const_to_pat(instance, val, expr.hir_id, lit.span).kind
                     },
-                    Err(()) => {
-                        self.errors.push(PatternError::FloatBug);
+                    Err(e) => {
+                        if e == LitToConstError::UnparseableFloat {
+                            self.errors.push(PatternError::FloatBug);
+                        }
                         PatternKind::Wild
                     },
                 }
@@ -764,8 +766,10 @@ fn lower_lit(&mut self, expr: &'tcx hir::Expr) -> PatternKind<'tcx> {
                         );
                         *self.const_to_pat(instance, val, expr.hir_id, lit.span).kind
                     },
-                    Err(()) => {
-                        self.errors.push(PatternError::FloatBug);
+                    Err(e) => {
+                        if e == LitToConstError::UnparseableFloat {
+                            self.errors.push(PatternError::FloatBug);
+                        }
                         PatternKind::Wild
                     },
                 }
@@ -1118,12 +1122,18 @@ pub fn compare_const_vals<'a, 'tcx>(
     fallback()
 }
 
+#[derive(PartialEq)]
+enum LitToConstError {
+    UnparseableFloat,
+    Propagated,
+}
+
 // FIXME: Combine with rustc_mir::hair::cx::const_eval_literal
 fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind,
                           tcx: TyCtxt<'a, 'tcx, 'tcx>,
                           ty: Ty<'tcx>,
                           neg: bool)
-                          -> Result<&'tcx ty::Const<'tcx>, ()> {
+                          -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
     use syntax::ast::*;
 
     use rustc::mir::interpret::*;
@@ -1152,7 +1162,10 @@ enum Int {
                 ty::TyInt(other) => Int::Signed(other),
                 ty::TyUint(UintTy::Usize) => Int::Unsigned(tcx.sess.target.usize_ty),
                 ty::TyUint(other) => Int::Unsigned(other),
-                _ => bug!(),
+                ty::TyError => { // Avoid ICE (#51963)
+                    return Err(LitToConstError::Propagated);
+                }
+                _ => bug!("literal integer type with bad type ({:?})", ty.sty),
             };
             // This converts from LitKind::Int (which is sign extended) to
             // Scalar::Bytes (which is zero extended)
@@ -1182,14 +1195,14 @@ enum Int {
             })
         },
         LitKind::Float(n, fty) => {
-            parse_float(n, fty, neg)?
+            parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
         }
         LitKind::FloatUnsuffixed(n) => {
             let fty = match ty.sty {
                 ty::TyFloat(fty) => fty,
                 _ => bug!()
             };
-            parse_float(n, fty, neg)?
+            parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
         }
         LitKind::Bool(b) => ConstValue::Scalar(Scalar::Bits {
             bits: b as u128,
index 749c0d04ae91f71a19f138287626e4b6a654e784..ea09bab5d1411f3a444a606522c928dc58062628 100644 (file)
@@ -1,3 +1,6 @@
+use std::fmt;
+use std::error::Error;
+
 use rustc::hir;
 use rustc::mir::interpret::{ConstEvalErr};
 use rustc::mir;
@@ -15,9 +18,6 @@
 };
 use super::{Place, EvalContext, StackPopCleanup, ValTy, PlaceExtra, Memory, MemoryKind};
 
-use std::fmt;
-use std::error::Error;
-
 pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     instance: Instance<'tcx>,
@@ -152,7 +152,7 @@ fn eval_body_using_ecx<'a, 'mir, 'tcx>(
     let ptr = ecx.memory.allocate(
         layout.size,
         layout.align,
-        None,
+        MemoryKind::Stack,
     )?;
     let internally_mutable = !layout.ty.is_freeze(tcx, param_env, mir.span);
     let is_static = tcx.is_static(cid.instance.def_id());
@@ -486,7 +486,7 @@ pub fn const_variant_index<'a, 'tcx>(
     let (ptr, align) = match value {
         Value::ScalarPair(..) | Value::Scalar(_) => {
             let layout = ecx.layout_of(val.ty)?;
-            let ptr = ecx.memory.allocate(layout.size, layout.align, Some(MemoryKind::Stack))?.into();
+            let ptr = ecx.memory.allocate(layout.size, layout.align, MemoryKind::Stack)?.into();
             ecx.write_value_to_ptr(value, ptr, layout.align, val.ty)?;
             (ptr, layout.align)
         },
@@ -515,7 +515,7 @@ pub fn const_value_to_allocation_provider<'a, 'tcx>(
             ());
         let value = ecx.const_to_value(val.val)?;
         let layout = ecx.layout_of(val.ty)?;
-        let ptr = ecx.memory.allocate(layout.size, layout.align, Some(MemoryKind::Stack))?;
+        let ptr = ecx.memory.allocate(layout.size, layout.align, MemoryKind::Stack)?;
         ecx.write_value_to_ptr(value, ptr.into(), layout.align, val.ty)?;
         let alloc = ecx.memory.get(ptr.alloc_id)?;
         Ok(tcx.intern_const_alloc(alloc.clone()))
index 15d8b9c36215a990ece3e7f18108a1f925b81ead..031c75013a27b00c684d2e371838c9f868546b47 100644 (file)
@@ -1,4 +1,5 @@
 use std::fmt::Write;
+use std::mem;
 
 use rustc::hir::def_id::DefId;
 use rustc::hir::def::Def;
 use rustc::ty::{self, Ty, TyCtxt, TypeAndMut};
 use rustc::ty::query::TyCtxtAt;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
-use rustc::mir::interpret::FrameInfo;
-use syntax::codemap::{self, Span};
-use syntax::ast::Mutability;
 use rustc::mir::interpret::{
-    GlobalId, Value, Scalar,
+    FrameInfo, GlobalId, Value, Scalar,
     EvalResult, EvalErrorKind, Pointer, ConstValue,
 };
-use std::mem;
+
+use syntax::codemap::{self, Span};
+use syntax::ast::Mutability;
 
 use super::{Place, PlaceExtra, Memory,
             HasMemory, MemoryKind,
@@ -206,7 +206,7 @@ pub fn alloc_ptr(&mut self, ty: Ty<'tcx>) -> EvalResult<'tcx, Pointer> {
         let layout = self.layout_of(ty)?;
         assert!(!layout.is_unsized(), "cannot alloc memory for unsized type");
 
-        self.memory.allocate(layout.size, layout.align, Some(MemoryKind::Stack))
+        self.memory.allocate(layout.size, layout.align, MemoryKind::Stack)
     }
 
     pub fn memory(&self) -> &Memory<'a, 'mir, 'tcx, M> {
@@ -246,7 +246,7 @@ pub fn const_to_value(
             }
             ConstValue::ByRef(alloc, offset) => {
                 // FIXME: Allocate new AllocId for all constants inside
-                let id = self.memory.allocate_value(alloc.clone(), Some(MemoryKind::Stack))?;
+                let id = self.memory.allocate_value(alloc.clone(), MemoryKind::Stack)?;
                 Ok(Value::ByRef(Pointer::new(id, offset).into(), alloc.align))
             },
             ConstValue::ScalarPair(a, b) => Ok(Value::ScalarPair(a, b)),
index f5da65ae44db7b4bc6bb8a12b23d2004c4f91d74..5cf734cce8a3f780f3aab248a3b05b41add99975 100644 (file)
@@ -6,12 +6,12 @@
 use rustc::ty::ParamEnv;
 use rustc::ty::query::TyCtxtAt;
 use rustc::ty::layout::{self, Align, TargetDataLayout, Size};
-use syntax::ast::Mutability;
-
-use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 use rustc::mir::interpret::{Pointer, AllocId, Allocation, AccessKind, Value,
                             EvalResult, Scalar, EvalErrorKind, GlobalId, AllocType};
 pub use rustc::mir::interpret::{write_target_uint, write_target_int, read_target_uint};
+use rustc_data_structures::fx::{FxHashSet, FxHashMap};
+
+use syntax::ast::Mutability;
 
 use super::{EvalContext, Machine};
 
@@ -41,11 +41,6 @@ pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
     /// Actual memory allocations (arbitrary bytes, may contain pointers into other allocations).
     alloc_map: FxHashMap<AllocId, Allocation>,
 
-    /// Actual memory allocations (arbitrary bytes, may contain pointers into other allocations).
-    ///
-    /// Stores statics while they are being processed, before they are interned and thus frozen
-    uninitialized_statics: FxHashMap<AllocId, Allocation>,
-
     /// The current stack frame.  Used to check accesses against locks.
     pub cur_frame: usize,
 
@@ -58,7 +53,6 @@ pub fn new(tcx: TyCtxtAt<'a, 'tcx, 'tcx>, data: M::MemoryData) -> Self {
             data,
             alloc_kind: FxHashMap::default(),
             alloc_map: FxHashMap::default(),
-            uninitialized_statics: FxHashMap::default(),
             tcx,
             cur_frame: usize::max_value(),
         }
@@ -82,20 +76,12 @@ pub fn allocate_bytes(&mut self, bytes: &[u8]) -> Pointer {
     pub fn allocate_value(
         &mut self,
         alloc: Allocation,
-        kind: Option<MemoryKind<M::MemoryKinds>>,
+        kind: MemoryKind<M::MemoryKinds>,
     ) -> EvalResult<'tcx, AllocId> {
         let id = self.tcx.alloc_map.lock().reserve();
         M::add_lock(self, id);
-        match kind {
-            Some(kind @ MemoryKind::Stack) |
-            Some(kind @ MemoryKind::Machine(_)) => {
-                self.alloc_map.insert(id, alloc);
-                self.alloc_kind.insert(id, kind);
-            },
-            None => {
-                self.uninitialized_statics.insert(id, alloc);
-            },
-        }
+        self.alloc_map.insert(id, alloc);
+        self.alloc_kind.insert(id, kind);
         Ok(id)
     }
 
@@ -104,7 +90,7 @@ pub fn allocate(
         &mut self,
         size: Size,
         align: Align,
-        kind: Option<MemoryKind<M::MemoryKinds>>,
+        kind: MemoryKind<M::MemoryKinds>,
     ) -> EvalResult<'tcx, Pointer> {
         self.allocate_value(Allocation::undef(size, align), kind).map(Pointer::from)
     }
@@ -132,7 +118,7 @@ pub fn reallocate(
         }
 
         // For simplicities' sake, we implement reallocate as "alloc, copy, dealloc"
-        let new_ptr = self.allocate(new_size, new_align, Some(kind))?;
+        let new_ptr = self.allocate(new_size, new_align, kind)?;
         self.copy(
             ptr.into(),
             old_align,
@@ -168,12 +154,7 @@ pub fn deallocate(
 
         let alloc = match self.alloc_map.remove(&ptr.alloc_id) {
             Some(alloc) => alloc,
-            None => if self.uninitialized_statics.contains_key(&ptr.alloc_id) {
-                return err!(DeallocatedWrongMemoryKind(
-                    "uninitializedstatic".to_string(),
-                    format!("{:?}", kind),
-                ))
-            } else {
+            None => {
                 return match self.tcx.alloc_map.lock().get(ptr.alloc_id) {
                     Some(AllocType::Function(..)) => err!(DeallocatedWrongMemoryKind(
                         "function".to_string(),
@@ -299,24 +280,21 @@ fn const_eval_static(&self, def_id: DefId) -> EvalResult<'tcx, &'tcx Allocation>
     pub fn get(&self, id: AllocId) -> EvalResult<'tcx, &Allocation> {
         // normal alloc?
         match self.alloc_map.get(&id) {
-                    Some(alloc) => Ok(alloc),
+            Some(alloc) => Ok(alloc),
             // uninitialized static alloc?
-            None => match self.uninitialized_statics.get(&id) {
-                Some(alloc) => Ok(alloc),
-                None => {
-                    // static alloc?
-                    let alloc = self.tcx.alloc_map.lock().get(id);
-                    match alloc {
-                        Some(AllocType::Memory(mem)) => Ok(mem),
-                        Some(AllocType::Function(..)) => {
-                            Err(EvalErrorKind::DerefFunctionPointer.into())
-                        }
-                        Some(AllocType::Static(did)) => {
-                            self.const_eval_static(did)
-                        }
-                        None => Err(EvalErrorKind::DanglingPointerDeref.into()),
+            None => {
+                // static alloc?
+                let alloc = self.tcx.alloc_map.lock().get(id);
+                match alloc {
+                    Some(AllocType::Memory(mem)) => Ok(mem),
+                    Some(AllocType::Function(..)) => {
+                        Err(EvalErrorKind::DerefFunctionPointer.into())
+                    }
+                    Some(AllocType::Static(did)) => {
+                        self.const_eval_static(did)
                     }
-                },
+                    None => Err(EvalErrorKind::DanglingPointerDeref.into()),
+                }
             },
         }
     }
@@ -329,17 +307,14 @@ fn get_mut(
         match self.alloc_map.get_mut(&id) {
             Some(alloc) => Ok(alloc),
             // uninitialized static alloc?
-            None => match self.uninitialized_statics.get_mut(&id) {
-                Some(alloc) => Ok(alloc),
-                None => {
-                    // no alloc or immutable alloc? produce an error
-                    match self.tcx.alloc_map.lock().get(id) {
-                        Some(AllocType::Memory(..)) |
-                        Some(AllocType::Static(..)) => err!(ModifiedConstantMemory),
-                        Some(AllocType::Function(..)) => err!(DerefFunctionPointer),
-                        None => err!(DanglingPointerDeref),
-                    }
-                },
+            None => {
+                // no alloc or immutable alloc? produce an error
+                match self.tcx.alloc_map.lock().get(id) {
+                    Some(AllocType::Memory(..)) |
+                    Some(AllocType::Static(..)) => err!(ModifiedConstantMemory),
+                    Some(AllocType::Function(..)) => err!(DerefFunctionPointer),
+                    None => err!(DanglingPointerDeref),
+                }
             },
         }
     }
@@ -390,27 +365,23 @@ pub fn dump_allocs(&self, mut allocs: Vec<AllocId>) {
                         MemoryKind::Stack => " (stack)".to_owned(),
                         MemoryKind::Machine(m) => format!(" ({:?})", m),
                     }),
-                    // uninitialized static alloc?
-                    None => match self.uninitialized_statics.get(&id) {
-                        Some(a) => (a, " (static in the process of initialization)".to_owned()),
-                        None => {
-                            // static alloc?
-                            match self.tcx.alloc_map.lock().get(id) {
-                                Some(AllocType::Memory(a)) => (a, "(immutable)".to_owned()),
-                                Some(AllocType::Function(func)) => {
-                                    trace!("{} {}", msg, func);
-                                    continue;
-                                }
-                                Some(AllocType::Static(did)) => {
-                                    trace!("{} {:?}", msg, did);
-                                    continue;
-                                }
-                                None => {
-                                    trace!("{} (deallocated)", msg);
-                                    continue;
-                                }
+                    None => {
+                        // static alloc?
+                        match self.tcx.alloc_map.lock().get(id) {
+                            Some(AllocType::Memory(a)) => (a, "(immutable)".to_owned()),
+                            Some(AllocType::Function(func)) => {
+                                trace!("{} {}", msg, func);
+                                continue;
                             }
-                        },
+                            Some(AllocType::Static(did)) => {
+                                trace!("{} {:?}", msg, did);
+                                continue;
+                            }
+                            None => {
+                                trace!("{} (deallocated)", msg);
+                                continue;
+                            }
+                        }
                     },
                 };
 
@@ -569,8 +540,7 @@ pub fn mark_static_initialized(
             Some(MemoryKind::Machine(_)) => bug!("machine didn't handle machine alloc"),
             Some(MemoryKind::Stack) => {},
         }
-        let uninit = self.uninitialized_statics.remove(&alloc_id);
-        if let Some(mut alloc) = alloc.or(uninit) {
+        if let Some(mut alloc) = alloc {
             // ensure llvm knows not to put this into immutable memroy
             alloc.runtime_mutability = mutability;
             let alloc = self.tcx.intern_const_alloc(alloc);
index 373a0b0d0bfedb75ffa80057d1ccbead6d870257..b6c7feda19fa813377fff50213a3b046deb3b96c 100644 (file)
@@ -1,9 +1,10 @@
 use rustc::ty::{self, Ty};
 use rustc::ty::layout::{Size, Align, LayoutOf};
+use rustc::mir::interpret::{Scalar, Value, Pointer, EvalResult};
+
 use syntax::ast::Mutability;
 
-use rustc::mir::interpret::{Scalar, Value, Pointer, EvalResult};
-use super::{EvalContext, Machine};
+use super::{EvalContext, Machine, MemoryKind};
 
 impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
     /// Creates a dynamic vtable for the given type and vtable origin. This is used only for
@@ -30,7 +31,7 @@ pub fn get_vtable(
         let vtable = self.memory.allocate(
             ptr_size * (3 + methods.len() as u64),
             ptr_align,
-            None,
+            MemoryKind::Stack,
         )?;
 
         let drop = ::monomorphize::resolve_drop_in_place(*self.tcx, ty);
index 3a046cd800a3e1db0419999a10f86ed804c40d61..09c5df000526031de3d68087af39aaa5a887bce4 100644 (file)
@@ -395,15 +395,8 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             };
             let param_env = ty::ParamEnv::reveal_all();
 
-            match tcx.const_eval(param_env.and(cid)) {
-                Ok(val) => collect_const(tcx, val, instance.substs, &mut neighbors),
-                Err(err) => {
-                    let span = tcx.def_span(def_id);
-                    err.report_as_error(
-                        tcx.at(span),
-                        "could not evaluate static initializer",
-                    );
-                }
+            if let Ok(val) = tcx.const_eval(param_env.and(cid)) {
+                collect_const(tcx, val, instance.substs, &mut neighbors);
             }
         }
         MonoItem::Fn(instance) => {
index 34f8141141d26180740b99793f62f1150cb38d91..e1d5e302c3a062fad7142faec591004c7802a1f1 100644 (file)
@@ -37,6 +37,7 @@
 use rustc::mir::visit::{PlaceContext, Visitor};
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 use rustc_data_structures::indexed_set::IdxSetBuf;
+use rustc_data_structures::work_queue::WorkQueue;
 use util::pretty::{dump_enabled, write_basic_block, write_mir_intro};
 use rustc::ty::item_path;
 use rustc::mir::visit::MirVisitable;
@@ -55,9 +56,6 @@ pub struct LivenessResult {
     /// Liveness mode in use when these results were computed.
     pub mode: LivenessMode,
 
-    /// Live variables on entry to each basic block.
-    pub ins: IndexVec<BasicBlock, LocalSet>,
-
     /// Live variables on exit to each basic block. This is equal to
     /// the union of the `ins` for each successor.
     pub outs: IndexVec<BasicBlock, LocalSet>,
@@ -124,37 +122,38 @@ pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>, mode: LivenessMode) -> Liveness
         .map(|b| block(mode, b, locals))
         .collect();
 
-    let mut ins: IndexVec<_, _> = mir.basic_blocks()
+    let mut outs: IndexVec<_, _> = mir.basic_blocks()
         .indices()
         .map(|_| LocalSet::new_empty(locals))
         .collect();
-    let mut outs = ins.clone();
 
-    let mut changed = true;
     let mut bits = LocalSet::new_empty(locals);
-    while changed {
-        changed = false;
-
-        for b in mir.basic_blocks().indices().rev() {
-            // outs[b] = âˆª {ins of successors}
-            bits.clear();
-            for &successor in mir.basic_blocks()[b].terminator().successors() {
-                bits.union(&ins[successor]);
-            }
-            outs[b].overwrite(&bits);
 
-            // bits = use âˆª (bits - def)
-            def_use[b].apply(&mut bits);
+    // queue of things that need to be re-processed, and a set containing
+    // the things currently in the queue
+    let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_all(mir.basic_blocks().len());
+
+    let predecessors = mir.predecessors();
 
-            // update bits on entry and flag if they have changed
-            if ins[b] != bits {
-                ins[b].overwrite(&bits);
-                changed = true;
+    while let Some(bb) = dirty_queue.pop() {
+        // bits = use âˆª (bits - def)
+        bits.overwrite(&outs[bb]);
+        def_use[bb].apply(&mut bits);
+
+        // `bits` now contains the live variables on entry. Therefore,
+        // add `bits` to the `out` set for each predecessor; if those
+        // bits were not already present, then enqueue the predecessor
+        // as dirty.
+        //
+        // (note that `union` returns true if the `self` set changed)
+        for &pred_bb in &predecessors[bb] {
+            if outs[pred_bb].union(&bits) {
+                dirty_queue.insert(pred_bb);
             }
         }
     }
 
-    LivenessResult { mode, ins, outs }
+    LivenessResult { mode, outs }
 }
 
 impl LivenessResult {
@@ -180,29 +179,6 @@ pub fn simulate_block<'tcx, OP>(&self, mir: &Mir<'tcx>, block: BasicBlock, mut c
             block,
             statement_index,
         };
-        let terminator_defs_uses = self.defs_uses(mir, terminator_location, &data.terminator);
-        terminator_defs_uses.apply(&mut bits);
-        callback(terminator_location, &bits);
-
-        // Compute liveness before each statement (in rev order) and invoke callback.
-        for statement in data.statements.iter().rev() {
-            statement_index -= 1;
-            let statement_location = Location {
-                block,
-                statement_index,
-            };
-            let statement_defs_uses = self.defs_uses(mir, statement_location, statement);
-            statement_defs_uses.apply(&mut bits);
-            callback(statement_location, &bits);
-        }
-
-        assert_eq!(bits, self.ins[block]);
-    }
-
-    fn defs_uses<'tcx, V>(&self, mir: &Mir<'tcx>, location: Location, thing: &V) -> DefsUses
-    where
-        V: MirVisitable<'tcx>,
-    {
         let locals = mir.local_decls.len();
         let mut visitor = DefsUsesVisitor {
             mode: self.mode,
@@ -211,12 +187,22 @@ fn defs_uses<'tcx, V>(&self, mir: &Mir<'tcx>, location: Location, thing: &V) ->
                 uses: LocalSet::new_empty(locals),
             },
         };
-
         // Visit the various parts of the basic block in reverse. If we go
         // forward, the logic in `add_def` and `add_use` would be wrong.
-        thing.apply(location, &mut visitor);
+        visitor.update_bits_and_do_callback(terminator_location, &data.terminator, &mut bits,
+                                            &mut callback);
 
-        visitor.defs_uses
+        // Compute liveness before each statement (in rev order) and invoke callback.
+        for statement in data.statements.iter().rev() {
+            statement_index -= 1;
+            let statement_location = Location {
+                block,
+                statement_index,
+            };
+            visitor.defs_uses.clear();
+            visitor.update_bits_and_do_callback(statement_location, statement, &mut bits,
+                                                &mut callback);
+        }
     }
 }
 
@@ -307,6 +293,11 @@ struct DefsUses {
 }
 
 impl DefsUses {
+    fn clear(&mut self) {
+        self.uses.clear();
+        self.defs.clear();
+    }
+
     fn apply(&self, bits: &mut LocalSet) -> bool {
         bits.subtract(&self.defs) | bits.union(&self.uses)
     }
@@ -341,6 +332,22 @@ fn add_use(&mut self, index: Local) {
     }
 }
 
+impl DefsUsesVisitor {
+    /// Update `bits` with the effects of `value` and call `callback`. We
+    /// should always visit in reverse order. This method assumes that we have
+    /// not visited anything before; if you have, clear `bits` first.
+    fn update_bits_and_do_callback<'tcx, OP>(&mut self, location: Location,
+                                             value: &impl MirVisitable<'tcx>, bits: &mut LocalSet,
+                                             callback: &mut OP)
+    where
+        OP: FnMut(Location, &LocalSet),
+    {
+        value.apply(location, self);
+        self.defs_uses.apply(bits);
+        callback(location, bits);
+    }
+}
+
 impl<'tcx> Visitor<'tcx> for DefsUsesVisitor {
     fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
         match categorize(context, self.mode) {
@@ -438,7 +445,6 @@ pub fn write_mir_fn<'a, 'tcx>(
                 .collect();
             writeln!(w, "{} {{{}}}", prefix, live.join(", "))
         };
-        print(w, "   ", &result.ins)?;
         write_basic_block(tcx, block, mir, &mut |_, _| Ok(()), w)?;
         print(w, "   ", &result.outs)?;
         if block.index() + 1 != mir.basic_blocks().len() {
index 8176c644dd7457b392b1fd07a62af275cd304e24..6472e588bc6219053a8b30881129b14eb85be6c3 100644 (file)
@@ -44,6 +44,9 @@ pub enum PassWhere {
 
     /// We just dumped the given statement or terminator.
     AfterLocation(Location),
+
+    /// We just dumped the terminator for a block but not the closing `}`.
+    AfterTerminator(BasicBlock),
 }
 
 /// If the session is properly configured, dumps a human-readable
@@ -351,6 +354,7 @@ pub fn write_basic_block<'cx, 'gcx, 'tcx, F>(
     })?;
 
     extra_data(PassWhere::AfterLocation(current_location), w)?;
+    extra_data(PassWhere::AfterTerminator(block), w)?;
 
     writeln!(w, "{}}}", INDENT)
 }
index c99f1e9da439f04ce9b3133814123ed977511745..eff0dbe1235ff85d75cd7cb43b7c585ca12efc13 100644 (file)
@@ -17,7 +17,7 @@
 use syntax::ast;
 use syntax_pos::Span;
 
-#[derive(Clone, Copy, PartialEq)]
+#[derive(Clone, Copy, Debug, PartialEq)]
 enum LoopKind {
     Loop(hir::LoopSource),
     WhileLoop,
@@ -34,12 +34,13 @@ fn name(self) -> &'static str {
     }
 }
 
-#[derive(Clone, Copy, PartialEq)]
+#[derive(Clone, Copy, Debug, PartialEq)]
 enum Context {
     Normal,
     Loop(LoopKind),
     Closure,
     LabeledBlock,
+    AnonConst,
 }
 
 #[derive(Copy, Clone)]
@@ -71,6 +72,10 @@ fn visit_impl_item(&mut self, i: &'hir hir::ImplItem) {
         self.with_context(Normal, |v| intravisit::walk_impl_item(v, i));
     }
 
+    fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) {
+        self.with_context(AnonConst, |v| intravisit::walk_anon_const(v, c));
+    }
+
     fn visit_expr(&mut self, e: &'hir hir::Expr) {
         match e.node {
             hir::ExprWhile(ref e, ref b, _) => {
@@ -194,7 +199,7 @@ fn require_break_cx(&self, name: &str, span: Span) {
                 .span_label(span, "cannot break inside of a closure")
                 .emit();
             }
-            Normal => {
+            Normal | AnonConst => {
                 struct_span_err!(self.sess, span, E0268, "`{}` outside of loop", name)
                 .span_label(span, "cannot break outside of a loop")
                 .emit();
index c55d57cb91631e8a30a95c5a7ad6ff00350ccac8..3919ba13076f6d839426226056ca2e904b720314 100644 (file)
@@ -229,8 +229,12 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
             hir::ItemUse(..) => {}
             // The interface is empty
             hir::ItemGlobalAsm(..) => {}
-            // Checked by visit_ty
-            hir::ItemExistential(..) => {}
+            hir::ItemExistential(..) => {
+                if item_level.is_some() {
+                    // Reach the (potentially private) type and the API being exposed
+                    self.reach(item.id).ty().predicates();
+                }
+            }
             // Visit everything
             hir::ItemConst(..) | hir::ItemStatic(..) |
             hir::ItemFn(..) | hir::ItemTy(..) => {
@@ -390,17 +394,6 @@ fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
             module_id = self.tcx.hir.get_parent_node(module_id);
         }
     }
-
-    fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
-        if let hir::TyImplTraitExistential(item_id, _, _) = ty.node {
-            if self.get(item_id.id).is_some() {
-                // Reach the (potentially private) type and the API being exposed
-                self.reach(item_id.id).ty().predicates();
-            }
-        }
-
-        intravisit::walk_ty(self, ty);
-    }
 }
 
 impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
@@ -1568,8 +1561,15 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
             hir::ItemUse(..) => {}
             // No subitems
             hir::ItemGlobalAsm(..) => {}
-            // Checked in visit_ty
-            hir::ItemExistential(..) => {}
+            hir::ItemExistential(..) => {
+                // Check the traits being exposed, as they're separate,
+                // e.g. `impl Iterator<Item=T>` has two predicates,
+                // `X: Iterator` and `<X as Iterator>::Item == T`,
+                // where `X` is the `impl Iterator<Item=T>` itself,
+                // stored in `predicates_of`, not in the `Ty` itself.
+
+                self.check(item.id, self.inner_visibility).predicates();
+            }
             // Subitems of these items have inherited publicity
             hir::ItemConst(..) | hir::ItemStatic(..) | hir::ItemFn(..) |
             hir::ItemTy(..) => {
@@ -1667,20 +1667,6 @@ fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) {
         // handled in `visit_item` above
     }
 
-    fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
-        if let hir::TyImplTraitExistential(ref exist_item, _, _) = ty.node {
-            // Check the traits being exposed, as they're separate,
-            // e.g. `impl Iterator<Item=T>` has two predicates,
-            // `X: Iterator` and `<X as Iterator>::Item == T`,
-            // where `X` is the `impl Iterator<Item=T>` itself,
-            // stored in `predicates_of`, not in the `Ty` itself.
-
-            self.check(exist_item.id, self.inner_visibility).predicates();
-        }
-
-        intravisit::walk_ty(self, ty);
-    }
-
     // Don't recurse into expressions in array sizes or const initializers
     fn visit_expr(&mut self, _: &'tcx hir::Expr) {}
     // Don't recurse into patterns in function arguments
index e54cd773123c8e5b7b5d88ad4a2118d7ee2dd6ee..49639915ee11585a45dd4952a8f25ee3274b66b1 100644 (file)
@@ -274,6 +274,7 @@ fn $module() {
     ("powerpc-unknown-linux-gnuspe", powerpc_unknown_linux_gnuspe),
     ("powerpc64-unknown-linux-gnu", powerpc64_unknown_linux_gnu),
     ("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu),
+    ("powerpc64le-unknown-linux-musl", powerpc64le_unknown_linux_musl),
     ("s390x-unknown-linux-gnu", s390x_unknown_linux_gnu),
     ("sparc-unknown-linux-gnu", sparc_unknown_linux_gnu),
     ("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu),
diff --git a/src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs b/src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs
new file mode 100644 (file)
index 0000000..34ec824
--- /dev/null
@@ -0,0 +1,35 @@
+// 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.
+
+use spec::{LinkerFlavor, Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::linux_musl_base::opts();
+    base.cpu = "ppc64le".to_string();
+    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
+    base.max_atomic_width = Some(64);
+
+    // see #36994
+    base.exe_allocation_crate = None;
+
+    Ok(Target {
+        llvm_target: "powerpc64le-unknown-linux-musl".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-i64:64-n32:64".to_string(),
+        arch: "powerpc64".to_string(),
+        target_os: "linux".to_string(),
+        target_env: "musl".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+        options: base,
+    })
+}
index 56170bbb869f31e8d3cec75b7e072ae8976fde6d..6f51495bae9d6211a3150cd2ef5ca4871732163a 100644 (file)
@@ -51,6 +51,9 @@ pub fn target() -> Result<Target, String> {
         // no dynamic linking, no need for default visibility!
         default_hidden_visibility: true,
 
+        // we use the LLD shipped with the Rust toolchain by default
+        linker: Some("rust-lld".to_owned()),
+
         .. Default::default()
     };
     Ok(Target {
index 214376b2e532b14a406e1d8854c23c4cb6d64241..27daebbf8c12d4b9cf90720b8f9f3f13f9cca298 100644 (file)
@@ -15,7 +15,6 @@
 use rustc::traits::{Clause, Clauses, DomainGoal, Goal, PolyDomainGoal, ProgramClause,
                     WhereClause, FromEnv, WellFormed};
 use rustc::ty::query::Providers;
-use rustc::ty::subst::Substs;
 use rustc::ty::{self, Slice, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
 use std::mem;
@@ -225,10 +224,7 @@ fn program_clauses_for_trait<'a, 'tcx>(
 
     // `Self: Trait<P1..Pn>`
     let trait_pred = ty::TraitPredicate {
-        trait_ref: ty::TraitRef {
-            def_id,
-            substs: Substs::identity_for_item(tcx, def_id),
-        },
+        trait_ref: ty::TraitRef::identity(tcx, def_id),
     };
 
     // `Implemented(Self: Trait<P1..Pn>)`
@@ -256,10 +252,8 @@ fn program_clauses_for_trait<'a, 'tcx>(
     // ```
 
     // `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`, for each where clause WC
-    // FIXME: Remove the [1..] slice; this is a hack because the query
-    // predicates_of currently includes the trait itself (`Self: Trait<P1..Pn>`).
-    let where_clauses = &tcx.predicates_of(def_id).predicates;
-    let implied_bound_clauses = where_clauses[1..]
+    let where_clauses = &tcx.predicates_defined_on(def_id).predicates;
+    let implied_bound_clauses = where_clauses
         .into_iter()
         .map(|wc| wc.lower())
 
index 762dc5d26f5a4f3a02972740a0b3b8580f763c21..2e467d315bedd7d7baf21a8f6b15955be39307f3 100644 (file)
@@ -1095,6 +1095,11 @@ pub fn def_to_ty(&self,
                     hir::TyStr => tcx.mk_str()
                 }
             }
+            Def::Existential(exist_ty_did) => {
+                assert!(exist_ty_did.is_local());
+                let lifetimes = &path.segments[0].args.as_ref().unwrap().args;
+                self.impl_trait_ty_to_ty(exist_ty_did, lifetimes)
+            }
             Def::Err => {
                 self.set_tainted_by_errors();
                 return self.tcx().types.err;
@@ -1140,9 +1145,6 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
             hir::TyTraitObject(ref bounds, ref lifetime) => {
                 self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
             }
-            hir::TyImplTraitExistential(_, def_id, ref lifetimes) => {
-                self.impl_trait_ty_to_ty(def_id, lifetimes)
-            }
             hir::TyPath(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
                 debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
                 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
@@ -1195,7 +1197,7 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
     pub fn impl_trait_ty_to_ty(
         &self,
         def_id: DefId,
-        lifetimes: &[hir::Lifetime],
+        lifetimes: &[hir::GenericArg],
     ) -> Ty<'tcx> {
         debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes);
         let tcx = self.tcx();
@@ -1208,7 +1210,11 @@ pub fn impl_trait_ty_to_ty(
                 // Our own parameters are the resolved lifetimes.
                 match param.kind {
                     GenericParamDefKind::Lifetime => {
-                        self.ast_region_to_region(&lifetimes[i], None).into()
+                        if let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] {
+                            self.ast_region_to_region(lifetime, None).into()
+                        } else {
+                            bug!()
+                        }
                     }
                     _ => bug!()
                 }
index 08d8dd2e498b68ff67c437929978b883bd124abe..aee64ad3b550c11cd42d951bf556f254f9843fae 100644 (file)
@@ -264,9 +264,11 @@ pub fn check_ref(&self,
                 (&ty::TyStr, &ty::TySlice(arr)) if arr == self.tcx.types.u8 => {
                     if let hir::ExprLit(_) = expr.node {
                         if let Ok(src) = cm.span_to_snippet(sp) {
-                            return Some((sp,
-                                         "consider removing the leading `b`",
-                                         src[1..].to_string()));
+                            if src.starts_with("b\"") {
+                                return Some((sp,
+                                             "consider removing the leading `b`",
+                                             src[1..].to_string()));
+                            }
                         }
                     }
                 },
@@ -274,9 +276,11 @@ pub fn check_ref(&self,
                 (&ty::TySlice(arr), &ty::TyStr) if arr == self.tcx.types.u8 => {
                     if let hir::ExprLit(_) = expr.node {
                         if let Ok(src) = cm.span_to_snippet(sp) {
-                            return Some((sp,
-                                         "consider adding a leading `b`",
-                                         format!("b{}", src)));
+                            if src.starts_with("\"") {
+                                return Some((sp,
+                                             "consider adding a leading `b`",
+                                             format!("b{}", src)));
+                            }
                         }
                     }
                 }
index fa78b38dbb7a84da4b2a36953ac26db3ec91b33d..646c4f17568f05c3aab5e20b309d7ff14c58b7ff 100644 (file)
@@ -3827,7 +3827,10 @@ fn check_expr_kind(&self,
                     // this can only happen if the `break` was not
                     // inside a loop at all, which is caught by the
                     // loop-checking pass.
-                    assert!(self.tcx.sess.err_count() > 0);
+                    if self.tcx.sess.err_count() == 0 {
+                        self.tcx.sess.delay_span_bug(expr.span,
+                            "break was outside loop, but no error was emitted");
+                    }
 
                     // We still need to assign a type to the inner expression to
                     // prevent the ICE in #43162.
@@ -3960,7 +3963,10 @@ fn check_expr_kind(&self,
                 // is nil. This makes sense because infinite loops
                 // (which would have type !) are only possible iff we
                 // permit break with a value [1].
-                assert!(ctxt.coerce.is_some() || ctxt.may_break); // [1]
+                if ctxt.coerce.is_none() && !ctxt.may_break {
+                    // [1]
+                    self.tcx.sess.delay_span_bug(body.span, "no coercion, but loop may not break");
+                }
                 ctxt.coerce.map(|c| c.complete(self)).unwrap_or(self.tcx.mk_nil())
             }
             hir::ExprMatch(ref discrim, ref arms, match_src) => {
index f6fcf2fcd48253c2c1cf2534f59feb5dd5f2cbac..68fcde0b1657aa5ed983e7fb371eec3fd1bb0b49 100644 (file)
@@ -1018,7 +1018,7 @@ fn link_fn_args(&self, body_scope: region::Scope, args: &[hir::Arg]) {
             let arg_ty = self.node_ty(arg.hir_id);
             let re_scope = self.tcx.mk_region(ty::ReScope(body_scope));
             let arg_cmt = self.with_mc(|mc| {
-                Rc::new(mc.cat_rvalue(arg.id, arg.pat.span, re_scope, arg_ty))
+                Rc::new(mc.cat_rvalue(arg.hir_id, arg.pat.span, re_scope, arg_ty))
             });
             debug!("arg_ty={:?} arg_cmt={:?} arg={:?}",
                    arg_ty,
@@ -1039,11 +1039,13 @@ fn link_pattern(&self, discr_cmt: mc::cmt<'tcx>, root_pat: &hir::Pat) {
                 match sub_pat.node {
                     // `ref x` pattern
                     PatKind::Binding(..) => {
-                        let bm = *mc.tables.pat_binding_modes().get(sub_pat.hir_id)
-                                                               .expect("missing binding mode");
-                        if let ty::BindByReference(mutbl) = bm {
-                            self.link_region_from_node_type(sub_pat.span, sub_pat.hir_id,
-                                                            mutbl, &sub_cmt);
+                        if let Some(&bm) = mc.tables.pat_binding_modes().get(sub_pat.hir_id) {
+                            if let ty::BindByReference(mutbl) = bm {
+                                self.link_region_from_node_type(sub_pat.span, sub_pat.hir_id,
+                                                                mutbl, &sub_cmt);
+                            }
+                        } else {
+                            self.tcx.sess.delay_span_bug(sub_pat.span, "missing binding mode");
                         }
                     }
                     _ => {}
index be42549df74a32ba816217ec314930619b7fe6d2..85fdcd417ff9d830266d2fcd89634e0772f9228e 100644 (file)
@@ -364,15 +364,16 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 /// Checks where clauses and inline bounds that are declared on def_id.
-fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
-                                    fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
-                                    span: Span,
-                                    def_id: DefId) {
+fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
+    tcx: TyCtxt<'a, 'gcx, 'gcx>,
+    fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
+    span: Span,
+    def_id: DefId,
+) {
     use ty::subst::Subst;
     use rustc::ty::TypeFoldable;
 
-    let mut predicates = fcx.tcx.predicates_of(def_id);
-    let mut substituted_predicates = Vec::new();
+    let predicates = fcx.tcx.predicates_of(def_id);
 
     let generics = tcx.generics_of(def_id);
     let is_our_default = |def: &ty::GenericParamDef| {
@@ -433,7 +434,7 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
         }
     });
     // Now we build the substituted predicates.
-    for &pred in predicates.predicates.iter() {
+    let default_obligations = predicates.predicates.iter().flat_map(|&pred| {
         struct CountParams { params: FxHashSet<u32> }
         impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams {
             fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
@@ -455,21 +456,37 @@ fn visit_region(&mut self, _: ty::Region<'tcx>) -> bool {
         let substituted_pred = pred.subst(fcx.tcx, substs);
         // Don't check non-defaulted params, dependent defaults (including lifetimes)
         // or preds with multiple params.
-        if substituted_pred.references_error() || param_count.params.len() > 1
-            || has_region {
-            continue;
-        }
-        // Avoid duplication of predicates that contain no parameters, for example.
-        if !predicates.predicates.contains(&substituted_pred) {
-            substituted_predicates.push(substituted_pred);
+        if {
+            substituted_pred.references_error() || param_count.params.len() > 1
+                || has_region
+        } {
+                None
+        } else if predicates.predicates.contains(&substituted_pred) {
+            // Avoid duplication of predicates that contain no parameters, for example.
+            None
+        } else {
+            Some(substituted_pred)
         }
-    }
+    }).map(|pred| {
+        // convert each of those into an obligation. So if you have
+        // something like `struct Foo<T: Copy = String>`, we would
+        // take that predicate `T: Copy`, substitute to `String: Copy`
+        // (actually that happens in the previous `flat_map` call),
+        // and then try to prove it (in this case, we'll fail).
+        //
+        // Note the subtle difference from how we handle `predicates`
+        // below: there, we are not trying to prove those predicates
+        // to be *true* but merely *well-formed*.
+        let pred = fcx.normalize_associated_types_in(span, &pred);
+        let cause = traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def_id));
+        traits::Obligation::new(cause, fcx.param_env, pred)
+    });
 
-    predicates.predicates.extend(substituted_predicates);
     let predicates = predicates.instantiate_identity(fcx.tcx);
     let predicates = fcx.normalize_associated_types_in(span, &predicates);
 
-    let obligations =
+    debug!("check_where_clauses: predicates={:?}", predicates.predicates);
+    let wf_obligations =
         predicates.predicates
                     .iter()
                     .flat_map(|p| ty::wf::predicate_obligations(fcx,
@@ -478,7 +495,8 @@ fn visit_region(&mut self, _: ty::Region<'tcx>) -> bool {
                                                                 p,
                                                                 span));
 
-    for obligation in obligations {
+    for obligation in wf_obligations.chain(default_obligations) {
+        debug!("next obligation cause: {:?}", obligation.cause);
         fcx.register_predicate(obligation);
     }
 }
index f7d1e40794580612dbbf3d35fc7686d3223fcecf..2445cae98607ae4a93bd01a65b8892782bcbfb85 100644 (file)
@@ -257,13 +257,11 @@ fn visit_block(&mut self, b: &'gcx hir::Block) {
     fn visit_pat(&mut self, p: &'gcx hir::Pat) {
         match p.node {
             hir::PatKind::Binding(..) => {
-                let bm = *self.fcx
-                    .tables
-                    .borrow()
-                    .pat_binding_modes()
-                    .get(p.hir_id)
-                    .expect("missing binding mode");
-                self.tables.pat_binding_modes_mut().insert(p.hir_id, bm);
+                if let Some(&bm) = self.fcx.tables.borrow().pat_binding_modes().get(p.hir_id) {
+                    self.tables.pat_binding_modes_mut().insert(p.hir_id, bm);
+                } else {
+                    self.tcx().sess.delay_span_bug(p.span, "missing binding mode");
+                }
             }
             hir::PatKind::Struct(_, ref fields, _) => {
                 for field in fields {
index 852603ac51c35deb24fa8b580a0227c4a91844cb..94b17532cb7887af040b1c5d6743127857021c62 100644 (file)
@@ -67,6 +67,7 @@ pub fn provide(providers: &mut Providers) {
         type_of,
         generics_of,
         predicates_of,
+        predicates_defined_on,
         explicit_predicates_of,
         super_predicates_of,
         type_param_predicates,
@@ -274,10 +275,9 @@ fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 ItemTrait(_, _, ref generics, ..) => {
                     // Implied `Self: Trait` and supertrait bounds.
                     if param_id == item_node_id {
-                        result.predicates.push(ty::TraitRef {
-                            def_id: item_def_id,
-                            substs: Substs::identity_for_item(tcx, item_def_id)
-                        }.to_predicate());
+                        result.predicates.push(
+                            ty::TraitRef::identity(tcx, item_def_id).to_predicate()
+                        );
                     }
                     generics
                 }
@@ -875,10 +875,6 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             }
         }
 
-        NodeTy(&hir::Ty { node: hir::TyImplTraitExistential(..), .. }) => {
-            bug!("impl Trait is desugared to existential type items");
-        }
-
         _ => &no_generics,
     };
 
@@ -1310,10 +1306,10 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx>(
     })
 }
 
-fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                           def_id: DefId)
-                           -> ty::GenericPredicates<'tcx> {
-    let explicit = explicit_predicates_of(tcx, def_id);
+fn predicates_defined_on<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                   def_id: DefId)
+                                   -> ty::GenericPredicates<'tcx> {
+    let explicit = tcx.explicit_predicates_of(def_id);
     let predicates = if tcx.sess.features_untracked().infer_outlives_requirements {
         [&explicit.predicates[..], &tcx.inferred_outlives_of(def_id)[..]].concat()
     } else { explicit.predicates };
@@ -1324,9 +1320,35 @@ fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 }
 
-pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                            def_id: DefId)
                            -> ty::GenericPredicates<'tcx> {
+    let ty::GenericPredicates { parent, mut predicates } =
+        tcx.predicates_defined_on(def_id);
+
+    if tcx.is_trait(def_id) {
+        // For traits, add `Self: Trait` predicate. This is
+        // not part of the predicates that a user writes, but it
+        // is something that one must prove in order to invoke a
+        // method or project an associated type.
+        //
+        // In the chalk setup, this predicate is not part of the
+        // "predicates" for a trait item. But it is useful in
+        // rustc because if you directly (e.g.) invoke a trait
+        // method like `Trait::method(...)`, you must naturally
+        // prove that the trait applies to the types that were
+        // used, and adding the predicate into this list ensures
+        // that this is done.
+        predicates.push(ty::TraitRef::identity(tcx, def_id).to_predicate());
+    }
+
+    ty::GenericPredicates { parent, predicates }
+}
+
+fn explicit_predicates_of<'a, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    def_id: DefId,
+) -> ty::GenericPredicates<'tcx> {
     use rustc::hir::map::*;
     use rustc::hir::*;
 
@@ -1341,7 +1363,10 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let icx = ItemCtxt::new(tcx, def_id);
     let no_generics = hir::Generics::empty();
     let ast_generics = match node {
-        NodeTraitItem(item) => &item.generics,
+        NodeTraitItem(item) => {
+            &item.generics
+        }
+
         NodeImplItem(item) => &item.generics,
 
         NodeItem(item) => {
@@ -1359,10 +1384,7 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 ItemUnion(_, ref generics) => generics,
 
                 ItemTrait(_, _, ref generics, .., ref items) => {
-                    is_trait = Some((ty::TraitRef {
-                        def_id,
-                        substs: Substs::identity_for_item(tcx, def_id)
-                    }, items));
+                    is_trait = Some((ty::TraitRef::identity(tcx, def_id), items));
                     generics
                 }
                 ItemExistential(ref exist_ty) => {
@@ -1409,12 +1431,8 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // and the explicit where-clauses, but to get the full set of predicates
     // on a trait we need to add in the supertrait bounds and bounds found on
     // associated types.
-    if let Some((trait_ref, _)) = is_trait {
+    if let Some((_trait_ref, _)) = is_trait {
         predicates = tcx.super_predicates_of(def_id).predicates;
-
-        // Add in a predicate that `Self:Trait` (where `Trait` is the
-        // current trait).  This is needed for builtin bounds.
-        predicates.push(trait_ref.to_poly_trait_ref().to_predicate());
     }
 
     // In default impls, we can assume that the self type implements
index 7677ccf8bf40c4ffd2007e71c69ef0d38a10a483..fa0e5a88f80e0e9732d74bd3956150bd845391e0 100644 (file)
 use std::iter::once;
 
 use syntax::ast;
-use rustc::hir;
+use syntax::ext::base::MacroKind;
+use syntax_pos::Span;
 
+use rustc::hir;
 use rustc::hir::def::{Def, CtorKind};
 use rustc::hir::def_id::DefId;
+use rustc::middle::cstore::LoadedMacro;
 use rustc::ty;
 use rustc::util::nodemap::FxHashSet;
 
 use core::{DocContext, DocAccessLevels};
 use doctree;
-use clean::{self, GetDefId, get_auto_traits_with_def_id};
+use clean::{self, GetDefId, ToSource, get_auto_traits_with_def_id};
 
 use super::Clean;
 
@@ -97,9 +100,12 @@ pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name, visited: &mut FxHa
             record_extern_fqn(cx, did, clean::TypeKind::Const);
             clean::ConstantItem(build_const(cx, did))
         }
-        // Macros are eagerly inlined back in visit_ast, don't show their export statements
-        // FIXME(50647): the eager inline does not take doc(hidden)/doc(no_inline) into account
-        Def::Macro(..) => return Some(Vec::new()),
+        // FIXME(misdreavus): if attributes/derives come down here we should probably document them
+        // separately
+        Def::Macro(did, MacroKind::Bang) => {
+            record_extern_fqn(cx, did, clean::TypeKind::Macro);
+            clean::MacroItem(build_macro(cx, did, name))
+        }
         _ => return None,
     };
     cx.renderinfo.borrow_mut().inlined.insert(did);
@@ -460,6 +466,33 @@ fn build_static(cx: &DocContext, did: DefId, mutable: bool) -> clean::Static {
     }
 }
 
+fn build_macro(cx: &DocContext, did: DefId, name: ast::Name) -> clean::Macro {
+    let imported_from = cx.tcx.original_crate_name(did.krate);
+    let def = match cx.cstore.load_macro_untracked(did, cx.sess()) {
+        LoadedMacro::MacroDef(macro_def) => macro_def,
+        // FIXME(jseyfried): document proc macro re-exports
+        LoadedMacro::ProcMacro(..) => panic!("attempting to document proc-macro re-export"),
+    };
+
+    let matchers: hir::HirVec<Span> = if let ast::ItemKind::MacroDef(ref def) = def.node {
+        let tts: Vec<_> = def.stream().into_trees().collect();
+        tts.chunks(4).map(|arm| arm[0].span()).collect()
+    } else {
+        unreachable!()
+    };
+
+    let source = format!("macro_rules! {} {{\n{}}}",
+                         name.clean(cx),
+                         matchers.iter().map(|span| {
+                             format!("    {} => {{ ... }};\n", span.to_src(cx))
+                         }).collect::<String>());
+
+    clean::Macro {
+        source,
+        imported_from: Some(imported_from).clean(cx),
+    }
+}
+
 /// A trait's generics clause actually contains all of the predicates for all of
 /// its associated types as well. We specifically move these clauses to the
 /// associated types instead when displaying, so when we're generating the
index b8abb98edec4800945d65bd3036d080bc8b1fa8e..f71d62d5a04e1e3cb39a613ec7a4682df613d423 100644 (file)
@@ -2987,14 +2987,6 @@ fn clean(&self, cx: &DocContext) -> Type {
                 }
             }
             TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
-            TyImplTraitExistential(hir_id, _, _) => {
-                match cx.tcx.hir.expect_item(hir_id.id).node {
-                    hir::ItemExistential(ref exist_ty) => {
-                        ImplTrait(exist_ty.bounds.clean(cx))
-                    },
-                    ref other => panic!("impl Trait pointed to {:#?}", other),
-                }
-            },
             TyInfer | TyErr => Infer,
             TyTypeof(..) => panic!("Unimplemented type {:?}", self.node),
         }
index 7088104cd7a31d8b6ee5a6f6baa1ca2b3a5c9cea..c77a720b16ba503657cfd6e07eb8d5a3841fc0fc 100644 (file)
 /// All lines are used in documentation tests.
 enum Line<'a> {
     Hidden(&'a str),
-    Shown(&'a str),
+    Shown(Cow<'a, str>),
 }
 
 impl<'a> Line<'a> {
-    fn for_html(self) -> Option<&'a str> {
+    fn for_html(self) -> Option<Cow<'a, str>> {
         match self {
             Line::Shown(l) => Some(l),
             Line::Hidden(_) => None,
         }
     }
 
-    fn for_code(self) -> &'a str {
+    fn for_code(self) -> Cow<'a, str> {
         match self {
-            Line::Shown(l) |
-            Line::Hidden(l) => l,
+            Line::Shown(l) => l,
+            Line::Hidden(l) => Cow::Borrowed(l),
         }
     }
 }
@@ -91,7 +91,7 @@ fn for_code(self) -> &'a str {
 fn map_line(s: &str) -> Line {
     let trimmed = s.trim();
     if trimmed.starts_with("##") {
-        Line::Shown(&trimmed[1..])
+        Line::Shown(Cow::Owned(s.replacen("##", "#", 1)))
     } else if trimmed.starts_with("# ") {
         // # text
         Line::Hidden(&trimmed[2..])
@@ -99,7 +99,7 @@ fn map_line(s: &str) -> Line {
         // We cannot handle '#text' because it could be #[attr].
         Line::Hidden("")
     } else {
-        Line::Shown(s)
+        Line::Shown(Cow::Borrowed(s))
     }
 }
 
@@ -168,7 +168,7 @@ fn next(&mut self) -> Option<Self::Item> {
             }
         }
         let lines = origtext.lines().filter_map(|l| map_line(l).for_html());
-        let text = lines.collect::<Vec<&str>>().join("\n");
+        let text = lines.collect::<Vec<Cow<str>>>().join("\n");
         PLAYGROUND.with(|play| {
             // insert newline to clearly separate it from the
             // previous block so we can shorten the html output
@@ -179,7 +179,7 @@ fn next(&mut self) -> Option<Self::Item> {
                 }
                 let test = origtext.lines()
                     .map(|l| map_line(l).for_code())
-                    .collect::<Vec<&str>>().join("\n");
+                    .collect::<Vec<Cow<str>>>().join("\n");
                 let krate = krate.as_ref().map(|s| &**s);
                 let (test, _) = test::make_test(&test, krate, false,
                                            &Default::default());
@@ -477,7 +477,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Sp
                 }
                 if let Some(offset) = offset {
                     let lines = test_s.lines().map(|l| map_line(l).for_code());
-                    let text = lines.collect::<Vec<&str>>().join("\n");
+                    let text = lines.collect::<Vec<Cow<str>>>().join("\n");
                     nb_lines += doc[prev_offset..offset].lines().count();
                     let line = tests.get_line() + (nb_lines - 1);
                     let filename = tests.get_filename();
index 130451d07af8649bb188549cb6b2fd27c4d17c2c..e4afb9ae54b8ad4d25a15e8257562b99c10023f2 100644 (file)
@@ -414,13 +414,13 @@ impl ToJson for Type {
     fn to_json(&self) -> Json {
         match self.name {
             Some(ref name) => {
-                let mut data = BTreeMap::new();
-                data.insert("n".to_owned(), name.to_json());
+                let mut data = Vec::with_capacity(2);
+                data.push(name.to_json());
                 if let Some(ref generics) = self.generics {
-                    data.insert("g".to_owned(), generics.to_json());
+                    data.push(generics.to_json());
                 }
-                Json::Object(data)
-            },
+                Json::Array(data)
+            }
             None => Json::Null
         }
     }
@@ -439,14 +439,12 @@ fn to_json(&self) -> Json {
         if self.inputs.iter().chain(self.output.iter()).any(|ref i| i.name.is_none()) {
             Json::Null
         } else {
-            let mut data = BTreeMap::new();
-            if !self.inputs.is_empty() {
-                data.insert("i".to_owned(), self.inputs.to_json());
-            }
+            let mut data = Vec::with_capacity(2);
+            data.push(self.inputs.to_json());
             if let Some(ref output) = self.output {
-                data.insert("o".to_owned(), output.to_json());
+                data.push(output.to_json());
             }
-            Json::Object(data)
+            Json::Array(data)
         }
     }
 }
@@ -963,9 +961,11 @@ fn show_item(item: &IndexItem, krate: &str) -> String {
     // with rustdoc running in parallel.
     all_indexes.sort();
     let mut w = try_err!(File::create(&dst), &dst);
-    try_err!(writeln!(&mut w, "var searchIndex = {{}};"), &dst);
+    try_err!(writeln!(&mut w, "var N = null;var searchIndex = {{}};"), &dst);
     for index in &all_indexes {
-        try_err!(writeln!(&mut w, "{}", *index), &dst);
+        try_err!(write_minify_replacer(&mut w, &*index, enable_minification,
+                                       &[(minifier::js::Keyword::Null, "N")]),
+                 &dst);
     }
     try_err!(writeln!(&mut w, "initSearch(searchIndex);"), &dst);
 
@@ -1076,6 +1076,19 @@ fn write_minify(dst: PathBuf, contents: &str, enable_minification: bool) -> Resu
     }
 }
 
+fn write_minify_replacer<W: Write>(dst: &mut W,
+                                   contents: &str,
+                                   enable_minification: bool,
+                                   keywords_to_replace: &[(minifier::js::Keyword, &str)])
+                                   -> io::Result<()> {
+    if enable_minification {
+        writeln!(dst, "{}",
+                 minifier::js::minify_and_replace_keywords(contents, keywords_to_replace))
+    } else {
+        writeln!(dst, "{}", contents)
+    }
+}
+
 /// Takes a path to a source file and cleans the path to it. This canonicalizes
 /// things like ".." to components which preserve the "top down" hierarchy of a
 /// static HTML tree. Each component in the cleaned path will be passed as an
index 01eb1ce7407be16fa868b1a45e2d356201dc1ba7..f3c9ce424106de1df81179290b69bc1941fabf86 100644 (file)
         var currentResults, index, searchIndex;
         var MAX_LEV_DISTANCE = 3;
         var MAX_RESULTS = 200;
+        var GENERICS_DATA = 1;
+        var NAME = 0;
+        var INPUTS_DATA = 0;
+        var OUTPUT_DATA = 1;
         var params = getQueryStringParams();
 
         // Populate search bar with query string search term when provided,
                 // match as well.
                 var lev_distance = MAX_LEV_DISTANCE + 1;
                 if (val.generics.length > 0) {
-                    if (obj.g && obj.g.length >= val.generics.length) {
-                        var elems = obj.g.slice(0);
+                    if (obj.length > GENERICS_DATA &&
+                          obj[GENERICS_DATA].length >= val.generics.length) {
+                        var elems = obj[GENERICS_DATA].slice(0);
                         var total = 0;
                         var done = 0;
                         // We need to find the type that matches the most to remove it in order
             // Check for type name and type generics (if any).
             function checkType(obj, val, literalSearch) {
                 var lev_distance = MAX_LEV_DISTANCE + 1;
-                if (obj.n === val.name) {
+                if (obj[NAME] === val.name) {
                     if (literalSearch === true) {
                         if (val.generics && val.generics.length !== 0) {
-                            if (obj.g && obj.length >= val.generics.length) {
-                                var elems = obj.g.slice(0);
+                            if (obj.length > GENERICS_DATA &&
+                                  obj[GENERICS_DATA].length >= val.generics.length) {
+                                var elems = obj[GENERICS_DATA].slice(0);
                                 var allFound = true;
                                 var x;
 
                     }
                     // If the type has generics but don't match, then it won't return at this point.
                     // Otherwise, `checkGenerics` will return 0 and it'll return.
-                    if (obj.g && obj.g.length !== 0) {
+                    if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length !== 0) {
                         var tmp_lev = checkGenerics(obj, val);
                         if (tmp_lev <= MAX_LEV_DISTANCE) {
                             return tmp_lev;
                 }
                 // Names didn't match so let's check if one of the generic types could.
                 if (literalSearch === true) {
-                     if (obj.g && obj.g.length > 0) {
-                        for (var x = 0; x < obj.g.length; ++x) {
-                            if (obj.g[x] === val.name) {
+                     if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) {
+                        for (var x = 0; x < obj[GENERICS_DATA].length; ++x) {
+                            if (obj[GENERICS_DATA][x] === val.name) {
                                 return true;
                             }
                         }
                     }
                     return false;
                 }
-                var lev_distance = Math.min(levenshtein(obj.n, val.name), lev_distance);
+                var lev_distance = Math.min(levenshtein(obj[NAME], val.name),
+                                            lev_distance);
                 if (lev_distance <= MAX_LEV_DISTANCE) {
                     lev_distance = Math.min(checkGenerics(obj, val), lev_distance);
-                } else if (obj.g && obj.g.length > 0) {
+                } else if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) {
                     // We can check if the type we're looking for is inside the generics!
-                    for (var x = 0; x < obj.g.length; ++x) {
-                        lev_distance = Math.min(levenshtein(obj.g[x], val.name),
+                    for (var x = 0; x < obj[GENERICS_DATA].length; ++x) {
+                        lev_distance = Math.min(levenshtein(obj[GENERICS_DATA][x], val.name),
                                                 lev_distance);
                     }
                 }
             function findArg(obj, val, literalSearch) {
                 var lev_distance = MAX_LEV_DISTANCE + 1;
 
-                if (obj && obj.type && obj.type.i && obj.type.i.length > 0) {
-                    for (var i = 0; i < obj.type.i.length; i++) {
-                        var tmp = checkType(obj.type.i[i], val, literalSearch);
+                if (obj && obj.type && obj.type[INPUTS_DATA] &&
+                      obj.type[INPUTS_DATA].length > 0) {
+                    for (var i = 0; i < obj.type[INPUTS_DATA].length; i++) {
+                        var tmp = checkType(obj.type[INPUTS_DATA][i], val, literalSearch);
                         if (literalSearch === true && tmp === true) {
                             return true;
                         }
             function checkReturned(obj, val, literalSearch) {
                 var lev_distance = MAX_LEV_DISTANCE + 1;
 
-                if (obj && obj.type && obj.type.o) {
-                    var tmp = checkType(obj.type.o, val, literalSearch);
+                if (obj && obj.type && obj.type.length > OUTPUT_DATA) {
+                    var tmp = checkType(obj.type[OUTPUT_DATA], val, literalSearch);
                     if (literalSearch === true && tmp === true) {
                         return true;
                     }
                     var fullId = generateId(ty);
 
                     // allow searching for void (no output) functions as well
-                    var typeOutput = type.o ? type.o.name : "";
+                    var typeOutput = type.length > OUTPUT_DATA ? type[OUTPUT_DATA].name : "";
                     var returned = checkReturned(ty, output, true);
                     if (output.name === "*" || returned === true) {
                         var in_args = false;
index 7add0e21f548c7b4f16e361f2ee21a6721b1246a..649ee0b781e484888ea0eb395a329112f0f53c25 100644 (file)
@@ -108,7 +108,7 @@ pre {
 
 .content .highlighted {
        color: #eee !important;
-       background-color: #333;
+       background-color: #616161;
 }
 .content .highlighted a, .content .highlighted span { color: #eee !important; }
 .content .highlighted.trait { background-color: #013191; }
index fdeba93990d1c244352befe719f5a5c4ceeec347..2fb69b2cee0184b3ac7af06e073f326ffb093a18 100644 (file)
@@ -21,9 +21,8 @@
 use rustc::hir::map as hir_map;
 use rustc::hir::def::Def;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
-use rustc::middle::cstore::{LoadedMacro, CrateStore};
+use rustc::middle::cstore::CrateStore;
 use rustc::middle::privacy::AccessLevel;
-use rustc::ty::Visibility;
 use rustc::util::nodemap::{FxHashSet, FxHashMap};
 
 use rustc::hir;
@@ -212,44 +211,6 @@ pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec<ast::Attribu
             self.visit_item(item, None, &mut om);
         }
         self.inside_public_path = orig_inside_public_path;
-        let def_id = self.cx.tcx.hir.local_def_id(id);
-        if let Some(exports) = self.cx.tcx.module_exports(def_id) {
-            for export in exports.iter().filter(|e| e.vis == Visibility::Public) {
-                if let Def::Macro(def_id, ..) = export.def {
-                    // FIXME(50647): this eager macro inlining does not take
-                    // doc(hidden)/doc(no_inline) into account
-                    if def_id.krate == LOCAL_CRATE {
-                        continue // These are `krate.exported_macros`, handled in `self.visit()`.
-                    }
-
-                    let imported_from = self.cx.tcx.original_crate_name(def_id.krate);
-                    let def = match self.cstore.load_macro_untracked(def_id, self.cx.sess()) {
-                        LoadedMacro::MacroDef(macro_def) => macro_def,
-                        // FIXME(jseyfried): document proc macro re-exports
-                        LoadedMacro::ProcMacro(..) => continue,
-                    };
-
-                    let matchers = if let ast::ItemKind::MacroDef(ref def) = def.node {
-                        let tts: Vec<_> = def.stream().into_trees().collect();
-                        tts.chunks(4).map(|arm| arm[0].span()).collect()
-                    } else {
-                        unreachable!()
-                    };
-
-                    debug!("inlining macro {}", def.ident.name);
-                    om.macros.push(Macro {
-                        def_id,
-                        attrs: def.attrs.clone().into(),
-                        name: def.ident.name,
-                        whence: self.cx.tcx.def_span(def_id),
-                        matchers,
-                        stab: self.cx.tcx.lookup_stability(def_id).cloned(),
-                        depr: self.cx.tcx.lookup_deprecation(def_id),
-                        imported_from: Some(imported_from),
-                    })
-                }
-            }
-        }
         om
     }
 
index 8ac52572810c6c99e2ce8ccddaa0d1be66174a55..aadd33b39542cb3ef908c2066046b01cab06b93e 100644 (file)
@@ -10,6 +10,7 @@
 
 use io::prelude::*;
 
+use core::convert::TryInto;
 use cmp;
 use io::{self, Initializer, SeekFrom, Error, ErrorKind};
 
@@ -259,26 +260,9 @@ fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<us
     Ok(amt)
 }
 
-/// Compensate removal of some impls per
-/// https://github.com/rust-lang/rust/pull/49305#issuecomment-376293243
-#[cfg(any(target_pointer_width = "16",
-          target_pointer_width = "32"))]
-fn try_into(n: u64) -> Result<usize, ()> {
-    if n <= (<usize>::max_value() as u64) {
-        Ok(n as usize)
-    } else {
-        Err(())
-    }
-}
-
-#[cfg(any(target_pointer_width = "64"))]
-fn try_into(n: u64) -> Result<usize, ()> {
-    Ok(n as usize)
-}
-
 // Resizing write implementation
 fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usize> {
-    let pos: usize = try_into(*pos_mut).map_err(|_| {
+    let pos: usize = (*pos_mut).try_into().map_err(|_| {
         Error::new(ErrorKind::InvalidInput,
                     "cursor position exceeds maximum possible vector length")
     })?;
index 2472bed5ba43570b3b0c3e2c6f9bb2e2216827f9..fce85a200ba2e98b39784f7279ffa7b5e3ea5ce1 100644 (file)
@@ -712,9 +712,31 @@ pub fn _eprint(args: fmt::Arguments) {
 
 #[cfg(test)]
 mod tests {
+    use panic::{UnwindSafe, RefUnwindSafe};
     use thread;
     use super::*;
 
+    #[test]
+    fn stdout_unwind_safe() {
+        assert_unwind_safe::<Stdout>();
+    }
+    #[test]
+    fn stdoutlock_unwind_safe() {
+        assert_unwind_safe::<StdoutLock>();
+        assert_unwind_safe::<StdoutLock<'static>>();
+    }
+    #[test]
+    fn stderr_unwind_safe() {
+        assert_unwind_safe::<Stderr>();
+    }
+    #[test]
+    fn stderrlock_unwind_safe() {
+        assert_unwind_safe::<StderrLock>();
+        assert_unwind_safe::<StderrLock<'static>>();
+    }
+
+    fn assert_unwind_safe<T: UnwindSafe + RefUnwindSafe>() {}
+
     #[test]
     #[cfg_attr(target_os = "emscripten", ignore)]
     fn panic_doesnt_poison() {
index 4e981012669033ff393d85a44f1511bab82df6a0..507e9d881717bbac63ce1a9082cfeadb71be7c0b 100644 (file)
@@ -59,6 +59,78 @@ pub trait FileExt {
     #[stable(feature = "file_offset", since = "1.15.0")]
     fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
 
+    /// Reads the exact number of byte required to fill `buf` from the given offset.
+    ///
+    /// The offset is relative to the start of the file and thus independent
+    /// from the current cursor.
+    ///
+    /// The current file cursor is not affected by this function.
+    ///
+    /// Similar to [`Read::read_exact`] but uses [`read_at`] instead of `read`.
+    ///
+    /// [`Read::read_exact`]: ../../../../std/io/trait.Read.html#method.read_exact
+    /// [`read_at`]: #tymethod.read_at
+    ///
+    /// # Errors
+    ///
+    /// If this function encounters an error of the kind
+    /// [`ErrorKind::Interrupted`] then the error is ignored and the operation
+    /// will continue.
+    ///
+    /// If this function encounters an "end of file" before completely filling
+    /// the buffer, it returns an error of the kind [`ErrorKind::UnexpectedEof`].
+    /// The contents of `buf` are unspecified in this case.
+    ///
+    /// If any other read error is encountered then this function immediately
+    /// returns. The contents of `buf` are unspecified in this case.
+    ///
+    /// If this function returns an error, it is unspecified how many bytes it
+    /// has read, but it will never read more than would be necessary to
+    /// completely fill the buffer.
+    ///
+    /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted
+    /// [`ErrorKind::UnexpectedEof`]: ../../../../std/io/enum.ErrorKind.html#variant.UnexpectedEof
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(rw_exact_all_at)]
+    /// use std::io;
+    /// use std::fs::File;
+    /// use std::os::unix::prelude::FileExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let mut buf = [0u8; 8];
+    ///     let file = File::open("foo.txt")?;
+    ///
+    ///     // We now read exactly 8 bytes from the offset 10.
+    ///     file.read_exact_at(&mut buf, 10)?;
+    ///     println!("read {} bytes: {:?}", buf.len(), buf);
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "rw_exact_all_at", issue = "51984")]
+    fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> {
+        while !buf.is_empty() {
+            match self.read_at(buf, offset) {
+                Ok(0) => break,
+                Ok(n) => {
+                    let tmp = buf;
+                    buf = &mut tmp[n..];
+                    offset += n as u64;
+                }
+                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
+                Err(e) => return Err(e),
+            }
+        }
+        if !buf.is_empty() {
+            Err(io::Error::new(io::ErrorKind::UnexpectedEof,
+                               "failed to fill whole buffer"))
+        } else {
+            Ok(())
+        }
+    }
+
     /// Writes a number of bytes starting from a given offset.
     ///
     /// Returns the number of bytes written.
@@ -93,6 +165,61 @@ pub trait FileExt {
     /// ```
     #[stable(feature = "file_offset", since = "1.15.0")]
     fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
+
+    /// Attempts to write an entire buffer starting from a given offset.
+    ///
+    /// The offset is relative to the start of the file and thus independent
+    /// from the current cursor.
+    ///
+    /// The current file cursor is not affected by this function.
+    ///
+    /// This method will continuously call [`write_at`] until there is no more data
+    /// to be written or an error of non-[`ErrorKind::Interrupted`] kind is
+    /// returned. This method will not return until the entire buffer has been
+    /// successfully written or such an error occurs. The first error that is
+    /// not of [`ErrorKind::Interrupted`] kind generated from this method will be
+    /// returned.
+    ///
+    /// # Errors
+    ///
+    /// This function will return the first error of
+    /// non-[`ErrorKind::Interrupted`] kind that [`write_at`] returns.
+    ///
+    /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted
+    /// [`write_at`]: #tymethod.write_at
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(rw_exact_all_at)]
+    /// use std::fs::File;
+    /// use std::io;
+    /// use std::os::unix::prelude::FileExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let file = File::open("foo.txt")?;
+    ///
+    ///     // We now write at the offset 10.
+    ///     file.write_all_at(b"sushi", 10)?;
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "rw_exact_all_at", issue = "51984")]
+    fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
+        while !buf.is_empty() {
+            match self.write_at(buf, offset) {
+                Ok(0) => return Err(io::Error::new(io::ErrorKind::WriteZero,
+                                                   "failed to write whole buffer")),
+                Ok(n) => {
+                    buf = &buf[n..];
+                    offset += n as u64
+                }
+                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
+                Err(e) => return Err(e),
+            }
+        }
+        Ok(())
+    }
 }
 
 #[stable(feature = "file_offset", since = "1.15.0")]
index 022056f8a8a700fd9c41c45006f4472ef4c0252e..071a3a25c7acdab8860b7ad0c577687c35ab1023 100644 (file)
@@ -13,6 +13,7 @@
 use ops::Deref;
 use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
 use sys::mutex as sys;
+use panic::{UnwindSafe, RefUnwindSafe};
 
 /// A re-entrant mutual exclusion
 ///
@@ -28,6 +29,9 @@ pub struct ReentrantMutex<T> {
 unsafe impl<T: Send> Send for ReentrantMutex<T> {}
 unsafe impl<T: Send> Sync for ReentrantMutex<T> {}
 
+impl<T> UnwindSafe for ReentrantMutex<T> {}
+impl<T> RefUnwindSafe for ReentrantMutex<T> {}
+
 
 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is
 /// dropped (falls out of scope), the lock will be unlocked.
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
deleted file mode 100644 (file)
index ded493f..0000000
+++ /dev/null
@@ -1,1478 +0,0 @@
-// Copyright 2012-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.
-
-// Functions dealing with attributes and meta items
-
-pub use self::StabilityLevel::*;
-pub use self::ReprAttr::*;
-pub use self::IntType::*;
-
-use ast;
-use ast::{AttrId, Attribute, Name, Ident, Path, PathSegment};
-use ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
-use ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam};
-use codemap::{BytePos, Spanned, respan, dummy_spanned};
-use syntax_pos::Span;
-use errors::{Applicability, Handler};
-use feature_gate::{Features, GatedCfg};
-use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
-use parse::parser::Parser;
-use parse::{self, ParseSess, PResult};
-use parse::token::{self, Token};
-use ptr::P;
-use symbol::Symbol;
-use tokenstream::{TokenStream, TokenTree, Delimited};
-use util::ThinVec;
-use GLOBALS;
-
-use std::iter;
-
-enum AttrError {
-    MultipleItem(Name),
-    UnknownMetaItem(Name),
-    MissingSince,
-    MissingFeature,
-    MultipleStabilityLevels,
-    UnsupportedLiteral
-}
-
-fn handle_errors(diag: &Handler, span: Span, error: AttrError) {
-    match error {
-        AttrError::MultipleItem(item) => span_err!(diag, span, E0538,
-                                                   "multiple '{}' items", item),
-        AttrError::UnknownMetaItem(item) => span_err!(diag, span, E0541,
-                                                      "unknown meta item '{}'", item),
-        AttrError::MissingSince => span_err!(diag, span, E0542, "missing 'since'"),
-        AttrError::MissingFeature => span_err!(diag, span, E0546, "missing 'feature'"),
-        AttrError::MultipleStabilityLevels => span_err!(diag, span, E0544,
-                                                        "multiple stability levels"),
-        AttrError::UnsupportedLiteral => span_err!(diag, span, E0565, "unsupported literal"),
-    }
-}
-
-pub fn mark_used(attr: &Attribute) {
-    debug!("Marking {:?} as used.", attr);
-    let AttrId(id) = attr.id;
-    GLOBALS.with(|globals| {
-        let mut slot = globals.used_attrs.lock();
-        let idx = (id / 64) as usize;
-        let shift = id % 64;
-        if slot.len() <= idx {
-            slot.resize(idx + 1, 0);
-        }
-        slot[idx] |= 1 << shift;
-    });
-}
-
-pub fn is_used(attr: &Attribute) -> bool {
-    let AttrId(id) = attr.id;
-    GLOBALS.with(|globals| {
-        let slot = globals.used_attrs.lock();
-        let idx = (id / 64) as usize;
-        let shift = id % 64;
-        slot.get(idx).map(|bits| bits & (1 << shift) != 0)
-            .unwrap_or(false)
-    })
-}
-
-pub fn mark_known(attr: &Attribute) {
-    debug!("Marking {:?} as known.", attr);
-    let AttrId(id) = attr.id;
-    GLOBALS.with(|globals| {
-        let mut slot = globals.known_attrs.lock();
-        let idx = (id / 64) as usize;
-        let shift = id % 64;
-        if slot.len() <= idx {
-            slot.resize(idx + 1, 0);
-        }
-        slot[idx] |= 1 << shift;
-    });
-}
-
-pub fn is_known(attr: &Attribute) -> bool {
-    let AttrId(id) = attr.id;
-    GLOBALS.with(|globals| {
-        let slot = globals.known_attrs.lock();
-        let idx = (id / 64) as usize;
-        let shift = id % 64;
-        slot.get(idx).map(|bits| bits & (1 << shift) != 0)
-            .unwrap_or(false)
-    })
-}
-
-const RUST_KNOWN_TOOL: &[&str] = &["clippy", "rustfmt"];
-
-pub fn is_known_tool(attr: &Attribute) -> bool {
-    let tool_name =
-        attr.path.segments.iter().next().expect("empty path in attribute").ident.name;
-    RUST_KNOWN_TOOL.contains(&tool_name.as_str().as_ref())
-}
-
-impl NestedMetaItem {
-    /// Returns the MetaItem if self is a NestedMetaItemKind::MetaItem.
-    pub fn meta_item(&self) -> Option<&MetaItem> {
-        match self.node {
-            NestedMetaItemKind::MetaItem(ref item) => Some(item),
-            _ => None
-        }
-    }
-
-    /// Returns the Lit if self is a NestedMetaItemKind::Literal.
-    pub fn literal(&self) -> Option<&Lit> {
-        match self.node {
-            NestedMetaItemKind::Literal(ref lit) => Some(lit),
-            _ => None
-        }
-    }
-
-    /// Returns the Span for `self`.
-    pub fn span(&self) -> Span {
-        self.span
-    }
-
-    /// Returns true if this list item is a MetaItem with a name of `name`.
-    pub fn check_name(&self, name: &str) -> bool {
-        self.meta_item().map_or(false, |meta_item| meta_item.check_name(name))
-    }
-
-    /// Returns the name of the meta item, e.g. `foo` in `#[foo]`,
-    /// `#[foo="bar"]` and `#[foo(bar)]`, if self is a MetaItem
-    pub fn name(&self) -> Option<Name> {
-        self.meta_item().and_then(|meta_item| Some(meta_item.name()))
-    }
-
-    /// Gets the string value if self is a MetaItem and the MetaItem is a
-    /// MetaItemKind::NameValue variant containing a string, otherwise None.
-    pub fn value_str(&self) -> Option<Symbol> {
-        self.meta_item().and_then(|meta_item| meta_item.value_str())
-    }
-
-    /// Returns a name and single literal value tuple of the MetaItem.
-    pub fn name_value_literal(&self) -> Option<(Name, &Lit)> {
-        self.meta_item().and_then(
-            |meta_item| meta_item.meta_item_list().and_then(
-                |meta_item_list| {
-                    if meta_item_list.len() == 1 {
-                        let nested_item = &meta_item_list[0];
-                        if nested_item.is_literal() {
-                            Some((meta_item.name(), nested_item.literal().unwrap()))
-                        } else {
-                            None
-                        }
-                    }
-                    else {
-                        None
-                    }}))
-    }
-
-    /// Returns a MetaItem if self is a MetaItem with Kind Word.
-    pub fn word(&self) -> Option<&MetaItem> {
-        self.meta_item().and_then(|meta_item| if meta_item.is_word() {
-            Some(meta_item)
-        } else {
-            None
-        })
-    }
-
-    /// Gets a list of inner meta items from a list MetaItem type.
-    pub fn meta_item_list(&self) -> Option<&[NestedMetaItem]> {
-        self.meta_item().and_then(|meta_item| meta_item.meta_item_list())
-    }
-
-    /// Returns `true` if the variant is MetaItem.
-    pub fn is_meta_item(&self) -> bool {
-        self.meta_item().is_some()
-    }
-
-    /// Returns `true` if the variant is Literal.
-    pub fn is_literal(&self) -> bool {
-        self.literal().is_some()
-    }
-
-    /// Returns `true` if self is a MetaItem and the meta item is a word.
-    pub fn is_word(&self) -> bool {
-        self.word().is_some()
-    }
-
-    /// Returns `true` if self is a MetaItem and the meta item is a ValueString.
-    pub fn is_value_str(&self) -> bool {
-        self.value_str().is_some()
-    }
-
-    /// Returns `true` if self is a MetaItem and the meta item is a list.
-    pub fn is_meta_item_list(&self) -> bool {
-        self.meta_item_list().is_some()
-    }
-}
-
-fn name_from_path(path: &Path) -> Name {
-    path.segments.last().expect("empty path in attribute").ident.name
-}
-
-impl Attribute {
-    pub fn check_name(&self, name: &str) -> bool {
-        let matches = self.path == name;
-        if matches {
-            mark_used(self);
-        }
-        matches
-    }
-
-    /// Returns the **last** segment of the name of this attribute.
-    /// E.g. `foo` for `#[foo]`, `skip` for `#[rustfmt::skip]`.
-    pub fn name(&self) -> Name {
-        name_from_path(&self.path)
-    }
-
-    pub fn value_str(&self) -> Option<Symbol> {
-        self.meta().and_then(|meta| meta.value_str())
-    }
-
-    pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> {
-        match self.meta() {
-            Some(MetaItem { node: MetaItemKind::List(list), .. }) => Some(list),
-            _ => None
-        }
-    }
-
-    pub fn is_word(&self) -> bool {
-        self.path.segments.len() == 1 && self.tokens.is_empty()
-    }
-
-    pub fn span(&self) -> Span {
-        self.span
-    }
-
-    pub fn is_meta_item_list(&self) -> bool {
-        self.meta_item_list().is_some()
-    }
-
-    /// Indicates if the attribute is a Value String.
-    pub fn is_value_str(&self) -> bool {
-        self.value_str().is_some()
-    }
-
-    pub fn is_scoped(&self) -> bool {
-        self.path.segments.len() > 1
-    }
-}
-
-impl MetaItem {
-    pub fn name(&self) -> Name {
-        name_from_path(&self.ident)
-    }
-
-    pub fn value_str(&self) -> Option<Symbol> {
-        match self.node {
-            MetaItemKind::NameValue(ref v) => {
-                match v.node {
-                    LitKind::Str(ref s, _) => Some(*s),
-                    _ => None,
-                }
-            },
-            _ => None
-        }
-    }
-
-    pub fn meta_item_list(&self) -> Option<&[NestedMetaItem]> {
-        match self.node {
-            MetaItemKind::List(ref l) => Some(&l[..]),
-            _ => None
-        }
-    }
-
-    pub fn is_word(&self) -> bool {
-        match self.node {
-            MetaItemKind::Word => true,
-            _ => false,
-        }
-    }
-
-    pub fn span(&self) -> Span { self.span }
-
-    pub fn check_name(&self, name: &str) -> bool {
-        self.name() == name
-    }
-
-    pub fn is_value_str(&self) -> bool {
-        self.value_str().is_some()
-    }
-
-    pub fn is_meta_item_list(&self) -> bool {
-        self.meta_item_list().is_some()
-    }
-}
-
-impl Attribute {
-    /// Extract the MetaItem from inside this Attribute.
-    pub fn meta(&self) -> Option<MetaItem> {
-        let mut tokens = self.tokens.trees().peekable();
-        Some(MetaItem {
-            ident: self.path.clone(),
-            node: if let Some(node) = MetaItemKind::from_tokens(&mut tokens) {
-                if tokens.peek().is_some() {
-                    return None;
-                }
-                node
-            } else {
-                return None;
-            },
-            span: self.span,
-        })
-    }
-
-    pub fn parse<'a, T, F>(&self, sess: &'a ParseSess, mut f: F) -> PResult<'a, T>
-        where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
-    {
-        let mut parser = Parser::new(sess, self.tokens.clone(), None, false, false);
-        let result = f(&mut parser)?;
-        if parser.token != token::Eof {
-            parser.unexpected()?;
-        }
-        Ok(result)
-    }
-
-    pub fn parse_list<'a, T, F>(&self, sess: &'a ParseSess, mut f: F) -> PResult<'a, Vec<T>>
-        where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
-    {
-        if self.tokens.is_empty() {
-            return Ok(Vec::new());
-        }
-        self.parse(sess, |parser| {
-            parser.expect(&token::OpenDelim(token::Paren))?;
-            let mut list = Vec::new();
-            while !parser.eat(&token::CloseDelim(token::Paren)) {
-                list.push(f(parser)?);
-                if !parser.eat(&token::Comma) {
-                   parser.expect(&token::CloseDelim(token::Paren))?;
-                    break
-                }
-            }
-            Ok(list)
-        })
-    }
-
-    pub fn parse_meta<'a>(&self, sess: &'a ParseSess) -> PResult<'a, MetaItem> {
-        Ok(MetaItem {
-            ident: self.path.clone(),
-            node: self.parse(sess, |parser| parser.parse_meta_item_kind())?,
-            span: self.span,
-        })
-    }
-
-    /// Convert self to a normal #[doc="foo"] comment, if it is a
-    /// comment like `///` or `/** */`. (Returns self unchanged for
-    /// non-sugared doc attributes.)
-    pub fn with_desugared_doc<T, F>(&self, f: F) -> T where
-        F: FnOnce(&Attribute) -> T,
-    {
-        if self.is_sugared_doc {
-            let comment = self.value_str().unwrap();
-            let meta = mk_name_value_item_str(
-                Ident::from_str("doc"),
-                dummy_spanned(Symbol::intern(&strip_doc_comment_decoration(&comment.as_str()))));
-            let mut attr = if self.style == ast::AttrStyle::Outer {
-                mk_attr_outer(self.span, self.id, meta)
-            } else {
-                mk_attr_inner(self.span, self.id, meta)
-            };
-            attr.is_sugared_doc = true;
-            f(&attr)
-        } else {
-            f(self)
-        }
-    }
-}
-
-/* Constructors */
-
-pub fn mk_name_value_item_str(ident: Ident, value: Spanned<Symbol>) -> MetaItem {
-    let value = respan(value.span, LitKind::Str(value.node, ast::StrStyle::Cooked));
-    mk_name_value_item(ident.span.to(value.span), ident, value)
-}
-
-pub fn mk_name_value_item(span: Span, ident: Ident, value: ast::Lit) -> MetaItem {
-    MetaItem { ident: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) }
-}
-
-pub fn mk_list_item(span: Span, ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem {
-    MetaItem { ident: Path::from_ident(ident), span, node: MetaItemKind::List(items) }
-}
-
-pub fn mk_word_item(ident: Ident) -> MetaItem {
-    MetaItem { ident: Path::from_ident(ident), span: ident.span, node: MetaItemKind::Word }
-}
-
-pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
-    respan(ident.span, NestedMetaItemKind::MetaItem(mk_word_item(ident)))
-}
-
-pub fn mk_attr_id() -> AttrId {
-    use std::sync::atomic::AtomicUsize;
-    use std::sync::atomic::Ordering;
-
-    static NEXT_ATTR_ID: AtomicUsize = AtomicUsize::new(0);
-
-    let id = NEXT_ATTR_ID.fetch_add(1, Ordering::SeqCst);
-    assert!(id != ::std::usize::MAX);
-    AttrId(id)
-}
-
-/// Returns an inner attribute with the given value.
-pub fn mk_attr_inner(span: Span, id: AttrId, item: MetaItem) -> Attribute {
-    mk_spanned_attr_inner(span, id, item)
-}
-
-/// Returns an inner attribute with the given value and span.
-pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: MetaItem) -> Attribute {
-    Attribute {
-        id,
-        style: ast::AttrStyle::Inner,
-        path: item.ident,
-        tokens: item.node.tokens(item.span),
-        is_sugared_doc: false,
-        span: sp,
-    }
-}
-
-
-/// Returns an outer attribute with the given value.
-pub fn mk_attr_outer(span: Span, id: AttrId, item: MetaItem) -> Attribute {
-    mk_spanned_attr_outer(span, id, item)
-}
-
-/// Returns an outer attribute with the given value and span.
-pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute {
-    Attribute {
-        id,
-        style: ast::AttrStyle::Outer,
-        path: item.ident,
-        tokens: item.node.tokens(item.span),
-        is_sugared_doc: false,
-        span: sp,
-    }
-}
-
-pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute {
-    let style = doc_comment_style(&text.as_str());
-    let lit = respan(span, LitKind::Str(text, ast::StrStyle::Cooked));
-    Attribute {
-        id,
-        style,
-        path: Path::from_ident(Ident::from_str("doc").with_span_pos(span)),
-        tokens: MetaItemKind::NameValue(lit).tokens(span),
-        is_sugared_doc: true,
-        span,
-    }
-}
-
-pub fn list_contains_name(items: &[NestedMetaItem], name: &str) -> bool {
-    items.iter().any(|item| {
-        item.check_name(name)
-    })
-}
-
-pub fn contains_name(attrs: &[Attribute], name: &str) -> bool {
-    attrs.iter().any(|item| {
-        item.check_name(name)
-    })
-}
-
-pub fn find_by_name<'a>(attrs: &'a [Attribute], name: &str) -> Option<&'a Attribute> {
-    attrs.iter().find(|attr| attr.check_name(name))
-}
-
-pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str) -> Option<Symbol> {
-    attrs.iter()
-        .find(|at| at.check_name(name))
-        .and_then(|at| at.value_str())
-}
-
-/// Check if `attrs` contains an attribute like `#![feature(feature_name)]`.
-/// This will not perform any "sanity checks" on the form of the attributes.
-pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool {
-    attrs.iter().any(|item| {
-        item.check_name("feature") &&
-        item.meta_item_list().map(|list| {
-            list.iter().any(|mi| {
-                mi.word().map(|w| w.name() == feature_name)
-                         .unwrap_or(false)
-            })
-        }).unwrap_or(false)
-    })
-}
-
-/* Higher-level applications */
-
-pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
-    first_attr_value_str_by_name(attrs, "crate_name")
-}
-
-#[derive(Copy, Clone, Hash, PartialEq, RustcEncodable, RustcDecodable)]
-pub enum InlineAttr {
-    None,
-    Hint,
-    Always,
-    Never,
-}
-
-#[derive(Copy, Clone, PartialEq)]
-pub enum UnwindAttr {
-    Allowed,
-    Aborts,
-}
-
-/// Determine what `#[unwind]` attribute is present in `attrs`, if any.
-pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Option<UnwindAttr> {
-    let syntax_error = |attr: &Attribute| {
-        mark_used(attr);
-        diagnostic.map(|d| {
-            span_err!(d, attr.span, E0633, "malformed `#[unwind]` attribute");
-        });
-        None
-    };
-
-    attrs.iter().fold(None, |ia, attr| {
-        if attr.path != "unwind" {
-            return ia;
-        }
-        let meta = match attr.meta() {
-            Some(meta) => meta.node,
-            None => return ia,
-        };
-        match meta {
-            MetaItemKind::Word => {
-                syntax_error(attr)
-            }
-            MetaItemKind::List(ref items) => {
-                mark_used(attr);
-                if items.len() != 1 {
-                    syntax_error(attr)
-                } else if list_contains_name(&items[..], "allowed") {
-                    Some(UnwindAttr::Allowed)
-                } else if list_contains_name(&items[..], "aborts") {
-                    Some(UnwindAttr::Aborts)
-                } else {
-                    syntax_error(attr)
-                }
-            }
-            _ => ia,
-        }
-    })
-}
-
-
-/// Tests if a cfg-pattern matches the cfg set
-pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) -> bool {
-    eval_condition(cfg, sess, &mut |cfg| {
-        if let (Some(feats), Some(gated_cfg)) = (features, GatedCfg::gate(cfg)) {
-            gated_cfg.check_and_emit(sess, feats);
-        }
-        sess.config.contains(&(cfg.name(), cfg.value_str()))
-    })
-}
-
-/// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to
-/// evaluate individual items.
-pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F)
-                         -> bool
-    where F: FnMut(&ast::MetaItem) -> bool
-{
-    match cfg.node {
-        ast::MetaItemKind::List(ref mis) => {
-            for mi in mis.iter() {
-                if !mi.is_meta_item() {
-                    handle_errors(&sess.span_diagnostic, mi.span, AttrError::UnsupportedLiteral);
-                    return false;
-                }
-            }
-
-            // The unwraps below may look dangerous, but we've already asserted
-            // that they won't fail with the loop above.
-            match &*cfg.name().as_str() {
-                "any" => mis.iter().any(|mi| {
-                    eval_condition(mi.meta_item().unwrap(), sess, eval)
-                }),
-                "all" => mis.iter().all(|mi| {
-                    eval_condition(mi.meta_item().unwrap(), sess, eval)
-                }),
-                "not" => {
-                    if mis.len() != 1 {
-                        span_err!(sess.span_diagnostic, cfg.span, E0536, "expected 1 cfg-pattern");
-                        return false;
-                    }
-
-                    !eval_condition(mis[0].meta_item().unwrap(), sess, eval)
-                },
-                p => {
-                    span_err!(sess.span_diagnostic, cfg.span, E0537, "invalid predicate `{}`", p);
-                    false
-                }
-            }
-        },
-        ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => {
-            eval(cfg)
-        }
-    }
-}
-
-/// Represents the #[stable], #[unstable], #[rustc_{deprecated,const_unstable}] attributes.
-#[derive(RustcEncodable, RustcDecodable, Clone, Debug, PartialEq, Eq, Hash)]
-pub struct Stability {
-    pub level: StabilityLevel,
-    pub feature: Symbol,
-    pub rustc_depr: Option<RustcDeprecation>,
-    pub rustc_const_unstable: Option<RustcConstUnstable>,
-}
-
-/// The available stability levels.
-#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
-pub enum StabilityLevel {
-    // Reason for the current stability level and the relevant rust-lang issue
-    Unstable { reason: Option<Symbol>, issue: u32 },
-    Stable { since: Symbol },
-}
-
-#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
-pub struct RustcDeprecation {
-    pub since: Symbol,
-    pub reason: Symbol,
-}
-
-#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
-pub struct RustcConstUnstable {
-    pub feature: Symbol,
-}
-
-#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
-pub struct Deprecation {
-    pub since: Option<Symbol>,
-    pub note: Option<Symbol>,
-}
-
-impl StabilityLevel {
-    pub fn is_unstable(&self) -> bool { if let Unstable {..} = *self { true } else { false }}
-    pub fn is_stable(&self) -> bool { if let Stable {..} = *self { true } else { false }}
-}
-
-fn find_stability_generic<'a, I>(diagnostic: &Handler,
-                                 attrs_iter: I,
-                                 item_sp: Span)
-                                 -> Option<Stability>
-    where I: Iterator<Item = &'a Attribute>
-{
-    let mut stab: Option<Stability> = None;
-    let mut rustc_depr: Option<RustcDeprecation> = None;
-    let mut rustc_const_unstable: Option<RustcConstUnstable> = None;
-
-    'outer: for attr in attrs_iter {
-        if ![
-            "rustc_deprecated",
-            "rustc_const_unstable",
-            "unstable",
-            "stable",
-        ].iter().any(|&s| attr.path == s) {
-            continue // not a stability level
-        }
-
-        mark_used(attr);
-
-        let meta = attr.meta();
-        if let Some(MetaItem { node: MetaItemKind::List(ref metas), .. }) = meta {
-            let meta = meta.as_ref().unwrap();
-            let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
-                if item.is_some() {
-                    handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.name()));
-                    return false
-                }
-                if let Some(v) = meta.value_str() {
-                    *item = Some(v);
-                    true
-                } else {
-                    span_err!(diagnostic, meta.span, E0539, "incorrect meta item");
-                    false
-                }
-            };
-
-            macro_rules! get_meta {
-                ($($name:ident),+) => {
-                    $(
-                        let mut $name = None;
-                    )+
-                    for meta in metas {
-                        if let Some(mi) = meta.meta_item() {
-                            match &*mi.name().as_str() {
-                                $(
-                                    stringify!($name)
-                                        => if !get(mi, &mut $name) { continue 'outer },
-                                )+
-                                _ => {
-                                    handle_errors(diagnostic, mi.span,
-                                                  AttrError::UnknownMetaItem(mi.name()));
-                                    continue 'outer
-                                }
-                            }
-                        } else {
-                            handle_errors(diagnostic, meta.span, AttrError::UnsupportedLiteral);
-                            continue 'outer
-                        }
-                    }
-                }
-            }
-
-            match &*meta.name().as_str() {
-                "rustc_deprecated" => {
-                    if rustc_depr.is_some() {
-                        span_err!(diagnostic, item_sp, E0540,
-                                  "multiple rustc_deprecated attributes");
-                        continue 'outer
-                    }
-
-                    get_meta!(since, reason);
-
-                    match (since, reason) {
-                        (Some(since), Some(reason)) => {
-                            rustc_depr = Some(RustcDeprecation {
-                                since,
-                                reason,
-                            })
-                        }
-                        (None, _) => {
-                            handle_errors(diagnostic, attr.span(), AttrError::MissingSince);
-                            continue
-                        }
-                        _ => {
-                            span_err!(diagnostic, attr.span(), E0543, "missing 'reason'");
-                            continue
-                        }
-                    }
-                }
-                "rustc_const_unstable" => {
-                    if rustc_const_unstable.is_some() {
-                        span_err!(diagnostic, item_sp, E0553,
-                                  "multiple rustc_const_unstable attributes");
-                        continue 'outer
-                    }
-
-                    get_meta!(feature);
-                    if let Some(feature) = feature {
-                        rustc_const_unstable = Some(RustcConstUnstable {
-                            feature
-                        });
-                    } else {
-                        span_err!(diagnostic, attr.span(), E0629, "missing 'feature'");
-                        continue
-                    }
-                }
-                "unstable" => {
-                    if stab.is_some() {
-                        handle_errors(diagnostic, attr.span(), AttrError::MultipleStabilityLevels);
-                        break
-                    }
-
-                    let mut feature = None;
-                    let mut reason = None;
-                    let mut issue = None;
-                    for meta in metas {
-                        if let Some(mi) = meta.meta_item() {
-                            match &*mi.name().as_str() {
-                                "feature" => if !get(mi, &mut feature) { continue 'outer },
-                                "reason" => if !get(mi, &mut reason) { continue 'outer },
-                                "issue" => if !get(mi, &mut issue) { continue 'outer },
-                                _ => {
-                                    handle_errors(diagnostic, meta.span,
-                                                  AttrError::UnknownMetaItem(mi.name()));
-                                    continue 'outer
-                                }
-                            }
-                        } else {
-                            handle_errors(diagnostic, meta.span, AttrError::UnsupportedLiteral);
-                            continue 'outer
-                        }
-                    }
-
-                    match (feature, reason, issue) {
-                        (Some(feature), reason, Some(issue)) => {
-                            stab = Some(Stability {
-                                level: Unstable {
-                                    reason,
-                                    issue: {
-                                        if let Ok(issue) = issue.as_str().parse() {
-                                            issue
-                                        } else {
-                                            span_err!(diagnostic, attr.span(), E0545,
-                                                      "incorrect 'issue'");
-                                            continue
-                                        }
-                                    }
-                                },
-                                feature,
-                                rustc_depr: None,
-                                rustc_const_unstable: None,
-                            })
-                        }
-                        (None, _, _) => {
-                            handle_errors(diagnostic, attr.span(), AttrError::MissingFeature);
-                            continue
-                        }
-                        _ => {
-                            span_err!(diagnostic, attr.span(), E0547, "missing 'issue'");
-                            continue
-                        }
-                    }
-                }
-                "stable" => {
-                    if stab.is_some() {
-                        handle_errors(diagnostic, attr.span(), AttrError::MultipleStabilityLevels);
-                        break
-                    }
-
-                    let mut feature = None;
-                    let mut since = None;
-                    for meta in metas {
-                        if let NestedMetaItemKind::MetaItem(ref mi) = meta.node {
-                            match &*mi.name().as_str() {
-                                "feature" => if !get(mi, &mut feature) { continue 'outer },
-                                "since" => if !get(mi, &mut since) { continue 'outer },
-                                _ => {
-                                    handle_errors(diagnostic, meta.span,
-                                                  AttrError::UnknownMetaItem(mi.name()));
-                                    continue 'outer
-                                }
-                            }
-                        } else {
-                            handle_errors(diagnostic, meta.span, AttrError::UnsupportedLiteral);
-                            continue 'outer
-                        }
-                    }
-
-                    match (feature, since) {
-                        (Some(feature), Some(since)) => {
-                            stab = Some(Stability {
-                                level: Stable {
-                                    since,
-                                },
-                                feature,
-                                rustc_depr: None,
-                                rustc_const_unstable: None,
-                            })
-                        }
-                        (None, _) => {
-                            handle_errors(diagnostic, attr.span(), AttrError::MissingFeature);
-                            continue
-                        }
-                        _ => {
-                            handle_errors(diagnostic, attr.span(), AttrError::MissingSince);
-                            continue
-                        }
-                    }
-                }
-                _ => unreachable!()
-            }
-        } else {
-            span_err!(diagnostic, attr.span(), E0548, "incorrect stability attribute type");
-            continue
-        }
-    }
-
-    // Merge the deprecation info into the stability info
-    if let Some(rustc_depr) = rustc_depr {
-        if let Some(ref mut stab) = stab {
-            stab.rustc_depr = Some(rustc_depr);
-        } else {
-            span_err!(diagnostic, item_sp, E0549,
-                      "rustc_deprecated attribute must be paired with \
-                       either stable or unstable attribute");
-        }
-    }
-
-    // Merge the const-unstable info into the stability info
-    if let Some(rustc_const_unstable) = rustc_const_unstable {
-        if let Some(ref mut stab) = stab {
-            stab.rustc_const_unstable = Some(rustc_const_unstable);
-        } else {
-            span_err!(diagnostic, item_sp, E0630,
-                      "rustc_const_unstable attribute must be paired with \
-                       either stable or unstable attribute");
-        }
-    }
-
-    stab
-}
-
-fn find_deprecation_generic<'a, I>(diagnostic: &Handler,
-                                   attrs_iter: I,
-                                   item_sp: Span)
-                                   -> Option<Deprecation>
-    where I: Iterator<Item = &'a Attribute>
-{
-    let mut depr: Option<Deprecation> = None;
-
-    'outer: for attr in attrs_iter {
-        if attr.path != "deprecated" {
-            continue
-        }
-
-        mark_used(attr);
-
-        if depr.is_some() {
-            span_err!(diagnostic, item_sp, E0550, "multiple deprecated attributes");
-            break
-        }
-
-        depr = if let Some(metas) = attr.meta_item_list() {
-            let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
-                if item.is_some() {
-                    handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.name()));
-                    return false
-                }
-                if let Some(v) = meta.value_str() {
-                    *item = Some(v);
-                    true
-                } else {
-                    span_err!(diagnostic, meta.span, E0551, "incorrect meta item");
-                    false
-                }
-            };
-
-            let mut since = None;
-            let mut note = None;
-            for meta in metas {
-                if let NestedMetaItemKind::MetaItem(ref mi) = meta.node {
-                    match &*mi.name().as_str() {
-                        "since" => if !get(mi, &mut since) { continue 'outer },
-                        "note" => if !get(mi, &mut note) { continue 'outer },
-                        _ => {
-                            handle_errors(diagnostic, meta.span,
-                                          AttrError::UnknownMetaItem(mi.name()));
-                            continue 'outer
-                        }
-                    }
-                } else {
-                    handle_errors(diagnostic, meta.span, AttrError::UnsupportedLiteral);
-                    continue 'outer
-                }
-            }
-
-            Some(Deprecation {since: since, note: note})
-        } else {
-            Some(Deprecation{since: None, note: None})
-        }
-    }
-
-    depr
-}
-
-/// Find the first stability attribute. `None` if none exists.
-pub fn find_stability(diagnostic: &Handler, attrs: &[Attribute],
-                      item_sp: Span) -> Option<Stability> {
-    find_stability_generic(diagnostic, attrs.iter(), item_sp)
-}
-
-/// Find the deprecation attribute. `None` if none exists.
-pub fn find_deprecation(diagnostic: &Handler, attrs: &[Attribute],
-                        item_sp: Span) -> Option<Deprecation> {
-    find_deprecation_generic(diagnostic, attrs.iter(), item_sp)
-}
-
-
-/// Parse #[repr(...)] forms.
-///
-/// Valid repr contents: any of the primitive integral type names (see
-/// `int_type_of_word`, below) to specify enum discriminant type; `C`, to use
-/// the same discriminant size that the corresponding C enum would or C
-/// structure layout, `packed` to remove padding, and `transparent` to elegate representation
-/// concerns to the only non-ZST field.
-pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr> {
-    let mut acc = Vec::new();
-    if attr.path == "repr" {
-        if let Some(items) = attr.meta_item_list() {
-            mark_used(attr);
-            for item in items {
-                if !item.is_meta_item() {
-                    handle_errors(diagnostic, item.span, AttrError::UnsupportedLiteral);
-                    continue
-                }
-
-                let mut recognised = false;
-                if let Some(mi) = item.word() {
-                    let word = &*mi.name().as_str();
-                    let hint = match word {
-                        "C" => Some(ReprC),
-                        "packed" => Some(ReprPacked(1)),
-                        "simd" => Some(ReprSimd),
-                        "transparent" => Some(ReprTransparent),
-                        _ => match int_type_of_word(word) {
-                            Some(ity) => Some(ReprInt(ity)),
-                            None => {
-                                None
-                            }
-                        }
-                    };
-
-                    if let Some(h) = hint {
-                        recognised = true;
-                        acc.push(h);
-                    }
-                } else if let Some((name, value)) = item.name_value_literal() {
-                    let parse_alignment = |node: &ast::LitKind| -> Result<u32, &'static str> {
-                        if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node {
-                            if literal.is_power_of_two() {
-                                // rustc::ty::layout::Align restricts align to <= 2^29
-                                if *literal <= 1 << 29 {
-                                    Ok(*literal as u32)
-                                } else {
-                                    Err("larger than 2^29")
-                                }
-                            } else {
-                                Err("not a power of two")
-                            }
-                        } else {
-                            Err("not an unsuffixed integer")
-                        }
-                    };
-
-                    let mut literal_error = None;
-                    if name == "align" {
-                        recognised = true;
-                        match parse_alignment(&value.node) {
-                            Ok(literal) => acc.push(ReprAlign(literal)),
-                            Err(message) => literal_error = Some(message)
-                        };
-                    }
-                    else if name == "packed" {
-                        recognised = true;
-                        match parse_alignment(&value.node) {
-                            Ok(literal) => acc.push(ReprPacked(literal)),
-                            Err(message) => literal_error = Some(message)
-                        };
-                    }
-                    if let Some(literal_error) = literal_error {
-                        span_err!(diagnostic, item.span, E0589,
-                                  "invalid `repr(align)` attribute: {}", literal_error);
-                    }
-                } else {
-                    if let Some(meta_item) = item.meta_item() {
-                        if meta_item.name() == "align" {
-                            if let MetaItemKind::NameValue(ref value) = meta_item.node {
-                                recognised = true;
-                                let mut err = struct_span_err!(diagnostic, item.span, E0693,
-                                    "incorrect `repr(align)` attribute format");
-                                match value.node {
-                                    ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
-                                        err.span_suggestion_with_applicability(
-                                            item.span,
-                                            "use parentheses instead",
-                                            format!("align({})", int),
-                                            Applicability::MachineApplicable
-                                        );
-                                    }
-                                    ast::LitKind::Str(s, _) => {
-                                        err.span_suggestion_with_applicability(
-                                            item.span,
-                                            "use parentheses instead",
-                                            format!("align({})", s),
-                                            Applicability::MachineApplicable
-                                        );
-                                    }
-                                    _ => {}
-                                }
-                                err.emit();
-                            }
-                        }
-                    }
-                }
-                if !recognised {
-                    // Not a word we recognize
-                    span_err!(diagnostic, item.span, E0552,
-                              "unrecognized representation hint");
-                }
-            }
-        }
-    }
-    acc
-}
-
-fn int_type_of_word(s: &str) -> Option<IntType> {
-    match s {
-        "i8" => Some(SignedInt(ast::IntTy::I8)),
-        "u8" => Some(UnsignedInt(ast::UintTy::U8)),
-        "i16" => Some(SignedInt(ast::IntTy::I16)),
-        "u16" => Some(UnsignedInt(ast::UintTy::U16)),
-        "i32" => Some(SignedInt(ast::IntTy::I32)),
-        "u32" => Some(UnsignedInt(ast::UintTy::U32)),
-        "i64" => Some(SignedInt(ast::IntTy::I64)),
-        "u64" => Some(UnsignedInt(ast::UintTy::U64)),
-        "i128" => Some(SignedInt(ast::IntTy::I128)),
-        "u128" => Some(UnsignedInt(ast::UintTy::U128)),
-        "isize" => Some(SignedInt(ast::IntTy::Isize)),
-        "usize" => Some(UnsignedInt(ast::UintTy::Usize)),
-        _ => None
-    }
-}
-
-#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
-pub enum ReprAttr {
-    ReprInt(IntType),
-    ReprC,
-    ReprPacked(u32),
-    ReprSimd,
-    ReprTransparent,
-    ReprAlign(u32),
-}
-
-#[derive(Eq, Hash, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
-pub enum IntType {
-    SignedInt(ast::IntTy),
-    UnsignedInt(ast::UintTy)
-}
-
-impl IntType {
-    #[inline]
-    pub fn is_signed(self) -> bool {
-        match self {
-            SignedInt(..) => true,
-            UnsignedInt(..) => false
-        }
-    }
-}
-
-impl MetaItem {
-    fn tokens(&self) -> TokenStream {
-        let mut idents = vec![];
-        let mut last_pos = BytePos(0 as u32);
-        for (i, segment) in self.ident.segments.iter().enumerate() {
-            let is_first = i == 0;
-            if !is_first {
-                let mod_sep_span = Span::new(last_pos,
-                                             segment.ident.span.lo(),
-                                             segment.ident.span.ctxt());
-                idents.push(TokenTree::Token(mod_sep_span, Token::ModSep).into());
-            }
-            idents.push(TokenTree::Token(segment.ident.span,
-                                         Token::from_ast_ident(segment.ident)).into());
-            last_pos = segment.ident.span.hi();
-        }
-        idents.push(self.node.tokens(self.span));
-        TokenStream::concat(idents)
-    }
-
-    fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItem>
-        where I: Iterator<Item = TokenTree>,
-    {
-        // FIXME: Share code with `parse_path`.
-        let ident = match tokens.next() {
-            Some(TokenTree::Token(span, Token::Ident(ident, _))) => {
-                if let Some(TokenTree::Token(_, Token::ModSep)) = tokens.peek() {
-                    let mut segments = vec![PathSegment::from_ident(ident.with_span_pos(span))];
-                    tokens.next();
-                    loop {
-                        if let Some(TokenTree::Token(span,
-                                                     Token::Ident(ident, _))) = tokens.next() {
-                            segments.push(PathSegment::from_ident(ident.with_span_pos(span)));
-                        } else {
-                            return None;
-                        }
-                        if let Some(TokenTree::Token(_, Token::ModSep)) = tokens.peek() {
-                            tokens.next();
-                        } else {
-                            break;
-                        }
-                    }
-                    let span = span.with_hi(segments.last().unwrap().ident.span.hi());
-                    Path { span, segments }
-                } else {
-                    Path::from_ident(ident.with_span_pos(span))
-                }
-            }
-            Some(TokenTree::Token(_, Token::Interpolated(ref nt))) => match nt.0 {
-                token::Nonterminal::NtIdent(ident, _) => Path::from_ident(ident),
-                token::Nonterminal::NtMeta(ref meta) => return Some(meta.clone()),
-                token::Nonterminal::NtPath(ref path) => path.clone(),
-                _ => return None,
-            },
-            _ => return None,
-        };
-        let list_closing_paren_pos = tokens.peek().map(|tt| tt.span().hi());
-        let node = MetaItemKind::from_tokens(tokens)?;
-        let hi = match node {
-            MetaItemKind::NameValue(ref lit) => lit.span.hi(),
-            MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(ident.span.hi()),
-            _ => ident.span.hi(),
-        };
-        let span = ident.span.with_hi(hi);
-        Some(MetaItem { ident, node, span })
-    }
-}
-
-impl MetaItemKind {
-    pub fn tokens(&self, span: Span) -> TokenStream {
-        match *self {
-            MetaItemKind::Word => TokenStream::empty(),
-            MetaItemKind::NameValue(ref lit) => {
-                TokenStream::concat(vec![TokenTree::Token(span, Token::Eq).into(), lit.tokens()])
-            }
-            MetaItemKind::List(ref list) => {
-                let mut tokens = Vec::new();
-                for (i, item) in list.iter().enumerate() {
-                    if i > 0 {
-                        tokens.push(TokenTree::Token(span, Token::Comma).into());
-                    }
-                    tokens.push(item.node.tokens());
-                }
-                TokenTree::Delimited(span, Delimited {
-                    delim: token::Paren,
-                    tts: TokenStream::concat(tokens).into(),
-                }).into()
-            }
-        }
-    }
-
-    fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItemKind>
-        where I: Iterator<Item = TokenTree>,
-    {
-        let delimited = match tokens.peek().cloned() {
-            Some(TokenTree::Token(_, token::Eq)) => {
-                tokens.next();
-                return if let Some(TokenTree::Token(span, token)) = tokens.next() {
-                    LitKind::from_token(token)
-                        .map(|lit| MetaItemKind::NameValue(Spanned { node: lit, span: span }))
-                } else {
-                    None
-                };
-            }
-            Some(TokenTree::Delimited(_, ref delimited)) if delimited.delim == token::Paren => {
-                tokens.next();
-                delimited.stream()
-            }
-            _ => return Some(MetaItemKind::Word),
-        };
-
-        let mut tokens = delimited.into_trees().peekable();
-        let mut result = Vec::new();
-        while let Some(..) = tokens.peek() {
-            let item = NestedMetaItemKind::from_tokens(&mut tokens)?;
-            result.push(respan(item.span(), item));
-            match tokens.next() {
-                None | Some(TokenTree::Token(_, Token::Comma)) => {}
-                _ => return None,
-            }
-        }
-        Some(MetaItemKind::List(result))
-    }
-}
-
-impl NestedMetaItemKind {
-    fn span(&self) -> Span {
-        match *self {
-            NestedMetaItemKind::MetaItem(ref item) => item.span,
-            NestedMetaItemKind::Literal(ref lit) => lit.span,
-        }
-    }
-
-    fn tokens(&self) -> TokenStream {
-        match *self {
-            NestedMetaItemKind::MetaItem(ref item) => item.tokens(),
-            NestedMetaItemKind::Literal(ref lit) => lit.tokens(),
-        }
-    }
-
-    fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<NestedMetaItemKind>
-        where I: Iterator<Item = TokenTree>,
-    {
-        if let Some(TokenTree::Token(span, token)) = tokens.peek().cloned() {
-            if let Some(node) = LitKind::from_token(token) {
-                tokens.next();
-                return Some(NestedMetaItemKind::Literal(respan(span, node)));
-            }
-        }
-
-        MetaItem::from_tokens(tokens).map(NestedMetaItemKind::MetaItem)
-    }
-}
-
-impl Lit {
-    fn tokens(&self) -> TokenStream {
-        TokenTree::Token(self.span, self.node.token()).into()
-    }
-}
-
-impl LitKind {
-    fn token(&self) -> Token {
-        use std::ascii;
-
-        match *self {
-            LitKind::Str(string, ast::StrStyle::Cooked) => {
-                let escaped = string.as_str().escape_default();
-                Token::Literal(token::Lit::Str_(Symbol::intern(&escaped)), None)
-            }
-            LitKind::Str(string, ast::StrStyle::Raw(n)) => {
-                Token::Literal(token::Lit::StrRaw(string, n), None)
-            }
-            LitKind::ByteStr(ref bytes) => {
-                let string = bytes.iter().cloned().flat_map(ascii::escape_default)
-                    .map(Into::<char>::into).collect::<String>();
-                Token::Literal(token::Lit::ByteStr(Symbol::intern(&string)), None)
-            }
-            LitKind::Byte(byte) => {
-                let string: String = ascii::escape_default(byte).map(Into::<char>::into).collect();
-                Token::Literal(token::Lit::Byte(Symbol::intern(&string)), None)
-            }
-            LitKind::Char(ch) => {
-                let string: String = ch.escape_default().map(Into::<char>::into).collect();
-                Token::Literal(token::Lit::Char(Symbol::intern(&string)), None)
-            }
-            LitKind::Int(n, ty) => {
-                let suffix = match ty {
-                    ast::LitIntType::Unsigned(ty) => Some(Symbol::intern(ty.ty_to_string())),
-                    ast::LitIntType::Signed(ty) => Some(Symbol::intern(ty.ty_to_string())),
-                    ast::LitIntType::Unsuffixed => None,
-                };
-                Token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())), suffix)
-            }
-            LitKind::Float(symbol, ty) => {
-                Token::Literal(token::Lit::Float(symbol), Some(Symbol::intern(ty.ty_to_string())))
-            }
-            LitKind::FloatUnsuffixed(symbol) => Token::Literal(token::Lit::Float(symbol), None),
-            LitKind::Bool(value) => Token::Ident(Ident::with_empty_ctxt(Symbol::intern(if value {
-                "true"
-            } else {
-                "false"
-            })), false),
-        }
-    }
-
-    fn from_token(token: Token) -> Option<LitKind> {
-        match token {
-            Token::Ident(ident, false) if ident.name == "true" => Some(LitKind::Bool(true)),
-            Token::Ident(ident, false) if ident.name == "false" => Some(LitKind::Bool(false)),
-            Token::Interpolated(ref nt) => match nt.0 {
-                token::NtExpr(ref v) | token::NtLiteral(ref v) => match v.node {
-                    ExprKind::Lit(ref lit) => Some(lit.node.clone()),
-                    _ => None,
-                },
-                _ => None,
-            },
-            Token::Literal(lit, suf) => {
-                let (suffix_illegal, result) = parse::lit_token(lit, suf, None);
-                if suffix_illegal && suf.is_some() {
-                    return None;
-                }
-                result
-            }
-            _ => None,
-        }
-    }
-}
-
-pub trait HasAttrs: Sized {
-    fn attrs(&self) -> &[ast::Attribute];
-    fn map_attrs<F: FnOnce(Vec<ast::Attribute>) -> Vec<ast::Attribute>>(self, f: F) -> Self;
-}
-
-impl<T: HasAttrs> HasAttrs for Spanned<T> {
-    fn attrs(&self) -> &[ast::Attribute] { self.node.attrs() }
-    fn map_attrs<F: FnOnce(Vec<ast::Attribute>) -> Vec<ast::Attribute>>(self, f: F) -> Self {
-        respan(self.span, self.node.map_attrs(f))
-    }
-}
-
-impl HasAttrs for Vec<Attribute> {
-    fn attrs(&self) -> &[Attribute] {
-        self
-    }
-    fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
-        f(self)
-    }
-}
-
-impl HasAttrs for ThinVec<Attribute> {
-    fn attrs(&self) -> &[Attribute] {
-        self
-    }
-    fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
-        f(self.into()).into()
-    }
-}
-
-impl<T: HasAttrs + 'static> HasAttrs for P<T> {
-    fn attrs(&self) -> &[Attribute] {
-        (**self).attrs()
-    }
-    fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
-        self.map(|t| t.map_attrs(f))
-    }
-}
-
-impl HasAttrs for StmtKind {
-    fn attrs(&self) -> &[Attribute] {
-        match *self {
-            StmtKind::Local(ref local) => local.attrs(),
-            StmtKind::Item(..) => &[],
-            StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.attrs(),
-            StmtKind::Mac(ref mac) => {
-                let (_, _, ref attrs) = **mac;
-                attrs.attrs()
-            }
-        }
-    }
-
-    fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
-        match self {
-            StmtKind::Local(local) => StmtKind::Local(local.map_attrs(f)),
-            StmtKind::Item(..) => self,
-            StmtKind::Expr(expr) => StmtKind::Expr(expr.map_attrs(f)),
-            StmtKind::Semi(expr) => StmtKind::Semi(expr.map_attrs(f)),
-            StmtKind::Mac(mac) => StmtKind::Mac(mac.map(|(mac, style, attrs)| {
-                (mac, style, attrs.map_attrs(f))
-            })),
-        }
-    }
-}
-
-impl HasAttrs for Stmt {
-    fn attrs(&self) -> &[ast::Attribute] { self.node.attrs() }
-    fn map_attrs<F: FnOnce(Vec<ast::Attribute>) -> Vec<ast::Attribute>>(self, f: F) -> Self {
-        Stmt { id: self.id, node: self.node.map_attrs(f), span: self.span }
-    }
-}
-
-impl HasAttrs for GenericParam {
-    fn attrs(&self) -> &[ast::Attribute] {
-        &self.attrs
-    }
-
-    fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(mut self, f: F) -> Self {
-        self.attrs = self.attrs.map_attrs(f);
-        self
-    }
-}
-
-macro_rules! derive_has_attrs {
-    ($($ty:path),*) => { $(
-        impl HasAttrs for $ty {
-            fn attrs(&self) -> &[Attribute] {
-                &self.attrs
-            }
-
-            fn map_attrs<F>(mut self, f: F) -> Self
-                where F: FnOnce(Vec<Attribute>) -> Vec<Attribute>,
-            {
-                self.attrs = self.attrs.map_attrs(f);
-                self
-            }
-        }
-    )* }
-}
-
-derive_has_attrs! {
-    Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::ImplItem, ast::TraitItem, ast::Arm,
-    ast::Field, ast::FieldPat, ast::Variant_
-}
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
new file mode 100644 (file)
index 0000000..ecd52a6
--- /dev/null
@@ -0,0 +1,730 @@
+// 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.
+
+//! Parsing and validation of builtin attributes
+
+use ast::{self, Attribute, MetaItem, Name, NestedMetaItemKind};
+use errors::{Applicability, Handler};
+use feature_gate::{Features, GatedCfg};
+use parse::ParseSess;
+use syntax_pos::{symbol::Symbol, Span};
+
+use super::{list_contains_name, mark_used, MetaItemKind};
+
+enum AttrError {
+    MultipleItem(Name),
+    UnknownMetaItem(Name, &'static [&'static str]),
+    MissingSince,
+    MissingFeature,
+    MultipleStabilityLevels,
+    UnsupportedLiteral
+}
+
+fn handle_errors(diag: &Handler, span: Span, error: AttrError) {
+    match error {
+        AttrError::MultipleItem(item) => span_err!(diag, span, E0538,
+                                                   "multiple '{}' items", item),
+        AttrError::UnknownMetaItem(item, expected) => {
+            let expected = expected
+                .iter()
+                .map(|name| format!("`{}`", name))
+                .collect::<Vec<_>>();
+            struct_span_err!(diag, span, E0541, "unknown meta item '{}'", item)
+                .span_label(span, format!("expected one of {}", expected.join(", ")))
+                .emit();
+        }
+        AttrError::MissingSince => span_err!(diag, span, E0542, "missing 'since'"),
+        AttrError::MissingFeature => span_err!(diag, span, E0546, "missing 'feature'"),
+        AttrError::MultipleStabilityLevels => span_err!(diag, span, E0544,
+                                                        "multiple stability levels"),
+        AttrError::UnsupportedLiteral => span_err!(diag, span, E0565, "unsupported literal"),
+    }
+}
+
+#[derive(Copy, Clone, Hash, PartialEq, RustcEncodable, RustcDecodable)]
+pub enum InlineAttr {
+    None,
+    Hint,
+    Always,
+    Never,
+}
+
+#[derive(Copy, Clone, PartialEq)]
+pub enum UnwindAttr {
+    Allowed,
+    Aborts,
+}
+
+/// Determine what `#[unwind]` attribute is present in `attrs`, if any.
+pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Option<UnwindAttr> {
+    let syntax_error = |attr: &Attribute| {
+        mark_used(attr);
+        diagnostic.map(|d| {
+            span_err!(d, attr.span, E0633, "malformed `#[unwind]` attribute");
+        });
+        None
+    };
+
+    attrs.iter().fold(None, |ia, attr| {
+        if attr.path != "unwind" {
+            return ia;
+        }
+        let meta = match attr.meta() {
+            Some(meta) => meta.node,
+            None => return ia,
+        };
+        match meta {
+            MetaItemKind::Word => {
+                syntax_error(attr)
+            }
+            MetaItemKind::List(ref items) => {
+                mark_used(attr);
+                if items.len() != 1 {
+                    syntax_error(attr)
+                } else if list_contains_name(&items[..], "allowed") {
+                    Some(UnwindAttr::Allowed)
+                } else if list_contains_name(&items[..], "aborts") {
+                    Some(UnwindAttr::Aborts)
+                } else {
+                    syntax_error(attr)
+                }
+            }
+            _ => ia,
+        }
+    })
+}
+
+/// Represents the #[stable], #[unstable], #[rustc_{deprecated,const_unstable}] attributes.
+#[derive(RustcEncodable, RustcDecodable, Clone, Debug, PartialEq, Eq, Hash)]
+pub struct Stability {
+    pub level: StabilityLevel,
+    pub feature: Symbol,
+    pub rustc_depr: Option<RustcDeprecation>,
+    pub rustc_const_unstable: Option<RustcConstUnstable>,
+}
+
+/// The available stability levels.
+#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
+pub enum StabilityLevel {
+    // Reason for the current stability level and the relevant rust-lang issue
+    Unstable { reason: Option<Symbol>, issue: u32 },
+    Stable { since: Symbol },
+}
+
+impl StabilityLevel {
+    pub fn is_unstable(&self) -> bool {
+        if let StabilityLevel::Unstable {..} = *self {
+            true
+        } else {
+            false
+        }
+    }
+    pub fn is_stable(&self) -> bool {
+        if let StabilityLevel::Stable {..} = *self {
+            true
+        } else {
+            false
+        }
+    }
+}
+
+#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
+pub struct RustcDeprecation {
+    pub since: Symbol,
+    pub reason: Symbol,
+}
+
+#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
+pub struct RustcConstUnstable {
+    pub feature: Symbol,
+}
+
+/// Check if `attrs` contains an attribute like `#![feature(feature_name)]`.
+/// This will not perform any "sanity checks" on the form of the attributes.
+pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool {
+    attrs.iter().any(|item| {
+        item.check_name("feature") &&
+        item.meta_item_list().map(|list| {
+            list.iter().any(|mi| {
+                mi.word().map(|w| w.name() == feature_name)
+                         .unwrap_or(false)
+            })
+        }).unwrap_or(false)
+    })
+}
+
+/// Find the first stability attribute. `None` if none exists.
+pub fn find_stability(diagnostic: &Handler, attrs: &[Attribute],
+                      item_sp: Span) -> Option<Stability> {
+    find_stability_generic(diagnostic, attrs.iter(), item_sp)
+}
+
+fn find_stability_generic<'a, I>(diagnostic: &Handler,
+                                 attrs_iter: I,
+                                 item_sp: Span)
+                                 -> Option<Stability>
+    where I: Iterator<Item = &'a Attribute>
+{
+    use self::StabilityLevel::*;
+
+    let mut stab: Option<Stability> = None;
+    let mut rustc_depr: Option<RustcDeprecation> = None;
+    let mut rustc_const_unstable: Option<RustcConstUnstable> = None;
+
+    'outer: for attr in attrs_iter {
+        if ![
+            "rustc_deprecated",
+            "rustc_const_unstable",
+            "unstable",
+            "stable",
+        ].iter().any(|&s| attr.path == s) {
+            continue // not a stability level
+        }
+
+        mark_used(attr);
+
+        let meta = attr.meta();
+        if let Some(MetaItem { node: MetaItemKind::List(ref metas), .. }) = meta {
+            let meta = meta.as_ref().unwrap();
+            let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
+                if item.is_some() {
+                    handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.name()));
+                    return false
+                }
+                if let Some(v) = meta.value_str() {
+                    *item = Some(v);
+                    true
+                } else {
+                    span_err!(diagnostic, meta.span, E0539, "incorrect meta item");
+                    false
+                }
+            };
+
+            macro_rules! get_meta {
+                ($($name:ident),+) => {
+                    $(
+                        let mut $name = None;
+                    )+
+                    for meta in metas {
+                        if let Some(mi) = meta.meta_item() {
+                            match &*mi.name().as_str() {
+                                $(
+                                    stringify!($name)
+                                        => if !get(mi, &mut $name) { continue 'outer },
+                                )+
+                                _ => {
+                                    let expected = &[ $( stringify!($name) ),+ ];
+                                    handle_errors(
+                                        diagnostic,
+                                        mi.span,
+                                        AttrError::UnknownMetaItem(mi.name(), expected));
+                                    continue 'outer
+                                }
+                            }
+                        } else {
+                            handle_errors(diagnostic, meta.span, AttrError::UnsupportedLiteral);
+                            continue 'outer
+                        }
+                    }
+                }
+            }
+
+            match &*meta.name().as_str() {
+                "rustc_deprecated" => {
+                    if rustc_depr.is_some() {
+                        span_err!(diagnostic, item_sp, E0540,
+                                  "multiple rustc_deprecated attributes");
+                        continue 'outer
+                    }
+
+                    get_meta!(since, reason);
+
+                    match (since, reason) {
+                        (Some(since), Some(reason)) => {
+                            rustc_depr = Some(RustcDeprecation {
+                                since,
+                                reason,
+                            })
+                        }
+                        (None, _) => {
+                            handle_errors(diagnostic, attr.span(), AttrError::MissingSince);
+                            continue
+                        }
+                        _ => {
+                            span_err!(diagnostic, attr.span(), E0543, "missing 'reason'");
+                            continue
+                        }
+                    }
+                }
+                "rustc_const_unstable" => {
+                    if rustc_const_unstable.is_some() {
+                        span_err!(diagnostic, item_sp, E0553,
+                                  "multiple rustc_const_unstable attributes");
+                        continue 'outer
+                    }
+
+                    get_meta!(feature);
+                    if let Some(feature) = feature {
+                        rustc_const_unstable = Some(RustcConstUnstable {
+                            feature
+                        });
+                    } else {
+                        span_err!(diagnostic, attr.span(), E0629, "missing 'feature'");
+                        continue
+                    }
+                }
+                "unstable" => {
+                    if stab.is_some() {
+                        handle_errors(diagnostic, attr.span(), AttrError::MultipleStabilityLevels);
+                        break
+                    }
+
+                    let mut feature = None;
+                    let mut reason = None;
+                    let mut issue = None;
+                    for meta in metas {
+                        if let Some(mi) = meta.meta_item() {
+                            match &*mi.name().as_str() {
+                                "feature" => if !get(mi, &mut feature) { continue 'outer },
+                                "reason" => if !get(mi, &mut reason) { continue 'outer },
+                                "issue" => if !get(mi, &mut issue) { continue 'outer },
+                                _ => {
+                                    handle_errors(
+                                        diagnostic,
+                                        meta.span,
+                                        AttrError::UnknownMetaItem(
+                                            mi.name(),
+                                            &["feature", "reason", "issue"]
+                                        ),
+                                    );
+                                    continue 'outer
+                                }
+                            }
+                        } else {
+                            handle_errors(diagnostic, meta.span, AttrError::UnsupportedLiteral);
+                            continue 'outer
+                        }
+                    }
+
+                    match (feature, reason, issue) {
+                        (Some(feature), reason, Some(issue)) => {
+                            stab = Some(Stability {
+                                level: Unstable {
+                                    reason,
+                                    issue: {
+                                        if let Ok(issue) = issue.as_str().parse() {
+                                            issue
+                                        } else {
+                                            span_err!(diagnostic, attr.span(), E0545,
+                                                      "incorrect 'issue'");
+                                            continue
+                                        }
+                                    }
+                                },
+                                feature,
+                                rustc_depr: None,
+                                rustc_const_unstable: None,
+                            })
+                        }
+                        (None, _, _) => {
+                            handle_errors(diagnostic, attr.span(), AttrError::MissingFeature);
+                            continue
+                        }
+                        _ => {
+                            span_err!(diagnostic, attr.span(), E0547, "missing 'issue'");
+                            continue
+                        }
+                    }
+                }
+                "stable" => {
+                    if stab.is_some() {
+                        handle_errors(diagnostic, attr.span(), AttrError::MultipleStabilityLevels);
+                        break
+                    }
+
+                    let mut feature = None;
+                    let mut since = None;
+                    for meta in metas {
+                        if let NestedMetaItemKind::MetaItem(ref mi) = meta.node {
+                            match &*mi.name().as_str() {
+                                "feature" => if !get(mi, &mut feature) { continue 'outer },
+                                "since" => if !get(mi, &mut since) { continue 'outer },
+                                _ => {
+                                    handle_errors(
+                                        diagnostic,
+                                        meta.span,
+                                        AttrError::UnknownMetaItem(mi.name(), &["since", "note"]),
+                                    );
+                                    continue 'outer
+                                }
+                            }
+                        } else {
+                            handle_errors(diagnostic, meta.span, AttrError::UnsupportedLiteral);
+                            continue 'outer
+                        }
+                    }
+
+                    match (feature, since) {
+                        (Some(feature), Some(since)) => {
+                            stab = Some(Stability {
+                                level: Stable {
+                                    since,
+                                },
+                                feature,
+                                rustc_depr: None,
+                                rustc_const_unstable: None,
+                            })
+                        }
+                        (None, _) => {
+                            handle_errors(diagnostic, attr.span(), AttrError::MissingFeature);
+                            continue
+                        }
+                        _ => {
+                            handle_errors(diagnostic, attr.span(), AttrError::MissingSince);
+                            continue
+                        }
+                    }
+                }
+                _ => unreachable!()
+            }
+        } else {
+            span_err!(diagnostic, attr.span(), E0548, "incorrect stability attribute type");
+            continue
+        }
+    }
+
+    // Merge the deprecation info into the stability info
+    if let Some(rustc_depr) = rustc_depr {
+        if let Some(ref mut stab) = stab {
+            stab.rustc_depr = Some(rustc_depr);
+        } else {
+            span_err!(diagnostic, item_sp, E0549,
+                      "rustc_deprecated attribute must be paired with \
+                       either stable or unstable attribute");
+        }
+    }
+
+    // Merge the const-unstable info into the stability info
+    if let Some(rustc_const_unstable) = rustc_const_unstable {
+        if let Some(ref mut stab) = stab {
+            stab.rustc_const_unstable = Some(rustc_const_unstable);
+        } else {
+            span_err!(diagnostic, item_sp, E0630,
+                      "rustc_const_unstable attribute must be paired with \
+                       either stable or unstable attribute");
+        }
+    }
+
+    stab
+}
+
+pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
+    super::first_attr_value_str_by_name(attrs, "crate_name")
+}
+
+/// Tests if a cfg-pattern matches the cfg set
+pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) -> bool {
+    eval_condition(cfg, sess, &mut |cfg| {
+        if let (Some(feats), Some(gated_cfg)) = (features, GatedCfg::gate(cfg)) {
+            gated_cfg.check_and_emit(sess, feats);
+        }
+        sess.config.contains(&(cfg.name(), cfg.value_str()))
+    })
+}
+
+/// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to
+/// evaluate individual items.
+pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F)
+                         -> bool
+    where F: FnMut(&ast::MetaItem) -> bool
+{
+    match cfg.node {
+        ast::MetaItemKind::List(ref mis) => {
+            for mi in mis.iter() {
+                if !mi.is_meta_item() {
+                    handle_errors(&sess.span_diagnostic, mi.span, AttrError::UnsupportedLiteral);
+                    return false;
+                }
+            }
+
+            // The unwraps below may look dangerous, but we've already asserted
+            // that they won't fail with the loop above.
+            match &*cfg.name().as_str() {
+                "any" => mis.iter().any(|mi| {
+                    eval_condition(mi.meta_item().unwrap(), sess, eval)
+                }),
+                "all" => mis.iter().all(|mi| {
+                    eval_condition(mi.meta_item().unwrap(), sess, eval)
+                }),
+                "not" => {
+                    if mis.len() != 1 {
+                        span_err!(sess.span_diagnostic, cfg.span, E0536, "expected 1 cfg-pattern");
+                        return false;
+                    }
+
+                    !eval_condition(mis[0].meta_item().unwrap(), sess, eval)
+                },
+                p => {
+                    span_err!(sess.span_diagnostic, cfg.span, E0537, "invalid predicate `{}`", p);
+                    false
+                }
+            }
+        },
+        ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => {
+            eval(cfg)
+        }
+    }
+}
+
+
+#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
+pub struct Deprecation {
+    pub since: Option<Symbol>,
+    pub note: Option<Symbol>,
+}
+
+/// Find the deprecation attribute. `None` if none exists.
+pub fn find_deprecation(diagnostic: &Handler, attrs: &[Attribute],
+                        item_sp: Span) -> Option<Deprecation> {
+    find_deprecation_generic(diagnostic, attrs.iter(), item_sp)
+}
+
+fn find_deprecation_generic<'a, I>(diagnostic: &Handler,
+                                   attrs_iter: I,
+                                   item_sp: Span)
+                                   -> Option<Deprecation>
+    where I: Iterator<Item = &'a Attribute>
+{
+    let mut depr: Option<Deprecation> = None;
+
+    'outer: for attr in attrs_iter {
+        if attr.path != "deprecated" {
+            continue
+        }
+
+        mark_used(attr);
+
+        if depr.is_some() {
+            span_err!(diagnostic, item_sp, E0550, "multiple deprecated attributes");
+            break
+        }
+
+        depr = if let Some(metas) = attr.meta_item_list() {
+            let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
+                if item.is_some() {
+                    handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.name()));
+                    return false
+                }
+                if let Some(v) = meta.value_str() {
+                    *item = Some(v);
+                    true
+                } else {
+                    span_err!(diagnostic, meta.span, E0551, "incorrect meta item");
+                    false
+                }
+            };
+
+            let mut since = None;
+            let mut note = None;
+            for meta in metas {
+                if let NestedMetaItemKind::MetaItem(ref mi) = meta.node {
+                    match &*mi.name().as_str() {
+                        "since" => if !get(mi, &mut since) { continue 'outer },
+                        "note" => if !get(mi, &mut note) { continue 'outer },
+                        _ => {
+                            handle_errors(
+                                diagnostic,
+                                meta.span,
+                                AttrError::UnknownMetaItem(mi.name(), &["since", "note"]),
+                            );
+                            continue 'outer
+                        }
+                    }
+                } else {
+                    handle_errors(diagnostic, meta.span, AttrError::UnsupportedLiteral);
+                    continue 'outer
+                }
+            }
+
+            Some(Deprecation {since: since, note: note})
+        } else {
+            Some(Deprecation{since: None, note: None})
+        }
+    }
+
+    depr
+}
+
+#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
+pub enum ReprAttr {
+    ReprInt(IntType),
+    ReprC,
+    ReprPacked(u32),
+    ReprSimd,
+    ReprTransparent,
+    ReprAlign(u32),
+}
+
+#[derive(Eq, Hash, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
+pub enum IntType {
+    SignedInt(ast::IntTy),
+    UnsignedInt(ast::UintTy)
+}
+
+impl IntType {
+    #[inline]
+    pub fn is_signed(self) -> bool {
+        use self::IntType::*;
+
+        match self {
+            SignedInt(..) => true,
+            UnsignedInt(..) => false
+        }
+    }
+}
+
+/// Parse #[repr(...)] forms.
+///
+/// Valid repr contents: any of the primitive integral type names (see
+/// `int_type_of_word`, below) to specify enum discriminant type; `C`, to use
+/// the same discriminant size that the corresponding C enum would or C
+/// structure layout, `packed` to remove padding, and `transparent` to elegate representation
+/// concerns to the only non-ZST field.
+pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr> {
+    use self::ReprAttr::*;
+
+    let mut acc = Vec::new();
+    if attr.path == "repr" {
+        if let Some(items) = attr.meta_item_list() {
+            mark_used(attr);
+            for item in items {
+                if !item.is_meta_item() {
+                    handle_errors(diagnostic, item.span, AttrError::UnsupportedLiteral);
+                    continue
+                }
+
+                let mut recognised = false;
+                if let Some(mi) = item.word() {
+                    let word = &*mi.name().as_str();
+                    let hint = match word {
+                        "C" => Some(ReprC),
+                        "packed" => Some(ReprPacked(1)),
+                        "simd" => Some(ReprSimd),
+                        "transparent" => Some(ReprTransparent),
+                        _ => match int_type_of_word(word) {
+                            Some(ity) => Some(ReprInt(ity)),
+                            None => {
+                                None
+                            }
+                        }
+                    };
+
+                    if let Some(h) = hint {
+                        recognised = true;
+                        acc.push(h);
+                    }
+                } else if let Some((name, value)) = item.name_value_literal() {
+                    let parse_alignment = |node: &ast::LitKind| -> Result<u32, &'static str> {
+                        if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node {
+                            if literal.is_power_of_two() {
+                                // rustc::ty::layout::Align restricts align to <= 2^29
+                                if *literal <= 1 << 29 {
+                                    Ok(*literal as u32)
+                                } else {
+                                    Err("larger than 2^29")
+                                }
+                            } else {
+                                Err("not a power of two")
+                            }
+                        } else {
+                            Err("not an unsuffixed integer")
+                        }
+                    };
+
+                    let mut literal_error = None;
+                    if name == "align" {
+                        recognised = true;
+                        match parse_alignment(&value.node) {
+                            Ok(literal) => acc.push(ReprAlign(literal)),
+                            Err(message) => literal_error = Some(message)
+                        };
+                    }
+                    else if name == "packed" {
+                        recognised = true;
+                        match parse_alignment(&value.node) {
+                            Ok(literal) => acc.push(ReprPacked(literal)),
+                            Err(message) => literal_error = Some(message)
+                        };
+                    }
+                    if let Some(literal_error) = literal_error {
+                        span_err!(diagnostic, item.span, E0589,
+                                  "invalid `repr(align)` attribute: {}", literal_error);
+                    }
+                } else {
+                    if let Some(meta_item) = item.meta_item() {
+                        if meta_item.name() == "align" {
+                            if let MetaItemKind::NameValue(ref value) = meta_item.node {
+                                recognised = true;
+                                let mut err = struct_span_err!(diagnostic, item.span, E0693,
+                                    "incorrect `repr(align)` attribute format");
+                                match value.node {
+                                    ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
+                                        err.span_suggestion_with_applicability(
+                                            item.span,
+                                            "use parentheses instead",
+                                            format!("align({})", int),
+                                            Applicability::MachineApplicable
+                                        );
+                                    }
+                                    ast::LitKind::Str(s, _) => {
+                                        err.span_suggestion_with_applicability(
+                                            item.span,
+                                            "use parentheses instead",
+                                            format!("align({})", s),
+                                            Applicability::MachineApplicable
+                                        );
+                                    }
+                                    _ => {}
+                                }
+                                err.emit();
+                            }
+                        }
+                    }
+                }
+                if !recognised {
+                    // Not a word we recognize
+                    span_err!(diagnostic, item.span, E0552,
+                              "unrecognized representation hint");
+                }
+            }
+        }
+    }
+    acc
+}
+
+fn int_type_of_word(s: &str) -> Option<IntType> {
+    use self::IntType::*;
+
+    match s {
+        "i8" => Some(SignedInt(ast::IntTy::I8)),
+        "u8" => Some(UnsignedInt(ast::UintTy::U8)),
+        "i16" => Some(SignedInt(ast::IntTy::I16)),
+        "u16" => Some(UnsignedInt(ast::UintTy::U16)),
+        "i32" => Some(SignedInt(ast::IntTy::I32)),
+        "u32" => Some(UnsignedInt(ast::UintTy::U32)),
+        "i64" => Some(SignedInt(ast::IntTy::I64)),
+        "u64" => Some(UnsignedInt(ast::UintTy::U64)),
+        "i128" => Some(SignedInt(ast::IntTy::I128)),
+        "u128" => Some(UnsignedInt(ast::UintTy::U128)),
+        "isize" => Some(SignedInt(ast::IntTy::Isize)),
+        "usize" => Some(UnsignedInt(ast::UintTy::Usize)),
+        _ => None
+    }
+}
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
new file mode 100644 (file)
index 0000000..4e27d6c
--- /dev/null
@@ -0,0 +1,810 @@
+// Copyright 2012-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.
+
+//! Functions dealing with attributes and meta items
+
+mod builtin;
+
+pub use self::builtin::{
+    cfg_matches, contains_feature_attr, eval_condition, find_crate_name, find_deprecation,
+    find_repr_attrs, find_stability, find_unwind_attr, Deprecation, InlineAttr, IntType, ReprAttr,
+    RustcConstUnstable, RustcDeprecation, Stability, StabilityLevel, UnwindAttr,
+};
+pub use self::IntType::*;
+pub use self::ReprAttr::*;
+pub use self::StabilityLevel::*;
+
+use ast;
+use ast::{AttrId, Attribute, Name, Ident, Path, PathSegment};
+use ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
+use ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam};
+use codemap::{BytePos, Spanned, respan, dummy_spanned};
+use syntax_pos::Span;
+use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
+use parse::parser::Parser;
+use parse::{self, ParseSess, PResult};
+use parse::token::{self, Token};
+use ptr::P;
+use symbol::Symbol;
+use tokenstream::{TokenStream, TokenTree, Delimited};
+use util::ThinVec;
+use GLOBALS;
+
+use std::iter;
+
+pub fn mark_used(attr: &Attribute) {
+    debug!("Marking {:?} as used.", attr);
+    let AttrId(id) = attr.id;
+    GLOBALS.with(|globals| {
+        let mut slot = globals.used_attrs.lock();
+        let idx = (id / 64) as usize;
+        let shift = id % 64;
+        if slot.len() <= idx {
+            slot.resize(idx + 1, 0);
+        }
+        slot[idx] |= 1 << shift;
+    });
+}
+
+pub fn is_used(attr: &Attribute) -> bool {
+    let AttrId(id) = attr.id;
+    GLOBALS.with(|globals| {
+        let slot = globals.used_attrs.lock();
+        let idx = (id / 64) as usize;
+        let shift = id % 64;
+        slot.get(idx).map(|bits| bits & (1 << shift) != 0)
+            .unwrap_or(false)
+    })
+}
+
+pub fn mark_known(attr: &Attribute) {
+    debug!("Marking {:?} as known.", attr);
+    let AttrId(id) = attr.id;
+    GLOBALS.with(|globals| {
+        let mut slot = globals.known_attrs.lock();
+        let idx = (id / 64) as usize;
+        let shift = id % 64;
+        if slot.len() <= idx {
+            slot.resize(idx + 1, 0);
+        }
+        slot[idx] |= 1 << shift;
+    });
+}
+
+pub fn is_known(attr: &Attribute) -> bool {
+    let AttrId(id) = attr.id;
+    GLOBALS.with(|globals| {
+        let slot = globals.known_attrs.lock();
+        let idx = (id / 64) as usize;
+        let shift = id % 64;
+        slot.get(idx).map(|bits| bits & (1 << shift) != 0)
+            .unwrap_or(false)
+    })
+}
+
+const RUST_KNOWN_TOOL: &[&str] = &["clippy", "rustfmt"];
+
+pub fn is_known_tool(attr: &Attribute) -> bool {
+    let tool_name =
+        attr.path.segments.iter().next().expect("empty path in attribute").ident.name;
+    RUST_KNOWN_TOOL.contains(&tool_name.as_str().as_ref())
+}
+
+impl NestedMetaItem {
+    /// Returns the MetaItem if self is a NestedMetaItemKind::MetaItem.
+    pub fn meta_item(&self) -> Option<&MetaItem> {
+        match self.node {
+            NestedMetaItemKind::MetaItem(ref item) => Some(item),
+            _ => None
+        }
+    }
+
+    /// Returns the Lit if self is a NestedMetaItemKind::Literal.
+    pub fn literal(&self) -> Option<&Lit> {
+        match self.node {
+            NestedMetaItemKind::Literal(ref lit) => Some(lit),
+            _ => None
+        }
+    }
+
+    /// Returns the Span for `self`.
+    pub fn span(&self) -> Span {
+        self.span
+    }
+
+    /// Returns true if this list item is a MetaItem with a name of `name`.
+    pub fn check_name(&self, name: &str) -> bool {
+        self.meta_item().map_or(false, |meta_item| meta_item.check_name(name))
+    }
+
+    /// Returns the name of the meta item, e.g. `foo` in `#[foo]`,
+    /// `#[foo="bar"]` and `#[foo(bar)]`, if self is a MetaItem
+    pub fn name(&self) -> Option<Name> {
+        self.meta_item().and_then(|meta_item| Some(meta_item.name()))
+    }
+
+    /// Gets the string value if self is a MetaItem and the MetaItem is a
+    /// MetaItemKind::NameValue variant containing a string, otherwise None.
+    pub fn value_str(&self) -> Option<Symbol> {
+        self.meta_item().and_then(|meta_item| meta_item.value_str())
+    }
+
+    /// Returns a name and single literal value tuple of the MetaItem.
+    pub fn name_value_literal(&self) -> Option<(Name, &Lit)> {
+        self.meta_item().and_then(
+            |meta_item| meta_item.meta_item_list().and_then(
+                |meta_item_list| {
+                    if meta_item_list.len() == 1 {
+                        let nested_item = &meta_item_list[0];
+                        if nested_item.is_literal() {
+                            Some((meta_item.name(), nested_item.literal().unwrap()))
+                        } else {
+                            None
+                        }
+                    }
+                    else {
+                        None
+                    }}))
+    }
+
+    /// Returns a MetaItem if self is a MetaItem with Kind Word.
+    pub fn word(&self) -> Option<&MetaItem> {
+        self.meta_item().and_then(|meta_item| if meta_item.is_word() {
+            Some(meta_item)
+        } else {
+            None
+        })
+    }
+
+    /// Gets a list of inner meta items from a list MetaItem type.
+    pub fn meta_item_list(&self) -> Option<&[NestedMetaItem]> {
+        self.meta_item().and_then(|meta_item| meta_item.meta_item_list())
+    }
+
+    /// Returns `true` if the variant is MetaItem.
+    pub fn is_meta_item(&self) -> bool {
+        self.meta_item().is_some()
+    }
+
+    /// Returns `true` if the variant is Literal.
+    pub fn is_literal(&self) -> bool {
+        self.literal().is_some()
+    }
+
+    /// Returns `true` if self is a MetaItem and the meta item is a word.
+    pub fn is_word(&self) -> bool {
+        self.word().is_some()
+    }
+
+    /// Returns `true` if self is a MetaItem and the meta item is a ValueString.
+    pub fn is_value_str(&self) -> bool {
+        self.value_str().is_some()
+    }
+
+    /// Returns `true` if self is a MetaItem and the meta item is a list.
+    pub fn is_meta_item_list(&self) -> bool {
+        self.meta_item_list().is_some()
+    }
+}
+
+fn name_from_path(path: &Path) -> Name {
+    path.segments.last().expect("empty path in attribute").ident.name
+}
+
+impl Attribute {
+    pub fn check_name(&self, name: &str) -> bool {
+        let matches = self.path == name;
+        if matches {
+            mark_used(self);
+        }
+        matches
+    }
+
+    /// Returns the **last** segment of the name of this attribute.
+    /// E.g. `foo` for `#[foo]`, `skip` for `#[rustfmt::skip]`.
+    pub fn name(&self) -> Name {
+        name_from_path(&self.path)
+    }
+
+    pub fn value_str(&self) -> Option<Symbol> {
+        self.meta().and_then(|meta| meta.value_str())
+    }
+
+    pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> {
+        match self.meta() {
+            Some(MetaItem { node: MetaItemKind::List(list), .. }) => Some(list),
+            _ => None
+        }
+    }
+
+    pub fn is_word(&self) -> bool {
+        self.path.segments.len() == 1 && self.tokens.is_empty()
+    }
+
+    pub fn span(&self) -> Span {
+        self.span
+    }
+
+    pub fn is_meta_item_list(&self) -> bool {
+        self.meta_item_list().is_some()
+    }
+
+    /// Indicates if the attribute is a Value String.
+    pub fn is_value_str(&self) -> bool {
+        self.value_str().is_some()
+    }
+
+    pub fn is_scoped(&self) -> bool {
+        self.path.segments.len() > 1
+    }
+}
+
+impl MetaItem {
+    pub fn name(&self) -> Name {
+        name_from_path(&self.ident)
+    }
+
+    pub fn value_str(&self) -> Option<Symbol> {
+        match self.node {
+            MetaItemKind::NameValue(ref v) => {
+                match v.node {
+                    LitKind::Str(ref s, _) => Some(*s),
+                    _ => None,
+                }
+            },
+            _ => None
+        }
+    }
+
+    pub fn meta_item_list(&self) -> Option<&[NestedMetaItem]> {
+        match self.node {
+            MetaItemKind::List(ref l) => Some(&l[..]),
+            _ => None
+        }
+    }
+
+    pub fn is_word(&self) -> bool {
+        match self.node {
+            MetaItemKind::Word => true,
+            _ => false,
+        }
+    }
+
+    pub fn span(&self) -> Span { self.span }
+
+    pub fn check_name(&self, name: &str) -> bool {
+        self.name() == name
+    }
+
+    pub fn is_value_str(&self) -> bool {
+        self.value_str().is_some()
+    }
+
+    pub fn is_meta_item_list(&self) -> bool {
+        self.meta_item_list().is_some()
+    }
+}
+
+impl Attribute {
+    /// Extract the MetaItem from inside this Attribute.
+    pub fn meta(&self) -> Option<MetaItem> {
+        let mut tokens = self.tokens.trees().peekable();
+        Some(MetaItem {
+            ident: self.path.clone(),
+            node: if let Some(node) = MetaItemKind::from_tokens(&mut tokens) {
+                if tokens.peek().is_some() {
+                    return None;
+                }
+                node
+            } else {
+                return None;
+            },
+            span: self.span,
+        })
+    }
+
+    pub fn parse<'a, T, F>(&self, sess: &'a ParseSess, mut f: F) -> PResult<'a, T>
+        where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
+    {
+        let mut parser = Parser::new(sess, self.tokens.clone(), None, false, false);
+        let result = f(&mut parser)?;
+        if parser.token != token::Eof {
+            parser.unexpected()?;
+        }
+        Ok(result)
+    }
+
+    pub fn parse_list<'a, T, F>(&self, sess: &'a ParseSess, mut f: F) -> PResult<'a, Vec<T>>
+        where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
+    {
+        if self.tokens.is_empty() {
+            return Ok(Vec::new());
+        }
+        self.parse(sess, |parser| {
+            parser.expect(&token::OpenDelim(token::Paren))?;
+            let mut list = Vec::new();
+            while !parser.eat(&token::CloseDelim(token::Paren)) {
+                list.push(f(parser)?);
+                if !parser.eat(&token::Comma) {
+                   parser.expect(&token::CloseDelim(token::Paren))?;
+                    break
+                }
+            }
+            Ok(list)
+        })
+    }
+
+    pub fn parse_meta<'a>(&self, sess: &'a ParseSess) -> PResult<'a, MetaItem> {
+        Ok(MetaItem {
+            ident: self.path.clone(),
+            node: self.parse(sess, |parser| parser.parse_meta_item_kind())?,
+            span: self.span,
+        })
+    }
+
+    /// Convert self to a normal #[doc="foo"] comment, if it is a
+    /// comment like `///` or `/** */`. (Returns self unchanged for
+    /// non-sugared doc attributes.)
+    pub fn with_desugared_doc<T, F>(&self, f: F) -> T where
+        F: FnOnce(&Attribute) -> T,
+    {
+        if self.is_sugared_doc {
+            let comment = self.value_str().unwrap();
+            let meta = mk_name_value_item_str(
+                Ident::from_str("doc"),
+                dummy_spanned(Symbol::intern(&strip_doc_comment_decoration(&comment.as_str()))));
+            let mut attr = if self.style == ast::AttrStyle::Outer {
+                mk_attr_outer(self.span, self.id, meta)
+            } else {
+                mk_attr_inner(self.span, self.id, meta)
+            };
+            attr.is_sugared_doc = true;
+            f(&attr)
+        } else {
+            f(self)
+        }
+    }
+}
+
+/* Constructors */
+
+pub fn mk_name_value_item_str(ident: Ident, value: Spanned<Symbol>) -> MetaItem {
+    let value = respan(value.span, LitKind::Str(value.node, ast::StrStyle::Cooked));
+    mk_name_value_item(ident.span.to(value.span), ident, value)
+}
+
+pub fn mk_name_value_item(span: Span, ident: Ident, value: ast::Lit) -> MetaItem {
+    MetaItem { ident: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) }
+}
+
+pub fn mk_list_item(span: Span, ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem {
+    MetaItem { ident: Path::from_ident(ident), span, node: MetaItemKind::List(items) }
+}
+
+pub fn mk_word_item(ident: Ident) -> MetaItem {
+    MetaItem { ident: Path::from_ident(ident), span: ident.span, node: MetaItemKind::Word }
+}
+
+pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
+    respan(ident.span, NestedMetaItemKind::MetaItem(mk_word_item(ident)))
+}
+
+pub fn mk_attr_id() -> AttrId {
+    use std::sync::atomic::AtomicUsize;
+    use std::sync::atomic::Ordering;
+
+    static NEXT_ATTR_ID: AtomicUsize = AtomicUsize::new(0);
+
+    let id = NEXT_ATTR_ID.fetch_add(1, Ordering::SeqCst);
+    assert!(id != ::std::usize::MAX);
+    AttrId(id)
+}
+
+/// Returns an inner attribute with the given value.
+pub fn mk_attr_inner(span: Span, id: AttrId, item: MetaItem) -> Attribute {
+    mk_spanned_attr_inner(span, id, item)
+}
+
+/// Returns an inner attribute with the given value and span.
+pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: MetaItem) -> Attribute {
+    Attribute {
+        id,
+        style: ast::AttrStyle::Inner,
+        path: item.ident,
+        tokens: item.node.tokens(item.span),
+        is_sugared_doc: false,
+        span: sp,
+    }
+}
+
+/// Returns an outer attribute with the given value.
+pub fn mk_attr_outer(span: Span, id: AttrId, item: MetaItem) -> Attribute {
+    mk_spanned_attr_outer(span, id, item)
+}
+
+/// Returns an outer attribute with the given value and span.
+pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute {
+    Attribute {
+        id,
+        style: ast::AttrStyle::Outer,
+        path: item.ident,
+        tokens: item.node.tokens(item.span),
+        is_sugared_doc: false,
+        span: sp,
+    }
+}
+
+pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute {
+    let style = doc_comment_style(&text.as_str());
+    let lit = respan(span, LitKind::Str(text, ast::StrStyle::Cooked));
+    Attribute {
+        id,
+        style,
+        path: Path::from_ident(Ident::from_str("doc").with_span_pos(span)),
+        tokens: MetaItemKind::NameValue(lit).tokens(span),
+        is_sugared_doc: true,
+        span,
+    }
+}
+
+pub fn list_contains_name(items: &[NestedMetaItem], name: &str) -> bool {
+    items.iter().any(|item| {
+        item.check_name(name)
+    })
+}
+
+pub fn contains_name(attrs: &[Attribute], name: &str) -> bool {
+    attrs.iter().any(|item| {
+        item.check_name(name)
+    })
+}
+
+pub fn find_by_name<'a>(attrs: &'a [Attribute], name: &str) -> Option<&'a Attribute> {
+    attrs.iter().find(|attr| attr.check_name(name))
+}
+
+pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str) -> Option<Symbol> {
+    attrs.iter()
+        .find(|at| at.check_name(name))
+        .and_then(|at| at.value_str())
+}
+
+impl MetaItem {
+    fn tokens(&self) -> TokenStream {
+        let mut idents = vec![];
+        let mut last_pos = BytePos(0 as u32);
+        for (i, segment) in self.ident.segments.iter().enumerate() {
+            let is_first = i == 0;
+            if !is_first {
+                let mod_sep_span = Span::new(last_pos,
+                                             segment.ident.span.lo(),
+                                             segment.ident.span.ctxt());
+                idents.push(TokenTree::Token(mod_sep_span, Token::ModSep).into());
+            }
+            idents.push(TokenTree::Token(segment.ident.span,
+                                         Token::from_ast_ident(segment.ident)).into());
+            last_pos = segment.ident.span.hi();
+        }
+        idents.push(self.node.tokens(self.span));
+        TokenStream::concat(idents)
+    }
+
+    fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItem>
+        where I: Iterator<Item = TokenTree>,
+    {
+        // FIXME: Share code with `parse_path`.
+        let ident = match tokens.next() {
+            Some(TokenTree::Token(span, Token::Ident(ident, _))) => {
+                if let Some(TokenTree::Token(_, Token::ModSep)) = tokens.peek() {
+                    let mut segments = vec![PathSegment::from_ident(ident.with_span_pos(span))];
+                    tokens.next();
+                    loop {
+                        if let Some(TokenTree::Token(span,
+                                                     Token::Ident(ident, _))) = tokens.next() {
+                            segments.push(PathSegment::from_ident(ident.with_span_pos(span)));
+                        } else {
+                            return None;
+                        }
+                        if let Some(TokenTree::Token(_, Token::ModSep)) = tokens.peek() {
+                            tokens.next();
+                        } else {
+                            break;
+                        }
+                    }
+                    let span = span.with_hi(segments.last().unwrap().ident.span.hi());
+                    Path { span, segments }
+                } else {
+                    Path::from_ident(ident.with_span_pos(span))
+                }
+            }
+            Some(TokenTree::Token(_, Token::Interpolated(ref nt))) => match nt.0 {
+                token::Nonterminal::NtIdent(ident, _) => Path::from_ident(ident),
+                token::Nonterminal::NtMeta(ref meta) => return Some(meta.clone()),
+                token::Nonterminal::NtPath(ref path) => path.clone(),
+                _ => return None,
+            },
+            _ => return None,
+        };
+        let list_closing_paren_pos = tokens.peek().map(|tt| tt.span().hi());
+        let node = MetaItemKind::from_tokens(tokens)?;
+        let hi = match node {
+            MetaItemKind::NameValue(ref lit) => lit.span.hi(),
+            MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(ident.span.hi()),
+            _ => ident.span.hi(),
+        };
+        let span = ident.span.with_hi(hi);
+        Some(MetaItem { ident, node, span })
+    }
+}
+
+impl MetaItemKind {
+    pub fn tokens(&self, span: Span) -> TokenStream {
+        match *self {
+            MetaItemKind::Word => TokenStream::empty(),
+            MetaItemKind::NameValue(ref lit) => {
+                TokenStream::concat(vec![TokenTree::Token(span, Token::Eq).into(), lit.tokens()])
+            }
+            MetaItemKind::List(ref list) => {
+                let mut tokens = Vec::new();
+                for (i, item) in list.iter().enumerate() {
+                    if i > 0 {
+                        tokens.push(TokenTree::Token(span, Token::Comma).into());
+                    }
+                    tokens.push(item.node.tokens());
+                }
+                TokenTree::Delimited(span, Delimited {
+                    delim: token::Paren,
+                    tts: TokenStream::concat(tokens).into(),
+                }).into()
+            }
+        }
+    }
+
+    fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItemKind>
+        where I: Iterator<Item = TokenTree>,
+    {
+        let delimited = match tokens.peek().cloned() {
+            Some(TokenTree::Token(_, token::Eq)) => {
+                tokens.next();
+                return if let Some(TokenTree::Token(span, token)) = tokens.next() {
+                    LitKind::from_token(token)
+                        .map(|lit| MetaItemKind::NameValue(Spanned { node: lit, span: span }))
+                } else {
+                    None
+                };
+            }
+            Some(TokenTree::Delimited(_, ref delimited)) if delimited.delim == token::Paren => {
+                tokens.next();
+                delimited.stream()
+            }
+            _ => return Some(MetaItemKind::Word),
+        };
+
+        let mut tokens = delimited.into_trees().peekable();
+        let mut result = Vec::new();
+        while let Some(..) = tokens.peek() {
+            let item = NestedMetaItemKind::from_tokens(&mut tokens)?;
+            result.push(respan(item.span(), item));
+            match tokens.next() {
+                None | Some(TokenTree::Token(_, Token::Comma)) => {}
+                _ => return None,
+            }
+        }
+        Some(MetaItemKind::List(result))
+    }
+}
+
+impl NestedMetaItemKind {
+    fn span(&self) -> Span {
+        match *self {
+            NestedMetaItemKind::MetaItem(ref item) => item.span,
+            NestedMetaItemKind::Literal(ref lit) => lit.span,
+        }
+    }
+
+    fn tokens(&self) -> TokenStream {
+        match *self {
+            NestedMetaItemKind::MetaItem(ref item) => item.tokens(),
+            NestedMetaItemKind::Literal(ref lit) => lit.tokens(),
+        }
+    }
+
+    fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<NestedMetaItemKind>
+        where I: Iterator<Item = TokenTree>,
+    {
+        if let Some(TokenTree::Token(span, token)) = tokens.peek().cloned() {
+            if let Some(node) = LitKind::from_token(token) {
+                tokens.next();
+                return Some(NestedMetaItemKind::Literal(respan(span, node)));
+            }
+        }
+
+        MetaItem::from_tokens(tokens).map(NestedMetaItemKind::MetaItem)
+    }
+}
+
+impl Lit {
+    fn tokens(&self) -> TokenStream {
+        TokenTree::Token(self.span, self.node.token()).into()
+    }
+}
+
+impl LitKind {
+    fn token(&self) -> Token {
+        use std::ascii;
+
+        match *self {
+            LitKind::Str(string, ast::StrStyle::Cooked) => {
+                let escaped = string.as_str().escape_default();
+                Token::Literal(token::Lit::Str_(Symbol::intern(&escaped)), None)
+            }
+            LitKind::Str(string, ast::StrStyle::Raw(n)) => {
+                Token::Literal(token::Lit::StrRaw(string, n), None)
+            }
+            LitKind::ByteStr(ref bytes) => {
+                let string = bytes.iter().cloned().flat_map(ascii::escape_default)
+                    .map(Into::<char>::into).collect::<String>();
+                Token::Literal(token::Lit::ByteStr(Symbol::intern(&string)), None)
+            }
+            LitKind::Byte(byte) => {
+                let string: String = ascii::escape_default(byte).map(Into::<char>::into).collect();
+                Token::Literal(token::Lit::Byte(Symbol::intern(&string)), None)
+            }
+            LitKind::Char(ch) => {
+                let string: String = ch.escape_default().map(Into::<char>::into).collect();
+                Token::Literal(token::Lit::Char(Symbol::intern(&string)), None)
+            }
+            LitKind::Int(n, ty) => {
+                let suffix = match ty {
+                    ast::LitIntType::Unsigned(ty) => Some(Symbol::intern(ty.ty_to_string())),
+                    ast::LitIntType::Signed(ty) => Some(Symbol::intern(ty.ty_to_string())),
+                    ast::LitIntType::Unsuffixed => None,
+                };
+                Token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())), suffix)
+            }
+            LitKind::Float(symbol, ty) => {
+                Token::Literal(token::Lit::Float(symbol), Some(Symbol::intern(ty.ty_to_string())))
+            }
+            LitKind::FloatUnsuffixed(symbol) => Token::Literal(token::Lit::Float(symbol), None),
+            LitKind::Bool(value) => Token::Ident(Ident::with_empty_ctxt(Symbol::intern(if value {
+                "true"
+            } else {
+                "false"
+            })), false),
+        }
+    }
+
+    fn from_token(token: Token) -> Option<LitKind> {
+        match token {
+            Token::Ident(ident, false) if ident.name == "true" => Some(LitKind::Bool(true)),
+            Token::Ident(ident, false) if ident.name == "false" => Some(LitKind::Bool(false)),
+            Token::Interpolated(ref nt) => match nt.0 {
+                token::NtExpr(ref v) | token::NtLiteral(ref v) => match v.node {
+                    ExprKind::Lit(ref lit) => Some(lit.node.clone()),
+                    _ => None,
+                },
+                _ => None,
+            },
+            Token::Literal(lit, suf) => {
+                let (suffix_illegal, result) = parse::lit_token(lit, suf, None);
+                if suffix_illegal && suf.is_some() {
+                    return None;
+                }
+                result
+            }
+            _ => None,
+        }
+    }
+}
+
+pub trait HasAttrs: Sized {
+    fn attrs(&self) -> &[ast::Attribute];
+    fn map_attrs<F: FnOnce(Vec<ast::Attribute>) -> Vec<ast::Attribute>>(self, f: F) -> Self;
+}
+
+impl<T: HasAttrs> HasAttrs for Spanned<T> {
+    fn attrs(&self) -> &[ast::Attribute] { self.node.attrs() }
+    fn map_attrs<F: FnOnce(Vec<ast::Attribute>) -> Vec<ast::Attribute>>(self, f: F) -> Self {
+        respan(self.span, self.node.map_attrs(f))
+    }
+}
+
+impl HasAttrs for Vec<Attribute> {
+    fn attrs(&self) -> &[Attribute] {
+        self
+    }
+    fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
+        f(self)
+    }
+}
+
+impl HasAttrs for ThinVec<Attribute> {
+    fn attrs(&self) -> &[Attribute] {
+        self
+    }
+    fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
+        f(self.into()).into()
+    }
+}
+
+impl<T: HasAttrs + 'static> HasAttrs for P<T> {
+    fn attrs(&self) -> &[Attribute] {
+        (**self).attrs()
+    }
+    fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
+        self.map(|t| t.map_attrs(f))
+    }
+}
+
+impl HasAttrs for StmtKind {
+    fn attrs(&self) -> &[Attribute] {
+        match *self {
+            StmtKind::Local(ref local) => local.attrs(),
+            StmtKind::Item(..) => &[],
+            StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.attrs(),
+            StmtKind::Mac(ref mac) => {
+                let (_, _, ref attrs) = **mac;
+                attrs.attrs()
+            }
+        }
+    }
+
+    fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
+        match self {
+            StmtKind::Local(local) => StmtKind::Local(local.map_attrs(f)),
+            StmtKind::Item(..) => self,
+            StmtKind::Expr(expr) => StmtKind::Expr(expr.map_attrs(f)),
+            StmtKind::Semi(expr) => StmtKind::Semi(expr.map_attrs(f)),
+            StmtKind::Mac(mac) => StmtKind::Mac(mac.map(|(mac, style, attrs)| {
+                (mac, style, attrs.map_attrs(f))
+            })),
+        }
+    }
+}
+
+impl HasAttrs for Stmt {
+    fn attrs(&self) -> &[ast::Attribute] { self.node.attrs() }
+    fn map_attrs<F: FnOnce(Vec<ast::Attribute>) -> Vec<ast::Attribute>>(self, f: F) -> Self {
+        Stmt { id: self.id, node: self.node.map_attrs(f), span: self.span }
+    }
+}
+
+impl HasAttrs for GenericParam {
+    fn attrs(&self) -> &[ast::Attribute] {
+        &self.attrs
+    }
+
+    fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(mut self, f: F) -> Self {
+        self.attrs = self.attrs.map_attrs(f);
+        self
+    }
+}
+
+macro_rules! derive_has_attrs {
+    ($($ty:path),*) => { $(
+        impl HasAttrs for $ty {
+            fn attrs(&self) -> &[Attribute] {
+                &self.attrs
+            }
+
+            fn map_attrs<F>(mut self, f: F) -> Self
+                where F: FnOnce(Vec<Attribute>) -> Vec<Attribute>,
+            {
+                self.attrs = self.attrs.map_attrs(f);
+                self
+            }
+        }
+    )* }
+}
+
+derive_has_attrs! {
+    Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::ImplItem, ast::TraitItem, ast::Arm,
+    ast::Field, ast::FieldPat, ast::Variant_
+}
index 1c817c7a0c828b8fc8e8e462afbe5db41c7052d1..509f29ac17874394acf4d49d6bae3cd93c652aa1 160000 (submodule)
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit 1c817c7a0c828b8fc8e8e462afbe5db41c7052d1
+Subproject commit 509f29ac17874394acf4d49d6bae3cd93c652aa1
index a19ca1cd91cf97777af8268a6136bd2e4648e189..886ff388fbbe8798e292431d824a5ff3c3458f4d 160000 (submodule)
@@ -1 +1 @@
-Subproject commit a19ca1cd91cf97777af8268a6136bd2e4648e189
+Subproject commit 886ff388fbbe8798e292431d824a5ff3c3458f4d
diff --git a/src/test/compile-fail/deprecation-sanity.rs b/src/test/compile-fail/deprecation-sanity.rs
deleted file mode 100644 (file)
index af2ac79..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.
-
-// Various checks that deprecation attributes are used correctly
-
-mod bogus_attribute_types_1 {
-    #[deprecated(since = "a", note = "a", reason)] //~ ERROR unknown meta item 'reason'
-    fn f1() { }
-
-    #[deprecated(since = "a", note)] //~ ERROR incorrect meta item
-    fn f2() { }
-
-    #[deprecated(since, note = "a")] //~ ERROR incorrect meta item
-    fn f3() { }
-
-    #[deprecated(since = "a", note(b))] //~ ERROR incorrect meta item
-    fn f5() { }
-
-    #[deprecated(since(b), note = "a")] //~ ERROR incorrect meta item
-    fn f6() { }
-}
-
-#[deprecated(since = "a", note = "b")]
-#[deprecated(since = "a", note = "b")]
-fn multiple1() { } //~ ERROR multiple deprecated attributes
-
-#[deprecated(since = "a", since = "b", note = "c")] //~ ERROR multiple 'since' items
-fn f1() { }
-
-fn main() { }
index b32056fcb915a0eacb8d77de39f640e43791bc77..61a074952efd289fc51a51f3678b854848fdb851 100644 (file)
 
 fn f(y: Box<isize>) {
     *y = 5; //[ast]~ ERROR cannot assign
-            //[mir]~^ ERROR cannot assign twice
+            //[mir]~^ ERROR cannot assign
 }
 
 fn g() {
     let _frob = |q: Box<isize>| { *q = 2; }; //[ast]~ ERROR cannot assign
-    //[mir]~^ ERROR cannot assign twice
+    //[mir]~^ ERROR cannot assign
 }
 
 fn main() {}
index 95f017061a2576efb65e4baf94083394bbc48e18..250e78ce2464005d9837f07fe7d7e4178cb4d369 100644 (file)
@@ -16,7 +16,5 @@
 static CRASH: () = symbol;
 //~^ ERROR could not evaluate static initializer
 //~| tried to read from foreign (extern) static
-//~^^^ ERROR could not evaluate static initializer
-//~| tried to read from foreign (extern) static
 
 fn main() {}
index 8512238dd31ca668d1dfa0dd1fd1bf248a2113ad..af73db2b4d211aa154863b35f4fbada37b19b175 100644 (file)
@@ -17,7 +17,5 @@
 pub static BAZ: u32 = *&error_message_count;
 //~^ ERROR could not evaluate static initializer
 //~| tried to read from foreign (extern) static
-//~^^^ ERROR could not evaluate static initializer
-//~| tried to read from foreign (extern) static
 
 fn main() {}
index e44b41993aa9512329cbefe78f3077d11a980efc..59261ec968740f3e2ea422005b4f5cd6f6b1529e 100644 (file)
@@ -34,38 +34,31 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
 //     ...
 //     let mut _2: ();
 //     let mut _3: [closure@NodeId(22) d:D];
-//     let mut _4: D;
 //     bb0: {
 //         StorageLive(_1);
 //         _1 = D::{{constructor}}(const 0i32,);
 //         StorageLive(_3);
-//         StorageLive(_4);
-//         _4 = move _1;
-//         _3 = [closure@NodeId(22)] { d: move _4 };
-//         drop(_4) -> [return: bb4, unwind: bb3];
+//         _3 = [closure@NodeId(22)] { d: move _1 };
+//         _2 = const foo(move _3) -> [return: bb2, unwind: bb4];
 //     }
 //     bb1: {
 //         resume;
 //     }
 //     bb2: {
-//         drop(_1) -> bb1;
+//         drop(_3) -> [return: bb5, unwind: bb3];
 //     }
 //     bb3: {
-//         drop(_3) -> bb2;
+//         drop(_1) -> bb1;
 //     }
 //     bb4: {
-//         StorageDead(_4);
-//         _2 = const foo(move _3) -> [return: bb5, unwind: bb3];
+//         drop(_3) -> bb3;
 //     }
 //     bb5: {
-//         drop(_3) -> [return: bb6, unwind: bb2];
-//     }
-//     bb6: {
 //         StorageDead(_3);
 //         _0 = ();
-//         drop(_1) -> [return: bb7, unwind: bb1];
+//         drop(_1) -> [return: bb6, unwind: bb1];
 //     }
-//     bb7: {
+//     bb6: {
 //         StorageDead(_1);
 //         return;
 //     }
index 7fdf971b3b9df0bd945de24c4347e3decb51976b..a49913a62d9d0bdef2445a7408798469a4c57c57 100644 (file)
@@ -37,17 +37,13 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
 //    ...
 //    let mut _3: ();
 //    let mut _4: [closure@NodeId(22) r:&'19s D];
-//    let mut _5: &'21_1rs D;
 //    bb0: {
 //        StorageLive(_1);
 //        _1 = D::{{constructor}}(const 0i32,);
 //        StorageLive(_2);
 //        _2 = &'21_1rs _1;
 //        StorageLive(_4);
-//        StorageLive(_5);
-//        _5 = _2;
-//        _4 = [closure@NodeId(22)] { r: move _5 };
-//        StorageDead(_5);
+//        _4 = [closure@NodeId(22)] { r: _2 };
 //        _3 = const foo(move _4) -> [return: bb2, unwind: bb3];
 //    }
 //    bb1: {
index f41b39845a579681bf5811aa2e9fcebc4deac32b..5fdea4208df996ec156ca19e8416cd7f1c581c95 100644 (file)
@@ -26,20 +26,20 @@ fn main() {
 //
 // END RUST SOURCE
 // START rustc.main.nll.0.mir
-//    | Live variables on entry to bb0: []
 //    bb0: {
 //            | Live variables on entry to bb0[0]: []
 //        StorageLive(_1);
 //            | Live variables on entry to bb0[1]: []
 //        _1 = const <std::boxed::Box<T>>::new(const 22usize) -> [return: bb2, unwind: bb1];
+//            | Live variables on exit from bb0: [_1 (drop)]
 //    }
 // END rustc.main.nll.0.mir
 // START rustc.main.nll.0.mir
-//    | Live variables on entry to bb2: [_1 (drop)]
 //    bb2: {
 //            | Live variables on entry to bb2[0]: [_1 (drop)]
 //        StorageLive(_2);
 //            | Live variables on entry to bb2[1]: [_1 (drop)]
 //        _2 = const can_panic() -> [return: bb3, unwind: bb4];
+//            | Live variables on exit from bb2: [_1 (drop), _2]
 //    }
 // END rustc.main.nll.0.mir
index 073b44d6e338763ef9a8a5d63d289469b7012d8f..001499b657de955af53762ee984fca5058825084 100644 (file)
@@ -25,7 +25,6 @@ fn main() {
 
 // END RUST SOURCE
 // START rustc.main.nll.0.mir
-//    | Live variables on entry to bb3: []
 //    bb3: {
 //            | Live variables on entry to bb3[0]: []
 //        _1 = const 55usize;
@@ -37,5 +36,6 @@ fn main() {
 //        _4 = _1;
 //            | Live variables on entry to bb3[4]: [_4]
 //        _3 = const use_x(move _4) -> [return: bb4, unwind: bb1];
+//            | Live variables on exit from bb3: [_3]
 //    }
 // END rustc.main.nll.0.mir
index 6a8749084068a30fa6afcd518b5a2b0cb1f14a44..fbe20d76ea721e4406c681aa9bfcce3926138ed7 100644 (file)
@@ -29,7 +29,6 @@ fn main() {
 
 // END RUST SOURCE
 // START rustc.main.nll.0.mir
-//     | Live variables on entry to bb3: [_1]
 //     bb3: {
 //             | Live variables on entry to bb3[0]: [_1]
 //         StorageLive(_4);
@@ -37,12 +36,13 @@ fn main() {
 //         _4 = _1;
 //             | Live variables on entry to bb3[2]: [_4]
 //         _3 = const make_live(move _4) -> [return: bb5, unwind: bb1];
+//             | Live variables on exit from bb3: []
 //     }
 // END rustc.main.nll.0.mir
 // START rustc.main.nll.0.mir
-//     | Live variables on entry to bb4: []
 //     bb4: {
 //             | Live variables on entry to bb4[0]: []
 //         _5 = const make_dead() -> [return: bb6, unwind: bb1];
+//             | Live variables on exit from bb4: []
 //     }
 // END rustc.main.nll.0.mir
index 75d8a6a4f6ac55ca3b830ecf4a58b3e79a9bade7..187d9e6ca899304256d060345f37b9510c85d781 100644 (file)
@@ -42,6 +42,7 @@ fn main() {
 //        _2 = &'_#2r _1[_3];
 //            | Live variables on entry to bb2[1]: [_2]
 //        switchInt(const true) -> [false: bb4, otherwise: bb3];
+//            | Live variables on exit from bb2: [_2]
 //    }
 // END rustc.main.nll.0.mir
 // START rustc.main.nll.0.mir
@@ -52,5 +53,6 @@ fn main() {
 //        _7 = (*_2);
 //            | Live variables on entry to bb3[2]: [_7]
 //        _6 = const use_x(move _7) -> [return: bb5, unwind: bb1];
+//            | Live variables on exit from bb3: []
 //    }
 // END rustc.main.nll.0.mir
index 8b649f6ef7bbdc548924c8dfcfc840831c6fdfeb..0ac37485d3dc81df976de0d747b979be4c3e0592 100644 (file)
     Arc,
     atomic::{self, AtomicUsize},
 };
+use std::future::FutureObj;
 use std::task::{
     Context, Poll, Wake,
-    Executor, TaskObj, SpawnObjError,
+    Executor, SpawnObjError,
     local_waker_from_nonlocal,
 };
 
@@ -37,7 +38,7 @@ fn wake(this: &Arc<Self>) {
 
 struct NoopExecutor;
 impl Executor for NoopExecutor {
-    fn spawn_obj(&mut self, _: TaskObj) -> Result<(), SpawnObjError> {
+    fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
         Ok(())
     }
 }
index 3b5a1725b66cbcd3fd980a2018b0c4d88dd0bf82..6cb975a9560b9403cb726ea043dee7744eaf7bb9 100644 (file)
     Arc,
     atomic::{self, AtomicUsize},
 };
+use std::future::FutureObj;
 use std::task::{
     Context, Poll,
     Wake, Waker, LocalWaker,
-    Executor, TaskObj, SpawnObjError,
+    Executor, SpawnObjError,
     local_waker, local_waker_from_nonlocal,
 };
 
@@ -44,7 +45,7 @@ unsafe fn wake_local(this: &Arc<Self>) {
 struct NoopExecutor;
 
 impl Executor for NoopExecutor {
-    fn spawn_obj(&mut self, _: TaskObj) -> Result<(), SpawnObjError> {
+    fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
         Ok(())
     }
 }
index 6078352fc0e0905b84dc8aba7ac0e9169a3caa00..15a774dc9353d57fb905066f3a6f65b73509384f 100644 (file)
@@ -66,6 +66,6 @@
 #[doc(no_inline)]
 pub use all_item_types::FOO_CONSTANT;
 
-// @has 'foo/index.html' '//a[@href="../foo/macro.foo_macro.html"]' 'foo_macro'
+// @has 'foo/index.html' '//a[@href="../all_item_types/macro.foo_macro.html"]' 'foo_macro'
 #[doc(no_inline)]
 pub use all_item_types::foo_macro;
diff --git a/src/test/rustdoc/inline_cross/auxiliary/macro-vis.rs b/src/test/rustdoc/inline_cross/auxiliary/macro-vis.rs
new file mode 100644 (file)
index 0000000..d4a9a9f
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "qwop"]
+
+/// (writen on a spider's web) Some Macro
+#[macro_export]
+macro_rules! some_macro {
+    () => {
+        println!("this is some macro, for sure");
+    };
+}
+
+/// Some other macro, to fill space.
+#[macro_export]
+macro_rules! other_macro {
+    () => {
+        println!("this is some other macro, whatev");
+    };
+}
+
+/// This macro is so cool, it's Super.
+#[macro_export]
+macro_rules! super_macro {
+    () => {
+        println!("is it a bird? a plane? no, it's Super Macro!");
+    };
+}
diff --git a/src/test/rustdoc/inline_cross/macro-vis.rs b/src/test/rustdoc/inline_cross/macro-vis.rs
new file mode 100644 (file)
index 0000000..6de1333
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:macro-vis.rs
+// build-aux-docs
+// ignore-cross-compile
+
+#![feature(use_extern_macros)]
+
+#[macro_use] extern crate qwop;
+
+// @has macro_vis/macro.some_macro.html
+// @has macro_vis/index.html '//a/@href' 'macro.some_macro.html'
+pub use qwop::some_macro;
+
+// @has macro_vis/macro.renamed_macro.html
+// @!has - '//pre' 'some_macro'
+// @has macro_vis/index.html '//a/@href' 'macro.renamed_macro.html'
+#[doc(inline)]
+pub use qwop::some_macro as renamed_macro;
+
+// @!has macro_vis/macro.other_macro.html
+// @!has macro_vis/index.html '//a/@href' 'macro.other_macro.html'
+// @!has - '//code' 'pub use qwop::other_macro;'
+#[doc(hidden)]
+pub use qwop::other_macro;
+
+// @has macro_vis/index.html '//code' 'pub use qwop::super_macro;'
+// @!has macro_vis/macro.super_macro.html
+#[doc(no_inline)]
+pub use qwop::super_macro;
+
+// @has macro_vis/macro.this_is_dope.html
+// @has macro_vis/index.html '//a/@href' 'macro.this_is_dope.html'
+/// What it says on the tin.
+#[macro_export]
+macro_rules! this_is_dope {
+    () => {
+        println!("yo check this out");
+    };
+}
index a6e707cc2adea7bc28bc4cb87df31cf7c339f10e..13957fd6a702294a7790acef048f15c64cea6bc0 100644 (file)
@@ -23,7 +23,7 @@
 #[doc(inline)]
 pub use macros::baz;
 
-// @has pub_use_extern_macros/macro.quux.html
+// @!has pub_use_extern_macros/macro.quux.html
 // @!has pub_use_extern_macros/index.html '//code' 'pub use macros::quux;'
 #[doc(hidden)]
 pub use macros::quux;
diff --git a/src/test/ui/array-break-length.rs b/src/test/ui/array-break-length.rs
new file mode 100644 (file)
index 0000000..c3cfff0
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    loop {
+        |_: [_; break]| {} //~ ERROR: `break` outside of loop
+    }
+
+    loop {
+        |_: [_; continue]| {} //~ ERROR: `continue` outside of loop
+    }
+}
diff --git a/src/test/ui/array-break-length.stderr b/src/test/ui/array-break-length.stderr
new file mode 100644 (file)
index 0000000..114245b
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0268]: `break` outside of loop
+  --> $DIR/array-break-length.rs:13:17
+   |
+LL |         |_: [_; break]| {} //~ ERROR: `break` outside of loop
+   |                 ^^^^^ cannot break outside of a loop
+
+error[E0268]: `continue` outside of loop
+  --> $DIR/array-break-length.rs:17:17
+   |
+LL |         |_: [_; continue]| {} //~ ERROR: `continue` outside of loop
+   |                 ^^^^^^^^ cannot break outside of a loop
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0268`.
index 3a280f85e76949e0e862df6135838f7a74e1ecf4..812418a3053e99554784b49da3b316ff6b29efa9 100644 (file)
@@ -4,7 +4,7 @@ error: program clause dump
 LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: FromEnv(Self: Bar) :- FromEnv(Self: Bar).
+   = note: FromEnv(Self: Foo) :- FromEnv(Self: Bar).
    = note: FromEnv(Self: Foo) :- FromEnv(Self: Bar).
    = note: Implemented(Self: Bar) :- FromEnv(Self: Bar).
 
@@ -14,7 +14,7 @@ error: program clause dump
 LL | #[rustc_dump_env_program_clauses] //~ ERROR program clause dump
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: FromEnv(Self: Bar) :- FromEnv(Self: Bar).
+   = note: FromEnv(Self: Foo) :- FromEnv(Self: Bar).
    = note: FromEnv(Self: Foo) :- FromEnv(Self: Bar).
    = note: Implemented(Self: Bar) :- FromEnv(Self: Bar).
    = note: Implemented(Self: Foo) :- FromEnv(Self: Foo).
index 2e99921956ab295b1f89dc4bdfe798b7d0bb39aa..8be5b925a399e35bf86d8f2cd068a581aad72cba 100644 (file)
@@ -11,7 +11,7 @@
 fn main() {
     |_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
 
-    while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label
+    while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of loop
 
-    while |_: [_; break]| {} {} //~ ERROR: `break` or `continue` with no label
+    while |_: [_; break]| {} {} //~ ERROR: `break` outside of loop
 }
index 139153992e27402d8a1fd1636ceaff4cd17c17bd..f62b1354370929bbb065ff54b0b4ff99152ce8a0 100644 (file)
@@ -4,19 +4,18 @@ error[E0268]: `continue` outside of loop
 LL |     |_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
    |             ^^^^^^^^ cannot break outside of a loop
 
-error[E0590]: `break` or `continue` with no label in the condition of a `while` loop
+error[E0268]: `continue` outside of loop
   --> $DIR/closure-array-break-length.rs:14:19
    |
-LL |     while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label
-   |                   ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop
+LL |     while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of loop
+   |                   ^^^^^^^^ cannot break outside of a loop
 
-error[E0590]: `break` or `continue` with no label in the condition of a `while` loop
+error[E0268]: `break` outside of loop
   --> $DIR/closure-array-break-length.rs:16:19
    |
-LL |     while |_: [_; break]| {} {} //~ ERROR: `break` or `continue` with no label
-   |                   ^^^^^ unlabeled `break` in the condition of a `while` loop
+LL |     while |_: [_; break]| {} {} //~ ERROR: `break` outside of loop
+   |                   ^^^^^ cannot break outside of a loop
 
 error: aborting due to 3 previous errors
 
-Some errors occurred: E0268, E0590.
-For more information about an error, try `rustc --explain E0268`.
+For more information about this error, try `rustc --explain E0268`.
index 10dcf7d0e657a38d177b763486190b1d1da6f925..46bb7c5af5744f9da42d2156b3800196dfd7ec87 100644 (file)
@@ -2,8 +2,9 @@ error[E0384]: cannot assign twice to immutable variable `x`
   --> $DIR/command-line-diagnostics.rs:16:5
    |
 LL |     let x = 42;
-   |         -   -- first assignment to `x`
+   |         -
    |         |
+   |         first assignment to `x`
    |         consider changing this to `mut x`
 LL |     x = 43;
    |     ^^^^^^ cannot assign twice to immutable variable
index 55c64d2b04e45e7194280eb19e3b8508d7cd82ed..f3578bcef6e411b5018155264b7bbc6be5d28b18 100644 (file)
@@ -10,7 +10,6 @@
 
 static FOO: i32 = [][0];
 //~^ ERROR E0080
-//~| ERROR E0080
 
 fn main() {
     let array = [std::env::args().len()];
index 828fba55a3afebc8b432e9fa6c36d7b18f531ded..464ba8ff92723b622b8987c7a750f7a68c822a20 100644 (file)
@@ -4,22 +4,14 @@ error[E0080]: could not evaluate static initializer
 LL | static FOO: i32 = [][0];
    |                   ^^^^^ index out of bounds: the len is 0 but the index is 0
 
-error[E0080]: could not evaluate static initializer
-  --> $DIR/index_out_of_bounds.rs:11:1
-   |
-LL | static FOO: i32 = [][0];
-   | ^^^^^^^^^^^^^^^^^^-----^
-   |                   |
-   |                   index out of bounds: the len is 0 but the index is 0
-
 error: index out of bounds: the len is 1 but the index is 1
-  --> $DIR/index_out_of_bounds.rs:17:5
+  --> $DIR/index_out_of_bounds.rs:16:5
    |
 LL |     array[1]; //~ ERROR index out of bounds
    |     ^^^^^^^^
    |
    = note: #[deny(const_err)] on by default
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/deprecation-sanity.rs b/src/test/ui/deprecation-sanity.rs
new file mode 100644 (file)
index 0000000..af2ac79
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Various checks that deprecation attributes are used correctly
+
+mod bogus_attribute_types_1 {
+    #[deprecated(since = "a", note = "a", reason)] //~ ERROR unknown meta item 'reason'
+    fn f1() { }
+
+    #[deprecated(since = "a", note)] //~ ERROR incorrect meta item
+    fn f2() { }
+
+    #[deprecated(since, note = "a")] //~ ERROR incorrect meta item
+    fn f3() { }
+
+    #[deprecated(since = "a", note(b))] //~ ERROR incorrect meta item
+    fn f5() { }
+
+    #[deprecated(since(b), note = "a")] //~ ERROR incorrect meta item
+    fn f6() { }
+}
+
+#[deprecated(since = "a", note = "b")]
+#[deprecated(since = "a", note = "b")]
+fn multiple1() { } //~ ERROR multiple deprecated attributes
+
+#[deprecated(since = "a", since = "b", note = "c")] //~ ERROR multiple 'since' items
+fn f1() { }
+
+fn main() { }
diff --git a/src/test/ui/deprecation-sanity.stderr b/src/test/ui/deprecation-sanity.stderr
new file mode 100644 (file)
index 0000000..967eb6e
--- /dev/null
@@ -0,0 +1,46 @@
+error[E0541]: unknown meta item 'reason'
+  --> $DIR/deprecation-sanity.rs:14:43
+   |
+LL |     #[deprecated(since = "a", note = "a", reason)] //~ ERROR unknown meta item 'reason'
+   |                                           ^^^^^^ expected one of `since`, `note`
+
+error[E0551]: incorrect meta item
+  --> $DIR/deprecation-sanity.rs:17:31
+   |
+LL |     #[deprecated(since = "a", note)] //~ ERROR incorrect meta item
+   |                               ^^^^
+
+error[E0551]: incorrect meta item
+  --> $DIR/deprecation-sanity.rs:20:18
+   |
+LL |     #[deprecated(since, note = "a")] //~ ERROR incorrect meta item
+   |                  ^^^^^
+
+error[E0551]: incorrect meta item
+  --> $DIR/deprecation-sanity.rs:23:31
+   |
+LL |     #[deprecated(since = "a", note(b))] //~ ERROR incorrect meta item
+   |                               ^^^^^^^
+
+error[E0551]: incorrect meta item
+  --> $DIR/deprecation-sanity.rs:26:18
+   |
+LL |     #[deprecated(since(b), note = "a")] //~ ERROR incorrect meta item
+   |                  ^^^^^^^^
+
+error[E0550]: multiple deprecated attributes
+  --> $DIR/deprecation-sanity.rs:32:1
+   |
+LL | fn multiple1() { } //~ ERROR multiple deprecated attributes
+   | ^^^^^^^^^^^^^^^^^^
+
+error[E0538]: multiple 'since' items
+  --> $DIR/deprecation-sanity.rs:34:27
+   |
+LL | #[deprecated(since = "a", since = "b", note = "c")] //~ ERROR multiple 'since' items
+   |                           ^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
+
+Some errors occurred: E0538, E0541, E0550, E0551.
+For more information about an error, try `rustc --explain E0538`.
index 0c1dcb29d4d2c2067f795325946bc69e76d45ed7..7eaa4c7d5fea0611e44c562f473965de43a93d86 100644 (file)
@@ -6,26 +6,24 @@ LL |     let f = Foo { v: Vec::new() };
 LL |     f.v.push("cat".to_string()); //~ ERROR cannot borrow
    |     ^^^ cannot borrow as mutable
 
-error[E0384]: cannot assign twice to immutable variable `s.x`
+error[E0384]: cannot assign twice to immutable variable `s`
   --> $DIR/issue-35937.rs:26:5
    |
 LL |     let s = S { x: 42 };
-   |         -   ----------- first assignment to `s.x`
+   |         -
    |         |
+   |         first assignment to `s`
    |         consider changing this to `mut s`
 LL |     s.x += 1; //~ ERROR cannot assign
    |     ^^^^^^^^ cannot assign twice to immutable variable
 
-error[E0384]: cannot assign twice to immutable variable `s.x`
+error[E0384]: cannot assign to immutable argument `s`
   --> $DIR/issue-35937.rs:30:5
    |
 LL | fn bar(s: S) {
-   |        -
-   |        |
-   |        first assignment to `s.x`
-   |        consider changing this to `mut s`
+   |        - consider changing this to `mut s`
 LL |     s.x += 1; //~ ERROR cannot assign
-   |     ^^^^^^^^ cannot assign twice to immutable variable
+   |     ^^^^^^^^ cannot assign to immutable argument
 
 error: aborting due to 3 previous errors
 
index 243e9018585138442786b9830af0e71b0b978069..015538b16f971e4d94d9dc87df35a81aa7894b46 100644 (file)
@@ -2,15 +2,10 @@ error[E0597]: `a` does not live long enough
   --> $DIR/borrowing.rs:18:18
    |
 LL |         unsafe { (|| yield &a).resume() }
-   |                  ^^^^^^^^^^^^^
-   |                  |
-   |                  borrowed value does not live long enough
-   |                  borrow may end up in a temporary, created here
+   |                  ^^^^^^^^^^^^^ borrowed value does not live long enough
 LL |         //~^ ERROR: `a` does not live long enough
 LL |     };
-   |     -- temporary later dropped here, potentially using the reference
-   |     |
-   |     borrowed value only lives until here
+   |     - borrowed value only lives until here
 
 error[E0597]: `a` does not live long enough
   --> $DIR/borrowing.rs:24:9
index 70870b98365b9d1a1cb11fe0dd41f726273d5222..08839c23c37622261aa1cb76e3a157e323af6534 100644 (file)
@@ -1,19 +1,11 @@
 error[E0597]: `b` does not live long enough
   --> $DIR/ref-escapes-but-not-over-yield.rs:24:13
    |
-LL |       let mut b = move || {
-   |  _________________-
-LL | |         yield();
-LL | |         let b = 5;
-LL | |         a = &b;
-   | |             ^^ borrowed value does not live long enough
-LL | |         //~^ ERROR `b` does not live long enough
-LL | |     };
-   | |     -
-   | |     |
-   | |     borrowed value only lives until here
-   | |_____temporary later dropped here, potentially using the reference
-   |       borrow may end up in a temporary, created here
+LL |         a = &b;
+   |             ^^ borrowed value does not live long enough
+LL |         //~^ ERROR `b` does not live long enough
+LL |     };
+   |     - borrowed value only lives until here
 
 error: aborting due to previous error
 
index b1289146e0ea9e12785675f1198dbedf4ea8636f..4bdce85d18b5feff02dbd3340dd7a1ef64f9e79b 100644 (file)
@@ -3,15 +3,9 @@ error[E0502]: cannot borrow `heap` as immutable because it is also borrowed as m
    |
 LL |     let borrow = heap.peek_mut();
    |                  ---- mutable borrow occurs here
-LL | 
-LL |     match (borrow, ()) {
-   |           ------------ borrow may end up in a temporary, created here
-LL |         (Some(_), ()) => {
+...
 LL |             println!("{:?}", heap); //~ ERROR cannot borrow `heap` as immutable
    |                              ^^^^ immutable borrow occurs here
-...
-LL |     };
-   |      - temporary later dropped here, potentially using the reference
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-51632-try-desugar-incompatible-types.fixed b/src/test/ui/issue-51632-try-desugar-incompatible-types.fixed
new file mode 100644 (file)
index 0000000..016cff9
--- /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.
+
+// run-rustfix
+
+#![allow(dead_code)]
+
+fn missing_discourses() -> Result<isize, ()> {
+    Ok(1)
+}
+
+fn forbidden_narratives() -> Result<isize, ()> {
+    Ok(missing_discourses()?)
+    //~^ ERROR try expression alternatives have incompatible types
+    //~| HELP try wrapping with a success variant
+}
+
+fn main() {}
diff --git a/src/test/ui/issue-51632-try-desugar-incompatible-types.rs b/src/test/ui/issue-51632-try-desugar-incompatible-types.rs
new file mode 100644 (file)
index 0000000..315773a
--- /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.
+
+// run-rustfix
+
+#![allow(dead_code)]
+
+fn missing_discourses() -> Result<isize, ()> {
+    Ok(1)
+}
+
+fn forbidden_narratives() -> Result<isize, ()> {
+    missing_discourses()?
+    //~^ ERROR try expression alternatives have incompatible types
+    //~| HELP try wrapping with a success variant
+}
+
+fn main() {}
diff --git a/src/test/ui/issue-51632-try-desugar-incompatible-types.stderr b/src/test/ui/issue-51632-try-desugar-incompatible-types.stderr
new file mode 100644 (file)
index 0000000..a50af56
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0308]: try expression alternatives have incompatible types
+  --> $DIR/issue-51632-try-desugar-incompatible-types.rs:20:5
+   |
+LL |     missing_discourses()?
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |     |
+   |     expected enum `std::result::Result`, found isize
+   |     help: try wrapping with a success variant: `Ok(missing_discourses()?)`
+   |
+   = note: expected type `std::result::Result<isize, ()>`
+              found type `isize`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
index 96c5b92ddfdcc974aa7ed691e900fccbc25791f7..2b9d51f81b9886d1da007d5cbc987277202e7acd 100644 (file)
@@ -9,11 +9,16 @@
 // except according to those terms.
 
 fn main() {
-    |_:  [_; return || {}] | {}
+    |_:  [_; return || {}] | {};
     //~^ ERROR return statement outside of function body
-}
 
-fn foo() {
     [(); return || {}];
     //~^ ERROR return statement outside of function body
+
+    [(); return |ice| {}];
+    //~^ ERROR return statement outside of function body
+
+    [(); return while let Some(n) = Some(0) {}];
+    //~^ ERROR return statement outside of function body
+    //~^^ ERROR irrefutable while-let pattern
 }
index 746adea6b7ed7bc687394456e4541c3fbd681284..ddc70bfb38e0127244d7ef2c82999722c42a493b 100644 (file)
@@ -1,15 +1,34 @@
 error[E0572]: return statement outside of function body
   --> $DIR/issue-51714.rs:12:14
    |
-LL |     |_:  [_; return || {}] | {}
+LL |     |_:  [_; return || {}] | {};
    |              ^^^^^^^^^^^^
 
 error[E0572]: return statement outside of function body
-  --> $DIR/issue-51714.rs:17:10
+  --> $DIR/issue-51714.rs:15:10
    |
 LL |     [(); return || {}];
    |          ^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error[E0572]: return statement outside of function body
+  --> $DIR/issue-51714.rs:18:10
+   |
+LL |     [(); return |ice| {}];
+   |          ^^^^^^^^^^^^^^^
+
+error[E0572]: return statement outside of function body
+  --> $DIR/issue-51714.rs:21:10
+   |
+LL |     [(); return while let Some(n) = Some(0) {}];
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0165]: irrefutable while-let pattern
+  --> $DIR/issue-51714.rs:21:27
+   |
+LL |     [(); return while let Some(n) = Some(0) {}];
+   |                           ^^^^^^^ irrefutable pattern
+
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0572`.
+Some errors occurred: E0165, E0572.
+For more information about an error, try `rustc --explain E0165`.
diff --git a/src/test/ui/lint/test-inner-fn.rs b/src/test/ui/lint/test-inner-fn.rs
new file mode 100644 (file)
index 0000000..4304c96
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: --test -D unnameable_test_functions
+
+#[test]
+fn foo() {
+    #[test] //~ ERROR cannot test inner function [unnameable_test_functions]
+    fn bar() {}
+    bar();
+}
+
+mod x {
+    #[test]
+    fn foo() {
+        #[test] //~ ERROR cannot test inner function [unnameable_test_functions]
+        fn bar() {}
+        bar();
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/test-inner-fn.stderr b/src/test/ui/lint/test-inner-fn.stderr
new file mode 100644 (file)
index 0000000..37f0c16
--- /dev/null
@@ -0,0 +1,16 @@
+error: cannot test inner function
+  --> $DIR/test-inner-fn.rs:15:5
+   |
+LL |     #[test] //~ ERROR cannot test inner function [unnameable_test_functions]
+   |     ^^^^^^^
+   |
+   = note: requested on the command line with `-D unnameable-test-functions`
+
+error: cannot test inner function
+  --> $DIR/test-inner-fn.rs:23:9
+   |
+LL |         #[test] //~ ERROR cannot test inner function [unnameable_test_functions]
+   |         ^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/nll/capture-mut-ref.rs b/src/test/ui/nll/capture-mut-ref.rs
new file mode 100644 (file)
index 0000000..c3c5053
--- /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.
+
+// Check that capturing a mutable reference by move and assigning to its
+// referent doesn't make the unused mut lint think that it is mutable.
+
+#![feature(nll)]
+#![deny(unused_mut)]
+
+fn mutable_upvar() {
+    let mut x = &mut 0;
+    //~^ ERROR
+    move || {
+        *x = 1;
+    };
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/capture-mut-ref.stderr b/src/test/ui/nll/capture-mut-ref.stderr
new file mode 100644 (file)
index 0000000..50a77ee
--- /dev/null
@@ -0,0 +1,16 @@
+error: variable does not need to be mutable
+  --> $DIR/capture-mut-ref.rs:18:9
+   |
+LL |     let mut x = &mut 0;
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+   |
+note: lint level defined here
+  --> $DIR/capture-mut-ref.rs:15:9
+   |
+LL | #![deny(unused_mut)]
+   |         ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/nll/extra-unused-mut.rs b/src/test/ui/nll/extra-unused-mut.rs
new file mode 100644 (file)
index 0000000..ce07e2b
--- /dev/null
@@ -0,0 +1,64 @@
+// 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.
+
+// extra unused mut lint tests for #51918
+
+// run-pass
+
+#![feature(generators, nll)]
+#![deny(unused_mut)]
+
+fn ref_argument(ref _y: i32) {}
+
+// #51801
+fn mutable_upvar() {
+    let mut x = 0;
+    move || {
+        x = 1;
+    };
+}
+
+// #50897
+fn generator_mutable_upvar() {
+    let mut x = 0;
+    move || {
+        x = 1;
+        yield;
+    };
+}
+
+// #51830
+fn ref_closure_argument() {
+    let _ = Some(0).as_ref().map(|ref _a| true);
+}
+
+struct Expr {
+    attrs: Vec<u32>,
+}
+
+// #51904
+fn parse_dot_or_call_expr_with(mut attrs: Vec<u32>) {
+    let x = Expr { attrs: vec![] };
+    Some(Some(x)).map(|expr|
+        expr.map(|mut expr| {
+            attrs.push(666);
+            expr.attrs = attrs;
+            expr
+        })
+    );
+}
+
+fn main() {
+    ref_argument(0);
+    mutable_upvar();
+    generator_mutable_upvar();
+    ref_closure_argument();
+    parse_dot_or_call_expr_with(Vec::new());
+}
diff --git a/src/test/ui/nll/generator-upvar-mutability.rs b/src/test/ui/nll/generator-upvar-mutability.rs
new file mode 100644 (file)
index 0000000..a32e076
--- /dev/null
@@ -0,0 +1,24 @@
+// 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.
+
+// Check that generators respect the muatability of their upvars.
+
+#![feature(generators, nll)]
+
+fn mutate_upvar() {
+    let x = 0;
+    move || {
+        x = 1;
+        //~^ ERROR
+        yield;
+    };
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/generator-upvar-mutability.stderr b/src/test/ui/nll/generator-upvar-mutability.stderr
new file mode 100644 (file)
index 0000000..9c5c576
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0594]: cannot assign to immutable item `x`
+  --> $DIR/generator-upvar-mutability.rs:18:9
+   |
+LL |         x = 1;
+   |         ^^^^^ cannot assign
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0594`.
diff --git a/src/test/ui/return-match-array-const.rs b/src/test/ui/return-match-array-const.rs
new file mode 100644 (file)
index 0000000..45fc571
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    [(); return match 0 { n => n }]; //~ ERROR: return statement outside of function body
+
+    [(); return match 0 { 0 => 0 }]; //~ ERROR: return statement outside of function body
+
+    [(); return match () { 'a' => 0, _ => 0 }]; //~ ERROR: return statement outside of function body
+}
diff --git a/src/test/ui/return-match-array-const.stderr b/src/test/ui/return-match-array-const.stderr
new file mode 100644 (file)
index 0000000..044dc8f
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0572]: return statement outside of function body
+  --> $DIR/return-match-array-const.rs:12:10
+   |
+LL |     [(); return match 0 { n => n }]; //~ ERROR: return statement outside of function body
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0572]: return statement outside of function body
+  --> $DIR/return-match-array-const.rs:14:10
+   |
+LL |     [(); return match 0 { 0 => 0 }]; //~ ERROR: return statement outside of function body
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0572]: return statement outside of function body
+  --> $DIR/return-match-array-const.rs:16:10
+   |
+LL |     [(); return match () { 'a' => 0, _ => 0 }]; //~ ERROR: return statement outside of function body
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0572`.
index 5de246cbb73413f78cd530aa30250ae2f567ba84..8be4cf445da3f77c2261843cd1c3b8a39c445176 100644 (file)
@@ -2,14 +2,9 @@ error[E0597]: `*a` does not live long enough
   --> $DIR/destructor-restrictions.rs:18:10
    |
 LL |         *a.borrow() + 1
-   |          ^---------
-   |          |
-   |          borrowed value does not live long enough
-   |          borrow may end up in a temporary, created here
+   |          ^ borrowed value does not live long enough
 LL |     }; //~^ ERROR `*a` does not live long enough
-   |     -- temporary later dropped here, potentially using the reference
-   |     |
-   |     borrowed value only lives until here
+   |     - borrowed value only lives until here
 
 error: aborting due to previous error
 
index 56f2d14390ecdb5ee60001ff3214dc6c67cb9301..ec2f5a25631c4aedb4748dbde77c01a39c9e5190 100644 (file)
@@ -2,28 +2,17 @@ error[E0597]: `y` does not live long enough
   --> $DIR/issue-23338-locals-die-before-temps-of-body.rs:20:5
    |
 LL |     y.borrow().clone()
-   |     ^---------
-   |     |
-   |     borrowed value does not live long enough
-   |     borrow may end up in a temporary, created here
+   |     ^ borrowed value does not live long enough
 LL | }
-   | -
-   | |
-   | borrowed value only lives until here
-   | temporary later dropped here, potentially using the reference
+   | - borrowed value only lives until here
 
 error[E0597]: `y` does not live long enough
   --> $DIR/issue-23338-locals-die-before-temps-of-body.rs:27:9
    |
 LL |         y.borrow().clone()
-   |         ^---------
-   |         |
-   |         borrowed value does not live long enough
-   |         borrow may end up in a temporary, created here
+   |         ^ borrowed value does not live long enough
 LL |     };
-   |     -- temporary later dropped here, potentially using the reference
-   |     |
-   |     borrowed value only lives until here
+   |     - borrowed value only lives until here
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/suggestions/issue-48364.rs b/src/test/ui/suggestions/issue-48364.rs
new file mode 100644 (file)
index 0000000..82cb722
--- /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.
+
+fn foo() -> bool {
+    b"".starts_with(stringify!(foo))
+    //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/issue-48364.stderr b/src/test/ui/suggestions/issue-48364.stderr
new file mode 100644 (file)
index 0000000..b420654
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-48364.rs:12:21
+   |
+LL |     b"".starts_with(stringify!(foo))
+   |                     ^^^^^^^^^^^^^^^ expected slice, found str
+   |
+   = note: expected type `&[u8]`
+              found type `&'static str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
index aa124110243a52cc6cdb67cedb742d45237a8843..f6d7086679a52560d98bc7accb128866ed5ed3ab 100644 (file)
@@ -30,7 +30,11 @@ error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not sa
 LL | struct Bounds<T:Copy=String>(T);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
    |
-   = note: required by `std::marker::Copy`
+note: required by `Bounds`
+  --> $DIR/type-check-defaults.rs:21:1
+   |
+LL | struct Bounds<T:Copy=String>(T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
   --> $DIR/type-check-defaults.rs:24:1
@@ -38,7 +42,11 @@ error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not sa
 LL | struct WhereClause<T=String>(T) where T: Copy;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
    |
-   = note: required by `std::marker::Copy`
+note: required by `WhereClause`
+  --> $DIR/type-check-defaults.rs:24:1
+   |
+LL | struct WhereClause<T=String>(T) where T: Copy;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
   --> $DIR/type-check-defaults.rs:27:1
@@ -46,7 +54,11 @@ error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not sa
 LL | trait TraitBound<T:Copy=String> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
    |
-   = note: required by `std::marker::Copy`
+note: required by `TraitBound`
+  --> $DIR/type-check-defaults.rs:27:1
+   |
+LL | trait TraitBound<T:Copy=String> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/type-check-defaults.rs:31:1
@@ -68,7 +80,11 @@ LL | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `i32 + u8`
    |
    = help: the trait `std::ops::Add<u8>` is not implemented for `i32`
-   = note: required by `std::ops::Add`
+note: required by `ProjectionPred`
+  --> $DIR/type-check-defaults.rs:34:1
+   |
+LL | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 7 previous errors
 
index 6add6495a9351b8cd3b456bec976db9e28ab75b3..b2aa5cfb444d9127496bb59b67a2457e5281845e 100644 (file)
@@ -88,6 +88,7 @@
     "powerpc-unknown-linux-gnuspe",
     "powerpc64-unknown-linux-gnu",
     "powerpc64le-unknown-linux-gnu",
+    "powerpc64le-unknown-linux-musl",
     "s390x-unknown-linux-gnu",
     "sparc-unknown-linux-gnu",
     "sparc64-unknown-linux-gnu",
@@ -183,6 +184,7 @@ struct Builder {
     rust_release: String,
     cargo_release: String,
     rls_release: String,
+    clippy_release: String,
     rustfmt_release: String,
     llvm_tools_release: String,
 
@@ -196,12 +198,14 @@ struct Builder {
     rust_version: Option<String>,
     cargo_version: Option<String>,
     rls_version: Option<String>,
+    clippy_version: Option<String>,
     rustfmt_version: Option<String>,
     llvm_tools_version: Option<String>,
 
     rust_git_commit_hash: Option<String>,
     cargo_git_commit_hash: Option<String>,
     rls_git_commit_hash: Option<String>,
+    clippy_git_commit_hash: Option<String>,
     rustfmt_git_commit_hash: Option<String>,
     llvm_tools_git_commit_hash: Option<String>,
 }
@@ -214,6 +218,7 @@ fn main() {
     let rust_release = args.next().unwrap();
     let cargo_release = args.next().unwrap();
     let rls_release = args.next().unwrap();
+    let clippy_release = args.next().unwrap();
     let rustfmt_release = args.next().unwrap();
     let llvm_tools_release = args.next().unwrap();
     let s3_address = args.next().unwrap();
@@ -224,6 +229,7 @@ fn main() {
         rust_release,
         cargo_release,
         rls_release,
+        clippy_release,
         rustfmt_release,
         llvm_tools_release,
 
@@ -237,12 +243,14 @@ fn main() {
         rust_version: None,
         cargo_version: None,
         rls_version: None,
+        clippy_version: None,
         rustfmt_version: None,
         llvm_tools_version: None,
 
         rust_git_commit_hash: None,
         cargo_git_commit_hash: None,
         rls_git_commit_hash: None,
+        clippy_git_commit_hash: None,
         rustfmt_git_commit_hash: None,
         llvm_tools_git_commit_hash: None,
     }.build();
@@ -259,6 +267,7 @@ fn build(&mut self) {
         self.rust_git_commit_hash = self.git_commit_hash("rust", "x86_64-unknown-linux-gnu");
         self.cargo_git_commit_hash = self.git_commit_hash("cargo", "x86_64-unknown-linux-gnu");
         self.rls_git_commit_hash = self.git_commit_hash("rls", "x86_64-unknown-linux-gnu");
+        self.clippy_git_commit_hash = self.git_commit_hash("clippy", "x86_64-unknown-linux-gnu");
         self.rustfmt_git_commit_hash = self.git_commit_hash("rustfmt", "x86_64-unknown-linux-gnu");
         self.llvm_tools_git_commit_hash = self.git_commit_hash("llvm-tools",
                                                                "x86_64-unknown-linux-gnu");
@@ -296,10 +305,12 @@ fn build_manifest(&mut self) -> Manifest {
         self.package("rust-docs", &mut manifest.pkg, TARGETS);
         self.package("rust-src", &mut manifest.pkg, &["*"]);
         self.package("rls-preview", &mut manifest.pkg, HOSTS);
+        self.package("clippy-preview", &mut manifest.pkg, HOSTS);
         self.package("rustfmt-preview", &mut manifest.pkg, HOSTS);
         self.package("rust-analysis", &mut manifest.pkg, TARGETS);
         self.package("llvm-tools-preview", &mut manifest.pkg, TARGETS);
 
+        let clippy_present = manifest.pkg.contains_key("clippy-preview");
         let rls_present = manifest.pkg.contains_key("rls-preview");
         let rustfmt_present = manifest.pkg.contains_key("rustfmt-preview");
         let llvm_tools_present = manifest.pkg.contains_key("llvm-tools-preview");
@@ -345,6 +356,12 @@ fn build_manifest(&mut self) -> Manifest {
                 });
             }
 
+            if clippy_present {
+                extensions.push(Component {
+                    pkg: "clippy-preview".to_string(),
+                    target: host.to_string(),
+                });
+            }
             if rls_present {
                 extensions.push(Component {
                     pkg: "rls-preview".to_string(),
@@ -470,6 +487,8 @@ fn filename(&self, component: &str, target: &str) -> String {
             format!("cargo-{}-{}.tar.gz", self.cargo_release, target)
         } else if component == "rls" || component == "rls-preview" {
             format!("rls-{}-{}.tar.gz", self.rls_release, target)
+        } else if component == "clippy" || component == "clippy-preview" {
+            format!("clippy-{}-{}.tar.gz", self.clippy_release, target)
         } else if component == "rustfmt" || component == "rustfmt-preview" {
             format!("rustfmt-{}-{}.tar.gz", self.rustfmt_release, target)
         } else if component == "llvm_tools" {
@@ -484,6 +503,8 @@ fn cached_version(&self, component: &str) -> &Option<String> {
             &self.cargo_version
         } else if component == "rls" || component == "rls-preview" {
             &self.rls_version
+        } else if component == "clippy" || component == "clippy-preview" {
+            &self.clippy_version
         } else if component == "rustfmt" || component == "rustfmt-preview" {
             &self.rustfmt_version
         } else if component == "llvm-tools" || component == "llvm-tools-preview" {
@@ -498,6 +519,8 @@ fn cached_git_commit_hash(&self, component: &str) -> &Option<String> {
             &self.cargo_git_commit_hash
         } else if component == "rls" || component == "rls-preview" {
             &self.rls_git_commit_hash
+        } else if component == "clippy" || component == "clippy-preview" {
+            &self.clippy_git_commit_hash
         } else if component == "rustfmt" || component == "rustfmt-preview" {
             &self.rustfmt_git_commit_hash
         } else if component == "llvm-tools" || component == "llvm-tools-preview" {
index ebe0b0eed596243a2839867363cb31d93f0b9754..28daee4c919dd88772847ec5240eb850bb0dcbf3 160000 (submodule)
@@ -1 +1 @@
-Subproject commit ebe0b0eed596243a2839867363cb31d93f0b9754
+Subproject commit 28daee4c919dd88772847ec5240eb850bb0dcbf3
index 9143a69f4b3ef4bda77afddefe934be363e39f31..5b7bb32b0e46d195b80c4da09b560ac7fc92015d 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 9143a69f4b3ef4bda77afddefe934be363e39f31
+Subproject commit 5b7bb32b0e46d195b80c4da09b560ac7fc92015d
index 3c1fceaf8faa88afcedafff243b0f8f3c3cf1c9c..c8ce4cf8bb5be935c999bab25991951f0caaaee9 100644 (file)
@@ -233,6 +233,7 @@ function main(argv) {
 
     var arraysToLoad = ["itemTypes"];
     var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS",
+                           "GENERICS_DATA", "NAME", "INPUTS_DATA", "OUTPUT_DATA",
                            "TY_PRIMITIVE", "TY_KEYWORD",
                            "levenshtein_row2"];
     // execQuery first parameter is built in getQuery (which takes in the search input).