]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #52046 - cramertj:fix-generator-mir, r=eddyb
authorbors <bors@rust-lang.org>
Fri, 13 Jul 2018 00:38:17 +0000 (00:38 +0000)
committerbors <bors@rust-lang.org>
Fri, 13 Jul 2018 00:38:17 +0000 (00:38 +0000)
Ensure StorageDead is created even if variable initialization fails

Rebase and slight cleanup of https://github.com/rust-lang/rust/pull/51109
Fixes https://github.com/rust-lang/rust/issues/49232

r? @eddyb

561 files changed:
.travis.yml
README.md
RELEASES.md
config.toml.example
src/Cargo.lock
src/Cargo.toml
src/bootstrap/Cargo.toml
src/bootstrap/bin/rustc.rs
src/bootstrap/bootstrap.py
src/bootstrap/builder.rs
src/bootstrap/cache.rs
src/bootstrap/check.rs
src/bootstrap/compile.rs
src/bootstrap/config.rs
src/bootstrap/configure.py
src/bootstrap/dist.rs
src/bootstrap/doc.rs
src/bootstrap/lib.rs
src/bootstrap/native.rs
src/bootstrap/test.rs
src/bootstrap/tool.rs
src/ci/docker/scripts/musl.sh
src/ci/docker/x86_64-gnu-llvm-3.9/Dockerfile [deleted file]
src/ci/docker/x86_64-gnu-llvm-5.0/Dockerfile [new file with mode: 0644]
src/doc/rustdoc/src/documentation-tests.md
src/doc/unstable-book/src/language-features/tool-lints.md [new file with mode: 0644]
src/liballoc/boxed.rs
src/liballoc/boxed_test.rs
src/liballoc/lib.rs
src/liballoc/prelude.rs [new file with mode: 0644]
src/liballoc/rc.rs
src/liballoc/sync.rs
src/liballoc/task.rs
src/liballoc/tests/arc.rs [new file with mode: 0644]
src/liballoc/tests/lib.rs
src/liballoc/tests/rc.rs [new file with mode: 0644]
src/liballoc/vec.rs
src/libcompiler_builtins
src/libcore/alloc.rs
src/libcore/any.rs
src/libcore/cell.rs
src/libcore/iter/iterator.rs
src/libcore/marker.rs
src/libcore/mem.rs
src/libcore/nonzero.rs
src/libcore/num/flt2dec/strategy/dragon.rs
src/libcore/num/flt2dec/strategy/grisu.rs
src/libcore/num/mod.rs
src/libcore/panic.rs
src/libcore/ptr.rs
src/libcore/slice/mod.rs
src/libcore/sync/atomic.rs
src/libcore/task/wake.rs
src/libcore/tests/slice.rs
src/libpanic_unwind/dwarf/eh.rs
src/libpanic_unwind/emcc.rs
src/libpanic_unwind/gcc.rs
src/libpanic_unwind/lib.rs
src/libpanic_unwind/seh.rs
src/libpanic_unwind/seh64_gnu.rs
src/libpanic_unwind/wasm32.rs
src/libproc_macro/lib.rs
src/librustc/dep_graph/dep_node.rs
src/librustc/diagnostics.rs
src/librustc/hir/check_attr.rs
src/librustc/hir/def.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/definitions.rs
src/librustc/hir/mod.rs
src/librustc/ich/impls_hir.rs
src/librustc/ich/impls_mir.rs
src/librustc/ich/impls_ty.rs
src/librustc/infer/error_reporting/mod.rs
src/librustc/infer/lexical_region_resolve/graphviz.rs
src/librustc/lib.rs
src/librustc/lint/builtin.rs
src/librustc/lint/levels.rs
src/librustc/middle/cstore.rs
src/librustc/middle/dead.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/weak_lang_items.rs
src/librustc/mir/interpret/error.rs
src/librustc/mir/interpret/mod.rs
src/librustc/mir/interpret/value.rs
src/librustc/mir/mod.rs
src/librustc/mir/mono.rs
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc/traits/fulfill.rs
src/librustc/traits/object_safety.rs
src/librustc/traits/select.rs
src/librustc/ty/context.rs
src/librustc/ty/fold.rs
src/librustc/ty/layout.rs
src/librustc/ty/mod.rs
src/librustc/ty/query/config.rs
src/librustc/ty/query/mod.rs
src/librustc/ty/query/plumbing.rs
src/librustc/ty/structural_impls.rs
src/librustc/ty/sty.rs
src/librustc/ty/util.rs
src/librustc/util/time_graph.rs [new file with mode: 0644]
src/librustc_allocator/expand.rs
src/librustc_allocator/lib.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_borrowck/borrowck/unused.rs
src/librustc_codegen_llvm/abi.rs
src/librustc_codegen_llvm/attributes.rs
src/librustc_codegen_llvm/back/archive.rs
src/librustc_codegen_llvm/back/link.rs
src/librustc_codegen_llvm/back/linker.rs
src/librustc_codegen_llvm/back/lto.rs
src/librustc_codegen_llvm/back/rpath.rs
src/librustc_codegen_llvm/back/wasm.rs
src/librustc_codegen_llvm/back/write.rs
src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/builder.rs
src/librustc_codegen_llvm/intrinsic.rs
src/librustc_codegen_llvm/lib.rs
src/librustc_codegen_llvm/llvm_util.rs
src/librustc_codegen_llvm/mir/mod.rs
src/librustc_codegen_llvm/mir/operand.rs
src/librustc_codegen_llvm/mir/place.rs
src/librustc_codegen_llvm/mir/rvalue.rs
src/librustc_codegen_llvm/mono_item.rs
src/librustc_codegen_llvm/time_graph.rs [deleted file]
src/librustc_codegen_llvm/type_of.rs
src/librustc_codegen_utils/Cargo.toml
src/librustc_codegen_utils/codegen_backend.rs
src/librustc_codegen_utils/lib.rs
src/librustc_data_structures/lib.rs
src/librustc_data_structures/owning_ref/mod.rs
src/librustc_data_structures/sync.rs
src/librustc_driver/Cargo.toml
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_lint/builtin.rs
src/librustc_lint/lib.rs
src/librustc_metadata/creader.rs
src/librustc_metadata/cstore.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/lib.rs
src/librustc_metadata/locator.rs
src/librustc_metadata/schema.rs
src/librustc_mir/borrow_check/borrow_set.rs
src/librustc_mir/borrow_check/error_reporting.rs
src/librustc_mir/borrow_check/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/error_reporting.rs [deleted file]
src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs [new file with mode: 0644]
src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs [new file with mode: 0644]
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
src/librustc_mir/borrow_check/nll/universal_regions.rs
src/librustc_mir/borrow_check/path_utils.rs
src/librustc_mir/borrow_check/places_conflict.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/machine.rs
src/librustc_mir/interpret/memory.rs
src/librustc_mir/interpret/place.rs
src/librustc_mir/interpret/step.rs
src/librustc_mir/monomorphize/collector.rs
src/librustc_mir/monomorphize/item.rs
src/librustc_mir/monomorphize/partitioning.rs
src/librustc_mir/transform/check_unsafety.rs
src/librustc_mir/transform/mod.rs
src/librustc_mir/transform/rustc_peek.rs
src/librustc_mir/util/liveness.rs
src/librustc_passes/loops.rs
src/librustc_passes/rvalue_promotion.rs
src/librustc_resolve/diagnostics.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/librustc_target/spec/mod.rs
src/librustc_target/spec/msp430_none_elf.rs
src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs [new file with mode: 0644]
src/librustc_target/spec/thumbv6m_none_eabi.rs
src/librustc_target/spec/wasm32_unknown_unknown.rs
src/librustc_target/spec/x86_64_unknown_haiku.rs
src/librustc_traits/lowering.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/librustc_typeck/outlives/explicit.rs
src/librustc_typeck/outlives/implicit_infer.rs
src/librustc_typeck/outlives/mod.rs
src/librustdoc/clean/inline.rs
src/librustdoc/core.rs
src/librustdoc/fold.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/lib.rs
src/librustdoc/plugins.rs
src/librustdoc/visit_ast.rs
src/libstd/alloc.rs
src/libstd/build.rs
src/libstd/env.rs
src/libstd/ffi/c_str.rs
src/libstd/ffi/os_str.rs
src/libstd/fs.rs
src/libstd/lib.rs
src/libstd/path.rs
src/libstd/prelude/v1.rs
src/libstd/sync/mpsc/mod.rs
src/libstd/sync/once.rs
src/libstd/sys/redox/ext/mod.rs
src/libstd/sys/redox/ext/net.rs [new file with mode: 0644]
src/libstd/sys/redox/fd.rs
src/libstd/sys/unix/ext/net.rs
src/libsyntax/attr/mod.rs
src/libsyntax/codemap.rs
src/libsyntax/diagnostics/metadata.rs
src/libsyntax/diagnostics/plugin.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/quote.rs
src/libsyntax/ext/source_util.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/feature_gate.rs
src/libsyntax/json.rs
src/libsyntax/lib.rs
src/libsyntax/parse/lexer/comments.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pp.rs
src/libsyntax/print/pprust.rs
src/libsyntax/test.rs
src/libsyntax_ext/asm.rs
src/libsyntax_ext/assert.rs
src/libsyntax_ext/cfg.rs
src/libsyntax_ext/compile_error.rs
src/libsyntax_ext/concat.rs
src/libsyntax_ext/concat_idents.rs
src/libsyntax_ext/deriving/bounds.rs
src/libsyntax_ext/deriving/clone.rs
src/libsyntax_ext/deriving/cmp/eq.rs
src/libsyntax_ext/deriving/cmp/ord.rs
src/libsyntax_ext/deriving/cmp/partial_eq.rs
src/libsyntax_ext/deriving/cmp/partial_ord.rs
src/libsyntax_ext/deriving/debug.rs
src/libsyntax_ext/deriving/decodable.rs
src/libsyntax_ext/deriving/default.rs
src/libsyntax_ext/deriving/encodable.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_ext/deriving/hash.rs
src/libsyntax_ext/deriving/mod.rs
src/libsyntax_ext/env.rs
src/libsyntax_ext/format.rs
src/libsyntax_ext/global_asm.rs
src/libsyntax_ext/lib.rs
src/libsyntax_ext/log_syntax.rs
src/libsyntax_ext/proc_macro_registrar.rs
src/libsyntax_ext/trace_macros.rs
src/libsyntax_pos/hygiene.rs
src/libsyntax_pos/lib.rs
src/libsyntax_pos/span_encoding.rs
src/llvm
src/rustllvm/PassWrapper.cpp
src/rustllvm/RustWrapper.cpp
src/rustllvm/rustllvm.h
src/test/codegen/align-struct.rs
src/test/codegen/call-metadata.rs
src/test/codegen/consts.rs
src/test/codegen/function-arguments.rs
src/test/codegen/issue-37945.rs
src/test/codegen/issue-45466.rs
src/test/codegen/mainsubprogram.rs
src/test/codegen/mainsubprogramstart.rs
src/test/codegen/noreturnflag.rs
src/test/codegen/packed.rs
src/test/codegen/repeat-trusted-len.rs
src/test/codegen/scalar-pair-bool.rs [new file with mode: 0644]
src/test/codegen/simd-intrinsic-float-minmax.rs
src/test/codegen/stack-probes.rs
src/test/codegen/stores.rs
src/test/codegen/vtabletype.rs
src/test/compile-fail/alloc-error-handler-bad-signature-1.rs [new file with mode: 0644]
src/test/compile-fail/alloc-error-handler-bad-signature-2.rs [new file with mode: 0644]
src/test/compile-fail/alloc-error-handler-bad-signature-3.rs [new file with mode: 0644]
src/test/compile-fail/associated-types-unsized.rs
src/test/compile-fail/bad-sized.rs
src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
src/test/compile-fail/dst-bad-assign-2.rs
src/test/compile-fail/dst-bad-assign-3.rs
src/test/compile-fail/dst-bad-assign.rs
src/test/compile-fail/dst-bad-deep-2.rs
src/test/compile-fail/dst-bad-deep.rs
src/test/compile-fail/dst-object-from-unsized-type.rs
src/test/compile-fail/dst-sized-trait-param.rs
src/test/compile-fail/extern-types-unsized.rs
src/test/compile-fail/feature-gate-alloc-error-handler.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-tool_lints.rs [new file with mode: 0644]
src/test/compile-fail/foreign-unsafe-fn-called.rs
src/test/compile-fail/forget-init-unsafe.rs [deleted file]
src/test/compile-fail/immut-function-arguments.rs
src/test/compile-fail/init-unsafe.rs [new file with mode: 0644]
src/test/compile-fail/issue-14227.rs
src/test/compile-fail/issue-14366.rs
src/test/compile-fail/issue-15756.rs
src/test/compile-fail/issue-17651.rs
src/test/compile-fail/issue-18107.rs
src/test/compile-fail/issue-18919.rs
src/test/compile-fail/issue-20005.rs
src/test/compile-fail/issue-20433.rs
src/test/compile-fail/issue-20605.rs
src/test/compile-fail/issue-22874.rs
src/test/compile-fail/issue-23281.rs
src/test/compile-fail/issue-24446.rs
src/test/compile-fail/issue-27060-2.rs
src/test/compile-fail/issue-27060.rs [deleted file]
src/test/compile-fail/issue-27078.rs
src/test/compile-fail/issue-28324.rs
src/test/compile-fail/issue-35988.rs
src/test/compile-fail/issue-38954.rs
src/test/compile-fail/issue-41229-ref-str.rs
src/test/compile-fail/issue-42312.rs
src/test/compile-fail/issue-43733.rs
src/test/compile-fail/issue-45087-unreachable-unsafe.rs
src/test/compile-fail/issue-45729-unsafe-in-generator.rs
src/test/compile-fail/issue-47412.rs
src/test/compile-fail/issue-52213.rs [new file with mode: 0644]
src/test/compile-fail/issue-5883.rs
src/test/compile-fail/mir-dataflow/def-inits-1.rs
src/test/compile-fail/mir-dataflow/inits-1.rs
src/test/compile-fail/mir-dataflow/uninits-1.rs
src/test/compile-fail/mir-dataflow/uninits-2.rs
src/test/compile-fail/mir_check_cast_closure.rs
src/test/compile-fail/mir_check_cast_reify.rs
src/test/compile-fail/mir_check_cast_unsafe_fn.rs
src/test/compile-fail/mir_check_cast_unsize.rs
src/test/compile-fail/range-1.rs
src/test/compile-fail/regions-static-bound.rs
src/test/compile-fail/safe-extern-statics-mut.rs
src/test/compile-fail/safe-extern-statics.rs
src/test/compile-fail/simd-intrinsic-generic-reduction.rs
src/test/compile-fail/str-mut-idx.rs
src/test/compile-fail/substs-ppaux.rs
src/test/compile-fail/tool_lints.rs [new file with mode: 0644]
src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
src/test/compile-fail/union/union-unsafe.rs
src/test/compile-fail/union/union-unsized.rs
src/test/compile-fail/unknown-lint-tool-name.rs [new file with mode: 0644]
src/test/compile-fail/unsafe-fn-assign-deref-ptr.rs
src/test/compile-fail/unsafe-fn-called-from-safe.rs
src/test/compile-fail/unsafe-fn-deref-ptr.rs
src/test/compile-fail/unsafe-fn-used-as-value.rs
src/test/compile-fail/unsafe-move-val-init.rs
src/test/compile-fail/unsized-bare-typaram.rs
src/test/compile-fail/unsized-enum.rs
src/test/compile-fail/unsized-inherent-impl-self-type.rs
src/test/compile-fail/unsized-struct.rs
src/test/compile-fail/unsized-trait-impl-self-type.rs
src/test/compile-fail/unsized-trait-impl-trait-arg.rs
src/test/compile-fail/unsized3.rs
src/test/compile-fail/unsized5.rs
src/test/compile-fail/unsized6.rs
src/test/compile-fail/unsized7.rs
src/test/mir-opt/end_region_7.rs
src/test/mir-opt/end_region_8.rs
src/test/mir-opt/lower_128bit_test.rs
src/test/pretty/cast-lt.pp
src/test/pretty/cast-lt.rs
src/test/pretty/issue-4264.pp
src/test/run-fail/issue-51345.rs [new file with mode: 0644]
src/test/run-make-fulldeps/cross-lang-lto/Makefile
src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile
src/test/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs
src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
src/test/run-make-fulldeps/issue-51671/app.rs
src/test/run-make-fulldeps/llvm-pass/llvm-function-pass.so.cc
src/test/run-make-fulldeps/llvm-pass/llvm-module-pass.so.cc
src/test/run-make-fulldeps/pgo-gen-lto/Makefile
src/test/run-make-fulldeps/pgo-gen/Makefile
src/test/run-make-fulldeps/target-without-atomic-cas/Makefile [new file with mode: 0644]
src/test/run-make-fulldeps/target-without-atomics/Makefile [deleted file]
src/test/run-pass-fulldeps/proc-macro/auxiliary/custom-attr-only-one-derive.rs [new file with mode: 0644]
src/test/run-pass-fulldeps/proc-macro/custom-attr-only-one-derive.rs [new file with mode: 0644]
src/test/run-pass/borrowck/borrowck-slice-pattern-element-loan.rs [new file with mode: 0644]
src/test/run-pass/default-alloc-error-hook.rs [new file with mode: 0644]
src/test/run-pass/hygiene/arguments.rs [deleted file]
src/test/run-pass/issue-40883.rs
src/test/run-pass/issue-51345.rs [new file with mode: 0644]
src/test/run-pass/issue-51907.rs [new file with mode: 0644]
src/test/run-pass/simd-intrinsic-float-math.rs
src/test/run-pass/simd-intrinsic-generic-reduction.rs
src/test/run-pass/stack-probes-lto.rs
src/test/run-pass/stack-probes.rs
src/test/run-pass/thin-lto-global-allocator.rs
src/test/run-pass/thinlto/all-crates.rs
src/test/run-pass/thinlto/dylib-works.rs
src/test/run-pass/thinlto/msvc-imp-present.rs
src/test/run-pass/thinlto/thin-lto-inlines.rs
src/test/run-pass/thinlto/thin-lto-inlines2.rs
src/test/run-pass/thinlto/weak-works.rs
src/test/run-pass/tool_lints.rs [new file with mode: 0644]
src/test/run-pass/tool_lints_2018_preview.rs [new file with mode: 0644]
src/test/run-pass/weak-new-uninhabited-issue-48493.rs [new file with mode: 0644]
src/test/run-pass/weird-exprs.rs
src/test/rustdoc-ui/unused.rs [new file with mode: 0644]
src/test/rustdoc/constructor-imports.rs [new file with mode: 0644]
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/rustdoc/short-dockblock.rs [new file with mode: 0644]
src/test/ui-fulldeps/proc-macro/auxiliary/generate-mod.rs [new file with mode: 0644]
src/test/ui-fulldeps/proc-macro/generate-mod.rs [new file with mode: 0644]
src/test/ui-fulldeps/proc-macro/generate-mod.stderr [new file with mode: 0644]
src/test/ui-fulldeps/proc-macro/invalid-attributes.rs [new file with mode: 0644]
src/test/ui-fulldeps/proc-macro/invalid-attributes.stderr [new file with mode: 0644]
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/borrowck/borrowck-slice-pattern-element-loan.rs [new file with mode: 0644]
src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr [new file with mode: 0644]
src/test/ui/borrowck/issue-45983.nll.stderr
src/test/ui/borrowck/issue-7573.nll.stderr
src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr
src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr
src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr
src/test/ui/chalkify/lower_env1.stderr
src/test/ui/chalkify/lower_trait.stderr
src/test/ui/chalkify/lower_trait_higher_rank.stderr
src/test/ui/chalkify/lower_trait_where_clause.stderr
src/test/ui/closure-array-break-length.rs
src/test/ui/closure-array-break-length.stderr
src/test/ui/closure-expected-type/expect-region-supply-region.nll.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/const-eval/infinite_loop.rs [new file with mode: 0644]
src/test/ui/const-eval/infinite_loop.stderr [new file with mode: 0644]
src/test/ui/const-unsized.rs
src/test/ui/const-unsized.stderr
src/test/ui/did_you_mean/issue-35937.nll.stderr
src/test/ui/error-codes/E0017.nll.stderr
src/test/ui/error-codes/E0133.stderr
src/test/ui/error-codes/E0277.rs
src/test/ui/error-codes/E0277.stderr
src/test/ui/error-codes/E0388.nll.stderr
src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr
src/test/ui/feature-gate-tool_lints.rs [new file with mode: 0644]
src/test/ui/feature-gate-tool_lints.stderr [new file with mode: 0644]
src/test/ui/feature-gate-trivial_bounds.stderr
src/test/ui/feature-gate-wasm_import_module.stderr
src/test/ui/generator/sized-yield.rs
src/test/ui/generator/sized-yield.stderr
src/test/ui/hygiene/arguments.rs [new file with mode: 0644]
src/test/ui/hygiene/arguments.stderr [new file with mode: 0644]
src/test/ui/hygiene/generate-mod.rs
src/test/ui/hygiene/generate-mod.stderr
src/test/ui/hygiene/globs.rs
src/test/ui/hygiene/globs.stderr
src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr
src/test/ui/include-macros/file.txt [new file with mode: 0644]
src/test/ui/include-macros/mismatched-types.rs [new file with mode: 0644]
src/test/ui/include-macros/mismatched-types.stderr [new file with mode: 0644]
src/test/ui/issue-27060.rs [new file with mode: 0644]
src/test/ui/issue-27060.stderr [new file with mode: 0644]
src/test/ui/issue-28776.stderr
src/test/ui/issue-46186.stderr
src/test/ui/issue-47184.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/macros/bad_hello.stderr
src/test/ui/mismatched_types/cast-rfc0401.rs
src/test/ui/mismatched_types/cast-rfc0401.stderr
src/test/ui/missing-alloc_error_handler.rs [new file with mode: 0644]
src/test/ui/missing-alloc_error_handler.stderr [new file with mode: 0644]
src/test/ui/missing-allocator.rs
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/closure-requirements/escape-argument-callee.rs
src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs
src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs
src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs
src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs
src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs
src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs
src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs
src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr
src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs
src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
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/nll/get_default.stderr
src/test/ui/nll/issue-48238.rs
src/test/ui/nll/issue-48238.stderr
src/test/ui/nll/issue-50716.rs
src/test/ui/nll/issue-50716.stderr
src/test/ui/nll/ty-outlives/projection-one-region-closure.rs
src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs
src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs
src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
src/test/ui/resolve/issue-5035-2.rs
src/test/ui/resolve/issue-5035-2.stderr
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/rfc-2093-infer-outlives/cross-crate.rs [new file with mode: 0644]
src/test/ui/rfc-2093-infer-outlives/cross-crate.stderr [new file with mode: 0644]
src/test/ui/rust-2018/issue-52202-use-suggestions.rs [new file with mode: 0644]
src/test/ui/rust-2018/issue-52202-use-suggestions.stderr [new file with mode: 0644]
src/test/ui/span/dropck_arr_cycle_checked.nll.stderr
src/test/ui/span/dropck_direct_cycle_with_drop.nll.stderr
src/test/ui/span/dropck_vec_cycle_checked.nll.stderr
src/test/ui/span/vec-must-not-hide-type-from-dropck.nll.stderr
src/test/ui/suggestions/issue-51515.rs [new file with mode: 0644]
src/test/ui/suggestions/issue-51515.stderr [new file with mode: 0644]
src/test/ui/suggestions/issue-52049.nll.stderr [new file with mode: 0644]
src/test/ui/suggestions/issue-52049.rs [new file with mode: 0644]
src/test/ui/suggestions/issue-52049.stderr [new file with mode: 0644]
src/test/ui/suggestions/str-array-assignment.rs
src/test/ui/suggestions/str-array-assignment.stderr
src/test/ui/tool_lints.rs [new file with mode: 0644]
src/test/ui/tool_lints.stderr [new file with mode: 0644]
src/test/ui/trait-safety-fn-body.stderr
src/test/ui/trait-suggest-where-clause.rs
src/test/ui/trait-suggest-where-clause.stderr
src/test/ui/trivial-bounds-leak.stderr
src/test/ui/type-check-defaults.stderr
src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr
src/test/ui/union/union-sized-field.rs
src/test/ui/union/union-sized-field.stderr
src/test/ui/unsafe-const-fn.stderr
src/test/ui/unsized-enum2.rs
src/test/ui/unsized-enum2.stderr
src/tools/build-manifest/src/main.rs
src/tools/cargo
src/tools/clippy
src/tools/compiletest/Cargo.toml
src/tools/compiletest/src/runtest.rs
src/tools/lld
src/tools/rls
src/tools/rustdoc-js/tester.js
src/tools/rustfmt
src/tools/tidy/src/deps.rs

index ba8a39f355c4ba0544643f7dd9900471bd98f81e..2cf10d76098011b87ecfc17d49f45339195bd91f 100644 (file)
@@ -12,7 +12,7 @@ matrix:
   fast_finish: true
   include:
     # Images used in testing PR and try-build should be run first.
-    - env: IMAGE=x86_64-gnu-llvm-3.9 RUST_BACKTRACE=1
+    - env: IMAGE=x86_64-gnu-llvm-5.0 RUST_BACKTRACE=1
       if: type = pull_request OR branch = auto
 
     - env: IMAGE=dist-x86_64-linux DEPLOY=1
index da6788824b034a11b22fc5b2278701a75ba40ab9..a2acfe8b478e28579028b5097644cbb8e759ca8a 100644 (file)
--- a/README.md
+++ b/README.md
@@ -225,13 +225,16 @@ variety of channels on Mozilla's IRC network, irc.mozilla.org. The
 most popular channel is [#rust], a venue for general discussion about
 Rust. And a good place to ask for help would be [#rust-beginners].
 
-Also, the [rustc guide] might be a good place to start if you want to
-find out how various parts of the compiler work.
+The [rustc guide] might be a good place to start if you want to find out how
+various parts of the compiler work.
+
+Also, you may find the [rustdocs for the compiler itself][rustdocs] useful.
 
 [IRC]: https://en.wikipedia.org/wiki/Internet_Relay_Chat
 [#rust]: irc://irc.mozilla.org/rust
 [#rust-beginners]: irc://irc.mozilla.org/rust-beginners
 [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/about-this-guide.html
+[rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/
 
 ## License
 [license]: #license
index 9d922f493d08ba7d2017956ea9ccd0f120b906a6..cf80c166759bfbef1f66cfd4e77ce7df5b818947 100644 (file)
@@ -1,3 +1,146 @@
+Version 1.28.0 (2018-08-02)
+===========================
+
+Language
+--------
+- [The `#[repr(transparent)]` attribute is now stable.][51562] This attribute
+  allows a Rust newtype wrapper (`struct NewType<T>(T);`) to be represented as
+  the inner type across Foreign Function Interface (FFI) boundaries.
+- [The keywords `pure`, `sizeof`, `alignof`, and `offsetof` have been unreserved
+  and can now be used as identifiers.][51196]
+- [The `GlobalAlloc` trait and `#[global_allocator]` attribute are now
+  stable.][51241] This will allow users to specify a global allocator for
+  their program.
+- [Unit test functions marked with the `#[test]` attribute can now return
+  `Result<(), E: Debug>` in addition to `()`.][51298]
+- [The `lifetime` specifier for `macro_rules!` is now stable.][50385] This
+  allows macros to easily target lifetimes.
+
+Compiler
+--------
+- [The `s` and `z` optimisation levels are now stable.][50265] These optimisations
+  prioritise making smaller binary sizes. `z` is the same as `s` with the
+  exception that it does not vectorise loops, which typically results in an even
+  smaller binary.
+- [The short error format is now stable.][49546] Specified with
+  `--error-format=short` this option will provide a more compressed output of
+  rust error messages.
+- [Added a lint warning when you have duplicated `macro_export`s.][50143]
+- [Reduced the number of allocations in the macro parser.][50855] This can
+  improve compile times of macro heavy crates on average by 5%.
+
+Libraries
+---------
+- [Implemented `Default` for `&mut str`.][51306]
+- [Implemented `From<bool>` for all integer and unsigned number types.][50554]
+- [Implemented `Extend` for `()`.][50234]
+- [The `Debug` implementation of `time::Duration` should now be more easily
+  human readable.][50364] Previously a `Duration` of one second would printed as
+  `Duration { secs: 1, nanos: 0 }` and will now be printed as `1s`.
+- [Implemented `From<&String>` for `Cow<str>`, `From<&Vec<T>>` for `Cow<[T]>`,
+  `From<Cow<CStr>>` for `CString`, `From<CString>, From<CStr>, From<&CString>`
+  for `Cow<CStr>`, `From<OsString>, From<OsStr>, From<&OsString>` for
+  `Cow<OsStr>`, `From<&PathBuf>` for `Cow<Path>`, and `From<Cow<Path>>`
+  for `PathBuf`.][50170]
+- [Implemented `Shl` and `Shr` for `Wrapping<u128>`
+  and `Wrapping<i128>`.][50465]
+- [`DirEntry::metadata` now uses `fstatat` instead of `lstat` when
+  possible.][51050] This can provide up to a 40% speed increase.
+- [Improved error messages when using `format!`.][50610]
+
+Stabilized APIs
+---------------
+- [`Iterator::step_by`]
+- [`Path::ancestors`]
+- [`btree_map::Entry::or_default`]
+- [`fmt::Alignment`]
+- [`hash_map::Entry::or_default`]
+- [`iter::repeat_with`]
+- [`num::NonZeroUsize`]
+- [`num::NonZeroU128`]
+- [`num::NonZeroU16`]
+- [`num::NonZeroU32`]
+- [`num::NonZeroU64`]
+- [`num::NonZeroU8`]
+- [`ops::RangeBounds`]
+- [`slice::SliceIndex`]
+- [`slice::from_mut`]
+- [`slice::from_ref`]
+- [`{Any + Send + Sync}::downcast_mut`]
+- [`{Any + Send + Sync}::downcast_ref`]
+- [`{Any + Send + Sync}::is`]
+
+Cargo
+-----
+- [Cargo will now no longer allow you to publish crates with build scripts that
+  modify the `src` directory.][cargo/5584] The `src` directory in a crate should be
+  considered to be immutable.
+
+Misc
+----
+- [The `suggestion_applicability` field in `rustc`'s json output is now
+  stable.][50486] This will allow dev tools to check whether a code suggestion
+  would apply to them.
+
+Compatibility Notes
+-------------------
+- [Rust will no longer consider trait objects with duplicated constraints to
+  have implementations.][51276] For example the below code will now fail
+  to compile.
+  ```rust
+  trait Trait {}
+
+  impl Trait + Send {
+      fn test(&self) { println!("one"); } //~ ERROR duplicate definitions with name `test`
+  }
+
+  impl Trait + Send + Send {
+      fn test(&self) { println!("two"); }
+  }
+  ```
+
+[49546]: https://github.com/rust-lang/rust/pull/49546/
+[50143]: https://github.com/rust-lang/rust/pull/50143/
+[50170]: https://github.com/rust-lang/rust/pull/50170/
+[50234]: https://github.com/rust-lang/rust/pull/50234/
+[50265]: https://github.com/rust-lang/rust/pull/50265/
+[50364]: https://github.com/rust-lang/rust/pull/50364/
+[50385]: https://github.com/rust-lang/rust/pull/50385/
+[50465]: https://github.com/rust-lang/rust/pull/50465/
+[50486]: https://github.com/rust-lang/rust/pull/50486/
+[50554]: https://github.com/rust-lang/rust/pull/50554/
+[50610]: https://github.com/rust-lang/rust/pull/50610/
+[50855]: https://github.com/rust-lang/rust/pull/50855/
+[51050]: https://github.com/rust-lang/rust/pull/51050/
+[51196]: https://github.com/rust-lang/rust/pull/51196/
+[51200]: https://github.com/rust-lang/rust/pull/51200/
+[51241]: https://github.com/rust-lang/rust/pull/51241/
+[51276]: https://github.com/rust-lang/rust/pull/51276/
+[51298]: https://github.com/rust-lang/rust/pull/51298/
+[51306]: https://github.com/rust-lang/rust/pull/51306/
+[51562]: https://github.com/rust-lang/rust/pull/51562/
+[cargo/5584]: https://github.com/rust-lang/cargo/pull/5584/
+[`Iterator::step_by`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.step_by
+[`Path::ancestors`]: https://doc.rust-lang.org/std/path/struct.Path.html#method.ancestors
+[`btree_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default
+[`fmt::Alignment`]: https://doc.rust-lang.org/std/fmt/enum.Alignment.html
+[`hash_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default
+[`iter::repeat_with`]: https://doc.rust-lang.org/std/iter/fn.repeat_with.html
+[`num::NonZeroUsize`]: https://doc.rust-lang.org/std/num/struct.NonZeroUsize.html
+[`num::NonZeroU128`]: https://doc.rust-lang.org/std/num/struct.NonZeroU128.html
+[`num::NonZeroU16`]: https://doc.rust-lang.org/std/num/struct.NonZeroU16.html
+[`num::NonZeroU32`]: https://doc.rust-lang.org/std/num/struct.NonZeroU32.html
+[`num::NonZeroU64`]: https://doc.rust-lang.org/std/num/struct.NonZeroU64.html
+[`num::NonZeroU8`]: https://doc.rust-lang.org/std/num/struct.NonZeroU8.html
+[`ops::RangeBounds`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html
+[`slice::SliceIndex`]: https://doc.rust-lang.org/std/slice/trait.SliceIndex.html
+[`slice::from_mut`]: https://doc.rust-lang.org/std/slice/fn.from_mut.html
+[`slice::from_ref`]: https://doc.rust-lang.org/std/slice/fn.from_ref.html
+[`{Any + Send + Sync}::downcast_mut`]: https://doc.rust-lang.org/std/any/trait.Any.html#method.downcast_mut-2
+[`{Any + Send + Sync}::downcast_ref`]: https://doc.rust-lang.org/std/any/trait.Any.html#method.downcast_ref-2
+[`{Any + Send + Sync}::is`]: https://doc.rust-lang.org/std/any/trait.Any.html#method.is-2
+
+
 Version 1.27.0 (2018-06-21)
 ==========================
 
@@ -188,7 +331,7 @@ Language
 - [Closures now implement `Copy` and/or `Clone` if all captured variables
   implement either or both traits.][49299]
 - [The inclusive range syntax e.g. `for x in 0..=10` is now stable.][47813]
-- [Stablise `'_`. The underscore lifetime can be used anywhere where a
+- [The `'_` lifetime is now stable. The underscore lifetime can be used anywhere where a
   lifetime can be elided.][49458]
 - [`impl Trait` is now stable allowing you to have abstract types in returns
    or in function parameters.][49255] e.g. `fn foo() -> impl Iterator<Item=u8>` or
@@ -389,7 +532,7 @@ Version 1.25.0 (2018-03-29)
 
 Language
 --------
-- [Stabilised `#[repr(align(x))]`.][47006] [RFC 1358]
+- [The `#[repr(align(x))]` attribute is now stable.][47006] [RFC 1358]
 - [You can now use nested groups of imports.][47948]
   e.g. `use std::{fs::File, io::Read, path::{Path, PathBuf}};`
 - [You can now have `|` at the start of a match arm.][47947] e.g.
index 0578f929224d99a0cbbaf97e64a2f29477dc7b60..99073416334f59ef7b02fcae69c7ac276c3084d3 100644 (file)
 # Print backtrace on internal compiler errors during bootstrap
 #backtrace-on-ice = false
 
+# Whether to verify generated LLVM IR
+#verify-llvm-ir = false
+
 # =============================================================================
 # Options for specific targets
 #
index 7b5b86d39fc525059127f56938116b5c98711622..539ab04af1a597af90fa72ca50db0ade79c71a80 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,14 +54,9 @@ 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]]
-name = "ar"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "arena"
 version = "0.0.0"
@@ -79,7 +74,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 +82,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 +132,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 +140,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)",
- "filetime 0.1.15 (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.2.1 (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 +169,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 +180,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 +249,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,26 +276,26 @@ 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)",
 ]
 
@@ -310,73 +304,52 @@ name = "clippy"
 version = "0.0.211"
 dependencies = [
  "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "backtrace 0.3.6 (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.211",
- "compiletest_rs 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "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)",
- "num-traits 0.2.2 (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)",
- "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)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "clippy-mini-macro-test"
 version = "0.2.0"
 
-[[package]]
-name = "clippy_lints"
-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)",
- "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.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)",
- "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)",
- "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "clippy_lints"
 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]]
@@ -400,14 +373,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",
 ]
 
@@ -416,37 +389,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)",
- "filetime 0.1.15 (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.2.1 (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]]
@@ -466,7 +439,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]]
@@ -480,9 +453,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)",
 ]
 
@@ -506,9 +479,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)",
@@ -519,7 +492,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]]
@@ -528,9 +501,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]]
@@ -540,11 +513,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)",
 ]
 
@@ -553,13 +526,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]]
@@ -567,14 +540,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"
@@ -584,9 +549,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]]
@@ -619,16 +584,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]]
@@ -636,14 +601,9 @@ 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]]
-name = "endian-type"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "enum_primitive"
 version = "0.1.1"
@@ -654,13 +614,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)",
 ]
 
@@ -674,7 +634,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]]
@@ -689,7 +649,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,22 +669,12 @@ version = "0.1.0"
 
 [[package]]
 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)",
-]
-
-[[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]]
@@ -745,7 +695,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)",
 ]
 
@@ -776,8 +726,17 @@ 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]]
+name = "fst"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -785,7 +744,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)",
 ]
 
@@ -796,16 +755,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]]
@@ -815,15 +774,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)",
 ]
 
@@ -833,8 +792,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)",
 ]
 
@@ -845,14 +804,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]]
@@ -861,22 +820,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]]
@@ -886,19 +845,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]]
@@ -906,7 +866,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]]
@@ -916,7 +876,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]]
@@ -926,19 +886,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]]
@@ -957,15 +917,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]]
@@ -978,9 +938,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]]
@@ -1001,8 +961,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)",
 ]
 
@@ -1016,11 +976,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,14 +994,14 @@ dependencies = [
 
 [[package]]
 name = "languageserver-types"
-version = "0.41.0"
+version = "0.43.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)",
 ]
@@ -1053,7 +1013,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]]
@@ -1071,34 +1031,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]]
@@ -1106,10 +1067,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]]
@@ -1121,34 +1082,34 @@ 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]]
 name = "lzma-sys"
-version = "0.1.9"
+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)",
- "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)",
+ "cc 1.0.17 (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)",
+ "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1166,13 +1127,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)",
 ]
 
@@ -1187,22 +1148,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)",
@@ -1214,7 +1175,16 @@ 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]]
+name = "memmap"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "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]]
@@ -1227,7 +1197,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]]
@@ -1235,8 +1205,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]]
@@ -1244,21 +1214,21 @@ 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]]
@@ -1266,9 +1236,12 @@ name = "multiple_bins"
 version = "0.1.0"
 
 [[package]]
-name = "nibble_vec"
-version = "0.0.4"
+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 = "nodrop"
@@ -1277,10 +1250,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]]
@@ -1288,12 +1261,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]]
@@ -1301,7 +1274,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]]
@@ -1311,14 +1284,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]]
@@ -1328,13 +1302,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]]
@@ -1342,12 +1316,17 @@ name = "ordermap"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "ordslice"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 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]]
@@ -1384,10 +1363,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]]
@@ -1421,33 +1400,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)",
@@ -1455,7 +1434,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]]
@@ -1464,7 +1443,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)",
 ]
 
@@ -1484,7 +1463,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)",
@@ -1504,7 +1491,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",
 ]
@@ -1520,7 +1507,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]]
@@ -1535,10 +1522,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]]
@@ -1546,43 +1541,24 @@ 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)",
 ]
 
-[[package]]
-name = "radix_trie"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "endian-type 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "nibble_vec 0.0.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]]
@@ -1600,15 +1576,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]]
@@ -1616,7 +1592,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]]
@@ -1629,31 +1605,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)",
@@ -1661,7 +1637,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)",
@@ -1680,49 +1656,52 @@ 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]]
 name = "rls"
-version = "0.128.0"
+version = "0.129.0"
 dependencies = [
  "cargo 0.30.0",
- "cargo_metadata 0.5.4 (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)",
+ "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clippy_lints 0.0.211",
+ "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)",
+ "languageserver-types 0.43.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)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ordslice 0.3.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)",
- "rls-analysis 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rls-analysis 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-blacklist 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-data 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-rustc 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustfmt-nightly 0.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)",
+ "rustfmt-nightly 0.8.2",
+ "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)",
 ]
 
 [[package]]
 name = "rls-analysis"
-version = "0.13.0"
+version = "0.14.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)",
- "radix_trie 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fst 0.3.0 (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.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-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1740,8 +1719,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]]
@@ -1755,8 +1734,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]]
@@ -1772,7 +1751,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)",
 ]
 
@@ -1781,16 +1760,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",
@@ -1800,7 +1779,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",
@@ -1809,188 +1788,99 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-arena"
-version = "149.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "rustc-ap-rustc_data_structures 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "rustc-ap-arena"
-version = "164.0.0"
+version = "182.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-ap-rustc_data_structures 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_cratesio_shim"
-version = "149.0.0"
+version = "182.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)",
-]
-
-[[package]]
-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]]
 name = "rustc-ap-rustc_data_structures"
-version = "149.0.0"
+version = "182.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)",
-]
-
-[[package]]
-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)",
- "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)",
- "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)",
- "rustc-ap-serialize 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 182.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)",
  "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)",
-]
-
-[[package]]
-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)",
- "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)",
- "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-width 0.1.5 (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]]
 name = "rustc-ap-rustc_errors"
-version = "164.0.0"
+version = "182.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)",
- "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)",
+ "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "termcolor 0.3.6 (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-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)",
- "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)",
-]
-
-[[package]]
-name = "rustc-ap-rustc_target"
-version = "164.0.0"
+version = "182.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)",
- "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)",
+ "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 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-serialize"
-version = "149.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "rustc-ap-serialize"
-version = "164.0.0"
+version = "182.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "rustc-ap-syntax"
-version = "149.0.0"
+version = "182.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)",
- "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)",
-]
-
-[[package]]
-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)",
- "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)",
+ "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 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-syntax_pos"
-version = "149.0.0"
+version = "182.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 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)",
- "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "rustc-ap-syntax_pos"
-version = "164.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-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)",
+ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-arena 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 182.0.0 (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]]
@@ -1998,7 +1888,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]]
@@ -2024,8 +1914,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)",
 ]
@@ -2039,7 +1929,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",
@@ -2051,7 +1941,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",
 ]
 
@@ -2062,7 +1952,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",
 ]
@@ -2072,7 +1962,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",
@@ -2085,16 +1975,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",
@@ -2115,9 +2005,8 @@ dependencies = [
 name = "rustc_codegen_utils"
 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",
@@ -2131,17 +2020,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)",
@@ -2149,18 +2038,17 @@ 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]]
 name = "rustc_driver"
 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",
@@ -2180,7 +2068,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",
@@ -2191,7 +2079,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",
@@ -2204,7 +2092,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",
@@ -2217,7 +2105,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",
@@ -2229,10 +2117,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",
 ]
 
@@ -2243,7 +2131,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",
 ]
@@ -2253,7 +2141,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",
@@ -2270,12 +2158,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",
@@ -2294,7 +2182,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",
 ]
@@ -2303,7 +2191,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",
@@ -2343,7 +2231,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",
@@ -2355,7 +2243,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",
@@ -2371,8 +2259,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",
 ]
@@ -2381,10 +2269,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",
@@ -2398,7 +2286,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",
 ]
@@ -2408,7 +2296,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",
@@ -2452,61 +2340,36 @@ 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]]
 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)",
+ "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)",
- "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)",
- "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)",
+ "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 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax 182.0.0 (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)",
-]
-
-[[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)",
- "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)",
- "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)",
- "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)",
- "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]]
@@ -2514,21 +2377,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]]
@@ -2542,7 +2405,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]]
@@ -2552,27 +2415,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]]
@@ -2580,18 +2433,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]]
@@ -2615,22 +2467,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]]
@@ -2641,7 +2494,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",
@@ -2667,26 +2520,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)",
 ]
 
@@ -2707,11 +2561,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]]
@@ -2726,11 +2581,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.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.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.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)",
 ]
 
@@ -2755,12 +2620,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",
 ]
@@ -2783,9 +2648,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)",
 ]
@@ -2795,7 +2660,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)",
@@ -2817,7 +2682,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)",
@@ -2828,12 +2693,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)",
 ]
 
@@ -2842,11 +2707,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]]
@@ -2854,7 +2719,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)",
 ]
@@ -2877,8 +2742,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]]
@@ -2894,8 +2759,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)",
 ]
 
@@ -2909,7 +2774,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)",
@@ -2920,7 +2785,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)",
 ]
 
@@ -2928,19 +2793,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]]
@@ -2948,7 +2813,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]]
@@ -2958,8 +2823,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)",
 ]
 
@@ -2978,12 +2843,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]]
@@ -3006,14 +2871,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"
@@ -3026,7 +2883,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",
 ]
 
@@ -3054,7 +2911,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)",
 ]
 
@@ -3079,12 +2936,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]]
@@ -3098,7 +2955,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]]
@@ -3108,7 +2965,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)",
@@ -3135,7 +2992,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]]
@@ -3147,15 +3004,15 @@ 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)",
+ "lzma-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3164,33 +3021,31 @@ 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 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 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 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"
@@ -3201,46 +3056,44 @@ 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"
 "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
 "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
 "checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
+"checksum fst 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d94485a00b1827b861dd9d1a2cc9764f9044d4c535514c0760a5a2012ef3399f"
 "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"
@@ -3249,39 +3102,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9ad0485404155f45cce53a40d4b2d6ac356418300daed05273d9e26f91c390be"
 "checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
-"checksum languageserver-types 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "017cf5ade4be5ebeb06277ccd281c268dbd2e0801128d3992b4b4057f34dd432"
+"checksum languageserver-types 0.43.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dedb2c8010c9c7530b205fd16ed24a158c3a46634cb0fc61528b17cbbb55df1a"
 "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 lzma-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c1b93b78f89e8737dac81837fc8f5521ac162abcba902e1a3db949d55346d1da"
+"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.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d1eaa027402541975218bb0eec67d6b0412f6233af96e0d096d31dbdfd22e614"
 "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"
 "checksum markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfedc97d5a503e96816d10fedcd5b42f760b2e525ce2f7ec71f6a41780548475"
 "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
 "checksum mdbook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "90b5a8d7e341ceee5db3882a06078d42661ddcfa2b3687319cc5da76ec4e782f"
 "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
+"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
 "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 nibble_vec 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c8d77f3db4bce033f4d04db08079b2ef1c3d02b44e86f25d08886fafa7756ffa"
+"checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"
 "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 ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd20eec3dbe4376829cb7d80ae6ac45e0a766831dca50202ff2d40db46a8a024"
 "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"
 "checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa"
@@ -3289,130 +3144,120 @@ 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-analysis 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96f84d303dcbe1c1bdd41b10867d3399c38fbdac32c4e3645cdb6dbd7f82db1d"
 "checksum rls-blacklist 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e4a9cc2545ccb7e05b355bfe047b8039a6ec12270d5f3c996b766b340a50f7d2"
 "checksum rls-data 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3dd20763e1c60ae8945384c8a8fa4ac44f8afa7b0a817511f5e8927e5d24f988"
 "checksum rls-rustc 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2c8c09117ae2887baaa4b17fe1cb572f9b22e4d2c6a5cda04093d8b366b0be99"
 "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a"
 "checksum rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be231e1e559c315bc60ced5ad2cc2d7a9c208ed7d4e2c126500149836fda19bb"
-"checksum rustc-ap-arena 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e794b25832224eea9252ebfa9f94ab7070d0a60c977793112c611501cb56b48d"
-"checksum rustc-ap-arena 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f0687e373d86505f31faeaee87d2be552843a830a0a20e252e76337b9596161"
-"checksum rustc-ap-rustc_cratesio_shim 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a78241b2ecb82ebb9221b4b7d37c024ff1f2e43f1b099f38a997f030fc7894b0"
-"checksum rustc-ap-rustc_cratesio_shim 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7ab5b83e209f3bcdb3c058a996d54b67db58eed5496bd114a781d9faa021aba7"
-"checksum rustc-ap-rustc_data_structures 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5529c3927f32b0b56d1f6449a34f2218dc2160c6a6dde0cf47954d83a9a45764"
-"checksum rustc-ap-rustc_data_structures 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4bb330c149e9b133d4707718a7981d65ce4eb14f2d59cb487761aa922fefb206"
-"checksum rustc-ap-rustc_errors 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb1fef44a7d63f5d204c981adb26a14e85fe7ee5962050a4f664df6f425f9b48"
-"checksum rustc-ap-rustc_errors 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e19ae6a813d5cdd12b8b95cea71438bf8a5fa3505bea1e7d68d438a8ac5ae7b"
-"checksum rustc-ap-rustc_target 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a3939a9f7bf063536dd646894ca43b1378ec6a56ac5b2698cc6ba0b42bfadbdc"
-"checksum rustc-ap-rustc_target 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "867d4a6bc1b62d373fc6ec72632d5cbd36f3cb1f4e51282d0c7b4e771b393031"
-"checksum rustc-ap-serialize 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "692169d0bac8a4547f9778039460799e162664477a1eaec15d31507705f8c736"
-"checksum rustc-ap-serialize 164.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e095f23598f115432ffef263201e030626f454d183cf425ef68fcca984f6594b"
-"checksum rustc-ap-syntax 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "22e93ee3817b007d56b5c5b151e6cd7c7063455a1facaf9e0ca01f9d9365b716"
-"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-ap-arena 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f7bd7aabbf60986181924ddad8c5bee830cf83213ed8553f715145d050e42d0c"
+"checksum rustc-ap-rustc_cratesio_shim 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1bc122961e39834268cb45baf75995eaca376b78146efce962b27de71b3e8b7"
+"checksum rustc-ap-rustc_data_structures 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6c2ed8ee3a204499534a1ea22a8eb6c87c0c39dd139197d4a0f913b8e12a4c2"
+"checksum rustc-ap-rustc_errors 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d35753d6c9159f49c74f800b0d00707db09863a7554679e1b701c7eeeb5a611c"
+"checksum rustc-ap-rustc_target 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f1b3da32f4862d4722e6f699e92ffa8b556166752fbdbbd64cc7d9ddd8db0e8"
+"checksum rustc-ap-serialize 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "182579d9dc2e46e232de4cdd1a56ec352a55440a86e7389a6109dae73f2a392b"
+"checksum rustc-ap-syntax 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c890882969e05d73cb97695a64e32b526830c7f197a708feb376e8684d16abb2"
+"checksum rustc-ap-syntax_pos 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6c779602d2e364440d28f8cb3c1fa13dcf11a546b96c5eab2bc7554869e2aca4"
+"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"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 "checksum rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a"
 "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 8ce4c97601bab7f5bb0ac02b0db62a271186ec51..3cf48671e76def0327fe9b3a68698b9107ade294 100644 (file)
@@ -64,10 +64,12 @@ debug-assertions = false
 [patch."https://github.com/rust-lang/cargo"]
 cargo = { path = "tools/cargo" }
 
-[patch.crates-io]
+[patch."https://github.com/rust-lang-nursery/rustfmt"]
 # Similar to Cargo above we want the RLS to use a vendored version of `rustfmt`
 # that we're shipping as well (to ensure that the rustfmt in RLS and the
-# `rustfmt` executable are the same exact vesion). Unlike Cargo, however, the
-# RLS depends on `rustfmt` from crates.io, so we put this in a `[patch]` section
-# for crates.io
+# `rustfmt` executable are the same exact version).
 rustfmt-nightly = { path = "tools/rustfmt" }
+
+[patch."https://github.com/rust-lang-nursery/rust-clippy"]
+clippy = { path = "tools/clippy" }
+clippy_lints = { path = "tools/clippy/clippy_lints" }
index af33ebf3c4250f77703d5c21b3aa4e05db5224c3..57a526038041e5037fe82acb2cbc23104968d463 100644 (file)
@@ -36,7 +36,7 @@ test = false
 [dependencies]
 build_helper = { path = "../build_helper" }
 cmake = "0.1.23"
-filetime = "0.1"
+filetime = "0.2"
 num_cpus = "1.0"
 getopts = "0.2"
 cc = "1.0.1"
index 4607ca5cf9f48e72b32672d424f97c48399c2e6c..e81595a8c62489005737056920ce7330b8ba5ba4 100644 (file)
@@ -283,6 +283,10 @@ fn main() {
         cmd.arg("--cfg").arg("parallel_queries");
     }
 
+    if env::var_os("RUSTC_VERIFY_LLVM_IR").is_some() {
+        cmd.arg("-Z").arg("verify-llvm-ir");
+    }
+
     let color = match env::var("RUSTC_COLOR") {
         Ok(s) => usize::from_str(&s).expect("RUSTC_COLOR should be an integer"),
         Err(_) => 0,
index 512d4d8c5b792ce0e1958574ff59e0168996793c..71c1c61e3d97ebd51e9bd8cf5b9946cbcbe5ca5c 100644 (file)
@@ -303,6 +303,19 @@ def default_build_triple():
     return "{}-{}".format(cputype, ostype)
 
 
+@contextlib.contextmanager
+def output(filepath):
+    tmp = filepath + '.tmp'
+    with open(tmp, 'w') as f:
+        yield f
+    try:
+        os.remove(filepath)  # PermissionError/OSError on Win32 if in use
+        os.rename(tmp, filepath)
+    except OSError:
+        shutil.copy2(tmp, filepath)
+        os.remove(tmp)
+
+
 class RustBuild(object):
     """Provide all the methods required to build Rust"""
     def __init__(self):
@@ -346,7 +359,7 @@ class RustBuild(object):
             self._download_stage0_helper(filename, "rustc")
             self.fix_executable("{}/bin/rustc".format(self.bin_root()))
             self.fix_executable("{}/bin/rustdoc".format(self.bin_root()))
-            with open(self.rustc_stamp(), 'w') as rust_stamp:
+            with output(self.rustc_stamp()) as rust_stamp:
                 rust_stamp.write(self.date)
 
             # This is required so that we don't mix incompatible MinGW
@@ -363,7 +376,7 @@ class RustBuild(object):
             filename = "cargo-{}-{}.tar.gz".format(cargo_channel, self.build)
             self._download_stage0_helper(filename, "cargo")
             self.fix_executable("{}/bin/cargo".format(self.bin_root()))
-            with open(self.cargo_stamp(), 'w') as cargo_stamp:
+            with output(self.cargo_stamp()) as cargo_stamp:
                 cargo_stamp.write(self.date)
 
     def _download_stage0_helper(self, filename, pattern):
@@ -776,7 +789,7 @@ def bootstrap(help_triggered):
     if build.use_vendored_sources:
         if not os.path.exists('.cargo'):
             os.makedirs('.cargo')
-        with open('.cargo/config', 'w') as cargo_config:
+        with output('.cargo/config') as cargo_config:
             cargo_config.write("""
                 [source.crates-io]
                 replace-with = 'vendored-sources'
index fa2440e27d06aba4f8125f480e619420a33e04be..eb534cb685e87a2afef58e8d5b53e79c99c11286 100644 (file)
@@ -44,7 +44,7 @@ pub struct Builder<'a> {
     pub top_stage: u32,
     pub kind: Kind,
     cache: Cache,
-    stack: RefCell<Vec<Box<Any>>>,
+    stack: RefCell<Vec<Box<dyn Any>>>,
     time_spent_on_dependencies: Cell<Duration>,
     pub paths: Vec<PathBuf>,
     graph_nodes: RefCell<HashMap<String, NodeIndex>>,
@@ -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() {
@@ -906,6 +922,10 @@ pub fn cargo(
             cargo.env("RUSTC_BACKTRACE_ON_ICE", "1");
         }
 
+        if self.config.rust_verify_llvm_ir {
+            cargo.env("RUSTC_VERIFY_LLVM_IR", "1");
+        }
+
         cargo.env("RUSTC_VERBOSE", format!("{}", self.verbosity));
 
         // in std, we want to avoid denying warnings for stage 0 as that makes cfg's painful.
index d81c6bc28e52705f06c463ad55b0b137eb7fa2e6..bca5ff85ba23e846052ed1ed1b073f02579fe2ce 100644 (file)
@@ -249,7 +249,7 @@ pub fn intern_path(&self, s: PathBuf) -> Interned<PathBuf> {
 pub struct Cache(
     RefCell<HashMap<
         TypeId,
-        Box<Any>, // actually a HashMap<Step, Interned<Step::Output>>
+        Box<dyn Any>, // actually a HashMap<Step, Interned<Step::Output>>
     >>
 );
 
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 aef2df3e2780f40e500c68c766b92851accfebdb..7d94bac66f7706aaf2fd10c19450c086954bae61 100644 (file)
@@ -821,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
@@ -1186,7 +1189,7 @@ pub fn run_cargo(builder: &Builder, cargo: &mut Command, stamp: &Path, is_check:
 pub fn stream_cargo(
     builder: &Builder,
     cargo: &mut Command,
-    cb: &mut FnMut(CargoMessage),
+    cb: &mut dyn FnMut(CargoMessage),
 ) -> bool {
     if builder.config.dry_run {
         return true;
index b3ed10257bdacf2d3c11256b45f7959df593b646..420ae1f349c3ed3a3d0d1d841eaf76166f46d160 100644 (file)
@@ -105,6 +105,7 @@ pub struct Config {
     pub rust_dist_src: bool,
     pub rust_codegen_backends: Vec<Interned<String>>,
     pub rust_codegen_backends_dir: String,
+    pub rust_verify_llvm_ir: bool,
 
     pub build: Interned<String>,
     pub hosts: Vec<Interned<String>>,
@@ -312,6 +313,7 @@ struct Rust {
     llvm_tools: Option<bool>,
     deny_warnings: Option<bool>,
     backtrace_on_ice: Option<bool>,
+    verify_llvm_ir: Option<bool>,
 }
 
 /// TOML representation of how each build target is configured.
@@ -543,6 +545,7 @@ pub fn parse(args: &[String]) -> Config {
             config.save_toolstates = rust.save_toolstates.clone().map(PathBuf::from);
             set(&mut config.deny_warnings, rust.deny_warnings.or(flags.warnings));
             set(&mut config.backtrace_on_ice, rust.backtrace_on_ice);
+            set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir);
 
             if let Some(ref backends) = rust.codegen_backends {
                 config.rust_codegen_backends = backends.iter()
index 80fa96509bd87f2a13cd563ebfd4086fdef2a306..9fdba044f4be3da82b035e5bc110c4a477f9085d 100755 (executable)
@@ -432,7 +432,7 @@ for section_key in config:
 # order that we read it in.
 p("")
 p("writing `config.toml` in current directory")
-with open('config.toml', 'w') as f:
+with bootstrap.output('config.toml') as f:
     for section in section_order:
         if section == 'target':
             for target in targets:
@@ -442,7 +442,7 @@ with open('config.toml', 'w') as f:
             for line in sections[section]:
                 f.write(line + "\n")
 
-with open('Makefile', 'w') as f:
+with bootstrap.output('Makefile') as f:
     contents = os.path.join(rust_dir, 'src', 'bootstrap', 'mk', 'Makefile.in')
     contents = open(contents).read()
     contents = contents.replace("$(CFG_SRC_DIR)", rust_dir + '/')
index 19a2c94dca7a2a40db9a9afe2a44089aa78349b9..ca804abd26ac4ea716d795225ca587b4ff28b173 100644 (file)
@@ -308,6 +308,14 @@ fn make_win_dist(
         builder.copy_to_folder(&src, &target_bin_dir);
     }
 
+    // Warn windows-gnu users that the bundled GCC cannot compile C files
+    builder.create(
+        &target_bin_dir.join("GCC-WARNING.txt"),
+        "gcc.exe contained in this folder cannot be used for compiling C files - it is only\
+         used as a linker. In order to be able to compile projects containing C code use\
+         the GCC provided by MinGW or Cygwin."
+    );
+
     //Copy platform libs to platform-specific lib directory
     let target_lib_dir = plat_root.join("lib").join("rustlib").join(target_triple).join("lib");
     fs::create_dir_all(&target_lib_dir).expect("creating target_lib_dir failed");
@@ -493,12 +501,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")
@@ -957,7 +966,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"
                 );
@@ -1220,7 +1229,7 @@ fn run(self, builder: &Builder) -> Option<PathBuf> {
         let tmp = tmpdir(builder);
         let image = tmp.join("clippy-image");
         drop(fs::remove_dir_all(&image));
-        t!(fs::create_dir_all(&image));
+        builder.create_dir(&image);
 
         // Prepare the image directory
         // We expect clippy to build, because we've exited this step above if tool
@@ -1229,8 +1238,13 @@ fn run(self, builder: &Builder) -> Option<PathBuf> {
             compiler: builder.compiler(stage, builder.config.build),
             target, extra_features: Vec::new()
         }).or_else(|| { println!("Unable to build clippy, skipping dist"); None })?;
+        let cargoclippy = builder.ensure(tool::CargoClippy {
+            compiler: builder.compiler(stage, builder.config.build),
+            target, extra_features: Vec::new()
+        }).or_else(|| { println!("Unable to build cargo clippy, skipping dist"); None })?;
 
         builder.install(&clippy, &image.join("bin"), 0o755);
+        builder.install(&cargoclippy, &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);
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 414f17dfad40059db52db5e79f5b95c3172a9764..cd9a639e82e2f9c85580e40152ab5b9ce59dbdc2 100644 (file)
 //! More documentation can be found in each respective module below, and you can
 //! also check out the `src/bootstrap/README.md` file for more information.
 
+#![deny(bare_trait_objects)]
 #![deny(warnings)]
 #![feature(core_intrinsics)]
+#![feature(drain_filter)]
 
 #[macro_use]
 extern crate build_helper;
 #[cfg(windows)]
 mod job;
 
-#[cfg(unix)]
+#[cfg(all(unix, not(target_os = "haiku")))]
 mod job {
     use libc;
 
@@ -188,7 +190,7 @@ pub unsafe fn setup(build: &mut ::Build) {
     }
 }
 
-#[cfg(not(any(unix, windows)))]
+#[cfg(any(target_os = "haiku", not(any(unix, windows))))]
 mod job {
     pub unsafe fn setup(_build: &mut ::Build) {
     }
@@ -328,16 +330,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
         }
     }
@@ -547,7 +556,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))
@@ -656,8 +667,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.
@@ -1160,13 +1175,13 @@ pub fn cp_r(&self, src: &Path, dst: &Path) {
     /// Copies the `src` directory recursively to `dst`. Both are assumed to exist
     /// when this function is called. Unwanted files or directories can be skipped
     /// by returning `false` from the filter function.
-    pub fn cp_filtered(&self, src: &Path, dst: &Path, filter: &Fn(&Path) -> bool) {
+    pub fn cp_filtered(&self, src: &Path, dst: &Path, filter: &dyn Fn(&Path) -> bool) {
         // Immediately recurse with an empty relative path
         self.recurse_(src, dst, Path::new(""), filter)
     }
 
     // Inner function does the actual work
-    fn recurse_(&self, src: &Path, dst: &Path, relative: &Path, filter: &Fn(&Path) -> bool) {
+    fn recurse_(&self, src: &Path, dst: &Path, relative: &Path, filter: &dyn Fn(&Path) -> bool) {
         for f in self.read_dir(src) {
             let path = f.path();
             let name = path.file_name().unwrap();
index 7dcdbe9c931cf23984fa9816759f51ddac79b098..264acfacee6b0f45eaa87a8969f5f93fb6d0c86c 100644 (file)
@@ -256,12 +256,12 @@ fn check_llvm_version(builder: &Builder, llvm_config: &Path) {
     let version = output(cmd.arg("--version"));
     let mut parts = version.split('.').take(2)
         .filter_map(|s| s.parse::<u32>().ok());
-    if let (Some(major), Some(minor)) = (parts.next(), parts.next()) {
-        if major > 3 || (major == 3 && minor >= 9) {
+    if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) {
+        if major >= 5 {
             return
         }
     }
-    panic!("\n\nbad LLVM version: {}, need >=3.9\n\n", version)
+    panic!("\n\nbad LLVM version: {}, need >=5.0\n\n", version)
 }
 
 fn configure_cmake(builder: &Builder,
@@ -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 3adfbb5e36b51d2088ba4f6aa7f18b11b21fc7b7..6254f98165665630550f7c68dbf88be360cb6dab 100644 (file)
@@ -1806,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 23b3f5a0826ecab3837d33527d637d2c8cbd3f47..42c65b750d33c42469a3c9438f5fecf18a0ecb67 100644 (file)
@@ -13,6 +13,7 @@
 use std::iter;
 use std::path::PathBuf;
 use std::process::{Command, exit};
+use std::collections::HashSet;
 
 use Mode;
 use Compiler;
@@ -104,9 +105,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,8 +123,13 @@ 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" && tool != "clippy-driver" {
-                return
+            match tool {
+                | "rls"
+                | "cargo"
+                | "clippy-driver"
+                => {}
+
+                _ => return,
             }
             let (id, features, filenames) = match msg {
                 compile::CargoMessage::CompilerArtifact {
@@ -178,12 +188,22 @@ fn run(self, builder: &Builder) -> Option<PathBuf> {
                       typically means that something was recompiled because \
                       a transitive dependency has different features activated \
                       than in a previous build:\n");
+            println!("the following dependencies are duplicated although they \
+                      have the same features enabled:");
+            for (id, cur, prev) in duplicates.drain_filter(|(_, cur, prev)| cur.2 == prev.2) {
+                println!("  {}", id);
+                // same features
+                println!("    `{}` ({:?})\n    `{}` ({:?})", cur.0, cur.1, prev.0, prev.1);
+            }
+            println!("the following dependencies have different features:");
             for (id, cur, prev) in duplicates {
                 println!("  {}", id);
-                println!("    `{}` enabled features {:?} at {:?}",
-                         cur.0, cur.2, cur.1);
-                println!("    `{}` enabled features {:?} at {:?}",
-                         prev.0, prev.2, prev.1);
+                let cur_features: HashSet<_> = cur.2.into_iter().collect();
+                let prev_features: HashSet<_> = prev.2.into_iter().collect();
+                println!("    `{}` additionally enabled features {:?} at {:?}",
+                         cur.0, &cur_features - &prev_features, cur.1);
+                println!("    `{}` additionally enabled features {:?} at {:?}",
+                         prev.0, &prev_features - &cur_features, prev.1);
             }
             println!("");
             panic!("tools should not compile multiple copies of the same crate");
@@ -341,17 +361,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)]
@@ -564,6 +584,14 @@ fn run(mut $sel, $builder: &Builder) -> Option<PathBuf> {
 
 tool_extended!((self, builder),
     Cargofmt, rustfmt, "src/tools/rustfmt", "cargo-fmt", {};
+    CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", {
+        // Clippy depends on procedural macros (serde), which requires a full host
+        // compiler to be available, so we need to depend on that.
+        builder.ensure(compile::Rustc {
+            compiler: self.compiler,
+            target: builder.config.build,
+        });
+    };
     Clippy, clippy, "src/tools/clippy", "clippy-driver", {
         // Clippy depends on procedural macros (serde), which requires a full host
         // compiler to be available, so we need to depend on that.
@@ -574,6 +602,14 @@ fn run(mut $sel, $builder: &Builder) -> Option<PathBuf> {
     };
     Miri, miri, "src/tools/miri", "miri", {};
     Rls, rls, "src/tools/rls", "rls", {
+        let clippy = builder.ensure(Clippy {
+            compiler: self.compiler,
+            target: self.target,
+            extra_features: Vec::new(),
+        });
+        if clippy.is_some() {
+            self.extra_features.push("clippy".to_owned());
+        }
         builder.ensure(native::Openssl {
             target: self.target,
         });
@@ -604,7 +640,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 f87ba8fe4e60e150613178a8157b170f33fc398c..4ca7389d6d1a53102eca067a43697f88250dbcd9 100644 (file)
@@ -32,11 +32,17 @@ shift
 
 export CFLAGS="-fPIC $CFLAGS"
 
-MUSL=musl-1.1.18
+# FIXME: remove the patch when upate to 1.1.20
+MUSL=musl-1.1.19
 
 # may have been downloaded in a previous run
 if [ ! -d $MUSL ]; then
   curl https://www.musl-libc.org/releases/$MUSL.tar.gz | tar xzf -
+  # Patch to fix https://github.com/rust-lang/rust/issues/48967
+  cd $MUSL && \
+    curl "https://git.musl-libc.org/cgit/musl/patch/?id=610c5a8524c3d6cd3ac5a5f1231422e7648a3791" |\
+    patch -p1 && \
+    cd -
 fi
 
 cd $MUSL
diff --git a/src/ci/docker/x86_64-gnu-llvm-3.9/Dockerfile b/src/ci/docker/x86_64-gnu-llvm-3.9/Dockerfile
deleted file mode 100644 (file)
index 6b81860..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-FROM ubuntu:16.04
-
-RUN apt-get update && apt-get install -y --no-install-recommends \
-  g++ \
-  make \
-  file \
-  curl \
-  ca-certificates \
-  python2.7 \
-  git \
-  cmake \
-  sudo \
-  gdb \
-  llvm-3.9-tools \
-  libedit-dev \
-  zlib1g-dev \
-  xz-utils
-
-COPY scripts/sccache.sh /scripts/
-RUN sh /scripts/sccache.sh
-
-# using llvm-link-shared due to libffi issues -- see #34486
-ENV RUST_CONFIGURE_ARGS \
-      --build=x86_64-unknown-linux-gnu \
-      --llvm-root=/usr/lib/llvm-3.9 \
-      --enable-llvm-link-shared
-ENV RUST_CHECK_TARGET check
diff --git a/src/ci/docker/x86_64-gnu-llvm-5.0/Dockerfile b/src/ci/docker/x86_64-gnu-llvm-5.0/Dockerfile
new file mode 100644 (file)
index 0000000..4f90c50
--- /dev/null
@@ -0,0 +1,27 @@
+FROM ubuntu:16.04
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+  g++ \
+  make \
+  file \
+  curl \
+  ca-certificates \
+  python2.7 \
+  git \
+  cmake \
+  sudo \
+  gdb \
+  llvm-5.0-tools \
+  libedit-dev \
+  zlib1g-dev \
+  xz-utils
+
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+# using llvm-link-shared due to libffi issues -- see #34486
+ENV RUST_CONFIGURE_ARGS \
+      --build=x86_64-unknown-linux-gnu \
+      --llvm-root=/usr/lib/llvm-5.0 \
+      --enable-llvm-link-shared
+ENV RUST_CHECK_TARGET check
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
 
diff --git a/src/doc/unstable-book/src/language-features/tool-lints.md b/src/doc/unstable-book/src/language-features/tool-lints.md
new file mode 100644 (file)
index 0000000..5c0d33b
--- /dev/null
@@ -0,0 +1,35 @@
+# `tool_lints`
+
+The tracking issue for this feature is: [#44690]
+
+[#44690]: https://github.com/rust-lang/rust/issues/44690
+
+------------------------
+
+Tool lints let you use scoped lints, to `allow`, `warn`, `deny` or `forbid` lints of
+certain tools.
+
+Currently `clippy` is the only available lint tool.
+
+It is recommended for lint tools to implement the scoped lints like this:
+
+- `#[_(TOOL_NAME::lintname)]`: for lint names
+- `#[_(TOOL_NAME::lintgroup)]`: for groups of lints
+- `#[_(TOOL_NAME::all)]`: for (almost[^1]) all lints
+
+## An example
+
+```rust
+#![feature(tool_lints)]
+
+#![warn(clippy::pedantic)]
+
+#[allow(clippy::filter_map)]
+fn main() {
+    let v = vec![0; 10];
+    let _ = v.into_iter().filter(|&x| x < 1).map(|x| x + 1).collect::<Vec<_>>();
+    println!("No filter_map()!");
+}
+```
+
+[^1]: Some defined lint groups can be excluded here.
index fb16bdf0ab43ae4d4872b87f4c44d5bb6aabb081..44f15981137ba2ac5a1ed3f61be13f6ea1d41fd1 100644 (file)
@@ -446,7 +446,7 @@ fn from(s: Box<str>) -> Self {
     }
 }
 
-impl Box<Any> {
+impl Box<dyn Any> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     /// Attempt to downcast the box to a concrete type.
@@ -468,10 +468,10 @@ impl Box<Any> {
     ///     print_if_string(Box::new(0i8));
     /// }
     /// ```
-    pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
+    pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<dyn Any>> {
         if self.is::<T>() {
             unsafe {
-                let raw: *mut Any = Box::into_raw(self);
+                let raw: *mut dyn Any = Box::into_raw(self);
                 Ok(Box::from_raw(raw as *mut T))
             }
         } else {
@@ -480,7 +480,7 @@ pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
     }
 }
 
-impl Box<Any + Send> {
+impl Box<dyn Any + Send> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     /// Attempt to downcast the box to a concrete type.
@@ -502,10 +502,10 @@ impl Box<Any + Send> {
     ///     print_if_string(Box::new(0i8));
     /// }
     /// ```
-    pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any + Send>> {
-        <Box<Any>>::downcast(self).map_err(|s| unsafe {
+    pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<dyn Any + Send>> {
+        <Box<dyn Any>>::downcast(self).map_err(|s| unsafe {
             // reapply the Send marker
-            Box::from_raw(Box::into_raw(s) as *mut (Any + Send))
+            Box::from_raw(Box::into_raw(s) as *mut (dyn Any + Send))
         })
     }
 }
@@ -643,7 +643,7 @@ fn call_box(self: Box<F>, args: A) -> F::Output {
 
 #[unstable(feature = "fnbox",
            reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
-impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + 'a> {
+impl<'a, A, R> FnOnce<A> for Box<dyn FnBox<A, Output = R> + 'a> {
     type Output = R;
 
     extern "rust-call" fn call_once(self, args: A) -> R {
@@ -653,7 +653,7 @@ extern "rust-call" fn call_once(self, args: A) -> R {
 
 #[unstable(feature = "fnbox",
            reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
-impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + Send + 'a> {
+impl<'a, A, R> FnOnce<A> for Box<dyn FnBox<A, Output = R> + Send + 'a> {
     type Output = R;
 
     extern "rust-call" fn call_once(self, args: A) -> R {
index 837f8dfaca13a52ecddab5f7dd9b6114a8a75ae5..55995742a4a7da7bfa1ce5ec4008145190da7842 100644 (file)
@@ -31,8 +31,8 @@ fn test_owned_clone() {
 
 #[test]
 fn any_move() {
-    let a = Box::new(8) as Box<Any>;
-    let b = Box::new(Test) as Box<Any>;
+    let a = Box::new(8) as Box<dyn Any>;
+    let b = Box::new(Test) as Box<dyn Any>;
 
     match a.downcast::<i32>() {
         Ok(a) => {
@@ -47,8 +47,8 @@ fn any_move() {
         Err(..) => panic!(),
     }
 
-    let a = Box::new(8) as Box<Any>;
-    let b = Box::new(Test) as Box<Any>;
+    let a = Box::new(8) as Box<dyn Any>;
+    let b = Box::new(Test) as Box<dyn Any>;
 
     assert!(a.downcast::<Box<Test>>().is_err());
     assert!(b.downcast::<Box<i32>>().is_err());
@@ -56,8 +56,8 @@ fn any_move() {
 
 #[test]
 fn test_show() {
-    let a = Box::new(8) as Box<Any>;
-    let b = Box::new(Test) as Box<Any>;
+    let a = Box::new(8) as Box<dyn Any>;
+    let b = Box::new(Test) as Box<dyn Any>;
     let a_str = format!("{:?}", a);
     let b_str = format!("{:?}", b);
     assert_eq!(a_str, "Any");
@@ -65,8 +65,8 @@ fn test_show() {
 
     static EIGHT: usize = 8;
     static TEST: Test = Test;
-    let a = &EIGHT as &Any;
-    let b = &TEST as &Any;
+    let a = &EIGHT as &dyn Any;
+    let b = &TEST as &dyn Any;
     let s = format!("{:?}", a);
     assert_eq!(s, "Any");
     let s = format!("{:?}", b);
@@ -110,12 +110,12 @@ fn set(&mut self, value: u32) {
         }
     }
 
-    let x: Box<Foo> = Box::new(Bar(17));
+    let x: Box<dyn Foo> = Box::new(Bar(17));
     let p = Box::into_raw(x);
     unsafe {
         assert_eq!(17, (*p).get());
         (*p).set(19);
-        let y: Box<Foo> = Box::from_raw(p);
+        let y: Box<dyn Foo> = Box::from_raw(p);
         assert_eq!(19, y.get());
     }
 }
index 493448eaf88fa9b0704191d82994e52d951e4526..63cf01a0facbca245ebc2b393464df9fdf85898b 100644 (file)
@@ -72,6 +72,7 @@
        test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
 #![no_std]
 #![needs_allocator]
+#![deny(bare_trait_objects)]
 #![deny(missing_debug_implementations)]
 
 #![cfg_attr(test, allow(deprecated))] // rand
@@ -162,11 +163,14 @@ mod boxed {
 #[cfg(test)]
 mod boxed_test;
 pub mod collections;
-#[cfg(target_has_atomic = "ptr")]
+#[cfg(any(
+    all(stage0, target_has_atomic = "ptr"),
+    all(not(stage0), target_has_atomic = "ptr", target_has_atomic = "cas")
+))]
 pub mod sync;
 pub mod rc;
 pub mod raw_vec;
-
+pub mod prelude;
 pub mod borrow;
 pub mod fmt;
 pub mod slice;
diff --git a/src/liballoc/prelude.rs b/src/liballoc/prelude.rs
new file mode 100644 (file)
index 0000000..53b5e93
--- /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.
+
+//! The alloc Prelude
+//!
+//! The purpose of this module is to alleviate imports of commonly-used
+//! items of the `alloc` crate by adding a glob import to the top of modules:
+//!
+//! ```
+//! # #![allow(unused_imports)]
+//! # #![feature(alloc)]
+//! extern crate alloc;
+//! use alloc::prelude::*;
+//! ```
+
+#![unstable(feature = "alloc", issue = "27783")]
+
+#[unstable(feature = "alloc", issue = "27783")] pub use borrow::ToOwned;
+#[unstable(feature = "alloc", issue = "27783")] pub use boxed::Box;
+#[unstable(feature = "alloc", issue = "27783")] pub use slice::SliceConcatExt;
+#[unstable(feature = "alloc", issue = "27783")] pub use string::{String, ToString};
+#[unstable(feature = "alloc", issue = "27783")] pub use vec::Vec;
index 32d624e8fbc7942f32660a2275a4ba8ec72ef43c..d76acb28df92b2ae6b43bf7c091f500a0b9154aa 100644 (file)
 use core::intrinsics::abort;
 use core::marker;
 use core::marker::{Unsize, PhantomData};
-use core::mem::{self, align_of_val, forget, size_of_val, uninitialized};
+use core::mem::{self, align_of_val, forget, size_of_val};
 use core::ops::Deref;
 use core::ops::CoerceUnsized;
 use core::ptr::{self, NonNull};
@@ -618,15 +618,14 @@ pub fn make_mut(this: &mut Self) -> &mut T {
     }
 }
 
-impl Rc<Any> {
+impl Rc<dyn Any> {
     #[inline]
-    #[unstable(feature = "rc_downcast", issue = "44608")]
+    #[stable(feature = "rc_downcast", since = "1.29.0")]
     /// Attempt to downcast the `Rc<Any>` to a concrete type.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(rc_downcast)]
     /// use std::any::Any;
     /// use std::rc::Rc;
     ///
@@ -642,7 +641,7 @@ impl Rc<Any> {
     ///     print_if_string(Rc::new(0i8));
     /// }
     /// ```
-    pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<Any>> {
+    pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> {
         if (*self).is::<T>() {
             let ptr = self.ptr.cast::<RcBox<T>>();
             forget(self);
@@ -1153,6 +1152,10 @@ fn from(mut v: Vec<T>) -> Rc<[T]> {
 /// [`None`]: ../../std/option/enum.Option.html#variant.None
 #[stable(feature = "rc_weak", since = "1.4.0")]
 pub struct Weak<T: ?Sized> {
+    // This is a `NonNull` to allow optimizing the size of this type in enums,
+    // but it is not necessarily a valid pointer.
+    // `Weak::new` sets this to a dangling pointer so that it doesn’t need
+    // to allocate space on the heap.
     ptr: NonNull<RcBox<T>>,
 }
 
@@ -1165,8 +1168,8 @@ impl<T: ?Sized> !marker::Sync for Weak<T> {}
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
 
 impl<T> Weak<T> {
-    /// Constructs a new `Weak<T>`, allocating memory for `T` without initializing
-    /// it. Calling [`upgrade`] on the return value always gives [`None`].
+    /// Constructs a new `Weak<T>`, without allocating any memory.
+    /// Calling [`upgrade`] on the return value always gives [`None`].
     ///
     /// [`upgrade`]: struct.Weak.html#method.upgrade
     /// [`None`]: ../../std/option/enum.Option.html
@@ -1181,18 +1184,18 @@ impl<T> Weak<T> {
     /// ```
     #[stable(feature = "downgraded_weak", since = "1.10.0")]
     pub fn new() -> Weak<T> {
-        unsafe {
-            Weak {
-                ptr: Box::into_raw_non_null(box RcBox {
-                    strong: Cell::new(0),
-                    weak: Cell::new(1),
-                    value: uninitialized(),
-                }),
-            }
+        Weak {
+            ptr: NonNull::dangling(),
         }
     }
 }
 
+pub(crate) fn is_dangling<T: ?Sized>(ptr: NonNull<T>) -> bool {
+    let address = ptr.as_ptr() as *mut () as usize;
+    let align = align_of_val(unsafe { ptr.as_ref() });
+    address == align
+}
+
 impl<T: ?Sized> Weak<T> {
     /// Attempts to upgrade the `Weak` pointer to an [`Rc`], extending
     /// the lifetime of the value if successful.
@@ -1222,13 +1225,25 @@ impl<T: ?Sized> Weak<T> {
     /// ```
     #[stable(feature = "rc_weak", since = "1.4.0")]
     pub fn upgrade(&self) -> Option<Rc<T>> {
-        if self.strong() == 0 {
+        let inner = self.inner()?;
+        if inner.strong() == 0 {
             None
         } else {
-            self.inc_strong();
+            inner.inc_strong();
             Some(Rc { ptr: self.ptr, phantom: PhantomData })
         }
     }
+
+    /// Return `None` when the pointer is dangling and there is no allocated `RcBox`,
+    /// i.e. this `Weak` was created by `Weak::new`
+    #[inline]
+    fn inner(&self) -> Option<&RcBox<T>> {
+        if is_dangling(self.ptr) {
+            None
+        } else {
+            Some(unsafe { self.ptr.as_ref() })
+        }
+    }
 }
 
 #[stable(feature = "rc_weak", since = "1.4.0")]
@@ -1258,12 +1273,14 @@ impl<T: ?Sized> Drop for Weak<T> {
     /// assert!(other_weak_foo.upgrade().is_none());
     /// ```
     fn drop(&mut self) {
-        unsafe {
-            self.dec_weak();
+        if let Some(inner) = self.inner() {
+            inner.dec_weak();
             // the weak count starts at 1, and will only go to zero if all
             // the strong pointers have disappeared.
-            if self.weak() == 0 {
-                Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()));
+            if inner.weak() == 0 {
+                unsafe {
+                    Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()));
+                }
             }
         }
     }
@@ -1284,7 +1301,9 @@ impl<T: ?Sized> Clone for Weak<T> {
     /// ```
     #[inline]
     fn clone(&self) -> Weak<T> {
-        self.inc_weak();
+        if let Some(inner) = self.inner() {
+            inner.inc_weak()
+        }
         Weak { ptr: self.ptr }
     }
 }
@@ -1317,7 +1336,7 @@ fn default() -> Weak<T> {
     }
 }
 
-// NOTE: We checked_add here to deal with mem::forget safety. In particular
+// NOTE: We checked_add here to deal with mem::forget safely. In particular
 // if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then
 // you can free the allocation while outstanding Rcs (or Weaks) exist.
 // We abort because this is such a degenerate scenario that we don't care about
@@ -1370,12 +1389,10 @@ fn inner(&self) -> &RcBox<T> {
     }
 }
 
-impl<T: ?Sized> RcBoxPtr<T> for Weak<T> {
+impl<T: ?Sized> RcBoxPtr<T> for RcBox<T> {
     #[inline(always)]
     fn inner(&self) -> &RcBox<T> {
-        unsafe {
-            self.ptr.as_ref()
-        }
+        self
     }
 }
 
@@ -1537,7 +1554,7 @@ fn test_into_from_raw_unsized() {
         assert_eq!(unsafe { &*ptr }, "foo");
         assert_eq!(rc, rc2);
 
-        let rc: Rc<Display> = Rc::new(123);
+        let rc: Rc<dyn Display> = Rc::new(123);
 
         let ptr = Rc::into_raw(rc.clone());
         let rc2 = unsafe { Rc::from_raw(ptr) };
@@ -1738,8 +1755,8 @@ fn test_from_box_trait() {
         use std::fmt::Display;
         use std::string::ToString;
 
-        let b: Box<Display> = box 123;
-        let r: Rc<Display> = Rc::from(b);
+        let b: Box<dyn Display> = box 123;
+        let r: Rc<dyn Display> = Rc::from(b);
 
         assert_eq!(r.to_string(), "123");
     }
@@ -1748,8 +1765,8 @@ fn test_from_box_trait() {
     fn test_from_box_trait_zero_sized() {
         use std::fmt::Debug;
 
-        let b: Box<Debug> = box ();
-        let r: Rc<Debug> = Rc::from(b);
+        let b: Box<dyn Debug> = box ();
+        let r: Rc<dyn Debug> = Rc::from(b);
 
         assert_eq!(format!("{:?}", r), "()");
     }
@@ -1766,8 +1783,8 @@ fn test_from_vec() {
     fn test_downcast() {
         use std::any::Any;
 
-        let r1: Rc<Any> = Rc::new(i32::max_value());
-        let r2: Rc<Any> = Rc::new("abc");
+        let r1: Rc<dyn Any> = Rc::new(i32::max_value());
+        let r2: Rc<dyn Any> = Rc::new("abc");
 
         assert!(r1.clone().downcast::<u32>().is_err());
 
index 2abd9c85c5754f140beb33dcd8ac148969375215..5def0237e7e71761c1ceb8752fa2118fb2258452 100644 (file)
@@ -34,6 +34,7 @@
 
 use alloc::{Global, Alloc, Layout, box_free, handle_alloc_error};
 use boxed::Box;
+use rc::is_dangling;
 use string::String;
 use vec::Vec;
 
@@ -43,9 +44,6 @@
 /// necessarily) at _exactly_ `MAX_REFCOUNT + 1` references.
 const MAX_REFCOUNT: usize = (isize::MAX) as usize;
 
-/// A sentinel value that is used for the pointer of `Weak::new()`.
-const WEAK_EMPTY: usize = 1;
-
 /// A thread-safe reference-counting pointer. 'Arc' stands for 'Atomically
 /// Reference Counted'.
 ///
@@ -239,9 +237,9 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
 #[stable(feature = "arc_weak", since = "1.4.0")]
 pub struct Weak<T: ?Sized> {
     // This is a `NonNull` to allow optimizing the size of this type in enums,
-    // but it is actually not truly "non-null". A `Weak::new()` will set this
-    // to a sentinel value, instead of needing to allocate some space in the
-    // heap.
+    // but it is not necessarily a valid pointer.
+    // `Weak::new` sets this to a dangling pointer so that it doesn’t need
+    // to allocate space on the heap.
     ptr: NonNull<ArcInner<T>>,
 }
 
@@ -886,13 +884,14 @@ fn is_unique(&mut self) -> bool {
         // holder.
         //
         // The acquire label here ensures a happens-before relationship with any
-        // writes to `strong` prior to decrements of the `weak` count (via drop,
-        // which uses Release).
+        // writes to `strong` (in particular in `Weak::upgrade`) prior to decrements
+        // of the `weak` count (via `Weak::drop`, which uses release).  If the upgraded
+        // weak ref was never dropped, the CAS here will fail so we do not care to synchronize.
         if self.inner().weak.compare_exchange(1, usize::MAX, Acquire, Relaxed).is_ok() {
-            // Due to the previous acquire read, this will observe any writes to
-            // `strong` that were due to upgrading weak pointers; only strong
-            // clones remain, which require that the strong count is > 1 anyway.
-            let unique = self.inner().strong.load(Relaxed) == 1;
+            // This needs to be an `Acquire` to synchronize with the decrement of the `strong`
+            // counter in `drop` -- the only access that happens when any but the last reference
+            // is being dropped.
+            let unique = self.inner().strong.load(Acquire) == 1;
 
             // The release write here synchronizes with a read in `downgrade`,
             // effectively preventing the above read of `strong` from happening
@@ -979,19 +978,18 @@ fn drop(&mut self) {
     }
 }
 
-impl Arc<Any + Send + Sync> {
+impl Arc<dyn Any + Send + Sync> {
     #[inline]
-    #[unstable(feature = "rc_downcast", issue = "44608")]
-    /// Attempt to downcast the `Arc<Any + Send + Sync>` to a concrete type.
+    #[stable(feature = "rc_downcast", since = "1.29.0")]
+    /// Attempt to downcast the `Arc<dyn Any + Send + Sync>` to a concrete type.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(rc_downcast)]
     /// use std::any::Any;
     /// use std::sync::Arc;
     ///
-    /// fn print_if_string(value: Arc<Any + Send + Sync>) {
+    /// fn print_if_string(value: Arc<dyn Any + Send + Sync>) {
     ///     if let Ok(string) = value.downcast::<String>() {
     ///         println!("String ({}): {}", string.len(), string);
     ///     }
@@ -1034,10 +1032,8 @@ impl<T> Weak<T> {
     /// ```
     #[stable(feature = "downgraded_weak", since = "1.10.0")]
     pub fn new() -> Weak<T> {
-        unsafe {
-            Weak {
-                ptr: NonNull::new_unchecked(WEAK_EMPTY as *mut _),
-            }
+        Weak {
+            ptr: NonNull::dangling(),
         }
     }
 }
@@ -1073,11 +1069,7 @@ impl<T: ?Sized> Weak<T> {
     pub fn upgrade(&self) -> Option<Arc<T>> {
         // We use a CAS loop to increment the strong count instead of a
         // fetch_add because once the count hits 0 it must never be above 0.
-        let inner = if self.ptr.as_ptr() as *const u8 as usize == WEAK_EMPTY {
-            return None;
-        } else {
-            unsafe { self.ptr.as_ref() }
-        };
+        let inner = self.inner()?;
 
         // Relaxed load because any write of 0 that we can observe
         // leaves the field in a permanently zero state (so a
@@ -1108,6 +1100,17 @@ pub fn upgrade(&self) -> Option<Arc<T>> {
             }
         }
     }
+
+    /// Return `None` when the pointer is dangling and there is no allocated `ArcInner`,
+    /// i.e. this `Weak` was created by `Weak::new`
+    #[inline]
+    fn inner(&self) -> Option<&ArcInner<T>> {
+        if is_dangling(self.ptr) {
+            None
+        } else {
+            Some(unsafe { self.ptr.as_ref() })
+        }
+    }
 }
 
 #[stable(feature = "arc_weak", since = "1.4.0")]
@@ -1125,10 +1128,10 @@ impl<T: ?Sized> Clone for Weak<T> {
     /// ```
     #[inline]
     fn clone(&self) -> Weak<T> {
-        let inner = if self.ptr.as_ptr() as *const u8 as usize == WEAK_EMPTY {
-            return Weak { ptr: self.ptr };
+        let inner = if let Some(inner) = self.inner() {
+            inner
         } else {
-            unsafe { self.ptr.as_ref() }
+            return Weak { ptr: self.ptr };
         };
         // See comments in Arc::clone() for why this is relaxed.  This can use a
         // fetch_add (ignoring the lock) because the weak count is only locked
@@ -1203,10 +1206,10 @@ fn drop(&mut self) {
         // weak count can only be locked if there was precisely one weak ref,
         // meaning that drop could only subsequently run ON that remaining weak
         // ref, which can only happen after the lock is released.
-        let inner = if self.ptr.as_ptr() as *const u8 as usize == WEAK_EMPTY {
-            return;
+        let inner = if let Some(inner) = self.inner() {
+            inner
         } else {
-            unsafe { self.ptr.as_ref() }
+            return
         };
 
         if inner.weak.fetch_sub(1, Release) == 1 {
@@ -1571,7 +1574,7 @@ fn test_into_from_raw_unsized() {
         assert_eq!(unsafe { &*ptr }, "foo");
         assert_eq!(arc, arc2);
 
-        let arc: Arc<Display> = Arc::new(123);
+        let arc: Arc<dyn Display> = Arc::new(123);
 
         let ptr = Arc::into_raw(arc.clone());
         let arc2 = unsafe { Arc::from_raw(ptr) };
@@ -1876,8 +1879,8 @@ fn test_from_box_trait() {
         use std::fmt::Display;
         use std::string::ToString;
 
-        let b: Box<Display> = box 123;
-        let r: Arc<Display> = Arc::from(b);
+        let b: Box<dyn Display> = box 123;
+        let r: Arc<dyn Display> = Arc::from(b);
 
         assert_eq!(r.to_string(), "123");
     }
@@ -1886,8 +1889,8 @@ fn test_from_box_trait() {
     fn test_from_box_trait_zero_sized() {
         use std::fmt::Debug;
 
-        let b: Box<Debug> = box ();
-        let r: Arc<Debug> = Arc::from(b);
+        let b: Box<dyn Debug> = box ();
+        let r: Arc<dyn Debug> = Arc::from(b);
 
         assert_eq!(format!("{:?}", r), "()");
     }
@@ -1904,8 +1907,8 @@ fn test_from_vec() {
     fn test_downcast() {
         use std::any::Any;
 
-        let r1: Arc<Any + Send + Sync> = Arc::new(i32::max_value());
-        let r2: Arc<Any + Send + Sync> = Arc::new("abc");
+        let r1: Arc<dyn Any + Send + Sync> = Arc::new(i32::max_value());
+        let r2: Arc<dyn Any + Send + Sync> = Arc::new("abc");
 
         assert!(r1.clone().downcast::<u32>().is_err());
 
index f14fe3a20da93ab2e062b37f9bde24f0f3b615ee..9792d52dd66d26c658bc5e3fbcb380f0f5022081 100644 (file)
 
 pub use core::task::*;
 
-#[cfg(target_has_atomic = "ptr")]
+#[cfg(any(
+    all(stage0, target_has_atomic = "ptr"),
+    all(not(stage0), target_has_atomic = "ptr", target_has_atomic = "cas")
+))]
 pub use self::if_arc::*;
 
-#[cfg(target_has_atomic = "ptr")]
+#[cfg(any(
+    all(stage0, target_has_atomic = "ptr"),
+    all(not(stage0), target_has_atomic = "ptr", target_has_atomic = "cas")
+))]
 mod if_arc {
     use super::*;
     use core::marker::PhantomData;
@@ -47,7 +53,10 @@ unsafe fn wake_local(arc_self: &Arc<Self>) {
         }
     }
 
-    #[cfg(target_has_atomic = "ptr")]
+    #[cfg(any(
+        all(stage0, target_has_atomic = "ptr"),
+        all(not(stage0), target_has_atomic = "ptr", target_has_atomic = "cas")
+    ))]
     struct ArcWrapped<T>(PhantomData<T>);
 
     unsafe impl<T: Wake + 'static> UnsafeWake for ArcWrapped<T> {
diff --git a/src/liballoc/tests/arc.rs b/src/liballoc/tests/arc.rs
new file mode 100644 (file)
index 0000000..753873d
--- /dev/null
@@ -0,0 +1,55 @@
+// 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 std::any::Any;
+use std::sync::{Arc, Weak};
+
+#[test]
+fn uninhabited() {
+    enum Void {}
+    let mut a = Weak::<Void>::new();
+    a = a.clone();
+    assert!(a.upgrade().is_none());
+
+    let mut a: Weak<Any> = a;  // Unsizing
+    a = a.clone();
+    assert!(a.upgrade().is_none());
+}
+
+#[test]
+fn slice() {
+    let a: Arc<[u32; 3]> = Arc::new([3, 2, 1]);
+    let a: Arc<[u32]> = a;  // Unsizing
+    let b: Arc<[u32]> = Arc::from(&[3, 2, 1][..]);  // Conversion
+    assert_eq!(a, b);
+
+    // Exercise is_dangling() with a DST
+    let mut a = Arc::downgrade(&a);
+    a = a.clone();
+    assert!(a.upgrade().is_some());
+}
+
+#[test]
+fn trait_object() {
+    let a: Arc<u32> = Arc::new(4);
+    let a: Arc<Any> = a;  // Unsizing
+
+    // Exercise is_dangling() with a DST
+    let mut a = Arc::downgrade(&a);
+    a = a.clone();
+    assert!(a.upgrade().is_some());
+
+    let mut b = Weak::<u32>::new();
+    b = b.clone();
+    assert!(b.upgrade().is_none());
+    let mut b: Weak<Any> = b;  // Unsizing
+    b = b.clone();
+    assert!(b.upgrade().is_none());
+}
index dbac2c0bb18a62b0fdfd1e8fd30110dbb9e83400..2c361598e8928c8389172f86a4a1a93e478825df 100644 (file)
 use std::hash::{Hash, Hasher};
 use std::collections::hash_map::DefaultHasher;
 
+mod arc;
 mod binary_heap;
 mod btree;
 mod cow_str;
 mod fmt;
 mod heap;
 mod linked_list;
+mod rc;
 mod slice;
 mod str;
 mod string;
diff --git a/src/liballoc/tests/rc.rs b/src/liballoc/tests/rc.rs
new file mode 100644 (file)
index 0000000..baa0406
--- /dev/null
@@ -0,0 +1,55 @@
+// 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 std::any::Any;
+use std::rc::{Rc, Weak};
+
+#[test]
+fn uninhabited() {
+    enum Void {}
+    let mut a = Weak::<Void>::new();
+    a = a.clone();
+    assert!(a.upgrade().is_none());
+
+    let mut a: Weak<Any> = a;  // Unsizing
+    a = a.clone();
+    assert!(a.upgrade().is_none());
+}
+
+#[test]
+fn slice() {
+    let a: Rc<[u32; 3]> = Rc::new([3, 2, 1]);
+    let a: Rc<[u32]> = a;  // Unsizing
+    let b: Rc<[u32]> = Rc::from(&[3, 2, 1][..]);  // Conversion
+    assert_eq!(a, b);
+
+    // Exercise is_dangling() with a DST
+    let mut a = Rc::downgrade(&a);
+    a = a.clone();
+    assert!(a.upgrade().is_some());
+}
+
+#[test]
+fn trait_object() {
+    let a: Rc<u32> = Rc::new(4);
+    let a: Rc<Any> = a;  // Unsizing
+
+    // Exercise is_dangling() with a DST
+    let mut a = Rc::downgrade(&a);
+    a = a.clone();
+    assert!(a.upgrade().is_some());
+
+    let mut b = Weak::<u32>::new();
+    b = b.clone();
+    assert!(b.upgrade().is_none());
+    let mut b: Weak<Any> = b;  // Unsizing
+    b = b.clone();
+    assert!(b.upgrade().is_none());
+}
index fbbaced540e70cace77f7c600b31da99a4c9ed90..5efe1e23309a7d7a84e96796149be522763511c9 100644 (file)
@@ -809,9 +809,15 @@ pub unsafe fn set_len(&mut self, len: usize) {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn swap_remove(&mut self, index: usize) -> T {
-        let length = self.len();
-        self.swap(index, length - 1);
-        self.pop().unwrap()
+        unsafe {
+            // We replace self[index] with the last element. Note that if the
+            // bounds check on hole succeeds there must be a last element (which
+            // can be self[index] itself).
+            let hole: *mut T = &mut self[index];
+            let last = ptr::read(self.get_unchecked(self.len - 1));
+            self.len -= 1;
+            ptr::replace(hole, last)
+        }
     }
 
     /// Inserts an element at position `index` within the vector, shifting all
index 4cfd7101eb549169cdaeda5313f7c39415b9d736..86bf357a14cacb4a4169455e729d409b5ecc1da0 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 4cfd7101eb549169cdaeda5313f7c39415b9d736
+Subproject commit 86bf357a14cacb4a4169455e729d409b5ecc1da0
index 01221aecb6284651aee6a4bf9189b90ec5ca0281..b6ac248b79f8666331ab77c82d7aa9d311b188ff 100644 (file)
@@ -48,6 +48,7 @@ fn size_align<T>() -> (usize, usize) {
 /// use specific allocators with looser requirements.)
 #[stable(feature = "alloc_layout", since = "1.28.0")]
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[cfg_attr(not(stage0), lang = "alloc_layout")]
 pub struct Layout {
     // size of the requested block of memory, measured in bytes.
     size_: usize,
index 4437c36c15a5be0b7d4040c531c600c2ae44edc2..94f23db1ccc36b4e6123d1aaa9145b7812a82fcd 100644 (file)
@@ -431,7 +431,7 @@ pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
 ///
 /// While `TypeId` implements `Hash`, `PartialOrd`, and `Ord`, it is worth
 /// noting that the hashes and ordering will vary between Rust releases. Beware
-/// of relying on them outside of your code!
+/// of relying on them inside of your code!
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct TypeId {
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,
 }
index 8836de3edc874c9a518783cc103a6e02a52ae3de..c0681619bf8b584ce9f71997a9e8b3e103a48221 100644 (file)
@@ -271,9 +271,30 @@ fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
     /// Creates an iterator starting at the same point, but stepping by
     /// the given amount at each iteration.
     ///
-    /// Note that it will always return the first element of the iterator,
+    /// Note 1: The first element of the iterator will always be returned,
     /// regardless of the step given.
     ///
+    /// Note 2: The time at which ignored elements are pulled is not fixed.
+    /// `StepBy` behaves like the sequence `next(), nth(step-1), nth(step-1), â€¦`,
+    /// but is also free to behave like the sequence
+    /// `advance_n_and_return_first(step), advance_n_and_return_first(step), â€¦`
+    /// Which way is used may change for some iterators for performance reasons.
+    /// The second way will advance the iterator earlier and may consume more items.
+    ///
+    /// `advance_n_and_return_first` is the equivalent of:
+    /// ```
+    /// fn advance_n_and_return_first<I>(iter: &mut I, total_step: usize) -> Option<I::Item>
+    /// where
+    ///     I: Iterator,
+    /// {
+    ///     let next = iter.next();
+    ///     if total_step > 1 {
+    ///         iter.nth(total_step-2);
+    ///     }
+    ///     next
+    /// }
+    /// ```
+    ///
     /// # Panics
     ///
     /// The method will panic if the given step is `0`.
index 5db5d88d4a5ff9bc2e3036ba5e9d1ecb46ed7c7b..090f61a5d6997619466bcfec28f574878ba92719 100644 (file)
@@ -92,7 +92,7 @@ impl<T: ?Sized> !Send for *mut T { }
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "sized"]
 #[rustc_on_unimplemented(
-    message="the size for value values of type `{Self}` cannot be known at compilation time",
+    message="the size for values of type `{Self}` cannot be known at compilation time",
     label="doesn't have a size known at compile-time",
     note="to learn more, visit <https://doc.rust-lang.org/book/second-edition/\
           ch19-04-advanced-types.html#dynamically-sized-types--sized>",
@@ -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 84173654655ebbe28f496e5ebbe11b040fec1835..8fb4e0d6a02e35cb0e13a7e58851281fc58df04f 100644 (file)
@@ -229,6 +229,8 @@ pub fn forget<T>(t: T) {
 /// 2. Round up the current size to the nearest multiple of the next field's [alignment].
 ///
 /// Finally, round the size of the struct to the nearest multiple of its [alignment].
+/// The alignment of the struct is usually the largest alignment of all its
+/// fields; this can be changed with the use of `repr(align(N))`.
 ///
 /// Unlike `C`, zero sized structs are not rounded up to one byte in size.
 ///
@@ -283,7 +285,8 @@ pub fn forget<T>(t: T) {
 /// // The size of the second field is 2, so add 2 to the size. Size is 4.
 /// // The alignment of the third field is 1, so add 0 to the size for padding. Size is 4.
 /// // The size of the third field is 1, so add 1 to the size. Size is 5.
-/// // Finally, the alignment of the struct is 2, so add 1 to the size for padding. Size is 6.
+/// // Finally, the alignment of the struct is 2 (because the largest alignment amongst its
+/// // fields is 2), so add 1 to the size for padding. Size is 6.
 /// assert_eq!(6, mem::size_of::<FieldStruct>());
 ///
 /// #[repr(C)]
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 6aa4f297e75ba7f79fe6164867c36dd01ee860b5..aa6a08cb2057ea34a4e1faed0dfa1c700a56b5a6 100644 (file)
@@ -8,12 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/*!
-Almost direct (but slightly optimized) Rust translation of Figure 3 of [1].
-
-[1] Burger, R. G. and Dybvig, R. K. 1996. Printing floating-point numbers
-    quickly and accurately. SIGPLAN Not. 31, 5 (May. 1996), 108-116.
-*/
+//! Almost direct (but slightly optimized) Rust translation of Figure 3 of "Printing
+//! Floating-Point Numbers Quickly and Accurately"[^1].
+//!
+//! [^1]: Burger, R. G. and Dybvig, R. K. 1996. Printing floating-point numbers
+//!   quickly and accurately. SIGPLAN Not. 31, 5 (May. 1996), 108-116.
 
 use cmp::Ordering;
 
index cf70a1978f5e6d53aa3de3fdf7b02fecfd459806..f33186e59c2e6a65107aee8c436c8f852ab44e67 100644 (file)
@@ -8,13 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/*!
-Rust adaptation of Grisu3 algorithm described in [1]. It uses about
-1KB of precomputed table, and in turn, it's very quick for most inputs.
-
-[1] Florian Loitsch. 2010. Printing floating-point numbers quickly and
-    accurately with integers. SIGPLAN Not. 45, 6 (June 2010), 233-243.
-*/
+//! Rust adaptation of the Grisu3 algorithm described in "Printing Floating-Point Numbers Quickly
+//! and Accurately with Integers"[^1]. It uses about 1KB of precomputed table, and in turn, it's
+//! very quick for most inputs.
+//!
+//! [^1]: Florian Loitsch. 2010. Printing floating-point numbers quickly and
+//!   accurately with integers. SIGPLAN Not. 45, 6 (June 2010), 233-243.
 
 use num::diy_float::Fp;
 use num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
index 260ebabf1fa4ad1dbab1cbf912bc60a96d6051b4..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);
 
index 1b4129b99fc535bc8315c068bfe8f9ccb3b6d50b..10f02ca2fdc45cf8e06b291fa94070370729109a 100644 (file)
 /// use std::panic;
 ///
 /// panic::set_hook(Box::new(|panic_info| {
-///     println!("panic occurred: {:?}", panic_info.payload().downcast_ref::<&str>().unwrap());
+///     if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
+///         println!("panic occurred: {:?}", s);
+///     } else {
+///         println!("panic occurred");
+///     }
 /// }));
 ///
 /// panic!("Normal panic");
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 87b7ae39cfd05f1baee657deea3adc74102eebea..f6ef4a79dc786683380382b4d57bd5d087dda26e 100644 (file)
@@ -729,7 +729,8 @@ pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> {
     /// Returns an iterator over `chunk_size` elements of the slice at a
     /// time. The chunks are slices and do not overlap. If `chunk_size` does
     /// not divide the length of the slice, then the last up to `chunk_size-1`
-    /// elements will be omitted.
+    /// elements will be omitted and can be retrieved from the `remainder`
+    /// function of the iterator.
     ///
     /// Due to each chunk having exactly `chunk_size` elements, the compiler
     /// can often optimize the resulting code better than in the case of
@@ -758,14 +759,15 @@ pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> {
         assert!(chunk_size != 0);
         let rem = self.len() % chunk_size;
         let len = self.len() - rem;
-        ExactChunks { v: &self[..len], chunk_size: chunk_size}
+        let (fst, snd) = self.split_at(len);
+        ExactChunks { v: fst, rem: snd, chunk_size: chunk_size}
     }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time.
     /// The chunks are mutable slices, and do not overlap. If `chunk_size` does
     /// not divide the length of the slice, then the last up to `chunk_size-1`
-    /// elements will be omitted.
-    ///
+    /// elements will be omitted and can be retrieved from the `into_remainder`
+    /// function of the iterator.
     ///
     /// Due to each chunk having exactly `chunk_size` elements, the compiler
     /// can often optimize the resulting code better than in the case of
@@ -799,7 +801,8 @@ pub fn exact_chunks_mut(&mut self, chunk_size: usize) -> ExactChunksMut<T> {
         assert!(chunk_size != 0);
         let rem = self.len() % chunk_size;
         let len = self.len() - rem;
-        ExactChunksMut { v: &mut self[..len], chunk_size: chunk_size}
+        let (fst, snd) = self.split_at_mut(len);
+        ExactChunksMut { v: fst, rem: snd, chunk_size: chunk_size}
     }
 
     /// Divides one slice into two at an index.
@@ -1541,6 +1544,9 @@ pub fn rotate_right(&mut self, k: usize) {
     /// let src = [1, 2, 3, 4];
     /// let mut dst = [0, 0];
     ///
+    /// // Because the slices have to be the same length,
+    /// // we slice the source slice from four elements
+    /// // to two. It will panic if we don't do this.
     /// dst.clone_from_slice(&src[2..]);
     ///
     /// assert_eq!(src, [1, 2, 3, 4]);
@@ -1607,6 +1613,9 @@ pub fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
     /// let src = [1, 2, 3, 4];
     /// let mut dst = [0, 0];
     ///
+    /// // Because the slices have to be the same length,
+    /// // we slice the source slice from four elements
+    /// // to two. It will panic if we don't do this.
     /// dst.copy_from_slice(&src[2..]);
     ///
     /// assert_eq!(src, [1, 2, 3, 4]);
@@ -3651,25 +3660,39 @@ fn may_have_side_effect() -> bool { false }
 /// time).
 ///
 /// When the slice len is not evenly divided by the chunk size, the last
-/// up to `chunk_size-1` elements will be omitted.
+/// up to `chunk_size-1` elements will be omitted but can be retrieved from
+/// the [`remainder`] function from the iterator.
 ///
 /// This struct is created by the [`exact_chunks`] method on [slices].
 ///
 /// [`exact_chunks`]: ../../std/primitive.slice.html#method.exact_chunks
+/// [`remainder`]: ../../std/slice/struct.ExactChunks.html#method.remainder
 /// [slices]: ../../std/primitive.slice.html
 #[derive(Debug)]
 #[unstable(feature = "exact_chunks", issue = "47115")]
 pub struct ExactChunks<'a, T:'a> {
     v: &'a [T],
+    rem: &'a [T],
     chunk_size: usize
 }
 
+#[unstable(feature = "exact_chunks", issue = "47115")]
+impl<'a, T> ExactChunks<'a, T> {
+    /// Return the remainder of the original slice that is not going to be
+    /// returned by the iterator. The returned slice has at most `chunk_size-1`
+    /// elements.
+    pub fn remainder(&self) -> &'a [T] {
+        self.rem
+    }
+}
+
 // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
 #[unstable(feature = "exact_chunks", issue = "47115")]
 impl<'a, T> Clone for ExactChunks<'a, T> {
     fn clone(&self) -> ExactChunks<'a, T> {
         ExactChunks {
             v: self.v,
+            rem: self.rem,
             chunk_size: self.chunk_size,
         }
     }
@@ -3757,20 +3780,35 @@ fn may_have_side_effect() -> bool { false }
 }
 
 /// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
-/// elements at a time). When the slice len is not evenly divided by the chunk
-/// size, the last up to `chunk_size-1` elements will be omitted.
+/// elements at a time).
+///
+/// When the slice len is not evenly divided by the chunk size, the last up to
+/// `chunk_size-1` elements will be omitted but can be retrieved from the
+/// [`into_remainder`] function from the iterator.
 ///
 /// This struct is created by the [`exact_chunks_mut`] method on [slices].
 ///
 /// [`exact_chunks_mut`]: ../../std/primitive.slice.html#method.exact_chunks_mut
+/// [`into_remainder`]: ../../std/slice/struct.ExactChunksMut.html#method.into_remainder
 /// [slices]: ../../std/primitive.slice.html
 #[derive(Debug)]
 #[unstable(feature = "exact_chunks", issue = "47115")]
 pub struct ExactChunksMut<'a, T:'a> {
     v: &'a mut [T],
+    rem: &'a mut [T],
     chunk_size: usize
 }
 
+#[unstable(feature = "exact_chunks", issue = "47115")]
+impl<'a, T> ExactChunksMut<'a, T> {
+    /// Return the remainder of the original slice that is not going to be
+    /// returned by the iterator. The returned slice has at most `chunk_size-1`
+    /// elements.
+    pub fn into_remainder(self) -> &'a mut [T] {
+        self.rem
+    }
+}
+
 #[unstable(feature = "exact_chunks", issue = "47115")]
 impl<'a, T> Iterator for ExactChunksMut<'a, T> {
     type Item = &'a mut [T];
index 7aba8b51cff510986be81832d27b24e4b5525967..1e2b18bf9b038fc83fa0485474db7aecaca1e232 100644 (file)
@@ -124,6 +124,7 @@ pub fn spin_loop_hint() {
 /// [`bool`]: ../../../std/primitive.bool.html
 #[cfg(target_has_atomic = "8")]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[repr(transparent)]
 pub struct AtomicBool {
     v: UnsafeCell<u8>,
 }
@@ -147,6 +148,7 @@ unsafe impl Sync for AtomicBool {}
 /// This type has the same in-memory representation as a `*mut T`.
 #[cfg(target_has_atomic = "ptr")]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[repr(transparent)]
 pub struct AtomicPtr<T> {
     p: UnsafeCell<*mut T>,
 }
@@ -371,6 +373,7 @@ pub fn store(&self, val: bool, order: Ordering) {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(any(stage0, target_has_atomic = "cas"))]
     pub fn swap(&self, val: bool, order: Ordering) -> bool {
         unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 }
     }
@@ -401,6 +404,7 @@ pub fn swap(&self, val: bool, order: Ordering) -> bool {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(any(stage0, target_has_atomic = "cas"))]
     pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool {
         match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
             Ok(x) => x,
@@ -446,6 +450,7 @@ pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> boo
     /// ```
     #[inline]
     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
+    #[cfg(any(stage0, target_has_atomic = "cas"))]
     pub fn compare_exchange(&self,
                             current: bool,
                             new: bool,
@@ -537,6 +542,7 @@ pub fn compare_exchange_weak(&self,
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(any(stage0, target_has_atomic = "cas"))]
     pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
         unsafe { atomic_and(self.v.get(), val as u8, order) != 0 }
     }
@@ -568,6 +574,7 @@ pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(any(stage0, target_has_atomic = "cas"))]
     pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
         // We can't use atomic_nand here because it can result in a bool with
         // an invalid value. This happens because the atomic operation is done
@@ -610,6 +617,7 @@ pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(any(stage0, target_has_atomic = "cas"))]
     pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
         unsafe { atomic_or(self.v.get(), val as u8, order) != 0 }
     }
@@ -640,6 +648,7 @@ pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(any(stage0, target_has_atomic = "cas"))]
     pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
         unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 }
     }
@@ -786,6 +795,7 @@ pub fn store(&self, ptr: *mut T, order: Ordering) {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(any(stage0, target_has_atomic = "cas"))]
     pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
         unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T }
     }
@@ -815,6 +825,7 @@ pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(any(stage0, target_has_atomic = "cas"))]
     pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T {
         match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
             Ok(x) => x,
@@ -853,6 +864,7 @@ pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) ->
     /// ```
     #[inline]
     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
+    #[cfg(any(stage0, target_has_atomic = "cas"))]
     pub fn compare_exchange(&self,
                             current: *mut T,
                             new: *mut T,
@@ -966,6 +978,7 @@ macro_rules! atomic_int {
         ///
         /// [module-level documentation]: index.html
         #[$stable]
+        #[repr(transparent)]
         pub struct $atomic_type {
             v: UnsafeCell<$int_type>,
         }
@@ -1138,6 +1151,7 @@ pub fn store(&self, val: $int_type, order: Ordering) {
 ```"),
                 #[inline]
                 #[$stable]
+                #[cfg(any(stage0, target_has_atomic = "cas"))]
                 pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
                     unsafe { atomic_swap(self.v.get(), val, order) }
                 }
@@ -1170,6 +1184,7 @@ pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
 ```"),
                 #[inline]
                 #[$stable]
+                #[cfg(any(stage0, target_has_atomic = "cas"))]
                 pub fn compare_and_swap(&self,
                                         current: $int_type,
                                         new: $int_type,
@@ -1223,6 +1238,7 @@ pub fn compare_and_swap(&self,
 ```"),
                 #[inline]
                 #[$stable_cxchg]
+                #[cfg(any(stage0, target_has_atomic = "cas"))]
                 pub fn compare_exchange(&self,
                                         current: $int_type,
                                         new: $int_type,
@@ -1677,6 +1693,7 @@ pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
 }
 
 #[inline]
+#[cfg(any(stage0, target_has_atomic = "cas"))]
 fn strongest_failure_ordering(order: Ordering) -> Ordering {
     match order {
         Release => Relaxed,
@@ -1713,6 +1730,7 @@ unsafe fn atomic_load<T>(dst: *const T, order: Ordering) -> T {
 }
 
 #[inline]
+#[cfg(any(stage0, target_has_atomic = "cas"))]
 unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
     match order {
         Acquire => intrinsics::atomic_xchg_acq(dst, val),
@@ -1751,6 +1769,7 @@ unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
 }
 
 #[inline]
+#[cfg(any(stage0, target_has_atomic = "cas"))]
 unsafe fn atomic_compare_exchange<T>(dst: *mut T,
                                      old: T,
                                      new: T,
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 7981567067dad3c1f241d175c39474e29b819cfc..2b37acdfe3e81386d4a4c3b5d6a7bb606df29e3d 100644 (file)
@@ -259,6 +259,13 @@ fn test_exact_chunks_last() {
     assert_eq!(c2.last().unwrap(), &[2, 3]);
 }
 
+#[test]
+fn test_exact_chunks_remainder() {
+    let v: &[i32] = &[0, 1, 2, 3, 4];
+    let c = v.exact_chunks(2);
+    assert_eq!(c.remainder(), &[4]);
+}
+
 #[test]
 fn test_exact_chunks_zip() {
     let v1: &[i32] = &[0, 1, 2, 3, 4];
@@ -310,6 +317,13 @@ fn test_exact_chunks_mut_last() {
     assert_eq!(c2.last().unwrap(), &[2, 3]);
 }
 
+#[test]
+fn test_exact_chunks_mut_remainder() {
+    let v: &mut [i32] = &mut [0, 1, 2, 3, 4];
+    let c = v.exact_chunks_mut(2);
+    assert_eq!(c.into_remainder(), &[4]);
+}
+
 #[test]
 fn test_exact_chunks_mut_zip() {
     let v1: &mut [i32] = &mut [0, 1, 2, 3, 4];
index 0c326ce3718435f6f4517275f1b7838e12b931b8..a24c659689139d6f7b6f3760f109ad0b1b56b647 100644 (file)
@@ -48,8 +48,8 @@
 pub struct EHContext<'a> {
     pub ip: usize, // Current instruction pointer
     pub func_start: usize, // Address of the current function
-    pub get_text_start: &'a Fn() -> usize, // Get address of the code section
-    pub get_data_start: &'a Fn() -> usize, // Get address of the data section
+    pub get_text_start: &'a dyn Fn() -> usize, // Get address of the code section
+    pub get_data_start: &'a dyn Fn() -> usize, // Get address of the data section
 }
 
 pub enum EHAction {
index 0e48e37c92358150f285f4cc5db6357e098b9fb3..87efc23abc81d7bec015bfff038a1e2fa2c3f9ed 100644 (file)
@@ -29,20 +29,20 @@ pub fn payload() -> *mut u8 {
     ptr::null_mut()
 }
 
-pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send> {
+pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
     assert!(!ptr.is_null());
     let ex = ptr::read(ptr as *mut _);
     __cxa_free_exception(ptr as *mut _);
     ex
 }
 
-pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
+pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
     let sz = mem::size_of_val(&data);
     let exception = __cxa_allocate_exception(sz);
     if exception == ptr::null_mut() {
         return uw::_URC_FATAL_PHASE1_ERROR as u32;
     }
-    let exception = exception as *mut Box<Any + Send>;
+    let exception = exception as *mut Box<dyn Any + Send>;
     ptr::write(exception, data);
     __cxa_throw(exception as *mut _, ptr::null_mut(), ptr::null_mut());
 
index 06c264725a9bb3e178fc4d53a497726bfa0be914..11ebcf5c01ea79e3ca62052577c394afd3c951c8 100644 (file)
 #[repr(C)]
 struct Exception {
     _uwe: uw::_Unwind_Exception,
-    cause: Option<Box<Any + Send>>,
+    cause: Option<Box<dyn Any + Send>>,
 }
 
-pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
+pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
     let exception = Box::new(Exception {
         _uwe: uw::_Unwind_Exception {
             exception_class: rust_exception_class(),
@@ -94,7 +94,7 @@ pub fn payload() -> *mut u8 {
     ptr::null_mut()
 }
 
-pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send> {
+pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
     let my_ep = ptr as *mut Exception;
     let cause = (*my_ep).cause.take();
     uw::_Unwind_DeleteException(ptr as *mut _);
index 6c52c0fa10cc0b534536ed0f19ef3f602801082f..f8cd29fc0861fe4d7a43b8fe646a6bb2d5322166 100644 (file)
@@ -22,6 +22,7 @@
 //! More documentation about each implementation can be found in the respective
 //! module.
 
+#![deny(bare_trait_objects)]
 #![no_std]
 #![unstable(feature = "panic_unwind", issue = "32837")]
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
 #[no_mangle]
 #[unwind(allowed)]
 pub unsafe extern "C" fn __rust_start_panic(payload: usize) -> u32 {
-    let payload = payload as *mut &mut BoxMeUp;
+    let payload = payload as *mut &mut dyn BoxMeUp;
     imp::panic(Box::from_raw((*payload).box_me_up()))
 }
index 5896421493008cefb36ca632a37a94d33391a22f..8cbc4a623fa052ebf44664614dfeac7f1e036cfd 100644 (file)
@@ -43,7 +43,7 @@
 //!   throwing. Note that throwing an exception into Rust is undefined behavior
 //!   anyway, so this should be fine.
 //! * We've got some data to transmit across the unwinding boundary,
-//!   specifically a `Box<Any + Send>`. Like with Dwarf exceptions
+//!   specifically a `Box<dyn Any + Send>`. Like with Dwarf exceptions
 //!   these two pointers are stored as a payload in the exception itself. On
 //!   MSVC, however, there's no need for an extra heap allocation because the
 //!   call stack is preserved while filter functions are being executed. This
@@ -243,7 +243,7 @@ pub struct _TypeDescriptor {
     name: imp::NAME2,
 };
 
-pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
+pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
     use core::intrinsics::atomic_store;
 
     // _CxxThrowException executes entirely on this stack frame, so there's no
@@ -297,7 +297,7 @@ pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
     [0; 2]
 }
 
-pub unsafe fn cleanup(payload: [u64; 2]) -> Box<Any + Send> {
+pub unsafe fn cleanup(payload: [u64; 2]) -> Box<dyn Any + Send> {
     mem::transmute(raw::TraitObject {
         data: payload[0] as *mut _,
         vtable: payload[1] as *mut _,
index c3715f96c6482eb7f234a04db1db26eac44d5eeb..0b08e54c6739a0684c41cf9478e87b35027f8e82 100644 (file)
 
 #[repr(C)]
 struct PanicData {
-    data: Box<Any + Send>,
+    data: Box<dyn Any + Send>,
 }
 
-pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
+pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
     let panic_ctx = Box::new(PanicData { data: data });
     let params = [Box::into_raw(panic_ctx) as c::ULONG_PTR];
     c::RaiseException(RUST_PANIC,
@@ -54,7 +54,7 @@ pub fn payload() -> *mut u8 {
     ptr::null_mut()
 }
 
-pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send> {
+pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
     let panic_ctx = Box::from_raw(ptr as *mut PanicData);
     return panic_ctx.data;
 }
index 8aed61b3c385a954b07e116c71859ab7d66cc621..7150560b4a13d809d29a0e4d0ab3cc2d3e9ad640 100644 (file)
@@ -20,10 +20,10 @@ pub fn payload() -> *mut u8 {
     0 as *mut u8
 }
 
-pub unsafe fn cleanup(_ptr: *mut u8) -> Box<Any + Send> {
+pub unsafe fn cleanup(_ptr: *mut u8) -> Box<dyn Any + Send> {
     intrinsics::abort()
 }
 
-pub unsafe fn panic(_data: Box<Any + Send>) -> u32 {
+pub unsafe fn panic(_data: Box<dyn Any + Send>) -> u32 {
     intrinsics::abort()
 }
index fb5cbf473a387e782f593d4b20dc4e305db1b370..876cf295acc1ba984c3037f2b630191a097dc3e6 100644 (file)
@@ -1351,7 +1351,7 @@ pub mod __internal {
     use syntax::parse::token::{self, Token};
     use syntax::tokenstream;
     use syntax_pos::{BytePos, Loc, DUMMY_SP};
-    use syntax_pos::hygiene::{Mark, SyntaxContext, Transparency};
+    use syntax_pos::hygiene::{SyntaxContext, Transparency};
 
     use super::{TokenStream, LexError, Span};
 
@@ -1436,20 +1436,15 @@ fn drop(&mut self) {
 
             // No way to determine def location for a proc macro right now, so use call location.
             let location = cx.current_expansion.mark.expn_info().unwrap().call_site;
-            // Opaque mark was already created by expansion, now create its transparent twin.
-            // We can't use the call-site span literally here, even if it appears to provide
-            // correct name resolution, because it has all the `ExpnInfo` wrong, so the edition
-            // checks, lint macro checks, macro backtraces will all break.
-            let opaque_mark = cx.current_expansion.mark;
-            let transparent_mark = Mark::fresh_cloned(opaque_mark);
-            transparent_mark.set_transparency(Transparency::Transparent);
-
-            let to_span = |mark| Span(location.with_ctxt(SyntaxContext::empty().apply_mark(mark)));
+            let to_span = |transparency| Span(location.with_ctxt(
+                SyntaxContext::empty().apply_mark_with_transparency(cx.current_expansion.mark,
+                                                                    transparency))
+            );
             p.set(ProcMacroSess {
                 parse_sess: cx.parse_sess,
                 data: ProcMacroData {
-                    def_site: to_span(opaque_mark),
-                    call_site: to_span(transparent_mark),
+                    def_site: to_span(Transparency::Opaque),
+                    call_site: to_span(Transparency::Transparent),
                 },
             });
             f()
index 6cc61d748001a191f9bf4428080f1881dc2f285e..ef564ac89f906145946579cbe1ace58a25da91e0 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),
@@ -664,8 +665,6 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool {
 
     [] InstanceDefSizeEstimate { instance_def: InstanceDef<'tcx> },
 
-    [] WasmCustomSections(CrateNum),
-
     [input] Features,
 
     [] ProgramClausesFor(DefId),
index 5fecf2b15359fcce888cbae08506e00797d3f9ae..5ace8397d9f827bbf17b434ddb8f0edd10edd44a 100644 (file)
@@ -2137,4 +2137,5 @@ trait Foo { }
     E0707, // multiple elided lifetimes used in arguments of `async fn`
     E0708, // `async` non-`move` closures with arguments are not currently supported
     E0709, // multiple different lifetimes used in arguments of `async fn`
+    E0710, // an unknown tool name found in scoped lint
 }
index c71b47fa4e1fe1366fb3d2e17a41e6f5304b9be9..2d83c158fe08f1bb8c65a1f2b695437ad6d7eed0 100644 (file)
@@ -57,7 +57,7 @@ struct CheckAttrVisitor<'a, 'tcx: 'a> {
 impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
     /// Check any attribute.
     fn check_attributes(&self, item: &hir::Item, target: Target) {
-        if target == Target::Fn {
+        if target == Target::Fn || target == Target::Const {
             self.tcx.codegen_fn_attrs(self.tcx.hir.local_def_id(item.id));
         } else if let Some(a) = item.attrs.iter().find(|a| a.check_name("target_feature")) {
             self.tcx.sess.struct_span_err(a.span, "attribute should be applied to a function")
@@ -85,11 +85,6 @@ fn check_attributes(&self, item: &hir::Item, target: Target) {
                 if target != Target::Const {
                     self.tcx.sess.span_err(attr.span, "only allowed on consts");
                 }
-
-                if attr.value_str().is_none() {
-                    self.tcx.sess.span_err(attr.span, "must be of the form \
-                        #[wasm_custom_section = \"foo\"]");
-                }
             }
         }
 
index 7c10292061f75dd885ce69674f48c1b51b3cf3c3..7a26a239aeffadb777733841e1411434752f789a 100644 (file)
@@ -129,6 +129,16 @@ pub enum Namespace {
     MacroNS,
 }
 
+impl Namespace {
+    pub fn descr(self) -> &'static str {
+        match self {
+            TypeNS => "type",
+            ValueNS => "value",
+            MacroNS => "macro",
+        }
+    }
+}
+
 /// Just a helper â€’ separate structure for each namespace.
 #[derive(Copy, Clone, Default, Debug)]
 pub struct PerNS<T> {
index 5990340ae29553e222cf7cc5215ce9740e0abfe4..7dd7954c8f439f0fea9e6c4349bff201f26aa411 100644 (file)
@@ -82,9 +82,9 @@ pub struct LoweringContext<'a> {
     // Use to assign ids to hir nodes that do not directly correspond to an ast node
     sess: &'a Session,
 
-    cstore: &'a CrateStore,
+    cstore: &'a dyn CrateStore,
 
-    resolver: &'a mut Resolver,
+    resolver: &'a mut dyn Resolver,
 
     /// The items being lowered are collected here.
     items: BTreeMap<NodeId, hir::Item>,
@@ -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
@@ -198,10 +199,10 @@ fn reborrow(&'b mut self) -> ImplTraitContext<'b> {
 
 pub fn lower_crate(
     sess: &Session,
-    cstore: &CrateStore,
+    cstore: &dyn CrateStore,
     dep_graph: &DepGraph,
     krate: &Crate,
-    resolver: &mut Resolver,
+    resolver: &mut dyn Resolver,
 ) -> hir::Crate {
     // We're constructing the HIR here; we don't care what we will
     // read, since we haven't even constructed the *input* to
@@ -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,
         }
     }
 
@@ -3447,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 328cb8225478bdc159c503a1b678203e580d6aaa..49a4a1b78a1a8714edf8d7808b6870e2fe04f19b 100644 (file)
@@ -153,6 +153,7 @@ fn decode<D: Decoder>(d: &mut D) -> Result<DefPathTable, D::Error> {
 /// The definition table containing node definitions.
 /// It holds the DefPathTable for local DefIds/DefPaths and it also stores a
 /// mapping from NodeIds to local DefIds.
+#[derive(Clone)]
 pub struct Definitions {
     table: DefPathTable,
     node_to_def_index: NodeMap<DefIndex>,
@@ -161,34 +162,12 @@ pub struct Definitions {
     /// If `Mark` is an ID of some macro expansion,
     /// then `DefId` is the normal module (`mod`) in which the expanded macro was defined.
     parent_modules_of_macro_defs: FxHashMap<Mark, DefId>,
-    /// Item with a given `DefIndex` was defined during opaque macro expansion with ID `Mark`.
-    /// It can actually be defined during transparent macro expansions inside that opaque expansion,
-    /// but transparent expansions are ignored here.
-    opaque_expansions_that_defined: FxHashMap<DefIndex, Mark>,
+    /// Item with a given `DefIndex` was defined during macro expansion with ID `Mark`.
+    expansions_that_defined: FxHashMap<DefIndex, Mark>,
     next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>,
     def_index_to_span: FxHashMap<DefIndex, Span>,
 }
 
-// Unfortunately we have to provide a manual impl of Clone because of the
-// fixed-sized array field.
-impl Clone for Definitions {
-    fn clone(&self) -> Self {
-        Definitions {
-            table: self.table.clone(),
-            node_to_def_index: self.node_to_def_index.clone(),
-            def_index_to_node: [
-                self.def_index_to_node[0].clone(),
-                self.def_index_to_node[1].clone(),
-            ],
-            node_to_hir_id: self.node_to_hir_id.clone(),
-            parent_modules_of_macro_defs: self.parent_modules_of_macro_defs.clone(),
-            opaque_expansions_that_defined: self.opaque_expansions_that_defined.clone(),
-            next_disambiguator: self.next_disambiguator.clone(),
-            def_index_to_span: self.def_index_to_span.clone(),
-        }
-    }
-}
-
 /// A unique identifier that we can use to lookup a definition
 /// precisely. It combines the index of the definition's parent (if
 /// any) with a `DisambiguatedDefPathData`.
@@ -409,7 +388,7 @@ pub fn new() -> Definitions {
             def_index_to_node: [vec![], vec![]],
             node_to_hir_id: IndexVec::new(),
             parent_modules_of_macro_defs: FxHashMap(),
-            opaque_expansions_that_defined: FxHashMap(),
+            expansions_that_defined: FxHashMap(),
             next_disambiguator: FxHashMap(),
             def_index_to_span: FxHashMap(),
         }
@@ -584,9 +563,8 @@ pub fn create_def_with_parent(&mut self,
             self.node_to_def_index.insert(node_id, index);
         }
 
-        let expansion = expansion.modern();
         if expansion != Mark::root() {
-            self.opaque_expansions_that_defined.insert(index, expansion);
+            self.expansions_that_defined.insert(index, expansion);
         }
 
         // The span is added if it isn't dummy
@@ -606,8 +584,8 @@ pub fn init_node_id_to_hir_id_mapping(&mut self,
         self.node_to_hir_id = mapping;
     }
 
-    pub fn opaque_expansion_that_defined(&self, index: DefIndex) -> Mark {
-        self.opaque_expansions_that_defined.get(&index).cloned().unwrap_or(Mark::root())
+    pub fn expansion_that_defined(&self, index: DefIndex) -> Mark {
+        self.expansions_that_defined.get(&index).cloned().unwrap_or(Mark::root())
     }
 
     pub fn parent_module_of_macro_def(&self, mark: Mark) -> DefId {
index 8d83dd3279c64d4b690c33608b3258128856e7b6..bae443bfc582403a036c732964b20ad4cd19f811 100644 (file)
@@ -402,6 +402,15 @@ pub enum GenericArg {
     Type(Ty),
 }
 
+impl GenericArg {
+    pub fn span(&self) -> Span {
+        match self {
+            GenericArg::Lifetime(l) => l.span,
+            GenericArg::Type(t) => t.span,
+        }
+    }
+}
+
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct GenericArgs {
     /// The generic arguments for this path segment.
@@ -2259,6 +2268,7 @@ pub struct CodegenFnAttrs {
     pub export_name: Option<Symbol>,
     pub target_features: Vec<Symbol>,
     pub linkage: Option<Linkage>,
+    pub wasm_custom_section: Option<Symbol>,
 }
 
 bitflags! {
@@ -2283,6 +2293,7 @@ pub fn new() -> CodegenFnAttrs {
             export_name: None,
             target_features: vec![],
             linkage: None,
+            wasm_custom_section: None,
         }
     }
 
index 8b62ba119ebb8feadb334100d8b5006a773856f6..b6add3e6f1205b247514aa8c93769e1b61411373 100644 (file)
@@ -1120,6 +1120,7 @@ fn to_stable_hash_key(&self,
     export_name,
     target_features,
     linkage,
+    wasm_custom_section,
 });
 
 impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
index f43ac7ad0dd5a4afd5afab40ee23b21e4889cf72..ed2127cc755fc5f47dbddac5184357e97feda701 100644 (file)
@@ -30,9 +30,9 @@
     internal,
     is_user_variable
 });
-impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref, mutability });
+impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, var_hir_id, by_ref, mutability });
 impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
-impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, kind });
+impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, details, kind });
 impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks });
 
 impl<'a> HashStable<StableHashingContext<'a>>
index 5753557a102aa95e664ae9dd3cff1b36a2d53ec2..a3600c04800176d447f14787779c65d76ca765a1 100644 (file)
@@ -549,7 +549,8 @@ fn hash_stable<W: StableHasherResult>(&self,
             RemainderByZero |
             DivisionByZero |
             GeneratorResumedAfterReturn |
-            GeneratorResumedAfterPanic => {}
+            GeneratorResumedAfterPanic |
+            InfiniteLoop => {}
             ReferencedConstant(ref err) => err.hash_stable(hcx, hasher),
             MachineError(ref err) => err.hash_stable(hcx, hasher),
             FunctionPointerTyMismatch(a, b) => {
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 d9d08294334db91eca4661e8eb4efdb40773149c..d76d33b99022275e3d49b1c2a1cecc46e7fdfa45 100644 (file)
 fn print_help_message() {
     println!("\
 -Z print-region-graph by default prints a region constraint graph for every \n\
-function body, to the path `/tmp/constraints.nodeXXX.dot`, where the XXX is \n\
+function body, to the path `constraints.nodeXXX.dot`, where the XXX is \n\
 replaced with the node id of the function under analysis.                   \n\
                                                                             \n\
 To select one particular function body, set `RUST_REGION_GRAPH_NODE=XXX`,   \n\
 where XXX is the node id desired.                                           \n\
                                                                             \n\
 To generate output to some path other than the default                      \n\
-`/tmp/constraints.nodeXXX.dot`, set `RUST_REGION_GRAPH=/path/desired.dot`;  \n\
+`constraints.nodeXXX.dot`, set `RUST_REGION_GRAPH=/path/desired.dot`;  \n\
 occurrences of the character `%` in the requested path will be replaced with\n\
 the node id of the function under analysis.                                 \n\
                                                                             \n\
@@ -90,7 +90,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
             }
 
             Ok(other_path) => other_path,
-            Err(_) => "/tmp/constraints.node%.dot".to_string(),
+            Err(_) => "constraints.node%.dot".to_string(),
         };
 
         if output_template.is_empty() {
index d8efb582eaa8b8d6c783a724c1f471bf5ca9f877..c72952efc61447ef5f5b988bebffc9371f01057b 100644 (file)
@@ -36,6 +36,8 @@
 //!
 //! This API is completely unstable and subject to change.
 
+#![deny(bare_trait_objects)]
+
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
@@ -162,6 +164,7 @@ pub mod util {
     pub mod ppaux;
     pub mod nodemap;
     pub mod fs;
+    pub mod time_graph;
 }
 
 // A private module so that macro-expanded idents like
index a6bbd93750575cb3093e3f34ff7236f0a9ffc994..efc2d9311c1dcbe67ee58d39cc4d14e7e2da43a7 100644 (file)
     "checks the object safety of where clauses"
 }
 
+declare_lint! {
+    pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
+    Warn,
+    "detects proc macro derives using inaccessible names from parent modules"
+}
+
 /// Does nothing as a lint pass, but registers some `Lint`s
 /// which are used by other parts of the compiler.
 #[derive(Copy, Clone)]
@@ -372,6 +378,7 @@ fn get_lints(&self) -> LintArray {
             DUPLICATE_MACRO_EXPORTS,
             INTRA_DOC_LINK_RESOLUTION_FAILURE,
             WHERE_CLAUSES_OBJECT_SAFETY,
+            PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
         )
     }
 }
@@ -384,6 +391,7 @@ pub enum BuiltinLintDiagnostics {
     BareTraitObject(Span, /* is_global */ bool),
     AbsPathWithModule(Span),
     DuplicatedMacroExports(ast::Ident, Span, Span),
+    ProcMacroDeriveResolutionFallback(Span),
 }
 
 impl BuiltinLintDiagnostics {
@@ -420,6 +428,10 @@ pub fn run(self, sess: &Session, db: &mut DiagnosticBuilder) {
                 db.span_label(later_span, format!("`{}` already exported", ident));
                 db.span_note(earlier_span, "previous macro export is now shadowed");
             }
+            BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
+                db.span_label(span, "names from parent modules are not \
+                                     accessible without an explicit import");
+            }
         }
     }
 }
index 3393a2bf89d4b41408108d3a636a88fdf75c6b2f..a1b84a7b716efdf4d4c9ea750bb34da9db858911 100644 (file)
@@ -22,6 +22,7 @@
 use syntax::ast;
 use syntax::attr;
 use syntax::codemap::MultiSpan;
+use syntax::feature_gate;
 use syntax::symbol::Symbol;
 use util::nodemap::FxHashMap;
 
@@ -118,6 +119,11 @@ fn get_lint_level(&self,
         // Ensure that we never exceed the `--cap-lints` argument.
         level = cmp::min(level, self.lint_cap);
 
+        if let Some(driver_level) = sess.driver_lint_caps.get(&LintId::of(lint)) {
+            // Ensure that we never exceed driver level.
+            level = cmp::min(*driver_level, level);
+        }
+
         return (level, src)
     }
 
@@ -221,6 +227,28 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
                         continue
                     }
                 };
+                if let Some(lint_tool) = word.is_scoped() {
+                    if !self.sess.features_untracked().tool_lints {
+                        feature_gate::emit_feature_err(&sess.parse_sess,
+                                                       "tool_lints",
+                                                       word.span,
+                                                       feature_gate::GateIssue::Language,
+                                                       &format!("scoped lint `{}` is experimental",
+                                                                word.ident));
+                    }
+
+                    if !attr::is_known_lint_tool(lint_tool) {
+                        span_err!(
+                            sess,
+                            lint_tool.span,
+                            E0710,
+                            "an unknown tool name found in scoped lint: `{}`",
+                            word.ident
+                        );
+                    }
+
+                    continue
+                }
                 let name = word.name();
                 match store.check_lint_name(&name.as_str()) {
                     CheckLintNameResult::Ok(ids) => {
index 518021f412574dcb73c849f370f31f0a2181a9a3..ed8e1654d5a7d6fb3441d69cb38c33db469a8f2a 100644 (file)
@@ -257,7 +257,7 @@ fn encode_metadata<'a, 'tcx>(&self,
     fn metadata_encoding_version(&self) -> &[u8];
 }
 
-pub type CrateStoreDyn = CrateStore + sync::Sync;
+pub type CrateStoreDyn = dyn CrateStore + sync::Sync;
 
 // FIXME: find a better place for this?
 pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
index 226d19a91240f3d081670b1f7661e9a90445394b..42775e3a1837ff4f63d1e62fb2185efec8afd8d8 100644 (file)
@@ -288,7 +288,17 @@ fn visit_path(&mut self, path: &'tcx hir::Path, _: ast::NodeId) {
 fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt,
                                     id: ast::NodeId,
                                     attrs: &[ast::Attribute]) -> bool {
-    if attr::contains_name(attrs, "lang") || attr::contains_name(attrs, "panic_implementation") {
+    if attr::contains_name(attrs, "lang") {
+        return true;
+    }
+
+    // (To be) stable attribute for #[lang = "panic_impl"]
+    if attr::contains_name(attrs, "panic_implementation") {
+        return true;
+    }
+
+    // (To be) stable attribute for #[lang = "oom"]
+    if attr::contains_name(attrs, "alloc_error_handler") {
         return true;
     }
 
index 6ccf09f4dfc4f27797e71641e7fe5113e7408575..a83aa47fd4f13ff2826715f7a0e46f19ee38488c 100644 (file)
@@ -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.hir_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");
                 }
             }
         }));
index fe676919a7d14d23aa08e0050e01869bcfdfb7e2..6c1ef851cbeca6fe4e2abac010e76a84c9602571 100644 (file)
@@ -187,6 +187,8 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
             }
         } else if attribute.check_name("panic_implementation") {
             return Some((Symbol::intern("panic_impl"), attribute.span))
+        } else if attribute.check_name("alloc_error_handler") {
+            return Some((Symbol::intern("oom"), attribute.span))
         }
     }
 
@@ -308,6 +310,7 @@ pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItems {
     BoxFreeFnLangItem,               "box_free",                box_free_fn;
     DropInPlaceFnLangItem,           "drop_in_place",           drop_in_place_fn;
     OomLangItem,                     "oom",                     oom;
+    AllocLayoutLangItem,             "alloc_layout",            alloc_layout;
 
     StartFnLangItem,                 "start",                   start_fn;
 
index c3a2d3ce0c27f6d48df22fed89cb2034f187bb47..3b89a9d2de512fbdabf268db97fc85ec1a162b7e 100644 (file)
@@ -1347,7 +1347,7 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR
                 ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty),
             };
             for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
-                let subpat_ty = self.pat_ty_unadjusted(&subpat)?; // see (*2)
+                let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2)
                 let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string())));
                 let subcmt = Rc::new(self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior));
                 self.cat_pattern_(subcmt, &subpat, op)?;
index 180e75df1a66ec55545fbae6c6f97807c020a132..d8570b43fbe276dc32d86cf4baaa582cb0915da7 100644 (file)
@@ -115,6 +115,9 @@ fn verify<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             if lang_items::$item == lang_items::PanicImplLangItem {
                 tcx.sess.err(&format!("`#[panic_implementation]` function required, \
                                         but not found"));
+            } else if lang_items::$item == lang_items::OomLangItem {
+                tcx.sess.err(&format!("`#[alloc_error_handler]` function required, \
+                                        but not found"));
             } else {
                 tcx.sess.err(&format!("language item required, but not found: `{}`",
                                         stringify!($name)));
index 7e2c144e0a71df68731067f21cd4e2ac1fd9aa63..9125597a7273eeae9558950f429b010099a0bbbb 100644 (file)
@@ -264,6 +264,7 @@ pub enum EvalErrorKind<'tcx, O> {
     ReferencedConstant(Lrc<ConstEvalErr<'tcx>>),
     GeneratorResumedAfterReturn,
     GeneratorResumedAfterPanic,
+    InfiniteLoop,
 }
 
 pub type EvalResult<'tcx, T = ()> = Result<T, EvalError<'tcx>>;
@@ -398,6 +399,8 @@ pub fn description(&self) -> &str {
             RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
             GeneratorResumedAfterReturn => "generator resumed after completion",
             GeneratorResumedAfterPanic => "generator resumed after panicking",
+            InfiniteLoop =>
+                "duplicate interpreter state observed here, const evaluation will never terminate",
         }
     }
 }
index f5b449d68e78fc843cece246c5cab247833a1793..4164fe3fd933b80a8c65eb7c300127a94a0d4539 100644 (file)
@@ -36,7 +36,7 @@ macro_rules! err {
 use std::sync::atomic::{AtomicU32, Ordering};
 use std::num::NonZeroU32;
 
-#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub enum Lock {
     NoLock,
     WriteLock(DynamicLifetime),
index 24595c9328208a2a1183e1b11baad07ec9f11f17..ffd138c9c4815542c897c6880c8fffcdea194923 100644 (file)
@@ -7,7 +7,7 @@
 
 use super::{EvalResult, Pointer, PointerArithmetic, Allocation};
 
-/// Represents a constant value in Rust. ByVal and ScalarPair are optimizations which
+/// Represents a constant value in Rust. Scalar and ScalarPair are optimizations which
 /// matches Value's optimizations for easy conversions between these two types
 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
 pub enum ConstValue<'tcx> {
@@ -72,7 +72,7 @@ pub fn to_ptr(&self) -> Option<Pointer> {
 /// A `Value` represents a single self-contained Rust value.
 ///
 /// A `Value` can either refer to a block of memory inside an allocation (`ByRef`) or to a primitve
-/// value held directly, outside of any allocation (`ByVal`).  For `ByRef`-values, we remember
+/// value held directly, outside of any allocation (`Scalar`).  For `ByRef`-values, we remember
 /// whether the pointer is supposed to be aligned or not (also see Place).
 ///
 /// For optimization of a few very common cases, there is also a representation for a pair of
index dca0d4f442a4cbf0971e759cc30fdddfdc7c69a7..f8f8753e214e85af15f9218388712ee4af5a05c9 100644 (file)
@@ -15,7 +15,7 @@
 use graphviz::IntoCow;
 use hir::def::CtorKind;
 use hir::def_id::DefId;
-use hir::{self, InlineAsm};
+use hir::{self, HirId, InlineAsm};
 use middle::region;
 use mir::interpret::{EvalErrorKind, Scalar, Value};
 use mir::visit::MirVisitable;
@@ -380,6 +380,15 @@ pub enum ClearCrossCrate<T> {
     Set(T),
 }
 
+impl<T> ClearCrossCrate<T> {
+    pub fn assert_crate_local(self) -> T {
+        match self {
+            ClearCrossCrate::Clear => bug!("unwrapping cross-crate data"),
+            ClearCrossCrate::Set(v) => v,
+        }
+    }
+}
+
 impl<T: serialize::Encodable> serialize::UseSpecializedEncodable for ClearCrossCrate<T> {}
 impl<T: serialize::Decodable> serialize::UseSpecializedDecodable for ClearCrossCrate<T> {}
 
@@ -785,6 +794,9 @@ pub fn new_return_place(return_ty: Ty, span: Span) -> LocalDecl {
 pub struct UpvarDecl {
     pub debug_name: Name,
 
+    /// `HirId` of the captured variable
+    pub var_hir_id: ClearCrossCrate<HirId>,
+
     /// If true, the capture is behind a reference.
     pub by_ref: bool,
 
@@ -1624,7 +1636,7 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
 }
 
 // This is generic so that it can be reused by miri
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Hash, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub struct ValidationOperand<'tcx, T> {
     pub place: T,
     pub ty: Ty<'tcx>,
@@ -2365,6 +2377,7 @@ pub enum UnsafetyViolationKind {
 pub struct UnsafetyViolation {
     pub source_info: SourceInfo,
     pub description: InternedString,
+    pub details: InternedString,
     pub kind: UnsafetyViolationKind,
 }
 
index 9de9347d0ce047644a81dd5842b72b3347fbdd4c..79566fbbc11a46c1cba41446fceeb5f2493cb61c 100644 (file)
@@ -24,6 +24,7 @@ pub enum MonoItem<'tcx> {
     Fn(Instance<'tcx>),
     Static(DefId),
     GlobalAsm(NodeId),
+    CustomSection(DefId),
 }
 
 impl<'tcx> MonoItem<'tcx> {
@@ -36,7 +37,9 @@ pub fn size_estimate<'a>(&self, tcx: &TyCtxt<'a, 'tcx, 'tcx>) -> usize {
             },
             // Conservatively estimate the size of a static declaration
             // or assembly to be 1.
-            MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1,
+            MonoItem::Static(_) |
+            MonoItem::GlobalAsm(_) |
+            MonoItem::CustomSection(_) => 1,
         }
     }
 }
@@ -51,7 +54,8 @@ fn hash_stable<W: StableHasherResult>(&self,
             MonoItem::Fn(ref instance) => {
                 instance.hash_stable(hcx, hasher);
             }
-            MonoItem::Static(def_id) => {
+            MonoItem::Static(def_id) |
+            MonoItem::CustomSection(def_id) => {
                 def_id.hash_stable(hcx, hasher);
             }
             MonoItem::GlobalAsm(node_id) => {
index f97e11ef72f490ae099f9867d215b2f37c68245f..55752141e30ebd4f8e7647be6a8b2f775d58851c 100644 (file)
@@ -98,15 +98,15 @@ pub enum Lto {
 #[derive(Clone, PartialEq, Hash)]
 pub enum CrossLangLto {
     LinkerPlugin(PathBuf),
-    NoLink,
+    LinkerPluginAuto,
     Disabled
 }
 
 impl CrossLangLto {
-    pub fn embed_bitcode(&self) -> bool {
+    pub fn enabled(&self) -> bool {
         match *self {
             CrossLangLto::LinkerPlugin(_) |
-            CrossLangLto::NoLink => true,
+            CrossLangLto::LinkerPluginAuto => true,
             CrossLangLto::Disabled => false,
         }
     }
@@ -1020,7 +1020,7 @@ fn parse_cross_lang_lto(slot: &mut CrossLangLto, v: Option<&str>) -> bool {
                 let mut bool_arg = None;
                 if parse_opt_bool(&mut bool_arg, v) {
                     *slot = if bool_arg.unwrap() {
-                        CrossLangLto::NoLink
+                        CrossLangLto::LinkerPluginAuto
                     } else {
                         CrossLangLto::Disabled
                     };
@@ -1029,8 +1029,7 @@ fn parse_cross_lang_lto(slot: &mut CrossLangLto, v: Option<&str>) -> bool {
             }
 
             *slot = match v {
-                None |
-                Some("no-link") => CrossLangLto::NoLink,
+                None => CrossLangLto::LinkerPluginAuto,
                 Some(path) => CrossLangLto::LinkerPlugin(PathBuf::from(path)),
             };
             true
@@ -1152,8 +1151,8 @@ fn parse_cross_lang_lto(slot: &mut CrossLangLto, v: Option<&str>) -> bool {
         "gather codegen statistics"),
     asm_comments: bool = (false, parse_bool, [TRACKED],
         "generate comments into the assembly (may change behavior)"),
-    no_verify: bool = (false, parse_bool, [TRACKED],
-        "skip LLVM verification"),
+    verify_llvm_ir: bool = (false, parse_bool, [TRACKED],
+        "verify LLVM IR"),
     borrowck_stats: bool = (false, parse_bool, [UNTRACKED],
         "gather borrowck statistics"),
     no_landing_pads: bool = (false, parse_bool, [TRACKED],
@@ -1367,6 +1366,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
     let vendor = &sess.target.target.target_vendor;
     let min_atomic_width = sess.target.target.min_atomic_width();
     let max_atomic_width = sess.target.target.max_atomic_width();
+    let atomic_cas = sess.target.target.options.atomic_cas;
 
     let mut ret = HashSet::new();
     // Target bindings.
@@ -1406,6 +1406,9 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
             }
         }
     }
+    if atomic_cas {
+        ret.insert((Symbol::intern("target_has_atomic"), Some(Symbol::intern("cas"))));
+    }
     if sess.opts.debug_assertions {
         ret.insert((Symbol::intern("debug_assertions"), None));
     }
@@ -1747,6 +1750,29 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> ast::CrateConfig {
         .collect::<ast::CrateConfig>()
 }
 
+pub fn get_cmd_lint_options(matches: &getopts::Matches,
+                            error_format: ErrorOutputType)
+                            -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
+    let mut lint_opts = vec![];
+    let mut describe_lints = false;
+
+    for &level in &[lint::Allow, lint::Warn, lint::Deny, lint::Forbid] {
+        for lint_name in matches.opt_strs(level.as_str()) {
+            if lint_name == "help" {
+                describe_lints = true;
+            } else {
+                lint_opts.push((lint_name.replace("-", "_"), level));
+            }
+        }
+    }
+
+    let lint_cap = matches.opt_str("cap-lints").map(|cap| {
+        lint::Level::from_str(&cap)
+            .unwrap_or_else(|| early_error(error_format, &format!("unknown lint level: `{}`", cap)))
+    });
+    (lint_opts, describe_lints, lint_cap)
+}
+
 pub fn build_session_options_and_crate_config(
     matches: &getopts::Matches,
 ) -> (Options, ast::CrateConfig) {
@@ -1787,7 +1813,7 @@ pub fn build_session_options_and_crate_config(
         early_error(
                 ErrorOutputType::default(),
                 &format!(
-                    "Edition {} is unstable an only\
+                    "Edition {} is unstable and only \
                     available for nightly builds of rustc.",
                     edition,
                 )
@@ -1824,23 +1850,7 @@ pub fn build_session_options_and_crate_config(
     let crate_types = parse_crate_types_from_list(unparsed_crate_types)
         .unwrap_or_else(|e| early_error(error_format, &e[..]));
 
-    let mut lint_opts = vec![];
-    let mut describe_lints = false;
-
-    for &level in &[lint::Allow, lint::Warn, lint::Deny, lint::Forbid] {
-        for lint_name in matches.opt_strs(level.as_str()) {
-            if lint_name == "help" {
-                describe_lints = true;
-            } else {
-                lint_opts.push((lint_name.replace("-", "_"), level));
-            }
-        }
-    }
-
-    let lint_cap = matches.opt_str("cap-lints").map(|cap| {
-        lint::Level::from_str(&cap)
-            .unwrap_or_else(|| early_error(error_format, &format!("unknown lint level: `{}`", cap)))
-    });
+    let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
 
     let mut debugging_opts = build_debugging_options(matches, error_format);
 
@@ -3104,7 +3114,7 @@ fn test_debugging_options_tracking_hash() {
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
         opts = reference.clone();
-        opts.debugging_opts.no_verify = true;
+        opts.debugging_opts.verify_llvm_ir = true;
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
         opts = reference.clone();
@@ -3152,7 +3162,7 @@ fn test_debugging_options_tracking_hash() {
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
         opts = reference.clone();
-        opts.debugging_opts.cross_lang_lto = CrossLangLto::NoLink;
+        opts.debugging_opts.cross_lang_lto = CrossLangLto::LinkerPluginAuto;
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
     }
 
index 076d56fb80842cab1c4efbe9677086fae7af1cf7..ad1df0a1348c53917b67d85dfc373942e97aaa3c 100644 (file)
@@ -22,7 +22,7 @@
 use session::search_paths::PathKind;
 use session::config::{OutputType};
 use ty::tls;
-use util::nodemap::{FxHashSet};
+use util::nodemap::{FxHashMap, FxHashSet};
 use util::common::{duration_to_secs_str, ErrorReported};
 use util::common::ProfileQueriesMsg;
 
@@ -160,6 +160,9 @@ pub struct Session {
 
     /// Metadata about the allocators for the current crate being compiled
     pub has_global_allocator: Once<bool>,
+
+    /// Cap lint level specified by a driver specifically.
+    pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
 }
 
 pub struct PerfStats {
@@ -513,8 +516,8 @@ pub fn meta_stats(&self) -> bool {
     pub fn asm_comments(&self) -> bool {
         self.opts.debugging_opts.asm_comments
     }
-    pub fn no_verify(&self) -> bool {
-        self.opts.debugging_opts.no_verify
+    pub fn verify_llvm_ir(&self) -> bool {
+        self.opts.debugging_opts.verify_llvm_ir
     }
     pub fn borrowck_stats(&self) -> bool {
         self.opts.debugging_opts.borrowck_stats
@@ -1164,6 +1167,7 @@ pub fn build_session_(
             (*GLOBAL_JOBSERVER).clone()
         },
         has_global_allocator: Once::new(),
+        driver_lint_caps: FxHashMap(),
     };
 
     sess
index e97171c481f1dd25c04fea9efdb7280be14eb2f1..b7d3ad76588f7253a8d596a4412eb76b675e8ce2 100644 (file)
@@ -87,8 +87,7 @@ pub fn new_ignoring_regions() -> FulfillmentContext<'tcx> {
         }
     }
 
-    /// Attempts to select obligations using `selcx`. If `only_new_obligations` is true, then it
-    /// only attempts to select obligations that haven't been seen before.
+    /// Attempts to select obligations using `selcx`.
     fn select(&mut self, selcx: &mut SelectionContext<'a, 'gcx, 'tcx>)
               -> Result<(),Vec<FulfillmentError<'tcx>>> {
         debug!("select(obligation-forest-size={})", self.predicates.len());
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 5142a30ae574f52064cf3ef1bd960348c5d3124d..8f7f9d09423f68198ffd321e6587a286881f7ba9 100644 (file)
@@ -1354,6 +1354,12 @@ pub fn check_for_mutation_in_guard_via_ast_walk(self) -> bool {
         !self.sess.opts.debugging_opts.disable_ast_check_for_mutation_in_guard
     }
 
+    /// If true, we should use the AST-based borrowck (we may *also* use
+    /// the MIR-based borrowck).
+    pub fn use_ast_borrowck(self) -> bool {
+        self.borrowck_mode().use_ast()
+    }
+
     /// If true, we should use the MIR-based borrowck (we may *also* use
     /// the AST-based borrowck).
     pub fn use_mir_borrowck(self) -> bool {
index f55a512908499a4b7817bea0b576ec1414d8dabc..1380d10e493a8deaca0c5d2cb667406724181828 100644 (file)
@@ -253,13 +253,34 @@ pub fn fold_regions<T>(
         value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f))
     }
 
-    pub fn for_each_free_region<T,F>(self,
-                                     value: &T,
-                                     callback: F)
-        where F: FnMut(ty::Region<'tcx>),
-              T: TypeFoldable<'tcx>,
-    {
-        value.visit_with(&mut RegionVisitor {
+    /// Invoke `callback` on every region appearing free in `value`.
+    pub fn for_each_free_region(
+        self,
+        value: &impl TypeFoldable<'tcx>,
+        mut callback: impl FnMut(ty::Region<'tcx>),
+    ) {
+        self.any_free_region_meets(value, |r| {
+            callback(r);
+            false
+        });
+    }
+
+    /// True if `callback` returns true for every region appearing free in `value`.
+    pub fn all_free_regions_meet(
+        self,
+        value: &impl TypeFoldable<'tcx>,
+        mut callback: impl FnMut(ty::Region<'tcx>) -> bool,
+    ) -> bool {
+        !self.any_free_region_meets(value, |r| !callback(r))
+    }
+
+    /// True if `callback` returns true for some region appearing free in `value`.
+    pub fn any_free_region_meets(
+        self,
+        value: &impl TypeFoldable<'tcx>,
+        callback: impl FnMut(ty::Region<'tcx>) -> bool,
+    ) -> bool {
+        return value.visit_with(&mut RegionVisitor {
             outer_index: ty::INNERMOST,
             callback
         });
@@ -287,25 +308,31 @@ struct RegionVisitor<F> {
         }
 
         impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor<F>
-            where F : FnMut(ty::Region<'tcx>)
+            where F: FnMut(ty::Region<'tcx>) -> bool
         {
             fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
                 self.outer_index.shift_in(1);
-                t.skip_binder().visit_with(self);
+                let result = t.skip_binder().visit_with(self);
                 self.outer_index.shift_out(1);
-
-                false // keep visiting
+                result
             }
 
             fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
                 match *r {
                     ty::ReLateBound(debruijn, _) if debruijn < self.outer_index => {
-                        /* ignore bound regions */
+                        false // ignore bound regions, keep visiting
                     }
                     _ => (self.callback)(r),
                 }
+            }
 
-                false // keep visiting
+            fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
+                // We're only interested in types involving regions
+                if ty.flags.intersects(TypeFlags::HAS_FREE_REGIONS) {
+                    ty.super_visit_with(self)
+                } else {
+                    false // keep visiting
+                }
             }
         }
     }
index f5c2a0c3f9f05f504c09026d9ec714749b7e8fff..faad32a5d994ec3402fa659295787672457ce82b 100644 (file)
@@ -1020,13 +1020,8 @@ enum StructKind {
                 let mut abi = Abi::Aggregate { sized: true };
                 if tag.value.size(dl) == size {
                     abi = Abi::Scalar(tag.clone());
-                } else if !tag.is_bool() {
-                    // HACK(nox): Blindly using ScalarPair for all tagged enums
-                    // where applicable leads to Option<u8> being handled as {i1, i8},
-                    // which later confuses SROA and some loop optimisations,
-                    // ultimately leading to the repeat-trusted-len test
-                    // failing. We make the trade-off of using ScalarPair only
-                    // for types where the tag isn't a boolean.
+                } else {
+                    // Try to use a ScalarPair for all tagged enums.
                     let mut common_prim = None;
                     for (field_layouts, layout_variant) in variants.iter().zip(&layout_variants) {
                         let offsets = match layout_variant.fields {
@@ -1115,12 +1110,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..4a76cc683f6800ecf8715ee725d12006bae4ddbf 100644 (file)
@@ -2724,7 +2724,7 @@ pub fn hygienic_eq(self, use_name: Ident, def_name: Ident, def_parent_def_id: De
     pub fn adjust_ident(self, mut ident: Ident, scope: DefId, block: NodeId) -> (Ident, DefId) {
         ident = ident.modern();
         let target_expansion = match scope.krate {
-            LOCAL_CRATE => self.hir.definitions().opaque_expansion_that_defined(scope.index),
+            LOCAL_CRATE => self.hir.definitions().expansion_that_defined(scope.index),
             _ => Mark::root(),
         };
         let scope = match ident.span.adjust(target_expansion) {
@@ -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 229caeb95d62105d77a15051c6edacfeac18ef2e..bd6217e28c755048249d971837e0ca420cdfd205 100644 (file)
@@ -776,12 +776,6 @@ fn describe(tcx: TyCtxt, def: ty::InstanceDef<'tcx>) -> String {
     }
 }
 
-impl<'tcx> QueryDescription<'tcx> for queries::wasm_custom_sections<'tcx> {
-    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
-        format!("custom wasm sections for a crate")
-    }
-}
-
 impl<'tcx> QueryDescription<'tcx> for queries::generics_of<'tcx> {
     #[inline]
     fn cache_on_disk(def_id: Self::Key) -> bool {
index 77644cdf02b116d63e173a9d5c9f97916da3941c..3581dd87f6f8d80d615b6ac47194faf1dcf98ea0 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>>,
         ty::ParamEnv<'tcx>
     ) -> Clauses<'tcx>,
 
-    [] fn wasm_custom_sections: WasmCustomSections(CrateNum) -> Lrc<Vec<DefId>>,
     [] fn wasm_import_module_map: WasmImportModuleMap(CrateNum)
         -> Lrc<FxHashMap<DefId, String>>,
 }
index d783b9574efb2fdbe21bcbd1d22d23fbf369a286..9dc8321f82575092efefde3190b97208f93df534 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); }
@@ -1207,7 +1208,6 @@ macro_rules! force {
         DepKind::Features => { force!(features_query, LOCAL_CRATE); }
 
         DepKind::ProgramClausesFor => { force!(program_clauses_for, def_id!()); }
-        DepKind::WasmCustomSections => { force!(wasm_custom_sections, krate!()); }
         DepKind::WasmImportModuleMap => { force!(wasm_import_module_map, krate!()); }
         DepKind::ForeignModules => { force!(foreign_modules, krate!()); }
 
index c84999a7e5990c6df750c963d2a833758d5a288d..874dabaf1c9e773cc6e052b76de9cf6cead06cf3 100644 (file)
@@ -587,6 +587,7 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
             RemainderByZero => RemainderByZero,
             GeneratorResumedAfterReturn => GeneratorResumedAfterReturn,
             GeneratorResumedAfterPanic => GeneratorResumedAfterPanic,
+            InfiniteLoop => InfiniteLoop,
         })
     }
 }
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 {
diff --git a/src/librustc/util/time_graph.rs b/src/librustc/util/time_graph.rs
new file mode 100644 (file)
index 0000000..a850268
--- /dev/null
@@ -0,0 +1,278 @@
+// 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::HashMap;
+use std::fs::File;
+use std::io::prelude::*;
+use std::marker::PhantomData;
+use std::mem;
+use std::sync::{Arc, Mutex};
+use std::time::Instant;
+
+const OUTPUT_WIDTH_IN_PX: u64 = 1000;
+const TIME_LINE_HEIGHT_IN_PX: u64 = 20;
+const TIME_LINE_HEIGHT_STRIDE_IN_PX: usize = 30;
+
+#[derive(Clone)]
+struct Timing {
+    start: Instant,
+    end: Instant,
+    work_package_kind: WorkPackageKind,
+    name: String,
+    events: Vec<(String, Instant)>,
+}
+
+#[derive(Clone, Copy, Hash, Eq, PartialEq, Debug)]
+pub struct TimelineId(pub usize);
+
+#[derive(Clone)]
+struct PerThread {
+    timings: Vec<Timing>,
+    open_work_package: Option<(Instant, WorkPackageKind, String)>,
+}
+
+#[derive(Clone)]
+pub struct TimeGraph {
+    data: Arc<Mutex<HashMap<TimelineId, PerThread>>>,
+}
+
+#[derive(Clone, Copy)]
+pub struct WorkPackageKind(pub &'static [&'static str]);
+
+pub struct Timeline {
+    token: Option<RaiiToken>,
+}
+
+struct RaiiToken {
+    graph: TimeGraph,
+    timeline: TimelineId,
+    events: Vec<(String, Instant)>,
+    // The token must not be Send:
+    _marker: PhantomData<*const ()>
+}
+
+
+impl Drop for RaiiToken {
+    fn drop(&mut self) {
+        self.graph.end(self.timeline, mem::replace(&mut self.events, Vec::new()));
+    }
+}
+
+impl TimeGraph {
+    pub fn new() -> TimeGraph {
+        TimeGraph {
+            data: Arc::new(Mutex::new(HashMap::new()))
+        }
+    }
+
+    pub fn start(&self,
+                 timeline: TimelineId,
+                 work_package_kind: WorkPackageKind,
+                 name: &str) -> Timeline {
+        {
+            let mut table = self.data.lock().unwrap();
+
+            let data = table.entry(timeline).or_insert(PerThread {
+                timings: Vec::new(),
+                open_work_package: None,
+            });
+
+            assert!(data.open_work_package.is_none());
+            data.open_work_package = Some((Instant::now(), work_package_kind, name.to_string()));
+        }
+
+        Timeline {
+            token: Some(RaiiToken {
+                graph: self.clone(),
+                timeline,
+                events: Vec::new(),
+                _marker: PhantomData,
+            }),
+        }
+    }
+
+    fn end(&self, timeline: TimelineId, events: Vec<(String, Instant)>) {
+        let end = Instant::now();
+
+        let mut table = self.data.lock().unwrap();
+        let data = table.get_mut(&timeline).unwrap();
+
+        if let Some((start, work_package_kind, name)) = data.open_work_package.take() {
+            data.timings.push(Timing {
+                start,
+                end,
+                work_package_kind,
+                name,
+                events,
+            });
+        } else {
+            bug!("end timing without start?")
+        }
+    }
+
+    pub fn dump(&self, output_filename: &str) {
+        let table = self.data.lock().unwrap();
+
+        for data in table.values() {
+            assert!(data.open_work_package.is_none());
+        }
+
+        let mut threads: Vec<PerThread> =
+            table.values().map(|data| data.clone()).collect();
+
+        threads.sort_by_key(|timeline| timeline.timings[0].start);
+
+        let earliest_instant = threads[0].timings[0].start;
+        let latest_instant = threads.iter()
+                                       .map(|timeline| timeline.timings
+                                                               .last()
+                                                               .unwrap()
+                                                               .end)
+                                       .max()
+                                       .unwrap();
+        let max_distance = distance(earliest_instant, latest_instant);
+
+        let mut file = File::create(format!("{}.html", output_filename)).unwrap();
+
+        writeln!(file, "
+            <html>
+            <head>
+                <style>
+                    #threads a {{
+                        position: absolute;
+                        overflow: hidden;
+                    }}
+                    #threads {{
+                        height: {total_height}px;
+                        width: {width}px;
+                    }}
+
+                    .timeline {{
+                        display: none;
+                        width: {width}px;
+                        position: relative;
+                    }}
+
+                    .timeline:target {{
+                        display: block;
+                    }}
+
+                    .event {{
+                        position: absolute;
+                    }}
+                </style>
+            </head>
+            <body>
+                <div id='threads'>
+        ",
+            total_height = threads.len() * TIME_LINE_HEIGHT_STRIDE_IN_PX,
+            width = OUTPUT_WIDTH_IN_PX,
+        ).unwrap();
+
+        let mut color = 0;
+        for (line_index, thread) in threads.iter().enumerate() {
+            let line_top = line_index * TIME_LINE_HEIGHT_STRIDE_IN_PX;
+
+            for span in &thread.timings {
+                let start = distance(earliest_instant, span.start);
+                let end = distance(earliest_instant, span.end);
+
+                let start = normalize(start, max_distance, OUTPUT_WIDTH_IN_PX);
+                let end = normalize(end, max_distance, OUTPUT_WIDTH_IN_PX);
+
+                let colors = span.work_package_kind.0;
+
+                writeln!(file, "<a href='#timing{}'
+                                   style='top:{}px; \
+                                          left:{}px; \
+                                          width:{}px; \
+                                          height:{}px; \
+                                          background:{};'>{}</a>",
+                    color,
+                    line_top,
+                    start,
+                    end - start,
+                    TIME_LINE_HEIGHT_IN_PX,
+                    colors[color % colors.len()],
+                    span.name,
+                    ).unwrap();
+
+                color += 1;
+            }
+        }
+
+        writeln!(file, "
+            </div>
+        ").unwrap();
+
+        let mut idx = 0;
+        for thread in threads.iter() {
+            for timing in &thread.timings {
+                let colors = timing.work_package_kind.0;
+                let height = TIME_LINE_HEIGHT_STRIDE_IN_PX * timing.events.len();
+                writeln!(file, "<div class='timeline'
+                                     id='timing{}'
+                                     style='background:{};height:{}px;'>",
+                         idx,
+                         colors[idx % colors.len()],
+                         height).unwrap();
+                idx += 1;
+                let max = distance(timing.start, timing.end);
+                for (i, &(ref event, time)) in timing.events.iter().enumerate() {
+                    let i = i as u64;
+                    let time = distance(timing.start, time);
+                    let at = normalize(time, max, OUTPUT_WIDTH_IN_PX);
+                    writeln!(file, "<span class='event'
+                                          style='left:{}px;\
+                                                 top:{}px;'>{}</span>",
+                             at,
+                             TIME_LINE_HEIGHT_IN_PX * i,
+                             event).unwrap();
+                }
+                writeln!(file, "</div>").unwrap();
+            }
+        }
+
+        writeln!(file, "
+            </body>
+            </html>
+        ").unwrap();
+    }
+}
+
+impl Timeline {
+    pub fn noop() -> Timeline {
+        Timeline { token: None }
+    }
+
+    /// Record an event which happened at this moment on this timeline.
+    ///
+    /// Events are displayed in the eventual HTML output where you can click on
+    /// a particular timeline and it'll expand to all of the events that
+    /// happened on that timeline. This can then be used to drill into a
+    /// particular timeline and see what events are happening and taking the
+    /// most time.
+    pub fn record(&mut self, name: &str) {
+        if let Some(ref mut token) = self.token {
+            token.events.push((name.to_string(), Instant::now()));
+        }
+    }
+}
+
+fn distance(zero: Instant, x: Instant) -> u64 {
+
+    let duration = x.duration_since(zero);
+    (duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64) // / div
+}
+
+fn normalize(distance: u64, max: u64, max_pixels: u64) -> u64 {
+    (max_pixels * distance) / max
+}
+
index 373ab04de4b825bbd1ea31ee512cea24a6b9feba..ffbbd8a33a1d04fdc748fe13475a0902c5f42a50 100644 (file)
@@ -37,7 +37,7 @@
 
 pub fn modify(
     sess: &ParseSess,
-    resolver: &mut Resolver,
+    resolver: &mut dyn Resolver,
     krate: Crate,
     crate_name: String,
     handler: &rustc_errors::Handler,
@@ -56,7 +56,7 @@ struct ExpandAllocatorDirectives<'a> {
     found: bool,
     handler: &'a rustc_errors::Handler,
     sess: &'a ParseSess,
-    resolver: &'a mut Resolver,
+    resolver: &'a mut dyn Resolver,
     crate_name: Option<String>,
 
     // For now, we disallow `global_allocator` in submodules because hygiene is hard. Keep track of
@@ -256,7 +256,7 @@ fn arg_ty(
         &self,
         ty: &AllocatorTy,
         args: &mut Vec<Arg>,
-        ident: &mut FnMut() -> Ident,
+        ident: &mut dyn FnMut() -> Ident,
     ) -> P<Expr> {
         match *ty {
             AllocatorTy::Layout => {
index b217d3665a24542306a6dceb838acbf80f7ab428..1227936ce96fc89a3cdc5352918e8d253b59cb2c 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![deny(bare_trait_objects)]
 #![feature(rustc_private)]
 
 #[macro_use] extern crate log;
index 4bd8e6afa76e3da07fb6b9b776205d0bd5d60583..7c2d5ba094ffa9e1d3a5ed7935860cb2fc7a7f35 100644 (file)
@@ -89,6 +89,8 @@ pub struct AnalysisData<'a, 'tcx: 'a> {
 fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
     -> Lrc<BorrowCheckResult>
 {
+    assert!(tcx.use_ast_borrowck());
+
     debug!("borrowck(body_owner_def_id={:?})", owner_def_id);
 
     let owner_id = tcx.hir.as_local_node_id(owner_def_id).unwrap();
@@ -1009,7 +1011,10 @@ fn report_bckerr(&self, err: &BckError<'a, 'tcx>) {
                     let node_id = scope.node_id(self.tcx, &self.region_scope_tree);
                     match self.tcx.hir.find(node_id) {
                         Some(hir_map::NodeStmt(_)) => {
-                            db.note("consider using a `let` binding to increase its lifetime");
+                            if *sub_scope != ty::ReStatic {
+                                db.note("consider using a `let` binding to increase its lifetime");
+                            }
+
                         }
                         _ => {}
                     }
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 6b5baa402b4ab88642e0821004e65e2a6bd2efbe..dbada85098b41b92bbf8cb614acb6a777b02d913 100644 (file)
@@ -261,9 +261,12 @@ fn new(cx: &CodegenCx<'a, 'tcx>,
     fn new_vtable(cx: &CodegenCx<'a, 'tcx>,
                   sig: ty::FnSig<'tcx>,
                   extra_args: &[Ty<'tcx>]) -> Self;
-    fn unadjusted(cx: &CodegenCx<'a, 'tcx>,
-                  sig: ty::FnSig<'tcx>,
-                  extra_args: &[Ty<'tcx>]) -> Self;
+    fn new_internal(
+        cx: &CodegenCx<'a, 'tcx>,
+        sig: ty::FnSig<'tcx>,
+        extra_args: &[Ty<'tcx>],
+        mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgType<'tcx, Ty<'tcx>>,
+    ) -> Self;
     fn adjust_for_abi(&mut self,
                       cx: &CodegenCx<'a, 'tcx>,
                       abi: Abi);
@@ -285,40 +288,40 @@ fn of_instance(cx: &CodegenCx<'a, 'tcx>, instance: &ty::Instance<'tcx>)
     fn new(cx: &CodegenCx<'a, 'tcx>,
                sig: ty::FnSig<'tcx>,
                extra_args: &[Ty<'tcx>]) -> Self {
-        let mut fn_ty = FnType::unadjusted(cx, sig, extra_args);
-        fn_ty.adjust_for_abi(cx, sig.abi);
-        fn_ty
+        FnType::new_internal(cx, sig, extra_args, |ty, _| {
+            ArgType::new(cx.layout_of(ty))
+        })
     }
 
     fn new_vtable(cx: &CodegenCx<'a, 'tcx>,
                       sig: ty::FnSig<'tcx>,
                       extra_args: &[Ty<'tcx>]) -> Self {
-        let mut fn_ty = FnType::unadjusted(cx, sig, extra_args);
-        // Don't pass the vtable, it's not an argument of the virtual fn.
-        {
-            let self_arg = &mut fn_ty.args[0];
-            match self_arg.mode {
-                PassMode::Pair(data_ptr, _) => {
-                    self_arg.mode = PassMode::Direct(data_ptr);
-                }
-                _ => bug!("FnType::new_vtable: non-pair self {:?}", self_arg)
-            }
-
-            let pointee = self_arg.layout.ty.builtin_deref(true)
-                .unwrap_or_else(|| {
-                    bug!("FnType::new_vtable: non-pointer self {:?}", self_arg)
-                }).ty;
-            let fat_ptr_ty = cx.tcx.mk_mut_ptr(pointee);
-            self_arg.layout = cx.layout_of(fat_ptr_ty).field(cx, 0);
-        }
-        fn_ty.adjust_for_abi(cx, sig.abi);
-        fn_ty
+        FnType::new_internal(cx, sig, extra_args, |ty, arg_idx| {
+            let mut layout = cx.layout_of(ty);
+            // Don't pass the vtable, it's not an argument of the virtual fn.
+            // Instead, pass just the (thin pointer) first field of `*dyn Trait`.
+            if arg_idx == Some(0) {
+                // FIXME(eddyb) `layout.field(cx, 0)` is not enough because e.g.
+                // `Box<dyn Trait>` has a few newtype wrappers around the raw
+                // pointer, so we'd have to "dig down" to find `*dyn Trait`.
+                let pointee = layout.ty.builtin_deref(true)
+                    .unwrap_or_else(|| {
+                        bug!("FnType::new_vtable: non-pointer self {:?}", layout)
+                    }).ty;
+                let fat_ptr_ty = cx.tcx.mk_mut_ptr(pointee);
+                layout = cx.layout_of(fat_ptr_ty).field(cx, 0);
+            }
+            ArgType::new(layout)
+        })
     }
 
-    fn unadjusted(cx: &CodegenCx<'a, 'tcx>,
-                      sig: ty::FnSig<'tcx>,
-                      extra_args: &[Ty<'tcx>]) -> Self {
-        debug!("FnType::unadjusted({:?}, {:?})", sig, extra_args);
+    fn new_internal(
+        cx: &CodegenCx<'a, 'tcx>,
+        sig: ty::FnSig<'tcx>,
+        extra_args: &[Ty<'tcx>],
+        mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgType<'tcx, Ty<'tcx>>,
+    ) -> Self {
+        debug!("FnType::new_internal({:?}, {:?})", sig, extra_args);
 
         use self::Abi::*;
         let conv = match cx.sess().target.target.adjust_abi(sig.abi) {
@@ -435,8 +438,9 @@ fn unadjusted(cx: &CodegenCx<'a, 'tcx>,
             }
         };
 
-        let arg_of = |ty: Ty<'tcx>, is_return: bool| {
-            let mut arg = ArgType::new(cx.layout_of(ty));
+        let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| {
+            let is_return = arg_idx.is_none();
+            let mut arg = mk_arg_type(ty, arg_idx);
             if arg.layout.is_zst() {
                 // For some forsaken reason, x86_64-pc-windows-gnu
                 // doesn't ignore zero-sized struct arguments.
@@ -479,14 +483,16 @@ fn unadjusted(cx: &CodegenCx<'a, 'tcx>,
             arg
         };
 
-        FnType {
-            ret: arg_of(sig.output(), true),
-            args: inputs.iter().chain(extra_args.iter()).map(|ty| {
-                arg_of(ty, false)
+        let mut fn_ty = FnType {
+            ret: arg_of(sig.output(), None),
+            args: inputs.iter().chain(extra_args).enumerate().map(|(i, ty)| {
+                arg_of(ty, Some(i))
             }).collect(),
             variadic: sig.variadic,
             conv,
-        }
+        };
+        fn_ty.adjust_for_abi(cx, sig.abi);
+        fn_ty
     }
 
     fn adjust_for_abi(&mut self,
@@ -582,8 +588,8 @@ fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type {
                 PassMode::Ignore => continue,
                 PassMode::Direct(_) => arg.layout.immediate_llvm_type(cx),
                 PassMode::Pair(..) => {
-                    llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(cx, 0));
-                    llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(cx, 1));
+                    llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(cx, 0, true));
+                    llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(cx, 1, true));
                     continue;
                 }
                 PassMode::Cast(cast) => cast.llvm_type(cx),
@@ -666,11 +672,7 @@ fn apply_attrs_callsite(&self, bx: &Builder<'a, 'tcx>, callsite: ValueRef) {
                 layout::Int(..) if !scalar.is_bool() => {
                     let range = scalar.valid_range_exclusive(bx.cx);
                     if range.start != range.end {
-                        // FIXME(nox): This causes very weird type errors about
-                        // SHL operators in constants in stage 2 with LLVM 3.9.
-                        if unsafe { llvm::LLVMRustVersionMajor() >= 4 } {
-                            bx.range_metadata(callsite, range);
-                        }
+                        bx.range_metadata(callsite, range);
                     }
                 }
                 _ => {}
index 429acbbe0c2cb1cb428447c55e22845378bcfa14..8246bb243669444ade1dc835cb737dbcacae6c87 100644 (file)
@@ -11,9 +11,8 @@
 
 use std::ffi::{CStr, CString};
 
-use rustc::hir::{self, CodegenFnAttrFlags};
+use rustc::hir::CodegenFnAttrFlags;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
-use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::session::Session;
 use rustc::session::config::Sanitizer;
 use rustc::ty::TyCtxt;
@@ -222,37 +221,9 @@ pub fn provide(providers: &mut Providers) {
         }
     };
 
-    providers.wasm_custom_sections = |tcx, cnum| {
-        assert_eq!(cnum, LOCAL_CRATE);
-        let mut finder = WasmSectionFinder { tcx, list: Vec::new() };
-        tcx.hir.krate().visit_all_item_likes(&mut finder);
-        Lrc::new(finder.list)
-    };
-
     provide_extern(providers);
 }
 
-struct WasmSectionFinder<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    list: Vec<DefId>,
-}
-
-impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for WasmSectionFinder<'a, 'tcx> {
-    fn visit_item(&mut self, i: &'tcx hir::Item) {
-        match i.node {
-            hir::ItemConst(..) => {}
-            _ => return,
-        }
-        if i.attrs.iter().any(|i| i.check_name("wasm_custom_section")) {
-            self.list.push(self.tcx.hir.local_def_id(i.id));
-        }
-    }
-
-    fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) {}
-
-    fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) {}
-}
-
 pub fn provide_extern(providers: &mut Providers) {
     providers.wasm_import_module_map = |tcx, cnum| {
         let mut ret = FxHashMap();
index 609629bffb9dad4f48318015f89bcfdeea605850..9ea6c44502a4b2bd6b4fa4aa110e0d6643595f11 100644 (file)
@@ -48,7 +48,7 @@ enum Addition {
     },
     Archive {
         archive: ArchiveRO,
-        skip: Box<FnMut(&str) -> bool>,
+        skip: Box<dyn FnMut(&str) -> bool>,
     },
 }
 
index 7e24e1114a0c2cf0118d6d2e5b49bb196b140d62..a7f0910a6fcccff6e1fe9eb48b1ea26d213499b9 100644 (file)
@@ -29,7 +29,7 @@
 use rustc::util::fs::fix_windows_verbatim_for_gcc;
 use rustc::hir::def_id::CrateNum;
 use tempfile::{Builder as TempFileBuilder, TempDir};
-use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor, TargetTriple};
+use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor};
 use rustc_data_structures::fx::FxHashSet;
 use context::get_reloc_model;
 use llvm;
@@ -251,7 +251,7 @@ fn filename_for_metadata(sess: &Session, crate_name: &str, outputs: &OutputFilen
 
 pub(crate) fn each_linked_rlib(sess: &Session,
                                info: &CrateInfo,
-                               f: &mut FnMut(CrateNum, &Path)) -> Result<(), String> {
+                               f: &mut dyn FnMut(CrateNum, &Path)) -> Result<(), String> {
     let crates = info.used_crates_static.iter();
     let fmts = sess.dependency_formats.borrow();
     let fmts = fmts.get(&config::CrateTypeExecutable)
@@ -816,8 +816,8 @@ fn escape_string(s: &[u8]) -> String {
             if sess.target.target.options.is_like_msvc && linker_not_found {
                 sess.note_without_error("the msvc targets depend on the msvc linker \
                     but `link.exe` was not found");
-                sess.note_without_error("please ensure that VS 2013 or VS 2015 was installed \
-                    with the Visual C++ option");
+                sess.note_without_error("please ensure that VS 2013, VS 2015 or VS 2017 \
+                    was installed with the Visual C++ option");
             }
             sess.abort_if_errors();
         }
@@ -837,10 +837,8 @@ fn escape_string(s: &[u8]) -> String {
         }
     }
 
-    if sess.opts.target_triple == TargetTriple::from_triple("wasm32-unknown-unknown") {
+    if sess.opts.target_triple.triple() == "wasm32-unknown-unknown" {
         wasm::rewrite_imports(&out_filename, &codegen_results.crate_info.wasm_imports);
-        wasm::add_custom_sections(&out_filename,
-                                  &codegen_results.crate_info.wasm_custom_sections);
     }
 }
 
@@ -986,7 +984,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-fn link_args(cmd: &mut Linker,
+fn link_args(cmd: &mut dyn Linker,
              sess: &Session,
              crate_type: config::CrateType,
              tmpdir: &Path,
@@ -1197,7 +1195,7 @@ fn link_args(cmd: &mut Linker,
 // Also note that the native libraries linked here are only the ones located
 // in the current crate. Upstream crates with native library dependencies
 // may have their native library pulled in above.
-fn add_local_native_libraries(cmd: &mut Linker,
+fn add_local_native_libraries(cmd: &mut dyn Linker,
                               sess: &Session,
                               codegen_results: &CodegenResults) {
     sess.target_filesearch(PathKind::All).for_each_lib_search_path(|path, k| {
@@ -1228,7 +1226,7 @@ fn add_local_native_libraries(cmd: &mut Linker,
 // Rust crates are not considered at all when creating an rlib output. All
 // dependencies will be linked when producing the final output (instead of
 // the intermediate rlib version)
-fn add_upstream_rust_crates(cmd: &mut Linker,
+fn add_upstream_rust_crates(cmd: &mut dyn Linker,
                             sess: &Session,
                             codegen_results: &CodegenResults,
                             crate_type: config::CrateType,
@@ -1352,7 +1350,7 @@ fn unlib<'a>(config: &config::Config, stem: &'a str) -> &'a str {
     // it's packed in a .rlib, it contains stuff that are not objects that will
     // make the linker error. So we must remove those bits from the .rlib before
     // linking it.
-    fn link_sanitizer_runtime(cmd: &mut Linker,
+    fn link_sanitizer_runtime(cmd: &mut dyn Linker,
                               sess: &Session,
                               codegen_results: &CodegenResults,
                               tmpdir: &Path,
@@ -1421,7 +1419,7 @@ fn link_sanitizer_runtime(cmd: &mut Linker,
     // (aka we're making an executable), we can just pass the rlib blindly to
     // the linker (fast) because it's fine if it's not actually included as
     // we're at the end of the dependency chain.
-    fn add_static_crate(cmd: &mut Linker,
+    fn add_static_crate(cmd: &mut dyn Linker,
                         sess: &Session,
                         codegen_results: &CodegenResults,
                         tmpdir: &Path,
@@ -1526,7 +1524,7 @@ fn looks_like_rust(s: &str) -> bool {
     }
 
     // Same thing as above, but for dynamic crates instead of static crates.
-    fn add_dynamic_crate(cmd: &mut Linker, sess: &Session, cratepath: &Path) {
+    fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
         // If we're performing LTO, then it should have been previously required
         // that all upstream rust dependencies were available in an rlib format.
         assert!(!is_full_lto_enabled(sess));
@@ -1561,7 +1559,7 @@ fn add_dynamic_crate(cmd: &mut Linker, sess: &Session, cratepath: &Path) {
 // generic function calls a native function, then the generic function must
 // be instantiated in the target crate, meaning that the native symbol must
 // also be resolved in the target crate.
-fn add_upstream_native_libraries(cmd: &mut Linker,
+fn add_upstream_native_libraries(cmd: &mut dyn Linker,
                                  sess: &Session,
                                  codegen_results: &CodegenResults,
                                  crate_type: config::CrateType) {
index dd1983bdc1723d57bc67343b2f49dcd43ff447cc..f5f486893854f8999d9ff6b959e9e58598c2c49b 100644 (file)
@@ -44,7 +44,7 @@ pub fn new(tcx: TyCtxt) -> LinkerInfo {
 
     pub fn to_linker<'a>(&'a self,
                          cmd: Command,
-                         sess: &'a Session) -> Box<Linker+'a> {
+                         sess: &'a Session) -> Box<dyn Linker+'a> {
         match sess.linker_flavor() {
             LinkerFlavor::Lld(LldFlavor::Link) |
             LinkerFlavor::Msvc => {
@@ -52,14 +52,14 @@ pub fn to_linker<'a>(&'a self,
                     cmd,
                     sess,
                     info: self
-                }) as Box<Linker>
+                }) as Box<dyn Linker>
             }
             LinkerFlavor::Em =>  {
                 Box::new(EmLinker {
                     cmd,
                     sess,
                     info: self
-                }) as Box<Linker>
+                }) as Box<dyn Linker>
             }
             LinkerFlavor::Gcc =>  {
                 Box::new(GccLinker {
@@ -68,7 +68,7 @@ pub fn to_linker<'a>(&'a self,
                     info: self,
                     hinted_static: false,
                     is_ld: false,
-                }) as Box<Linker>
+                }) as Box<dyn Linker>
             }
 
             LinkerFlavor::Lld(LldFlavor::Ld) |
@@ -80,13 +80,14 @@ pub fn to_linker<'a>(&'a self,
                     info: self,
                     hinted_static: false,
                     is_ld: true,
-                }) as Box<Linker>
+                }) as Box<dyn Linker>
             }
 
             LinkerFlavor::Lld(LldFlavor::Wasm) => {
                 Box::new(WasmLd {
                     cmd,
-                }) as Box<Linker>
+                    sess,
+                }) as Box<dyn Linker>
             }
         }
     }
@@ -182,6 +183,38 @@ fn hint_dynamic(&mut self) {
             self.hinted_static = false;
         }
     }
+
+    fn push_cross_lang_lto_args(&mut self, plugin_path: Option<&OsStr>) {
+        if let Some(plugin_path) = plugin_path {
+            let mut arg = OsString::from("-plugin=");
+            arg.push(plugin_path);
+            self.linker_arg(&arg);
+        }
+
+        let opt_level = match self.sess.opts.optimize {
+            config::OptLevel::No => "O0",
+            config::OptLevel::Less => "O1",
+            config::OptLevel::Default => "O2",
+            config::OptLevel::Aggressive => "O3",
+            config::OptLevel::Size => "Os",
+            config::OptLevel::SizeMin => "Oz",
+        };
+
+        self.linker_arg(&format!("-plugin-opt={}", opt_level));
+        self.linker_arg(&format!("-plugin-opt=mcpu={}", self.sess.target_cpu()));
+
+        match self.sess.opts.cg.lto {
+            config::Lto::Thin |
+            config::Lto::ThinLocal => {
+                self.linker_arg(&format!("-plugin-opt=thin"));
+            }
+            config::Lto::Fat |
+            config::Lto::Yes |
+            config::Lto::No => {
+                // default to regular LTO
+            }
+        }
+    }
 }
 
 impl<'a> Linker for GccLinker<'a> {
@@ -439,36 +472,14 @@ fn group_end(&mut self) {
 
     fn cross_lang_lto(&mut self) {
         match self.sess.opts.debugging_opts.cross_lang_lto {
-            CrossLangLto::Disabled |
-            CrossLangLto::NoLink => {
+            CrossLangLto::Disabled => {
                 // Nothing to do
             }
+            CrossLangLto::LinkerPluginAuto => {
+                self.push_cross_lang_lto_args(None);
+            }
             CrossLangLto::LinkerPlugin(ref path) => {
-                self.linker_arg(&format!("-plugin={}", path.display()));
-
-                let opt_level = match self.sess.opts.optimize {
-                    config::OptLevel::No => "O0",
-                    config::OptLevel::Less => "O1",
-                    config::OptLevel::Default => "O2",
-                    config::OptLevel::Aggressive => "O3",
-                    config::OptLevel::Size => "Os",
-                    config::OptLevel::SizeMin => "Oz",
-                };
-
-                self.linker_arg(&format!("-plugin-opt={}", opt_level));
-                self.linker_arg(&format!("-plugin-opt=mcpu={}", self.sess.target_cpu()));
-
-                match self.sess.opts.cg.lto {
-                    config::Lto::Thin |
-                    config::Lto::ThinLocal => {
-                        self.linker_arg(&format!("-plugin-opt=thin"));
-                    }
-                    config::Lto::Fat |
-                    config::Lto::Yes |
-                    config::Lto::No => {
-                        // default to regular LTO
-                    }
-                }
+                self.push_cross_lang_lto_args(Some(path.as_os_str()));
             }
         }
     }
@@ -909,11 +920,12 @@ fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec<String> {
     symbols
 }
 
-pub struct WasmLd {
+pub struct WasmLd<'a> {
     cmd: Command,
+    sess: &'a Session,
 }
 
-impl Linker for WasmLd {
+impl<'a> Linker for WasmLd<'a> {
     fn link_dylib(&mut self, lib: &str) {
         self.cmd.arg("-l").arg(lib);
     }
@@ -978,9 +990,20 @@ fn link_whole_rlib(&mut self, lib: &Path) {
     }
 
     fn gc_sections(&mut self, _keep_metadata: bool) {
+        self.cmd.arg("--gc-sections");
     }
 
     fn optimize(&mut self) {
+        self.cmd.arg(match self.sess.opts.optimize {
+            OptLevel::No => "-O0",
+            OptLevel::Less => "-O1",
+            OptLevel::Default => "-O2",
+            OptLevel::Aggressive => "-O3",
+            // Currently LLD doesn't support `Os` and `Oz`, so pass through `O2`
+            // instead.
+            OptLevel::Size => "-O2",
+            OptLevel::SizeMin => "-O2"
+        });
     }
 
     fn pgo_gen(&mut self) {
@@ -1010,8 +1033,28 @@ fn finalize(&mut self) -> Command {
         // this isn't yet the bottleneck of compilation at all anyway.
         self.cmd.arg("--no-threads");
 
+        // By default LLD only gives us one page of stack (64k) which is a
+        // little small. Default to a larger stack closer to other PC platforms
+        // (1MB) and users can always inject their own link-args to override this.
         self.cmd.arg("-z").arg("stack-size=1048576");
 
+        // By default LLD's memory layout is:
+        //
+        // 1. First, a blank page
+        // 2. Next, all static data
+        // 3. Finally, the main stack (which grows down)
+        //
+        // This has the unfortunate consequence that on stack overflows you
+        // corrupt static data and can cause some exceedingly weird bugs. To
+        // help detect this a little sooner we instead request that the stack is
+        // placed before static data.
+        //
+        // This means that we'll generate slightly larger binaries as references
+        // to static data will take more bytes in the ULEB128 encoding, but
+        // stack overflow will be guaranteed to trap as it underflows instead of
+        // corrupting static data.
+        self.cmd.arg("--stack-first");
+
         // FIXME we probably shouldn't pass this but instead pass an explicit
         // whitelist of symbols we'll allow to be undefined. Unfortunately
         // though we can't handle symbols like `log10` that LLVM injects at a
index 96eda50d7883573340eb1aff7e2628df307ddbbd..a33f8b569d0a8585e3cee4a92ffbf70e90b19699 100644 (file)
@@ -461,9 +461,12 @@ fn run_pass_manager(cgcx: &CodegenContext,
     unsafe {
         let pm = llvm::LLVMCreatePassManager();
         llvm::LLVMRustAddAnalysisPasses(tm, pm, llmod);
-        let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
-        assert!(!pass.is_null());
-        llvm::LLVMRustAddPass(pm, pass);
+
+        if config.verify_llvm_ir {
+            let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
+            assert!(!pass.is_null());
+            llvm::LLVMRustAddPass(pm, pass);
+        }
 
         // When optimizing for LTO we don't actually pass in `-O0`, but we force
         // it to always happen at least with `-O1`.
@@ -494,9 +497,11 @@ fn run_pass_manager(cgcx: &CodegenContext,
             }
         });
 
-        let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
-        assert!(!pass.is_null());
-        llvm::LLVMRustAddPass(pm, pass);
+        if config.verify_llvm_ir {
+            let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
+            assert!(!pass.is_null());
+            llvm::LLVMRustAddPass(pm, pass);
+        }
 
         time_ext(cgcx.time_passes, None, "LTO passes", ||
              llvm::LLVMRunPassManager(pm, llmod));
index 8e5e7d376488b7df5b69af8b100b736f6fe15a8d..f46205cb59088741a00d000540a3711079bcf415 100644 (file)
@@ -22,7 +22,7 @@ pub struct RPathConfig<'a> {
     pub is_like_osx: bool,
     pub has_rpath: bool,
     pub linker_is_gnu: bool,
-    pub get_install_prefix_lib_path: &'a mut FnMut() -> PathBuf,
+    pub get_install_prefix_lib_path: &'a mut dyn FnMut() -> PathBuf,
 }
 
 pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
index c553eca08e6b4979a929d9dafbf49c3c40e6727d..d378d5af1c0f60e46098d29b09a318ebbeb0a0c3 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::collections::BTreeMap;
 use std::fs;
 use std::path::Path;
 use std::str;
 const WASM_EXTERNAL_KIND_MEMORY: u8 = 2;
 const WASM_EXTERNAL_KIND_GLOBAL: u8 = 3;
 
-/// Append all the custom sections listed in `sections` to the wasm binary
-/// specified at `path`.
-///
-/// LLVM 6 which we're using right now doesn't have the ability to create custom
-/// sections in wasm files nor does LLD have the ability to merge these sections
-/// into one larger section when linking. It's expected that this will
-/// eventually get implemented, however!
-///
-/// Until that time though this is a custom implementation in rustc to append
-/// all sections to a wasm file to the finished product that LLD produces.
-///
-/// Support for this is landing in LLVM in https://reviews.llvm.org/D43097,
-/// although after that support will need to be in LLD as well.
-pub fn add_custom_sections(path: &Path, sections: &BTreeMap<String, Vec<u8>>) {
-    if sections.len() == 0 {
-        return
-    }
-
-    let wasm = fs::read(path).expect("failed to read wasm output");
-
-    // see https://webassembly.github.io/spec/core/binary/modules.html#custom-section
-    let mut wasm = WasmEncoder { data: wasm };
-    for (section, bytes) in sections {
-        // write the `id` identifier, 0 for a custom section
-        wasm.byte(0);
-
-        // figure out how long our name descriptor will be
-        let mut name = WasmEncoder::new();
-        name.str(section);
-
-        // write the length of the payload followed by all its contents
-        wasm.u32((bytes.len() + name.data.len()) as u32);
-        wasm.data.extend_from_slice(&name.data);
-        wasm.data.extend_from_slice(bytes);
-    }
-
-    fs::write(path, &wasm.data).expect("failed to write wasm output");
-}
-
 /// Rewrite the module imports are listed from in a wasm module given the field
 /// name to module name mapping in `import_map`.
 ///
@@ -80,7 +40,7 @@ pub fn add_custom_sections(path: &Path, sections: &BTreeMap<String, Vec<u8>>) {
 ///
 /// Support for this was added to LLVM in
 /// https://github.com/llvm-mirror/llvm/commit/0f32e1365, although support still
-/// needs to be added (AFAIK at the time of this writing) to LLD
+/// needs to be added, tracked at https://bugs.llvm.org/show_bug.cgi?id=37168
 pub fn rewrite_imports(path: &Path, import_map: &FxHashMap<String, String>) {
     if import_map.len() == 0 {
         return
index baab3c618be58e84a5c6e3820c907976be1d5301..467782518f6738b7a9dcded8ee495d333530e1e0 100644 (file)
@@ -140,7 +140,7 @@ pub fn create_target_machine(sess: &Session, find_features: bool) -> TargetMachi
 // that `is_pie_binary` is false. When we discover LLVM target features
 // `sess.crate_types` is uninitialized so we cannot access it.
 pub fn target_machine_factory(sess: &Session, find_features: bool)
-    -> Arc<Fn() -> Result<TargetMachineRef, String> + Send + Sync>
+    -> Arc<dyn Fn() -> Result<TargetMachineRef, String> + Send + Sync>
 {
     let reloc_model = get_reloc_model(sess);
 
@@ -232,7 +232,7 @@ pub struct ModuleConfig {
     emit_obj: bool,
     // Miscellaneous flags.  These are mostly copied from command-line
     // options.
-    no_verify: bool,
+    pub verify_llvm_ir: bool,
     no_prepopulate_passes: bool,
     no_builtins: bool,
     time_passes: bool,
@@ -271,7 +271,7 @@ fn new(passes: Vec<String>) -> ModuleConfig {
             embed_bitcode_marker: false,
             no_integrated_as: false,
 
-            no_verify: false,
+            verify_llvm_ir: false,
             no_prepopulate_passes: false,
             no_builtins: false,
             time_passes: false,
@@ -283,15 +283,15 @@ fn new(passes: Vec<String>) -> ModuleConfig {
     }
 
     fn set_flags(&mut self, sess: &Session, no_builtins: bool) {
-        self.no_verify = sess.no_verify();
+        self.verify_llvm_ir = sess.verify_llvm_ir();
         self.no_prepopulate_passes = sess.opts.cg.no_prepopulate_passes;
         self.no_builtins = no_builtins || sess.target.target.options.no_builtins;
         self.time_passes = sess.time_passes();
         self.inline_threshold = sess.opts.cg.inline_threshold;
-        self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode;
+        self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode ||
+                              sess.opts.debugging_opts.cross_lang_lto.enabled();
         let embed_bitcode = sess.target.target.options.embed_bitcode ||
-                            sess.opts.debugging_opts.embed_bitcode ||
-                            sess.opts.debugging_opts.cross_lang_lto.embed_bitcode();
+                            sess.opts.debugging_opts.embed_bitcode;
         if embed_bitcode {
             match sess.opts.optimize {
                 config::OptLevel::No |
@@ -343,7 +343,7 @@ pub struct CodegenContext {
     regular_module_config: Arc<ModuleConfig>,
     metadata_module_config: Arc<ModuleConfig>,
     allocator_module_config: Arc<ModuleConfig>,
-    pub tm_factory: Arc<Fn() -> Result<TargetMachineRef, String> + Send + Sync>,
+    pub tm_factory: Arc<dyn Fn() -> Result<TargetMachineRef, String> + Send + Sync>,
     pub msvc_imps_needed: bool,
     pub target_pointer_width: String,
     debuginfo: config::DebugInfoLevel,
@@ -362,7 +362,7 @@ pub struct CodegenContext {
     // compiling incrementally
     pub incr_comp_session_dir: Option<PathBuf>,
     // Channel back to the main control thread to send messages to
-    coordinator_send: Sender<Box<Any + Send>>,
+    coordinator_send: Sender<Box<dyn Any + Send>>,
     // A reference to the TimeGraph so we can register timings. None means that
     // measuring is disabled.
     time_graph: Option<TimeGraph>,
@@ -542,7 +542,7 @@ unsafe fn optimize(cgcx: &CodegenContext,
             true
         };
 
-        if !config.no_verify { assert!(addpass("verify")); }
+        if config.verify_llvm_ir { assert!(addpass("verify")); }
         if !config.no_prepopulate_passes {
             llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
             llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
@@ -884,7 +884,7 @@ pub fn start_async_codegen(tcx: TyCtxt,
                                time_graph: Option<TimeGraph>,
                                link: LinkMeta,
                                metadata: EncodedMetadata,
-                               coordinator_receive: Receiver<Box<Any + Send>>,
+                               coordinator_receive: Receiver<Box<dyn Any + Send>>,
                                total_cgus: usize)
                                -> OngoingCodegen {
     let sess = tcx.sess;
@@ -1365,7 +1365,7 @@ fn execute_work_item(cgcx: &CodegenContext,
             // Don't run LTO passes when cross-lang LTO is enabled. The linker
             // will do that for us in this case.
             let needs_lto = needs_lto &&
-                !cgcx.opts.debugging_opts.cross_lang_lto.embed_bitcode();
+                !cgcx.opts.debugging_opts.cross_lang_lto.enabled();
 
             if needs_lto {
                 Ok(WorkItemResult::NeedsLTO(module))
@@ -1412,7 +1412,7 @@ fn start_executing_work(tcx: TyCtxt,
                         crate_info: &CrateInfo,
                         shared_emitter: SharedEmitter,
                         codegen_worker_send: Sender<Message>,
-                        coordinator_receive: Receiver<Box<Any + Send>>,
+                        coordinator_receive: Receiver<Box<dyn Any + Send>>,
                         total_cgus: usize,
                         jobserver: Client,
                         time_graph: Option<TimeGraph>,
@@ -1976,7 +1976,7 @@ fn spawn_work(cgcx: CodegenContext, work: WorkItem) {
         // Set up a destructor which will fire off a message that we're done as
         // we exit.
         struct Bomb {
-            coordinator_send: Sender<Box<Any + Send>>,
+            coordinator_send: Sender<Box<dyn Any + Send>>,
             result: Option<WorkItemResult>,
             worker_id: usize,
         }
@@ -2056,7 +2056,7 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
                             config: &ModuleConfig,
                             opt_level: llvm::CodeGenOptLevel,
                             prepare_for_thin_lto: bool,
-                            f: &mut FnMut(llvm::PassManagerBuilderRef)) {
+                            f: &mut dyn FnMut(llvm::PassManagerBuilderRef)) {
     use std::ptr;
 
     // Create the PassManagerBuilder for LLVM. We configure it with
@@ -2243,7 +2243,7 @@ pub struct OngoingCodegen {
     linker_info: LinkerInfo,
     crate_info: CrateInfo,
     time_graph: Option<TimeGraph>,
-    coordinator_send: Sender<Box<Any + Send>>,
+    coordinator_send: Sender<Box<dyn Any + Send>>,
     codegen_worker_receive: Receiver<Message>,
     shared_emitter_main: SharedEmitterMain,
     future: thread::JoinHandle<Result<CompiledModules, ()>>,
index a4709739a23ddabcbb587813975a407d82fe9af3..ea26e271c9bb3edad6c6221b951f28b6b36c3f26 100644 (file)
@@ -33,6 +33,7 @@
 use back::write::{self, OngoingCodegen, create_target_machine};
 use llvm::{ContextRef, ModuleRef, ValueRef, Vector, get_param};
 use llvm;
+use libc::c_uint;
 use metadata;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::middle::lang_items::StartFnLangItem;
@@ -56,6 +57,7 @@
 use callee;
 use common::{C_bool, C_bytes_in_context, C_i32, C_usize};
 use rustc_mir::monomorphize::collector::{self, MonoItemCollectionMode};
+use rustc_mir::monomorphize::item::DefPathBasedNames;
 use common::{self, C_struct_in_context, C_array, val_ty};
 use consts;
 use context::{self, CodegenCx};
 use monomorphize::partitioning::{self, PartitioningStrategy, CodegenUnit, CodegenUnitExt};
 use rustc_codegen_utils::symbol_names_test;
 use time_graph;
-use mono_item::{MonoItem, BaseMonoItemExt, MonoItemExt, DefPathBasedNames};
+use mono_item::{MonoItem, BaseMonoItemExt, MonoItemExt};
 use type_::Type;
 use type_of::LayoutLlvmExt;
 use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet};
 use CrateInfo;
 use rustc_data_structures::sync::Lrc;
-use rustc_target::spec::TargetTriple;
 
 use std::any::Any;
-use std::collections::BTreeMap;
 use std::ffi::CString;
 use std::str;
 use std::sync::Arc;
@@ -92,7 +92,7 @@
 
 use mir::operand::OperandValue;
 
-pub use rustc_codegen_utils::check_for_rustc_errors_attr;
+use rustc_codegen_utils::check_for_rustc_errors_attr;
 
 pub struct StatRecorder<'a, 'tcx: 'a> {
     cx: &'a CodegenCx<'a, 'tcx>,
@@ -265,8 +265,8 @@ pub fn unsize_thin_ptr<'a, 'tcx>(
             }
             let (lldata, llextra) = result.unwrap();
             // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
-            (bx.bitcast(lldata, dst_layout.scalar_pair_element_llvm_type(bx.cx, 0)),
-             bx.bitcast(llextra, dst_layout.scalar_pair_element_llvm_type(bx.cx, 1)))
+            (bx.bitcast(lldata, dst_layout.scalar_pair_element_llvm_type(bx.cx, 0, true)),
+             bx.bitcast(llextra, dst_layout.scalar_pair_element_llvm_type(bx.cx, 1, true)))
         }
         _ => bug!("unsize_thin_ptr: called on bad types"),
     }
@@ -396,9 +396,14 @@ pub fn from_immediate(bx: &Builder, val: ValueRef) -> ValueRef {
 
 pub fn to_immediate(bx: &Builder, val: ValueRef, layout: layout::TyLayout) -> ValueRef {
     if let layout::Abi::Scalar(ref scalar) = layout.abi {
-        if scalar.is_bool() {
-            return bx.trunc(val, Type::i1(bx.cx));
-        }
+        return to_immediate_scalar(bx, val, scalar);
+    }
+    val
+}
+
+pub fn to_immediate_scalar(bx: &Builder, val: ValueRef, scalar: &layout::Scalar) -> ValueRef {
+    if scalar.is_bool() {
+        return bx.trunc(val, Type::i1(bx.cx));
     }
     val
 }
@@ -712,7 +717,7 @@ pub fn iter_globals(llmod: llvm::ModuleRef) -> ValueIter {
 }
 
 pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                             rx: mpsc::Receiver<Box<Any + Send>>)
+                             rx: mpsc::Receiver<Box<dyn Any + Send>>)
                              -> OngoingCodegen {
 
     check_for_rustc_errors_attr(tcx);
@@ -1094,7 +1099,6 @@ pub fn new(tcx: TyCtxt) -> CrateInfo {
             used_crates_dynamic: cstore::used_crates(tcx, LinkagePreference::RequireDynamic),
             used_crates_static: cstore::used_crates(tcx, LinkagePreference::RequireStatic),
             used_crate_source: FxHashMap(),
-            wasm_custom_sections: BTreeMap::new(),
             wasm_imports: FxHashMap(),
             lang_item_to_crate: FxHashMap(),
             missing_lang_items: FxHashMap(),
@@ -1104,16 +1108,9 @@ pub fn new(tcx: TyCtxt) -> CrateInfo {
         let load_wasm_items = tcx.sess.crate_types.borrow()
             .iter()
             .any(|c| *c != config::CrateTypeRlib) &&
-            tcx.sess.opts.target_triple == TargetTriple::from_triple("wasm32-unknown-unknown");
+            tcx.sess.opts.target_triple.triple() == "wasm32-unknown-unknown";
 
         if load_wasm_items {
-            info!("attempting to load all wasm sections");
-            for &id in tcx.wasm_custom_sections(LOCAL_CRATE).iter() {
-                let (name, contents) = fetch_wasm_section(tcx, id);
-                info.wasm_custom_sections.entry(name)
-                    .or_insert(Vec::new())
-                    .extend(contents);
-            }
             info.load_wasm_imports(tcx, LOCAL_CRATE);
         }
 
@@ -1137,12 +1134,6 @@ pub fn new(tcx: TyCtxt) -> CrateInfo {
                 info.is_no_builtins.insert(cnum);
             }
             if load_wasm_items {
-                for &id in tcx.wasm_custom_sections(cnum).iter() {
-                    let (name, contents) = fetch_wasm_section(tcx, id);
-                    info.wasm_custom_sections.entry(name)
-                        .or_insert(Vec::new())
-                        .extend(contents);
-                }
                 info.load_wasm_imports(tcx, cnum);
             }
             let missing = tcx.missing_lang_items(cnum);
@@ -1379,25 +1370,41 @@ fn hash_stable<W: StableHasherResult>(&self,
     }
 }
 
-fn fetch_wasm_section(tcx: TyCtxt, id: DefId) -> (String, Vec<u8>) {
+pub fn define_custom_section(cx: &CodegenCx, def_id: DefId) {
     use rustc::mir::interpret::GlobalId;
 
-    info!("loading wasm section {:?}", id);
+    assert!(cx.tcx.sess.opts.target_triple.triple().starts_with("wasm32"));
 
-    let section = tcx.get_attrs(id)
-        .iter()
-        .find(|a| a.check_name("wasm_custom_section"))
-        .expect("missing #[wasm_custom_section] attribute")
-        .value_str()
-        .expect("malformed #[wasm_custom_section] attribute");
+    info!("loading wasm section {:?}", def_id);
 
-    let instance = ty::Instance::mono(tcx, id);
+    let section = cx.tcx.codegen_fn_attrs(def_id).wasm_custom_section.unwrap();
+
+    let instance = ty::Instance::mono(cx.tcx, def_id);
     let cid = GlobalId {
         instance,
         promoted: None
     };
     let param_env = ty::ParamEnv::reveal_all();
-    let val = tcx.const_eval(param_env.and(cid)).unwrap();
-    let alloc = tcx.const_value_to_allocation(val);
-    (section.to_string(), alloc.bytes.clone())
+    let val = cx.tcx.const_eval(param_env.and(cid)).unwrap();
+    let alloc = cx.tcx.const_value_to_allocation(val);
+
+    unsafe {
+        let section = llvm::LLVMMDStringInContext(
+            cx.llcx,
+            section.as_str().as_ptr() as *const _,
+            section.as_str().len() as c_uint,
+        );
+        let alloc = llvm::LLVMMDStringInContext(
+            cx.llcx,
+            alloc.bytes.as_ptr() as *const _,
+            alloc.bytes.len() as c_uint,
+        );
+        let data = [section, alloc];
+        let meta = llvm::LLVMMDNodeInContext(cx.llcx, data.as_ptr(), 2);
+        llvm::LLVMAddNamedMetadataOperand(
+            cx.llmod,
+            "wasm.custom_sections\0".as_ptr() as *const _,
+            meta,
+        );
+    }
 }
index 7b4998e85881efa9a03ad31810021ce8b0a0d18d..c71e49b0d8821888b952f700ed09868c3f337853 100644 (file)
@@ -277,7 +277,7 @@ pub fn sub(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
     }
 
     pub fn nswsub(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
-        self.count_insn("nwsub");
+        self.count_insn("nswsub");
         unsafe {
             llvm::LLVMBuildNSWSub(self.llbuilder, lhs, rhs, noname())
         }
@@ -291,14 +291,14 @@ pub fn nuwsub(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
     }
 
     pub fn fsub(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
-        self.count_insn("sub");
+        self.count_insn("fsub");
         unsafe {
             llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, noname())
         }
     }
 
     pub fn fsub_fast(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
-        self.count_insn("sub");
+        self.count_insn("fsub");
         unsafe {
             let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, noname());
             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
@@ -1315,6 +1315,7 @@ pub fn add_case(&self, s: ValueRef, on_val: ValueRef, dest: BasicBlockRef) {
     }
 
     pub fn add_incoming_to_phi(&self, phi: ValueRef, val: ValueRef, bb: BasicBlockRef) {
+        self.count_insn("addincoming");
         unsafe {
             llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
         }
index 6bb5456f9034f7ee91d3c45b24a8e6055b322a46..7625e4c7e0f29e2ecacc1ad982b1b993f72dc23b 100644 (file)
@@ -916,7 +916,7 @@ fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
                     name: &str,
                     inputs: Vec<Ty<'tcx>>,
                     output: Ty<'tcx>,
-                    codegen: &mut for<'b> FnMut(Builder<'b, 'tcx>))
+                    codegen: &mut dyn for<'b> FnMut(Builder<'b, 'tcx>))
                     -> ValueRef {
     let rust_fn_ty = cx.tcx.mk_fn_ptr(ty::Binder::bind(cx.tcx.mk_fn_sig(
         inputs.into_iter(),
@@ -936,7 +936,7 @@ fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
 //
 // This function is only generated once and is then cached.
 fn get_rust_try_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
-                             codegen: &mut for<'b> FnMut(Builder<'b, 'tcx>))
+                             codegen: &mut dyn for<'b> FnMut(Builder<'b, 'tcx>))
                              -> ValueRef {
     if let Some(llfn) = cx.rust_try_fn.get() {
         return llfn;
index b11b0c7abe875b11b3a3bd184768ef00e330e17b..8aa7902021f240891e2b8686c43b7e2f0931a136 100644 (file)
@@ -23,6 +23,7 @@
 #![feature(custom_attribute)]
 #![feature(fs_read_write)]
 #![allow(unused_attributes)]
+#![deny(bare_trait_objects)]
 #![feature(libc)]
 #![feature(quote)]
 #![feature(range_contains)]
@@ -65,7 +66,6 @@
 use std::any::Any;
 use std::path::PathBuf;
 use std::sync::mpsc;
-use std::collections::BTreeMap;
 use rustc_data_structures::sync::Lrc;
 
 use rustc::dep_graph::DepGraph;
@@ -76,6 +76,7 @@
 use rustc::session::{Session, CompileIncomplete};
 use rustc::session::config::{OutputFilenames, OutputType, PrintRequest};
 use rustc::ty::{self, TyCtxt};
+use rustc::util::time_graph;
 use rustc::util::nodemap::{FxHashSet, FxHashMap};
 use rustc_mir::monomorphize;
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
@@ -93,7 +94,7 @@ mod back {
     pub mod symbol_export;
     pub mod write;
     mod rpath;
-    mod wasm;
+    pub mod wasm;
 }
 
 mod abi;
@@ -114,7 +115,6 @@ mod back {
 mod metadata;
 mod meth;
 mod mir;
-mod time_graph;
 mod mono_item;
 mod type_;
 mod type_of;
@@ -126,7 +126,7 @@ impl !Send for LlvmCodegenBackend {} // Llvm is on a per-thread basis
 impl !Sync for LlvmCodegenBackend {}
 
 impl LlvmCodegenBackend {
-    pub fn new() -> Box<CodegenBackend> {
+    pub fn new() -> Box<dyn CodegenBackend> {
         box LlvmCodegenBackend(())
     }
 }
@@ -179,7 +179,7 @@ fn target_features(&self, sess: &Session) -> Vec<Symbol> {
         target_features(sess)
     }
 
-    fn metadata_loader(&self) -> Box<MetadataLoader + Sync> {
+    fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
         box metadata::LlvmMetadataLoader
     }
 
@@ -199,14 +199,14 @@ fn provide_extern(&self, providers: &mut ty::query::Providers) {
     fn codegen_crate<'a, 'tcx>(
         &self,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
-        rx: mpsc::Receiver<Box<Any + Send>>
-    ) -> Box<Any> {
+        rx: mpsc::Receiver<Box<dyn Any + Send>>
+    ) -> Box<dyn Any> {
         box base::codegen_crate(tcx, rx)
     }
 
     fn join_codegen_and_link(
         &self,
-        ongoing_codegen: Box<Any>,
+        ongoing_codegen: Box<dyn Any>,
         sess: &Session,
         dep_graph: &DepGraph,
         outputs: &OutputFilenames,
@@ -248,7 +248,7 @@ fn join_codegen_and_link(
 
 /// This is the entrypoint for a hot plugged rustc_codegen_llvm
 #[no_mangle]
-pub fn __rustc_codegen_backend() -> Box<CodegenBackend> {
+pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
     LlvmCodegenBackend::new()
 }
 
@@ -368,7 +368,7 @@ struct CodegenResults {
     crate_info: CrateInfo,
 }
 
-// Misc info we load from metadata to persist beyond the tcx
+/// Misc info we load from metadata to persist beyond the tcx
 struct CrateInfo {
     panic_runtime: Option<CrateNum>,
     compiler_builtins: Option<CrateNum>,
@@ -382,7 +382,6 @@ struct CrateInfo {
     used_crate_source: FxHashMap<CrateNum, Lrc<CrateSource>>,
     used_crates_static: Vec<(CrateNum, LibSource)>,
     used_crates_dynamic: Vec<(CrateNum, LibSource)>,
-    wasm_custom_sections: BTreeMap<String, Vec<u8>>,
     wasm_imports: FxHashMap<String, String>,
     lang_item_to_crate: FxHashMap<LangItem, CrateNum>,
     missing_lang_items: FxHashMap<CrateNum, Vec<LangItem>>,
index 357b639e78890593c7c3767bf4d5721f51eb5fa2..87ee9ef5adb23aad019ecafd85a8c1571d24e198 100644 (file)
@@ -84,6 +84,7 @@ unsafe fn configure_llvm(sess: &Session) {
 // array, leading to crashes.
 
 const ARM_WHITELIST: &[(&str, Option<&str>)] = &[
+    ("mclass", Some("arm_target_feature")),
     ("neon", Some("arm_target_feature")),
     ("v7", Some("arm_target_feature")),
     ("vfp2", Some("arm_target_feature")),
index f9be91b4f3f13d93d2ae1ad16f66b31c1e03cbc0..608539dd3fa7e3367915bd748a12f07a03789759 100644 (file)
@@ -22,7 +22,7 @@
 use common::{CodegenCx, Funclet};
 use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebugContext};
 use monomorphize::Instance;
-use abi::{ArgAttribute, ArgTypeExt, FnType, FnTypeExt, PassMode};
+use abi::{ArgTypeExt, FnType, FnTypeExt, PassMode};
 use type_::Type;
 
 use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span};
@@ -430,10 +430,6 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
         None
     };
 
-    let deref_op = unsafe {
-        [llvm::LLVMRustDIBuilderCreateOpDeref()]
-    };
-
     mir.args_iter().enumerate().map(|(arg_index, local)| {
         let arg_decl = &mir.local_decls[local];
 
@@ -543,21 +539,11 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
             if arg_index > 0 || mir.upvar_decls.is_empty() {
                 // The Rust ABI passes indirect variables using a pointer and a manual copy, so we
                 // need to insert a deref here, but the C ABI uses a pointer and a copy using the
-                // byval attribute, for which LLVM does the deref itself, so we must not add it.
-                // Starting with D31439 in LLVM 5, it *always* does the deref itself.
-                let mut variable_access = VariableAccess::DirectVariable {
+                // byval attribute, for which LLVM always does the deref itself,
+                // so we must not add it.
+                let variable_access = VariableAccess::DirectVariable {
                     alloca: place.llval
                 };
-                if unsafe { llvm::LLVMRustVersionMajor() < 5 } {
-                    if let PassMode::Indirect(ref attrs) = arg.mode {
-                        if !attrs.contains(ArgAttribute::ByVal) {
-                            variable_access = VariableAccess::IndirectVariable {
-                                alloca: place.llval,
-                                address_operations: &deref_op,
-                            };
-                        }
-                    }
-                }
 
                 declare_local(
                     bx,
index 3d3a4400bd8108abca11973e5693f839dbc5fc32..5d36eef99af2d393c8124c84a2fb31b49dd0552b 100644 (file)
@@ -18,7 +18,7 @@
 use rustc_data_structures::sync::Lrc;
 
 use base;
-use common::{self, CodegenCx, C_null, C_undef, C_usize};
+use common::{CodegenCx, C_null, C_undef, C_usize};
 use builder::{Builder, MemFlags};
 use value::Value;
 use type_of::LayoutLlvmExt;
@@ -128,13 +128,13 @@ pub fn from_const(bx: &Builder<'a, 'tcx>,
                     bx.cx,
                     a,
                     a_scalar,
-                    layout.scalar_pair_element_llvm_type(bx.cx, 0),
+                    layout.scalar_pair_element_llvm_type(bx.cx, 0, true),
                 );
                 let b_llval = scalar_to_llvm(
                     bx.cx,
                     b,
                     b_scalar,
-                    layout.scalar_pair_element_llvm_type(bx.cx, 1),
+                    layout.scalar_pair_element_llvm_type(bx.cx, 1, true),
                 );
                 OperandValue::Pair(a_llval, b_llval)
             },
@@ -193,8 +193,8 @@ pub fn immediate_or_packed_pair(self, bx: &Builder<'a, 'tcx>) -> ValueRef {
                    self, llty);
             // Reconstruct the immediate aggregate.
             let mut llpair = C_undef(llty);
-            llpair = bx.insert_value(llpair, a, 0);
-            llpair = bx.insert_value(llpair, b, 1);
+            llpair = bx.insert_value(llpair, base::from_immediate(bx, a), 0);
+            llpair = bx.insert_value(llpair, base::from_immediate(bx, b), 1);
             llpair
         } else {
             self.immediate()
@@ -206,13 +206,14 @@ pub fn from_immediate_or_packed_pair(bx: &Builder<'a, 'tcx>,
                                          llval: ValueRef,
                                          layout: TyLayout<'tcx>)
                                          -> OperandRef<'tcx> {
-        let val = if layout.is_llvm_scalar_pair() {
+        let val = if let layout::Abi::ScalarPair(ref a, ref b) = layout.abi {
             debug!("Operand::from_immediate_or_packed_pair: unpacking {:?} @ {:?}",
                     llval, layout);
 
             // Deconstruct the immediate aggregate.
-            OperandValue::Pair(bx.extract_value(llval, 0),
-                               bx.extract_value(llval, 1))
+            let a_llval = base::to_immediate_scalar(bx, bx.extract_value(llval, 0), a);
+            let b_llval = base::to_immediate_scalar(bx, bx.extract_value(llval, 1), b);
+            OperandValue::Pair(a_llval, b_llval)
         } else {
             OperandValue::Immediate(llval)
         };
@@ -264,8 +265,8 @@ pub fn extract_field(&self, bx: &Builder<'a, 'tcx>, i: usize) -> OperandRef<'tcx
                 *llval = bx.bitcast(*llval, field.immediate_llvm_type(bx.cx));
             }
             OperandValue::Pair(ref mut a, ref mut b) => {
-                *a = bx.bitcast(*a, field.scalar_pair_element_llvm_type(bx.cx, 0));
-                *b = bx.bitcast(*b, field.scalar_pair_element_llvm_type(bx.cx, 1));
+                *a = bx.bitcast(*a, field.scalar_pair_element_llvm_type(bx.cx, 0, true));
+                *b = bx.bitcast(*b, field.scalar_pair_element_llvm_type(bx.cx, 1, true));
             }
             OperandValue::Ref(..) => bug!()
         }
@@ -308,11 +309,7 @@ fn store_with_flags(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>, flags: M
             }
             OperandValue::Pair(a, b) => {
                 for (i, &x) in [a, b].iter().enumerate() {
-                    let mut llptr = bx.struct_gep(dest.llval, i as u64);
-                    // Make sure to always store i1 as i8.
-                    if common::val_ty(x) == Type::i1(bx.cx) {
-                        llptr = bx.pointercast(llptr, Type::i8p(bx.cx));
-                    }
+                    let llptr = bx.struct_gep(dest.llval, i as u64);
                     let val = base::from_immediate(bx, x);
                     bx.store_with_flags(val, llptr, dest.align, flags);
                 }
index 2a1e3980adbcfaa58ee83880d10818127ce5d8cb..e7f9457a6a1cac2ed4868790a3b81f736e9fd55a 100644 (file)
@@ -127,11 +127,7 @@ pub fn load(&self, bx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> {
             OperandValue::Immediate(base::to_immediate(bx, llval, self.layout))
         } else if let layout::Abi::ScalarPair(ref a, ref b) = self.layout.abi {
             let load = |i, scalar: &layout::Scalar| {
-                let mut llptr = bx.struct_gep(self.llval, i as u64);
-                // Make sure to always load i1 as i8.
-                if scalar.is_bool() {
-                    llptr = bx.pointercast(llptr, Type::i8p(bx.cx));
-                }
+                let llptr = bx.struct_gep(self.llval, i as u64);
                 let load = bx.load(llptr, self.align);
                 scalar_load_metadata(load, scalar);
                 if scalar.is_bool() {
index 0fd81c6074e48e87012ee895350119966bc5ff29..2e81fc16a58388d935024ac40d25b4ff1cb59b32 100644 (file)
@@ -232,7 +232,7 @@ pub fn codegen_rvalue_operand(&mut self,
                                 // HACK(eddyb) have to bitcast pointers
                                 // until LLVM removes pointee types.
                                 let lldata = bx.pointercast(lldata,
-                                    cast.scalar_pair_element_llvm_type(bx.cx, 0));
+                                    cast.scalar_pair_element_llvm_type(bx.cx, 0, true));
                                 OperandValue::Pair(lldata, llextra)
                             }
                             OperandValue::Immediate(lldata) => {
@@ -251,7 +251,7 @@ pub fn codegen_rvalue_operand(&mut self,
                         if let OperandValue::Pair(data_ptr, meta) = operand.val {
                             if cast.is_llvm_scalar_pair() {
                                 let data_cast = bx.pointercast(data_ptr,
-                                    cast.scalar_pair_element_llvm_type(bx.cx, 0));
+                                    cast.scalar_pair_element_llvm_type(bx.cx, 0, true));
                                 OperandValue::Pair(data_cast, meta)
                             } else { // cast to thin-ptr
                                 // Cast of fat-ptr to thin-ptr is an extraction of data-ptr and
index c4a23ac653ca009a57c8458ce009f7f2b0426352..e142a7d9c1ce7b0183df55cf4936bedb37c87ea2 100644 (file)
@@ -33,7 +33,6 @@
 
 pub use rustc::mir::mono::MonoItem;
 
-pub use rustc_mir::monomorphize::item::*;
 pub use rustc_mir::monomorphize::item::MonoItemExt as BaseMonoItemExt;
 
 pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
@@ -67,6 +66,9 @@ fn define(&self, cx: &CodegenCx<'a, 'tcx>) {
                     span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type")
                 }
             }
+            MonoItem::CustomSection(def_id) => {
+                base::define_custom_section(cx, def_id);
+            }
             MonoItem::Fn(instance) => {
                 base::codegen_instance(&cx, instance);
             }
@@ -98,6 +100,7 @@ fn predefine(&self,
             MonoItem::Fn(instance) => {
                 predefine_fn(cx, instance, linkage, visibility, &symbol_name);
             }
+            MonoItem::CustomSection(..) => {}
             MonoItem::GlobalAsm(..) => {}
         }
 
@@ -117,6 +120,9 @@ fn to_raw_string(&self) -> String {
             MonoItem::Static(id) => {
                 format!("Static({:?})", id)
             }
+            MonoItem::CustomSection(id) => {
+                format!("CustomSection({:?})", id)
+            }
             MonoItem::GlobalAsm(id) => {
                 format!("GlobalAsm({:?})", id)
             }
diff --git a/src/librustc_codegen_llvm/time_graph.rs b/src/librustc_codegen_llvm/time_graph.rs
deleted file mode 100644 (file)
index a850268..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-// 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::HashMap;
-use std::fs::File;
-use std::io::prelude::*;
-use std::marker::PhantomData;
-use std::mem;
-use std::sync::{Arc, Mutex};
-use std::time::Instant;
-
-const OUTPUT_WIDTH_IN_PX: u64 = 1000;
-const TIME_LINE_HEIGHT_IN_PX: u64 = 20;
-const TIME_LINE_HEIGHT_STRIDE_IN_PX: usize = 30;
-
-#[derive(Clone)]
-struct Timing {
-    start: Instant,
-    end: Instant,
-    work_package_kind: WorkPackageKind,
-    name: String,
-    events: Vec<(String, Instant)>,
-}
-
-#[derive(Clone, Copy, Hash, Eq, PartialEq, Debug)]
-pub struct TimelineId(pub usize);
-
-#[derive(Clone)]
-struct PerThread {
-    timings: Vec<Timing>,
-    open_work_package: Option<(Instant, WorkPackageKind, String)>,
-}
-
-#[derive(Clone)]
-pub struct TimeGraph {
-    data: Arc<Mutex<HashMap<TimelineId, PerThread>>>,
-}
-
-#[derive(Clone, Copy)]
-pub struct WorkPackageKind(pub &'static [&'static str]);
-
-pub struct Timeline {
-    token: Option<RaiiToken>,
-}
-
-struct RaiiToken {
-    graph: TimeGraph,
-    timeline: TimelineId,
-    events: Vec<(String, Instant)>,
-    // The token must not be Send:
-    _marker: PhantomData<*const ()>
-}
-
-
-impl Drop for RaiiToken {
-    fn drop(&mut self) {
-        self.graph.end(self.timeline, mem::replace(&mut self.events, Vec::new()));
-    }
-}
-
-impl TimeGraph {
-    pub fn new() -> TimeGraph {
-        TimeGraph {
-            data: Arc::new(Mutex::new(HashMap::new()))
-        }
-    }
-
-    pub fn start(&self,
-                 timeline: TimelineId,
-                 work_package_kind: WorkPackageKind,
-                 name: &str) -> Timeline {
-        {
-            let mut table = self.data.lock().unwrap();
-
-            let data = table.entry(timeline).or_insert(PerThread {
-                timings: Vec::new(),
-                open_work_package: None,
-            });
-
-            assert!(data.open_work_package.is_none());
-            data.open_work_package = Some((Instant::now(), work_package_kind, name.to_string()));
-        }
-
-        Timeline {
-            token: Some(RaiiToken {
-                graph: self.clone(),
-                timeline,
-                events: Vec::new(),
-                _marker: PhantomData,
-            }),
-        }
-    }
-
-    fn end(&self, timeline: TimelineId, events: Vec<(String, Instant)>) {
-        let end = Instant::now();
-
-        let mut table = self.data.lock().unwrap();
-        let data = table.get_mut(&timeline).unwrap();
-
-        if let Some((start, work_package_kind, name)) = data.open_work_package.take() {
-            data.timings.push(Timing {
-                start,
-                end,
-                work_package_kind,
-                name,
-                events,
-            });
-        } else {
-            bug!("end timing without start?")
-        }
-    }
-
-    pub fn dump(&self, output_filename: &str) {
-        let table = self.data.lock().unwrap();
-
-        for data in table.values() {
-            assert!(data.open_work_package.is_none());
-        }
-
-        let mut threads: Vec<PerThread> =
-            table.values().map(|data| data.clone()).collect();
-
-        threads.sort_by_key(|timeline| timeline.timings[0].start);
-
-        let earliest_instant = threads[0].timings[0].start;
-        let latest_instant = threads.iter()
-                                       .map(|timeline| timeline.timings
-                                                               .last()
-                                                               .unwrap()
-                                                               .end)
-                                       .max()
-                                       .unwrap();
-        let max_distance = distance(earliest_instant, latest_instant);
-
-        let mut file = File::create(format!("{}.html", output_filename)).unwrap();
-
-        writeln!(file, "
-            <html>
-            <head>
-                <style>
-                    #threads a {{
-                        position: absolute;
-                        overflow: hidden;
-                    }}
-                    #threads {{
-                        height: {total_height}px;
-                        width: {width}px;
-                    }}
-
-                    .timeline {{
-                        display: none;
-                        width: {width}px;
-                        position: relative;
-                    }}
-
-                    .timeline:target {{
-                        display: block;
-                    }}
-
-                    .event {{
-                        position: absolute;
-                    }}
-                </style>
-            </head>
-            <body>
-                <div id='threads'>
-        ",
-            total_height = threads.len() * TIME_LINE_HEIGHT_STRIDE_IN_PX,
-            width = OUTPUT_WIDTH_IN_PX,
-        ).unwrap();
-
-        let mut color = 0;
-        for (line_index, thread) in threads.iter().enumerate() {
-            let line_top = line_index * TIME_LINE_HEIGHT_STRIDE_IN_PX;
-
-            for span in &thread.timings {
-                let start = distance(earliest_instant, span.start);
-                let end = distance(earliest_instant, span.end);
-
-                let start = normalize(start, max_distance, OUTPUT_WIDTH_IN_PX);
-                let end = normalize(end, max_distance, OUTPUT_WIDTH_IN_PX);
-
-                let colors = span.work_package_kind.0;
-
-                writeln!(file, "<a href='#timing{}'
-                                   style='top:{}px; \
-                                          left:{}px; \
-                                          width:{}px; \
-                                          height:{}px; \
-                                          background:{};'>{}</a>",
-                    color,
-                    line_top,
-                    start,
-                    end - start,
-                    TIME_LINE_HEIGHT_IN_PX,
-                    colors[color % colors.len()],
-                    span.name,
-                    ).unwrap();
-
-                color += 1;
-            }
-        }
-
-        writeln!(file, "
-            </div>
-        ").unwrap();
-
-        let mut idx = 0;
-        for thread in threads.iter() {
-            for timing in &thread.timings {
-                let colors = timing.work_package_kind.0;
-                let height = TIME_LINE_HEIGHT_STRIDE_IN_PX * timing.events.len();
-                writeln!(file, "<div class='timeline'
-                                     id='timing{}'
-                                     style='background:{};height:{}px;'>",
-                         idx,
-                         colors[idx % colors.len()],
-                         height).unwrap();
-                idx += 1;
-                let max = distance(timing.start, timing.end);
-                for (i, &(ref event, time)) in timing.events.iter().enumerate() {
-                    let i = i as u64;
-                    let time = distance(timing.start, time);
-                    let at = normalize(time, max, OUTPUT_WIDTH_IN_PX);
-                    writeln!(file, "<span class='event'
-                                          style='left:{}px;\
-                                                 top:{}px;'>{}</span>",
-                             at,
-                             TIME_LINE_HEIGHT_IN_PX * i,
-                             event).unwrap();
-                }
-                writeln!(file, "</div>").unwrap();
-            }
-        }
-
-        writeln!(file, "
-            </body>
-            </html>
-        ").unwrap();
-    }
-}
-
-impl Timeline {
-    pub fn noop() -> Timeline {
-        Timeline { token: None }
-    }
-
-    /// Record an event which happened at this moment on this timeline.
-    ///
-    /// Events are displayed in the eventual HTML output where you can click on
-    /// a particular timeline and it'll expand to all of the events that
-    /// happened on that timeline. This can then be used to drill into a
-    /// particular timeline and see what events are happening and taking the
-    /// most time.
-    pub fn record(&mut self, name: &str) {
-        if let Some(ref mut token) = self.token {
-            token.events.push((name.to_string(), Instant::now()));
-        }
-    }
-}
-
-fn distance(zero: Instant, x: Instant) -> u64 {
-
-    let duration = x.duration_since(zero);
-    (duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64) // / div
-}
-
-fn normalize(distance: u64, max: u64, max_pixels: u64) -> u64 {
-    (max_pixels * distance) / max
-}
-
index 88b75ff9c09439cbfa68c1241024ae1c06db99b2..4728d7717a1e1d3f874ee69660a8c9c357c848db 100644 (file)
@@ -16,7 +16,7 @@
 use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout};
 use rustc_target::spec::PanicStrategy;
 use rustc_target::abi::FloatTy;
-use mono_item::DefPathBasedNames;
+use rustc_mir::monomorphize::item::DefPathBasedNames;
 use type_::Type;
 
 use std::fmt::Write;
@@ -47,8 +47,8 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
         }
         layout::Abi::ScalarPair(..) => {
             return Type::struct_(cx, &[
-                layout.scalar_pair_element_llvm_type(cx, 0),
-                layout.scalar_pair_element_llvm_type(cx, 1),
+                layout.scalar_pair_element_llvm_type(cx, 0, false),
+                layout.scalar_pair_element_llvm_type(cx, 1, false),
             ], false);
         }
         layout::Abi::Uninhabited |
@@ -206,7 +206,7 @@ pub trait LayoutLlvmExt<'tcx> {
     fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
                                scalar: &layout::Scalar, offset: Size) -> Type;
     fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
-                                         index: usize) -> Type;
+                                         index: usize, immediate: bool) -> Type;
     fn llvm_field_index(&self, index: usize) -> u64;
     fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size)
                            -> Option<PointeeInfo>;
@@ -340,7 +340,7 @@ fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
     }
 
     fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
-                                         index: usize) -> Type {
+                                         index: usize, immediate: bool) -> Type {
         // HACK(eddyb) special-case fat pointers until LLVM removes
         // pointee types, to avoid bitcasting every `OperandRef::deref`.
         match self.ty.sty {
@@ -350,7 +350,7 @@ fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
             }
             ty::TyAdt(def, _) if def.is_box() => {
                 let ptr_ty = cx.tcx.mk_mut_ptr(self.ty.boxed_ty());
-                return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index);
+                return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index, immediate);
             }
             _ => {}
         }
@@ -361,14 +361,13 @@ fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
         };
         let scalar = [a, b][index];
 
-        // Make sure to return the same type `immediate_llvm_type` would,
-        // to avoid dealing with two types and the associated conversions.
-        // This means that `(bool, bool)` is represented as `{i1, i1}`,
-        // both in memory and as an immediate, while `bool` is typically
-        // `i8` in memory and only `i1` when immediate. While we need to
-        // load/store `bool` as `i8` to avoid crippling LLVM optimizations,
-        // `i1` in a LLVM aggregate is valid and mostly equivalent to `i8`.
-        if scalar.is_bool() {
+        // Make sure to return the same type `immediate_llvm_type` would when
+        // dealing with an immediate pair.  This means that `(bool, bool)` is
+        // effectively represented as `{i8, i8}` in memory and two `i1`s as an
+        // immediate, just like `bool` is typically `i8` in memory and only `i1`
+        // when immediate.  We need to load/store `bool` as `i8` to avoid
+        // crippling LLVM optimizations or triggering other LLVM bugs with `i1`.
+        if immediate && scalar.is_bool() {
             return Type::i1(cx);
         }
 
index 690fb260390e52b90dcb0be4cd7c8a4c2e137946..30f533285ddfdc809e3f54a7a323a8120541578e 100644 (file)
@@ -10,7 +10,6 @@ crate-type = ["dylib"]
 test = false
 
 [dependencies]
-ar = "0.3.0"
 flate2 = "1.0"
 log = "0.4"
 
index 8ba6f30cf16e587b7cb8441f0af808cde34c9699..3f230dd5d451b5545f241a6d8a9d5ce3ce0a69e5 100644 (file)
 #![feature(box_syntax)]
 
 use std::any::Any;
-use std::io::prelude::*;
-use std::io::{self, Cursor};
+use std::io::{self, Write};
 use std::fs::File;
 use std::path::Path;
-use std::sync::mpsc;
+use std::sync::{mpsc, Arc};
 
 use rustc_data_structures::owning_ref::OwningRef;
 use rustc_data_structures::sync::Lrc;
-use ar::{Archive, Builder, Header};
 use flate2::Compression;
 use flate2::write::DeflateEncoder;
 
@@ -58,112 +56,44 @@ fn print_passes(&self) {}
     fn print_version(&self) {}
     fn diagnostics(&self) -> &[(&'static str, &'static str)] { &[] }
 
-    fn metadata_loader(&self) -> Box<MetadataLoader + Sync>;
+    fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync>;
     fn provide(&self, _providers: &mut Providers);
     fn provide_extern(&self, _providers: &mut Providers);
     fn codegen_crate<'a, 'tcx>(
         &self,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
-        rx: mpsc::Receiver<Box<Any + Send>>
-    ) -> Box<Any>;
+        rx: mpsc::Receiver<Box<dyn Any + Send>>
+    ) -> Box<dyn Any>;
 
-    /// This is called on the returned `Box<Any>` from `codegen_backend`
+    /// This is called on the returned `Box<dyn Any>` from `codegen_backend`
     ///
     /// # Panics
     ///
-    /// Panics when the passed `Box<Any>` was not returned by `codegen_backend`.
+    /// Panics when the passed `Box<dyn Any>` was not returned by `codegen_backend`.
     fn join_codegen_and_link(
         &self,
-        ongoing_codegen: Box<Any>,
+        ongoing_codegen: Box<dyn Any>,
         sess: &Session,
         dep_graph: &DepGraph,
         outputs: &OutputFilenames,
     ) -> Result<(), CompileIncomplete>;
 }
 
-pub struct DummyCodegenBackend;
-
-impl CodegenBackend for DummyCodegenBackend {
-    fn metadata_loader(&self) -> Box<MetadataLoader + Sync> {
-        box DummyMetadataLoader(())
-    }
-
-    fn provide(&self, _providers: &mut Providers) {
-        bug!("DummyCodegenBackend::provide");
-    }
-
-    fn provide_extern(&self, _providers: &mut Providers) {
-        bug!("DummyCodegenBackend::provide_extern");
-    }
-
-    fn codegen_crate<'a, 'tcx>(
-        &self,
-        _tcx: TyCtxt<'a, 'tcx, 'tcx>,
-        _rx: mpsc::Receiver<Box<Any + Send>>
-    ) -> Box<Any> {
-        bug!("DummyCodegenBackend::codegen_backend");
-    }
-
-    fn join_codegen_and_link(
-        &self,
-        _ongoing_codegen: Box<Any>,
-        _sess: &Session,
-        _dep_graph: &DepGraph,
-        _outputs: &OutputFilenames,
-    ) -> Result<(), CompileIncomplete> {
-        bug!("DummyCodegenBackend::join_codegen_and_link");
-    }
-}
-
-pub struct DummyMetadataLoader(());
-
-impl MetadataLoader for DummyMetadataLoader {
-    fn get_rlib_metadata(
-        &self,
-        _target: &Target,
-        _filename: &Path
-    ) -> Result<MetadataRef, String> {
-        bug!("DummyMetadataLoader::get_rlib_metadata");
-    }
-
-    fn get_dylib_metadata(
-        &self,
-        _target: &Target,
-        _filename: &Path
-    ) -> Result<MetadataRef, String> {
-        bug!("DummyMetadataLoader::get_dylib_metadata");
-    }
-}
-
 pub struct NoLlvmMetadataLoader;
 
 impl MetadataLoader for NoLlvmMetadataLoader {
     fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
-        let file = File::open(filename)
+        let mut file = File::open(filename)
             .map_err(|e| format!("metadata file open err: {:?}", e))?;
-        let mut archive = Archive::new(file);
 
-        while let Some(entry_result) = archive.next_entry() {
-            let mut entry = entry_result
-                .map_err(|e| format!("metadata section read err: {:?}", e))?;
-            if entry.header().identifier() == "rust.metadata.bin" {
-                let mut buf = Vec::new();
-                io::copy(&mut entry, &mut buf).unwrap();
-                let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
-                return Ok(rustc_erase_owner!(buf.map_owner_box()));
-            }
-        }
-
-        Err("Couldn't find metadata section".to_string())
+        let mut buf = Vec::new();
+        io::copy(&mut file, &mut buf).unwrap();
+        let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
+        return Ok(rustc_erase_owner!(buf.map_owner_box()));
     }
 
-    fn get_dylib_metadata(
-        &self,
-        _target: &Target,
-        _filename: &Path,
-    ) -> Result<MetadataRef, String> {
-        // FIXME: Support reading dylibs from llvm enabled rustc
-        self.get_rlib_metadata(_target, _filename)
+    fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String> {
+        self.get_rlib_metadata(target, filename)
     }
 }
 
@@ -175,7 +105,7 @@ pub struct OngoingCodegen {
 }
 
 impl MetadataOnlyCodegenBackend {
-    pub fn new() -> Box<CodegenBackend> {
+    pub fn new() -> Box<dyn CodegenBackend> {
         box MetadataOnlyCodegenBackend(())
     }
 }
@@ -195,7 +125,7 @@ fn init(&self, sess: &Session) {
         }
     }
 
-    fn metadata_loader(&self) -> Box<MetadataLoader + Sync> {
+    fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
         box NoLlvmMetadataLoader
     }
 
@@ -205,14 +135,18 @@ fn provide(&self, providers: &mut Providers) {
         providers.target_features_whitelist = |_tcx, _cnum| {
             Lrc::new(FxHashMap()) // Just a dummy
         };
+        providers.is_reachable_non_generic = |_tcx, _defid| true;
+        providers.exported_symbols = |_tcx, _crate| Arc::new(Vec::new());
+    }
+    fn provide_extern(&self, providers: &mut Providers) {
+        providers.is_reachable_non_generic = |_tcx, _defid| true;
     }
-    fn provide_extern(&self, _providers: &mut Providers) {}
 
     fn codegen_crate<'a, 'tcx>(
         &self,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
-        _rx: mpsc::Receiver<Box<Any + Send>>
-    ) -> Box<Any> {
+        _rx: mpsc::Receiver<Box<dyn Any + Send>>
+    ) -> Box<dyn Any> {
         use rustc_mir::monomorphize::item::MonoItem;
 
         ::check_for_rustc_errors_attr(tcx);
@@ -225,7 +159,8 @@ fn codegen_crate<'a, 'tcx>(
                 collector::MonoItemCollectionMode::Eager
             ).0.iter()
         );
-        ::rustc::middle::dependency_format::calculate(tcx);
+        // FIXME: Fix this
+        // ::rustc::middle::dependency_format::calculate(tcx);
         let _ = tcx.link_args(LOCAL_CRATE);
         let _ = tcx.native_libraries(LOCAL_CRATE);
         for mono_item in
@@ -258,13 +193,13 @@ fn codegen_crate<'a, 'tcx>(
 
     fn join_codegen_and_link(
         &self,
-        ongoing_codegen: Box<Any>,
+        ongoing_codegen: Box<dyn Any>,
         sess: &Session,
         _dep_graph: &DepGraph,
         outputs: &OutputFilenames,
     ) -> Result<(), CompileIncomplete> {
         let ongoing_codegen = ongoing_codegen.downcast::<OngoingCodegen>()
-            .expect("Expected MetadataOnlyCodegenBackend's OngoingCodegen, found Box<Any>");
+            .expect("Expected MetadataOnlyCodegenBackend's OngoingCodegen, found Box<dyn Any>");
         for &crate_type in sess.opts.crate_types.iter() {
             if crate_type != CrateType::CrateTypeRlib && crate_type != CrateType::CrateTypeDylib {
                 continue;
@@ -280,9 +215,8 @@ fn join_codegen_and_link(
             } else {
                 &ongoing_codegen.metadata.raw_data
             };
-            let mut builder = Builder::new(File::create(&output_name).unwrap());
-            let header = Header::new("rust.metadata.bin".to_string(), metadata.len() as u64);
-            builder.append(&header, Cursor::new(metadata)).unwrap();
+            let mut file = File::create(&output_name).unwrap();
+            file.write_all(metadata).unwrap();
         }
 
         sess.abort_if_errors();
index d09e8f4845e5edf4ecd2a7b2bba3d2f4e2afaab9..e9031007a4eedbdce4b6b6d50035c925c16adbc6 100644 (file)
 #![feature(box_syntax)]
 #![feature(custom_attribute)]
 #![allow(unused_attributes)]
+#![deny(bare_trait_objects)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 
 #![recursion_limit="256"]
 
-extern crate ar;
 extern crate flate2;
 #[macro_use]
 extern crate log;
@@ -39,8 +39,6 @@
 extern crate syntax_pos;
 #[macro_use] extern crate rustc_data_structures;
 
-pub extern crate rustc as __rustc;
-
 use rustc::ty::TyCtxt;
 
 pub mod link;
index e4d0bc596cba6fb11a41fda148c4939771466377..2cca31f70a092ce82fa07146bad432148d121e10 100644 (file)
@@ -16,6 +16,8 @@
 //!
 //! This API is completely unstable and subject to change.
 
+#![deny(bare_trait_objects)]
+
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://www.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
index aa113fac9fb7dff28baa92dfba7bfe5f0b80b50b..02640a71010e2daf5a7d501987a839451be0203f 100644 (file)
@@ -1046,7 +1046,7 @@ unsafe impl<O, T: ?Sized> Send for OwningRefMut<O, T>
 unsafe impl<O, T: ?Sized> Sync for OwningRefMut<O, T>
     where O: Sync, for<'a> (&'a mut T): Sync {}
 
-impl Debug for Erased {
+impl Debug for dyn Erased {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "<Erased>",)
     }
@@ -1166,35 +1166,35 @@ unsafe fn to_handle_mut(x: *const Self) -> Self::HandleMut { (*x).borrow_mut() }
 pub type RwLockWriteGuardRefMut<'a, T, U = T> = OwningRef<RwLockWriteGuard<'a, T>, U>;
 
 unsafe impl<'a, T: 'a> IntoErased<'a> for Box<T> {
-    type Erased = Box<Erased + 'a>;
+    type Erased = Box<dyn Erased + 'a>;
     fn into_erased(self) -> Self::Erased {
         self
     }
 }
 unsafe impl<'a, T: 'a> IntoErased<'a> for Rc<T> {
-    type Erased = Rc<Erased + 'a>;
+    type Erased = Rc<dyn Erased + 'a>;
     fn into_erased(self) -> Self::Erased {
         self
     }
 }
 unsafe impl<'a, T: 'a> IntoErased<'a> for Arc<T> {
-    type Erased = Arc<Erased + 'a>;
+    type Erased = Arc<dyn Erased + 'a>;
     fn into_erased(self) -> Self::Erased {
         self
     }
 }
 
 unsafe impl<'a, T: Send + 'a> IntoErasedSend<'a> for Box<T> {
-    type Erased = Box<Erased + Send + 'a>;
+    type Erased = Box<dyn Erased + Send + 'a>;
     fn into_erased_send(self) -> Self::Erased {
         self
     }
 }
 
 unsafe impl<'a, T: Send + 'a> IntoErasedSendSync<'a> for Box<T> {
-    type Erased = Box<Erased + Sync + Send + 'a>;
+    type Erased = Box<dyn Erased + Sync + Send + 'a>;
     fn into_erased_send_sync(self) -> Self::Erased {
-        let result: Box<Erased + Send + 'a> = self;
+        let result: Box<dyn Erased + Send + 'a> = self;
         // This is safe since Erased can always implement Sync
         // Only the destructor is available and it takes &mut self
         unsafe {
@@ -1204,21 +1204,21 @@ fn into_erased_send_sync(self) -> Self::Erased {
 }
 
 unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Arc<T> {
-    type Erased = Arc<Erased + Send + Sync + 'a>;
+    type Erased = Arc<dyn Erased + Send + Sync + 'a>;
     fn into_erased_send_sync(self) -> Self::Erased {
         self
     }
 }
 
 /// Typedef of a owning reference that uses an erased `Box` as the owner.
-pub type ErasedBoxRef<U> = OwningRef<Box<Erased>, U>;
+pub type ErasedBoxRef<U> = OwningRef<Box<dyn Erased>, U>;
 /// Typedef of a owning reference that uses an erased `Rc` as the owner.
-pub type ErasedRcRef<U> = OwningRef<Rc<Erased>, U>;
+pub type ErasedRcRef<U> = OwningRef<Rc<dyn Erased>, U>;
 /// Typedef of a owning reference that uses an erased `Arc` as the owner.
-pub type ErasedArcRef<U> = OwningRef<Arc<Erased>, U>;
+pub type ErasedArcRef<U> = OwningRef<Arc<dyn Erased>, U>;
 
 /// Typedef of a mutable owning reference that uses an erased `Box` as the owner.
-pub type ErasedBoxRefMut<U> = OwningRefMut<Box<Erased>, U>;
+pub type ErasedBoxRefMut<U> = OwningRefMut<Box<dyn Erased>, U>;
 
 #[cfg(test)]
 mod tests {
@@ -1443,8 +1443,8 @@ fn total_erase() {
             let c: OwningRef<Rc<Vec<u8>>, [u8]> = unsafe {a.map_owner(Rc::new)};
             let d: OwningRef<Rc<Box<[u8]>>, [u8]> = unsafe {b.map_owner(Rc::new)};
 
-            let e: OwningRef<Rc<Erased>, [u8]> = c.erase_owner();
-            let f: OwningRef<Rc<Erased>, [u8]> = d.erase_owner();
+            let e: OwningRef<Rc<dyn Erased>, [u8]> = c.erase_owner();
+            let f: OwningRef<Rc<dyn Erased>, [u8]> = d.erase_owner();
 
             let _g = e.clone();
             let _h = f.clone();
@@ -1460,8 +1460,8 @@ fn total_erase_box() {
             let c: OwningRef<Box<Vec<u8>>, [u8]> = a.map_owner_box();
             let d: OwningRef<Box<Box<[u8]>>, [u8]> = b.map_owner_box();
 
-            let _e: OwningRef<Box<Erased>, [u8]> = c.erase_owner();
-            let _f: OwningRef<Box<Erased>, [u8]> = d.erase_owner();
+            let _e: OwningRef<Box<dyn Erased>, [u8]> = c.erase_owner();
+            let _f: OwningRef<Box<dyn Erased>, [u8]> = d.erase_owner();
         }
 
         #[test]
@@ -1469,7 +1469,7 @@ fn try_map1() {
             use std::any::Any;
 
             let x = Box::new(123_i32);
-            let y: Box<Any> = x;
+            let y: Box<dyn Any> = x;
 
             OwningRef::new(y).try_map(|x| x.downcast_ref::<i32>().ok_or(())).is_ok();
         }
@@ -1479,7 +1479,7 @@ fn try_map2() {
             use std::any::Any;
 
             let x = Box::new(123_i32);
-            let y: Box<Any> = x;
+            let y: Box<dyn Any> = x;
 
             OwningRef::new(y).try_map(|x| x.downcast_ref::<i32>().ok_or(())).is_err();
         }
@@ -1843,8 +1843,8 @@ fn total_erase() {
             let c: OwningRefMut<Box<Vec<u8>>, [u8]> = unsafe {a.map_owner(Box::new)};
             let d: OwningRefMut<Box<Box<[u8]>>, [u8]> = unsafe {b.map_owner(Box::new)};
 
-            let _e: OwningRefMut<Box<Erased>, [u8]> = c.erase_owner();
-            let _f: OwningRefMut<Box<Erased>, [u8]> = d.erase_owner();
+            let _e: OwningRefMut<Box<dyn Erased>, [u8]> = c.erase_owner();
+            let _f: OwningRefMut<Box<dyn Erased>, [u8]> = d.erase_owner();
         }
 
         #[test]
@@ -1857,8 +1857,8 @@ fn total_erase_box() {
             let c: OwningRefMut<Box<Vec<u8>>, [u8]> = a.map_owner_box();
             let d: OwningRefMut<Box<Box<[u8]>>, [u8]> = b.map_owner_box();
 
-            let _e: OwningRefMut<Box<Erased>, [u8]> = c.erase_owner();
-            let _f: OwningRefMut<Box<Erased>, [u8]> = d.erase_owner();
+            let _e: OwningRefMut<Box<dyn Erased>, [u8]> = c.erase_owner();
+            let _f: OwningRefMut<Box<dyn Erased>, [u8]> = d.erase_owner();
         }
 
         #[test]
@@ -1866,7 +1866,7 @@ fn try_map1() {
             use std::any::Any;
 
             let x = Box::new(123_i32);
-            let y: Box<Any> = x;
+            let y: Box<dyn Any> = x;
 
             OwningRefMut::new(y).try_map_mut(|x| x.downcast_mut::<i32>().ok_or(())).is_ok();
         }
@@ -1876,7 +1876,7 @@ fn try_map2() {
             use std::any::Any;
 
             let x = Box::new(123_i32);
-            let y: Box<Any> = x;
+            let y: Box<dyn Any> = x;
 
             OwningRefMut::new(y).try_map_mut(|x| x.downcast_mut::<i32>().ok_or(())).is_err();
         }
@@ -1886,7 +1886,7 @@ fn try_map3() {
             use std::any::Any;
 
             let x = Box::new(123_i32);
-            let y: Box<Any> = x;
+            let y: Box<dyn Any> = x;
 
             OwningRefMut::new(y).try_map(|x| x.downcast_ref::<i32>().ok_or(())).is_ok();
         }
@@ -1896,7 +1896,7 @@ fn try_map4() {
             use std::any::Any;
 
             let x = Box::new(123_i32);
-            let y: Box<Any> = x;
+            let y: Box<dyn Any> = x;
 
             OwningRefMut::new(y).try_map(|x| x.downcast_ref::<i32>().ok_or(())).is_err();
         }
index b82fe3ec60c3b6fcc09bb7c72129072dfcafc413..d4c6b1c2ced812fc4ddce1fedc8988180ec8665d 100644 (file)
@@ -88,7 +88,7 @@ pub fn par_iter<T: IntoIterator>(t: T) -> T::IntoIter {
             t.into_iter()
         }
 
-        pub type MetadataRef = OwningRef<Box<Erased>, [u8]>;
+        pub type MetadataRef = OwningRef<Box<dyn Erased>, [u8]>;
 
         pub use std::rc::Rc as Lrc;
         pub use std::rc::Weak as Weak;
@@ -268,7 +268,7 @@ pub fn par_iter<T: IntoParallelIterator>(t: T) -> T::Iter {
             t.into_par_iter()
         }
 
-        pub type MetadataRef = OwningRef<Box<Erased + Send + Sync>, [u8]>;
+        pub type MetadataRef = OwningRef<Box<dyn Erased + Send + Sync>, [u8]>;
 
         /// This makes locks panic if they are already held.
         /// It is only useful when you are running in a single thread
index 5b75912c18f50dac3973bcff7df157ac66213bee..7a020f331e50b1119c8e3830c56a2edca361ce3b 100644 (file)
@@ -37,5 +37,3 @@ serialize = { path = "../libserialize" }
 syntax = { path = "../libsyntax" }
 syntax_ext = { path = "../libsyntax_ext" }
 syntax_pos = { path = "../libsyntax_pos" }
-
-ar = "0.3.0"
index feeac9d938b6a4b01a352293d6fa54b0a355d2b6..96e9616699d3717a8ba86adfb524547f4307927c 100644 (file)
@@ -1279,7 +1279,11 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(
                 middle::liveness::check_crate(tcx)
             });
 
-            time(sess, "borrow checking", || borrowck::check_crate(tcx));
+            time(sess, "borrow checking", || {
+                if tcx.use_ast_borrowck() {
+                    borrowck::check_crate(tcx);
+                }
+            });
 
             time(sess,
                  "MIR borrow checking",
index 84f7b35d21f33c542ba2d01dd37d44bebb7c2557..1078dadce25f596d1d1b6efc26c359d8cad0d8de 100644 (file)
@@ -1493,7 +1493,7 @@ pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<Any + Send>>
     // Temporarily have stack size set to 16MB to deal with nom-using crates failing
     const STACK_SIZE: usize = 16 * 1024 * 1024; // 16MB
 
-    #[cfg(unix)]
+    #[cfg(all(unix,not(target_os = "haiku")))]
     let spawn_thread = unsafe {
         // Fetch the current resource limits
         let mut rlim = libc::rlimit {
@@ -1525,6 +1525,26 @@ pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<Any + Send>>
     #[cfg(windows)]
     let spawn_thread = false;
 
+    #[cfg(target_os = "haiku")]
+    let spawn_thread = unsafe {
+        // Haiku does not have setrlimit implemented for the stack size.
+        // By default it does have the 16 MB stack limit, but we check this in
+        // case the minimum STACK_SIZE changes or Haiku's defaults change.
+        let mut rlim = libc::rlimit {
+            rlim_cur: 0,
+            rlim_max: 0,
+        };
+        if libc::getrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 {
+            let err = io::Error::last_os_error();
+            error!("in_rustc_thread: error calling getrlimit: {}", err);
+            true
+        } else if rlim.rlim_cur >= STACK_SIZE {
+            false
+        } else {
+            true
+        }
+    };
+
     #[cfg(not(any(windows,unix)))]
     let spawn_thread = true;
 
index c5f3b45950ed7f86faf1e8631a6d65a0a75574fb..d6e5c70b8f7e1b4320788cf5c83e5bfef44849c7 100644 (file)
@@ -280,7 +280,7 @@ fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) {
 }
 
 declare_lint! {
-    MISSING_DOCS,
+    pub MISSING_DOCS,
     Allow,
     "detects missing documentation for public members"
 }
index adc700506ffc0bc15f271a2b3b365edca9711021..359b056b5a2d1f5da0fe7e14e6cbeb10e31c14a1 100644 (file)
@@ -56,7 +56,7 @@
 use lint::FutureIncompatibleInfo;
 
 mod bad_style;
-mod builtin;
+pub mod builtin;
 mod types;
 mod unused;
 
@@ -293,6 +293,11 @@ macro_rules! add_lint_group {
             reference: "issue #50589 <https://github.com/rust-lang/rust/issues/50589>",
             edition: None,
         },
+        FutureIncompatibleInfo {
+            id: LintId::of(PROC_MACRO_DERIVE_RESOLUTION_FALLBACK),
+            reference: "issue #50504 <https://github.com/rust-lang/rust/issues/50504>",
+            edition: None,
+        },
         ]);
 
     // Register renamed and removed lints
index cdeee92cb073fc4914539e6ce61af79bc02144ce..1e227b8a1a6596b08aa2170dc3435da77418a8fb 100644 (file)
@@ -536,7 +536,7 @@ fn load_derive_macros(&mut self, root: &CrateRoot, dylib: Option<PathBuf>, span:
                 Ok(f) => f,
                 Err(err) => self.sess.span_fatal(span, &err),
             };
-            mem::transmute::<*mut u8, fn(&mut Registry)>(sym)
+            mem::transmute::<*mut u8, fn(&mut dyn Registry)>(sym)
         };
 
         struct MyRegistrar {
@@ -1019,7 +1019,7 @@ fn visit_item(&mut self, i: &'ast ast::Item) {
     fn inject_dependency_if(&self,
                             krate: CrateNum,
                             what: &str,
-                            needs_dep: &Fn(&cstore::CrateMetadata) -> bool) {
+                            needs_dep: &dyn Fn(&cstore::CrateMetadata) -> bool) {
         // don't perform this validation if the session has errors, as one of
         // those errors may indicate a circular dependency which could cause
         // this to stack overflow.
index 2bc5f6074866432742c32d15ce322dd817e7a1d3..d93a7f9526e1aed9377d69d89acba136b4d24de8 100644 (file)
@@ -90,11 +90,11 @@ pub struct CStore {
     metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
     /// Map from NodeId's of local extern crate statements to crate numbers
     extern_mod_crate_map: Lock<NodeMap<CrateNum>>,
-    pub metadata_loader: Box<MetadataLoader + Sync>,
+    pub metadata_loader: Box<dyn MetadataLoader + Sync>,
 }
 
 impl CStore {
-    pub fn new(metadata_loader: Box<MetadataLoader + Sync>) -> CStore {
+    pub fn new(metadata_loader: Box<dyn MetadataLoader + Sync>) -> CStore {
         CStore {
             // We add an empty entry for LOCAL_CRATE (which maps to zero) in
             // order to make array indices in `metas` match with the
index 23da82f5a4514241ca5fc56fed10f80fef37bd6d..d5078642147681488abb37c11e75d9a027217306 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))
@@ -265,8 +266,6 @@ fn into_args(self) -> (DefId, DefId) { (self.0.as_def_id(), self.1) }
 
         Arc::new(cdata.exported_symbols(tcx))
     }
-
-    wasm_custom_sections => { Lrc::new(cdata.wasm_custom_sections()) }
 }
 
 pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
@@ -414,11 +413,11 @@ fn is_const_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
 }
 
 impl CrateStore for cstore::CStore {
-    fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc<Any> {
+    fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc<dyn Any> {
         self.get_crate_data(krate)
     }
 
-    fn metadata_loader(&self) -> &MetadataLoader {
+    fn metadata_loader(&self) -> &dyn MetadataLoader {
         &*self.metadata_loader
     }
 
index 1985900b3e1170b05e03e4ae8bf48207997807a2..b8c643839506637b85f504285dc858e9bbed6086 100644 (file)
@@ -391,7 +391,7 @@ pub fn get_root(&self) -> CrateRoot {
     }
 
     pub fn list_crate_metadata(&self,
-                               out: &mut io::Write) -> io::Result<()> {
+                               out: &mut dyn io::Write) -> io::Result<()> {
         write!(out, "=External Dependencies=\n")?;
         let root = self.get_root();
         for (i, dep) in root.crate_deps
@@ -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>)
@@ -1004,16 +1011,6 @@ pub fn get_rendered_const(&self, id: DefIndex) -> String {
         }
     }
 
-    pub fn wasm_custom_sections(&self) -> Vec<DefId> {
-        let sections = self.root
-            .wasm_custom_sections
-            .decode(self)
-            .map(|def_index| self.local_def_id(def_index))
-            .collect::<Vec<_>>();
-        info!("loaded wasm sections {:?}", sections);
-        return sections
-    }
-
     pub fn get_macro(&self, id: DefIndex) -> (InternedString, MacroDef) {
         let entry = self.entry(id);
         match entry.kind {
index 3cfde7a8297f97c957bf73542124fbeb36bc7df5..72f91dcea608805932dc1bed90eac9a2cd0d494d 100644 (file)
@@ -436,12 +436,6 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
             &exported_symbols);
         let exported_symbols_bytes = self.position() - i;
 
-        // encode wasm custom sections
-        let wasm_custom_sections = self.tcx.wasm_custom_sections(LOCAL_CRATE);
-        let wasm_custom_sections = self.tracked(
-            IsolatedEncoder::encode_wasm_custom_sections,
-            &wasm_custom_sections);
-
         let tcx = self.tcx;
 
         // Encode the items.
@@ -527,7 +521,6 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
             def_path_table,
             impls,
             exported_symbols,
-            wasm_custom_sections,
             interpret_alloc_index,
             index,
         });
@@ -629,6 +622,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 +660,7 @@ fn encode_info_for_mod(&mut self,
             variances: LazySeq::empty(),
             generics: None,
             predicates: None,
+            predicates_defined_on: None,
 
             mir: None
         }
@@ -706,6 +701,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 +759,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 +777,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 +872,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 +969,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 +1233,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 +1293,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 +1321,7 @@ fn encode_info_for_ty_param(&mut self,
             variances: LazySeq::empty(),
             generics: None,
             predicates: None,
+            predicates_defined_on: None,
 
             mir: None,
         }
@@ -1349,6 +1366,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 +1394,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),
         }
@@ -1517,11 +1536,6 @@ fn encode_exported_symbols(&mut self,
         }
     }
 
-    fn encode_wasm_custom_sections(&mut self, statics: &[DefId]) -> LazySeq<DefIndex> {
-        info!("encoding custom wasm section constants {:?}", statics);
-        self.lazy_seq(statics.iter().map(|id| id.index))
-    }
-
     fn encode_dylib_dependency_formats(&mut self, _: ()) -> LazySeq<Option<LinkagePreference>> {
         match self.tcx.sess.dependency_formats.borrow().get(&config::CrateTypeDylib) {
             Some(arr) => {
@@ -1577,6 +1591,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 dad1030cb610bfc7ee4c7c82cbab0a65fc962169..5c9915e94e56d34a15b5a3eee3234cc3d43df5c6 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![deny(bare_trait_objects)]
+
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
index 9b1b48efca58562d5388f74a3008ffe09c226b2e..b747624338c83c8208e8eef55739019fa583de66 100644 (file)
@@ -273,7 +273,7 @@ pub struct Context<'a> {
     pub rejected_via_filename: Vec<CrateMismatch>,
     pub should_match_name: bool,
     pub is_proc_macro: Option<bool>,
-    pub metadata_loader: &'a MetadataLoader,
+    pub metadata_loader: &'a dyn MetadataLoader,
 }
 
 pub struct CratePaths {
@@ -842,7 +842,7 @@ fn find_commandline_library<'b, LOCS>(&mut self, locs: LOCS) -> Option<Library>
 fn get_metadata_section(target: &Target,
                         flavor: CrateFlavor,
                         filename: &Path,
-                        loader: &MetadataLoader)
+                        loader: &dyn MetadataLoader)
                         -> Result<MetadataBlob, String> {
     let start = Instant::now();
     let ret = get_metadata_section_imp(target, flavor, filename, loader);
@@ -855,7 +855,7 @@ fn get_metadata_section(target: &Target,
 fn get_metadata_section_imp(target: &Target,
                             flavor: CrateFlavor,
                             filename: &Path,
-                            loader: &MetadataLoader)
+                            loader: &dyn MetadataLoader)
                             -> Result<MetadataBlob, String> {
     if !filename.exists() {
         return Err(format!("no such file: '{}'", filename.display()));
@@ -904,8 +904,8 @@ fn get_metadata_section_imp(target: &Target,
 // A diagnostic function for dumping crate metadata to an output stream
 pub fn list_file_metadata(target: &Target,
                           path: &Path,
-                          loader: &MetadataLoader,
-                          out: &mut io::Write)
+                          loader: &dyn MetadataLoader,
+                          out: &mut dyn io::Write)
                           -> io::Result<()> {
     let filename = path.file_name().unwrap().to_str().unwrap();
     let flavor = if filename.ends_with(".rlib") {
index 21d6d15457aa0252a4ac51f14e6f61af78e3b913..430cbf9b529fbecef55869fe74664a64b69f1a1c 100644 (file)
@@ -206,7 +206,6 @@ pub struct CrateRoot {
     pub def_path_table: Lazy<hir::map::definitions::DefPathTable>,
     pub impls: LazySeq<TraitImpls>,
     pub exported_symbols: EncodedExportedSymbols,
-    pub wasm_custom_sections: LazySeq<DefIndex>,
     pub interpret_alloc_index: LazySeq<u32>,
 
     pub index: LazySeq<index::Index>,
@@ -273,6 +272,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 +290,7 @@ pub struct Entry<'tcx> {
     variances,
     generics,
     predicates,
+    predicates_defined_on,
     mir
 });
 
index 3d6f49c3772264032914b83c2fbfe4805a69c0a0..e9e0c5c36135322c7594209307c627ec4cae2df8 100644 (file)
@@ -53,15 +53,13 @@ fn index(&self, index: BorrowIndex) -> &BorrowData<'tcx> {
     }
 }
 
-/// Every two-phase borrow has *exactly one* use (or else it is not a
-/// proper two-phase borrow under our current definition). However, not
-/// all uses are actually ones that activate the reservation.. In
-/// particular, a shared borrow of a `&mut` does not activate the
-/// reservation.
+/// Location where a two phase borrow is activated, if a borrow
+/// is in fact a two phase borrow.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
-crate enum TwoPhaseUse {
-    MutActivate,
-    SharedUse,
+crate enum TwoPhaseActivation {
+    NotTwoPhase,
+    NotActivated,
+    ActivatedAt(Location),
 }
 
 #[derive(Debug)]
@@ -69,9 +67,8 @@ fn index(&self, index: BorrowIndex) -> &BorrowData<'tcx> {
     /// Location where the borrow reservation starts.
     /// In many cases, this will be equal to the activation location but not always.
     crate reserve_location: Location,
-    /// Location where the borrow is activated. None if this is not a
-    /// 2-phase borrow.
-    crate activation_location: Option<(TwoPhaseUse, Location)>,
+    /// Location where the borrow is activated.
+    crate activation_location: TwoPhaseActivation,
     /// What kind of borrow this is
     crate kind: mir::BorrowKind,
     /// The region for which this borrow is live
@@ -116,19 +113,6 @@ pub fn build(tcx: TyCtxt<'_, '_, 'tcx>, mir: &Mir<'tcx>) -> Self {
             visitor.visit_basic_block_data(block, block_data);
         }
 
-        // Double check: We should have found an activation for every pending
-        // activation.
-        assert_eq!(
-            visitor
-                .pending_activations
-                .iter()
-                .find(|&(_local, &borrow_index)| visitor.idx_vec[borrow_index]
-                    .activation_location
-                    .is_none()),
-            None,
-            "never found an activation for this borrow!",
-        );
-
         BorrowSet {
             borrows: visitor.idx_vec,
             location_map: visitor.location_map,
@@ -183,7 +167,7 @@ fn visit_assign(
                 kind,
                 region,
                 reserve_location: location,
-                activation_location: None,
+                activation_location: TwoPhaseActivation::NotTwoPhase,
                 borrowed_place: borrowed_place.clone(),
                 assigned_place: assigned_place.clone(),
             };
@@ -232,38 +216,43 @@ fn visit_place(
                         return;
                     }
 
-                    if let Some(other_activation) = borrow_data.activation_location {
+                    if let TwoPhaseActivation::ActivatedAt(other_location) =
+                            borrow_data.activation_location {
                         span_bug!(
                             self.mir.source_info(location).span,
                             "found two uses for 2-phase borrow temporary {:?}: \
                              {:?} and {:?}",
                             temp,
                             location,
-                            other_activation,
+                            other_location,
                         );
                     }
 
                     // Otherwise, this is the unique later use
                     // that we expect.
-
-                    let two_phase_use;
-
-                    match context {
+                    borrow_data.activation_location = match context {
                         // The use of TMP in a shared borrow does not
                         // count as an actual activation.
                         PlaceContext::Borrow { kind: mir::BorrowKind::Shared, .. } => {
-                            two_phase_use = TwoPhaseUse::SharedUse;
+                            TwoPhaseActivation::NotActivated
                         }
                         _ => {
-                            two_phase_use = TwoPhaseUse::MutActivate;
+                            // Double check: This borrow is indeed a two-phase borrow (that is,
+                            // we are 'transitioning' from `NotActivated` to `ActivatedAt`) and
+                            // we've not found any other activations (checked above).
+                            assert_eq!(
+                                borrow_data.activation_location,
+                                TwoPhaseActivation::NotActivated,
+                                "never found an activation for this borrow!",
+                            );
+
                             self.activation_map
                                 .entry(location)
                                 .or_insert(Vec::new())
                                 .push(borrow_index);
+                            TwoPhaseActivation::ActivatedAt(location)
                         }
-                    }
-
-                    borrow_data.activation_location = Some((two_phase_use, location));
+                    };
                 }
 
                 None => {}
@@ -342,6 +331,11 @@ fn insert_as_pending_if_two_phase(
             );
         };
 
+        // Consider the borrow not activated to start. When we find an activation, we'll update
+        // this field.
+        let borrow_data = &mut self.idx_vec[borrow_index];
+        borrow_data.activation_location = TwoPhaseActivation::NotActivated;
+
         // Insert `temp` into the list of pending activations. From
         // now on, we'll be on the lookout for a use of it. Note that
         // we are guaranteed that this use will come after the
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..1a66a2d2cb902a0614f0e5c2b45ad3c227d0755b 100644 (file)
@@ -80,7 +80,7 @@ fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> BorrowC
     let mut return_early;
 
     // Return early if we are not supposed to use MIR borrow checker for this function.
-    return_early = !tcx.has_attr(def_id, "rustc_mir_borrowck") && !tcx.use_mir_borrowck();
+    return_early = !tcx.has_attr(def_id, "rustc_mir") && !tcx.use_mir_borrowck();
 
     if tcx.is_struct_constructor(def_id) {
         // We are not borrow checking the automatically generated struct constructors
@@ -128,6 +128,8 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
     input_mir: &Mir<'gcx>,
     def_id: DefId,
 ) -> BorrowCheckResult<'gcx> {
+    debug!("do_mir_borrowck(def_id = {:?})", def_id);
+
     let tcx = infcx.tcx;
     let attributes = tcx.get_attrs(def_id);
     let param_env = tcx.param_env(def_id);
@@ -319,10 +321,14 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
         }
     }
 
-    BorrowCheckResult {
+    let result = BorrowCheckResult {
         closure_requirements: opt_closure_req,
         used_mut_upvars: mbcx.used_mut_upvars,
-    }
+    };
+
+    debug!("do_mir_borrowck: result = {:#?}", result);
+
+    result
 }
 
 #[allow(dead_code)]
@@ -1182,26 +1188,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 {
@@ -1888,8 +1905,10 @@ fn find_place_to_suggest_ampmut<'cx, 'gcx, 'tcx>(
                     // highlighted text will always be `&<expr>` and
                     // thus can transform to `&mut` by slicing off
                     // first ASCII character and prepending "&mut ".
-                    let borrowed_expr = src[1..].to_string();
-                    return (assignment_rhs_span, format!("&mut {}", borrowed_expr));
+                    if src.starts_with('&') {
+                        let borrowed_expr = src[1..].to_string();
+                        return (assignment_rhs_span, format!("&mut {}", borrowed_expr));
+                    }
                 }
             }
 
@@ -1940,6 +1959,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 +2138,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
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting.rs
deleted file mode 100644 (file)
index 6543516..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-// 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::fmt;
-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;
-use rustc::infer::InferCtxt;
-use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
-use rustc::mir::{self, Location, Mir, Place, StatementKind, TerminatorKind, Rvalue};
-use rustc::ty::RegionVid;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_data_structures::indexed_vec::IndexVec;
-use syntax_pos::Span;
-
-/// Constraints that are considered interesting can be categorized to
-/// determine why they are interesting. Order of variants indicates
-/// sort order of the category, thereby influencing diagnostic output.
-#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)]
-enum ConstraintCategory {
-    Cast,
-    Assignment,
-    Return,
-    CallArgument,
-    Other,
-    Boring,
-}
-
-impl fmt::Display for ConstraintCategory {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match self {
-            ConstraintCategory::Assignment => write!(f, "assignment"),
-            ConstraintCategory::Return => write!(f, "return"),
-            ConstraintCategory::Cast => write!(f, "cast"),
-            ConstraintCategory::CallArgument => write!(f, "argument"),
-            _ => write!(f, "free region"),
-        }
-    }
-}
-
-impl<'tcx> RegionInferenceContext<'tcx> {
-    /// When reporting an error, it is useful to be able to determine which constraints influenced
-    /// the region being reported as an error. This function finds all of the paths from the
-    /// constraint.
-    fn find_constraint_paths_from_region(
-        &self,
-        r0: RegionVid
-    ) -> Vec<Vec<ConstraintIndex>> {
-        let constraints = self.constraints.clone();
-
-        // Mapping of regions to the previous region and constraint index that led to it.
-        let mut previous = FxHashMap();
-        // Regions yet to be visited.
-        let mut next = vec! [ r0 ];
-        // Regions that have been visited.
-        let mut visited = FxHashSet();
-        // Ends of paths.
-        let mut end_regions = FxHashSet();
-
-        // When we've still got points to visit...
-        while let Some(current) = next.pop() {
-            // ...take the next point...
-            debug!("find_constraint_paths_from_region: current={:?} visited={:?} next={:?}",
-                   current, visited, next);
-            // ...but make sure not to visit this point again...
-            visited.insert(current);
-
-            // ...find the edges containing it...
-            let mut upcoming = Vec::new();
-            for (index, constraint) in constraints.iter_enumerated() {
-                if constraint.sub == current {
-                    // ...add the regions that join us with to the path we've taken...
-                    debug!("find_constraint_paths_from_region: index={:?} constraint={:?}",
-                           index, constraint);
-                    let next_region = constraint.sup.clone();
-
-                    // ...unless we've visited it since this was added...
-                    if visited.contains(&next_region) {
-                        debug!("find_constraint_paths_from_region: skipping as visited");
-                        continue;
-                    }
-
-                    previous.insert(next_region, (index, Some(current)));
-                    upcoming.push(next_region);
-                }
-            }
-
-            if upcoming.is_empty() {
-                // If we didn't find any edges then this is the end of a path...
-                debug!("find_constraint_paths_from_region: new end region current={:?}", current);
-                end_regions.insert(current);
-            } else {
-                // ...but, if we did find edges, then add these to the regions yet to visit.
-                debug!("find_constraint_paths_from_region: extend next upcoming={:?}", upcoming);
-                next.extend(upcoming);
-            }
-
-        }
-
-        // Now we've visited each point, compute the final paths.
-        let mut paths: Vec<Vec<ConstraintIndex>> = Vec::new();
-        debug!("find_constraint_paths_from_region: end_regions={:?}", end_regions);
-        for end_region in end_regions {
-            debug!("find_constraint_paths_from_region: end_region={:?}", end_region);
-
-            // Get the constraint and region that led to this end point.
-            // We can unwrap as we know if end_point was in the vector that it
-            // must also be in our previous map.
-            let (mut index, mut region) = previous.get(&end_region).unwrap();
-            debug!("find_constraint_paths_from_region: index={:?} region={:?}", index, region);
-
-            // Keep track of the indices.
-            let mut path: Vec<ConstraintIndex> = vec![index];
-
-            while region.is_some() && region != Some(r0) {
-                let p = previous.get(&region.unwrap()).unwrap();
-                index = p.0;
-                region = p.1;
-
-                debug!("find_constraint_paths_from_region: index={:?} region={:?}", index, region);
-                path.push(index);
-            }
-
-            // Add to our paths.
-            paths.push(path);
-        }
-
-        debug!("find_constraint_paths_from_region: paths={:?}", paths);
-        paths
-    }
-
-    /// This function will return true if a constraint is interesting and false if a constraint
-    /// is not. It is useful in filtering constraint paths to only interesting points.
-    fn constraint_is_interesting(&self, index: &ConstraintIndex) -> bool {
-        self.constraints.get(*index).filter(|constraint| {
-            debug!("constraint_is_interesting: locations={:?} constraint={:?}",
-                   constraint.locations, constraint);
-            if let Locations::Interesting(_) = constraint.locations { true } else { false }
-        }).is_some()
-    }
-
-    /// This function classifies a constraint from a location.
-    fn classify_constraint(&self, index: &ConstraintIndex,
-                           mir: &Mir<'tcx>) -> Option<(ConstraintCategory, Span)> {
-        let constraint = self.constraints.get(*index)?;
-        let span = constraint.locations.span(mir);
-        let location = constraint.locations.from_location()?;
-
-        if !self.constraint_is_interesting(index) {
-            return Some((ConstraintCategory::Boring, span));
-        }
-
-        let data = &mir[location.block];
-        let category = if location.statement_index == data.statements.len() {
-            if let Some(ref terminator) = data.terminator {
-                match terminator.kind {
-                    TerminatorKind::DropAndReplace { .. } => ConstraintCategory::Assignment,
-                    TerminatorKind::Call { .. } => ConstraintCategory::CallArgument,
-                    _ => ConstraintCategory::Other,
-                }
-            } else {
-                ConstraintCategory::Other
-            }
-        } else {
-            let statement = &data.statements[location.statement_index];
-            match statement.kind {
-                StatementKind::Assign(ref place, ref rvalue) => {
-                    if *place == Place::Local(mir::RETURN_PLACE) {
-                        ConstraintCategory::Return
-                    } else {
-                        match rvalue {
-                            Rvalue::Cast(..) => ConstraintCategory::Cast,
-                            Rvalue::Use(..) => ConstraintCategory::Assignment,
-                            _ => ConstraintCategory::Other,
-                        }
-                    }
-                },
-                _ => ConstraintCategory::Other,
-            }
-        };
-
-        Some((category, span))
-    }
-
-    /// Report an error because the universal region `fr` was required to outlive
-    /// `outlived_fr` but it is not known to do so. For example:
-    ///
-    /// ```
-    /// fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }
-    /// ```
-    ///
-    /// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`.
-    pub(super) fn report_error(
-        &self,
-        mir: &Mir<'tcx>,
-        infcx: &InferCtxt<'_, '_, 'tcx>,
-        mir_def_id: DefId,
-        fr: RegionVid,
-        outlived_fr: RegionVid,
-        blame_span: Span,
-    ) {
-        // Obviously uncool error reporting.
-
-        let fr_name = self.to_error_region(fr);
-        let outlived_fr_name = self.to_error_region(outlived_fr);
-
-        if let (Some(f), Some(o)) = (fr_name, outlived_fr_name) {
-            let tables = infcx.tcx.typeck_tables_of(mir_def_id);
-            let nice = NiceRegionError::new_from_span(infcx.tcx, blame_span, o, f, Some(tables));
-            if let Some(_error_reported) = nice.try_report() {
-                return;
-            }
-        }
-
-        let fr_string = match fr_name {
-            Some(r) => format!("free region `{}`", r),
-            None => format!("free region `{:?}`", fr),
-        };
-
-        let outlived_fr_string = match outlived_fr_name {
-            Some(r) => format!("free region `{}`", r),
-            None => format!("free region `{:?}`", outlived_fr),
-        };
-
-        let constraints = self.find_constraint_paths_from_region(fr.clone());
-        let path = constraints.iter().min_by_key(|p| p.len()).unwrap();
-        debug!("report_error: shortest_path={:?}", path);
-
-        let mut categorized_path = path.iter().filter_map(|index| {
-            self.classify_constraint(index, mir)
-        }).collect::<Vec<(ConstraintCategory, Span)>>();
-        debug!("report_error: categorized_path={:?}", categorized_path);
-
-        categorized_path.sort_by(|p0, p1| p0.0.cmp(&p1.0));
-        debug!("report_error: sorted_path={:?}", categorized_path);
-
-        if let Some((category, span)) = &categorized_path.first() {
-            let mut diag = infcx.tcx.sess.struct_span_err(
-                *span, &format!("{} requires that data must outlive {}",
-                                category, outlived_fr_string),
-            );
-
-            diag.emit();
-        } else {
-            let mut diag = infcx.tcx.sess.struct_span_err(
-                blame_span,
-                &format!("{} does not outlive {}", fr_string, outlived_fr_string,),
-            );
-
-            diag.emit();
-        }
-    }
-
-    // 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);
-        self.constraints[index].sub
-    }
-
-    /// Tries to finds a good span to blame for the fact that `fr1`
-    /// contains `fr2`.
-    pub(super) fn blame_constraint(&self, fr1: RegionVid,
-                                   elem: impl ToElementIndex) -> ConstraintIndex {
-        // Find everything that influenced final value of `fr`.
-        let influenced_fr1 = self.dependencies(fr1);
-
-        // Try to find some outlives constraint `'X: fr2` where `'X`
-        // influenced `fr1`. Blame that.
-        //
-        // NB, this is a pretty bad choice most of the time. In
-        // particular, the connection between `'X` and `fr1` may not
-        // be obvious to the user -- not to mention the naive notion
-        // of dependencies, which doesn't account for the locations of
-        // contraints at all. But it will do for now.
-        let relevant_constraint = self.constraints
-            .iter_enumerated()
-            .filter_map(|(i, constraint)| {
-                if !self.liveness_constraints.contains(constraint.sub, elem) {
-                    None
-                } else {
-                    influenced_fr1[constraint.sup]
-                        .map(|distance| (distance, i))
-                }
-            })
-            .min() // constraining fr1 with fewer hops *ought* to be more obvious
-            .map(|(_dist, i)| i);
-
-        relevant_constraint.unwrap_or_else(|| {
-            bug!(
-                "could not find any constraint to blame for {:?}: {:?}",
-                fr1,
-                elem,
-            );
-        })
-    }
-
-    /// Finds all regions whose values `'a` may depend on in some way.
-    /// For each region, returns either `None` (does not influence
-    /// `'a`) or `Some(d)` which indicates that it influences `'a`
-    /// with distinct `d` (minimum number of edges that must be
-    /// traversed).
-    ///
-    /// Used during error reporting, extremely naive and inefficient.
-    fn dependencies(&self, r0: RegionVid) -> IndexVec<RegionVid, Option<usize>> {
-        let mut result_set = IndexVec::from_elem(None, &self.definitions);
-        let mut changed = true;
-        result_set[r0] = Some(0); // distance 0 from `r0`
-
-        while changed {
-            changed = false;
-            for constraint in &*self.constraints {
-                if let Some(n) = result_set[constraint.sup] {
-                    let m = n + 1;
-                    if result_set[constraint.sub]
-                        .map(|distance| m < distance)
-                        .unwrap_or(true)
-                    {
-                        result_set[constraint.sub] = Some(m);
-                        changed = true;
-                    }
-                }
-            }
-        }
-
-        result_set
-    }
-}
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
new file mode 100644 (file)
index 0000000..786b6a7
--- /dev/null
@@ -0,0 +1,338 @@
+// 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 borrow_check::nll::region_infer::values::ToElementIndex;
+use borrow_check::nll::region_infer::{ConstraintIndex, RegionInferenceContext};
+use borrow_check::nll::type_check::Locations;
+use rustc::hir::def_id::DefId;
+use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
+use rustc::infer::InferCtxt;
+use rustc::mir::{self, Location, Mir, Place, Rvalue, StatementKind, TerminatorKind};
+use rustc::ty::RegionVid;
+use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::indexed_vec::IndexVec;
+use std::fmt;
+use syntax_pos::Span;
+
+mod region_name;
+
+/// Constraints that are considered interesting can be categorized to
+/// determine why they are interesting. Order of variants indicates
+/// sort order of the category, thereby influencing diagnostic output.
+#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)]
+enum ConstraintCategory {
+    Cast,
+    Assignment,
+    Return,
+    CallArgument,
+    Other,
+    Boring,
+}
+
+impl fmt::Display for ConstraintCategory {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            ConstraintCategory::Assignment => write!(f, "assignment"),
+            ConstraintCategory::Return => write!(f, "return"),
+            ConstraintCategory::Cast => write!(f, "cast"),
+            ConstraintCategory::CallArgument => write!(f, "argument"),
+            _ => write!(f, "free region"),
+        }
+    }
+}
+
+impl<'tcx> RegionInferenceContext<'tcx> {
+    /// Walks the graph of constraints (where `'a: 'b` is considered
+    /// an edge `'b -> 'a`) to find all paths from `from_region` to
+    /// `to_region`. The paths are accumulated into the vector
+    /// `results`. The paths are stored as a series of
+    /// `ConstraintIndex` values -- in other words, a list of *edges*.
+    ///
+    /// # Parameters
+    ///
+    /// - `from_region`
+    /// When reporting an error, it is useful to be able to determine
+    /// which constraints influenced the region being reported as an
+    /// error. This function finds all of the paths from the
+    /// constraint.
+    fn find_constraint_paths_between_regions(
+        &self,
+        from_region: RegionVid,
+        target_test: impl Fn(RegionVid) -> bool,
+    ) -> Vec<Vec<ConstraintIndex>> {
+        let mut results = vec![];
+        self.find_constraint_paths_between_regions_helper(
+            from_region,
+            from_region,
+            &target_test,
+            &mut FxHashSet::default(),
+            &mut vec![],
+            &mut results,
+        );
+        results
+    }
+
+    /// Helper for `find_constraint_paths_between_regions`.
+    fn find_constraint_paths_between_regions_helper(
+        &self,
+        from_region: RegionVid,
+        current_region: RegionVid,
+        target_test: &impl Fn(RegionVid) -> bool,
+        visited: &mut FxHashSet<RegionVid>,
+        stack: &mut Vec<ConstraintIndex>,
+        results: &mut Vec<Vec<ConstraintIndex>>,
+    ) {
+        let dependency_map = self.dependency_map.as_ref().unwrap();
+
+        // Check if we already visited this region.
+        if !visited.insert(current_region) {
+            return;
+        }
+
+        // Check if we reached the region we were looking for.
+        if target_test(current_region) {
+            if !stack.is_empty() {
+                assert_eq!(self.constraints[stack[0]].sub, from_region);
+                results.push(stack.clone());
+            }
+            return;
+        }
+
+        self.constraints
+            .each_affected_by_dirty(dependency_map[current_region], |constraint| {
+                assert_eq!(self.constraints[constraint].sub, current_region);
+                stack.push(constraint);
+                self.find_constraint_paths_between_regions_helper(
+                    from_region,
+                    self.constraints[constraint].sup,
+                    target_test,
+                    visited,
+                    stack,
+                    results,
+                );
+                stack.pop();
+            });
+    }
+
+    /// This function will return true if a constraint is interesting and false if a constraint
+    /// is not. It is useful in filtering constraint paths to only interesting points.
+    fn constraint_is_interesting(&self, index: ConstraintIndex) -> bool {
+        let constraint = self.constraints[index];
+        debug!(
+            "constraint_is_interesting: locations={:?} constraint={:?}",
+            constraint.locations, constraint
+        );
+        if let Locations::Interesting(_) = constraint.locations {
+            true
+        } else {
+            false
+        }
+    }
+
+    /// This function classifies a constraint from a location.
+    fn classify_constraint(
+        &self,
+        index: ConstraintIndex,
+        mir: &Mir<'tcx>,
+    ) -> (ConstraintCategory, Span) {
+        let constraint = self.constraints[index];
+        let span = constraint.locations.span(mir);
+        let location = constraint.locations.from_location().unwrap_or(Location::START);
+
+        if !self.constraint_is_interesting(index) {
+            return (ConstraintCategory::Boring, span);
+        }
+
+        let data = &mir[location.block];
+        let category = if location.statement_index == data.statements.len() {
+            if let Some(ref terminator) = data.terminator {
+                match terminator.kind {
+                    TerminatorKind::DropAndReplace { .. } => ConstraintCategory::Assignment,
+                    TerminatorKind::Call { .. } => ConstraintCategory::CallArgument,
+                    _ => ConstraintCategory::Other,
+                }
+            } else {
+                ConstraintCategory::Other
+            }
+        } else {
+            let statement = &data.statements[location.statement_index];
+            match statement.kind {
+                StatementKind::Assign(ref place, ref rvalue) => {
+                    if *place == Place::Local(mir::RETURN_PLACE) {
+                        ConstraintCategory::Return
+                    } else {
+                        match rvalue {
+                            Rvalue::Cast(..) => ConstraintCategory::Cast,
+                            Rvalue::Use(..) => ConstraintCategory::Assignment,
+                            _ => ConstraintCategory::Other,
+                        }
+                    }
+                }
+                _ => ConstraintCategory::Other,
+            }
+        };
+
+        (category, span)
+    }
+
+    /// Report an error because the universal region `fr` was required to outlive
+    /// `outlived_fr` but it is not known to do so. For example:
+    ///
+    /// ```
+    /// fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }
+    /// ```
+    ///
+    /// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`.
+    pub(super) fn report_error(
+        &self,
+        mir: &Mir<'tcx>,
+        infcx: &InferCtxt<'_, '_, 'tcx>,
+        mir_def_id: DefId,
+        fr: RegionVid,
+        outlived_fr: RegionVid,
+        blame_span: Span,
+    ) {
+        debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
+
+        if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) {
+            let tables = infcx.tcx.typeck_tables_of(mir_def_id);
+            let nice = NiceRegionError::new_from_span(infcx.tcx, blame_span, o, f, Some(tables));
+            if let Some(_error_reported) = nice.try_report() {
+                return;
+            }
+        }
+
+        // Find all paths
+        let constraint_paths = self.find_constraint_paths_between_regions(outlived_fr, |r| r == fr);
+        debug!("report_error: constraint_paths={:#?}", constraint_paths);
+
+        // Find the shortest such path.
+        let path = constraint_paths.iter().min_by_key(|p| p.len()).unwrap();
+        debug!("report_error: shortest_path={:?}", path);
+
+        // Classify each of the constraints along the path.
+        let mut categorized_path: Vec<(ConstraintCategory, Span)> = path.iter()
+            .map(|&index| self.classify_constraint(index, mir))
+            .collect();
+        debug!("report_error: categorized_path={:?}", categorized_path);
+
+        // Find what appears to be the most interesting path to report to the user.
+        categorized_path.sort_by(|p0, p1| p0.0.cmp(&p1.0));
+        debug!("report_error: sorted_path={:?}", categorized_path);
+
+        // Get a span
+        let (category, span) = categorized_path.first().unwrap();
+        let diag = &mut infcx.tcx.sess.struct_span_err(
+            *span,
+            &format!("unsatisfied lifetime constraints"), // FIXME
+        );
+
+        // Figure out how we can refer
+        let counter = &mut 1;
+        let fr_name = self.give_region_a_name(infcx.tcx, mir, mir_def_id, fr, counter, diag);
+        let outlived_fr_name = self.give_region_a_name(
+            infcx.tcx,
+            mir,
+            mir_def_id,
+            outlived_fr,
+            counter,
+            diag,
+        );
+
+        diag.span_label(
+            *span,
+            format!(
+                "{} requires that `{}` must outlive `{}`",
+                category, fr_name, outlived_fr_name,
+            ),
+        );
+
+        diag.emit();
+    }
+
+    // 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);
+        self.constraints[index].sub
+    }
+
+    /// Tries to finds a good span to blame for the fact that `fr1`
+    /// contains `fr2`.
+    pub(super) fn blame_constraint(
+        &self,
+        fr1: RegionVid,
+        elem: impl ToElementIndex,
+    ) -> ConstraintIndex {
+        // Find everything that influenced final value of `fr`.
+        let influenced_fr1 = self.dependencies(fr1);
+
+        // Try to find some outlives constraint `'X: fr2` where `'X`
+        // influenced `fr1`. Blame that.
+        //
+        // NB, this is a pretty bad choice most of the time. In
+        // particular, the connection between `'X` and `fr1` may not
+        // be obvious to the user -- not to mention the naive notion
+        // of dependencies, which doesn't account for the locations of
+        // contraints at all. But it will do for now.
+        let relevant_constraint = self.constraints
+            .iter_enumerated()
+            .filter_map(|(i, constraint)| {
+                if !self.liveness_constraints.contains(constraint.sub, elem) {
+                    None
+                } else {
+                    influenced_fr1[constraint.sup]
+                        .map(|distance| (distance, i))
+                }
+            })
+            .min() // constraining fr1 with fewer hops *ought* to be more obvious
+            .map(|(_dist, i)| i);
+
+        relevant_constraint.unwrap_or_else(|| {
+            bug!(
+                "could not find any constraint to blame for {:?}: {:?}",
+                fr1,
+                elem,
+            );
+        })
+    }
+
+    /// Finds all regions whose values `'a` may depend on in some way.
+    /// For each region, returns either `None` (does not influence
+    /// `'a`) or `Some(d)` which indicates that it influences `'a`
+    /// with distinct `d` (minimum number of edges that must be
+    /// traversed).
+    ///
+    /// Used during error reporting, extremely naive and inefficient.
+    fn dependencies(&self, r0: RegionVid) -> IndexVec<RegionVid, Option<usize>> {
+        let mut result_set = IndexVec::from_elem(None, &self.definitions);
+        let mut changed = true;
+        result_set[r0] = Some(0); // distance 0 from `r0`
+
+        while changed {
+            changed = false;
+            for constraint in &*self.constraints {
+                if let Some(n) = result_set[constraint.sup] {
+                    let m = n + 1;
+                    if result_set[constraint.sub]
+                        .map(|distance| m < distance)
+                        .unwrap_or(true)
+                    {
+                        result_set[constraint.sub] = Some(m);
+                        changed = true;
+                    }
+                }
+            }
+        }
+
+        result_set
+    }
+}
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
new file mode 100644 (file)
index 0000000..16dec27
--- /dev/null
@@ -0,0 +1,516 @@
+// 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 borrow_check::nll::region_infer::RegionInferenceContext;
+use borrow_check::nll::ToRegionVid;
+use rustc::hir;
+use rustc::hir::def_id::DefId;
+use rustc::mir::{Local, Mir};
+use rustc::ty::subst::{Substs, UnpackedKind};
+use rustc::ty::{self, RegionVid, Ty, TyCtxt};
+use rustc_data_structures::indexed_vec::Idx;
+use rustc_errors::DiagnosticBuilder;
+use syntax::ast::Name;
+use syntax::symbol::keywords;
+use syntax_pos::symbol::InternedString;
+
+impl<'tcx> RegionInferenceContext<'tcx> {
+    /// Maps from an internal MIR region vid to something that we can
+    /// report to the user. In some cases, the region vids will map
+    /// directly to lifetimes that the user has a name for (e.g.,
+    /// `'static`). But frequently they will not, in which case we
+    /// have to find some way to identify the lifetime to the user. To
+    /// that end, this function takes a "diagnostic" so that it can
+    /// create auxiliary notes as needed.
+    ///
+    /// Example (function arguments):
+    ///
+    /// Suppose we are trying to give a name to the lifetime of the
+    /// reference `x`:
+    ///
+    /// ```
+    /// fn foo(x: &u32) { .. }
+    /// ```
+    ///
+    /// This function would create a label like this:
+    ///
+    /// ```
+    ///  | fn foo(x: &u32) { .. }
+    ///           ------- fully elaborated type of `x` is `&'1 u32`
+    /// ```
+    ///
+    /// and then return the name `'1` for us to use.
+    crate fn give_region_a_name(
+        &self,
+        tcx: TyCtxt<'_, '_, 'tcx>,
+        mir: &Mir<'tcx>,
+        mir_def_id: DefId,
+        fr: RegionVid,
+        counter: &mut usize,
+        diag: &mut DiagnosticBuilder,
+    ) -> InternedString {
+        debug!("give_region_a_name(fr={:?}, counter={})", fr, counter);
+
+        assert!(self.universal_regions.is_universal_region(fr));
+
+        self.give_name_from_error_region(tcx, mir_def_id, fr, counter, diag)
+            .or_else(|| {
+                self.give_name_if_anonymous_region_appears_in_arguments(
+                    tcx, mir, mir_def_id, fr, counter, diag,
+                )
+            })
+            .or_else(|| {
+                self.give_name_if_anonymous_region_appears_in_upvars(tcx, mir, fr, counter, diag)
+            })
+            .or_else(|| {
+                self.give_name_if_anonymous_region_appears_in_output(tcx, mir, fr, counter, diag)
+            })
+            .unwrap_or_else(|| span_bug!(mir.span, "can't make a name for free region {:?}", fr))
+    }
+
+    /// Check for the case where `fr` maps to something that the
+    /// *user* has a name for. In that case, we'll be able to map
+    /// `fr` to a `Region<'tcx>`, and that region will be one of
+    /// named variants.
+    fn give_name_from_error_region(
+        &self,
+        tcx: TyCtxt<'_, '_, 'tcx>,
+        mir_def_id: DefId,
+        fr: RegionVid,
+        counter: &mut usize,
+        diag: &mut DiagnosticBuilder<'_>,
+    ) -> Option<InternedString> {
+        let error_region = self.to_error_region(fr)?;
+        debug!("give_region_a_name: error_region = {:?}", error_region);
+        match error_region {
+            ty::ReEarlyBound(ebr) => Some(ebr.name),
+
+            ty::ReStatic => Some(keywords::StaticLifetime.name().as_interned_str()),
+
+            ty::ReFree(free_region) => match free_region.bound_region {
+                ty::BoundRegion::BrNamed(_, name) => Some(name),
+
+                ty::BoundRegion::BrEnv => {
+                    let closure_span = tcx.hir.span_if_local(mir_def_id).unwrap();
+                    let region_name = self.synthesize_region_name(counter);
+                    diag.span_label(
+                        closure_span,
+                        format!("lifetime `{}` represents the closure body", region_name),
+                    );
+                    Some(region_name)
+                }
+
+                ty::BoundRegion::BrAnon(_) | ty::BoundRegion::BrFresh(_) => None,
+            },
+
+            ty::ReLateBound(..)
+            | ty::ReScope(..)
+            | ty::ReVar(..)
+            | ty::ReSkolemized(..)
+            | ty::ReEmpty
+            | ty::ReErased
+            | ty::ReClosureBound(..)
+            | ty::ReCanonical(..) => None,
+        }
+    }
+
+    /// Find an argument that contains `fr` and label it with a fully
+    /// elaborated type, returning something like `'1`. Result looks
+    /// like:
+    ///
+    /// ```
+    ///  | fn foo(x: &u32) { .. }
+    ///           ------- fully elaborated type of `x` is `&'1 u32`
+    /// ```
+    fn give_name_if_anonymous_region_appears_in_arguments(
+        &self,
+        tcx: TyCtxt<'_, '_, 'tcx>,
+        mir: &Mir<'tcx>,
+        mir_def_id: DefId,
+        fr: RegionVid,
+        counter: &mut usize,
+        diag: &mut DiagnosticBuilder<'_>,
+    ) -> Option<InternedString> {
+        let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
+        let argument_index = self
+            .universal_regions
+            .unnormalized_input_tys
+            .iter()
+            .skip(implicit_inputs)
+            .position(|arg_ty| {
+                debug!(
+                    "give_name_if_anonymous_region_appears_in_arguments: arg_ty = {:?}",
+                    arg_ty
+                );
+                tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr)
+            })?;
+
+        debug!(
+            "give_name_if_anonymous_region_appears_in_arguments: \
+             found {:?} in argument {} which has type {:?}",
+            fr, argument_index, self.universal_regions.unnormalized_input_tys[argument_index],
+        );
+
+        let arg_ty =
+            self.universal_regions.unnormalized_input_tys[implicit_inputs + argument_index];
+        if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument(
+            tcx,
+            mir_def_id,
+            fr,
+            arg_ty,
+            argument_index,
+            counter,
+            diag,
+        ) {
+            return Some(region_name);
+        }
+
+        let region_name = self.synthesize_region_name(counter);
+
+        let argument_local = Local::new(argument_index + implicit_inputs + 1);
+        let argument_span = mir.local_decls[argument_local].source_info.span;
+        diag.span_label(
+            argument_span,
+            format!("lifetime `{}` appears in this argument", region_name,),
+        );
+
+        Some(region_name)
+    }
+
+    fn give_name_if_we_can_match_hir_ty_from_argument(
+        &self,
+        tcx: TyCtxt<'_, '_, 'tcx>,
+        mir_def_id: DefId,
+        needle_fr: RegionVid,
+        argument_ty: Ty<'tcx>,
+        argument_index: usize,
+        counter: &mut usize,
+        diag: &mut DiagnosticBuilder<'_>,
+    ) -> Option<InternedString> {
+        let mir_node_id = tcx.hir.as_local_node_id(mir_def_id)?;
+        let fn_decl = tcx.hir.fn_decl(mir_node_id)?;
+        let argument_hir_ty: &hir::Ty = &fn_decl.inputs[argument_index];
+        match argument_hir_ty.node {
+            // This indicates a variable with no type annotation, like
+            // `|x|`... in that case, we can't highlight the type but
+            // must highlight the variable.
+            hir::TyInfer => None,
+
+            _ => self.give_name_if_we_can_match_hir_ty(
+                tcx,
+                needle_fr,
+                argument_ty,
+                argument_hir_ty,
+                counter,
+                diag,
+            ),
+        }
+    }
+
+    /// Attempts to highlight the specific part of a type annotation
+    /// that contains the anonymous reference we want to give a name
+    /// to. For example, we might produce an annotation like this:
+    ///
+    /// ```
+    ///  | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
+    ///  |                - let's call the lifetime of this reference `'1`
+    /// ```
+    ///
+    /// the way this works is that we match up `argument_ty`, which is
+    /// a `Ty<'tcx>` (the internal form of the type) with
+    /// `argument_hir_ty`, a `hir::Ty` (the syntax of the type
+    /// annotation). We are descending through the types stepwise,
+    /// looking in to find the region `needle_fr` in the internal
+    /// type.  Once we find that, we can use the span of the `hir::Ty`
+    /// to add the highlight.
+    ///
+    /// This is a somewhat imperfect process, so long the way we also
+    /// keep track of the **closest** type we've found. If we fail to
+    /// find the exact `&` or `'_` to highlight, then we may fall back
+    /// to highlighting that closest type instead.
+    fn give_name_if_we_can_match_hir_ty(
+        &self,
+        tcx: TyCtxt<'_, '_, 'tcx>,
+        needle_fr: RegionVid,
+        argument_ty: Ty<'tcx>,
+        argument_hir_ty: &hir::Ty,
+        counter: &mut usize,
+        diag: &mut DiagnosticBuilder<'_>,
+    ) -> Option<InternedString> {
+        let search_stack: &mut Vec<(Ty<'tcx>, &hir::Ty)> = &mut Vec::new();
+
+        search_stack.push((argument_ty, argument_hir_ty));
+
+        let mut closest_match: &hir::Ty = argument_hir_ty;
+
+        while let Some((ty, hir_ty)) = search_stack.pop() {
+            // While we search, also track the closet match.
+            if tcx.any_free_region_meets(&ty, |r| r.to_region_vid() == needle_fr) {
+                closest_match = hir_ty;
+            }
+
+            match (&ty.sty, &hir_ty.node) {
+                // Check if the `argument_ty` is `&'X ..` where `'X`
+                // is the region we are looking for -- if so, and we have a `&T`
+                // on the RHS, then we want to highlight the `&` like so:
+                //
+                //     &
+                //     - let's call the lifetime of this reference `'1`
+                (ty::TyRef(region, referent_ty, _), hir::TyRptr(_lifetime, referent_hir_ty)) => {
+                    if region.to_region_vid() == needle_fr {
+                        let region_name = self.synthesize_region_name(counter);
+
+                        // Just grab the first character, the `&`.
+                        let codemap = tcx.sess.codemap();
+                        let ampersand_span = codemap.start_point(hir_ty.span);
+
+                        diag.span_label(
+                            ampersand_span,
+                            format!(
+                                "let's call the lifetime of this reference `{}`",
+                                region_name
+                            ),
+                        );
+
+                        return Some(region_name);
+                    }
+
+                    // Otherwise, let's descend into the referent types.
+                    search_stack.push((referent_ty, &referent_hir_ty.ty));
+                }
+
+                // Match up something like `Foo<'1>`
+                (ty::TyAdt(_adt_def, substs), hir::TyPath(hir::QPath::Resolved(None, path))) => {
+                    if let Some(last_segment) = path.segments.last() {
+                        if let Some(name) = self.match_adt_and_segment(
+                            substs,
+                            needle_fr,
+                            last_segment,
+                            counter,
+                            diag,
+                            search_stack,
+                        ) {
+                            return Some(name);
+                        }
+                    }
+                }
+
+                // The following cases don't have lifetimes, so we
+                // just worry about trying to match up the rustc type
+                // with the HIR types:
+                (ty::TyTuple(elem_tys), hir::TyTup(elem_hir_tys)) => {
+                    search_stack.extend(elem_tys.iter().cloned().zip(elem_hir_tys));
+                }
+
+                (ty::TySlice(elem_ty), hir::TySlice(elem_hir_ty))
+                | (ty::TyArray(elem_ty, _), hir::TyArray(elem_hir_ty, _)) => {
+                    search_stack.push((elem_ty, elem_hir_ty));
+                }
+
+                (ty::TyRawPtr(mut_ty), hir::TyPtr(mut_hir_ty)) => {
+                    search_stack.push((mut_ty.ty, &mut_hir_ty.ty));
+                }
+
+                _ => {
+                    // FIXME there are other cases that we could trace
+                }
+            }
+        }
+
+        let region_name = self.synthesize_region_name(counter);
+        diag.span_label(
+            closest_match.span,
+            format!("lifetime `{}` appears in this type", region_name),
+        );
+
+        return Some(region_name);
+    }
+
+    /// We've found an enum/struct/union type with the substitutions
+    /// `substs` and -- in the HIR -- a path type with the final
+    /// segment `last_segment`. Try to find a `'_` to highlight in
+    /// the generic args (or, if not, to produce new zipped pairs of
+    /// types+hir to search through).
+    fn match_adt_and_segment<'hir>(
+        &self,
+        substs: &'tcx Substs<'tcx>,
+        needle_fr: RegionVid,
+        last_segment: &'hir hir::PathSegment,
+        counter: &mut usize,
+        diag: &mut DiagnosticBuilder<'_>,
+        search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty)>,
+    ) -> Option<InternedString> {
+        // Did the user give explicit arguments? (e.g., `Foo<..>`)
+        let args = last_segment.args.as_ref()?;
+        let lifetime = self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
+        match lifetime.name {
+            hir::LifetimeName::Param(_)
+            | hir::LifetimeName::Static
+            | hir::LifetimeName::Underscore => {
+                let region_name = self.synthesize_region_name(counter);
+                let ampersand_span = lifetime.span;
+                diag.span_label(ampersand_span, format!("let's call this `{}`", region_name));
+                return Some(region_name);
+            }
+
+            hir::LifetimeName::Implicit => {
+                // In this case, the user left off the lifetime; so
+                // they wrote something like:
+                //
+                // ```
+                // x: Foo<T>
+                // ```
+                //
+                // where the fully elaborated form is `Foo<'_, '1,
+                // T>`. We don't consider this a match; instead we let
+                // the "fully elaborated" type fallback above handle
+                // it.
+                return None;
+            }
+        }
+    }
+
+    /// We've found an enum/struct/union type with the substitutions
+    /// `substs` and -- in the HIR -- a path with the generic
+    /// arguments `args`. If `needle_fr` appears in the args, return
+    /// the `hir::Lifetime` that corresponds to it. If not, push onto
+    /// `search_stack` the types+hir to search through.
+    fn try_match_adt_and_generic_args<'hir>(
+        &self,
+        substs: &'tcx Substs<'tcx>,
+        needle_fr: RegionVid,
+        args: &'hir hir::GenericArgs,
+        search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty)>,
+    ) -> Option<&'hir hir::Lifetime> {
+        for (kind, hir_arg) in substs.iter().zip(&args.args) {
+            match (kind.unpack(), hir_arg) {
+                (UnpackedKind::Lifetime(r), hir::GenericArg::Lifetime(lt)) => {
+                    if r.to_region_vid() == needle_fr {
+                        return Some(lt);
+                    }
+                }
+
+                (UnpackedKind::Type(ty), hir::GenericArg::Type(hir_ty)) => {
+                    search_stack.push((ty, hir_ty));
+                }
+
+                (UnpackedKind::Lifetime(_), _) | (UnpackedKind::Type(_), _) => {
+                    // I *think* that HIR lowering should ensure this
+                    // doesn't happen, even in erroneous
+                    // programs. Else we should use delay-span-bug.
+                    span_bug!(
+                        hir_arg.span(),
+                        "unmatched subst and hir arg: found {:?} vs {:?}",
+                        kind,
+                        hir_arg,
+                    );
+                }
+            }
+        }
+
+        None
+    }
+
+    /// Find a closure upvar that contains `fr` and label it with a
+    /// fully elaborated type, returning something like `'1`. Result
+    /// looks like:
+    ///
+    /// ```
+    ///  | let x = Some(&22);
+    ///        - fully elaborated type of `x` is `Option<&'1 u32>`
+    /// ```
+    fn give_name_if_anonymous_region_appears_in_upvars(
+        &self,
+        tcx: TyCtxt<'_, '_, 'tcx>,
+        mir: &Mir<'tcx>,
+        fr: RegionVid,
+        counter: &mut usize,
+        diag: &mut DiagnosticBuilder<'_>,
+    ) -> Option<InternedString> {
+        let upvar_index = self
+            .universal_regions
+            .defining_ty
+            .upvar_tys(tcx)
+            .position(|upvar_ty| {
+                debug!(
+                    "give_name_if_anonymous_region_appears_in_upvars: upvar_ty = {:?}",
+                    upvar_ty,
+                );
+                tcx.any_free_region_meets(&upvar_ty, |r| r.to_region_vid() == fr)
+            })?;
+
+        let upvar_ty = self
+            .universal_regions
+            .defining_ty
+            .upvar_tys(tcx)
+            .nth(upvar_index);
+
+        debug!(
+            "give_name_if_anonymous_region_appears_in_upvars: \
+             found {:?} in upvar {} which has type {:?}",
+            fr, upvar_index, upvar_ty,
+        );
+
+        let region_name = self.synthesize_region_name(counter);
+
+        let upvar_hir_id = mir.upvar_decls[upvar_index].var_hir_id.assert_crate_local();
+        let upvar_node_id = tcx.hir.hir_to_node_id(upvar_hir_id);
+        let upvar_span = tcx.hir.span(upvar_node_id);
+        let upvar_name = tcx.hir.name(upvar_node_id);
+        diag.span_label(
+            upvar_span,
+            format!(
+                "lifetime `{}` appears in the type of `{}`",
+                region_name, upvar_name,
+            ),
+        );
+
+        Some(region_name)
+    }
+
+    /// Check for arguments appearing in the (closure) return type. It
+    /// must be a closure since, in a free fn, such an argument would
+    /// have to either also appear in an argument (if using elision)
+    /// or be early bound (named, not in argument).
+    fn give_name_if_anonymous_region_appears_in_output(
+        &self,
+        tcx: TyCtxt<'_, '_, 'tcx>,
+        mir: &Mir<'tcx>,
+        fr: RegionVid,
+        counter: &mut usize,
+        diag: &mut DiagnosticBuilder<'_>,
+    ) -> Option<InternedString> {
+        let return_ty = self.universal_regions.unnormalized_output_ty;
+        debug!(
+            "give_name_if_anonymous_region_appears_in_output: return_ty = {:?}",
+            return_ty
+        );
+        if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) {
+            return None;
+        }
+
+        let region_name = self.synthesize_region_name(counter);
+        diag.span_label(
+            mir.span,
+            format!("lifetime `{}` appears in return type", region_name),
+        );
+
+        Some(region_name)
+    }
+
+    /// Create a synthetic region named `'1`, incrementing the
+    /// counter.
+    fn synthesize_region_name(&self, counter: &mut usize) -> InternedString {
+        let c = *counter;
+        *counter += 1;
+
+        Name::intern(&format!("'{:?}", c)).as_interned_str()
+    }
+}
index 13cc0c0419eab1673e0064fd9ab637f209161e71..164941203e05443a2319c59aac6ed8f5bc54ca15 100644 (file)
@@ -256,6 +256,11 @@ pub(crate) fn new(
     fn init_universal_regions(&mut self) {
         // Update the names (if any)
         for (external_name, variable) in self.universal_regions.named_universal_regions() {
+            debug!(
+                "init_universal_regions: region {:?} has external name {:?}",
+                variable,
+                external_name
+            );
             self.definitions[variable].external_name = Some(external_name);
         }
 
index ec8cd386679c39970592a29f82593069cfe3e189..8590e3d0765f0c9f77adbab6fba903a4bbae64a7 100644 (file)
 //! The code in this file doesn't *do anything* with those results; it
 //! just returns them for other code to use.
 
-use rustc::hir::{self, BodyOwnerKind, HirId};
+use either::Either;
 use rustc::hir::def_id::DefId;
-use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
-use rustc::infer::region_constraints::GenericKind;
+use rustc::hir::{self, BodyOwnerKind, HirId};
 use rustc::infer::outlives::bounds::{self, OutlivesBound};
 use rustc::infer::outlives::free_region_map::FreeRegionRelations;
-use rustc::ty::{self, RegionVid, Ty, TyCtxt, ClosureSubsts, GeneratorSubsts};
+use rustc::infer::region_constraints::GenericKind;
+use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::subst::Substs;
+use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, RegionVid, Ty, TyCtxt};
 use rustc::util::nodemap::FxHashMap;
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 use rustc_data_structures::transitive_relation::TransitiveRelation;
@@ -128,6 +129,34 @@ pub enum DefiningTy<'tcx> {
     Const(DefId, &'tcx Substs<'tcx>),
 }
 
+impl<'tcx> DefiningTy<'tcx> {
+    /// Returns a list of all the upvar types for this MIR. If this is
+    /// not a closure or generator, there are no upvars, and hence it
+    /// will be an empty list. The order of types in this list will
+    /// match up with the `upvar_decls` field of `Mir`.
+    pub fn upvar_tys(self, tcx: TyCtxt<'_, '_, 'tcx>) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
+        match self {
+            DefiningTy::Closure(def_id, substs) => Either::Left(substs.upvar_tys(def_id, tcx)),
+            DefiningTy::Generator(def_id, substs, _) => {
+                Either::Right(Either::Left(substs.upvar_tys(def_id, tcx)))
+            }
+            DefiningTy::FnDef(..) | DefiningTy::Const(..) => {
+                Either::Right(Either::Right(iter::empty()))
+            }
+        }
+    }
+
+    /// Number of implicit inputs -- notably the "environment"
+    /// parameter for closures -- that appear in MIR but not in the
+    /// user's code.
+    pub fn implicit_inputs(self) -> usize {
+        match self {
+            DefiningTy::Closure(..) | DefiningTy::Generator(..) => 1,
+            DefiningTy::FnDef(..) | DefiningTy::Const(..) => 0,
+        }
+    }
+}
+
 #[derive(Debug)]
 struct UniversalRegionIndices<'tcx> {
     /// For those regions that may appear in the parameter environment
@@ -493,18 +522,15 @@ fn build(mut self) -> UniversalRegions<'tcx> {
 
         debug!(
             "build: global regions = {}..{}",
-            FIRST_GLOBAL_INDEX,
-            first_extern_index
+            FIRST_GLOBAL_INDEX, first_extern_index
         );
         debug!(
             "build: extern regions = {}..{}",
-            first_extern_index,
-            first_local_index
+            first_extern_index, first_local_index
         );
         debug!(
             "build: local regions  = {}..{}",
-            first_local_index,
-            num_universals
+            first_local_index, num_universals
         );
 
         let yield_ty = match defining_ty {
@@ -545,10 +571,12 @@ fn defining_ty(&self) -> DefiningTy<'tcx> {
                     tables.node_id_to_type(self.mir_hir_id)
                 };
 
+                debug!("defining_ty (pre-replacement): {:?}", defining_ty);
+
                 let defining_ty = self.infcx
                     .replace_free_regions_with_nll_infer_vars(FR, &defining_ty);
 
-                match defining_ty.sty  {
+                match defining_ty.sty {
                     ty::TyClosure(def_id, substs) => DefiningTy::Closure(def_id, substs),
                     ty::TyGenerator(def_id, substs, movability) => {
                         DefiningTy::Generator(def_id, substs, movability)
@@ -587,8 +615,8 @@ fn compute_indices(
         let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id);
         let identity_substs = Substs::identity_for_item(gcx, closure_base_def_id);
         let fr_substs = match defining_ty {
-            DefiningTy::Closure(_, ClosureSubsts { ref substs }) |
-            DefiningTy::Generator(_, GeneratorSubsts { ref substs }, _) => {
+            DefiningTy::Closure(_, ClosureSubsts { ref substs })
+            DefiningTy::Generator(_, GeneratorSubsts { ref substs }, _) => {
                 // In the case of closures, we rely on the fact that
                 // the first N elements in the ClosureSubsts are
                 // inherited from the `closure_base_def_id`.
@@ -726,8 +754,7 @@ impl UniversalRegionRelations {
     fn relate_universal_regions(&mut self, fr_a: RegionVid, fr_b: RegionVid) {
         debug!(
             "relate_universal_regions: fr_a={:?} outlives fr_b={:?}",
-            fr_a,
-            fr_b
+            fr_a, fr_b
         );
         self.outlives.add(fr_a, fr_b);
         self.inverse_outlives.add(fr_b, fr_a);
@@ -780,8 +807,7 @@ fn replace_bound_regions_with_nll_infer_vars<T>(
     {
         debug!(
             "replace_bound_regions_with_nll_infer_vars(value={:?}, all_outlive_scope={:?})",
-            value,
-            all_outlive_scope,
+            value, all_outlive_scope,
         );
         let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| {
             let liberated_region = self.tcx.mk_region(ty::ReFree(ty::FreeRegion {
@@ -790,7 +816,10 @@ fn replace_bound_regions_with_nll_infer_vars<T>(
             }));
             let region_vid = self.next_nll_region_var(origin);
             indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid());
-            debug!("liberated_region={:?} => {:?}", liberated_region, region_vid);
+            debug!(
+                "liberated_region={:?} => {:?}",
+                liberated_region, region_vid
+            );
             region_vid
         });
         value
@@ -803,9 +832,8 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
     /// in later and instantiate the late-bound regions, and then we
     /// insert the `ReFree` version of those into the map as
     /// well. These are used for error reporting.
-    fn insert_late_bound_region(&mut self, r: ty::Region<'tcx>,
-                                vid: ty::RegionVid)
-    {
+    fn insert_late_bound_region(&mut self, r: ty::Region<'tcx>, vid: ty::RegionVid) {
+        debug!("insert_late_bound_region({:?}, {:?})", r, vid);
         self.indices.insert(r, vid);
     }
 
@@ -821,9 +849,9 @@ pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
         if let ty::ReVar(..) = r {
             r.to_region_vid()
         } else {
-            *self.indices.get(&r).unwrap_or_else(|| {
-                bug!("cannot convert `{:?}` to a region vid", r)
-            })
+            *self.indices
+                .get(&r)
+                .unwrap_or_else(|| bug!("cannot convert `{:?}` to a region vid", r))
         }
     }
 
index 8ae98bde003441452bae85e8a9a2f9e551e979f1..ca2a120ceb7375e3ece7b6eb3ed23e376a41fdbc 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use borrow_check::borrow_set::{BorrowSet, BorrowData, TwoPhaseUse};
+use borrow_check::borrow_set::{BorrowSet, BorrowData, TwoPhaseActivation};
 use borrow_check::places_conflict;
 use borrow_check::Context;
 use borrow_check::ShallowOrDeep;
@@ -83,11 +83,11 @@ pub(super) fn is_active<'tcx>(
 
     let activation_location = match borrow_data.activation_location {
         // If this is not a 2-phase borrow, it is always active.
-        None => return true,
+        TwoPhaseActivation::NotTwoPhase => return true,
         // And if the unique 2-phase use is not an activation, then it is *never* active.
-        Some((TwoPhaseUse::SharedUse, _)) => return false,
-        // Otherwise, we derive info from the activation point `v`:
-        Some((TwoPhaseUse::MutActivate, v)) => v,
+        TwoPhaseActivation::NotActivated => return false,
+        // Otherwise, we derive info from the activation point `loc`:
+        TwoPhaseActivation::ActivatedAt(loc) => loc,
     };
 
     // Otherwise, it is active for every location *except* in between
index 24bd675fac28e25f8eda73da69b4c60fbb012eb6..a9eec53fd94b28a2c4d7a7a70577ceda4484e3fe 100644 (file)
@@ -15,6 +15,7 @@
 use rustc::mir::{Mir, Place};
 use rustc::mir::{Projection, ProjectionElem};
 use rustc::ty::{self, TyCtxt};
+use std::cmp::max;
 
 pub(super) fn places_conflict<'gcx, 'tcx>(
     tcx: TyCtxt<'_, 'gcx, 'tcx>,
@@ -394,27 +395,78 @@ fn place_element_conflict<'a, 'gcx: 'tcx, 'tcx>(
                 | (ProjectionElem::Index(..), ProjectionElem::ConstantIndex { .. })
                 | (ProjectionElem::Index(..), ProjectionElem::Subslice { .. })
                 | (ProjectionElem::ConstantIndex { .. }, ProjectionElem::Index(..))
-                | (ProjectionElem::ConstantIndex { .. }, ProjectionElem::ConstantIndex { .. })
-                | (ProjectionElem::ConstantIndex { .. }, ProjectionElem::Subslice { .. })
-                | (ProjectionElem::Subslice { .. }, ProjectionElem::Index(..))
-                | (ProjectionElem::Subslice { .. }, ProjectionElem::ConstantIndex { .. })
-                | (ProjectionElem::Subslice { .. }, ProjectionElem::Subslice { .. }) => {
+                | (ProjectionElem::Subslice { .. }, ProjectionElem::Index(..)) => {
                     // Array indexes (`a[0]` vs. `a[i]`). These can either be disjoint
                     // (if the indexes differ) or equal (if they are the same), so this
                     // is the recursive case that gives "equal *or* disjoint" its meaning.
-                    //
-                    // Note that by construction, MIR at borrowck can't subdivide
-                    // `Subslice` accesses (e.g. `a[2..3][i]` will never be present) - they
-                    // are only present in slice patterns, and we "merge together" nested
-                    // slice patterns. That means we don't have to think about these. It's
-                    // probably a good idea to assert this somewhere, but I'm too lazy.
-                    //
-                    // FIXME(#8636) we might want to return Disjoint if
-                    // both projections are constant and disjoint.
-                    debug!("place_element_conflict: DISJOINT-OR-EQ-ARRAY");
+                    debug!("place_element_conflict: DISJOINT-OR-EQ-ARRAY-INDEX");
                     Overlap::EqualOrDisjoint
                 }
-
+                (ProjectionElem::ConstantIndex { offset: o1, min_length: _, from_end: false },
+                    ProjectionElem::ConstantIndex { offset: o2, min_length: _, from_end: false })
+                | (ProjectionElem::ConstantIndex { offset: o1, min_length: _, from_end: true },
+                    ProjectionElem::ConstantIndex {
+                        offset: o2, min_length: _, from_end: true }) => {
+                    if o1 == o2 {
+                        debug!("place_element_conflict: DISJOINT-OR-EQ-ARRAY-CONSTANT-INDEX");
+                        Overlap::EqualOrDisjoint
+                    } else {
+                        debug!("place_element_conflict: DISJOINT-ARRAY-CONSTANT-INDEX");
+                        Overlap::Disjoint
+                    }
+                }
+                (ProjectionElem::ConstantIndex {
+                    offset: offset_from_begin, min_length: min_length1, from_end: false },
+                    ProjectionElem::ConstantIndex {
+                        offset: offset_from_end, min_length: min_length2, from_end: true })
+                | (ProjectionElem::ConstantIndex {
+                    offset: offset_from_end, min_length: min_length1, from_end: true },
+                   ProjectionElem::ConstantIndex {
+                       offset: offset_from_begin, min_length: min_length2, from_end: false }) => {
+                    // both patterns matched so it must be at least the greater of the two
+                    let min_length = max(min_length1, min_length2);
+                    // `offset_from_end` can be in range `[1..min_length]`, 1 indicates the last
+                    // element (like -1 in Python) and `min_length` the first.
+                    // Therefore, `min_length - offset_from_end` gives the minimal possible
+                    // offset from the beginning
+                    if *offset_from_begin >= min_length - offset_from_end {
+                        debug!("place_element_conflict: DISJOINT-OR-EQ-ARRAY-CONSTANT-INDEX-FE");
+                        Overlap::EqualOrDisjoint
+                    } else {
+                        debug!("place_element_conflict: DISJOINT-ARRAY-CONSTANT-INDEX-FE");
+                        Overlap::Disjoint
+                    }
+                }
+                (ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false },
+                 ProjectionElem::Subslice {from, .. })
+                | (ProjectionElem::Subslice {from, .. },
+                    ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false }) => {
+                    if offset >= from {
+                        debug!(
+                            "place_element_conflict: DISJOINT-OR-EQ-ARRAY-CONSTANT-INDEX-SUBSLICE");
+                        Overlap::EqualOrDisjoint
+                    } else {
+                        debug!("place_element_conflict: DISJOINT-ARRAY-CONSTANT-INDEX-SUBSLICE");
+                        Overlap::Disjoint
+                    }
+                }
+                (ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true },
+                 ProjectionElem::Subslice {from: _, to })
+                | (ProjectionElem::Subslice {from: _, to },
+                    ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true }) => {
+                    if offset > to {
+                        debug!("place_element_conflict: \
+                               DISJOINT-OR-EQ-ARRAY-CONSTANT-INDEX-SUBSLICE-FE");
+                        Overlap::EqualOrDisjoint
+                    } else {
+                        debug!("place_element_conflict: DISJOINT-ARRAY-CONSTANT-INDEX-SUBSLICE-FE");
+                        Overlap::Disjoint
+                    }
+                }
+                (ProjectionElem::Subslice { .. }, ProjectionElem::Subslice { .. }) => {
+                    debug!("place_element_conflict: DISJOINT-OR-EQ-ARRAY-SUBSLICES");
+                     Overlap::EqualOrDisjoint
+                }
                 (ProjectionElem::Deref, _)
                 | (ProjectionElem::Field(..), _)
                 | (ProjectionElem::Index(..), _)
index a1cea9259f698da7d3b9b56c245820582a3c4c8f..7bd9a241a534ef3eaa72b58000e894f18dc5f4f0 100644 (file)
@@ -188,10 +188,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 0a53511a4f95d8c32e9e27293fe476fde5893574..cfdb8b0048a863024d38098fad80ea4a6d1b95dc 100644 (file)
@@ -535,6 +535,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
             };
             let mut decl = UpvarDecl {
                 debug_name: keywords::Invalid.name(),
+                var_hir_id: ClearCrossCrate::Set(var_hir_id),
                 by_ref,
                 mutability: Mutability::Not,
             };
@@ -542,13 +543,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");
                     }
                 }
             }
@@ -673,11 +675,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 e99c6f4f987a398ea86f7375c0f8221aedeb9c5a..2dc5138c6f08248b77810c6f176e78a8234f1096 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 e4cae5fe6c8266c2d2f1d2eb639061f7536009e7..e3b67b0a003efd2b202deafa16a4953f5466e885 100644 (file)
@@ -17,6 +17,7 @@
 
 use rustc::ty::{self, TyCtxt};
 use rustc::mir::{self, Mir, BasicBlock, BasicBlockData, Location, Statement, Terminator};
+use rustc::mir::traversal;
 use rustc::session::Session;
 
 use std::borrow::Borrow;
@@ -332,7 +333,7 @@ fn visit_terminator_entry(&mut self,
 
     fn analyze_results(&mut self, flow_uninit: &mut Self::FlowState) {
         let flow = flow_uninit;
-        for bb in self.mir().basic_blocks().indices() {
+        for (bb, _) in traversal::reverse_postorder(self.mir()) {
             flow.reset_to_entry_of(bb);
             self.process_basic_block(bb, flow);
         }
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 ea09bab5d1411f3a444a606522c928dc58062628..e84132f27cc62d66090b1f535c63aa6ec8b80f7f 100644 (file)
@@ -185,6 +185,7 @@ fn eval_body_using_ecx<'a, 'mir, 'tcx>(
     Ok((value, ptr, layout.ty))
 }
 
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct CompileTimeEvaluator;
 
 impl<'tcx> Into<EvalError<'tcx>> for ConstEvalError {
index 031c75013a27b00c684d2e371838c9f868546b47..a92c81e046a0ffd9f01d650d54875ab30191c272 100644 (file)
@@ -1,4 +1,5 @@
 use std::fmt::Write;
+use std::hash::{Hash, Hasher};
 use std::mem;
 
 use rustc::hir::def_id::DefId;
@@ -9,6 +10,7 @@
 use rustc::ty::subst::{Subst, Substs};
 use rustc::ty::{self, Ty, TyCtxt, TypeAndMut};
 use rustc::ty::query::TyCtxtAt;
+use rustc_data_structures::fx::{FxHashSet, FxHasher};
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use rustc::mir::interpret::{
     FrameInfo, GlobalId, Value, Scalar,
@@ -41,13 +43,17 @@ pub struct EvalContext<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
     /// The maximum number of stack frames allowed
     pub(crate) stack_limit: usize,
 
-    /// The maximum number of terminators that may be evaluated.
-    /// This prevents infinite loops and huge computations from freezing up const eval.
-    /// Remove once halting problem is solved.
-    pub(crate) terminators_remaining: usize,
+    /// When this value is negative, it indicates the number of interpreter
+    /// steps *until* the loop detector is enabled. When it is positive, it is
+    /// the number of steps after the detector has been enabled modulo the loop
+    /// detector period.
+    pub(crate) steps_since_detector_enabled: isize,
+
+    pub(crate) loop_detector: InfiniteLoopDetector<'a, 'mir, 'tcx, M>,
 }
 
 /// A stack frame.
+#[derive(Clone)]
 pub struct Frame<'mir, 'tcx: 'mir> {
     ////////////////////////////////////////////////////////////////////////////////
     // Function and callsite information
@@ -89,6 +95,121 @@ pub struct Frame<'mir, 'tcx: 'mir> {
     pub stmt: usize,
 }
 
+impl<'mir, 'tcx: 'mir> Eq for Frame<'mir, 'tcx> {}
+
+impl<'mir, 'tcx: 'mir> PartialEq for Frame<'mir, 'tcx> {
+    fn eq(&self, other: &Self) -> bool {
+        let Frame {
+            mir: _,
+            instance,
+            span: _,
+            return_to_block,
+            return_place,
+            locals,
+            block,
+            stmt,
+        } = self;
+
+        // Some of these are constant during evaluation, but are included
+        // anyways for correctness.
+        *instance == other.instance
+            && *return_to_block == other.return_to_block
+            && *return_place == other.return_place
+            && *locals == other.locals
+            && *block == other.block
+            && *stmt == other.stmt
+    }
+}
+
+impl<'mir, 'tcx: 'mir> Hash for Frame<'mir, 'tcx> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        let Frame {
+            mir: _,
+            instance,
+            span: _,
+            return_to_block,
+            return_place,
+            locals,
+            block,
+            stmt,
+        } = self;
+
+        instance.hash(state);
+        return_to_block.hash(state);
+        return_place.hash(state);
+        locals.hash(state);
+        block.hash(state);
+        stmt.hash(state);
+    }
+}
+
+/// The virtual machine state during const-evaluation at a given point in time.
+type EvalSnapshot<'a, 'mir, 'tcx, M>
+    = (M, Vec<Frame<'mir, 'tcx>>, Memory<'a, 'mir, 'tcx, M>);
+
+pub(crate) struct InfiniteLoopDetector<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
+    /// The set of all `EvalSnapshot` *hashes* observed by this detector.
+    ///
+    /// When a collision occurs in this table, we store the full snapshot in
+    /// `snapshots`.
+    hashes: FxHashSet<u64>,
+
+    /// The set of all `EvalSnapshot`s observed by this detector.
+    ///
+    /// An `EvalSnapshot` will only be fully cloned once it has caused a
+    /// collision in `hashes`. As a result, the detector must observe at least
+    /// *two* full cycles of an infinite loop before it triggers.
+    snapshots: FxHashSet<EvalSnapshot<'a, 'mir, 'tcx, M>>,
+}
+
+impl<'a, 'mir, 'tcx, M> Default for InfiniteLoopDetector<'a, 'mir, 'tcx, M>
+    where M: Machine<'mir, 'tcx>,
+          'tcx: 'a + 'mir,
+{
+    fn default() -> Self {
+        InfiniteLoopDetector {
+            hashes: FxHashSet::default(),
+            snapshots: FxHashSet::default(),
+        }
+    }
+}
+
+impl<'a, 'mir, 'tcx, M> InfiniteLoopDetector<'a, 'mir, 'tcx, M>
+    where M: Machine<'mir, 'tcx>,
+          'tcx: 'a + 'mir,
+{
+    /// Returns `true` if the loop detector has not yet observed a snapshot.
+    pub fn is_empty(&self) -> bool {
+        self.hashes.is_empty()
+    }
+
+    pub fn observe_and_analyze(
+        &mut self,
+        machine: &M,
+        stack: &Vec<Frame<'mir, 'tcx>>,
+        memory: &Memory<'a, 'mir, 'tcx, M>,
+    ) -> EvalResult<'tcx, ()> {
+        let snapshot = (machine, stack, memory);
+
+        let mut fx = FxHasher::default();
+        snapshot.hash(&mut fx);
+        let hash = fx.finish();
+
+        if self.hashes.insert(hash) {
+            // No collision
+            return Ok(())
+        }
+
+        if self.snapshots.insert((machine.clone(), stack.clone(), memory.clone())) {
+            // Spurious collision or first cycle
+            return Ok(())
+        }
+
+        // Second cycle
+        Err(EvalErrorKind::InfiniteLoop.into())
+    }
+}
+
 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
 pub enum StackPopCleanup {
     /// The stackframe existed to compute the initial value of a static/constant, make sure it
@@ -173,7 +294,7 @@ fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
     }
 }
 
-const MAX_TERMINATORS: usize = 1_000_000;
+const STEPS_UNTIL_DETECTOR_ENABLED: isize = 1_000_000;
 
 impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
     pub fn new(
@@ -189,16 +310,17 @@ pub fn new(
             memory: Memory::new(tcx, memory_data),
             stack: Vec::new(),
             stack_limit: tcx.sess.const_eval_stack_frame_limit,
-            terminators_remaining: MAX_TERMINATORS,
+            loop_detector: Default::default(),
+            steps_since_detector_enabled: -STEPS_UNTIL_DETECTOR_ENABLED,
         }
     }
 
     pub(crate) fn with_fresh_body<F: FnOnce(&mut Self) -> R, R>(&mut self, f: F) -> R {
         let stack = mem::replace(&mut self.stack, Vec::new());
-        let terminators_remaining = mem::replace(&mut self.terminators_remaining, MAX_TERMINATORS);
+        let steps = mem::replace(&mut self.steps_since_detector_enabled, -STEPS_UNTIL_DETECTOR_ENABLED);
         let r = f(self);
         self.stack = stack;
-        self.terminators_remaining = terminators_remaining;
+        self.steps_since_detector_enabled = steps;
         r
     }
 
@@ -538,8 +660,6 @@ pub(super) fn eval_rvalue_into_place(
             }
 
             Aggregate(ref kind, ref operands) => {
-                self.inc_step_counter_and_check_limit(operands.len());
-
                 let (dest, active_field_index) = match **kind {
                     mir::AggregateKind::Adt(adt_def, variant_index, _, active_field_index) => {
                         self.write_discriminant_value(dest_ty, dest, variant_index)?;
index 4d04900320fe900553bfd28b67feb7ebb868effe..e2086c57c7c7c5ee53da4097bda0f93610809dac 100644 (file)
@@ -2,6 +2,8 @@
 //! This separation exists to ensure that no fancy miri features like
 //! interpreting common C functions leak into CTFE.
 
+use std::hash::Hash;
+
 use rustc::mir::interpret::{AllocId, EvalResult, Scalar, Pointer, AccessKind, GlobalId};
 use super::{EvalContext, Place, ValTy, Memory};
 
@@ -13,9 +15,9 @@
 
 /// Methods of this trait signifies a point where CTFE evaluation would fail
 /// and some use case dependent behaviour can instead be applied
-pub trait Machine<'mir, 'tcx>: Sized {
+pub trait Machine<'mir, 'tcx>: Clone + Eq + Hash {
     /// Additional data that can be accessed via the Memory
-    type MemoryData;
+    type MemoryData: Clone + Eq + Hash;
 
     /// Additional memory kinds a machine wishes to distinguish from the builtin ones
     type MemoryKinds: ::std::fmt::Debug + PartialEq + Copy + Clone;
index 5cf734cce8a3f780f3aab248a3b05b41add99975..ac4d1c74b8cc1296d8e15eab450cc600ebabfa08 100644 (file)
@@ -1,4 +1,5 @@
 use std::collections::VecDeque;
+use std::hash::{Hash, Hasher};
 use std::ptr;
 
 use rustc::hir::def_id::DefId;
@@ -9,7 +10,7 @@
 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 rustc_data_structures::fx::{FxHashSet, FxHashMap, FxHasher};
 
 use syntax::ast::Mutability;
 
@@ -19,7 +20,7 @@
 // Allocations and pointers
 ////////////////////////////////////////////////////////////////////////////////
 
-#[derive(Debug, PartialEq, Copy, Clone)]
+#[derive(Debug, PartialEq, Eq, Copy, Clone)]
 pub enum MemoryKind<T> {
     /// Error if deallocated except during a stack pop
     Stack,
@@ -31,6 +32,7 @@ pub enum MemoryKind<T> {
 // Top-level interpreter memory
 ////////////////////////////////////////////////////////////////////////////////
 
+#[derive(Clone)]
 pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
     /// Additional data required by the Machine
     pub data: M::MemoryData,
@@ -47,6 +49,64 @@ pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
     pub tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
 }
 
+impl<'a, 'mir, 'tcx, M> Eq for Memory<'a, 'mir, 'tcx, M>
+    where M: Machine<'mir, 'tcx>,
+          'tcx: 'a + 'mir,
+{}
+
+impl<'a, 'mir, 'tcx, M> PartialEq for Memory<'a, 'mir, 'tcx, M>
+    where M: Machine<'mir, 'tcx>,
+          'tcx: 'a + 'mir,
+{
+    fn eq(&self, other: &Self) -> bool {
+        let Memory {
+            data,
+            alloc_kind,
+            alloc_map,
+            cur_frame,
+            tcx: _,
+        } = self;
+
+        *data == other.data
+            && *alloc_kind == other.alloc_kind
+            && *alloc_map == other.alloc_map
+            && *cur_frame == other.cur_frame
+    }
+}
+
+impl<'a, 'mir, 'tcx, M> Hash for Memory<'a, 'mir, 'tcx, M>
+    where M: Machine<'mir, 'tcx>,
+          'tcx: 'a + 'mir,
+{
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        let Memory {
+            data,
+            alloc_kind: _,
+            alloc_map: _,
+            cur_frame,
+            tcx: _,
+        } = self;
+
+        data.hash(state);
+        cur_frame.hash(state);
+
+        // We ignore some fields which don't change between evaluation steps.
+
+        // Since HashMaps which contain the same items may have different
+        // iteration orders, we use a commutative operation (in this case
+        // addition, but XOR would also work), to combine the hash of each
+        // `Allocation`.
+        self.allocations()
+            .map(|allocs| {
+                let mut h = FxHasher::default();
+                allocs.hash(&mut h);
+                h.finish()
+            })
+            .fold(0u64, |hash, x| hash.wrapping_add(x))
+            .hash(state);
+    }
+}
+
 impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
     pub fn new(tcx: TyCtxtAt<'a, 'tcx, 'tcx>, data: M::MemoryData) -> Self {
         Memory {
@@ -866,7 +926,7 @@ fn copy_undef_mask(
 
         for i in 0..size.bytes() {
             let defined = undef_mask.get(src.offset + Size::from_bytes(i));
-            
+
             for j in 0..repeat {
                 dest_allocation.undef_mask.set(
                     dest.offset + Size::from_bytes(i + (size.bytes() * j)),
index 51b33fa54b249e517d44f2674b704d66ddb42ab8..bb8e5c99d499be8fc3e64017db1fff181a851d1a 100644 (file)
@@ -7,7 +7,7 @@
 use super::{EvalContext, Machine, ValTy};
 use interpret::memory::HasMemory;
 
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
 pub enum Place {
     /// A place referring to a value allocated in the `Memory` system.
     Ptr {
@@ -24,7 +24,7 @@ pub enum Place {
     Local { frame: usize, local: mir::Local },
 }
 
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
 pub enum PlaceExtra {
     None,
     Length(u64),
index ab15278219f40aa5fa5cdad605d7dcde6421f037..db90714d0e6231d7b747fa142f8c6e21d112ac00 100644 (file)
@@ -8,13 +8,34 @@
 use super::{EvalContext, Machine};
 
 impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
-    pub fn inc_step_counter_and_check_limit(&mut self, n: usize) {
-        self.terminators_remaining = self.terminators_remaining.saturating_sub(n);
-        if self.terminators_remaining == 0 {
+    pub fn inc_step_counter_and_detect_loops(&mut self) -> EvalResult<'tcx, ()> {
+        /// The number of steps between loop detector snapshots.
+        /// Should be a power of two for performance reasons.
+        const DETECTOR_SNAPSHOT_PERIOD: isize = 256;
+
+        {
+            let steps = &mut self.steps_since_detector_enabled;
+
+            *steps += 1;
+            if *steps < 0 {
+                return Ok(());
+            }
+
+            *steps %= DETECTOR_SNAPSHOT_PERIOD;
+            if *steps != 0 {
+                return Ok(());
+            }
+        }
+
+        if self.loop_detector.is_empty() {
+            // First run of the loop detector
+
             // FIXME(#49980): make this warning a lint
-            self.tcx.sess.span_warn(self.frame().span, "Constant evaluating a complex constant, this might take some time");
-            self.terminators_remaining = 1_000_000;
+            self.tcx.sess.span_warn(self.frame().span,
+                "Constant evaluating a complex constant, this might take some time");
         }
+
+        self.loop_detector.observe_and_analyze(&self.machine, &self.stack, &self.memory)
     }
 
     /// Returns true as long as there are more things to do.
@@ -36,7 +57,7 @@ pub fn step(&mut self) -> EvalResult<'tcx, bool> {
             return Ok(true);
         }
 
-        self.inc_step_counter_and_check_limit(1);
+        self.inc_step_counter_and_detect_loops()?;
 
         let terminator = basic_block.terminator();
         assert_eq!(old_frames, self.cur_frame());
index 3a046cd800a3e1db0419999a10f86ed804c40d61..ce917b8ca5516bc71e2a8abfe6cb5d9909c549a0 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) => {
@@ -421,6 +414,9 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         MonoItem::GlobalAsm(..) => {
             recursion_depth_reset = None;
         }
+        MonoItem::CustomSection(..) => {
+            recursion_depth_reset = None;
+        }
     }
 
     record_accesses(tcx, starting_point, &neighbors[..], inlining_map);
@@ -997,6 +993,13 @@ fn visit_item(&mut self, item: &'v hir::Item) {
             hir::ItemConst(..) => {
                 // const items only generate mono items if they are
                 // actually used somewhere. Just declaring them is insufficient.
+
+                let def_id = self.tcx.hir.local_def_id(item.id);
+                if self.tcx.sess.opts.target_triple.triple().starts_with("wasm32") &&
+                    self.tcx.codegen_fn_attrs(def_id).wasm_custom_section.is_some()
+                {
+                    self.output.push(MonoItem::CustomSection(def_id));
+                }
             }
             hir::ItemFn(..) => {
                 let def_id = self.tcx.hir.local_def_id(item.id);
index 0428489fd8d78b06c831d1559a2b17740a8042be..1389ad63c3a3b0bf27fa4cc66a3698c57dfa75ce 100644 (file)
@@ -63,6 +63,7 @@ fn is_generic_fn(&self) -> bool {
                 instance.substs.types().next().is_some()
             }
             MonoItem::Static(..) |
+            MonoItem::CustomSection(..) |
             MonoItem::GlobalAsm(..) => false,
         }
     }
@@ -73,6 +74,9 @@ fn symbol_name(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::SymbolName {
             MonoItem::Static(def_id) => {
                 tcx.symbol_name(Instance::mono(tcx, def_id))
             }
+            MonoItem::CustomSection(def_id) => {
+                tcx.symbol_name(Instance::mono(tcx, def_id))
+            }
             MonoItem::GlobalAsm(node_id) => {
                 let def_id = tcx.hir.local_def_id(node_id);
                 ty::SymbolName {
@@ -121,9 +125,8 @@ fn instantiation_mode(&self,
                     }
                 }
             }
-            MonoItem::Static(..) => {
-                InstantiationMode::GloballyShared { may_conflict: false }
-            }
+            MonoItem::Static(..) |
+            MonoItem::CustomSection(..) |
             MonoItem::GlobalAsm(..) => {
                 InstantiationMode::GloballyShared { may_conflict: false }
             }
@@ -134,6 +137,7 @@ fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<Linkage> {
         let def_id = match *self.as_mono_item() {
             MonoItem::Fn(ref instance) => instance.def_id(),
             MonoItem::Static(def_id) => def_id,
+            MonoItem::CustomSection(..) => return None,
             MonoItem::GlobalAsm(..) => return None,
         };
 
@@ -171,6 +175,7 @@ fn is_instantiable(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
         let (def_id, substs) = match *self.as_mono_item() {
             MonoItem::Fn(ref instance) => (instance.def_id(), instance.substs),
             MonoItem::Static(def_id) => (def_id, Substs::empty()),
+            MonoItem::CustomSection(..) => return true,
             // global asm never has predicates
             MonoItem::GlobalAsm(..) => return true
         };
@@ -187,6 +192,10 @@ fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
                 let instance = Instance::new(def_id, tcx.intern_substs(&[]));
                 to_string_internal(tcx, "static ", instance)
             },
+            MonoItem::CustomSection(def_id) => {
+                let instance = Instance::new(def_id, tcx.intern_substs(&[]));
+                to_string_internal(tcx, "custom-section ", instance)
+            },
             MonoItem::GlobalAsm(..) => {
                 "global_asm".to_string()
             }
@@ -212,6 +221,9 @@ fn local_span(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<Span> {
             MonoItem::Static(def_id) => {
                 tcx.hir.as_local_node_id(def_id)
             }
+            MonoItem::CustomSection(def_id) => {
+                tcx.hir.as_local_node_id(def_id)
+            }
             MonoItem::GlobalAsm(node_id) => {
                 Some(node_id)
             }
index f83ea6fa13b5284b1fb1cb349f181d2f987fe127..5f15870d6fbc306c4e7d2c5725cc4f9180ab9eea 100644 (file)
@@ -180,7 +180,8 @@ fn item_sort_key<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                         }
                     }
                 }
-                MonoItem::Static(def_id) => {
+                MonoItem::Static(def_id) |
+                MonoItem::CustomSection(def_id) => {
                     tcx.hir.as_local_node_id(def_id)
                 }
                 MonoItem::GlobalAsm(node_id) => {
@@ -449,6 +450,9 @@ fn place_root_mono_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                         };
                         (Linkage::External, visibility)
                     }
+                    MonoItem::CustomSection(..) => {
+                        (Linkage::External, Visibility::Hidden)
+                    }
                     MonoItem::GlobalAsm(node_id) => {
                         let def_id = tcx.hir.local_def_id(node_id);
                         let visibility = if tcx.is_reachable_non_generic(def_id) {
@@ -714,6 +718,7 @@ fn characteristic_def_id_of_mono_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             Some(def_id)
         }
         MonoItem::Static(def_id) => Some(def_id),
+        MonoItem::CustomSection(def_id) => Some(def_id),
         MonoItem::GlobalAsm(node_id) => Some(tcx.hir.local_def_id(node_id)),
     }
 }
index 00e064fbb4717ce541a61a629ab05e021bfd8367..7768e96d036125f007511c52794f4b7eab6791e7 100644 (file)
@@ -85,7 +85,9 @@ fn visit_terminator(&mut self,
                 let func_ty = func.ty(self.mir, self.tcx);
                 let sig = func_ty.fn_sig(self.tcx);
                 if let hir::Unsafety::Unsafe = sig.unsafety() {
-                    self.require_unsafe("call to unsafe function")
+                    self.require_unsafe("call to unsafe function",
+                        "consult the function's documentation for information on how to avoid \
+                         undefined behavior")
                 }
             }
         }
@@ -112,7 +114,8 @@ fn visit_statement(&mut self,
             }
 
             StatementKind::InlineAsm { .. } => {
-                self.require_unsafe("use of inline assembly")
+                self.require_unsafe("use of inline assembly",
+                    "inline assembly is entirely unchecked and can cause undefined behavior")
             },
         }
         self.super_statement(block, statement, location);
@@ -151,6 +154,11 @@ fn visit_place(&mut self,
                 self.register_violations(&[UnsafetyViolation {
                     source_info,
                     description: Symbol::intern("borrow of packed field").as_interned_str(),
+                    details:
+                        Symbol::intern("fields of packed structs might be misaligned: \
+                                        dereferencing a misaligned pointer or even just creating a \
+                                        misaligned reference is undefined behavior")
+                            .as_interned_str(),
                     kind: UnsafetyViolationKind::BorrowPacked(lint_root)
                 }], &[]);
             }
@@ -172,7 +180,10 @@ fn visit_place(&mut self,
                 let base_ty = base.ty(self.mir, self.tcx).to_ty(self.tcx);
                 match base_ty.sty {
                     ty::TyRawPtr(..) => {
-                        self.require_unsafe("dereference of raw pointer")
+                        self.require_unsafe("dereference of raw pointer",
+                            "raw pointers may be NULL, dangling or unaligned; they can violate \
+                             aliasing rules and cause data races: all of these are undefined \
+                             behavior")
                     }
                     ty::TyAdt(adt, _) => {
                         if adt.is_union() {
@@ -190,12 +201,17 @@ fn visit_place(&mut self,
                                 if elem_ty.moves_by_default(self.tcx, self.param_env,
                                                             self.source_info.span) {
                                     self.require_unsafe(
-                                        "assignment to non-`Copy` union field")
+                                        "assignment to non-`Copy` union field",
+                                        "the previous content of the field will be dropped, which \
+                                         causes undefined behavior if the field was not properly \
+                                         initialized")
                                 } else {
                                     // write to non-move union, safe
                                 }
                             } else {
-                                self.require_unsafe("access to union field")
+                                self.require_unsafe("access to union field",
+                                    "the field may not be properly initialized: using \
+                                     uninitialized data will cause undefined behavior")
                             }
                         }
                     }
@@ -208,7 +224,9 @@ fn visit_place(&mut self,
             }
             &Place::Static(box Static { def_id, ty: _ }) => {
                 if self.tcx.is_static(def_id) == Some(hir::Mutability::MutMutable) {
-                    self.require_unsafe("use of mutable static");
+                    self.require_unsafe("use of mutable static",
+                        "mutable statics can be mutated by multiple threads: aliasing violations \
+                         or data races will cause undefined behavior");
                 } else if self.tcx.is_foreign_item(def_id) {
                     let source_info = self.source_info;
                     let lint_root =
@@ -216,6 +234,11 @@ fn visit_place(&mut self,
                     self.register_violations(&[UnsafetyViolation {
                         source_info,
                         description: Symbol::intern("use of extern static").as_interned_str(),
+                        details:
+                            Symbol::intern("extern statics are not controlled by the Rust type \
+                                            system: invalid data, aliasing violations or data \
+                                            races will cause undefined behavior")
+                                .as_interned_str(),
                         kind: UnsafetyViolationKind::ExternStatic(lint_root)
                     }], &[]);
                 }
@@ -227,12 +250,14 @@ fn visit_place(&mut self,
 
 impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
     fn require_unsafe(&mut self,
-                      description: &'static str)
+                      description: &'static str,
+                      details: &'static str)
     {
         let source_info = self.source_info;
         self.register_violations(&[UnsafetyViolation {
             source_info,
             description: Symbol::intern(description).as_interned_str(),
+            details: Symbol::intern(details).as_interned_str(),
             kind: UnsafetyViolationKind::General,
         }], &[]);
     }
@@ -437,33 +462,36 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
     } = tcx.unsafety_check_result(def_id);
 
     for &UnsafetyViolation {
-        source_info, description, kind
+        source_info, description, details, kind
     } in violations.iter() {
         // Report an error.
         match kind {
             UnsafetyViolationKind::General => {
                 struct_span_err!(
                     tcx.sess, source_info.span, E0133,
-                    "{} requires unsafe function or block", description)
+                    "{} is unsafe and requires unsafe function or block", description)
                     .span_label(source_info.span, &description.as_str()[..])
+                    .note(&details.as_str()[..])
                     .emit();
             }
             UnsafetyViolationKind::ExternStatic(lint_node_id) => {
-                tcx.lint_node(SAFE_EXTERN_STATICS,
+                tcx.lint_node_note(SAFE_EXTERN_STATICS,
                               lint_node_id,
                               source_info.span,
-                              &format!("{} requires unsafe function or \
-                                        block (error E0133)", &description.as_str()[..]));
+                              &format!("{} is unsafe and requires unsafe function or block \
+                                        (error E0133)", &description.as_str()[..]),
+                              &details.as_str()[..]);
             }
             UnsafetyViolationKind::BorrowPacked(lint_node_id) => {
                 if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) {
                     tcx.unsafe_derive_on_repr_packed(impl_def_id);
                 } else {
-                    tcx.lint_node(SAFE_PACKED_BORROWS,
+                    tcx.lint_node_note(SAFE_PACKED_BORROWS,
                                   lint_node_id,
                                   source_info.span,
-                                  &format!("{} requires unsafe function or \
-                                            block (error E0133)", &description.as_str()[..]));
+                                  &format!("{} is unsafe and requires unsafe function or block \
+                                            (error E0133)", &description.as_str()[..]),
+                                  &details.as_str()[..]);
                 }
             }
         }
index 06be2bb3734f438e8defeb49c3148e2db83f2c7a..90dfebeef1b0ca7b0bb194b1bc46d3808e2ca251 100644 (file)
@@ -225,7 +225,10 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
     // (Mir-)Borrowck uses `mir_validated`, so we have to force it to
     // execute before we can steal.
     let _ = tcx.mir_borrowck(def_id);
-    let _ = tcx.borrowck(def_id);
+
+    if tcx.use_ast_borrowck() {
+        let _ = tcx.borrowck(def_id);
+    }
 
     let mut mir = tcx.mir_validated(def_id).steal();
     run_passes![tcx, mir, def_id, 2;
index b23f05680121028dfd34f1f69dad8783215d9582..da149f420644c5cd551dfd04cb013150b334caaa 100644 (file)
@@ -36,7 +36,7 @@ fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                           src: MirSource, mir: &mut Mir<'tcx>) {
         let def_id = src.def_id;
         let id = tcx.hir.as_local_node_id(def_id).unwrap();
-        if !tcx.has_attr(def_id, "rustc_mir_borrowck") {
+        if !tcx.has_attr(def_id, "rustc_mir") {
             debug!("skipping rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id));
             return;
         } else {
index 4630cdae47d627d855c5e3fa5e71e2e76fa753a3..e1d5e302c3a062fad7142faec591004c7802a1f1 100644 (file)
@@ -179,27 +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);
-        }
-    }
-
-    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,
@@ -208,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);
+        }
     }
 }
 
@@ -304,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)
     }
@@ -338,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) {
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 e9d03daa7ea06b82dd3d5e5794f4f9883204edfc..c3ee98039f3f6fb197d959b07dcf9ba9f905f27f 100644 (file)
@@ -40,7 +40,6 @@
 use syntax::ast;
 use syntax::attr;
 use syntax_pos::{Span, DUMMY_SP};
-use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 
 pub fn provide(providers: &mut Providers) {
     *providers = Providers {
@@ -65,7 +64,7 @@ fn const_is_rvalue_promotable_to_static<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     assert!(def_id.is_local());
 
     let node_id = tcx.hir.as_local_node_id(def_id)
-                     .expect("rvalue_promotable_map invoked with non-local def-id");
+        .expect("rvalue_promotable_map invoked with non-local def-id");
     let body_id = tcx.hir.body_owned_by(node_id);
     let body_hir_id = tcx.hir.node_to_hir_id(body_id.node_id);
     tcx.rvalue_promotable_map(def_id).contains(&body_hir_id.local_id)
@@ -94,7 +93,7 @@ fn rvalue_promotable_map<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     // `def_id` should be a `Body` owner
     let node_id = tcx.hir.as_local_node_id(def_id)
-                     .expect("rvalue_promotable_map invoked with non-local def-id");
+        .expect("rvalue_promotable_map invoked with non-local def-id");
     let body_id = tcx.hir.body_owned_by(node_id);
     visitor.visit_nested_body(body_id);
 
@@ -117,7 +116,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
     // Returns true iff all the values of the type are promotable.
     fn type_has_only_promotable_values(&mut self, ty: Ty<'gcx>) -> bool {
         ty.is_freeze(self.tcx, self.param_env, DUMMY_SP) &&
-        !ty.needs_drop(self.tcx, self.param_env)
+            !ty.needs_drop(self.tcx, self.param_env)
     }
 
     fn handle_const_fn_call(&mut self, def_id: DefId, ret_ty: Ty<'gcx>, span: Span) {
@@ -133,9 +132,9 @@ fn handle_const_fn_call(&mut self, def_id: DefId, ret_ty: Ty<'gcx>, span: Span)
 
         if let Some(&attr::Stability {
             rustc_const_unstable: Some(attr::RustcConstUnstable {
-                feature: ref feature_name
-            }),
-        .. }) = self.tcx.lookup_stability(def_id) {
+                                           feature: ref feature_name
+                                       }),
+            .. }) = self.tcx.lookup_stability(def_id) {
             self.promotable &=
                 // feature-gate is enabled,
                 self.tcx.features()
@@ -143,11 +142,11 @@ fn handle_const_fn_call(&mut self, def_id: DefId, ret_ty: Ty<'gcx>, span: Span)
                     .iter()
                     .any(|&(ref sym, _)| sym == feature_name) ||
 
-                // this comes from a crate with the feature-gate enabled,
-                !def_id.is_local() ||
+                    // this comes from a crate with the feature-gate enabled,
+                    !def_id.is_local() ||
 
-                // this comes from a macro that has #[allow_internal_unstable]
-                span.allows_unstable();
+                    // this comes from a macro that has #[allow_internal_unstable]
+                    span.allows_unstable();
         }
     }
 
@@ -169,12 +168,7 @@ fn remove_mut_rvalue_borrow(&mut self, pat: &hir::Pat) -> bool {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
-    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        // note that we *do* visit nested bodies, because we override `visit_nested_body` below
-        NestedVisitorMap::None
-    }
-
+impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
     fn visit_nested_body(&mut self, body_id: hir::BodyId) {
         let item_id = self.tcx.hir.body_owner(body_id);
         let item_def_id = self.tcx.hir.local_def_id(item_id);
@@ -206,8 +200,7 @@ fn visit_nested_body(&mut self, body_id: hir::BodyId) {
         euv::ExprUseVisitor::new(self, tcx, param_env, &region_scope_tree, self.tables, None)
             .consume_body(body);
 
-        self.visit_body(body);
-
+        self.visit_expr(&body.value);
         self.in_fn = outer_in_fn;
         self.tables = outer_tables;
         self.param_env = outer_param_env;
@@ -216,27 +209,31 @@ fn visit_nested_body(&mut self, body_id: hir::BodyId) {
 
     fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt) {
         match stmt.node {
-            hir::StmtDecl(ref decl, _) => {
+            hir::StmtDecl(ref decl, _node_id) => {
                 match &decl.node {
                     hir::DeclLocal(local) => {
                         self.promotable = false;
-
                         if self.remove_mut_rvalue_borrow(&local.pat) {
                             if let Some(init) = &local.init {
                                 self.mut_rvalue_borrows.insert(init.id);
                             }
                         }
+
+                        match local.init {
+                            Some(ref expr) => self.visit_expr(&expr),
+                            None => {},
+                        }
                     }
                     // Item statements are allowed
                     hir::DeclItem(_) => {}
                 }
             }
-            hir::StmtExpr(..) |
-            hir::StmtSemi(..) => {
+            hir::StmtExpr(ref box_expr, _node_id) |
+            hir::StmtSemi(ref box_expr, _node_id) => {
+                self.visit_expr(box_expr);
                 self.promotable = false;
             }
         }
-        intravisit::walk_stmt(self, stmt);
     }
 
     fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
@@ -247,20 +244,6 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
         check_expr(self, ex, node_ty);
         check_adjustments(self, ex);
 
-        if let hir::ExprMatch(ref discr, ref arms, _) = ex.node {
-            // Compute the most demanding borrow from all the arms'
-            // patterns and set that on the discriminator.
-            let mut mut_borrow = false;
-            for pat in arms.iter().flat_map(|arm| &arm.pats) {
-                mut_borrow = self.remove_mut_rvalue_borrow(pat);
-            }
-            if mut_borrow {
-                self.mut_rvalue_borrows.insert(discr.id);
-            }
-        }
-
-        intravisit::walk_expr(self, ex);
-
         // Handle borrows on (or inside the autorefs of) this expression.
         if self.mut_rvalue_borrows.remove(&ex.id) {
             self.promotable = false;
@@ -271,6 +254,16 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
         }
         self.promotable &= outer;
     }
+
+    fn visit_block(&mut self, block: &'tcx hir::Block) {
+        for index in block.stmts.iter() {
+            self.visit_stmt(index)
+        }
+        match block.expr {
+            Some(ref box_expr) => { self.visit_expr(&*box_expr) },
+            None => {},
+        }
+    }
 }
 
 /// This function is used to enforce the constraints on
@@ -279,7 +272,9 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
 /// every nested expression. If the expression is not part
 /// of a const/static item, it is qualified for promotion
 /// instead of producing errors.
-fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node_ty: Ty<'tcx>) {
+fn check_expr<'a, 'tcx>(
+    v: &mut CheckCrateVisitor<'a, 'tcx>,
+    e: &'tcx hir::Expr, node_ty: Ty<'tcx>) {
     match node_ty.sty {
         ty::TyAdt(def, _) if def.has_dtor(v.tcx) => {
             v.promotable = false;
@@ -288,25 +283,30 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
     }
 
     match e.node {
-        hir::ExprUnary(..) |
-        hir::ExprBinary(..) |
-        hir::ExprIndex(..) if v.tables.is_method_call(e) => {
+        hir::ExprBox(ref expr) => {
+            v.visit_expr(&expr);
             v.promotable = false;
         }
-        hir::ExprBox(_) => {
-            v.promotable = false;
-        }
-        hir::ExprUnary(op, _) => {
+        hir::ExprUnary(op, ref expr) => {
+            if v.tables.is_method_call(e) {
+                v.promotable = false;
+            }
             if op == hir::UnDeref {
                 v.promotable = false;
             }
+            v.visit_expr(expr);
         }
-        hir::ExprBinary(op, ref lhs, _) => {
+        hir::ExprBinary(op, ref lhs, ref rhs) => {
+            if v.tables.is_method_call(e) {
+                v.promotable = false;
+            }
+            v.visit_expr(lhs);
+            v.visit_expr(rhs);
             match v.tables.node_id_to_type(lhs.hir_id).sty {
                 ty::TyRawPtr(_) => {
                     assert!(op.node == hir::BiEq || op.node == hir::BiNe ||
-                            op.node == hir::BiLe || op.node == hir::BiLt ||
-                            op.node == hir::BiGe || op.node == hir::BiGt);
+                        op.node == hir::BiLe || op.node == hir::BiLt ||
+                        op.node == hir::BiGe || op.node == hir::BiGt);
 
                     v.promotable = false;
                 }
@@ -314,6 +314,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
             }
         }
         hir::ExprCast(ref from, _) => {
+            v.visit_expr(from);
             debug!("Checking const cast(id={})", from.id);
             match v.tables.cast_kinds().get(from.hir_id) {
                 None => v.tcx.sess.delay_span_bug(e.span, "no kind for cast"),
@@ -379,7 +380,11 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
                 }
             }
         }
-        hir::ExprCall(ref callee, _) => {
+        hir::ExprCall(ref callee, ref hirvec) => {
+            v.visit_expr(callee);
+            for index in hirvec.iter() {
+                v.visit_expr(index)
+            }
             let mut callee = &**callee;
             loop {
                 callee = match callee.node {
@@ -413,7 +418,10 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
                 _ => v.promotable = false
             }
         }
-        hir::ExprMethodCall(..) => {
+        hir::ExprMethodCall(ref _pathsegment, ref _span, ref hirvec) => {
+            for index in hirvec.iter() {
+                v.visit_expr(index)
+            }
             if let Some(def) = v.tables.type_dependent_defs().get(e.hir_id) {
                 let def_id = def.def_id();
                 match v.tcx.associated_item(def_id).container {
@@ -424,7 +432,14 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
                 v.tcx.sess.delay_span_bug(e.span, "no type-dependent def for method call");
             }
         }
-        hir::ExprStruct(..) => {
+        hir::ExprStruct(ref _qpath, ref hirvec, ref option_expr) => {
+            for index in hirvec.iter() {
+                v.visit_expr(&index.expr);
+            }
+            match *option_expr {
+                Some(ref expr) => { v.visit_expr(&expr) },
+                None => {},
+            }
             if let ty::TyAdt(adt, ..) = v.tables.expr_ty(e).sty {
                 // unsafe_cell_type doesn't necessarily exist with no_core
                 if Some(adt.did) == v.tcx.lang_items().unsafe_cell_type() {
@@ -433,11 +448,16 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
             }
         }
 
-        hir::ExprLit(_) |
-        hir::ExprAddrOf(..) |
-        hir::ExprRepeat(..) => {}
+        hir::ExprLit(_) => {}
 
-        hir::ExprClosure(..) => {
+        hir::ExprAddrOf(_, ref expr) |
+        hir::ExprRepeat(ref expr, _) => {
+            v.visit_expr(expr);
+        }
+
+        hir::ExprClosure(_capture_clause, ref _box_fn_decl,
+                         body_id, _span, _option_generator_movability) => {
+            v.visit_nested_body(body_id);
             // Paths in constant contexts cannot refer to local variables,
             // as there are none, and thus closures can't have upvars there.
             if v.tcx.with_freevars(e.id, |fv| !fv.is_empty()) {
@@ -445,7 +465,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
             }
         }
 
-        hir::ExprField(ref expr, _) => {
+        hir::ExprField(ref expr, _ident) => {
+            v.visit_expr(expr);
             if let Some(def) = v.tables.expr_ty(expr).ty_adt_def() {
                 if def.is_union() {
                     v.promotable = false
@@ -453,32 +474,113 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
             }
         }
 
-        hir::ExprBlock(..) |
-        hir::ExprIndex(..) |
-        hir::ExprArray(_) |
-        hir::ExprType(..) |
-        hir::ExprTup(..) => {}
+        hir::ExprBlock(ref box_block, ref _option_label) => {
+            v.visit_block(box_block);
+        }
+
+        hir::ExprIndex(ref lhs, ref rhs) => {
+            if v.tables.is_method_call(e) {
+                v.promotable = false;
+            }
+            v.visit_expr(lhs);
+            v.visit_expr(rhs);
+        }
+
+        hir::ExprArray(ref hirvec) => {
+            for index in hirvec.iter() {
+                v.visit_expr(index)
+            }
+        }
+
+        hir::ExprType(ref expr, ref _ty) => {
+            v.visit_expr(expr);
+        }
+
+        hir::ExprTup(ref hirvec) => {
+            for index in hirvec.iter() {
+                v.visit_expr(index)
+            }
+        }
+
 
         // Conditional control flow (possible to implement).
-        hir::ExprMatch(..) |
-        hir::ExprIf(..) |
+        hir::ExprMatch(ref expr, ref hirvec_arm, ref _match_source) => {
+            // Compute the most demanding borrow from all the arms'
+            // patterns and set that on the discriminator.
+            let mut mut_borrow = false;
+            for pat in hirvec_arm.iter().flat_map(|arm| &arm.pats) {
+                mut_borrow = v.remove_mut_rvalue_borrow(pat);
+            }
+            if mut_borrow {
+                v.mut_rvalue_borrows.insert(expr.id);
+            }
+
+            v.visit_expr(expr);
+            for index in hirvec_arm.iter() {
+                v.visit_expr(&*index.body);
+                match index.guard {
+                    Some(ref expr) => v.visit_expr(&expr),
+                    None => {},
+                }
+            }
+            v.promotable = false;
+        }
+
+        hir::ExprIf(ref lhs, ref rhs, ref option_expr) => {
+            v.visit_expr(lhs);
+            v.visit_expr(rhs);
+            match option_expr {
+                Some(ref expr) => v.visit_expr(&expr),
+                None => {},
+            }
+            v.promotable = false;
+        }
 
         // Loops (not very meaningful in constants).
-        hir::ExprWhile(..) |
-        hir::ExprLoop(..) |
+        hir::ExprWhile(ref expr, ref box_block, ref _option_label) => {
+            v.visit_expr(expr);
+            v.visit_block(box_block);
+            v.promotable = false;
+        }
+
+        hir::ExprLoop(ref box_block, ref _option_label, ref _loop_source) => {
+            v.visit_block(box_block);
+            v.promotable = false;
+        }
 
         // More control flow (also not very meaningful).
-        hir::ExprBreak(..) |
-        hir::ExprContinue(_) |
-        hir::ExprRet(_) |
+        hir::ExprBreak(_, ref option_expr) | hir::ExprRet(ref option_expr) => {
+            match *option_expr {
+                Some(ref expr) => { v.visit_expr(&expr) },
+                None => {},
+            }
+            v.promotable = false;
+        }
+
+        hir::ExprContinue(_) => {
+            v.promotable = false;
+        }
 
         // Generator expressions
-        hir::ExprYield(_) |
+        hir::ExprYield(ref expr) => {
+            v.visit_expr(&expr);
+            v.promotable = false;
+        }
 
         // Expressions with side-effects.
-        hir::ExprAssign(..) |
-        hir::ExprAssignOp(..) |
-        hir::ExprInlineAsm(..) => {
+        hir::ExprAssignOp(_, ref lhs, ref rhs) | hir::ExprAssign(ref lhs, ref rhs) => {
+            v.visit_expr(lhs);
+            v.visit_expr(rhs);
+            v.promotable = false;
+        }
+
+        hir::ExprInlineAsm(ref _inline_asm, ref hirvec_lhs, ref hirvec_rhs) => {
+            for index in hirvec_lhs.iter() {
+                v.visit_expr(index)
+            }
+            for index in hirvec_rhs.iter() {
+                v.visit_expr(index)
+            }
             v.promotable = false;
         }
     }
index 537333380fa74da34b426a308a37868983689a53..6593e239bc302db54bdafd0d09429589d8adba0c 100644 (file)
@@ -1256,7 +1256,7 @@ mod something {
 ```
 
 Please verify you didn't misspell the type/module's name or that you didn't
-forgot to import it:
+forget to import it:
 
 
 ```
index b8dfd21e54076ce3de0b4ff6ec4f3ddf79731483..aed70861e33837d1d8cd462e8f2694f08dcc98b8 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![deny(bare_trait_objects)]
+
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
@@ -55,7 +57,7 @@
 
 use syntax::visit::{self, FnKind, Visitor};
 use syntax::attr;
-use syntax::ast::{Arm, IsAsync, BindingMode, Block, Crate, Expr, ExprKind};
+use syntax::ast::{CRATE_NODE_ID, Arm, IsAsync, BindingMode, Block, Crate, Expr, ExprKind};
 use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, GenericParamKind, Generics};
 use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
 use syntax::ast::{Label, Local, Mutability, Pat, PatKind, Path};
@@ -1292,7 +1294,7 @@ fn intern(&mut self, string: &str, primitive_type: PrimTy) {
 /// This is the visitor that walks the whole crate.
 pub struct Resolver<'a> {
     session: &'a Session,
-    cstore: &'a CrateStore,
+    cstore: &'a dyn CrateStore,
 
     pub definitions: Definitions,
 
@@ -1388,7 +1390,7 @@ pub struct Resolver<'a> {
     /// true if `#![feature(use_extern_macros)]`
     use_extern_macros: bool,
 
-    crate_loader: &'a mut CrateLoader,
+    crate_loader: &'a mut dyn CrateLoader,
     macro_names: FxHashSet<Ident>,
     global_macros: FxHashMap<Name, &'a NameBinding<'a>>,
     pub all_macros: FxHashMap<Name, Def>,
@@ -1604,11 +1606,11 @@ fn resolve_hir_path_cb<F>(&mut self, path: &mut hir::Path, is_value: bool, error
 
 impl<'a> Resolver<'a> {
     pub fn new(session: &'a Session,
-               cstore: &'a CrateStore,
+               cstore: &'a dyn CrateStore,
                krate: &Crate,
                crate_name: &str,
                make_glob_map: MakeGlobMap,
-               crate_loader: &'a mut CrateLoader,
+               crate_loader: &'a mut dyn CrateLoader,
                arenas: &'a ResolverArenas<'a>)
                -> Resolver<'a> {
         let root_def_id = DefId::local(CRATE_DEF_INDEX);
@@ -1891,7 +1893,12 @@ fn resolve_ident_in_lexical_scope(&mut self,
 
         ident.span = ident.span.modern();
         loop {
-            module = unwrap_or!(self.hygienic_lexical_parent(module, &mut ident.span), break);
+            let (opt_module, poisoned) = if record_used {
+                self.hygienic_lexical_parent_with_compatibility_fallback(module, &mut ident.span)
+            } else {
+                (self.hygienic_lexical_parent(module, &mut ident.span), false)
+            };
+            module = unwrap_or!(opt_module, break);
             let orig_current_module = self.current_module;
             self.current_module = module; // Lexical resolutions can never be a privacy error.
             let result = self.resolve_ident_in_module_unadjusted(
@@ -1900,7 +1907,19 @@ fn resolve_ident_in_lexical_scope(&mut self,
             self.current_module = orig_current_module;
 
             match result {
-                Ok(binding) => return Some(LexicalScopeBinding::Item(binding)),
+                Ok(binding) => {
+                    if poisoned {
+                        self.session.buffer_lint_with_diagnostic(
+                            lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
+                            CRATE_NODE_ID, ident.span,
+                            &format!("cannot find {} `{}` in this scope", ns.descr(), ident),
+                            lint::builtin::BuiltinLintDiagnostics::
+                                ProcMacroDeriveResolutionFallback(ident.span),
+                        );
+                    }
+                    return Some(LexicalScopeBinding::Item(binding))
+                }
+                _ if poisoned => break,
                 Err(Undetermined) => return None,
                 Err(Determined) => {}
             }
@@ -1935,7 +1954,7 @@ fn resolve_ident_in_lexical_scope(&mut self,
         None
     }
 
-    fn hygienic_lexical_parent(&mut self, mut module: Module<'a>, span: &mut Span)
+    fn hygienic_lexical_parent(&mut self, module: Module<'a>, span: &mut Span)
                                -> Option<Module<'a>> {
         if !module.expansion.is_descendant_of(span.ctxt().outer()) {
             return Some(self.macro_def_scope(span.remove_mark()));
@@ -1945,22 +1964,41 @@ fn hygienic_lexical_parent(&mut self, mut module: Module<'a>, span: &mut Span)
             return Some(module.parent.unwrap());
         }
 
-        let mut module_expansion = module.expansion.modern(); // for backward compatibility
-        while let Some(parent) = module.parent {
-            let parent_expansion = parent.expansion.modern();
-            if module_expansion.is_descendant_of(parent_expansion) &&
-               parent_expansion != module_expansion {
-                return if parent_expansion.is_descendant_of(span.ctxt().outer()) {
-                    Some(parent)
-                } else {
-                    None
-                };
+        None
+    }
+
+    fn hygienic_lexical_parent_with_compatibility_fallback(
+        &mut self, module: Module<'a>, span: &mut Span) -> (Option<Module<'a>>, /* poisoned */ bool
+    ) {
+        if let module @ Some(..) = self.hygienic_lexical_parent(module, span) {
+            return (module, false);
+        }
+
+        // We need to support the next case under a deprecation warning
+        // ```
+        // struct MyStruct;
+        // ---- begin: this comes from a proc macro derive
+        // mod implementation_details {
+        //     // Note that `MyStruct` is not in scope here.
+        //     impl SomeTrait for MyStruct { ... }
+        // }
+        // ---- end
+        // ```
+        // So we have to fall back to the module's parent during lexical resolution in this case.
+        if let Some(parent) = module.parent {
+            // Inner module is inside the macro, parent module is outside of the macro.
+            if module.expansion != parent.expansion &&
+            module.expansion.is_descendant_of(parent.expansion) {
+                // The macro is a proc macro derive
+                if module.expansion.looks_like_proc_macro_derive() {
+                    if parent.expansion.is_descendant_of(span.ctxt().outer()) {
+                        return (module.parent, true);
+                    }
+                }
             }
-            module = parent;
-            module_expansion = parent_expansion;
         }
 
-        None
+        (None, false)
     }
 
     fn resolve_ident_in_module(&mut self,
@@ -1996,8 +2034,8 @@ fn resolve_crate_root(&mut self, ident: Ident) -> Module<'a> {
             let mut iter = ctxt.marks().into_iter().rev().peekable();
             let mut result = None;
             // Find the last modern mark from the end if it exists.
-            while let Some(&mark) = iter.peek() {
-                if mark.transparency() == Transparency::Opaque {
+            while let Some(&(mark, transparency)) = iter.peek() {
+                if transparency == Transparency::Opaque {
                     result = Some(mark);
                     iter.next();
                 } else {
@@ -2005,8 +2043,8 @@ fn resolve_crate_root(&mut self, ident: Ident) -> Module<'a> {
                 }
             }
             // Then find the last legacy mark from the end if it exists.
-            for mark in iter {
-                if mark.transparency() == Transparency::SemiTransparent {
+            for (mark, transparency) in iter {
+                if transparency == Transparency::SemiTransparent {
                     result = Some(mark);
                 } else {
                     break;
@@ -4037,8 +4075,9 @@ fn get_traits_containing_item(&mut self, mut ident: Ident, ns: Namespace)
         let mut search_module = self.current_module;
         loop {
             self.get_traits_in_module_containing_item(ident, ns, search_module, &mut found_traits);
-            search_module =
-                unwrap_or!(self.hygienic_lexical_parent(search_module, &mut ident.span), break);
+            search_module = unwrap_or!(
+                self.hygienic_lexical_parent(search_module, &mut ident.span), break
+            );
         }
 
         if let Some(prelude) = self.prelude {
@@ -4125,7 +4164,18 @@ fn lookup_import_candidates<FilterFn>(&mut self,
                 if ident.name == lookup_name && ns == namespace {
                     if filter_fn(name_binding.def()) {
                         // create the path
-                        let mut segms = path_segments.clone();
+                        let mut segms = if self.session.rust_2018() && !in_module_is_extern {
+                            // crate-local absolute paths start with `crate::` in edition 2018
+                            // FIXME: may also be stabilized for Rust 2015 (Issues #45477, #44660)
+                            let mut full_segms = vec![
+                                ast::PathSegment::from_ident(keywords::Crate.ident())
+                            ];
+                            full_segms.extend(path_segments.clone());
+                            full_segms
+                        } else {
+                            path_segments.clone()
+                        };
+
                         segms.push(ast::PathSegment::from_ident(ident));
                         let path = Path {
                             span: name_binding.span,
@@ -4395,12 +4445,6 @@ fn report_conflict<'b>(&mut self,
             (TypeNS, _) => "type",
         };
 
-        let namespace = match ns {
-            ValueNS => "value",
-            MacroNS => "macro",
-            TypeNS => "type",
-        };
-
         let msg = format!("the name `{}` is defined multiple times", name);
 
         let mut err = match (old_binding.is_extern_crate(), new_binding.is_extern_crate()) {
@@ -4418,7 +4462,7 @@ fn report_conflict<'b>(&mut self,
 
         err.note(&format!("`{}` must be defined only once in the {} namespace of this {}",
                           name,
-                          namespace,
+                          ns.descr(),
                           container));
 
         err.span_label(span, format!("`{}` re{} here", name, new_participle));
index 0523765ea189750cb879d61588967d3511855fa1..024506ed7f8e73d11a5841fb2902e7830947c687 100644 (file)
@@ -24,7 +24,7 @@
 use syntax::ext::base::{self, Annotatable, Determinacy, MultiModifier, MultiDecorator};
 use syntax::ext::base::{MacroKind, SyntaxExtension, Resolver as SyntaxResolver};
 use syntax::ext::expand::{self, AstFragment, AstFragmentKind, Invocation, InvocationKind};
-use syntax::ext::hygiene::{self, Mark, Transparency};
+use syntax::ext::hygiene::{self, Mark};
 use syntax::ext::placeholders::placeholder;
 use syntax::ext::tt::macro_rules;
 use syntax::feature_gate::{self, emit_feature_err, GateIssue};
@@ -331,13 +331,8 @@ fn resolve_invoc(&mut self, invoc: &mut Invocation, scope: Mark, force: bool)
 
         self.unused_macros.remove(&def_id);
         let ext = self.get_macro(def);
-        if ext.is_modern() {
-            let transparency =
-                if ext.is_transparent() { Transparency::Transparent } else { Transparency::Opaque };
-            invoc.expansion_data.mark.set_transparency(transparency);
-        } else if def_id.krate == BUILTIN_MACROS_CRATE {
-            invoc.expansion_data.mark.set_is_builtin(true);
-        }
+        invoc.expansion_data.mark.set_default_transparency(ext.default_transparency());
+        invoc.expansion_data.mark.set_is_builtin(def_id.krate == BUILTIN_MACROS_CRATE);
         Ok(Some(ext))
     }
 
@@ -390,6 +385,22 @@ fn resolve_invoc_to_def(&mut self, invoc: &mut Invocation, scope: Mark, force: b
             Err(Determinacy::Determined) => {}
         }
 
+        // Ok at this point we've determined that the `attr` above doesn't
+        // actually resolve at this time, so we may want to report an error.
+        // It could be the case, though, that `attr` won't ever resolve! If
+        // there's a custom derive that could be used it might declare `attr` as
+        // a custom attribute accepted by the derive. In this case we don't want
+        // to report this particular invocation as unresolved, but rather we'd
+        // want to move on to the next invocation.
+        //
+        // This loop here looks through all of the derive annotations in scope
+        // and tries to resolve them. If they themselves successfully resolve
+        // *and* the resolve mentions that this attribute's name is a registered
+        // custom attribute then we flag this attribute as known and update
+        // `invoc` above to point to the next invocation.
+        //
+        // By then returning `Undetermined` we should continue resolution to
+        // resolve the next attribute.
         let attr_name = match path.segments.len() {
             1 => path.segments[0].ident.name,
             _ => return Err(determinacy),
@@ -411,8 +422,8 @@ fn resolve_invoc_to_def(&mut self, invoc: &mut Invocation, scope: Mark, force: b
                             attrs.push(inert_attr);
                             attrs
                         });
+                        return Err(Determinacy::Undetermined)
                     }
-                    return Err(Determinacy::Undetermined);
                 },
                 Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined,
                 Err(Determinacy::Determined) => {}
index e54cd773123c8e5b7b5d88ad4a2118d7ee2dd6ee..19e353c6a942d67211d8e0c4e68af8cb6a7073ef 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),
@@ -572,6 +573,9 @@ pub struct TargetOptions {
     /// Don't use this field; instead use the `.max_atomic_width()` method.
     pub max_atomic_width: Option<u64>,
 
+    /// Whether the target supports atomic CAS operations natively
+    pub atomic_cas: bool,
+
     /// Panic strategy: "unwind" or "abort"
     pub panic_strategy: PanicStrategy,
 
@@ -690,6 +694,7 @@ fn default() -> TargetOptions {
             no_integrated_as: false,
             min_atomic_width: None,
             max_atomic_width: None,
+            atomic_cas: true,
             panic_strategy: PanicStrategy::Unwind,
             abi_blacklist: vec![],
             crt_static_allows_dylibs: false,
@@ -946,6 +951,7 @@ macro_rules! key {
         key!(no_integrated_as, bool);
         key!(max_atomic_width, Option<u64>);
         key!(min_atomic_width, Option<u64>);
+        key!(atomic_cas, bool);
         try!(key!(panic_strategy, PanicStrategy));
         key!(crt_static_allows_dylibs, bool);
         key!(crt_static_default, bool);
@@ -1154,6 +1160,7 @@ macro_rules! target_option_val {
         target_option_val!(no_integrated_as);
         target_option_val!(min_atomic_width);
         target_option_val!(max_atomic_width);
+        target_option_val!(atomic_cas);
         target_option_val!(panic_strategy);
         target_option_val!(crt_static_allows_dylibs);
         target_option_val!(crt_static_default);
index ce42a908b0e431525d91e199722f06dc1d4c353c..3ac4c459c63841dcbff1eafea39f8c2e6c4e783b 100644 (file)
@@ -34,9 +34,10 @@ pub fn target() -> TargetResult {
             linker: Some("msp430-elf-gcc".to_string()),
             no_integrated_as: true,
 
-            // There are no atomic instructions available in the MSP430
+            // There are no atomic CAS instructions available in the MSP430
             // instruction set
-            max_atomic_width: Some(0),
+            max_atomic_width: Some(16),
+            atomic_cas: false,
 
             // Because these devices have very little resources having an
             // unwinder is too onerous so we default to "abort" because the
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 9fea07c36f4ef7be17075a65e03d8a267e405b06..26812501814f535b863a24fbea689124de91ab27 100644 (file)
@@ -29,9 +29,9 @@ pub fn target() -> TargetResult {
             // The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them
             // with +strict-align.
             features: "+strict-align".to_string(),
-            // There are no atomic instructions available in the instruction set of the ARMv6-M
+            // There are no atomic CAS instructions available in the instruction set of the ARMv6-M
             // architecture
-            max_atomic_width: Some(0),
+            atomic_cas: false,
             .. super::thumb_base::opts()
         }
     })
index 56170bbb869f31e8d3cec75b7e072ae8976fde6d..51d402e197da96062ed90d6804bde630ae7ae601 100644 (file)
@@ -51,10 +51,13 @@ 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 {
-        llvm_target: "wasm32-unknown-unknown-wasm".to_string(),
+        llvm_target: "wasm32-unknown-unknown".to_string(),
         target_endian: "little".to_string(),
         target_pointer_width: "32".to_string(),
         target_c_int_width: "32".to_string(),
index 1e78461861a95f3d6bf4514d1fb19c03ba064b22..68fa58b922019f9453bd7bd672cb68f537601a41 100644 (file)
@@ -16,6 +16,8 @@ pub fn target() -> TargetResult {
     base.max_atomic_width = Some(64);
     base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
     base.stack_probes = true;
+    // This option is required to build executables on Haiku x86_64
+    base.position_independent_executables = true;
 
     Ok(Target {
         llvm_target: "x86_64-unknown-haiku".to_string(),
index 214376b2e532b14a406e1d8854c23c4cb6d64241..cf61258577619e90dcf643ecc44c7e13dfa75cac 100644 (file)
 use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc::hir::map::definitions::DefPathData;
 use rustc::hir::{self, ImplPolarity};
-use rustc::traits::{Clause, Clauses, DomainGoal, Goal, PolyDomainGoal, ProgramClause,
-                    WhereClause, FromEnv, WellFormed};
+use rustc::traits::{
+    Clause, Clauses, DomainGoal, FromEnv, Goal, PolyDomainGoal, ProgramClause, WellFormed,
+    WhereClause,
+};
 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;
@@ -102,34 +103,50 @@ fn lower(&self) -> PolyDomainGoal<'tcx> {
             Predicate::RegionOutlives(predicate) => predicate.lower(),
             Predicate::TypeOutlives(predicate) => predicate.lower(),
             Predicate::Projection(predicate) => predicate.lower(),
-            Predicate::WellFormed(ty) => ty::Binder::dummy(
-                DomainGoal::WellFormed(WellFormed::Ty(*ty))
-            ),
-            Predicate::ObjectSafe(..) |
-            Predicate::ClosureKind(..) |
-            Predicate::Subtype(..) |
-            Predicate::ConstEvaluatable(..) => {
-                unimplemented!()
+            Predicate::WellFormed(ty) => {
+                ty::Binder::dummy(DomainGoal::WellFormed(WellFormed::Ty(*ty)))
             }
+            Predicate::ObjectSafe(..)
+            | Predicate::ClosureKind(..)
+            | Predicate::Subtype(..)
+            | Predicate::ConstEvaluatable(..) => unimplemented!(),
         }
     }
 }
 
-/// Transforms an existing goal into a FromEnv goal.
-///
-/// Used for lowered where clauses (see rustc guide).
+/// Used for implied bounds related rules (see rustc guide).
 trait IntoFromEnvGoal {
+    /// Transforms an existing goal into a `FromEnv` goal.
     fn into_from_env_goal(self) -> Self;
 }
 
+/// Used for well-formedness related rules (see rustc guide).
+trait IntoWellFormedGoal {
+    /// Transforms an existing goal into a `WellFormed` goal.
+    fn into_well_formed_goal(self) -> Self;
+}
+
 impl<'tcx> IntoFromEnvGoal for DomainGoal<'tcx> {
     fn into_from_env_goal(self) -> DomainGoal<'tcx> {
         use self::WhereClause::*;
 
         match self {
-            DomainGoal::Holds(Implemented(trait_ref)) => DomainGoal::FromEnv(
-                FromEnv::Trait(trait_ref)
-            ),
+            DomainGoal::Holds(Implemented(trait_ref)) => {
+                DomainGoal::FromEnv(FromEnv::Trait(trait_ref))
+            }
+            other => other,
+        }
+    }
+}
+
+impl<'tcx> IntoWellFormedGoal for DomainGoal<'tcx> {
+    fn into_well_formed_goal(self) -> DomainGoal<'tcx> {
+        use self::WhereClause::*;
+
+        match self {
+            DomainGoal::Holds(Implemented(trait_ref)) => {
+                DomainGoal::WellFormed(WellFormed::Trait(trait_ref))
+            }
             other => other,
         }
     }
@@ -225,16 +242,13 @@ 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>)`
     let impl_trait: DomainGoal = trait_pred.lower();
 
-     // `FromEnv(Self: Trait<P1..Pn>)`
+    // `FromEnv(Self: Trait<P1..Pn>)`
     let from_env_goal = impl_trait.into_from_env_goal().into_goal();
     let hypotheses = tcx.intern_goals(&[from_env_goal]);
 
@@ -246,6 +260,8 @@ fn program_clauses_for_trait<'a, 'tcx>(
 
     let clauses = iter::once(Clause::ForAll(ty::Binder::dummy(implemented_from_env)));
 
+    let where_clauses = &tcx.predicates_defined_on(def_id).predicates;
+
     // Rule Implied-Bound-From-Trait
     //
     // For each where clause WC:
@@ -256,10 +272,7 @@ 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 implied_bound_clauses = where_clauses
         .into_iter()
         .map(|wc| wc.lower())
 
@@ -268,10 +281,40 @@ fn program_clauses_for_trait<'a, 'tcx>(
             goal: goal.into_from_env_goal(),
             hypotheses,
         }))
-
         .map(Clause::ForAll);
 
-    tcx.mk_clauses(clauses.chain(implied_bound_clauses))
+    // Rule WellFormed-TraitRef
+    //
+    // Here `WC` denotes the set of all where clauses:
+    // ```
+    // forall<Self, P1..Pn> {
+    //   WellFormed(Self: Trait<P1..Pn>) :- Implemented(Self: Trait<P1..Pn>) && WellFormed(WC)
+    // }
+    // ```
+
+    // `Implemented(Self: Trait<P1..Pn>) && WellFormed(WC)`
+    let wf_conditions = iter::once(ty::Binder::dummy(trait_pred.lower()))
+        .chain(
+            where_clauses
+                .into_iter()
+                .map(|wc| wc.lower())
+                .map(|wc| wc.map_bound(|goal| goal.into_well_formed_goal()))
+        );
+
+    // `WellFormed(Self: Trait<P1..Pn>) :- Implemented(Self: Trait<P1..Pn>) && WellFormed(WC)`
+    let wf_clause = ProgramClause {
+        goal: DomainGoal::WellFormed(WellFormed::Trait(trait_pred)),
+        hypotheses: tcx.mk_goals(
+            wf_conditions.map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
+        ),
+    };
+    let wf_clause = iter::once(Clause::ForAll(ty::Binder::dummy(wf_clause)));
+
+    tcx.mk_clauses(
+        clauses
+            .chain(implied_bound_clauses)
+            .chain(wf_clause)
+    )
 }
 
 fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Clauses<'tcx> {
@@ -313,7 +356,6 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     def_id: DefId,
 ) -> Clauses<'tcx> {
-
     // Rule WellFormed-Type
     //
     // `struct Ty<P1..Pn> where WC1, ..., WCm`
@@ -334,7 +376,10 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
     let well_formed = ProgramClause {
         goal: DomainGoal::WellFormed(WellFormed::Ty(ty)),
         hypotheses: tcx.mk_goals(
-            where_clauses.iter().cloned().map(|wc| Goal::from_poly_domain_goal(wc, tcx))
+            where_clauses
+                .iter()
+                .cloned()
+                .map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
         ),
     };
 
@@ -465,7 +510,8 @@ fn process_attrs(&mut self, node_id: ast::NodeId, attrs: &[ast::Attribute]) {
             }
 
             if let Some(clauses) = clauses {
-                let mut err = self.tcx
+                let mut err = self
+                    .tcx
                     .sess
                     .struct_span_err(attr.span, "program clause dump");
 
index fa78b38dbb7a84da4b2a36953ac26db3ec91b33d..c7ad3398873eabc00e12491b7ad70d74bd629a54 100644 (file)
@@ -1182,7 +1182,54 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
                 fcx.tcx.sess.err("language item required, but not found: `panic_info`");
             }
         }
+    }
+
+    // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
+    if let Some(alloc_error_handler_did) = fcx.tcx.lang_items().oom() {
+        if alloc_error_handler_did == fcx.tcx.hir.local_def_id(fn_id) {
+            if let Some(alloc_layout_did) = fcx.tcx.lang_items().alloc_layout() {
+                if declared_ret_ty.sty != ty::TyNever {
+                    fcx.tcx.sess.span_err(
+                        decl.output.span(),
+                        "return type should be `!`",
+                    );
+                }
+
+                let inputs = fn_sig.inputs();
+                let span = fcx.tcx.hir.span(fn_id);
+                if inputs.len() == 1 {
+                    let arg_is_alloc_layout = match inputs[0].sty {
+                        ty::TyAdt(ref adt, _) => {
+                            adt.did == alloc_layout_did
+                        },
+                        _ => false,
+                    };
+
+                    if !arg_is_alloc_layout {
+                        fcx.tcx.sess.span_err(
+                            decl.inputs[0].span,
+                            "argument should be `Layout`",
+                        );
+                    }
 
+                    if let Node::NodeItem(item) = fcx.tcx.hir.get(fn_id) {
+                        if let Item_::ItemFn(_, _, ref generics, _) = item.node {
+                            if !generics.params.is_empty() {
+                                fcx.tcx.sess.span_err(
+                                    span,
+                                    "`#[alloc_error_handler]` function should have no type \
+                                     parameters",
+                                );
+                            }
+                        }
+                    }
+                } else {
+                    fcx.tcx.sess.span_err(span, "function should have one argument");
+                }
+            } else {
+                fcx.tcx.sess.err("language item required, but not found: `alloc_layout`");
+            }
+        }
     }
 
     (fcx, gen_ty)
@@ -3827,7 +3874,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 +4010,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 e489c4d4a46be731045fd25f7351e211c427ae8c..79ee322d1095a5c4f7e5113e18a591534cf39578 100644 (file)
 
 // a variation on try that just returns unit
 macro_rules! ignore_err {
-    ($e:expr) => (match $e { Ok(e) => e, Err(_) => return () })
+    ($e:expr) => (match $e { Ok(e) => e, Err(_) => {
+        debug!("ignoring mem-categorization error!");
+        return ()
+    }})
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -1034,22 +1037,24 @@ fn link_pattern(&self, discr_cmt: mc::cmt<'tcx>, root_pat: &hir::Pat) {
         debug!("link_pattern(discr_cmt={:?}, root_pat={:?})",
                discr_cmt,
                root_pat);
-        let _ = self.with_mc(|mc| {
+        ignore_err!(self.with_mc(|mc| {
             mc.cat_pattern(discr_cmt, root_pat, |sub_cmt, sub_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");
                         }
                     }
                     _ => {}
                 }
             })
-        });
+        }));
     }
 
     /// Link lifetime of borrowed pointer resulting from autoref to lifetimes in the value being
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 4931cbfa5acc386f274537569228089e3c3b4637..fa2f9885964dee3bfe3b4c007a11c4299b858941 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
                 }
@@ -1306,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 };
@@ -1320,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::*;
 
@@ -1337,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) => {
@@ -1355,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) => {
@@ -1405,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
@@ -1903,6 +1925,14 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
             if let Some(val) = attr.value_str() {
                 codegen_fn_attrs.linkage = Some(linkage_by_name(tcx, id, &val.as_str()));
             }
+        } else if attr.check_name("wasm_custom_section") {
+            match attr.value_str() {
+                Some(name) => codegen_fn_attrs.wasm_custom_section = Some(name),
+                None => {
+                    tcx.sess.span_err(attr.span, "must be of the form \
+                        #[wasm_custom_section = \"foo\"]");
+                }
+            }
         }
     }
 
index bbe47ecee7907793859a0843097d93e677413e07..a7ecfc269f35badcdc81d4474c1a210945a69f39 100644 (file)
@@ -8,77 +8,66 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use rustc::hir;
-use rustc::hir::def_id::{CrateNum, DefId};
-use rustc::hir::itemlikevisit::ItemLikeVisitor;
-use rustc::ty::{self, TyCtxt};
+use rustc::hir::def_id::DefId;
+use rustc::ty::{self, OutlivesPredicate, TyCtxt};
 use util::nodemap::FxHashMap;
 
 use super::utils::*;
 
-pub fn explicit_predicates<'tcx>(
-    tcx: TyCtxt<'_, 'tcx, 'tcx>,
-    crate_num: CrateNum,
-) -> FxHashMap<DefId, RequiredPredicates<'tcx>> {
-    let mut predicates = FxHashMap::default();
-
-    // iterate over the entire crate
-    tcx.hir.krate().visit_all_item_likes(&mut ExplicitVisitor {
-        tcx: tcx,
-        explicit_predicates: &mut predicates,
-        crate_num: crate_num,
-    });
-
-    predicates
+#[derive(Debug)]
+pub struct ExplicitPredicatesMap<'tcx> {
+    map: FxHashMap<DefId, RequiredPredicates<'tcx>>,
 }
 
-pub struct ExplicitVisitor<'cx, 'tcx: 'cx> {
-    tcx: TyCtxt<'cx, 'tcx, 'tcx>,
-    explicit_predicates: &'cx mut FxHashMap<DefId, RequiredPredicates<'tcx>>,
-    crate_num: CrateNum,
-}
+impl<'tcx> ExplicitPredicatesMap<'tcx> {
+    pub fn new() -> ExplicitPredicatesMap<'tcx> {
+        ExplicitPredicatesMap {
+            map: FxHashMap::default(),
+        }
+    }
 
-impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for ExplicitVisitor<'cx, 'tcx> {
-    fn visit_item(&mut self, item: &'tcx hir::Item) {
-        let def_id = DefId {
-            krate: self.crate_num,
-            index: item.hir_id.owner,
-        };
+    pub fn explicit_predicates_of(
+        &mut self,
+        tcx: TyCtxt<'_, 'tcx, 'tcx>,
+        def_id: DefId,
+    ) -> &RequiredPredicates<'tcx> {
+        self.map.entry(def_id).or_insert_with(|| {
+            let predicates = if def_id.is_local() {
+                tcx.explicit_predicates_of(def_id).predicates
+            } else {
+                tcx.predicates_of(def_id).predicates
+            };
+            let mut required_predicates = RequiredPredicates::default();
 
-        let mut required_predicates = RequiredPredicates::default();
-        let local_explicit_predicate = self.tcx.explicit_predicates_of(def_id).predicates;
+            // process predicates and convert to `RequiredPredicates` entry, see below
+            for pred in predicates.into_iter() {
+                match pred {
+                    ty::Predicate::TypeOutlives(predicate) => {
+                        let OutlivesPredicate(ref ty, ref reg) = predicate.skip_binder();
+                        insert_outlives_predicate(tcx, (*ty).into(), reg, &mut required_predicates)
+                    }
 
-        for pred in local_explicit_predicate.into_iter() {
-            match pred {
-                ty::Predicate::TypeOutlives(predicate) => {
-                    let ty::OutlivesPredicate(ref ty, ref reg) = predicate.skip_binder();
-                    insert_outlives_predicate(self.tcx, (*ty).into(), reg, &mut required_predicates)
-                }
+                    ty::Predicate::RegionOutlives(predicate) => {
+                        let OutlivesPredicate(ref reg1, ref reg2) = predicate.skip_binder();
+                        insert_outlives_predicate(
+                            tcx,
+                            (*reg1).into(),
+                            reg2,
+                            &mut required_predicates,
+                        )
+                    }
 
-                ty::Predicate::RegionOutlives(predicate) => {
-                    let ty::OutlivesPredicate(ref reg1, ref reg2) = predicate.skip_binder();
-                    insert_outlives_predicate(
-                        self.tcx,
-                        (*reg1).into(),
-                        reg2,
-                        &mut required_predicates,
-                    )
+                    ty::Predicate::Trait(..)
+                    | ty::Predicate::Projection(..)
+                    | ty::Predicate::WellFormed(..)
+                    | ty::Predicate::ObjectSafe(..)
+                    | ty::Predicate::ClosureKind(..)
+                    | ty::Predicate::Subtype(..)
+                    | ty::Predicate::ConstEvaluatable(..) => (),
                 }
-
-                ty::Predicate::Trait(..)
-                | ty::Predicate::Projection(..)
-                | ty::Predicate::WellFormed(..)
-                | ty::Predicate::ObjectSafe(..)
-                | ty::Predicate::ClosureKind(..)
-                | ty::Predicate::Subtype(..)
-                | ty::Predicate::ConstEvaluatable(..) => (),
             }
-        }
 
-        self.explicit_predicates.insert(def_id, required_predicates);
+            required_predicates
+        })
     }
-
-    fn visit_trait_item(&mut self, _trait_item: &'tcx hir::TraitItem) {}
-
-    fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) {}
 }
index c966db98c8e170de3947b220f90e74ed8f32abb2..a015122d62e74a17902062f7506b22d02003267d 100644 (file)
@@ -15,6 +15,7 @@
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::util::nodemap::FxHashMap;
 
+use super::explicit::ExplicitPredicatesMap;
 use super::utils::*;
 
 /// Infer predicates for the items in the crate.
@@ -24,7 +25,7 @@
 ///     now be filled with inferred predicates.
 pub fn infer_predicates<'tcx>(
     tcx: TyCtxt<'_, 'tcx, 'tcx>,
-    explicit_map: &FxHashMap<DefId, RequiredPredicates<'tcx>>,
+    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
 ) -> FxHashMap<DefId, RequiredPredicates<'tcx>> {
     debug!("infer_predicates");
 
@@ -55,7 +56,7 @@ pub struct InferVisitor<'cx, 'tcx: 'cx> {
     tcx: TyCtxt<'cx, 'tcx, 'tcx>,
     global_inferred_outlives: &'cx mut FxHashMap<DefId, RequiredPredicates<'tcx>>,
     predicates_added: &'cx mut bool,
-    explicit_map: &'cx FxHashMap<DefId, RequiredPredicates<'tcx>>,
+    explicit_map: &'cx mut ExplicitPredicatesMap<'tcx>,
 }
 
 impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for InferVisitor<'cx, 'tcx> {
@@ -93,7 +94,7 @@ fn visit_item(&mut self, item: &hir::Item) {
                         field_ty,
                         self.global_inferred_outlives,
                         &mut item_required_predicates,
-                        self.explicit_map,
+                        &mut self.explicit_map,
                     );
                 }
             }
@@ -129,7 +130,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
     field_ty: Ty<'tcx>,
     global_inferred_outlives: &FxHashMap<DefId, RequiredPredicates<'tcx>>,
     required_predicates: &mut RequiredPredicates<'tcx>,
-    explicit_map: &FxHashMap<DefId, RequiredPredicates<'tcx>>,
+    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
 ) {
     for ty in field_ty.walk() {
         match ty.sty {
@@ -257,53 +258,54 @@ pub fn check_explicit_predicates<'tcx>(
     def_id: &DefId,
     substs: &[Kind<'tcx>],
     required_predicates: &mut RequiredPredicates<'tcx>,
-    explicit_map: &FxHashMap<DefId, RequiredPredicates<'tcx>>,
+    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
     ignore_self_ty: bool,
 ) {
     debug!("def_id = {:?}", &def_id);
     debug!("substs = {:?}", &substs);
     debug!("explicit_map =  {:?}", explicit_map);
     debug!("required_predicates = {:?}", required_predicates);
-    if let Some(explicit_predicates) = explicit_map.get(def_id) {
-        for outlives_predicate in explicit_predicates.iter() {
-            debug!("outlives_predicate = {:?}", &outlives_predicate);
+    let explicit_predicates = explicit_map.explicit_predicates_of(tcx, *def_id);
 
-            // Careful: If we are inferring the effects of a `dyn Trait<..>`
-            // type, then when we look up the predicates for `Trait`,
-            // we may find some that reference `Self`. e.g., perhaps the
-            // definition of `Trait` was:
-            //
-            // ```
-            // trait Trait<'a, T> where Self: 'a  { .. }
-            // ```
-            //
-            // we want to ignore such predicates here, because
-            // there is no type parameter for them to affect. Consider
-            // a struct containing `dyn Trait`:
-            //
-            // ```
-            // struct MyStruct<'x, X> { field: Box<dyn Trait<'x, X>> }
-            // ```
-            //
-            // The `where Self: 'a` predicate refers to the *existential, hidden type*
-            // that is represented by the `dyn Trait`, not to the `X` type parameter
-            // (or any other generic parameter) declared on `MyStruct`.
-            //
-            // Note that we do this check for self **before** applying `substs`. In the
-            // case that `substs` come from a `dyn Trait` type, our caller will have
-            // included `Self = dyn Trait<'x, X>` as the value for `Self`. If we were
-            // to apply the substs, and not filter this predicate, we might then falsely
-            // conclude that e.g. `X: 'x` was a reasonable inferred requirement.
-            if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() {
-                if ty.is_self() && ignore_self_ty {
-                    debug!("skipping self ty = {:?}", &ty);
-                    continue;
-                }
-            }
+    for outlives_predicate in explicit_predicates.iter() {
+        debug!("outlives_predicate = {:?}", &outlives_predicate);
 
-            let predicate = outlives_predicate.subst(tcx, substs);
-            debug!("predicate = {:?}", &predicate);
-            insert_outlives_predicate(tcx, predicate.0.into(), predicate.1, required_predicates);
+        // Careful: If we are inferring the effects of a `dyn Trait<..>`
+        // type, then when we look up the predicates for `Trait`,
+        // we may find some that reference `Self`. e.g., perhaps the
+        // definition of `Trait` was:
+        //
+        // ```
+        // trait Trait<'a, T> where Self: 'a  { .. }
+        // ```
+        //
+        // we want to ignore such predicates here, because
+        // there is no type parameter for them to affect. Consider
+        // a struct containing `dyn Trait`:
+        //
+        // ```
+        // struct MyStruct<'x, X> { field: Box<dyn Trait<'x, X>> }
+        // ```
+        //
+        // The `where Self: 'a` predicate refers to the *existential, hidden type*
+        // that is represented by the `dyn Trait`, not to the `X` type parameter
+        // (or any other generic parameter) declared on `MyStruct`.
+        //
+        // Note that we do this check for self **before** applying `substs`. In the
+        // case that `substs` come from a `dyn Trait` type, our caller will have
+        // included `Self = dyn Trait<'x, X>` as the value for `Self`. If we were
+        // to apply the substs, and not filter this predicate, we might then falsely
+        // conclude that e.g. `X: 'x` was a reasonable inferred requirement.
+        if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() {
+            if ty.is_self() && ignore_self_ty {
+                debug!("skipping self ty = {:?}", &ty);
+                continue;
+            }
         }
+
+        let predicate = outlives_predicate.subst(tcx, substs);
+        debug!("predicate = {:?}", &predicate);
+        insert_outlives_predicate(tcx, predicate.0.into(), predicate.1, required_predicates);
     }
+    // }
 }
index c6c7e8f931f8b0bbf14270beccab1164d5d79208..9c483924992d48384858c5f31a70011b9f78420f 100644 (file)
@@ -84,6 +84,8 @@ fn inferred_outlives_crate<'tcx>(
     tcx: TyCtxt<'_, 'tcx, 'tcx>,
     crate_num: CrateNum,
 ) -> Lrc<CratePredicatesMap<'tcx>> {
+    assert_eq!(crate_num, LOCAL_CRATE);
+
     // Compute a map from each struct/enum/union S to the **explicit**
     // outlives predicates (`T: 'a`, `'a: 'b`) that the user wrote.
     // Typically there won't be many of these, except in older code where
@@ -92,8 +94,9 @@ fn inferred_outlives_crate<'tcx>(
     // for the type.
 
     // Compute the inferred predicates
-    let exp = explicit::explicit_predicates(tcx, crate_num);
-    let global_inferred_outlives = implicit_infer::infer_predicates(tcx, &exp);
+    let mut exp_map = explicit::ExplicitPredicatesMap::new();
+
+    let global_inferred_outlives = implicit_infer::infer_predicates(tcx, &mut exp_map);
 
     // Convert the inferred predicates into the "collected" form the
     // global data structure expects.
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 ddc9bdb384c0b359812661b4ac37058adeae0578..0a56c639220b464406056cebdff1a704926ddf6e 100644 (file)
@@ -178,7 +178,10 @@ pub fn run_core(search_paths: SearchPaths,
                 force_unstable_if_unmarked: bool,
                 edition: Edition,
                 cg: CodegenOptions,
-                error_format: ErrorOutputType) -> (clean::Crate, RenderInfo)
+                error_format: ErrorOutputType,
+                cmd_lints: Vec<(String, lint::Level)>,
+                lint_cap: Option<lint::Level>,
+                describe_lints: bool) -> (clean::Crate, RenderInfo)
 {
     // Parse, resolve, and typecheck the given crate.
 
@@ -189,6 +192,18 @@ pub fn run_core(search_paths: SearchPaths,
 
     let intra_link_resolution_failure_name = lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE.name;
     let warnings_lint_name = lint::builtin::WARNINGS.name;
+    let missing_docs = rustc_lint::builtin::MISSING_DOCS.name;
+
+    // In addition to those specific lints, we also need to whitelist those given through
+    // command line, otherwise they'll get ignored and we don't want that.
+    let mut whitelisted_lints = vec![warnings_lint_name.to_owned(),
+                                     intra_link_resolution_failure_name.to_owned(),
+                                     missing_docs.to_owned()];
+
+    for (lint, _) in &cmd_lints {
+        whitelisted_lints.push(lint.clone());
+    }
+
     let lints = lint::builtin::HardwiredLints.get_lints()
                     .into_iter()
                     .chain(rustc_lint::SoftLints.get_lints().into_iter())
@@ -200,6 +215,7 @@ pub fn run_core(search_paths: SearchPaths,
                             Some((lint.name_lower(), lint::Allow))
                         }
                     })
+                    .chain(cmd_lints.into_iter())
                     .collect::<Vec<_>>();
 
     let host_triple = TargetTriple::from_triple(config::host_triple());
@@ -213,7 +229,7 @@ pub fn run_core(search_paths: SearchPaths,
         } else {
             vec![]
         },
-        lint_cap: Some(lint::Forbid),
+        lint_cap: Some(lint_cap.unwrap_or_else(|| lint::Forbid)),
         cg,
         externs,
         target_triple: triple.unwrap_or(host_triple),
@@ -226,6 +242,7 @@ pub fn run_core(search_paths: SearchPaths,
         },
         error_format,
         edition,
+        describe_lints,
         ..config::basic_options()
     };
     driver::spawn_thread_pool(sessopts, move |sessopts| {
@@ -235,6 +252,24 @@ pub fn run_core(search_paths: SearchPaths,
         let mut sess = session::build_session_(
             sessopts, cpath, diagnostic_handler, codemap,
         );
+
+        lint::builtin::HardwiredLints.get_lints()
+                                     .into_iter()
+                                     .chain(rustc_lint::SoftLints.get_lints().into_iter())
+                                     .filter_map(|lint| {
+                                         // We don't want to whitelist *all* lints so let's
+                                         // ignore those ones.
+                                         if whitelisted_lints.iter().any(|l| &lint.name == l) {
+                                             None
+                                         } else {
+                                             Some(lint)
+                                         }
+                                     })
+                                     .for_each(|l| {
+                                         sess.driver_lint_caps.insert(lint::LintId::of(l),
+                                                                      lint::Allow);
+                                     });
+
         let codegen_backend = rustc_driver::get_codegen_backend(&sess);
         let cstore = Rc::new(CStore::new(codegen_backend.metadata_loader()));
         rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
@@ -299,7 +334,6 @@ pub fn run_core(search_paths: SearchPaths,
                                                             &sess);
 
         let resolver = RefCell::new(resolver);
-
         abort_on_err(driver::phase_3_run_analysis_passes(&*codegen_backend,
                                                         control,
                                                         &sess,
index 54c57c9ac6eebf727d2b0885a83642f56471aa31..8e8566cbbde264ca1135f6aaf569d52e73af088f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::mem;
+
 use clean::*;
 
 pub enum FoldItem {
@@ -109,12 +111,13 @@ fn fold_mod(&mut self, m: Module) -> Module {
     }
 
     fn fold_crate(&mut self, mut c: Crate) -> Crate {
-        c.module = c.module.and_then(|module| self.fold_item(module));
+        c.module = c.module.take().and_then(|module| self.fold_item(module));
 
-        c.external_traits = c.external_traits.into_iter().map(|(k, mut v)| {
+        let traits = mem::replace(&mut c.external_traits, Default::default());
+        c.external_traits.extend(traits.into_iter().map(|(k, mut v)| {
             v.items = v.items.into_iter().filter_map(|i| self.fold_item(i)).collect();
             (k, v)
-        }).collect();
+        }));
         c
     }
 }
index 7088104cd7a31d8b6ee5a6f6baa1ca2b3a5c9cea..8040548ce6bbe68ad315719895ee4b9f943cf70f 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());
@@ -339,6 +339,20 @@ fn new(iter: I) -> Self {
     }
 }
 
+fn check_if_allowed_tag(t: &Tag) -> bool {
+    match *t {
+        Tag::Paragraph
+        | Tag::CodeBlock(_)
+        | Tag::Item
+        | Tag::Emphasis
+        | Tag::Strong
+        | Tag::Code
+        | Tag::Link(_, _)
+        | Tag::BlockQuote => true,
+        _ => false,
+    }
+}
+
 impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
     type Item = Event<'a>;
 
@@ -350,12 +364,28 @@ fn next(&mut self) -> Option<Self::Item> {
             self.started = true;
         }
         let event = self.inner.next();
-        match event {
-            Some(Event::Start(..)) => self.depth += 1,
-            Some(Event::End(..)) => self.depth -= 1,
-            _ => {}
+        let mut is_start = true;
+        let is_allowed_tag = match event {
+            Some(Event::Start(ref c)) => {
+                self.depth += 1;
+                check_if_allowed_tag(c)
+            }
+            Some(Event::End(ref c)) => {
+                self.depth -= 1;
+                is_start = false;
+                check_if_allowed_tag(c)
+            }
+            _ => true,
+        };
+        if is_allowed_tag == false {
+            if is_start {
+                Some(Event::Start(Tag::Paragraph))
+            } else {
+                Some(Event::End(Tag::Paragraph))
+            }
+        } else {
+            event
         }
-        event
     }
 }
 
@@ -477,7 +507,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();
@@ -688,8 +718,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
             }
         };
 
-        let p = Parser::new_with_broken_link_callback(md, Options::empty(),
-                                                      Some(&replacer));
+        let p = Parser::new_with_broken_link_callback(md, Options::empty(), Some(&replacer));
 
         let mut s = String::new();
 
index 130451d07af8649bb188549cb6b2fd27c4d17c2c..41c08dbf4ab6552121e50eed28eeb3b689978795 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
@@ -1656,6 +1669,8 @@ pub fn new(root_path: &'a str, suffix: &'a str) -> Settings<'a> {
             settings: vec![
                 ("item-declarations", "Auto-hide item declarations.", true),
                 ("item-attributes", "Auto-hide item attributes.", true),
+                ("trait-implementations", "Auto-hide trait implementations documentation",
+                 true),
                 ("go-to-only-result", "Directly go to item in search if there is only one result",
                  false),
             ],
index 01eb1ce7407be16fa868b1a45e2d356201dc1ba7..3bd343c0c0b6813d93804bf02e8268133d0cace2 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;
         if (collapse) {
             toggleAllDocs(pageId, true);
         }
-        onEach(document.getElementsByClassName("collapse-toggle"), function(e) {
-            // inherent impl ids are like 'impl' or impl-<number>'.
-            // they will never be hidden by default.
-            var n = e.parentNode;
-            if (n.id.match(/^impl(?:-\d+)?$/) === null) {
-                // Automatically minimize all non-inherent impls
-                if (collapse || hasClass(n, 'impl')) {
-                    collapseDocs(e, "hide", pageId);
+        if (getCurrentValue('rustdoc-trait-implementations') !== "false") {
+            onEach(document.getElementsByClassName("collapse-toggle"), function(e) {
+                // inherent impl ids are like 'impl' or impl-<number>'.
+                // they will never be hidden by default.
+                var n = e.parentNode;
+                if (n.id.match(/^impl(?:-\d+)?$/) === null) {
+                    // Automatically minimize all non-inherent impls
+                    if (collapse || hasClass(n, 'impl')) {
+                        collapseDocs(e, "hide", pageId);
+                    }
                 }
-            }
-        });
+            });
+        }
     }
 
     var x = document.getElementById('toggle-all-docs');
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 284406589b38c5d48e08385a347995cf4939a63c..3e26ed2b97c23c893bb05f1f0857076a2e230c7f 100644 (file)
@@ -68,6 +68,7 @@
 use rustc::session::config::{ErrorOutputType, RustcOptGroup, Externs, CodegenOptions};
 use rustc::session::config::{nightly_options, build_codegen_options};
 use rustc_target::spec::TargetTriple;
+use rustc::session::config::get_cmd_lint_options;
 
 #[macro_use]
 pub mod externalfiles;
@@ -164,7 +165,7 @@ pub fn opts() -> Vec<RustcOptGroup> {
             o.optmulti("", "extern", "pass an --extern to rustc", "NAME=PATH")
         }),
         stable("plugin-path", |o| {
-            o.optmulti("", "plugin-path", "directory to load plugins from", "DIR")
+            o.optmulti("", "plugin-path", "removed", "DIR")
         }),
         stable("C", |o| {
             o.optmulti("C", "codegen", "pass a codegen option to rustc", "OPT[=VALUE]")
@@ -177,7 +178,7 @@ pub fn opts() -> Vec<RustcOptGroup> {
                        "PASSES")
         }),
         stable("plugins", |o| {
-            o.optmulti("", "plugins", "space separated list of plugins to also load",
+            o.optmulti("", "plugins", "removed",
                        "PLUGINS")
         }),
         stable("no-default", |o| {
@@ -308,6 +309,28 @@ pub fn opts() -> Vec<RustcOptGroup> {
                        "disable-minification",
                        "Disable minification applied on JS files")
         }),
+        unstable("warn", |o| {
+            o.optmulti("W", "warn", "Set lint warnings", "OPT")
+        }),
+        unstable("allow", |o| {
+            o.optmulti("A", "allow", "Set lint allowed", "OPT")
+        }),
+        unstable("deny", |o| {
+            o.optmulti("D", "deny", "Set lint denied", "OPT")
+        }),
+        unstable("forbid", |o| {
+            o.optmulti("F", "forbid", "Set lint forbidden", "OPT")
+        }),
+        unstable("cap-lints", |o| {
+            o.optmulti(
+                "",
+                "cap-lints",
+                "Set the most restrictive lint level. \
+                 More restrictive lints are capped at this \
+                 level. By default, it is at `forbid` level.",
+                "LEVEL",
+            )
+        }),
     ]
 }
 
@@ -640,6 +663,8 @@ fn rust_input<R, F>(cratefile: PathBuf,
         *x == "force-unstable-if-unmarked"
     });
 
+    let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
+
     let (tx, rx) = channel();
 
     rustc_driver::monitor(move || syntax::with_globals(move || {
@@ -648,7 +673,8 @@ fn rust_input<R, F>(cratefile: PathBuf,
         let (mut krate, renderinfo) =
             core::run_core(paths, cfgs, externs, Input::File(cratefile), triple, maybe_sysroot,
                            display_warnings, crate_name.clone(),
-                           force_unstable_if_unmarked, edition, cg, error_format);
+                           force_unstable_if_unmarked, edition, cg, error_format,
+                           lint_opts, lint_cap, describe_lints);
 
         info!("finished with rustc");
 
@@ -715,9 +741,16 @@ fn report_deprecated_attr(name: &str, diag: &errors::Handler) {
             }
         }
 
+        if !plugins.is_empty() {
+            eprintln!("WARNING: --plugins no longer functions; see CVE-2018-1000622");
+        }
+
+        if !plugin_path.is_none() {
+            eprintln!("WARNING: --plugin-path no longer functions; see CVE-2018-1000622");
+        }
+
         // Load all plugins/passes into a PluginManager
-        let path = plugin_path.unwrap_or("/tmp/rustdoc/plugins".to_string());
-        let mut pm = plugins::PluginManager::new(PathBuf::from(path));
+        let mut pm = plugins::PluginManager::new();
         for pass in &passes {
             let plugin = match passes::PASSES.iter()
                                              .position(|&(p, ..)| {
@@ -731,10 +764,6 @@ fn report_deprecated_attr(name: &str, diag: &errors::Handler) {
             };
             pm.add_plugin(plugin);
         }
-        info!("loading plugins...");
-        for pname in plugins {
-            pm.load_plugin(pname);
-        }
 
         // Run everything!
         info!("Executing passes/plugins");
@@ -750,8 +779,6 @@ fn check_deprecated_options(matches: &getopts::Matches, diag: &errors::Handler)
     let deprecated_flags = [
        "input-format",
        "output-format",
-       "plugin-path",
-       "plugins",
        "no-defaults",
        "passes",
     ];
index 1a1e60a6945edd2fc26bb7e3c8a7fbe5292aec89..261ff728aef605aabe41a2a10cbc50134c1271f5 100644 (file)
 
 use clean;
 
-use std::mem;
-use std::string::String;
-use std::path::PathBuf;
-
-use rustc_metadata::dynamic_lib as dl;
-
 pub type PluginResult = clean::Crate;
 pub type PluginCallback = fn (clean::Crate) -> PluginResult;
 
 /// Manages loading and running of plugins
 pub struct PluginManager {
-    dylibs: Vec<dl::DynamicLibrary> ,
     callbacks: Vec<PluginCallback> ,
-    /// The directory plugins will be loaded from
-    pub prefix: PathBuf,
 }
 
 impl PluginManager {
     /// Create a new plugin manager
-    pub fn new(prefix: PathBuf) -> PluginManager {
+    pub fn new() -> PluginManager {
         PluginManager {
-            dylibs: Vec::new(),
             callbacks: Vec::new(),
-            prefix,
-        }
-    }
-
-    /// Load a plugin with the given name.
-    ///
-    /// Turns `name` into the proper dynamic library filename for the given
-    /// platform. On windows, it turns into name.dll, on macOS, name.dylib, and
-    /// elsewhere, libname.so.
-    pub fn load_plugin(&mut self, name: String) {
-        let x = self.prefix.join(libname(name));
-        let lib_result = dl::DynamicLibrary::open(Some(&x));
-        let lib = lib_result.unwrap();
-        unsafe {
-            let plugin = lib.symbol("rustdoc_plugin_entrypoint").unwrap();
-            self.callbacks.push(mem::transmute::<*mut u8,PluginCallback>(plugin));
         }
-        self.dylibs.push(lib);
     }
 
     /// Load a normal Rust function as a plugin.
@@ -70,23 +43,3 @@ pub fn run_plugins(&self, mut krate: clean::Crate) -> clean::Crate {
         krate
     }
 }
-
-#[cfg(target_os = "windows")]
-fn libname(mut n: String) -> String {
-    n.push_str(".dll");
-    n
-}
-
-#[cfg(target_os="macos")]
-fn libname(mut n: String) -> String {
-    n.push_str(".dylib");
-    n
-}
-
-#[cfg(all(not(target_os="windows"), not(target_os="macos")))]
-fn libname(n: String) -> String {
-    let mut i = String::from("lib");
-    i.push_str(&n);
-    i.push_str(".so");
-    i
-}
index fdeba93990d1c244352befe719f5a5c4ceeec347..b7a9f95fdc0de9d7bdb9a9a90eeadd677e28a7a5 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
     }
 
@@ -362,11 +323,6 @@ fn inherits_doc_hidden(cx: &core::DocContext, mut node: ast::NodeId) -> bool {
                 });
                 true
             }
-            hir_map::NodeStructCtor(_) if !glob => {
-                // struct constructors always show up alongside their struct definitions, we've
-                // already processed that so just discard this
-                true
-            }
             _ => false,
         };
         self.view_item_stack.remove(&def_node_id);
@@ -414,6 +370,13 @@ pub fn visit_item(&mut self, item: &hir::Item,
             hir::ItemUse(ref path, kind) => {
                 let is_glob = kind == hir::UseKind::Glob;
 
+                // struct and variant constructors always show up alongside their definitions, we've
+                // already processed them so just discard these.
+                match path.def {
+                    Def::StructCtor(..) | Def::VariantCtor(..) => return,
+                    _ => {}
+                }
+
                 // If there was a private module in the current path then don't bother inlining
                 // anything as it will probably be stripped anyway.
                 if item.vis.node.is_pub() && self.inside_public_path {
index f6cecbea11f8d89fefbf1114a74e4dfaf139d3bd..8db365cd21d67938be2bbca12cfee14a3fded4cd 100644 (file)
@@ -125,9 +125,10 @@ fn default_alloc_error_hook(layout: Layout) {
 
 #[cfg(not(test))]
 #[doc(hidden)]
-#[lang = "oom"]
+#[cfg_attr(stage0, lang = "oom")]
+#[cfg_attr(not(stage0), alloc_error_handler)]
 #[unstable(feature = "alloc_internals", issue = "0")]
-pub extern fn rust_oom(layout: Layout) -> ! {
+pub fn rust_oom(layout: Layout) -> ! {
     let hook = HOOK.load(Ordering::SeqCst);
     let hook: fn(Layout) = if hook.is_null() {
         default_alloc_error_hook
index 9d5aebde62568ff87d681987907453c9a971e551..26d93f97e69f381e6e56479e9fe1775ab3af2b19 100644 (file)
@@ -121,7 +121,8 @@ fn build_libbacktrace(target: &str) -> Result<(), ()> {
     if !target.contains("apple-ios") &&
        !target.contains("solaris") &&
        !target.contains("redox") &&
-       !target.contains("android") {
+       !target.contains("android") &&
+       !target.contains("haiku") {
         build.define("HAVE_DL_ITERATE_PHDR", "1");
     }
     build.define("_GNU_SOURCE", "1");
index 91e417c64da6e9a314de21be4a0950dfa7272df3..9066c0b7694793b9319789634df49d5587250486 100644 (file)
@@ -512,18 +512,20 @@ fn description(&self) -> &str { self.inner.description() }
 ///
 /// # Unix
 ///
-/// Returns the value of the 'HOME' environment variable if it is set
-/// and not equal to the empty string. Otherwise, it tries to determine the
-/// home directory by invoking the `getpwuid_r` function on the UID of the
-/// current user.
+/// - Returns the value of the 'HOME' environment variable if it is set
+///   (including to an empty string).
+/// - Otherwise, it tries to determine the home directory by invoking the `getpwuid_r` function
+///   using the UID of the current user. An empty home directory field returned from the
+///   `getpwuid_r` function is considered to be a valid value.
+/// - Returns `None` if the current user has no entry in the /etc/passwd file.
 ///
 /// # Windows
 ///
-/// Returns the value of the 'HOME' environment variable if it is
-/// set and not equal to the empty string. Otherwise, returns the value of the
-/// 'USERPROFILE' environment variable if it is set and not equal to the empty
-/// string. If both do not exist, [`GetUserProfileDirectory`][msdn] is used to
-/// return the appropriate path.
+/// - Returns the value of the 'HOME' environment variable if it is set
+///   (including to an empty string).
+/// - Otherwise, returns the value of the 'USERPROFILE' environment variable if it is set
+///   (including to an empty string).
+/// - If both do not exist, [`GetUserProfileDirectory`][msdn] is used to return the path.
 ///
 /// [msdn]: https://msdn.microsoft.com/en-us/library/windows/desktop/bb762280(v=vs.85).aspx
 ///
@@ -533,10 +535,13 @@ fn description(&self) -> &str { self.inner.description() }
 /// use std::env;
 ///
 /// match env::home_dir() {
-///     Some(path) => println!("{}", path.display()),
+///     Some(path) => println!("Your home directory, probably: {}", path.display()),
 ///     None => println!("Impossible to get your home dir!"),
 /// }
 /// ```
+#[rustc_deprecated(since = "1.29.0",
+    reason = "This function's behavior is unexpected and probably not what you want. \
+              Consider using the home_dir function from https://crates.io/crates/dirs instead.")]
 #[stable(feature = "env", since = "1.0.0")]
 pub fn home_dir() -> Option<PathBuf> {
     os_imp::home_dir()
index 6513d11dd517c436c25afe16c7def1f54d1cea0c..b816f4b7850efb17aaea0f3e4b0bcca774a838a4 100644 (file)
@@ -706,6 +706,14 @@ fn from(s: Box<CStr>) -> CString {
     }
 }
 
+#[stable(feature = "more_box_slice_clone", since = "1.29.0")]
+impl Clone for Box<CStr> {
+    #[inline]
+    fn clone(&self) -> Self {
+        (**self).into()
+    }
+}
+
 #[stable(feature = "box_from_c_string", since = "1.20.0")]
 impl From<CString> for Box<CStr> {
     #[inline]
index 4ada6a77a8eec9ff1d24388103d48cf2e4134db6..b1c6e7af693d0a00eae72517ef9fe984dfe644d9 100644 (file)
@@ -642,6 +642,14 @@ fn from(s: OsString) -> Box<OsStr> {
     }
 }
 
+#[stable(feature = "more_box_slice_clone", since = "1.29.0")]
+impl Clone for Box<OsStr> {
+    #[inline]
+    fn clone(&self) -> Self {
+        self.to_os_string().into_boxed_os_str()
+    }
+}
+
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<OsString> for Arc<OsStr> {
     #[inline]
index 987687ea8e865b7acbe575ddceedc5c07b16aaa6..7632fbc41f5a322e64fe0ddfca7050178ce94e22 100644 (file)
@@ -356,9 +356,9 @@ impl File {
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
-    /// let mut f = File::open("foo.txt")?;
-    /// # Ok(())
-    /// }
+    ///     let mut f = File::open("foo.txt")?;
+    ///     Ok(())
+    /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {
index d73cb1f8349a655ca5414a42445b93360bc31cc8..fec14b8d67d359c0322a449439e000878fe99d60 100644 (file)
 // std is implemented with unstable features, many of which are internal
 // compiler details that will never be stable
 #![feature(alloc)]
-#![feature(allocator_api)]
+#![feature(alloc_error_handler)]
 #![feature(alloc_system)]
+#![feature(allocator_api)]
 #![feature(allocator_internals)]
 #![feature(allow_internal_unsafe)]
 #![feature(allow_internal_unstable)]
index 3dc1e9c3dadc85ff4c5c250d8f0d58a68c997fe5..2d8686292788448fa13b98156fdaab240cfabcb4 100644 (file)
@@ -1410,6 +1410,14 @@ fn from(p: PathBuf) -> Box<Path> {
     }
 }
 
+#[stable(feature = "more_box_slice_clone", since = "1.29.0")]
+impl Clone for Box<Path> {
+    #[inline]
+    fn clone(&self) -> Self {
+        self.to_path_buf().into_boxed_path()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for PathBuf {
     fn from(s: &'a T) -> PathBuf {
index feedd4e1abe5f852a37738589ab4071e707616f5..53763da5e288646d3216c7cb142a9159479dbd87 100644 (file)
 //!
 //! See the [module-level documentation](../index.html) for more.
 
+
+
 #![stable(feature = "rust1", since = "1.0.0")]
 
 // Re-exported core operators
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use marker::{Copy, Send, Sized, Sync};
+#[doc(no_inline)]
+pub use marker::{Copy, Send, Sized, Sync};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use ops::{Drop, Fn, FnMut, FnOnce};
+#[doc(no_inline)]
+pub use ops::{Drop, Fn, FnMut, FnOnce};
 
 // Re-exported functions
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use mem::drop;
+#[doc(no_inline)]
+pub use mem::drop;
 
 // Re-exported types and traits
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use boxed::Box;
+#[doc(no_inline)]
+pub use clone::Clone;
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use borrow::ToOwned;
+#[doc(no_inline)]
+pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use clone::Clone;
+#[doc(no_inline)]
+pub use convert::{AsRef, AsMut, Into, From};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
+#[doc(no_inline)]
+pub use default::Default;
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use convert::{AsRef, AsMut, Into, From};
+#[doc(no_inline)]
+pub use iter::{Iterator, Extend, IntoIterator};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use default::Default;
+#[doc(no_inline)]
+pub use iter::{DoubleEndedIterator, ExactSizeIterator};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use iter::{Iterator, Extend, IntoIterator};
+#[doc(no_inline)]
+pub use option::Option::{self, Some, None};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use iter::{DoubleEndedIterator, ExactSizeIterator};
+#[doc(no_inline)]
+pub use result::Result::{self, Ok, Err};
+
+
+// The file so far is equivalent to src/libcore/prelude/v1.rs,
+// and below to src/liballoc/prelude.rs.
+// Those files are duplicated rather than using glob imports
+// because we want docs to show these re-exports as pointing to within `std`.
+
+
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use option::Option::{self, Some, None};
+#[doc(no_inline)]
+pub use boxed::Box;
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use result::Result::{self, Ok, Err};
+#[doc(no_inline)]
+pub use borrow::ToOwned;
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use slice::SliceConcatExt;
+#[doc(no_inline)]
+pub use slice::SliceConcatExt;
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use string::{String, ToString};
+#[doc(no_inline)]
+pub use string::{String, ToString};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use vec::Vec;
+#[doc(no_inline)]
+pub use vec::Vec;
index 2dd3aebe6108ee839a83e5088d387bc8f76e0a53..cbda5afadcdfc14858813589527d7ba76615fe14 100644 (file)
@@ -689,7 +689,7 @@ fn inner_unsafe(&self) -> &UnsafeCell<Flavor<T>> {
 /// only one [`Receiver`] is supported.
 ///
 /// If the [`Receiver`] is disconnected while trying to [`send`] with the
-/// [`Sender`], the [`send`] method will return a [`SendError`]. Similarly, If the
+/// [`Sender`], the [`send`] method will return a [`SendError`]. Similarly, if the
 /// [`Sender`] is disconnected while trying to [`recv`], the [`recv`] method will
 /// return a [`RecvError`].
 ///
index 7eb7be23128b3143ec4a0e0c833445b95a5cbcfa..51c42995d5e71947c60783b12935bc17e9940eb1 100644 (file)
@@ -149,9 +149,9 @@ struct Waiter {
 
 // Helper struct used to clean up after a closure call with a `Drop`
 // implementation to also run on panic.
-struct Finish {
+struct Finish<'a> {
     panicked: bool,
-    me: &'static Once,
+    me: &'a Once,
 }
 
 impl Once {
@@ -218,7 +218,7 @@ pub const fn new() -> Once {
     ///
     /// [poison]: struct.Mutex.html#poisoning
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn call_once<F>(&'static self, f: F) where F: FnOnce() {
+    pub fn call_once<F>(&self, f: F) where F: FnOnce() {
         // Fast path, just see if we've completed initialization.
         if self.state.load(Ordering::SeqCst) == COMPLETE {
             return
@@ -275,7 +275,7 @@ pub fn call_once<F>(&'static self, f: F) where F: FnOnce() {
     /// INIT.call_once(|| {});
     /// ```
     #[unstable(feature = "once_poison", issue = "33577")]
-    pub fn call_once_force<F>(&'static self, f: F) where F: FnOnce(&OnceState) {
+    pub fn call_once_force<F>(&self, f: F) where F: FnOnce(&OnceState) {
         // same as above, just with a different parameter to `call_inner`.
         if self.state.load(Ordering::SeqCst) == COMPLETE {
             return
@@ -299,7 +299,7 @@ pub fn call_once_force<F>(&'static self, f: F) where F: FnOnce(&OnceState) {
     // currently no way to take an `FnOnce` and call it via virtual dispatch
     // without some allocation overhead.
     #[cold]
-    fn call_inner(&'static self,
+    fn call_inner(&self,
                   ignore_poisoning: bool,
                   init: &mut FnMut(bool)) {
         let mut state = self.state.load(Ordering::SeqCst);
@@ -390,7 +390,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl Drop for Finish {
+impl<'a> Drop for Finish<'a> {
     fn drop(&mut self) {
         // Swap out our state with however we finished. We should only ever see
         // an old state which was RUNNING.
index 9fd8d6c91869c07422eedf0c7f10deb008ed985c..cb2c75ae0bfa8e1824bd936178ba45aa05cf7884 100644 (file)
@@ -33,6 +33,7 @@
 pub mod ffi;
 pub mod fs;
 pub mod io;
+pub mod net;
 pub mod process;
 pub mod thread;
 
diff --git a/src/libstd/sys/redox/ext/net.rs b/src/libstd/sys/redox/ext/net.rs
new file mode 100644 (file)
index 0000000..4c5f857
--- /dev/null
@@ -0,0 +1,729 @@
+// 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.
+
+#![unstable(feature = "unix_socket_redox", reason = "new feature", issue="51553")]
+
+//! Unix-specific networking functionality
+
+use fmt;
+use io::{self, Error, ErrorKind, Initializer};
+use net::Shutdown;
+use os::unix::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd};
+use path::Path;
+use time::Duration;
+use sys::{cvt, fd::FileDesc, syscall};
+
+/// An address associated with a Unix socket.
+///
+/// # Examples
+///
+/// ```
+/// use std::os::unix::net::UnixListener;
+///
+/// let socket = match UnixListener::bind("/tmp/sock") {
+///     Ok(sock) => sock,
+///     Err(e) => {
+///         println!("Couldn't bind: {:?}", e);
+///         return
+///     }
+/// };
+/// let addr = socket.local_addr().expect("Couldn't get local address");
+/// ```
+#[derive(Clone)]
+pub struct SocketAddr(());
+
+impl SocketAddr {
+    /// Returns the contents of this address if it is a `pathname` address.
+    ///
+    /// # Examples
+    ///
+    /// With a pathname:
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    /// use std::path::Path;
+    ///
+    /// let socket = UnixListener::bind("/tmp/sock").unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock")));
+    /// ```
+    ///
+    /// Without a pathname:
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let socket = UnixDatagram::unbound().unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// assert_eq!(addr.as_pathname(), None);
+    /// ```
+    pub fn as_pathname(&self) -> Option<&Path> {
+        None
+    }
+
+    /// Returns true if and only if the address is unnamed.
+    ///
+    /// # Examples
+    ///
+    /// A named address:
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let socket = UnixListener::bind("/tmp/sock").unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// assert_eq!(addr.is_unnamed(), false);
+    /// ```
+    ///
+    /// An unnamed address:
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let socket = UnixDatagram::unbound().unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// assert_eq!(addr.is_unnamed(), true);
+    /// ```
+    pub fn is_unnamed(&self) -> bool {
+        false
+    }
+}
+impl fmt::Debug for SocketAddr {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        write!(fmt, "SocketAddr")
+    }
+}
+
+/// A Unix stream socket.
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::os::unix::net::UnixStream;
+/// use std::io::prelude::*;
+///
+/// let mut stream = UnixStream::connect("/path/to/my/socket").unwrap();
+/// stream.write_all(b"hello world").unwrap();
+/// let mut response = String::new();
+/// stream.read_to_string(&mut response).unwrap();
+/// println!("{}", response);
+/// ```
+pub struct UnixStream(FileDesc);
+
+impl fmt::Debug for UnixStream {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        let mut builder = fmt.debug_struct("UnixStream");
+        builder.field("fd", &self.0.raw());
+        if let Ok(addr) = self.local_addr() {
+            builder.field("local", &addr);
+        }
+        if let Ok(addr) = self.peer_addr() {
+            builder.field("peer", &addr);
+        }
+        builder.finish()
+    }
+}
+
+impl UnixStream {
+    /// Connects to the socket named by `path`.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = match UnixStream::connect("/tmp/sock") {
+    ///     Ok(sock) => sock,
+    ///     Err(e) => {
+    ///         println!("Couldn't connect: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
+    pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
+        if let Some(s) = path.as_ref().to_str() {
+            cvt(syscall::open(format!("chan:{}", s), syscall::O_CLOEXEC))
+                .map(FileDesc::new)
+                .map(UnixStream)
+        } else {
+            Err(Error::new(
+                ErrorKind::Other,
+                "UnixStream::connect: non-utf8 paths not supported on redox"
+            ))
+        }
+    }
+
+    /// Creates an unnamed pair of connected sockets.
+    ///
+    /// Returns two `UnixStream`s which are connected to each other.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let (sock1, sock2) = match UnixStream::pair() {
+    ///     Ok((sock1, sock2)) => (sock1, sock2),
+    ///     Err(e) => {
+    ///         println!("Couldn't create a pair of sockets: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
+    pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
+        let server = cvt(syscall::open("chan:", syscall::O_CREAT | syscall::O_CLOEXEC))
+            .map(FileDesc::new)?;
+        let client = server.duplicate_path(b"connect")?;
+        let stream = server.duplicate_path(b"listen")?;
+        Ok((UnixStream(client), UnixStream(stream)))
+    }
+
+    /// Creates a new independently owned handle to the underlying socket.
+    ///
+    /// The returned `UnixStream` is a reference to the same stream that this
+    /// object references. Both handles will read and write the same stream of
+    /// data, and options set on one stream will be propagated to the other
+    /// stream.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
+    /// ```
+    pub fn try_clone(&self) -> io::Result<UnixStream> {
+        self.0.duplicate().map(UnixStream)
+    }
+
+    /// Returns the socket address of the local half of this connection.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// ```
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        Err(Error::new(ErrorKind::Other, "UnixStream::local_addr unimplemented on redox"))
+    }
+
+    /// Returns the socket address of the remote half of this connection.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// let addr = socket.peer_addr().expect("Couldn't get peer address");
+    /// ```
+    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+        Err(Error::new(ErrorKind::Other, "UnixStream::peer_addr unimplemented on redox"))
+    }
+
+    /// Sets the read timeout for the socket.
+    ///
+    /// If the provided value is [`None`], then [`read`] calls will block
+    /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
+    /// method.
+    ///
+    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+    /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
+    /// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read
+    /// [`Duration`]: ../../../../std/time/struct.Duration.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
+    /// ```
+    ///
+    /// An [`Err`] is returned if the zero [`Duration`] is passed to this
+    /// method:
+    ///
+    /// ```no_run
+    /// use std::io;
+    /// use std::os::unix::net::UnixStream;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
+    /// let err = result.unwrap_err();
+    /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
+    /// ```
+    pub fn set_read_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> {
+        Err(Error::new(ErrorKind::Other, "UnixStream::set_read_timeout unimplemented on redox"))
+    }
+
+    /// Sets the write timeout for the socket.
+    ///
+    /// If the provided value is [`None`], then [`write`] calls will block
+    /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
+    /// passed to this method.
+    ///
+    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+    /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
+    /// [`write`]: ../../../../std/io/trait.Write.html#tymethod.write
+    /// [`Duration`]: ../../../../std/time/struct.Duration.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
+    /// ```
+    ///
+    /// An [`Err`] is returned if the zero [`Duration`] is passed to this
+    /// method:
+    ///
+    /// ```no_run
+    /// use std::io;
+    /// use std::net::UdpSocket;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
+    /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
+    /// let err = result.unwrap_err();
+    /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
+    /// ```
+    pub fn set_write_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> {
+        Err(Error::new(ErrorKind::Other, "UnixStream::set_write_timeout unimplemented on redox"))
+    }
+
+    /// Returns the read timeout of this socket.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
+    /// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0)));
+    /// ```
+    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
+        Err(Error::new(ErrorKind::Other, "UnixStream::read_timeout unimplemented on redox"))
+    }
+
+    /// Returns the write timeout of this socket.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
+    /// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0)));
+    /// ```
+    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
+        Err(Error::new(ErrorKind::Other, "UnixStream::write_timeout unimplemented on redox"))
+    }
+
+    /// Moves the socket into or out of nonblocking mode.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
+    /// ```
+    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        self.0.set_nonblocking(nonblocking)
+    }
+
+    /// Returns the value of the `SO_ERROR` option.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// if let Ok(Some(err)) = socket.take_error() {
+    ///     println!("Got error: {:?}", err);
+    /// }
+    /// ```
+    ///
+    /// # Platform specific
+    /// On Redox this always returns None.
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        Ok(None)
+    }
+
+    /// Shuts down the read, write, or both halves of this connection.
+    ///
+    /// This function will cause all pending and future I/O calls on the
+    /// specified portions to immediately return with an appropriate value
+    /// (see the documentation of [`Shutdown`]).
+    ///
+    /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::net::Shutdown;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
+    /// ```
+    pub fn shutdown(&self, _how: Shutdown) -> io::Result<()> {
+        Err(Error::new(ErrorKind::Other, "UnixStream::shutdown unimplemented on redox"))
+    }
+}
+
+impl io::Read for UnixStream {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        io::Read::read(&mut &*self, buf)
+    }
+
+    #[inline]
+    unsafe fn initializer(&self) -> Initializer {
+        Initializer::nop()
+    }
+}
+
+impl<'a> io::Read for &'a UnixStream {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        self.0.read(buf)
+    }
+
+    #[inline]
+    unsafe fn initializer(&self) -> Initializer {
+        Initializer::nop()
+    }
+}
+
+impl io::Write for UnixStream {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        io::Write::write(&mut &*self, buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        io::Write::flush(&mut &*self)
+    }
+}
+
+impl<'a> io::Write for &'a UnixStream {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.0.write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+impl AsRawFd for UnixStream {
+    fn as_raw_fd(&self) -> RawFd {
+        self.0.raw()
+    }
+}
+
+impl FromRawFd for UnixStream {
+    unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
+        UnixStream(FileDesc::new(fd))
+    }
+}
+
+impl IntoRawFd for UnixStream {
+    fn into_raw_fd(self) -> RawFd {
+        self.0.into_raw()
+    }
+}
+
+/// A structure representing a Unix domain socket server.
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::thread;
+/// use std::os::unix::net::{UnixStream, UnixListener};
+///
+/// fn handle_client(stream: UnixStream) {
+///     // ...
+/// }
+///
+/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+///
+/// // accept connections and process them, spawning a new thread for each one
+/// for stream in listener.incoming() {
+///     match stream {
+///         Ok(stream) => {
+///             /* connection succeeded */
+///             thread::spawn(|| handle_client(stream));
+///         }
+///         Err(err) => {
+///             /* connection failed */
+///             break;
+///         }
+///     }
+/// }
+/// ```
+pub struct UnixListener(FileDesc);
+
+impl fmt::Debug for UnixListener {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        let mut builder = fmt.debug_struct("UnixListener");
+        builder.field("fd", &self.0.raw());
+        if let Ok(addr) = self.local_addr() {
+            builder.field("local", &addr);
+        }
+        builder.finish()
+    }
+}
+
+impl UnixListener {
+    /// Creates a new `UnixListener` bound to the specified socket.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = match UnixListener::bind("/path/to/the/socket") {
+    ///     Ok(sock) => sock,
+    ///     Err(e) => {
+    ///         println!("Couldn't connect: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
+    pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
+        if let Some(s) = path.as_ref().to_str() {
+            cvt(syscall::open(format!("chan:{}", s), syscall::O_CREAT | syscall::O_CLOEXEC))
+                .map(FileDesc::new)
+                .map(UnixListener)
+        } else {
+            Err(Error::new(
+                ErrorKind::Other,
+                "UnixListener::bind: non-utf8 paths not supported on redox"
+            ))
+        }
+    }
+
+    /// Accepts a new incoming connection to this listener.
+    ///
+    /// This function will block the calling thread until a new Unix connection
+    /// is established. When established, the corresponding [`UnixStream`] and
+    /// the remote peer's address will be returned.
+    ///
+    /// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// match listener.accept() {
+    ///     Ok((socket, addr)) => println!("Got a client: {:?}", addr),
+    ///     Err(e) => println!("accept function failed: {:?}", e),
+    /// }
+    /// ```
+    pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
+        self.0.duplicate_path(b"listen").map(|fd| (UnixStream(fd), SocketAddr(())))
+    }
+
+    /// Creates a new independently owned handle to the underlying socket.
+    ///
+    /// The returned `UnixListener` is a reference to the same socket that this
+    /// object references. Both handles can be used to accept incoming
+    /// connections and options set on one listener will affect the other.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// let listener_copy = listener.try_clone().expect("try_clone failed");
+    /// ```
+    pub fn try_clone(&self) -> io::Result<UnixListener> {
+        self.0.duplicate().map(UnixListener)
+    }
+
+    /// Returns the local socket address of this listener.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// let addr = listener.local_addr().expect("Couldn't get local address");
+    /// ```
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        Err(Error::new(ErrorKind::Other, "UnixListener::local_addr unimplemented on redox"))
+    }
+
+    /// Moves the socket into or out of nonblocking mode.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// listener.set_nonblocking(true).expect("Couldn't set non blocking");
+    /// ```
+    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        self.0.set_nonblocking(nonblocking)
+    }
+
+    /// Returns the value of the `SO_ERROR` option.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/tmp/sock").unwrap();
+    ///
+    /// if let Ok(Some(err)) = listener.take_error() {
+    ///     println!("Got error: {:?}", err);
+    /// }
+    /// ```
+    ///
+    /// # Platform specific
+    /// On Redox this always returns None.
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        Ok(None)
+    }
+
+    /// Returns an iterator over incoming connections.
+    ///
+    /// The iterator will never return [`None`] and will also not yield the
+    /// peer's [`SocketAddr`] structure.
+    ///
+    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+    /// [`SocketAddr`]: struct.SocketAddr.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::thread;
+    /// use std::os::unix::net::{UnixStream, UnixListener};
+    ///
+    /// fn handle_client(stream: UnixStream) {
+    ///     // ...
+    /// }
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// for stream in listener.incoming() {
+    ///     match stream {
+    ///         Ok(stream) => {
+    ///             thread::spawn(|| handle_client(stream));
+    ///         }
+    ///         Err(err) => {
+    ///             break;
+    ///         }
+    ///     }
+    /// }
+    /// ```
+    pub fn incoming<'a>(&'a self) -> Incoming<'a> {
+        Incoming { listener: self }
+    }
+}
+
+impl AsRawFd for UnixListener {
+    fn as_raw_fd(&self) -> RawFd {
+        self.0.raw()
+    }
+}
+
+impl FromRawFd for UnixListener {
+    unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
+        UnixListener(FileDesc::new(fd))
+    }
+}
+
+impl IntoRawFd for UnixListener {
+    fn into_raw_fd(self) -> RawFd {
+        self.0.into_raw()
+    }
+}
+
+impl<'a> IntoIterator for &'a UnixListener {
+    type Item = io::Result<UnixStream>;
+    type IntoIter = Incoming<'a>;
+
+    fn into_iter(self) -> Incoming<'a> {
+        self.incoming()
+    }
+}
+
+/// An iterator over incoming connections to a [`UnixListener`].
+///
+/// It will never return [`None`].
+///
+/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+/// [`UnixListener`]: struct.UnixListener.html
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::thread;
+/// use std::os::unix::net::{UnixStream, UnixListener};
+///
+/// fn handle_client(stream: UnixStream) {
+///     // ...
+/// }
+///
+/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+///
+/// for stream in listener.incoming() {
+///     match stream {
+///         Ok(stream) => {
+///             thread::spawn(|| handle_client(stream));
+///         }
+///         Err(err) => {
+///             break;
+///         }
+///     }
+/// }
+/// ```
+#[derive(Debug)]
+pub struct Incoming<'a> {
+    listener: &'a UnixListener,
+}
+
+impl<'a> Iterator for Incoming<'a> {
+    type Item = io::Result<UnixStream>;
+
+    fn next(&mut self) -> Option<io::Result<UnixStream>> {
+        Some(self.listener.accept().map(|s| s.0))
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (usize::max_value(), None)
+    }
+}
index ba7bbdc657fcf90240696b46d5a28b3d8a0b5f77..e04e2791b23a1a496694af26b6f134d7a566ba27 100644 (file)
@@ -47,7 +47,10 @@ pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
     }
 
     pub fn duplicate(&self) -> io::Result<FileDesc> {
-        let new_fd = cvt(syscall::dup(self.fd, &[]))?;
+        self.duplicate_path(&[])
+    }
+    pub fn duplicate_path(&self, path: &[u8]) -> io::Result<FileDesc> {
+        let new_fd = cvt(syscall::dup(self.fd, path))?;
         Ok(FileDesc::new(new_fd))
     }
 
index e277b1aa7b5f99b872c97f737558677d80bd2d76..55f43ccd7db4d7542e548343e4d4fcf77eb67275 100644 (file)
@@ -524,6 +524,9 @@ pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
     ///     println!("Got error: {:?}", err);
     /// }
     /// ```
+    ///
+    /// # Platform specific
+    /// On Redox this always returns None.
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         self.0.take_error()
@@ -846,6 +849,9 @@ pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
     ///     println!("Got error: {:?}", err);
     /// }
     /// ```
+    ///
+    /// # Platform specific
+    /// On Redox this always returns None.
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         self.0.take_error()
index 4e27d6c15258bedef5e7e59e773f36533eac7ce4..d746ac3c5771bb19f9c15526c1a4c37f3c504ae4 100644 (file)
@@ -90,6 +90,7 @@ pub fn is_known(attr: &Attribute) -> bool {
 }
 
 const RUST_KNOWN_TOOL: &[&str] = &["clippy", "rustfmt"];
+const RUST_KNOWN_LINT_TOOL: &[&str] = &["clippy"];
 
 pub fn is_known_tool(attr: &Attribute) -> bool {
     let tool_name =
@@ -97,6 +98,10 @@ pub fn is_known_tool(attr: &Attribute) -> bool {
     RUST_KNOWN_TOOL.contains(&tool_name.as_str().as_ref())
 }
 
+pub fn is_known_lint_tool(m_item: Ident) -> bool {
+    RUST_KNOWN_LINT_TOOL.contains(&m_item.as_str().as_ref())
+}
+
 impl NestedMetaItem {
     /// Returns the MetaItem if self is a NestedMetaItemKind::MetaItem.
     pub fn meta_item(&self) -> Option<&MetaItem> {
@@ -290,6 +295,14 @@ pub fn is_value_str(&self) -> bool {
     pub fn is_meta_item_list(&self) -> bool {
         self.meta_item_list().is_some()
     }
+
+    pub fn is_scoped(&self) -> Option<Ident> {
+        if self.ident.segments.len() > 1 {
+            Some(self.ident.segments[0].ident)
+        } else {
+            None
+        }
+    }
 }
 
 impl Attribute {
index ea6b39504e81d72463c90b4fd32d1fce8490c6dc..0a9991d33b186c5a98bd2d5757f1af3662bd61fc 100644 (file)
@@ -131,7 +131,7 @@ pub(super) struct CodeMapFiles {
 
 pub struct CodeMap {
     pub(super) files: Lock<CodeMapFiles>,
-    file_loader: Box<FileLoader + Sync + Send>,
+    file_loader: Box<dyn FileLoader + Sync + Send>,
     // This is used to apply the file path remapping as specified via
     // --remap-path-prefix to all FileMaps allocated within this CodeMap.
     path_mapping: FilePathMapping,
@@ -162,7 +162,7 @@ pub fn new_doctest(path_mapping: FilePathMapping,
 
     }
 
-    pub fn with_file_loader(file_loader: Box<FileLoader + Sync + Send>,
+    pub fn with_file_loader(file_loader: Box<dyn FileLoader + Sync + Send>,
                             path_mapping: FilePathMapping)
                             -> CodeMap {
         CodeMap {
@@ -689,6 +689,15 @@ pub fn def_span(&self, sp: Span) -> Span {
         self.span_until_char(sp, '{')
     }
 
+    /// Returns a new span representing just the start-point of this span
+    pub fn start_point(&self, sp: Span) -> Span {
+        let pos = sp.lo().0;
+        let width = self.find_width_of_character_at_span(sp, false);
+        let corrected_start_position = pos.checked_add(width).unwrap_or(pos);
+        let end_point = BytePos(cmp::max(corrected_start_position, sp.lo().0));
+        sp.with_hi(end_point)
+    }
+
     /// Returns a new span representing just the end-point of this span
     pub fn end_point(&self, sp: Span) -> Span {
         let pos = sp.hi().0;
index dc01a79190b3ad90eb884b20bf59a87f58e2c0e8..61b0579a3e76bc137722c31eb1072242fbc9c325 100644 (file)
@@ -73,7 +73,7 @@ fn get_metadata_path(directory: PathBuf, name: &str) -> PathBuf {
 /// For our current purposes the prefix is the target architecture and the name is a crate name.
 /// If an error occurs steps will be taken to ensure that no file is created.
 pub fn output_metadata(ecx: &ExtCtxt, prefix: &str, name: &str, err_map: &ErrorMap)
-    -> Result<(), Box<Error>>
+    -> Result<(), Box<dyn Error>>
 {
     // Create the directory to place the file in.
     let metadata_dir = get_metadata_dir(prefix);
index ca0293aca6e77ad0e22631172568c78247c14c4b..72ce2740190d421ba4d2c1c25adb43b1604ed2d7 100644 (file)
@@ -42,7 +42,7 @@ pub struct ErrorInfo {
 pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
                                    span: Span,
                                    token_tree: &[TokenTree])
-                                   -> Box<MacResult+'cx> {
+                                   -> Box<dyn MacResult+'cx> {
     let code = match (token_tree.len(), token_tree.get(0)) {
         (1, Some(&TokenTree::Token(_, token::Ident(code, _)))) => code,
         _ => unreachable!()
@@ -75,7 +75,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
 pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
                                        span: Span,
                                        token_tree: &[TokenTree])
-                                       -> Box<MacResult+'cx> {
+                                       -> Box<dyn MacResult+'cx> {
     let (code, description) = match (
         token_tree.len(),
         token_tree.get(0),
@@ -145,7 +145,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
 pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
                                           span: Span,
                                           token_tree: &[TokenTree])
-                                          -> Box<MacResult+'cx> {
+                                          -> Box<dyn MacResult+'cx> {
     assert_eq!(token_tree.len(), 3);
     let (crate_name, name) = match (&token_tree[0], &token_tree[2]) {
         (
index e2424de4d1449a25a81d4bcac7618cb5e8bf4fa9..e49a521040fddb17c95ad630385c80b0eca48aad 100644 (file)
@@ -17,7 +17,7 @@
 use edition::Edition;
 use errors::{DiagnosticBuilder, DiagnosticId};
 use ext::expand::{self, AstFragment, Invocation};
-use ext::hygiene::{self, Mark, SyntaxContext};
+use ext::hygiene::{self, Mark, SyntaxContext, Transparency};
 use fold::{self, Folder};
 use parse::{self, parser, DirectoryOwnership};
 use parse::token;
@@ -153,18 +153,18 @@ fn expand(&self,
               sp: Span,
               meta_item: &ast::MetaItem,
               item: &Annotatable,
-              push: &mut FnMut(Annotatable));
+              push: &mut dyn FnMut(Annotatable));
 }
 
 impl<F> MultiItemDecorator for F
-    where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &Annotatable, &mut FnMut(Annotatable))
+    where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &Annotatable, &mut dyn FnMut(Annotatable))
 {
     fn expand(&self,
               ecx: &mut ExtCtxt,
               sp: Span,
               meta_item: &ast::MetaItem,
               item: &Annotatable,
-              push: &mut FnMut(Annotatable)) {
+              push: &mut dyn FnMut(Annotatable)) {
         (*self)(ecx, sp, meta_item, item, push)
     }
 }
@@ -247,18 +247,19 @@ fn expand<'cx>(&self,
 /// Represents a thing that maps token trees to Macro Results
 pub trait TTMacroExpander {
     fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, span: Span, input: TokenStream)
-                   -> Box<MacResult+'cx>;
+                   -> Box<dyn MacResult+'cx>;
 }
 
 pub type MacroExpanderFn =
     for<'cx> fn(&'cx mut ExtCtxt, Span, &[tokenstream::TokenTree])
-                -> Box<MacResult+'cx>;
+                -> Box<dyn MacResult+'cx>;
 
 impl<F> TTMacroExpander for F
-    where F: for<'cx> Fn(&'cx mut ExtCtxt, Span, &[tokenstream::TokenTree]) -> Box<MacResult+'cx>
+    where F: for<'cx> Fn(&'cx mut ExtCtxt, Span, &[tokenstream::TokenTree])
+    -> Box<dyn MacResult+'cx>
 {
     fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, span: Span, input: TokenStream)
-                   -> Box<MacResult+'cx> {
+                   -> Box<dyn MacResult+'cx> {
         struct AvoidInterpolatedIdents;
 
         impl Folder for AvoidInterpolatedIdents {
@@ -289,23 +290,23 @@ fn expand<'cx>(&self,
                    sp: Span,
                    ident: ast::Ident,
                    token_tree: Vec<tokenstream::TokenTree>)
-                   -> Box<MacResult+'cx>;
+                   -> Box<dyn MacResult+'cx>;
 }
 
 pub type IdentMacroExpanderFn =
     for<'cx> fn(&'cx mut ExtCtxt, Span, ast::Ident, Vec<tokenstream::TokenTree>)
-                -> Box<MacResult+'cx>;
+                -> Box<dyn MacResult+'cx>;
 
 impl<F> IdentMacroExpander for F
     where F : for<'cx> Fn(&'cx mut ExtCtxt, Span, ast::Ident,
-                          Vec<tokenstream::TokenTree>) -> Box<MacResult+'cx>
+                          Vec<tokenstream::TokenTree>) -> Box<dyn MacResult+'cx>
 {
     fn expand<'cx>(&self,
                    cx: &'cx mut ExtCtxt,
                    sp: Span,
                    ident: ast::Ident,
                    token_tree: Vec<tokenstream::TokenTree>)
-                   -> Box<MacResult+'cx>
+                   -> Box<dyn MacResult+'cx>
     {
         (*self)(cx, sp, ident, token_tree)
     }
@@ -378,7 +379,7 @@ pub struct MacEager {
 
         impl MacEager {
             $(
-                pub fn $fld(v: $t) -> Box<MacResult> {
+                pub fn $fld(v: $t) -> Box<dyn MacResult> {
                     Box::new(MacEager {
                         $fld: Some(v),
                         ..Default::default()
@@ -462,7 +463,7 @@ impl DummyResult {
     ///
     /// Use this as a return value after hitting any errors and
     /// calling `span_err`.
-    pub fn any(sp: Span) -> Box<MacResult+'static> {
+    pub fn any(sp: Span) -> Box<dyn MacResult+'static> {
         Box::new(DummyResult { expr_only: false, span: sp })
     }
 
@@ -471,7 +472,7 @@ pub fn any(sp: Span) -> Box<MacResult+'static> {
     /// Use this for macros that must expand to an expression, so even
     /// if an error is encountered internally, the user will receive
     /// an error that they also used it in the wrong place.
-    pub fn expr(sp: Span) -> Box<MacResult+'static> {
+    pub fn expr(sp: Span) -> Box<dyn MacResult+'static> {
         Box::new(DummyResult { expr_only: true, span: sp })
     }
 
@@ -559,7 +560,7 @@ fn make_ty(self: Box<DummyResult>) -> Option<P<ast::Ty>> {
 }
 
 pub type BuiltinDeriveFn =
-    for<'cx> fn(&'cx mut ExtCtxt, Span, &MetaItem, &Annotatable, &mut FnMut(Annotatable));
+    for<'cx> fn(&'cx mut ExtCtxt, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable));
 
 /// Represents different kinds of macro invocations that can be resolved.
 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
@@ -590,15 +591,15 @@ pub enum SyntaxExtension {
     /// `#[derive(...)]` is a `MultiItemDecorator`.
     ///
     /// Prefer ProcMacro or MultiModifier since they are more flexible.
-    MultiDecorator(Box<MultiItemDecorator + sync::Sync + sync::Send>),
+    MultiDecorator(Box<dyn MultiItemDecorator + sync::Sync + sync::Send>),
 
     /// A syntax extension that is attached to an item and modifies it
     /// in-place. Also allows decoration, i.e., creating new items.
-    MultiModifier(Box<MultiItemModifier + sync::Sync + sync::Send>),
+    MultiModifier(Box<dyn MultiItemModifier + sync::Sync + sync::Send>),
 
     /// A function-like procedural macro. TokenStream -> TokenStream.
     ProcMacro {
-        expander: Box<ProcMacro + sync::Sync + sync::Send>,
+        expander: Box<dyn ProcMacro + sync::Sync + sync::Send>,
         allow_internal_unstable: bool,
         edition: Edition,
     },
@@ -607,13 +608,13 @@ pub enum SyntaxExtension {
     /// The first TokenSteam is the attribute, the second is the annotated item.
     /// Allows modification of the input items and adding new items, similar to
     /// MultiModifier, but uses TokenStreams, rather than AST nodes.
-    AttrProcMacro(Box<AttrProcMacro + sync::Sync + sync::Send>, Edition),
+    AttrProcMacro(Box<dyn AttrProcMacro + sync::Sync + sync::Send>, Edition),
 
     /// A normal, function-like syntax extension.
     ///
     /// `bytes!` is a `NormalTT`.
     NormalTT {
-        expander: Box<TTMacroExpander + sync::Sync + sync::Send>,
+        expander: Box<dyn TTMacroExpander + sync::Sync + sync::Send>,
         def_info: Option<(ast::NodeId, Span)>,
         /// Whether the contents of the macro can
         /// directly use `#[unstable]` things (true == yes).
@@ -633,13 +634,13 @@ pub enum SyntaxExtension {
     /// A function-like syntax extension that has an extra ident before
     /// the block.
     ///
-    IdentTT(Box<IdentMacroExpander + sync::Sync + sync::Send>, Option<Span>, bool),
+    IdentTT(Box<dyn IdentMacroExpander + sync::Sync + sync::Send>, Option<Span>, bool),
 
     /// An attribute-like procedural macro. TokenStream -> TokenStream.
     /// The input is the annotated item.
     /// Allows generating code to implement a Trait for a given struct
     /// or enum item.
-    ProcMacroDerive(Box<MultiItemModifier + sync::Sync + sync::Send>,
+    ProcMacroDerive(Box<dyn MultiItemModifier + sync::Sync + sync::Send>,
                     Vec<Symbol> /* inert attribute names */, Edition),
 
     /// An attribute-like procedural macro that derives a builtin trait.
@@ -647,7 +648,7 @@ pub enum SyntaxExtension {
 
     /// A declarative macro, e.g. `macro m() {}`.
     DeclMacro {
-        expander: Box<TTMacroExpander + sync::Sync + sync::Send>,
+        expander: Box<dyn TTMacroExpander + sync::Sync + sync::Send>,
         def_info: Option<(ast::NodeId, Span)>,
         is_transparent: bool,
         edition: Edition,
@@ -673,20 +674,14 @@ pub fn kind(&self) -> MacroKind {
         }
     }
 
-    pub fn is_modern(&self) -> bool {
+    pub fn default_transparency(&self) -> Transparency {
         match *self {
-            SyntaxExtension::DeclMacro { .. } |
             SyntaxExtension::ProcMacro { .. } |
             SyntaxExtension::AttrProcMacro(..) |
-            SyntaxExtension::ProcMacroDerive(..) => true,
-            _ => false,
-        }
-    }
-
-    pub fn is_transparent(&self) -> bool {
-        match *self {
-            SyntaxExtension::DeclMacro { is_transparent, .. } => is_transparent,
-            _ => false,
+            SyntaxExtension::ProcMacroDerive(..) |
+            SyntaxExtension::DeclMacro { is_transparent: false, .. } => Transparency::Opaque,
+            SyntaxExtension::DeclMacro { is_transparent: true, .. } => Transparency::Transparent,
+            _ => Transparency::SemiTransparent,
         }
     }
 
@@ -784,7 +779,7 @@ pub struct ExtCtxt<'a> {
     pub parse_sess: &'a parse::ParseSess,
     pub ecfg: expand::ExpansionConfig<'a>,
     pub root_path: PathBuf,
-    pub resolver: &'a mut Resolver,
+    pub resolver: &'a mut dyn Resolver,
     pub resolve_err_count: usize,
     pub current_expansion: ExpansionData,
     pub expansions: HashMap<Span, Vec<String>>,
@@ -793,7 +788,7 @@ pub struct ExtCtxt<'a> {
 impl<'a> ExtCtxt<'a> {
     pub fn new(parse_sess: &'a parse::ParseSess,
                ecfg: expand::ExpansionConfig<'a>,
-               resolver: &'a mut Resolver)
+               resolver: &'a mut dyn Resolver)
                -> ExtCtxt<'a> {
         ExtCtxt {
             parse_sess,
index f29bff20f3dd6a4d671c81a472375d1210786ef5..865cb3d0d45783d65580cd93f4f8f5ed1fa2e3f8 100644 (file)
@@ -71,7 +71,7 @@ pub fn name(self) -> &'static str {
                 }
             }
 
-            fn make_from<'a>(self, result: Box<MacResult + 'a>) -> Option<AstFragment> {
+            fn make_from<'a>(self, result: Box<dyn MacResult + 'a>) -> Option<AstFragment> {
                 match self {
                     AstFragmentKind::OptExpr =>
                         result.make_expr().map(Some).map(AstFragment::OptExpr),
index a6e6ccde72c9f46b2b0a54b0fbf82d7c9497a9e8..1ace4d4a880e212f9e75b6bd26954bb8d2f4e918 100644 (file)
@@ -452,7 +452,7 @@ pub fn parse_path_panic(parser: &mut Parser, mode: PathStyle) -> ast::Path {
 pub fn expand_quote_tokens<'cx>(cx: &'cx mut ExtCtxt,
                                 sp: Span,
                                 tts: &[TokenTree])
-                                -> Box<base::MacResult+'cx> {
+                                -> Box<dyn base::MacResult+'cx> {
     let (cx_expr, expr) = expand_tts(cx, sp, tts);
     let expanded = expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"]]);
     base::MacEager::expr(expanded)
@@ -461,7 +461,7 @@ pub fn expand_quote_tokens<'cx>(cx: &'cx mut ExtCtxt,
 pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt,
                               sp: Span,
                               tts: &[TokenTree])
-                              -> Box<base::MacResult+'cx> {
+                              -> Box<dyn base::MacResult+'cx> {
     let expanded = expand_parse_call(cx, sp, "parse_expr_panic", vec![], tts);
     base::MacEager::expr(expanded)
 }
@@ -469,7 +469,7 @@ pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt,
 pub fn expand_quote_item<'cx>(cx: &'cx mut ExtCtxt,
                               sp: Span,
                               tts: &[TokenTree])
-                              -> Box<base::MacResult+'cx> {
+                              -> Box<dyn base::MacResult+'cx> {
     let expanded = expand_parse_call(cx, sp, "parse_item_panic", vec![], tts);
     base::MacEager::expr(expanded)
 }
@@ -477,7 +477,7 @@ pub fn expand_quote_item<'cx>(cx: &'cx mut ExtCtxt,
 pub fn expand_quote_pat<'cx>(cx: &'cx mut ExtCtxt,
                              sp: Span,
                              tts: &[TokenTree])
-                             -> Box<base::MacResult+'cx> {
+                             -> Box<dyn base::MacResult+'cx> {
     let expanded = expand_parse_call(cx, sp, "parse_pat_panic", vec![], tts);
     base::MacEager::expr(expanded)
 }
@@ -485,7 +485,7 @@ pub fn expand_quote_pat<'cx>(cx: &'cx mut ExtCtxt,
 pub fn expand_quote_arm(cx: &mut ExtCtxt,
                         sp: Span,
                         tts: &[TokenTree])
-                        -> Box<base::MacResult+'static> {
+                        -> Box<dyn base::MacResult+'static> {
     let expanded = expand_parse_call(cx, sp, "parse_arm_panic", vec![], tts);
     base::MacEager::expr(expanded)
 }
@@ -493,7 +493,7 @@ pub fn expand_quote_arm(cx: &mut ExtCtxt,
 pub fn expand_quote_ty(cx: &mut ExtCtxt,
                        sp: Span,
                        tts: &[TokenTree])
-                       -> Box<base::MacResult+'static> {
+                       -> Box<dyn base::MacResult+'static> {
     let expanded = expand_parse_call(cx, sp, "parse_ty_panic", vec![], tts);
     base::MacEager::expr(expanded)
 }
@@ -501,7 +501,7 @@ pub fn expand_quote_ty(cx: &mut ExtCtxt,
 pub fn expand_quote_stmt(cx: &mut ExtCtxt,
                          sp: Span,
                          tts: &[TokenTree])
-                         -> Box<base::MacResult+'static> {
+                         -> Box<dyn base::MacResult+'static> {
     let expanded = expand_parse_call(cx, sp, "parse_stmt_panic", vec![], tts);
     base::MacEager::expr(expanded)
 }
@@ -509,7 +509,7 @@ pub fn expand_quote_stmt(cx: &mut ExtCtxt,
 pub fn expand_quote_attr(cx: &mut ExtCtxt,
                          sp: Span,
                          tts: &[TokenTree])
-                         -> Box<base::MacResult+'static> {
+                         -> Box<dyn base::MacResult+'static> {
     let expanded = expand_parse_call(cx, sp, "parse_attribute_panic",
                                     vec![cx.expr_bool(sp, true)], tts);
 
@@ -519,7 +519,7 @@ pub fn expand_quote_attr(cx: &mut ExtCtxt,
 pub fn expand_quote_arg(cx: &mut ExtCtxt,
                         sp: Span,
                         tts: &[TokenTree])
-                        -> Box<base::MacResult+'static> {
+                        -> Box<dyn base::MacResult+'static> {
     let expanded = expand_parse_call(cx, sp, "parse_arg_panic", vec![], tts);
     base::MacEager::expr(expanded)
 }
@@ -527,7 +527,7 @@ pub fn expand_quote_arg(cx: &mut ExtCtxt,
 pub fn expand_quote_block(cx: &mut ExtCtxt,
                         sp: Span,
                         tts: &[TokenTree])
-                        -> Box<base::MacResult+'static> {
+                        -> Box<dyn base::MacResult+'static> {
     let expanded = expand_parse_call(cx, sp, "parse_block_panic", vec![], tts);
     base::MacEager::expr(expanded)
 }
@@ -535,7 +535,7 @@ pub fn expand_quote_block(cx: &mut ExtCtxt,
 pub fn expand_quote_meta_item(cx: &mut ExtCtxt,
                         sp: Span,
                         tts: &[TokenTree])
-                        -> Box<base::MacResult+'static> {
+                        -> Box<dyn base::MacResult+'static> {
     let expanded = expand_parse_call(cx, sp, "parse_meta_item_panic", vec![], tts);
     base::MacEager::expr(expanded)
 }
@@ -543,7 +543,7 @@ pub fn expand_quote_meta_item(cx: &mut ExtCtxt,
 pub fn expand_quote_path(cx: &mut ExtCtxt,
                         sp: Span,
                         tts: &[TokenTree])
-                        -> Box<base::MacResult+'static> {
+                        -> Box<dyn base::MacResult+'static> {
     let mode = mk_parser_path(cx, sp, &["PathStyle", "Type"]);
     let expanded = expand_parse_call(cx, sp, "parse_path_panic", vec![mode], tts);
     base::MacEager::expr(expanded)
index 669536f519ce31274453123b7ea42d384851921d..0c36c072a03023a4304d3c3f3656f72d215f4674 100644 (file)
@@ -32,7 +32,7 @@
 
 /// line!(): expands to the current line number
 pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
-                   -> Box<base::MacResult+'static> {
+                   -> Box<dyn base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "line!");
 
     let topmost = cx.expansion_cause().unwrap_or(sp);
@@ -43,7 +43,7 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
 
 /* column!(): expands to the current column number */
 pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
-                  -> Box<base::MacResult+'static> {
+                  -> Box<dyn base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "column!");
 
     let topmost = cx.expansion_cause().unwrap_or(sp);
@@ -54,7 +54,7 @@ pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
 
 /* __rust_unstable_column!(): expands to the current column number */
 pub fn expand_column_gated(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
-                  -> Box<base::MacResult+'static> {
+                  -> Box<dyn base::MacResult+'static> {
     if sp.allows_unstable() {
         expand_column(cx, sp, tts)
     } else {
@@ -66,7 +66,7 @@ pub fn expand_column_gated(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::Token
 /// The filemap (`loc.file`) contains a bunch more information we could spit
 /// out if we wanted.
 pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
-                   -> Box<base::MacResult+'static> {
+                   -> Box<dyn base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "file!");
 
     let topmost = cx.expansion_cause().unwrap_or(sp);
@@ -75,13 +75,13 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
 }
 
 pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
-                        -> Box<base::MacResult+'static> {
+                        -> Box<dyn base::MacResult+'static> {
     let s = pprust::tts_to_string(tts);
     base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&s)))
 }
 
 pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
-                  -> Box<base::MacResult+'static> {
+                  -> Box<dyn base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "module_path!");
     let mod_path = &cx.current_expansion.module.mod_path;
     let string = mod_path.iter().map(|x| x.to_string()).collect::<Vec<String>>().join("::");
@@ -93,7 +93,7 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
 /// This is generally a bad idea because it's going to behave
 /// unhygienically.
 pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
-                           -> Box<base::MacResult+'cx> {
+                           -> Box<dyn base::MacResult+'cx> {
     let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
         Some(f) => f,
         None => return DummyResult::expr(sp),
@@ -131,7 +131,7 @@ fn make_items(mut self: Box<ExpandResult<'a>>)
 
 // include_str! : read the given file, insert it as a literal string expr
 pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
-                          -> Box<base::MacResult+'static> {
+                          -> Box<dyn base::MacResult+'static> {
     let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
         Some(f) => f,
         None => return DummyResult::expr(sp)
@@ -168,7 +168,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenT
 }
 
 pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
-                            -> Box<base::MacResult+'static> {
+                            -> Box<dyn base::MacResult+'static> {
     let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
         Some(f) => f,
         None => return DummyResult::expr(sp)
index 70fc9dada428ea7f8c60f17720fec27a010cb49f..9ebead1062ebcfc3c6b1bb5ea3915e1833f7ecc7 100644 (file)
@@ -73,7 +73,7 @@ fn expand<'cx>(&self,
                    cx: &'cx mut ExtCtxt,
                    sp: Span,
                    input: TokenStream)
-                   -> Box<MacResult+'cx> {
+                   -> Box<dyn MacResult+'cx> {
         if !self.valid {
             return DummyResult::any(sp);
         }
@@ -99,7 +99,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt,
                           arg: TokenStream,
                           lhses: &[quoted::TokenTree],
                           rhses: &[quoted::TokenTree])
-                          -> Box<MacResult+'cx> {
+                          -> Box<dyn MacResult+'cx> {
     if cx.trace_macros() {
         trace_macros_note(cx, sp, format!("expanding `{}! {{ {} }}`", name, arg));
     }
index 2ae0e669fd031a3c0282c22f9f87c7b3ca63befd..e70d93ae85a1d1dca16bd4708a03cb80a1b44964 100644 (file)
@@ -421,7 +421,7 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     (active, wasm_custom_section, "1.26.0", Some(51088), None),
 
     // The #![wasm_import_module] attribute
-    (active, wasm_import_module, "1.26.0", Some(51088), None),
+    (active, wasm_import_module, "1.26.0", Some(52090), None),
 
     // Allows keywords to be escaped for use as identifiers
     (active, raw_identifiers, "1.26.0", Some(48589), None),
@@ -458,6 +458,8 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
 
     // Scoped attributes
     (active, tool_attributes, "1.25.0", Some(44690), None),
+    // Scoped lints
+    (active, tool_lints, "1.28.0", Some(44690), None),
 
     // allow irrefutable patterns in if-let and while-let statements (RFC 2086)
     (active, irrefutable_let_patterns, "1.27.0", Some(44495), None),
@@ -479,6 +481,9 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
 
     // Allows async and await syntax
     (active, async_await, "1.28.0", Some(50547), None),
+
+    // #[alloc_error_handler]
+    (active, alloc_error_handler, "1.29.0", Some(51540), None),
 );
 
 declare_features! (
@@ -1081,6 +1086,11 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
                            "#[panic_implementation] is an unstable feature",
                            cfg_fn!(panic_implementation))),
 
+    ("alloc_error_handler", Normal, Gated(Stability::Unstable,
+                           "alloc_error_handler",
+                           "#[alloc_error_handler] is an unstable feature",
+                           cfg_fn!(alloc_error_handler))),
+
     // Crate level attributes
     ("crate_name", CrateLevel, Ungated),
     ("crate_type", CrateLevel, Ungated),
index f129aea32b8fea36b39c43297def6c93b78513a3..65de1503966bfdc2020aa1aceecc64be687e2a66 100644 (file)
@@ -34,9 +34,9 @@
 use rustc_serialize::json::{as_json, as_pretty_json};
 
 pub struct JsonEmitter {
-    dst: Box<Write + Send>,
+    dst: Box<dyn Write + Send>,
     registry: Option<Registry>,
-    cm: Lrc<CodeMapper + sync::Send + sync::Sync>,
+    cm: Lrc<dyn CodeMapper + sync::Send + sync::Sync>,
     pretty: bool,
     ui_testing: bool,
 }
@@ -60,7 +60,7 @@ pub fn basic(pretty: bool) -> JsonEmitter {
                             pretty)
     }
 
-    pub fn new(dst: Box<Write + Send>,
+    pub fn new(dst: Box<dyn Write + Send>,
                registry: Option<Registry>,
                code_map: Lrc<CodeMap>,
                pretty: bool) -> JsonEmitter {
index 1ace9193dc69dafaf675a0fb9e9c270d6d77a039..ffaad9bf94c187313f7abfbea487d2a8981a9356 100644 (file)
@@ -14,6 +14,8 @@
 //!
 //! This API is completely unstable and subject to change.
 
+#![deny(bare_trait_objects)]
+
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/",
index 3995a9b8689e77e7a4b2f139ee019cef55ccc8f7..20a585b6601a51da4b3cf4f273991efc37958200 100644 (file)
@@ -357,7 +357,7 @@ pub struct Literal {
 
 // it appears this function is called only from pprust... that's
 // probably not a good thing.
-pub fn gather_comments_and_literals(sess: &ParseSess, path: FileName, srdr: &mut Read)
+pub fn gather_comments_and_literals(sess: &ParseSess, path: FileName, srdr: &mut dyn Read)
                                     -> (Vec<Comment>, Vec<Literal>) {
     let mut src = Vec::new();
     srdr.read_to_end(&mut src).unwrap();
index 1f062656b813bed98dbecb6d37a4ed87adc562be..a1b78a23b8f8d777c5a5d1106560f6f465da1165 100644 (file)
@@ -6135,6 +6135,22 @@ fn parse_mod_items(&mut self, term: &token::Token, inner_lo: Span) -> PResult<'a
                 err.span_suggestion_short_with_applicability(
                     self.span, msg, "".to_string(), Applicability::MachineApplicable
                 );
+                if !items.is_empty() {  // Issue #51603
+                    let previous_item = &items[items.len()-1];
+                    let previous_item_kind_name = match previous_item.node {
+                        // say "braced struct" because tuple-structs and
+                        // braceless-empty-struct declarations do take a semicolon
+                        ItemKind::Struct(..) => Some("braced struct"),
+                        ItemKind::Enum(..) => Some("enum"),
+                        ItemKind::Trait(..) => Some("trait"),
+                        ItemKind::Union(..) => Some("union"),
+                        _ => None,
+                    };
+                    if let Some(name) = previous_item_kind_name {
+                        err.help(&format!("{} declarations are not followed by a semicolon",
+                                          name));
+                    }
+                }
             } else {
                 err.span_label(self.span, "expected item");
             }
index e7bd369053cf9c98aed73e40fdfd3e7b2f961686..086de35d531c7f8db1d6b49e25749ba55c6b9ce2 100644 (file)
@@ -241,7 +241,7 @@ pub struct PrintStackElem {
 
 const SIZE_INFINITY: isize = 0xffff;
 
-pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> {
+pub fn mk_printer<'a>(out: Box<dyn io::Write+'a>, linewidth: usize) -> Printer<'a> {
     // Yes 55, it makes the ring buffers big enough to never fall behind.
     let n: usize = 55 * linewidth;
     debug!("mk_printer {}", linewidth);
@@ -264,7 +264,7 @@ pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> {
 }
 
 pub struct Printer<'a> {
-    out: Box<io::Write+'a>,
+    out: Box<dyn io::Write+'a>,
     buf_max_len: usize,
     /// Width of lines we're constrained to
     margin: isize,
index 74edf538842c6bbb717d826597a4dfe6a3d5b7e4..c5ba7daaeb8f687753c849e9c03c12d289bde4fb 100644 (file)
@@ -62,10 +62,10 @@ pub struct State<'a> {
     literals: Peekable<vec::IntoIter<comments::Literal>>,
     cur_cmnt: usize,
     boxes: Vec<pp::Breaks>,
-    ann: &'a (PpAnn+'a),
+    ann: &'a (dyn PpAnn+'a),
 }
 
-fn rust_printer<'a>(writer: Box<Write+'a>, ann: &'a PpAnn) -> State<'a> {
+fn rust_printer<'a>(writer: Box<dyn Write+'a>, ann: &'a dyn PpAnn) -> State<'a> {
     State {
         s: pp::mk_printer(writer, DEFAULT_COLUMNS),
         cm: None,
@@ -88,9 +88,9 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
                        sess: &ParseSess,
                        krate: &ast::Crate,
                        filename: FileName,
-                       input: &mut Read,
-                       out: Box<Write+'a>,
-                       ann: &'a PpAnn,
+                       input: &mut dyn Read,
+                       out: Box<dyn Write+'a>,
+                       ann: &'a dyn PpAnn,
                        is_expanded: bool) -> io::Result<()> {
     let mut s = State::new_from_input(cm, sess, filename, input, out, ann, is_expanded);
 
@@ -121,9 +121,9 @@ impl<'a> State<'a> {
     pub fn new_from_input(cm: &'a CodeMap,
                           sess: &ParseSess,
                           filename: FileName,
-                          input: &mut Read,
-                          out: Box<Write+'a>,
-                          ann: &'a PpAnn,
+                          input: &mut dyn Read,
+                          out: Box<dyn Write+'a>,
+                          ann: &'a dyn PpAnn,
                           is_expanded: bool) -> State<'a> {
         let (cmnts, lits) = comments::gather_comments_and_literals(sess, filename, input);
 
@@ -139,8 +139,8 @@ pub fn new_from_input(cm: &'a CodeMap,
     }
 
     pub fn new(cm: &'a CodeMap,
-               out: Box<Write+'a>,
-               ann: &'a PpAnn,
+               out: Box<dyn Write+'a>,
+               ann: &'a dyn PpAnn,
                comments: Option<Vec<comments::Comment>>,
                literals: Option<Vec<comments::Literal>>) -> State<'a> {
         State {
index 51fbe34028e8f66b8af6cdb48eadef73bf684bde..4d5b0b327dd2e32784fd602c53279ee15bea2b2d 100644 (file)
@@ -72,7 +72,7 @@ struct TestCtxt<'a> {
 // Traverse the crate, collecting all the test functions, eliding any
 // existing main functions, and synthesizing a main test harness
 pub fn modify_for_testing(sess: &ParseSess,
-                          resolver: &mut Resolver,
+                          resolver: &mut dyn Resolver,
                           should_test: bool,
                           krate: ast::Crate,
                           span_diagnostic: &errors::Handler,
@@ -278,7 +278,7 @@ fn mk_reexport_mod(cx: &mut TestCtxt,
 }
 
 fn generate_test_harness(sess: &ParseSess,
-                         resolver: &mut Resolver,
+                         resolver: &mut dyn Resolver,
                          reexport_test_harness_main: Option<Symbol>,
                          krate: ast::Crate,
                          sd: &errors::Handler,
index dd8f79d20abda429638cfc6f2cdce96b7430bdb1..4ebb1fcb65393da183cdf489cd0166cb93aa5017 100644 (file)
@@ -50,7 +50,7 @@ fn next(&self) -> State {
 pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
                        sp: Span,
                        tts: &[tokenstream::TokenTree])
-                       -> Box<base::MacResult + 'cx> {
+                       -> Box<dyn base::MacResult + 'cx> {
     if !cx.ecfg.enable_asm() {
         feature_gate::emit_feature_err(&cx.parse_sess,
                                        "asm",
index fe4d599d8242633a34ffd173f04adcf331ab4214..8d0a04831fcb48c4b5cb5f0da5a166604099ef00 100644 (file)
@@ -22,7 +22,7 @@ pub fn expand_assert<'cx>(
     cx: &'cx mut ExtCtxt,
     sp: Span,
     tts: &[TokenTree],
-) -> Box<MacResult + 'cx> {
+) -> Box<dyn MacResult + 'cx> {
     let mut parser = cx.new_parser_from_tts(tts);
     let cond_expr = panictry!(parser.parse_expr());
     let custom_msg_args = if parser.eat(&token::Comma) {
index 6acc578d07e783040ba0aec680b6b242f4d008c0..2384b6a796e198cc1e0aab1c3c552f7d7f4789ea 100644 (file)
@@ -23,7 +23,7 @@
 pub fn expand_cfg<'cx>(cx: &mut ExtCtxt,
                        sp: Span,
                        tts: &[tokenstream::TokenTree])
-                       -> Box<base::MacResult + 'static> {
+                       -> Box<dyn base::MacResult + 'static> {
     let sp = sp.apply_mark(cx.current_expansion.mark);
     let mut p = cx.new_parser_from_tts(tts);
     let cfg = panictry!(p.parse_meta_item());
index 7bc7afba63cb4d8f43539e851847391d74c84df7..ce7fb400bd547b51b6e08b8195f8654d86020967 100644 (file)
@@ -18,7 +18,7 @@
 pub fn expand_compile_error<'cx>(cx: &'cx mut ExtCtxt,
                               sp: Span,
                               tts: &[tokenstream::TokenTree])
-                              -> Box<base::MacResult + 'cx> {
+                              -> Box<dyn base::MacResult + 'cx> {
     let var = match get_single_str_from_tts(cx, sp, tts, "compile_error!") {
         None => return DummyResult::expr(sp),
         Some(v) => v,
index 6c085528a6632e4ac17091a68399dab6d1c79928..69b4a83764e4624f999864f50f4a23d12b073f6d 100644 (file)
 use syntax::ext::base;
 use syntax::ext::build::AstBuilder;
 use syntax::symbol::Symbol;
-use syntax_pos;
 use syntax::tokenstream;
+use syntax_pos;
 
 use std::string::String;
 
-pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
-                         sp: syntax_pos::Span,
-                         tts: &[tokenstream::TokenTree])
-                         -> Box<base::MacResult + 'static> {
+pub fn expand_syntax_ext(
+    cx: &mut base::ExtCtxt,
+    sp: syntax_pos::Span,
+    tts: &[tokenstream::TokenTree],
+) -> Box<dyn base::MacResult + 'static> {
     let es = match base::get_exprs_from_tts(cx, sp, tts) {
         Some(e) => e,
         None => return base::DummyResult::expr(sp),
@@ -28,32 +29,36 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
     let mut accumulator = String::new();
     for e in es {
         match e.node {
-            ast::ExprKind::Lit(ref lit) => {
-                match lit.node {
-                    ast::LitKind::Str(ref s, _) |
-                    ast::LitKind::Float(ref s, _) |
-                    ast::LitKind::FloatUnsuffixed(ref s) => {
-                        accumulator.push_str(&s.as_str());
-                    }
-                    ast::LitKind::Char(c) => {
-                        accumulator.push(c);
-                    }
-                    ast::LitKind::Int(i, ast::LitIntType::Unsigned(_)) |
-                    ast::LitKind::Int(i, ast::LitIntType::Signed(_)) |
-                    ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) => {
-                        accumulator.push_str(&format!("{}", i));
-                    }
-                    ast::LitKind::Bool(b) => {
-                        accumulator.push_str(&format!("{}", b));
-                    }
-                    ast::LitKind::Byte(..) |
-                    ast::LitKind::ByteStr(..) => {
-                        cx.span_err(e.span, "cannot concatenate a byte string literal");
-                    }
+            ast::ExprKind::Lit(ref lit) => match lit.node {
+                ast::LitKind::Str(ref s, _)
+                | ast::LitKind::Float(ref s, _)
+                | ast::LitKind::FloatUnsuffixed(ref s) => {
+                    accumulator.push_str(&s.as_str());
                 }
-            }
+                ast::LitKind::Char(c) => {
+                    accumulator.push(c);
+                }
+                ast::LitKind::Int(i, ast::LitIntType::Unsigned(_))
+                | ast::LitKind::Int(i, ast::LitIntType::Signed(_))
+                | ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) => {
+                    accumulator.push_str(&format!("{}", i));
+                }
+                ast::LitKind::Bool(b) => {
+                    accumulator.push_str(&format!("{}", b));
+                }
+                ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..) => {
+                    cx.span_err(e.span, "cannot concatenate a byte string literal");
+                }
+            },
             _ => {
-                cx.span_err(e.span, "expected a literal");
+                let mut err = cx.struct_span_err(e.span, "expected a literal");
+                let snippet = cx.codemap().span_to_snippet(e.span).unwrap();
+                err.span_suggestion(
+                    e.span,
+                    "you might be missing a string literal to format with",
+                    format!("\"{{}}\", {}", snippet),
+                );
+                err.emit();
             }
         }
     }
index 828c24708416732e2708a77c8e5284b4fa2be032..a3c5c3df66e4c424e4c2d3709d689d9d21f724f4 100644 (file)
@@ -21,7 +21,7 @@
 pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
                               sp: Span,
                               tts: &[TokenTree])
-                              -> Box<base::MacResult + 'cx> {
+                              -> Box<dyn base::MacResult + 'cx> {
     if !cx.ecfg.enable_concat_idents() {
         feature_gate::emit_feature_err(&cx.parse_sess,
                                        "concat_idents",
index 7f03001d9c6ebf92259aba08c3211a2a95560d7d..41e980b334616ade5931bb301b9880daaa96544c 100644 (file)
@@ -19,7 +19,7 @@ pub fn expand_deriving_unsafe_bound(cx: &mut ExtCtxt,
                                     span: Span,
                                     _: &MetaItem,
                                     _: &Annotatable,
-                                    _: &mut FnMut(Annotatable)) {
+                                    _: &mut dyn FnMut(Annotatable)) {
     cx.span_err(span, "this unsafe trait should be implemented explicitly");
 }
 
@@ -27,7 +27,7 @@ pub fn expand_deriving_copy(cx: &mut ExtCtxt,
                             span: Span,
                             mitem: &MetaItem,
                             item: &Annotatable,
-                            push: &mut FnMut(Annotatable)) {
+                            push: &mut dyn FnMut(Annotatable)) {
     let trait_def = TraitDef {
         span,
         attributes: Vec::new(),
index 9aeac5b1ddb2ae9937cb952897cde1b90e4cda49..ec935b3e72f230955fc8884210c09e8d7c6d200d 100644 (file)
@@ -25,7 +25,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
                              span: Span,
                              mitem: &MetaItem,
                              item: &Annotatable,
-                             push: &mut FnMut(Annotatable)) {
+                             push: &mut dyn FnMut(Annotatable)) {
     // check if we can use a short form
     //
     // the short form is `fn clone(&self) -> Self { *self }`
index 00ab39032acbd2489dbdc6273ca1812d1a8f9259..f202bc4e524d2204ca854861d8a499e85a8766b0 100644 (file)
@@ -23,7 +23,7 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt,
                           span: Span,
                           mitem: &MetaItem,
                           item: &Annotatable,
-                          push: &mut FnMut(Annotatable)) {
+                          push: &mut dyn FnMut(Annotatable)) {
     let inline = cx.meta_word(span, Symbol::intern("inline"));
     let hidden = cx.meta_list_item_word(span, Symbol::intern("hidden"));
     let doc = cx.meta_list(span, Symbol::intern("doc"), vec![hidden]);
index 99b6f752e9406a48c91e12f1ef8a806897cb9d71..117bedf453e6c33b17cdcc11b56d686915fd599b 100644 (file)
@@ -23,7 +23,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
                            span: Span,
                            mitem: &MetaItem,
                            item: &Annotatable,
-                           push: &mut FnMut(Annotatable)) {
+                           push: &mut dyn FnMut(Annotatable)) {
     let inline = cx.meta_word(span, Symbol::intern("inline"));
     let attrs = vec![cx.attribute(span, inline)];
     let trait_def = TraitDef {
index c259733d81abdc8e8e288b3f7a91c940672b40d5..24a3a7542fb669507be2dc3044d056c172269d68 100644 (file)
@@ -23,7 +23,7 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt,
                                   span: Span,
                                   mitem: &MetaItem,
                                   item: &Annotatable,
-                                  push: &mut FnMut(Annotatable)) {
+                                  push: &mut dyn FnMut(Annotatable)) {
     // structures are equal if all fields are equal, and non equal, if
     // any fields are not equal or if the enum variants are different
     fn cs_op(cx: &mut ExtCtxt,
index 2b3930063f369028e9c23122ff398e1885d61c0a..3705a245584d02f1127599ab2de717e103bd38e0 100644 (file)
@@ -25,7 +25,7 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt,
                                    span: Span,
                                    mitem: &MetaItem,
                                    item: &Annotatable,
-                                   push: &mut FnMut(Annotatable)) {
+                                   push: &mut dyn FnMut(Annotatable)) {
     macro_rules! md {
         ($name:expr, $op:expr, $equal:expr) => { {
             let inline = cx.meta_word(span, Symbol::intern("inline"));
index b546f5df15799467ad2daf2f8dd9408c4692a9e1..c2a7dea331673f835394c07edf53b026f82e52ba 100644 (file)
@@ -23,7 +23,7 @@ pub fn expand_deriving_debug(cx: &mut ExtCtxt,
                              span: Span,
                              mitem: &MetaItem,
                              item: &Annotatable,
-                             push: &mut FnMut(Annotatable)) {
+                             push: &mut dyn FnMut(Annotatable)) {
     // &mut ::std::fmt::Formatter
     let fmtr = Ptr(Box::new(Literal(path_std!(cx, fmt::Formatter))),
                    Borrowed(None, ast::Mutability::Mutable));
index 7618fe63ab3354461b499c423792defbe1f3a93b..1e04d8fa22a673e522c6b9f80ee1067572c65bb3 100644 (file)
@@ -27,7 +27,7 @@ pub fn expand_deriving_rustc_decodable(cx: &mut ExtCtxt,
                                        span: Span,
                                        mitem: &MetaItem,
                                        item: &Annotatable,
-                                       push: &mut FnMut(Annotatable)) {
+                                       push: &mut dyn FnMut(Annotatable)) {
     expand_deriving_decodable_imp(cx, span, mitem, item, push, "rustc_serialize")
 }
 
@@ -35,7 +35,7 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
                                  span: Span,
                                  mitem: &MetaItem,
                                  item: &Annotatable,
-                                 push: &mut FnMut(Annotatable)) {
+                                 push: &mut dyn FnMut(Annotatable)) {
     warn_if_deprecated(cx, span, "Decodable");
     expand_deriving_decodable_imp(cx, span, mitem, item, push, "serialize")
 }
@@ -44,7 +44,7 @@ fn expand_deriving_decodable_imp(cx: &mut ExtCtxt,
                                  span: Span,
                                  mitem: &MetaItem,
                                  item: &Annotatable,
-                                 push: &mut FnMut(Annotatable),
+                                 push: &mut dyn FnMut(Annotatable),
                                  krate: &'static str) {
     let typaram = &*deriving::hygienic_type_parameter(item, "__D");
 
index cbd6a257b77e8ae2ae23951d0915495547c09624..958116f7809bbb3d078455fbc80be8f863763795 100644 (file)
@@ -23,7 +23,7 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt,
                                span: Span,
                                mitem: &MetaItem,
                                item: &Annotatable,
-                               push: &mut FnMut(Annotatable)) {
+                               push: &mut dyn FnMut(Annotatable)) {
     let inline = cx.meta_word(span, Symbol::intern("inline"));
     let attrs = vec![cx.attribute(span, inline)];
     let trait_def = TraitDef {
index 8b409df1f09964616c0c941db37cf1b04d1110ea..5438c8b52af05e283bd9038549ef159aa58cc7ce 100644 (file)
@@ -108,7 +108,7 @@ pub fn expand_deriving_rustc_encodable(cx: &mut ExtCtxt,
                                        span: Span,
                                        mitem: &MetaItem,
                                        item: &Annotatable,
-                                       push: &mut FnMut(Annotatable)) {
+                                       push: &mut dyn FnMut(Annotatable)) {
     expand_deriving_encodable_imp(cx, span, mitem, item, push, "rustc_serialize")
 }
 
@@ -116,7 +116,7 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
                                  span: Span,
                                  mitem: &MetaItem,
                                  item: &Annotatable,
-                                 push: &mut FnMut(Annotatable)) {
+                                 push: &mut dyn FnMut(Annotatable)) {
     warn_if_deprecated(cx, span, "Encodable");
     expand_deriving_encodable_imp(cx, span, mitem, item, push, "serialize")
 }
@@ -125,7 +125,7 @@ fn expand_deriving_encodable_imp(cx: &mut ExtCtxt,
                                  span: Span,
                                  mitem: &MetaItem,
                                  item: &Annotatable,
-                                 push: &mut FnMut(Annotatable),
+                                 push: &mut dyn FnMut(Annotatable),
                                  krate: &'static str) {
     let typaram = &*deriving::hygienic_type_parameter(item, "__S");
 
index 3ea0eb8bbd842e63155a3c1369b9116a540892fa..aad69c109f9795f75bee0ffa5776f90947a34068 100644 (file)
@@ -330,7 +330,7 @@ pub enum SubstructureFields<'a> {
 /// Combine the values of all the fields together. The last argument is
 /// all the fields of all the structures.
 pub type CombineSubstructureFunc<'a> =
-    Box<FnMut(&mut ExtCtxt, Span, &Substructure) -> P<Expr> + 'a>;
+    Box<dyn FnMut(&mut ExtCtxt, Span, &Substructure) -> P<Expr> + 'a>;
 
 /// Deal with non-matching enum variants.  The tuple is a list of
 /// identifiers (one for each `Self` argument, which could be any of the
@@ -338,7 +338,7 @@ pub enum SubstructureFields<'a> {
 /// holding the variant index value for each of the `Self` arguments.  The
 /// last argument is all the non-`Self` args of the method being derived.
 pub type EnumNonMatchCollapsedFunc<'a> =
-    Box<FnMut(&mut ExtCtxt, Span, (&[Ident], &[Ident]), &[P<Expr>]) -> P<Expr> + 'a>;
+    Box<dyn FnMut(&mut ExtCtxt, Span, (&[Ident], &[Ident]), &[P<Expr>]) -> P<Expr> + 'a>;
 
 pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
                                 -> RefCell<CombineSubstructureFunc<'a>> {
@@ -398,7 +398,7 @@ pub fn expand(self,
                   cx: &mut ExtCtxt,
                   mitem: &ast::MetaItem,
                   item: &'a Annotatable,
-                  push: &mut FnMut(Annotatable)) {
+                  push: &mut dyn FnMut(Annotatable)) {
         self.expand_ext(cx, mitem, item, push, false);
     }
 
@@ -406,7 +406,7 @@ pub fn expand_ext(self,
                       cx: &mut ExtCtxt,
                       mitem: &ast::MetaItem,
                       item: &'a Annotatable,
-                      push: &mut FnMut(Annotatable),
+                      push: &mut dyn FnMut(Annotatable),
                       from_scratch: bool) {
         match *item {
             Annotatable::Item(ref item) => {
index 67096cdb49a3c5da2d589f47c4978b8a12a9cc3d..7d22998487ba7598010c5996c677e03150b02a93 100644 (file)
@@ -22,7 +22,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
                             span: Span,
                             mitem: &MetaItem,
                             item: &Annotatable,
-                            push: &mut FnMut(Annotatable)) {
+                            push: &mut dyn FnMut(Annotatable)) {
 
     let path = Path::new_(pathvec_std!(cx, hash::Hash), None, vec![], PathKind::Std);
 
index e6a1434ca9d10ca540432f668a1008ed6be7da3f..2f5e42d2f7b17f6d70be355adea003a2c34f953d 100644 (file)
@@ -72,7 +72,7 @@ pub fn is_builtin_trait(name: ast::Name) -> bool {
             }
         }
 
-        pub fn register_builtin_derives(resolver: &mut Resolver) {
+        pub fn register_builtin_derives(resolver: &mut dyn Resolver) {
             $(
                 resolver.add_builtin(
                     ast::Ident::with_empty_ctxt(Symbol::intern($name)),
index bbc5b03d6885eaa3f1a69cf2119b7d12f3550827..3c34bf496da594a460022f81773d3291755299fe 100644 (file)
@@ -26,7 +26,7 @@
 pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt,
                               sp: Span,
                               tts: &[tokenstream::TokenTree])
-                              -> Box<base::MacResult + 'cx> {
+                              -> Box<dyn base::MacResult + 'cx> {
     let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") {
         None => return DummyResult::expr(sp),
         Some(v) => v,
@@ -57,7 +57,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt,
 pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt,
                        sp: Span,
                        tts: &[tokenstream::TokenTree])
-                       -> Box<base::MacResult + 'cx> {
+                       -> Box<dyn base::MacResult + 'cx> {
     let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
         Some(ref exprs) if exprs.is_empty() => {
             cx.span_err(sp, "env! takes 1 or 2 arguments");
index 4bf764b1101fa6f1ffae26c15a65f5aaff2a31c7..8587d11b2278650fe2547e3e6a3ebd0076421821 100644 (file)
@@ -679,7 +679,7 @@ fn format_arg(ecx: &ExtCtxt,
 pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt,
                                mut sp: Span,
                                tts: &[tokenstream::TokenTree])
-                               -> Box<base::MacResult + 'cx> {
+                               -> Box<dyn base::MacResult + 'cx> {
     sp = sp.apply_mark(ecx.current_expansion.mark);
     match parse_args(ecx, sp, tts) {
         Some((efmt, args, names)) => {
index 642aa0e5b125da1ea99803eb361f3e516266ab8e..40ecd6e1519c3f91584731673a5205ba43aea758 100644 (file)
@@ -34,7 +34,7 @@
 
 pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt,
                               sp: Span,
-                              tts: &[tokenstream::TokenTree]) -> Box<base::MacResult + 'cx> {
+                              tts: &[tokenstream::TokenTree]) -> Box<dyn base::MacResult + 'cx> {
     if !cx.ecfg.enable_global_asm() {
         feature_gate::emit_feature_err(&cx.parse_sess,
                                        MACRO,
index 311251832664e960e25285aee14d6c6bb80c3233..bdf7a8d704042bd92c4e39f1489fa38cde56bc19 100644 (file)
@@ -10,6 +10,8 @@
 
 //! Syntax extensions in the Rust compiler.
 
+#![deny(bare_trait_objects)]
+
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
@@ -59,7 +61,7 @@
 use syntax::ext::hygiene;
 use syntax::symbol::Symbol;
 
-pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver,
+pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
                          user_exts: Vec<NamedSyntaxExtension>,
                          enable_quotes: bool) {
     deriving::register_builtin_derives(resolver);
index 71f1951d5d455c168d7c9d23d784d8ed8a19691b..7b76b1e8914684a292bc0947dad5a796eff6cbf0 100644 (file)
@@ -17,7 +17,7 @@
 pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt,
                               sp: syntax_pos::Span,
                               tts: &[tokenstream::TokenTree])
-                              -> Box<base::MacResult + 'cx> {
+                              -> Box<dyn base::MacResult + 'cx> {
     if !cx.ecfg.enable_log_syntax() {
         feature_gate::emit_feature_err(&cx.parse_sess,
                                        "log_syntax",
index ef29e5a6b022b624498854b93e13b4d81be48a22..85aa84acc4221f71279c51be50294cad20257a33 100644 (file)
@@ -55,7 +55,7 @@ struct CollectProcMacros<'a> {
 }
 
 pub fn modify(sess: &ParseSess,
-              resolver: &mut ::syntax::ext::base::Resolver,
+              resolver: &mut dyn (::syntax::ext::base::Resolver),
               mut krate: ast::Crate,
               is_proc_macro_crate: bool,
               is_test_crate: bool,
@@ -200,8 +200,8 @@ fn collect_custom_derive(&mut self, item: &'a ast::Item, attr: &'a ast::Attribut
     }
 
     fn collect_attr_proc_macro(&mut self, item: &'a ast::Item, attr: &'a ast::Attribute) {
-        if let Some(_) = attr.meta_item_list() {
-            self.handler.span_err(attr.span, "`#[proc_macro_attribute]` attribute
+        if !attr.is_word() {
+            self.handler.span_err(attr.span, "`#[proc_macro_attribute]` attribute \
                 does not take any arguments");
             return;
         }
@@ -223,8 +223,8 @@ fn collect_attr_proc_macro(&mut self, item: &'a ast::Item, attr: &'a ast::Attrib
     }
 
     fn collect_bang_proc_macro(&mut self, item: &'a ast::Item, attr: &'a ast::Attribute) {
-        if let Some(_) = attr.meta_item_list() {
-            self.handler.span_err(attr.span, "`#[proc_macro]` attribute
+        if !attr.is_word() {
+            self.handler.span_err(attr.span, "`#[proc_macro]` attribute \
                 does not take any arguments");
             return;
         }
index 48be8e0c53c2ed2c41363da6e7c843efb8053135..256b525b8bea636f40dc98b745c147c8bc10db5d 100644 (file)
@@ -18,7 +18,7 @@
 pub fn expand_trace_macros(cx: &mut ExtCtxt,
                            sp: Span,
                            tt: &[TokenTree])
-                           -> Box<base::MacResult + 'static> {
+                           -> Box<dyn base::MacResult + 'static> {
     if !cx.ecfg.enable_trace_macros() {
         feature_gate::emit_feature_err(&cx.parse_sess,
                                        "trace_macros",
index 33d02d0b10a7bd5283558892069b7d78f65cb1cf..c7076478332f4c01b1fb7c3ca22ef089576a0c99 100644 (file)
 
 /// A SyntaxContext represents a chain of macro expansions (represented by marks).
 #[derive(Clone, Copy, PartialEq, Eq, Default, PartialOrd, Ord, Hash)]
-pub struct SyntaxContext(pub(super) u32);
+pub struct SyntaxContext(u32);
 
 #[derive(Copy, Clone, Debug)]
-pub struct SyntaxContextData {
-    pub outer_mark: Mark,
-    pub prev_ctxt: SyntaxContext,
+struct SyntaxContextData {
+    outer_mark: Mark,
+    transparency: Transparency,
+    prev_ctxt: SyntaxContext,
     // This context, but with all transparent and semi-transparent marks filtered away.
-    pub opaque: SyntaxContext,
+    opaque: SyntaxContext,
     // This context, but with all transparent marks filtered away.
-    pub opaque_and_semitransparent: SyntaxContext,
+    opaque_and_semitransparent: SyntaxContext,
 }
 
 /// A mark is a unique id associated with a macro expansion.
@@ -46,14 +47,14 @@ pub struct SyntaxContextData {
 #[derive(Clone, Debug)]
 struct MarkData {
     parent: Mark,
-    transparency: Transparency,
+    default_transparency: Transparency,
     is_builtin: bool,
     expn_info: Option<ExpnInfo>,
 }
 
 /// A property of a macro expansion that determines how identifiers
 /// produced by that expansion are resolved.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Hash, Debug)]
 pub enum Transparency {
     /// Identifier produced by a transparent expansion is always resolved at call-site.
     /// Call-site spans in procedural macros, hygiene opt-out in `macro` should use this.
@@ -71,26 +72,16 @@ pub enum Transparency {
 }
 
 impl Mark {
-    fn fresh_with_data(mark_data: MarkData, data: &mut HygieneData) -> Self {
-        data.marks.push(mark_data);
-        Mark(data.marks.len() as u32 - 1)
-    }
-
     pub fn fresh(parent: Mark) -> Self {
         HygieneData::with(|data| {
-            Mark::fresh_with_data(MarkData {
+            data.marks.push(MarkData {
                 parent,
                 // By default expansions behave like `macro_rules`.
-                transparency: Transparency::SemiTransparent,
+                default_transparency: Transparency::SemiTransparent,
                 is_builtin: false,
                 expn_info: None,
-            }, data)
-        })
-    }
-
-    pub fn fresh_cloned(clone_from: Mark) -> Self {
-        HygieneData::with(|data| {
-            Mark::fresh_with_data(data.marks[clone_from.0 as usize].clone(), data)
+            });
+            Mark(data.marks.len() as u32 - 1)
         })
     }
 
@@ -127,34 +118,21 @@ pub fn set_expn_info(self, info: ExpnInfo) {
         })
     }
 
-    pub fn modern(mut self) -> Mark {
-        HygieneData::with(|data| {
-            while data.marks[self.0 as usize].transparency != Transparency::Opaque {
-                self = data.marks[self.0 as usize].parent;
-            }
-            self
-        })
-    }
-
-    #[inline]
-    pub fn transparency(self) -> Transparency {
-        assert_ne!(self, Mark::root());
-        HygieneData::with(|data| data.marks[self.0 as usize].transparency)
-    }
-
     #[inline]
-    pub fn set_transparency(self, transparency: Transparency) {
+    pub fn set_default_transparency(self, transparency: Transparency) {
         assert_ne!(self, Mark::root());
-        HygieneData::with(|data| data.marks[self.0 as usize].transparency = transparency)
+        HygieneData::with(|data| data.marks[self.0 as usize].default_transparency = transparency)
     }
 
     #[inline]
     pub fn is_builtin(self) -> bool {
+        assert_ne!(self, Mark::root());
         HygieneData::with(|data| data.marks[self.0 as usize].is_builtin)
     }
 
     #[inline]
     pub fn set_is_builtin(self, is_builtin: bool) {
+        assert_ne!(self, Mark::root());
         HygieneData::with(|data| data.marks[self.0 as usize].is_builtin = is_builtin)
     }
 
@@ -195,29 +173,48 @@ pub fn least_ancestor(mut a: Mark, mut b: Mark) -> Mark {
             b
         })
     }
+
+    // Used for enabling some compatibility fallback in resolve.
+    #[inline]
+    pub fn looks_like_proc_macro_derive(self) -> bool {
+        HygieneData::with(|data| {
+            let mark_data = &data.marks[self.0 as usize];
+            if mark_data.default_transparency == Transparency::Opaque {
+                if let Some(expn_info) = &mark_data.expn_info {
+                    if let ExpnFormat::MacroAttribute(name) = expn_info.format {
+                        if name.as_str().starts_with("derive(") {
+                            return true;
+                        }
+                    }
+                }
+            }
+            false
+        })
+    }
 }
 
 #[derive(Debug)]
-pub struct HygieneData {
+crate struct HygieneData {
     marks: Vec<MarkData>,
     syntax_contexts: Vec<SyntaxContextData>,
-    markings: HashMap<(SyntaxContext, Mark), SyntaxContext>,
+    markings: HashMap<(SyntaxContext, Mark, Transparency), SyntaxContext>,
     default_edition: Edition,
 }
 
 impl HygieneData {
-    pub fn new() -> Self {
+    crate fn new() -> Self {
         HygieneData {
             marks: vec![MarkData {
                 parent: Mark::root(),
                 // If the root is opaque, then loops searching for an opaque mark
                 // will automatically stop after reaching it.
-                transparency: Transparency::Opaque,
+                default_transparency: Transparency::Opaque,
                 is_builtin: true,
                 expn_info: None,
             }],
             syntax_contexts: vec![SyntaxContextData {
                 outer_mark: Mark::root(),
+                transparency: Transparency::Opaque,
                 prev_ctxt: SyntaxContext(0),
                 opaque: SyntaxContext(0),
                 opaque_and_semitransparent: SyntaxContext(0),
@@ -249,6 +246,14 @@ pub const fn empty() -> Self {
         SyntaxContext(0)
     }
 
+    crate fn as_u32(self) -> u32 {
+        self.0
+    }
+
+    crate fn from_u32(raw: u32) -> SyntaxContext {
+        SyntaxContext(raw)
+    }
+
     // Allocate a new SyntaxContext with the given ExpnInfo. This is used when
     // deserializing Spans from the incr. comp. cache.
     // FIXME(mw): This method does not restore MarkData::parent or
@@ -259,7 +264,7 @@ pub fn allocate_directly(expansion_info: ExpnInfo) -> Self {
         HygieneData::with(|data| {
             data.marks.push(MarkData {
                 parent: Mark::root(),
-                transparency: Transparency::SemiTransparent,
+                default_transparency: Transparency::SemiTransparent,
                 is_builtin: false,
                 expn_info: Some(expansion_info),
             });
@@ -268,6 +273,7 @@ pub fn allocate_directly(expansion_info: ExpnInfo) -> Self {
 
             data.syntax_contexts.push(SyntaxContextData {
                 outer_mark: mark,
+                transparency: Transparency::SemiTransparent,
                 prev_ctxt: SyntaxContext::empty(),
                 opaque: SyntaxContext::empty(),
                 opaque_and_semitransparent: SyntaxContext::empty(),
@@ -276,22 +282,32 @@ pub fn allocate_directly(expansion_info: ExpnInfo) -> Self {
         })
     }
 
-    /// Extend a syntax context with a given mark
+    /// Extend a syntax context with a given mark and default transparency for that mark.
     pub fn apply_mark(self, mark: Mark) -> SyntaxContext {
-        if mark.transparency() == Transparency::Opaque {
-            return self.apply_mark_internal(mark);
+        assert_ne!(mark, Mark::root());
+        self.apply_mark_with_transparency(
+            mark, HygieneData::with(|data| data.marks[mark.0 as usize].default_transparency)
+        )
+    }
+
+    /// Extend a syntax context with a given mark and transparency
+    pub fn apply_mark_with_transparency(self, mark: Mark, transparency: Transparency)
+                                        -> SyntaxContext {
+        assert_ne!(mark, Mark::root());
+        if transparency == Transparency::Opaque {
+            return self.apply_mark_internal(mark, transparency);
         }
 
         let call_site_ctxt =
             mark.expn_info().map_or(SyntaxContext::empty(), |info| info.call_site.ctxt());
-        let call_site_ctxt = if mark.transparency() == Transparency::SemiTransparent {
+        let call_site_ctxt = if transparency == Transparency::SemiTransparent {
             call_site_ctxt.modern()
         } else {
             call_site_ctxt.modern_and_legacy()
         };
 
         if call_site_ctxt == SyntaxContext::empty() {
-            return self.apply_mark_internal(mark);
+            return self.apply_mark_internal(mark, transparency);
         }
 
         // Otherwise, `mark` is a macros 1.0 definition and the call site is in a
@@ -304,27 +320,26 @@ pub fn apply_mark(self, mark: Mark) -> SyntaxContext {
         //
         // See the example at `test/run-pass/hygiene/legacy_interaction.rs`.
         let mut ctxt = call_site_ctxt;
-        for mark in self.marks() {
-            ctxt = ctxt.apply_mark_internal(mark);
+        for (mark, transparency) in self.marks() {
+            ctxt = ctxt.apply_mark_internal(mark, transparency);
         }
-        ctxt.apply_mark_internal(mark)
+        ctxt.apply_mark_internal(mark, transparency)
     }
 
-    fn apply_mark_internal(self, mark: Mark) -> SyntaxContext {
+    fn apply_mark_internal(self, mark: Mark, transparency: Transparency) -> SyntaxContext {
         HygieneData::with(|data| {
             let syntax_contexts = &mut data.syntax_contexts;
-            let transparency = data.marks[mark.0 as usize].transparency;
-
             let mut opaque = syntax_contexts[self.0 as usize].opaque;
             let mut opaque_and_semitransparent =
                 syntax_contexts[self.0 as usize].opaque_and_semitransparent;
 
             if transparency >= Transparency::Opaque {
                 let prev_ctxt = opaque;
-                opaque = *data.markings.entry((prev_ctxt, mark)).or_insert_with(|| {
+                opaque = *data.markings.entry((prev_ctxt, mark, transparency)).or_insert_with(|| {
                     let new_opaque = SyntaxContext(syntax_contexts.len() as u32);
                     syntax_contexts.push(SyntaxContextData {
                         outer_mark: mark,
+                        transparency,
                         prev_ctxt,
                         opaque: new_opaque,
                         opaque_and_semitransparent: new_opaque,
@@ -336,11 +351,12 @@ fn apply_mark_internal(self, mark: Mark) -> SyntaxContext {
             if transparency >= Transparency::SemiTransparent {
                 let prev_ctxt = opaque_and_semitransparent;
                 opaque_and_semitransparent =
-                        *data.markings.entry((prev_ctxt, mark)).or_insert_with(|| {
+                        *data.markings.entry((prev_ctxt, mark, transparency)).or_insert_with(|| {
                     let new_opaque_and_semitransparent =
                         SyntaxContext(syntax_contexts.len() as u32);
                     syntax_contexts.push(SyntaxContextData {
                         outer_mark: mark,
+                        transparency,
                         prev_ctxt,
                         opaque,
                         opaque_and_semitransparent: new_opaque_and_semitransparent,
@@ -350,11 +366,12 @@ fn apply_mark_internal(self, mark: Mark) -> SyntaxContext {
             }
 
             let prev_ctxt = self;
-            *data.markings.entry((prev_ctxt, mark)).or_insert_with(|| {
+            *data.markings.entry((prev_ctxt, mark, transparency)).or_insert_with(|| {
                 let new_opaque_and_semitransparent_and_transparent =
                     SyntaxContext(syntax_contexts.len() as u32);
                 syntax_contexts.push(SyntaxContextData {
                     outer_mark: mark,
+                    transparency,
                     prev_ctxt,
                     opaque,
                     opaque_and_semitransparent,
@@ -388,12 +405,13 @@ pub fn remove_mark(&mut self) -> Mark {
         })
     }
 
-    pub fn marks(mut self) -> Vec<Mark> {
+    pub fn marks(mut self) -> Vec<(Mark, Transparency)> {
         HygieneData::with(|data| {
             let mut marks = Vec::new();
             while self != SyntaxContext::empty() {
-                marks.push(data.syntax_contexts[self.0 as usize].outer_mark);
-                self = data.syntax_contexts[self.0 as usize].prev_ctxt;
+                let ctxt_data = &data.syntax_contexts[self.0 as usize];
+                marks.push((ctxt_data.outer_mark, ctxt_data.transparency));
+                self = ctxt_data.prev_ctxt;
             }
             marks.reverse();
             marks
index 491ce720f36c5f0eacd0408dd07a6c99f5e1a65e..61af70af47d85a42287a303669ffbcdf77977156 100644 (file)
       html_root_url = "https://doc.rust-lang.org/nightly/")]
 
 #![feature(const_fn)]
+#![feature(crate_visibility_modifier)]
 #![feature(custom_attribute)]
 #![feature(non_exhaustive)]
 #![feature(optin_builtin_traits)]
-#![allow(unused_attributes)]
 #![feature(specialization)]
 #![feature(stdsimd)]
 
index 601a0273ae91178efa1b52a9c58321a1ea397d7c..473aa1bd1b8a471e2e1c6de98169c8cc9965818d 100644 (file)
@@ -100,7 +100,7 @@ pub fn data(self) -> SpanData {
 
 #[inline]
 fn encode(sd: &SpanData) -> Span {
-    let (base, len, ctxt) = (sd.lo.0, sd.hi.0 - sd.lo.0, sd.ctxt.0);
+    let (base, len, ctxt) = (sd.lo.0, sd.hi.0 - sd.lo.0, sd.ctxt.as_u32());
 
     let val = if (base >> INLINE_SIZES[BASE_INDEX]) == 0 &&
                  (len >> INLINE_SIZES[LEN_INDEX]) == 0 &&
@@ -132,7 +132,7 @@ fn decode(span: Span) -> SpanData {
         let index = extract(INTERNED_INDEX_OFFSET, INTERNED_INDEX_SIZE);
         return with_span_interner(|interner| *interner.get(index));
     };
-    SpanData { lo: BytePos(base), hi: BytePos(base + len), ctxt: SyntaxContext(ctxt) }
+    SpanData { lo: BytePos(base), hi: BytePos(base + len), ctxt: SyntaxContext::from_u32(ctxt) }
 }
 
 #[derive(Default)]
index 1c817c7a0c828b8fc8e8e462afbe5db41c7052d1..03684905101f0b7e49dfe530e54dc1aeac6ef0fb 160000 (submodule)
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit 1c817c7a0c828b8fc8e8e462afbe5db41c7052d1
+Subproject commit 03684905101f0b7e49dfe530e54dc1aeac6ef0fb
index d5410feb254a033549da30663caf91b8eea51c9d..a00ff3b345d116e4c0127fde7c4d3f07f15ea6ab 100644 (file)
@@ -545,7 +545,11 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
     return LLVMRustResult::Failure;
   }
 
+#if LLVM_VERSION_GE(7, 0)
+  unwrap(Target)->addPassesToEmitFile(*PM, OS, nullptr, FileType, false);
+#else
   unwrap(Target)->addPassesToEmitFile(*PM, OS, FileType, false);
+#endif
   PM->run(*unwrap(M));
 
   // Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
index df8602d0803a459d848040a2f3e2d299391e33a9..d82410618d04ba6253744b67ee7a0cd54af59ec3 100644 (file)
@@ -492,13 +492,8 @@ inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
   return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
 }
 
-#if LLVM_VERSION_GE(4, 0)
 static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
   DINode::DIFlags Result = DINode::DIFlags::FlagZero;
-#else
-static unsigned fromRust(LLVMRustDIFlags Flags) {
-  unsigned Result = 0;
-#endif
 
   switch (visibility(Flags)) {
   case LLVMRustDIFlags::FlagPrivate:
@@ -565,14 +560,12 @@ static unsigned fromRust(LLVMRustDIFlags Flags) {
   if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
     Result |= DINode::DIFlags::FlagBitField;
   }
-#if LLVM_RUSTLLVM || LLVM_VERSION_GE(4, 0)
   if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
     Result |= DINode::DIFlags::FlagNoReturn;
   }
   if (isSet(Flags & LLVMRustDIFlags::FlagMainSubprogram)) {
     Result |= DINode::DIFlags::FlagMainSubprogram;
   }
-#endif
 
   return Result;
 }
@@ -612,14 +605,8 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
     unsigned RuntimeVer, const char *SplitName) {
   auto *File = unwrapDI<DIFile>(FileRef);
 
-#if LLVM_VERSION_GE(4, 0)
   return wrap(Builder->createCompileUnit(Lang, File, Producer, isOptimized,
                                          Flags, RuntimeVer, SplitName));
-#else
-  return wrap(Builder->createCompileUnit(Lang, File->getFilename(),
-      File->getDirectory(), Producer, isOptimized,
-      Flags, RuntimeVer, SplitName));
-#endif
 }
 
 extern "C" LLVMMetadataRef
@@ -657,11 +644,7 @@ extern "C" LLVMMetadataRef
 LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder, const char *Name,
                                  uint64_t SizeInBits, uint32_t AlignInBits,
                                  unsigned Encoding) {
-  return wrap(Builder->createBasicType(Name, SizeInBits,
-#if LLVM_VERSION_LE(3, 9)
-                                       AlignInBits,
-#endif
-                                       Encoding));
+  return wrap(Builder->createBasicType(Name, SizeInBits, Encoding));
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
@@ -722,7 +705,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
     LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
   llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
 
-#if LLVM_VERSION_GE(4, 0)
   llvm::DIExpression *InitExpr = nullptr;
   if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
     InitExpr = Builder->createConstantValueExpression(
@@ -741,12 +723,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
   InitVal->setMetadata("dbg", VarExpr);
 
   return wrap(VarExpr);
-#else
-  return wrap(Builder->createGlobalVariable(
-      unwrapDI<DIDescriptor>(Context), Name, LinkageName,
-      unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
-      InitVal, unwrapDIPtr<MDNode>(Decl)));
-#endif
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
@@ -757,12 +733,7 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
   if (Tag == 0x100) { // DW_TAG_auto_variable
     return wrap(Builder->createAutoVariable(
         unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNo,
-        unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)
-#if LLVM_VERSION_GE(4, 0)
-        ,
-  AlignInBits
-#endif
-        ));
+        unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
   } else {
     return wrap(Builder->createParameterVariable(
         unwrapDI<DIDescriptor>(Scope), Name, ArgNo, unwrapDI<DIFile>(File),
index f4bd78147f6316ed0d0e4c6330c68b68291a5642..1070068b99845f86c72e6cc839a4e0d90f2da995 100644 (file)
@@ -22,8 +22,6 @@
 #include "llvm/ExecutionEngine/MCJIT.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/InlineAsm.h"
-#include "llvm/IR/InlineAsm.h"
-#include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/CommandLine.h"
index f306608f4328eca67009df4d9ed38b54bcae8bd7..bf119da2e829fc32bfe1545378e4a92a42cf2158 100644 (file)
@@ -10,6 +10,7 @@
 
 // compile-flags: -C no-prepopulate-passes
 // ignore-tidy-linelength
+// min-llvm-version 7.0
 
 #![crate_type = "lib"]
 
@@ -42,7 +43,7 @@ pub enum Enum64 {
 #[no_mangle]
 pub fn align64(i : i32) -> Align64 {
 // CHECK: %a64 = alloca %Align64, align 64
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 64, i32 64, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 64 %{{.*}}, i8* align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false)
     let a64 = Align64(i);
     a64
 }
index 20d42ed852dfed745d79c177eb629e07d49e5649..1b92ff60226aa8a7f6c52a341a161befe5980e50 100644 (file)
@@ -12,8 +12,6 @@
 // scalar value.
 
 // compile-flags: -C no-prepopulate-passes
-// min-llvm-version 4.0
-
 
 #![crate_type = "lib"]
 
index 007fb7f4596621c74a76a83f24a19d7757548515..30fffbb769b30dc2aa0484021446a1f4891cb585 100644 (file)
@@ -10,6 +10,7 @@
 
 // compile-flags: -C no-prepopulate-passes
 // ignore-tidy-linelength
+// min-llvm-version 7.0
 
 #![crate_type = "lib"]
 
@@ -54,7 +55,7 @@ pub fn inline_enum_const() -> E<i8, i16> {
 #[no_mangle]
 pub fn low_align_const() -> E<i16, [i16; 3]> {
 // Check that low_align_const and high_align_const use the same constant
-// CHECK: i8* getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* [[LOW_HIGH]], i32 0, i32 0, i32 0),
+// CHECK: i8* align 2 getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* [[LOW_HIGH]], i32 0, i32 0, i32 0),
     *&E::A(0)
 }
 
@@ -62,6 +63,6 @@ pub fn inline_enum_const() -> E<i8, i16> {
 #[no_mangle]
 pub fn high_align_const() -> E<i16, i32> {
 // Check that low_align_const and high_align_const use the same constant
-// CHECK: i8* getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* [[LOW_HIGH]], i32 0, i32 0, i32 0),
+// CHECK: i8* align 4 getelementptr inbounds (<{ [8 x i8] }>, <{ [8 x i8] }>* [[LOW_HIGH]], i32 0, i32 0, i32 0),
     *&E::A(0)
 }
index e3fa7a7db39a254bd2736fdd8ced347ad4a0157c..c027dece01414255ea136847fe7d82c519f6268d 100644 (file)
@@ -149,7 +149,7 @@ pub fn enum_id_1(x: Option<Result<u16, u16>>) -> Option<Result<u16, u16>> {
   x
 }
 
-// CHECK: i16 @enum_id_2(i16)
+// CHECK: { i8, i8 } @enum_id_2(i1 zeroext %x.0, i8 %x.1)
 #[no_mangle]
 pub fn enum_id_2(x: Option<u8>) -> Option<u8> {
   x
index df02426badcc5dde1e2055779a8f0396afde4460..a36a50415ada55f8e3532beeb9de6baf3c5a0951 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// min-llvm-version 4.0
 // compile-flags: -O
 // ignore-x86
 // ignore-arm
index 3702b6753898e125143ea03c36581ed8cdcadec7..149547639440cf39187535a6d168bae4bad3f70b 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// min-llvm-version 4.0
 // compile-flags: -O
+// min-llvm-version 6.0
 
 #![crate_type="rlib"]
 
index f0508bc90f20c9941b537b8fc4549d82f3ec4342..2cfc20e30ca5c79da9f8b2d3fe916847a2ebdefc 100644 (file)
@@ -14,7 +14,6 @@
 // ignore-tidy-linelength
 // ignore-windows
 // ignore-macos
-// min-llvm-version 4.0
 
 // compile-flags: -g -C no-prepopulate-passes
 
index 8325318f9afc56dcecadf961d21de6b13a2acec0..62a996316c4f5d045a77bf171f9851970e4e52a1 100644 (file)
@@ -8,13 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// This test depends on a patch that was committed to upstream LLVM
-// before 4.0, formerly backported to the Rust LLVM fork.
-
 // ignore-tidy-linelength
 // ignore-windows
 // ignore-macos
-// min-llvm-version 4.0
 
 // compile-flags: -g -C no-prepopulate-passes
 
index 7239223ca2019d032b2faa749bdf851f61843a72..f66369782e5a67e464ecbb42df040bf826a22811 100644 (file)
@@ -10,7 +10,6 @@
 
 // compile-flags: -g -C no-prepopulate-passes
 // ignore-tidy-linelength
-// min-llvm-version 4.0
 
 #![crate_type = "lib"]
 
index 0693eae7d7884f443698839d13da5d75e75a695f..10dd12909b6444a65772dfa4cd5a0c7aa85aad05 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-tidy-linelength
 // compile-flags: -C no-prepopulate-passes
+// min-llvm-version 7.0
 
 #![crate_type = "lib"]
 #![feature(repr_packed)]
@@ -63,7 +65,7 @@ pub struct BigPacked2 {
 pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
 // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
 // CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 32, i32 1, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 %{{.*}}, i8* align 1 %{{.*}}, i{{[0-9]+}} 32, i1 false)
     // check that calls whose destination is a field of a packed struct
     // go through an alloca rather than calling the function with an
     // unaligned destination.
@@ -75,7 +77,7 @@ pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
 pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 {
 // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
 // CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 32, i32 2, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 2 %{{.*}}, i8* align 2 %{{.*}}, i{{[0-9]+}} 32, i1 false)
     // check that calls whose destination is a field of a packed struct
     // go through an alloca rather than calling the function with an
     // unaligned destination.
@@ -93,14 +95,14 @@ pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 {
 // CHECK-LABEL: @pkd1_pair
 #[no_mangle]
 pub fn pkd1_pair(pair1: &mut Packed1Pair, pair2: &mut Packed1Pair) {
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 5, i32 1, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 %{{.*}}, i8* align 1 %{{.*}}, i{{[0-9]+}} 5, i1 false)
     *pair2 = *pair1;
 }
 
 // CHECK-LABEL: @pkd2_pair
 #[no_mangle]
 pub fn pkd2_pair(pair1: &mut Packed2Pair, pair2: &mut Packed2Pair) {
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 6, i32 2, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 2 %{{.*}}, i8* align 2 %{{.*}}, i{{[0-9]+}} 6, i1 false)
     *pair2 = *pair1;
 }
 
@@ -115,14 +117,14 @@ pub fn pkd2_pair(pair1: &mut Packed2Pair, pair2: &mut Packed2Pair) {
 // CHECK-LABEL: @pkd1_nested_pair
 #[no_mangle]
 pub fn pkd1_nested_pair(pair1: &mut Packed1NestedPair, pair2: &mut Packed1NestedPair) {
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 8, i32 1, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 %{{.*}}, i8* align 1 %{{.*}}, i{{[0-9]+}} 8, i1 false)
     *pair2 = *pair1;
 }
 
 // CHECK-LABEL: @pkd2_nested_pair
 #[no_mangle]
 pub fn pkd2_nested_pair(pair1: &mut Packed2NestedPair, pair2: &mut Packed2NestedPair) {
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 8, i32 2, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 2 %{{.*}}, i8* align 2 %{{.*}}, i{{[0-9]+}} 8, i1 false)
     *pair2 = *pair1;
 }
 
index 8b3294281e9603cf24dd8db15420bedb67efbb78..8565335bd75df857a7c5b42a160c6712b21cd90c 100644 (file)
@@ -10,6 +10,7 @@
 
 // compile-flags: -O
 // ignore-tidy-linelength
+// min-llvm-version 7.0
 
 #![crate_type = "lib"]
 
@@ -23,6 +24,6 @@ pub fn helper(_: usize) {
 // CHECK-LABEL: @repeat_take_collect
 #[no_mangle]
 pub fn repeat_take_collect() -> Vec<u8> {
-// CHECK: call void @llvm.memset.p0i8.[[USIZE]](i8* {{(nonnull )?}}%{{[0-9]+}}, i8 42, [[USIZE]] 100000, i32 1, i1 false)
+// CHECK: call void @llvm.memset.p0i8.[[USIZE]](i8* {{(nonnull )?}}align 1 %{{[0-9]+}}, i8 42, [[USIZE]] 100000, i1 false)
     iter::repeat(42).take(100000).collect()
 }
diff --git a/src/test/codegen/scalar-pair-bool.rs b/src/test/codegen/scalar-pair-bool.rs
new file mode 100644 (file)
index 0000000..f50e032
--- /dev/null
@@ -0,0 +1,54 @@
+// 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: -O
+
+#![crate_type = "lib"]
+
+// CHECK: define { i8, i8 } @pair_bool_bool(i1 zeroext %pair.0, i1 zeroext %pair.1)
+#[no_mangle]
+pub fn pair_bool_bool(pair: (bool, bool)) -> (bool, bool) {
+    pair
+}
+
+// CHECK: define { i8, i32 } @pair_bool_i32(i1 zeroext %pair.0, i32 %pair.1)
+#[no_mangle]
+pub fn pair_bool_i32(pair: (bool, i32)) -> (bool, i32) {
+    pair
+}
+
+// CHECK: define { i32, i8 } @pair_i32_bool(i32 %pair.0, i1 zeroext %pair.1)
+#[no_mangle]
+pub fn pair_i32_bool(pair: (i32, bool)) -> (i32, bool) {
+    pair
+}
+
+// CHECK: define { i8, i8 } @pair_and_or(i1 zeroext %arg0.0, i1 zeroext %arg0.1)
+#[no_mangle]
+pub fn pair_and_or((a, b): (bool, bool)) -> (bool, bool) {
+    // Make sure it can operate directly on the unpacked args
+    // CHECK: and i1 %arg0.0, %arg0.1
+    // CHECK: or i1 %arg0.0, %arg0.1
+    (a && b, a || b)
+}
+
+// CHECK: define void @pair_branches(i1 zeroext %arg0.0, i1 zeroext %arg0.1)
+#[no_mangle]
+pub fn pair_branches((a, b): (bool, bool)) {
+    // Make sure it can branch directly on the unpacked bool args
+    // CHECK: br i1 %arg0.0
+    if a {
+        println!("Hello!");
+    }
+    // CHECK: br i1 %arg0.1
+    if b {
+        println!("Goodbye!");
+    }
+}
index d963c7e8ddf1b60511b6ed237971d4aec92e5a0a..16f86735c2ed7179c0712a72ed78f3fe147e8194 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // ignore-emscripten
-// min-llvm-version 6.0
+// min-llvm-version 7.0
 
 // compile-flags: -C no-prepopulate-passes
 
@@ -34,10 +34,9 @@ pub unsafe fn fmin(a: f32x4, b: f32x4) -> f32x4 {
     simd_fmin(a, b)
 }
 
-// FIXME(49261)
-// // C_HECK-LABEL: @fmax
-// #[no_mangle]
-// pub unsafe fn fmax(a: f32x4, b: f32x4) -> f32x4 {
-// // C_HECK: call <4 x float> @llvm.maxnum.v4f32
-//     simd_fmax(a, b)
-// }
+// CHECK-LABEL: @fmax
+#[no_mangle]
+pub unsafe fn fmax(a: f32x4, b: f32x4) -> f32x4 {
+    // CHECK: call <4 x float> @llvm.maxnum.v4f32
+    simd_fmax(a, b)
+}
index 6ab71723a1dc5f04aa4818178573875bc34aa7fc..b8c2e62abef622bcd6a7455ba7bca773288abe6c 100644 (file)
@@ -21,7 +21,6 @@
 // ignore-wasm
 // ignore-emscripten
 // ignore-windows
-// min-system-llvm-version 5.0
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
index 08f5038fb186e466598d07bf01ab759b7ca5c61a..0aaf00bfdbe8ef1597825ed81c7d0ade8c1287f0 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // compile-flags: -C no-prepopulate-passes
+// ignore-tidy-linelength
+// min-llvm-version 7.0
 
 #![crate_type = "lib"]
 
@@ -29,7 +31,7 @@ pub struct Bytes {
 // CHECK: store i32 %0, i32* [[TMP]]
 // CHECK: [[Y8:%[0-9]+]] = bitcast [4 x i8]* %y to i8*
 // CHECK: [[TMP8:%[0-9]+]] = bitcast i32* [[TMP]] to i8*
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* [[Y8]], i8* [[TMP8]], i{{[0-9]+}} 4, i32 1, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 [[Y8]], i8* align 1 [[TMP8]], i{{[0-9]+}} 4, i1 false)
     *x = y;
 }
 
@@ -43,6 +45,6 @@ pub fn small_struct_alignment(x: &mut Bytes, y: Bytes) {
 // CHECK: store i32 %0, i32* [[TMP]]
 // CHECK: [[Y8:%[0-9]+]] = bitcast %Bytes* %y to i8*
 // CHECK: [[TMP8:%[0-9]+]] = bitcast i32* [[TMP]] to i8*
-// CHECK: call void @llvm.memcpy.{{.*}}(i8* [[Y8]], i8* [[TMP8]], i{{[0-9]+}} 4, i32 1, i1 false)
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 [[Y8]], i8* align 1 [[TMP8]], i{{[0-9]+}} 4, i1 false)
     *x = y;
 }
index b6466467548492be0f949776617ca5d2f0059ea9..abd1eb3e2cc7b061d16b054969534ea7a2614eb6 100644 (file)
@@ -14,7 +14,7 @@
 // ignore-tidy-linelength
 // ignore-windows
 // ignore-macos
-// min-system-llvm-version 5.1
+// min-llvm-version 6.0
 
 // compile-flags: -g -C no-prepopulate-passes
 
diff --git a/src/test/compile-fail/alloc-error-handler-bad-signature-1.rs b/src/test/compile-fail/alloc-error-handler-bad-signature-1.rs
new file mode 100644 (file)
index 0000000..e398f16
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags:-C panic=abort
+
+#![feature(alloc_error_handler, panic_implementation)]
+#![no_std]
+#![no_main]
+
+use core::alloc::Layout;
+
+#[alloc_error_handler]
+fn oom(
+    info: &Layout, //~ ERROR argument should be `Layout`
+) -> () //~ ERROR return type should be `!`
+{
+    loop {}
+}
+
+#[panic_implementation]
+fn panic(_: &core::panic::PanicInfo) -> ! { loop {} }
diff --git a/src/test/compile-fail/alloc-error-handler-bad-signature-2.rs b/src/test/compile-fail/alloc-error-handler-bad-signature-2.rs
new file mode 100644 (file)
index 0000000..4fee9d2
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags:-C panic=abort
+
+#![feature(alloc_error_handler, panic_implementation)]
+#![no_std]
+#![no_main]
+
+struct Layout;
+
+#[alloc_error_handler]
+fn oom(
+    info: Layout, //~ ERROR argument should be `Layout`
+) { //~ ERROR return type should be `!`
+    loop {}
+}
+
+#[panic_implementation]
+fn panic(_: &core::panic::PanicInfo) -> ! { loop {} }
diff --git a/src/test/compile-fail/alloc-error-handler-bad-signature-3.rs b/src/test/compile-fail/alloc-error-handler-bad-signature-3.rs
new file mode 100644 (file)
index 0000000..828a780
--- /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.
+
+// compile-flags:-C panic=abort
+
+#![feature(alloc_error_handler, panic_implementation)]
+#![no_std]
+#![no_main]
+
+struct Layout;
+
+#[alloc_error_handler]
+fn oom() -> ! { //~ ERROR function should have one argument
+    loop {}
+}
+
+#[panic_implementation]
+fn panic(_: &core::panic::PanicInfo) -> ! { loop {} }
index 3bb0382ef037be8299c335d675a14253ca13d9b1..c561ae861ed2ae02d3ab0e6646b88833080b5815 100644 (file)
@@ -14,7 +14,7 @@ trait Get {
 }
 
 fn foo<T:Get>(t: T) {
-    let x = t.get(); //~ ERROR the size for value values of type
+    let x = t.get(); //~ ERROR the size for values of type
 }
 
 fn main() {
index 9b87ec4d446cd155bf5ce4f2a8b18317973b20fb..a58aebee77be7d7618a8688c3c1e9d2d22179fac 100644 (file)
@@ -13,6 +13,6 @@ trait Trait {}
 pub fn main() {
     let x: Vec<Trait + Sized> = Vec::new();
     //~^ ERROR only auto traits can be used as additional traits in a trait object
-    //~| ERROR the size for value values of type
-    //~| ERROR the size for value values of type
+    //~| ERROR the size for values of type
+    //~| ERROR the size for values of type
 }
index 3a7e4a13740d070ab1b4afbba2bf2a7283f52968..b821c7cfa34ff97029aa489ee569e7381e38e61f 100644 (file)
@@ -302,7 +302,7 @@ unsafe fn bump2(mut block: *mut Block2) {
         // FIXME(#49824) -- the free region error below should probably not be there
         let mut x = 0;
            || {
-               || { //[mir]~ ERROR free region `` does not outlive
+               || { //[mir]~ ERROR unsatisfied lifetime constraints
                    let y = &mut x;
                    &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time
                    //[mir]~^ ERROR cannot borrow `x` as mutable more than once at a time
index 1dbdd42ca36e267e8e32f9bdcefe0cc9f54b9431..372f3187805083dd27cb4bafc435f861736ad6e1 100644 (file)
@@ -43,6 +43,6 @@ pub fn main() {
     let f5: &mut Fat<ToBar> = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} };
     let z: Box<ToBar> = Box::new(Bar1 {f: 36});
     f5.ptr = *z;
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 
 }
index 2a209a2959bfd7bf08c84b4338d92a636de68c28..339cfb5443de385de9244b30c6dc19c056bffdee 100644 (file)
@@ -45,5 +45,5 @@ pub fn main() {
     //~| expected type `dyn ToBar`
     //~| found type `Bar1`
     //~| expected trait ToBar, found struct `Bar1`
-    //~| ERROR the size for value values of type
+    //~| ERROR the size for values of type
 }
index e28586c4755e872320a026ee9b195ab5b623e1d6..9a329c636ae468817574f0cf042e45ba993871b4 100644 (file)
@@ -47,5 +47,5 @@ pub fn main() {
     //~| expected type `dyn ToBar`
     //~| found type `Bar1`
     //~| expected trait ToBar, found struct `Bar1`
-    //~| ERROR the size for value values of type
+    //~| ERROR the size for values of type
 }
index 82d81913cd3a3dbd6a290bc52ccb72c742d61459..a54301071ba0e341162124e2aa409f91ceb6cd10 100644 (file)
@@ -19,5 +19,5 @@ pub fn main() {
     let f: ([isize; 3],) = ([5, 6, 7],);
     let g: &([isize],) = &f;
     let h: &(([isize],),) = &(*g,);
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
index b8ca22185bc3c9dd33e4ca8f7c5833e2bb997eb1..3d7e2b8f6711d1eb3e5421396f46d1d68c7b9b0a 100644 (file)
@@ -21,5 +21,5 @@ pub fn main() {
     let f: Fat<[isize; 3]> = Fat { ptr: [5, 6, 7] };
     let g: &Fat<[isize]> = &f;
     let h: &Fat<Fat<[isize]>> = &Fat { ptr: *g };
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
index 4a892753595a72cb4f3c7a76550878aa8848cd05..70b46b1bd79fd6042e8f7753ebef13ad4fa45273 100644 (file)
@@ -16,22 +16,22 @@ impl Foo for [u8] {}
 
 fn test1<T: ?Sized + Foo>(t: &T) {
     let u: &Foo = t;
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn test2<T: ?Sized + Foo>(t: &T) {
     let v: &Foo = t as &Foo;
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn test3() {
     let _: &[&Foo] = &["hi"];
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn test4(x: &[u8]) {
     let _: &Foo = x as &Foo;
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn main() { }
index 0679556743228c28af4c363ed92fb6b08e72ddc1..7316a48970f67a9bad9a9dadd02821ba1dfce4d0 100644 (file)
@@ -15,9 +15,9 @@
 trait Foo<T> : Sized { fn take(self, x: &T) { } } // Note: T is sized
 
 impl Foo<[isize]> for usize { }
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 
 impl Foo<isize> for [usize] { }
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 
 pub fn main() { }
index 135b466161d77a0cbe88c62d9314bf9da04eebcd..f2db4553868100ef0f0003e5cab5242760b4fc13 100644 (file)
@@ -30,14 +30,14 @@ fn assert_sized<T>() { }
 
 fn main() {
     assert_sized::<A>();
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 
     assert_sized::<Foo>();
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 
     assert_sized::<Bar<A>>();
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 
     assert_sized::<Bar<Bar<A>>>();
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
diff --git a/src/test/compile-fail/feature-gate-alloc-error-handler.rs b/src/test/compile-fail/feature-gate-alloc-error-handler.rs
new file mode 100644 (file)
index 0000000..66691af
--- /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.
+
+// compile-flags:-C panic=abort
+
+#![no_std]
+#![no_main]
+
+use core::alloc::Layout;
+
+#[alloc_error_handler] //~ ERROR #[alloc_error_handler] is an unstable feature (see issue #51540)
+fn oom(info: Layout) -> ! {
+    loop {}
+}
diff --git a/src/test/compile-fail/feature-gate-tool_lints.rs b/src/test/compile-fail/feature-gate-tool_lints.rs
new file mode 100644 (file)
index 0000000..c311eb7
--- /dev/null
@@ -0,0 +1,12 @@
+// 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.
+
+#[warn(clippy::assign_ops)] //~ ERROR scoped lint `clippy::assign_ops` is experimental
+fn main() {}
index 88fe9cd44a39e26af233b4071e5bf2ad033c43ed..5fad4c3677c0d79b1360f124ad155fe54fcb2764 100644 (file)
@@ -17,5 +17,5 @@ mod test {
 
 fn main() {
     test::free();
-    //~^ ERROR call to unsafe function requires unsafe function or block
+    //~^ ERROR call to unsafe function is unsafe
 }
diff --git a/src/test/compile-fail/forget-init-unsafe.rs b/src/test/compile-fail/forget-init-unsafe.rs
deleted file mode 100644 (file)
index 48c9fda..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 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.
-
-#![feature(core_intrinsics)]
-
-use std::intrinsics::{init};
-
-// Test that the `forget` and `init` intrinsics are really unsafe
-pub fn main() {
-    let stuff = init::<isize>(); //~ ERROR call to unsafe function requires unsafe
-}
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() {}
diff --git a/src/test/compile-fail/init-unsafe.rs b/src/test/compile-fail/init-unsafe.rs
new file mode 100644 (file)
index 0000000..9e599ce
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 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.
+
+#![feature(core_intrinsics)]
+
+use std::intrinsics::{init};
+
+// Test that the `init` intrinsic is really unsafe
+pub fn main() {
+    let stuff = init::<isize>(); //~ ERROR call to unsafe function is unsafe
+}
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 5212cbb004efadffd955977b1e68fd8367cf749e..0b154d0a3ea88f12b9b72d798fbe578310a24ef8 100644 (file)
@@ -10,5 +10,5 @@
 
 fn main() {
     let _x = "test" as &::std::any::Any;
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
index 4756099ab95689c954112855ecfba28136c177e0..c123e85a0e0fcdf87bc94b3eaaa522c5ccd77673 100644 (file)
@@ -15,7 +15,7 @@ fn dft_iter<'a, T>(arg1: Chunks<'a,T>, arg2: ChunksMut<'a,T>)
 {
     for
     &mut something
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     in arg2
     {
     }
index e7019ff7c0d21193caaa0a91119a31596622cdc1..cbd0da4b53ce341d6da0a5c6fff400c36587affc 100644 (file)
@@ -13,5 +13,5 @@
 
 fn main() {
     (|| Box::new(*(&[0][..])))();
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
index 9239ceb341fc6da523732dbd941e7ccf80195488..260038b7add59f561e463210359c9ef3c249270c 100644 (file)
@@ -12,7 +12,7 @@ pub trait AbstractRenderer {}
 
 fn _create_render(_: &()) ->
     AbstractRenderer
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 {
     match 0 {
         _ => unimplemented!()
index 0b717ec641375d8a27af24804aef5a8ebf91263b..cc87a0977a0ccdbc1934f7d34a87f135811be09e 100644 (file)
@@ -11,7 +11,7 @@
 type FuncType<'f> = Fn(&isize) -> isize + 'f;
 
 fn ho_func(f: Option<FuncType>) {
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn main() {}
index 426657ac92e2c868a902d9edec48f5701ce410e4..8db09182fa3bb7011f9bb73b59d0f64e6b06887e 100644 (file)
@@ -15,7 +15,7 @@ trait From<Src> {
 }
 
 trait To {
-    fn to<Dst>(  //~ ERROR the size for value values of type
+    fn to<Dst>(  //~ ERROR the size for values of type
         self
     ) -> <Dst as From<Self>>::Result where Dst: From<Self> {
         From::from(self)
index 8b7f2d5a4588e3334ce464e0959643bf2cc52a19..f760cd59968c214c844a1ec1afbc36e83f96d257 100644 (file)
@@ -14,5 +14,5 @@ fn main() {}
 
 impl The {
     fn iceman(c: Vec<[i32]>) {}
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
index 2d8d9c6565532c84ed65e24bb2b07a9e41c627f9..60d012ab13426a7e7c6b68b077ba578060a6f828 100644 (file)
@@ -10,7 +10,7 @@
 
 fn changer<'a>(mut things: Box<Iterator<Item=&'a mut u8>>) {
     for item in *things { *item = 0 }
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 }
 
 fn main() {}
index cb199580b10dd182137a89de62dd8404dea87a63..e0a87b3a1746e99db5679c0506011dbee56de075 100644 (file)
@@ -10,7 +10,7 @@
 
 struct Table {
     rows: [[String]],
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn f(table: &Table) -> &[String] {
index d6b5c32982554a3055ff4e911552bc4cd994fc6b..5de00eb8f6823859ae66678d4ec90b3db50c0d86 100644 (file)
@@ -14,7 +14,7 @@
 
 impl Struct {
     pub fn function(funs: Vec<Fn() -> ()>) {}
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn main() {}
index 74c68c50ae35aee6b8a773654d14a81c254f35d9..a9c7978642d5f528766af4558ba64f32417566b3 100644 (file)
@@ -11,7 +11,7 @@
 fn main() {
     static foo: Fn() -> u32 = || -> u32 {
         //~^ ERROR mismatched types
-        //~| ERROR the size for value values of type
+        //~| ERROR the size for values of type
         0
     };
 }
index bc5567e1686d3ac16b35849c5d07f26cf8860c06..619616adda6debb5cc27dd85f20b976d76872df7 100644 (file)
@@ -10,7 +10,7 @@
 
 #[repr(packed)]
 pub struct Bad<T: ?Sized> {
-    data: T, //~ ERROR the size for value values of type
+    data: T, //~ ERROR the size for values of type
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-27060.rs b/src/test/compile-fail/issue-27060.rs
deleted file mode 100644 (file)
index 37369d5..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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.
-
-#[repr(packed)]
-pub struct Good {
-    data: &'static u32,
-    data2: [&'static u32; 2],
-    aligned: [u8; 32],
-}
-
-#[repr(packed)]
-pub struct JustArray {
-    array: [u32]
-}
-
-#[deny(safe_packed_borrows)]
-fn main() {
-    let good = Good {
-        data: &0,
-        data2: [&0, &0],
-        aligned: [0; 32]
-    };
-
-    unsafe {
-        let _ = &good.data; // ok
-        let _ = &good.data2[0]; // ok
-    }
-
-    let _ = &good.data; //~ ERROR borrow of packed field requires unsafe
-                        //~| hard error
-    let _ = &good.data2[0]; //~ ERROR borrow of packed field requires unsafe
-                            //~| hard error
-    let _ = &*good.data; // ok, behind a pointer
-    let _ = &good.aligned; // ok, has align 1
-    let _ = &good.aligned[2]; // ok, has align 1
-}
index 6efc1f1024317ff8853c46faf4939921b845fb1f..294c288a970dfc0f24b878406dbf0db2ba3b9285 100644 (file)
@@ -13,7 +13,7 @@
 trait Foo {
     const BAR: i32;
     fn foo(self) -> &'static i32 {
-        //~^ ERROR the size for value values of type
+        //~^ ERROR the size for values of type
         &<Self>::BAR
     }
 }
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 805b1a48a038012a67f2be38acb4ec080bcce1c3..5909322ff1fe595ff0156b71bc4b8c446ed21c44 100644 (file)
@@ -10,7 +10,7 @@
 
 enum E {
     V([Box<E>]),
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn main() {}
index 1b64d17bbeffe4b1de41f6c66aacbf2c465f68c1..7f01ed3f8201322f3dd2ba480fe3016b2eb5d2d4 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 fn _test(ref _p: str) {}
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 
 fn main() { }
index 6207e669d0092ad790c994b743d3714bbe805a34..5d7546e1bc4b345fb796f519fd8f77f7a11d95f8 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 pub fn example(ref s: str) {}
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 
 fn main() {}
index 2ab44433ede82151cd1e97320ad70b2127a26807..f7705297dfdba00f30928ab62fe5fc91fd736161 100644 (file)
 
 pub trait Foo {
     fn baz(_: Self::Target) where Self: Deref {}
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 pub fn f(_: ToString) {}
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 
 fn main() { }
index 90ccc589b4ea7378667a788541a1285349209a00..7b1364ff41c4023754343aa601bd9c38ccd74cf7 100644 (file)
@@ -27,12 +27,12 @@ fn __getit() -> std::option::Option<
     &'static std::cell::UnsafeCell<
         std::option::Option<Foo>>>
 {
-    __KEY.get() //~ ERROR call to unsafe function requires unsafe
+    __KEY.get() //~ ERROR call to unsafe function is unsafe
 }
 
 static FOO: std::thread::LocalKey<Foo> =
     std::thread::LocalKey::new(__getit, Default::default);
-//~^ ERROR call to unsafe function requires unsafe
+//~^ ERROR call to unsafe function is unsafe
 
 fn main() {
     FOO.with(|foo| println!("{}", foo.borrow()));
index eeb66fa0e2c3b01de118b62f85fa9b94fd8e62e4..5af0bf6be56e93147665903733a5106a985724cd 100644 (file)
@@ -11,5 +11,5 @@
 fn main() {
     return;
     *(1 as *mut u32) = 42;
-    //~^ ERROR dereference of raw pointer requires unsafe
+    //~^ ERROR dereference of raw pointer is unsafe
 }
index 489e91797f3d76ccd79166cee1df25a0cc24ef48..b42ced07583f4f0fc63df3fe40f5c11047a9850d 100644 (file)
@@ -13,7 +13,7 @@
 fn main() {
     let _ = || {
         *(1 as *mut u32) = 42;
-        //~^ ERROR dereference of raw pointer requires unsafe
+        //~^ ERROR dereference of raw pointer is unsafe
         yield;
     };
 }
index 7481befcb7952c91dc17b0e8de7d604216993dca..683ef876f4e37ca7ac3b4e0bb3c9bdde1d275589 100644 (file)
@@ -19,13 +19,13 @@ fn union_field() {
     union Union { unit: (), void: Void }
     let u = Union { unit: () };
     match u.void {}
-    //~^ ERROR access to union field requires unsafe function or block
+    //~^ ERROR access to union field is unsafe
 }
 
 fn raw_ptr_deref() {
     let ptr = std::ptr::null::<Void>();
     match *ptr {}
-    //~^ ERROR dereference of raw pointer requires unsafe function or block
+    //~^ ERROR dereference of raw pointer is unsafe
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-52213.rs b/src/test/compile-fail/issue-52213.rs
new file mode 100644 (file)
index 0000000..810379c
--- /dev/null
@@ -0,0 +1,24 @@
+// 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.
+
+fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T {
+    match (&t,) { //~ ERROR cannot infer an appropriate lifetime
+        ((u,),) => u,
+    }
+}
+
+fn main() {
+    let x = {
+        let y = Box::new((42,));
+        transmute_lifetime(&y)
+    };
+
+    println!("{}", x);
+}
index 82d4666ce549ca1a68de9c2fb58ba98a40e995b4..a91f5d281dd9044ec40ed3a0520fb073b842a7de 100644 (file)
@@ -15,8 +15,8 @@ struct Struct {
 }
 
 fn new_struct(r: A+'static)
-    -> Struct { //~^ ERROR the size for value values of type
-    //~^ ERROR the size for value values of type
+    -> Struct { //~^ ERROR the size for values of type
+    //~^ ERROR the size for values of type
     Struct { r: r }
 }
 
index f3c9f29821ebb6c3b96f003270ad7b64c38c8f3b..f5f0ede6864f4df3fe5064aef97b50de96edfdb0 100644 (file)
@@ -10,6 +10,7 @@
 
 // General test of maybe_uninits state computed by MIR dataflow.
 
+#![feature(nll)]
 #![feature(core_intrinsics, rustc_attrs)]
 
 use std::intrinsics::rustc_peek;
@@ -17,7 +18,6 @@
 
 struct S(i32);
 
-#[rustc_mir_borrowck]
 #[rustc_mir(rustc_peek_definite_init,stop_after_dataflow)]
 fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
     let ret;
index 8a5ab6e420adefb0ff83d298dc2f116844013cb7..595f01f7c94b34a065a5736b8297a6ea34b2c1f4 100644 (file)
@@ -10,6 +10,7 @@
 
 // General test of maybe_inits state computed by MIR dataflow.
 
+#![feature(nll)]
 #![feature(core_intrinsics, rustc_attrs)]
 
 use std::intrinsics::rustc_peek;
@@ -17,7 +18,6 @@
 
 struct S(i32);
 
-#[rustc_mir_borrowck]
 #[rustc_mir(rustc_peek_maybe_init,stop_after_dataflow)]
 fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
     let ret;
index 8df66ea815c68800b80e2f6debc653fc74ba192c..bb10c03254e3cb065a7514ee7108635a9f86a289 100644 (file)
@@ -10,6 +10,7 @@
 
 // General test of maybe_uninits state computed by MIR dataflow.
 
+#![feature(nll)]
 #![feature(core_intrinsics, rustc_attrs)]
 
 use std::intrinsics::rustc_peek;
@@ -17,7 +18,6 @@
 
 struct S(i32);
 
-#[rustc_mir_borrowck]
 #[rustc_mir(rustc_peek_maybe_uninit,stop_after_dataflow)]
 fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
     let ret;
index 2edd275e78691e59d73dd362ebdcf52d6c3f363f..9854ea779b3adfac2de73d5d63a36fd5e195a420 100644 (file)
@@ -10,6 +10,7 @@
 
 // General test of maybe_uninits state computed by MIR dataflow.
 
+#![feature(nll)]
 #![feature(core_intrinsics, rustc_attrs)]
 
 use std::intrinsics::rustc_peek;
@@ -17,7 +18,6 @@
 
 struct S(i32);
 
-#[rustc_mir_borrowck]
 #[rustc_mir(rustc_peek_maybe_uninit,stop_after_dataflow)]
 fn foo(x: &mut S) {
     // `x` is initialized here, so maybe-uninit bit is 0.
index d8f5956b585303847cde55e450d7aa96b1835070..2200c1569e5728c388c4d3c1c60b093ac3e7f846 100644 (file)
@@ -14,7 +14,7 @@
 
 fn bar<'a, 'b>() -> fn(&'a u32, &'b u32) -> &'a u32 {
     let g: fn(_, _) -> _ = |_x, y| y;
-    //~^ ERROR free region `'b` does not outlive free region `'a`
+    //~^ ERROR unsatisfied lifetime constraints
     g
     //~^ WARNING not reporting region error due to nll
 }
index 1f9174b3574a7bb57d0c5177eff5cc12067da4d7..f85104dff867f6402898941a06469070147173a8 100644 (file)
@@ -45,7 +45,7 @@ fn bar<'a>(x: &'a u32) -> &'static u32 {
     // as part of checking the `ReifyFnPointer`.
     let f: fn(_) -> _ = foo;
     //~^ WARNING not reporting region error due to nll
-    //~| ERROR free region `'a` does not outlive free region `'static`
+    //~| ERROR unsatisfied lifetime constraints
     f(x)
 }
 
index 27ca2728ddfd623a5bb74f2b2710d3531206bba4..e90242f3f87dac42d7bc4b9d8db330cb4995565f 100644 (file)
@@ -17,7 +17,7 @@ fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 {
     // in `g`. These are related via the `UnsafeFnPointer` cast.
     let g: unsafe fn(_) -> _ = f;
     //~^ WARNING not reporting region error due to nll
-    //~| ERROR free region `'a` does not outlive free region `'static`
+    //~| ERROR unsatisfied lifetime constraints
     unsafe { g(input) }
 }
 
index a2c840a70980b5937970ca3d18cf03a20233370f..d242186a6f7ea6983efbdde21cb04db7ec480ee5 100644 (file)
@@ -15,8 +15,7 @@
 use std::fmt::Debug;
 
 fn bar<'a>(x: &'a u32) -> &'static dyn Debug {
-    //~^ ERROR free region `'a` does not outlive free region `'static`
-    x
+    x //~ ERROR unsatisfied lifetime constraints
     //~^ WARNING not reporting region error due to nll
 }
 
index ed26204bbe10920d39a5896ae8c9d0e9a949ed03..59c78052e15d243f829aea4b08faa190cd861f8d 100644 (file)
@@ -22,5 +22,5 @@ pub fn main() {
     // Unsized type.
     let arr: &[_] = &[1, 2, 3];
     let range = *arr..;
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
index a0097b9f6d7df84ae0e3ce2e8e59cabc5bec13e0..0a37df4f0c788d11bc04249a830ed71bb96af32c 100644 (file)
@@ -18,7 +18,7 @@ fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
 fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
     t //[ll]~ ERROR E0312
         //[nll]~^ WARNING not reporting region error due to nll
-        //[nll]~| ERROR free region `'a` does not outlive free region `'static`
+        //[nll]~| ERROR unsatisfied lifetime constraints
 }
 
 fn error(u: &(), v: &()) {
index ed8d5900776a9f79be0576a736a69b67d3718b75..35ea6dd52c4f28fe29ff3cc19f326ca5e9fb46b4 100644 (file)
@@ -18,8 +18,8 @@
 }
 
 fn main() {
-    let b = B; //~ ERROR use of mutable static requires unsafe function or block
-    let rb = &B; //~ ERROR use of mutable static requires unsafe function or block
-    let xb = XB; //~ ERROR use of mutable static requires unsafe function or block
-    let xrb = &XB; //~ ERROR use of mutable static requires unsafe function or block
+    let b = B; //~ ERROR use of mutable static is unsafe
+    let rb = &B; //~ ERROR use of mutable static is unsafe
+    let xb = XB; //~ ERROR use of mutable static is unsafe
+    let xrb = &XB; //~ ERROR use of mutable static is unsafe
 }
index 4d939f33c46dccd67ce03f54812efed0a7d2615c..83aa4b3316da0b7b9781ac2df49f1e977525c66c 100644 (file)
 }
 
 fn main() {
-    let a = A; //~ ERROR use of extern static requires unsafe function or block
+    let a = A; //~ ERROR use of extern static is unsafe
                //~^ WARN this was previously accepted by the compiler
-    let ra = &A; //~ ERROR use of extern static requires unsafe function or block
+    let ra = &A; //~ ERROR use of extern static is unsafe
                  //~^ WARN this was previously accepted by the compiler
-    let xa = XA; //~ ERROR use of extern static requires unsafe function or block
+    let xa = XA; //~ ERROR use of extern static is unsafe
                  //~^ WARN this was previously accepted by the compiler
-    let xra = &XA; //~ ERROR use of extern static requires unsafe function or block
+    let xra = &XA; //~ ERROR use of extern static is unsafe
                    //~^ WARN this was previously accepted by the compiler
 }
index 57e4bb76a6ce8272678833bd3c98483e6639ef32..725960a866ba01745b972a27e3e760900de1cbd5 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// min-llvm-version 5.0
 // ignore-emscripten
 
 // Test that the simd_reduce_{op} intrinsics produce ok-ish error
index cc5fd7e3f24d82fd64dcd99b7ec1a35810b90463..136bfaefa71c695485c8e83a9999f540286a7a33 100644 (file)
@@ -12,8 +12,8 @@ fn bot<T>() -> T { loop {} }
 
 fn mutate(s: &mut str) {
     s[1..2] = bot();
-    //~^ ERROR the size for value values of type
-    //~| ERROR the size for value values of type
+    //~^ ERROR the size for values of type
+    //~| ERROR the size for values of type
     s[1usize] = bot();
     //~^ ERROR the type `str` cannot be mutably indexed by `usize`
 }
index b8557cb79e38743d5008faa28819f2cc39ac122c..d0e9a7f4a400db56735418d7aa324ed8b91a0438 100644 (file)
@@ -56,6 +56,6 @@ fn foo<'z>() where &'z (): Sized {
     //[normal]~| found type `fn() {foo::<'static>}`
 
     <str as Foo<u8>>::bar;
-    //[verbose]~^ ERROR the size for value values of type
-    //[normal]~^^ ERROR the size for value values of type
+    //[verbose]~^ ERROR the size for values of type
+    //[normal]~^^ ERROR the size for values of type
 }
diff --git a/src/test/compile-fail/tool_lints.rs b/src/test/compile-fail/tool_lints.rs
new file mode 100644 (file)
index 0000000..ea1efab
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+// Don't allow tool_lints, which aren't scoped
+
+#![feature(tool_lints)]
+#![deny(unknown_lints)]
+
+#![deny(clippy)] //~ ERROR: unknown lint: `clippy`
+
+fn main() {}
index 89fddf1f65f0240ea7f391358ea8d43ffc98d866..9c38d8a9e2a36872254a41409db5ea42bab75836 100644 (file)
@@ -15,7 +15,7 @@ fn dummy(&self) { }
 // This should emit the less confusing error, not the more confusing one.
 
 fn foo(_x: Foo + Send) {
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn main() { }
index e57d65dcb891f7b5b1439969f12ac5e80e617be9..d993816e6f476f6234f1e8db55766ef8362bb0c8 100644 (file)
@@ -28,7 +28,7 @@ union U4<T: Copy> {
 
 fn generic_noncopy<T: Default>() {
     let mut u3 = U3 { a: T::default() };
-    u3.a = T::default(); //~ ERROR assignment to non-`Copy` union field requires unsafe
+    u3.a = T::default(); //~ ERROR assignment to non-`Copy` union field is unsafe
 }
 
 fn generic_copy<T: Copy + Default>() {
@@ -40,16 +40,16 @@ fn generic_copy<T: Copy + Default>() {
 
 fn main() {
     let mut u1 = U1 { a: 10 }; // OK
-    let a = u1.a; //~ ERROR access to union field requires unsafe
+    let a = u1.a; //~ ERROR access to union field is unsafe
     u1.a = 11; // OK
-    let U1 { a } = u1; //~ ERROR access to union field requires unsafe
-    if let U1 { a: 12 } = u1 {} //~ ERROR access to union field requires unsafe
+    let U1 { a } = u1; //~ ERROR access to union field is unsafe
+    if let U1 { a: 12 } = u1 {} //~ ERROR access to union field is unsafe
     // let U1 { .. } = u1; // OK
 
     let mut u2 = U2 { a: String::from("old") }; // OK
-    u2.a = String::from("new"); //~ ERROR assignment to non-`Copy` union field requires unsafe
+    u2.a = String::from("new"); //~ ERROR assignment to non-`Copy` union field is unsafe
     let mut u3 = U3 { a: 0 }; // OK
     u3.a = 1; // OK
     let mut u3 = U3 { a: String::from("old") }; // OK
-    u3.a = String::from("new"); //~ ERROR assignment to non-`Copy` union field requires unsafe
+    u3.a = String::from("new"); //~ ERROR assignment to non-`Copy` union field is unsafe
 }
index a9a2a3c4c92a11064698d939d08873d183f41f8b..d79c2ed710e35f876b4e60d876d1a99d2c4ed0f5 100644 (file)
@@ -12,7 +12,7 @@
 
 union U {
     a: str,
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 
     b: u8,
 }
@@ -20,7 +20,7 @@ union U {
 union W {
     a: u8,
     b: str,
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/unknown-lint-tool-name.rs b/src/test/compile-fail/unknown-lint-tool-name.rs
new file mode 100644 (file)
index 0000000..78b736e
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(tool_lints)]
+
+#![deny(foo::bar)] //~ ERROR an unknown tool name found in scoped lint: `foo::bar`
+
+#[allow(foo::bar)] //~ ERROR an unknown tool name found in scoped lint: `foo::bar`
+fn main() {}
index f30da250f6ac80f2eb8a0ec66d429a4d17c6d077..baf2002a94fc905157f2e3403c5219e98a5c2a67 100644 (file)
@@ -11,7 +11,7 @@
 
 
 fn f(p: *mut u8) {
-    *p = 0; //~ ERROR dereference of raw pointer requires unsafe function or block
+    *p = 0; //~ ERROR dereference of raw pointer is unsafe
     return;
 }
 
index 15bcad95cb22b36568e7e2e388fcaa1ee1248965..46f28da43d03b4493cbc5ce12750482fe2009f8a 100644 (file)
@@ -12,5 +12,5 @@
 unsafe fn f() { return; }
 
 fn main() {
-    f(); //~ ERROR call to unsafe function requires unsafe function or block
+    f(); //~ ERROR call to unsafe function is unsafe
 }
index bf87df71fd87dc77163aebfe05b48caec1ef56c1..8e3ce8ff9b57d84fa1c373afeb7ae1f8b73ca21d 100644 (file)
@@ -10,7 +10,7 @@
 
 
 fn f(p: *const u8) -> u8 {
-    return *p; //~ ERROR dereference of raw pointer requires unsafe function or block
+    return *p; //~ ERROR dereference of raw pointer is unsafe
 }
 
 fn main() {
index 8e2d82b8fdbf448fab5d5f4b6c730fdaebc7f760..f09a0c7107a8a847e41bf8ab86d32669068c94ab 100644 (file)
@@ -13,5 +13,5 @@
 
 fn main() {
     let x = f;
-    x();    //~ ERROR call to unsafe function requires unsafe function or block
+    x();    //~ ERROR call to unsafe function is unsafe
 }
index 84a8c84a0dbd203ae46cf6ca2e64a06e097b4fb6..b4e425e7bbff130ecdaa3c230735d5ca1200408e 100644 (file)
@@ -16,5 +16,5 @@
 // as unsafe.
 fn main() {
     intrinsics::move_val_init(1 as *mut u32, 1);
-    //~^ ERROR dereference of raw pointer requires unsafe function or block
+    //~^ ERROR dereference of raw pointer is unsafe
 }
index 736794ac5384e0c768404c791b9ce6b2dcfaf34c..498bdded350f2614a756006c9617519e7b9c5f91 100644 (file)
@@ -10,5 +10,5 @@
 
 fn bar<T: Sized>() { }
 fn foo<T: ?Sized>() { bar::<T>() }
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 fn main() { }
index f9702e29f1dc36ea44cc03fda326ca6859c58523..4a6a5557c956069b98bc05af8cf7c68c14ec84a4 100644 (file)
@@ -15,7 +15,7 @@ fn not_sized<T: ?Sized>() { }
 enum Foo<U> { FooSome(U), FooNone }
 fn foo1<T>() { not_sized::<Foo<T>>() } // Hunky dory.
 fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 //
 // Not OK: `T` is not sized.
 
index 03d3d98b59f012d62b54c16c73817128db8da673..a679bf770153cfa93a76d688fb326063c511c666 100644 (file)
@@ -15,7 +15,7 @@
 struct S5<Y>(Y);
 
 impl<X: ?Sized> S5<X> {
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn main() { }
index 8cb1f760664de469aec6c0572f6ab7086c1d619e..f2c63455c517db573af3331e36a510efbe94cf2f 100644 (file)
@@ -15,14 +15,14 @@ fn not_sized<T: ?Sized>() { }
 struct Foo<T> { data: T }
 fn foo1<T>() { not_sized::<Foo<T>>() } // Hunky dory.
 fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 //
 // Not OK: `T` is not sized.
 
 struct Bar<T: ?Sized> { data: T }
 fn bar1<T: ?Sized>() { not_sized::<Bar<T>>() }
 fn bar2<T: ?Sized>() { is_sized::<Bar<T>>() }
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 //
 // Not OK: `Bar<T>` is not sized, but it should be.
 
index b3610a4c9b9b64b8f0ddd5921e3e181fa9649ec7..5c0b8f124025725f13459b1658c1a8d2d567a15e 100644 (file)
@@ -18,7 +18,7 @@ trait T3<Z: ?Sized> {
 struct S5<Y>(Y);
 
 impl<X: ?Sized> T3<X> for S5<X> {
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn main() { }
index 50a058a4338d8d56f9813d32dbedddce449a2cb9..875a52e11c0deecdc1ad36e439071365791075cb 100644 (file)
@@ -16,7 +16,7 @@ trait T2<Z> {
 }
 struct S4<Y: ?Sized>(Box<Y>);
 impl<X: ?Sized> T2<X> for S4<X> {
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn main() { }
index 945f20b28779ed9963fd552ca7c47a28683f830f..2e346e473ca12daf596c9d2b93dc6338e9ba8c4d 100644 (file)
@@ -15,7 +15,7 @@
 // Unbounded.
 fn f1<X: ?Sized>(x: &X) {
     f2::<X>(x);
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 fn f2<X>(x: &X) {
 }
@@ -26,7 +26,7 @@ fn foo(&self) { }
 }
 fn f3<X: ?Sized + T>(x: &X) {
     f4::<X>(x);
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 fn f4<X: T>(x: &X) {
 }
@@ -41,20 +41,20 @@ struct S<X: ?Sized> {
 
 fn f8<X: ?Sized>(x1: &S<X>, x2: &S<X>) {
     f5(x1);
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     f6(x2); // ok
 }
 
 // Test some tuples.
 fn f9<X: ?Sized>(x1: Box<S<X>>) {
     f5(&(*x1, 34));
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn f10<X: ?Sized>(x1: Box<S<X>>) {
     f5(&(32, *x1));
-    //~^ ERROR the size for value values of type
-    //~| ERROR the size for value values of type
+    //~^ ERROR the size for values of type
+    //~| ERROR the size for values of type
 }
 
 pub fn main() {
index e04aa3599e9b5805e47af228ffcdf65d3287d1c5..a50786e306a57cc4c8a4369b1e7af6ed72514c0c 100644 (file)
 
 struct S1<X: ?Sized> {
     f1: X,
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     f2: isize,
 }
 struct S2<X: ?Sized> {
     f: isize,
     g: X,
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     h: isize,
 }
 struct S3 {
     f: str,
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     g: [usize]
 }
 struct S4 {
     f: [u8],
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     g: usize
 }
 enum E<X: ?Sized> {
     V1(X, isize),
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 enum F<X: ?Sized> {
     V2{f1: X, f: isize},
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 pub fn main() {
index 8ac9fe4c58787b1a54cd78cb0bd4acafd4dbf2e7..1a57f2caf8dd20b7998df0b6b236447626e4e58e 100644 (file)
@@ -15,40 +15,40 @@ trait T {}
 fn f1<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized>(x: &X) {
     let _: W; // <-- this is OK, no bindings created, no initializer.
     let _: (isize, (X, isize));
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     let y: Y;
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     let y: (isize, (Z, usize));
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 fn f2<X: ?Sized, Y: ?Sized>(x: &X) {
     let y: X;
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     let y: (isize, (Y, isize));
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn f3<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
     let y: X = *x1;
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     let y = *x2;
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     let (y, z) = (*x3, 4);
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 fn f4<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
     let y: X = *x1;
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     let y = *x2;
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     let (y, z) = (*x3, 4);
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn g1<X: ?Sized>(x: X) {}
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 fn g2<X: ?Sized + T>(x: X) {}
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 
 pub fn main() {
 }
index 44d7df35680ce3bee8d5a6c7ea416d38514ce537..07b4ae4c3941c5d62ac140a6f3c0cb73bf3957b2 100644 (file)
@@ -20,7 +20,7 @@ trait T1<Z: T> {
 
 struct S3<Y: ?Sized>(Box<Y>);
 impl<X: ?Sized + T> T1<X> for S3<X> {
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 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 27446d6bd28f58c2b7485d2abcb5e3e4e3da500c..b4b54e13a698ee87d2334ca6a3eae888e1b48ab6 100644 (file)
@@ -8,9 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// asmjs can't even pass i128 as arguments or return values, so ignore it.
-// this will hopefully be fixed by the LLVM 5 upgrade (#43370)
-// ignore-asmjs
 // ignore-emscripten
 
 // compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=no
index b21158abfe551d53be911e1bbd635bdfce2f82eb..f1b4b4f5a0c8a05d16a6e2fe12fcb8db95577a51 100644 (file)
@@ -3,7 +3,7 @@
 #[prelude_import]
 use std::prelude::v1::*;
 #[macro_use]
-extern crate std as std;
+extern crate std;
 // 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.
@@ -21,4 +21,3 @@ extern crate std as std;
 macro_rules! negative(( $ e : expr ) => { $ e < 0 });
 
 fn main() { (1 as i32) < 0; }
-
index 87b5274545f385425b4b4ac682c7ef5c97bf587f..ca4c364c6315778aa8743534914c836001370c1e 100644 (file)
@@ -19,4 +19,3 @@ macro_rules! negative {
 fn main() {
       negative!(1 as i32);
 }
-
index 81518b0b87271c85d5168bc4ec076240a604ea35..a4380d9212fdf1e596fc25c7b72a611701bffd53 100644 (file)
@@ -1,7 +1,7 @@
 #[prelude_import]
 use std::prelude::v1::*;
 #[macro_use]
-extern crate std as std;
+extern crate std;
 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
diff --git a/src/test/run-fail/issue-51345.rs b/src/test/run-fail/issue-51345.rs
new file mode 100644 (file)
index 0000000..9efd081
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern: thread 'main' panicked at 'explicit panic'
+
+#![feature(nll)]
+
+fn main() {
+    let mut vec = vec![];
+    vec.push((vec.len(), panic!()));
+}
index f5480178db0d14aff54b2ed1898a11fcf705b9b0..efe1b7072ffb8f75a3d5460a67e100c6854af46a 100644 (file)
@@ -1,53 +1,47 @@
-
-# min-llvm-version 4.0
-# ignore-mingw
+# ignore-msvc
 
 -include ../tools.mk
 
-# This test makes sure that the expected .llvmbc sections for use by
-# linker-based LTO are available in object files when compiling with
-# -Z cross-lang-lto
-
-LLVMBC_SECTION_NAME=\\.llvmbc
-
-ifeq ($(UNAME),Darwin)
-       LLVMBC_SECTION_NAME=__bitcode
-endif
-
-
-OBJDUMP=llvm-objdump
-SECTION_HEADERS=$(OBJDUMP) -section-headers
+# This test makes sure that the object files we generate are actually
+# LLVM bitcode files (as used by linker LTO plugins) when compiling with
+# -Z cross-lang-lto.
 
-BUILD_LIB=$(RUSTC) lib.rs -Copt-level=2 -Z cross-lang-lto=no-link -Ccodegen-units=1
+ASSERT_IS_BITCODE_OBJ=llvm-bcanalyzer # this only succeeds for bitcode files
+EXTRACT_OBJS=(cd $(TMPDIR); rm -f ./*.o; llvm-ar x $(1))
 
-BUILD_EXE=$(RUSTC) main.rs -Copt-level=2 -Z cross-lang-lto=no-link -Ccodegen-units=1 --emit=obj
+BUILD_LIB=$(RUSTC) lib.rs -Copt-level=2 -Z cross-lang-lto=on -Ccodegen-units=1
+BUILD_EXE=$(RUSTC) main.rs -Copt-level=2 -Z cross-lang-lto=on -Ccodegen-units=1 --emit=obj
 
 all: staticlib staticlib-fat-lto staticlib-thin-lto rlib exe cdylib rdylib
 
 staticlib: lib.rs
        $(BUILD_LIB) --crate-type=staticlib -o $(TMPDIR)/liblib.a
-       [ "$$($(SECTION_HEADERS) $(TMPDIR)/liblib.a | grep -c $(LLVMBC_SECTION_NAME))" -ne "0" ]
+       $(call EXTRACT_OBJS, liblib.a)
+       $(ASSERT_IS_BITCODE_OBJ) $(TMPDIR)/liblib.lib0.rcgu.o
 
 staticlib-fat-lto: lib.rs
        $(BUILD_LIB) --crate-type=staticlib -o $(TMPDIR)/liblib-fat-lto.a -Clto=fat
-       [ "$$($(SECTION_HEADERS) $(TMPDIR)/liblib-fat-lto.a | grep -c $(LLVMBC_SECTION_NAME))" -ne "0" ]
+       $(call EXTRACT_OBJS, liblib-fat-lto.a)
+       $(ASSERT_IS_BITCODE_OBJ) $(TMPDIR)/liblib-fat-lto.lib0.rcgu.o
 
 staticlib-thin-lto: lib.rs
        $(BUILD_LIB) --crate-type=staticlib -o $(TMPDIR)/liblib-thin-lto.a -Clto=thin
-       [ "$$($(SECTION_HEADERS) $(TMPDIR)/liblib-thin-lto.a | grep -c $(LLVMBC_SECTION_NAME))" -ne "0" ]
+       $(call EXTRACT_OBJS, liblib-thin-lto.a)
+       $(ASSERT_IS_BITCODE_OBJ) $(TMPDIR)/liblib-thin-lto.lib0.rcgu.o
 
 rlib: lib.rs
        $(BUILD_LIB) --crate-type=rlib -o $(TMPDIR)/liblib.rlib
-       [ "$$($(SECTION_HEADERS) $(TMPDIR)/liblib.rlib | grep -c $(LLVMBC_SECTION_NAME))" -ne "0" ]
+       $(call EXTRACT_OBJS, liblib.rlib)
+       $(ASSERT_IS_BITCODE_OBJ) $(TMPDIR)/liblib.lib0.rcgu.o
 
 cdylib: lib.rs
        $(BUILD_LIB) --crate-type=cdylib --emit=obj -o $(TMPDIR)/cdylib.o
-       [ "$$($(SECTION_HEADERS) $(TMPDIR)/cdylib.o | grep -c $(LLVMBC_SECTION_NAME))" -ne "0" ]
+       $(ASSERT_IS_BITCODE_OBJ) $(TMPDIR)/cdylib.o
 
 rdylib: lib.rs
        $(BUILD_LIB) --crate-type=dylib --emit=obj -o $(TMPDIR)/rdylib.o
-       [ "$$($(SECTION_HEADERS) $(TMPDIR)/rdylib.o | grep -c $(LLVMBC_SECTION_NAME))" -ne "0" ]
+       $(ASSERT_IS_BITCODE_OBJ) $(TMPDIR)/rdylib.o
 
 exe: lib.rs
        $(BUILD_EXE) -o $(TMPDIR)/exe.o
-       [ "$$($(SECTION_HEADERS) $(TMPDIR)/exe.o | grep -c $(LLVMBC_SECTION_NAME))" -ne "0" ]
+       $(ASSERT_IS_BITCODE_OBJ) $(TMPDIR)/exe.o
index 2ddf3aa5439f62d4b0d3be11924d705da4fa5a6e..e203ec2737fc7f2cb67465461145e921cb61be7b 100644 (file)
@@ -4,6 +4,6 @@ all:
        /bin/echo || exit 0 # This test requires /bin/echo to exist
        $(RUSTC) the_backend.rs --crate-name the_backend --crate-type dylib \
                -o $(TMPDIR)/the_backend.dylib
-       $(RUSTC) some_crate.rs --crate-name some_crate --crate-type bin -o $(TMPDIR)/some_crate \
+       $(RUSTC) some_crate.rs --crate-name some_crate --crate-type lib -o $(TMPDIR)/some_crate \
                -Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options
        grep -x "This has been \"compiled\" successfully." $(TMPDIR)/some_crate
index 26ffce01b2e2c0516f319e9527829e6a904793e8..bfa8b6b3ef69a24af26f7f1bd216b9276dc68b83 100644 (file)
@@ -8,6 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main() {
-    ::std::process::exit(1);
-}
+#![feature(no_core)]
+#![no_core]
index 439bc017fee618ce357141a56618f8f07f2c47b3..a3cd033f86382ed00a78ddcffa21806e6e716c19 100644 (file)
@@ -63,7 +63,7 @@ fn join_codegen_and_link(
         let crate_name = ongoing_codegen.downcast::<Symbol>()
             .expect("in join_codegen_and_link: ongoing_codegen is not a Symbol");
         for &crate_type in sess.opts.crate_types.iter() {
-            if crate_type != CrateType::CrateTypeExecutable {
+            if crate_type != CrateType::CrateTypeRlib {
                 sess.fatal(&format!("Crate type is {:?}", crate_type));
             }
             let output_name =
index 720ce1512f26a8120c0beae2193bb0c441afdb4b..453602b800b5e546d7cecb9d7e4069885a04a8dd 100644 (file)
@@ -14,6 +14,7 @@
 #![no_main]
 #![no_std]
 
+use core::alloc::Layout;
 use core::panic::PanicInfo;
 
 #[panic_implementation]
@@ -25,4 +26,6 @@ fn panic(_: &PanicInfo) -> ! {
 fn eh() {}
 
 #[lang = "oom"]
-fn oom() {}
+fn oom(_: Layout) -> ! {
+    loop {}
+}
index 880c9bce5628f4a3b4d377bcb42a101ff23198c5..c0a17d920cffc91154ee4b0e22d473225a408b92 100644 (file)
@@ -28,12 +28,7 @@ namespace {
 
     bool runOnFunction(Function &F) override;
 
-#if LLVM_VERSION_MAJOR >= 4
-    StringRef
-#else
-    const char *
-#endif
-    getPassName() const override {
+    StringRef getPassName() const override {
       return "Some LLVM pass";
     }
 
index 280eca7e8f0155fe2c26f3960f6cf195c87a1eb9..70051681ab0350393a8f25eae75e5becce325974 100644 (file)
@@ -27,12 +27,7 @@ namespace {
 
     bool runOnModule(Module &M) override;
 
-#if LLVM_VERSION_MAJOR >= 4
-    StringRef
-#else
-    const char *
-#endif
-    getPassName() const override {
+    StringRef getPassName() const override {
       return "Some LLVM pass";
     }
 
index e8c695f52bec0def2d90598f874b94f247f3cddf..6ec2978058dfcbd606359bc13d6355dfdf38d338 100644 (file)
@@ -2,7 +2,9 @@
 
 all:
 ifeq ($(PROFILER_SUPPORT),1)
+ifndef IS_WINDOWS
        $(RUSTC) -Copt-level=3 -Clto=fat -Z pgo-gen="$(TMPDIR)/test.profraw" test.rs
        $(call RUN,test) || exit 1
        [ -e "$(TMPDIR)/test.profraw" ] || (echo "No .profraw file"; exit 1)
 endif
+endif
index 7dc227b5a145a342c3f3783151633a5f49f58965..96126ab7a79461453f4b318c21309f3260b6f350 100644 (file)
@@ -2,7 +2,9 @@
 
 all:
 ifeq ($(PROFILER_SUPPORT),1)
+ifndef IS_WINDOWS
        $(RUSTC) -g -Z pgo-gen="$(TMPDIR)/test.profraw" test.rs
        $(call RUN,test) || exit 1
        [ -e "$(TMPDIR)/test.profraw" ] || (echo "No .profraw file"; exit 1)
 endif
+endif
diff --git a/src/test/run-make-fulldeps/target-without-atomic-cas/Makefile b/src/test/run-make-fulldeps/target-without-atomic-cas/Makefile
new file mode 100644 (file)
index 0000000..c2eb4ca
--- /dev/null
@@ -0,0 +1,5 @@
+-include ../tools.mk
+
+# The target used below doesn't support atomic CAS operations. Verify that's the case
+all:
+       $(RUSTC) --print cfg --target thumbv6m-none-eabi | $(CGREP) -v 'target_has_atomic="cas"'
diff --git a/src/test/run-make-fulldeps/target-without-atomics/Makefile b/src/test/run-make-fulldeps/target-without-atomics/Makefile
deleted file mode 100644 (file)
index c5f575d..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
--include ../tools.mk
-
-# The target used below doesn't support atomic operations. Verify that's the case
-all:
-       $(RUSTC) --print cfg --target thumbv6m-none-eabi | $(CGREP) -v target_has_atomic
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/custom-attr-only-one-derive.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/custom-attr-only-one-derive.rs
new file mode 100644 (file)
index 0000000..4609f57
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(Foo)]
+pub fn foo(a: TokenStream) -> TokenStream {
+    "".parse().unwrap()
+}
+
+#[proc_macro_derive(Bar, attributes(custom))]
+pub fn bar(a: TokenStream) -> TokenStream {
+    "".parse().unwrap()
+}
diff --git a/src/test/run-pass-fulldeps/proc-macro/custom-attr-only-one-derive.rs b/src/test/run-pass-fulldeps/proc-macro/custom-attr-only-one-derive.rs
new file mode 100644 (file)
index 0000000..3b2833a
--- /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.
+
+// aux-build:custom-attr-only-one-derive.rs
+
+#![feature(rust_2018_preview)]
+
+#[macro_use]
+extern crate custom_attr_only_one_derive;
+
+#[derive(Bar, Foo)]
+#[custom = "test"]
+pub enum A {
+    B,
+    C,
+}
+
+fn main() {}
diff --git a/src/test/run-pass/borrowck/borrowck-slice-pattern-element-loan.rs b/src/test/run-pass/borrowck/borrowck-slice-pattern-element-loan.rs
new file mode 100644 (file)
index 0000000..48d1610
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//compile-flags: -Z borrowck=mir
+
+#![feature(slice_patterns)]
+
+fn mut_head_tail<'a, A>(v: &'a mut [A]) -> Option<(&'a mut A, &'a mut [A])> {
+    match *v {
+        [ref mut head, ref mut tail..] => {
+            Some((head, tail))
+        }
+        [] => None
+    }
+}
+
+fn main() {
+    let mut v = [1,2,3,4];
+    match mut_head_tail(&mut v) {
+        None => {},
+        Some((h,t)) => {
+            *h = 1000;
+            t.reverse();
+        }
+    }
+}
diff --git a/src/test/run-pass/default-alloc-error-hook.rs b/src/test/run-pass/default-alloc-error-hook.rs
new file mode 100644 (file)
index 0000000..5f6b60a
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-cloudabi no processes
+// ignore-emscripten no processes
+
+use std::alloc::{Layout, handle_alloc_error};
+use std::env;
+use std::process::Command;
+use std::str;
+
+fn main() {
+    if env::args().len() > 1 {
+        handle_alloc_error(Layout::new::<[u8; 42]>())
+    }
+
+    let me = env::current_exe().unwrap();
+    let output = Command::new(&me).arg("next").output().unwrap();
+    assert!(!output.status.success(), "{:?} is a success", output.status);
+    assert_eq!(str::from_utf8(&output.stderr).unwrap(), "memory allocation of 42 bytes failed");
+}
diff --git a/src/test/run-pass/hygiene/arguments.rs b/src/test/run-pass/hygiene/arguments.rs
deleted file mode 100644 (file)
index 5d9e186..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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.
-
-// ignore-pretty pretty-printing is unhygienic
-
-#![feature(decl_macro)]
-
-macro m($t:ty, $e:expr) {
-    mod foo {
-        #[allow(unused)]
-        struct S;
-        pub(super) fn f(_: $t) {}
-    }
-    foo::f($e);
-}
-
-fn main() {
-    struct S;
-    m!(S, S);
-}
index feb4a88a1d1e15b0ff8d35be92c71895514b0a49..c1f3b2028aa7ef5df27fccd497b75172baba91da 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // check that we don't have linear stack usage with multiple calls to `push`
-// min-llvm-version 4.0
 
 #![feature(test)]
 
diff --git a/src/test/run-pass/issue-51345.rs b/src/test/run-pass/issue-51345.rs
new file mode 100644 (file)
index 0000000..7d39294
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(nll)]
+
+fn main() {
+    let mut v = Vec::new();
+
+    loop { v.push(break) }
+}
diff --git a/src/test/run-pass/issue-51907.rs b/src/test/run-pass/issue-51907.rs
new file mode 100644 (file)
index 0000000..de2a59c
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Foo {
+    extern fn borrow(&self);
+    extern fn take(self: Box<Self>);
+}
+
+struct Bar;
+impl Foo for Bar {
+    extern fn borrow(&self) {}
+    extern fn take(self: Box<Self>) {}
+}
+
+fn main() {
+    let foo: Box<dyn Foo> = Box::new(Bar);
+    foo.borrow();
+    foo.take()
+}
index 4597674b3f1d2d953be005d90714813ac3e74379..3c7ca21459f461be245a23af453af958151bff55 100644 (file)
     fn simd_fpowi<T>(x: T, y: i32) -> T;
 }
 
+macro_rules! assert_approx_eq_f32 {
+    ($a:expr, $b:expr) => ({
+        let (a, b) = (&$a, &$b);
+        assert!((*a - *b).abs() < 1.0e-6,
+                "{} is not approximately equal to {}", *a, *b);
+    })
+}
+macro_rules! assert_approx_eq {
+    ($a:expr, $b:expr) => ({
+        let a = $a;
+        let b = $b;
+        assert_approx_eq_f32!(a.0, b.0);
+        assert_approx_eq_f32!(a.1, b.1);
+        assert_approx_eq_f32!(a.2, b.2);
+        assert_approx_eq_f32!(a.3, b.3);
+    })
+}
+
 fn main() {
     let x = f32x4(1.0, 1.0, 1.0, 1.0);
     let y = f32x4(-1.0, -1.0, -1.0, -1.0);
@@ -50,45 +68,45 @@ fn main() {
 
     unsafe {
         let r = simd_fabs(y);
-        assert_eq!(x, r);
+        assert_approx_eq!(x, r);
 
         let r = simd_fcos(z);
-        assert_eq!(x, r);
+        assert_approx_eq!(x, r);
 
         let r = simd_ceil(h);
-        assert_eq!(x, r);
+        assert_approx_eq!(x, r);
 
         let r = simd_fexp(z);
-        assert_eq!(x, r);
+        assert_approx_eq!(x, r);
 
         let r = simd_fexp2(z);
-        assert_eq!(x, r);
+        assert_approx_eq!(x, r);
 
         let r = simd_floor(h);
-        assert_eq!(z, r);
+        assert_approx_eq!(z, r);
 
         let r = simd_fma(x, h, h);
-        assert_eq!(x, r);
+        assert_approx_eq!(x, r);
 
         let r = simd_fsqrt(x);
-        assert_eq!(x, r);
+        assert_approx_eq!(x, r);
 
         let r = simd_flog(x);
-        assert_eq!(z, r);
+        assert_approx_eq!(z, r);
 
         let r = simd_flog2(x);
-        assert_eq!(z, r);
+        assert_approx_eq!(z, r);
 
         let r = simd_flog10(x);
-        assert_eq!(z, r);
+        assert_approx_eq!(z, r);
 
         let r = simd_fpow(h, x);
-        assert_eq!(h, r);
+        assert_approx_eq!(h, r);
 
         let r = simd_fpowi(h, 1);
-        assert_eq!(h, r);
+        assert_approx_eq!(h, r);
 
         let r = simd_fsin(z);
-        assert_eq!(z, r);
+        assert_approx_eq!(z, r);
     }
 }
index 9a1214d3b35e5b7ac4ac2e2b022f961a739bc34b..8e999b7115ea13ee71292444870138f04a687934 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// min-llvm-version 5.0
 // ignore-emscripten
 
 // Test that the simd_reduce_{op} intrinsics produce the correct results.
index 3fef19c51bd288722bb95fb8ec7a3cb765102f99..ff5413ce06ca05384c6cd6a913f767f2bd42575c 100644 (file)
@@ -21,7 +21,6 @@
 // ignore-emscripten no processes
 // ignore-musl FIXME #31506
 // ignore-pretty
-// min-system-llvm-version 5.0
 // compile-flags: -C lto
 // no-prefer-dynamic
 
index c93dcf019397b34eef0a91adc26ec9a92f805dd2..1334ab8dc63780346d99252995c20c19aef8bf89 100644 (file)
@@ -20,7 +20,6 @@
 // ignore-cloudabi no processes
 // ignore-emscripten no processes
 // ignore-musl FIXME #31506
-// min-system-llvm-version 5.0
 
 use std::mem;
 use std::process::Command;
index 3a0e2fe01db055ce62388095eca1225f80ae01a6..257d5bbc30677e2f5658fe5dc165c1673d3b37c1 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // compile-flags: -Z thinlto -C codegen-units=2
-// min-llvm-version 4.0
 
 #[global_allocator]
 static A: std::alloc::System = std::alloc::System;
index 772a9ec8293e4becbb76955de1d059473206ee70..8d68202d71176922148a0cb12bb60f1ddeb15237 100644 (file)
@@ -10,7 +10,6 @@
 
 // compile-flags: -Clto=thin
 // no-prefer-dynamic
-// min-llvm-version 4.0
 
 fn main() {
     println!("hello!");
index 3f54519d0d8ceb23a17463a84419a31065a0ce73..06df40f61427d4db537eded2401b4ece6d81afe1 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:dylib.rs
-// min-llvm-version 4.0
 
 extern crate dylib;
 
index 8329c7032f1b695b04ffaff630c8c1e87804e76e..95cff2a28620743cee6c41b7ae0d7843688fb9df 100644 (file)
@@ -10,7 +10,6 @@
 
 // aux-build:msvc-imp-present.rs
 // compile-flags: -Z thinlto -C codegen-units=8
-// min-llvm-version: 4.0
 // no-prefer-dynamic
 
 // On MSVC we have a "hack" where we emit symbols that look like `_imp_$name`
index 7a71dd2bc5125f080d7c0e9804f561cc2f96fc01..41ca983af51c7810ae72726d90e44b47b67defa9 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // compile-flags: -Z thinlto -C codegen-units=8 -O
-// min-llvm-version 4.0
 // ignore-emscripten can't inspect instructions on emscripten
 
 // We want to assert here that ThinLTO will inline across codegen units. There's
index 6020f72415dad2740d2d543a8ec2c4fef1a7d29e..3c0e904662a3534e871f2ae95621fcbe5df96bc2 100644 (file)
@@ -10,7 +10,6 @@
 
 // compile-flags: -C codegen-units=8 -O -C lto=thin
 // aux-build:thin-lto-inlines-aux.rs
-// min-llvm-version 4.0
 // no-prefer-dynamic
 // ignore-emscripten can't inspect instructions on emscripten
 
index b9719e04f34470b6e67804bf5e95a58be11a7a2f..0a1b7307a46ff705ca48bb8b1a3014c9f1806c33 100644 (file)
@@ -10,7 +10,6 @@
 
 // compile-flags: -C codegen-units=8 -Z thinlto
 // ignore-windows
-// min-llvm-version 4.0
 
 #![feature(linkage)]
 
diff --git a/src/test/run-pass/tool_lints.rs b/src/test/run-pass/tool_lints.rs
new file mode 100644 (file)
index 0000000..24ec43b
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(tool_lints)]
+#![deny(unknown_lints)]
+
+#[allow(clippy::almost_swapped)]
+fn main() {}
diff --git a/src/test/run-pass/tool_lints_2018_preview.rs b/src/test/run-pass/tool_lints_2018_preview.rs
new file mode 100644 (file)
index 0000000..6cd57ea
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(tool_lints)]
+#![feature(rust_2018_preview)]
+#![deny(unknown_lints)]
+
+#[allow(clippy::almost_swapped)]
+fn main() {}
diff --git a/src/test/run-pass/weak-new-uninhabited-issue-48493.rs b/src/test/run-pass/weak-new-uninhabited-issue-48493.rs
new file mode 100644 (file)
index 0000000..eb57c12
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    enum Void {}
+    std::rc::Weak::<Void>::new();
+    std::sync::Weak::<Void>::new();
+}
index a15fbf377ecf67780c1b2fc45f565bb4366943df..35120e428a7bd3d508103707da582cebd2ee66a8 100644 (file)
@@ -10,6 +10,8 @@
 
 // compile-flags: -Z borrowck=compare
 
+#![recursion_limit = "128"]
+
 use std::cell::Cell;
 use std::mem::swap;
 
@@ -121,6 +123,16 @@ fn special_characters() {
     assert!(!val);
 }
 
+fn punch_card() -> impl std::fmt::Debug {
+    ..=..=.. ..    .. .. .. ..    .. .. .. ..    .. ..=.. ..
+    ..=.. ..=..    .. .. .. ..    .. .. .. ..    ..=..=..=..
+    ..=.. ..=..    ..=.. ..=..    .. ..=..=..    .. ..=.. ..
+    ..=..=.. ..    ..=.. ..=..    ..=.. .. ..    .. ..=.. ..
+    ..=.. ..=..    ..=.. ..=..    .. ..=.. ..    .. ..=.. ..
+    ..=.. ..=..    ..=.. ..=..    .. .. ..=..    .. ..=.. ..
+    ..=.. ..=..    .. ..=..=..    ..=..=.. ..    .. ..=.. ..
+}
+
 pub fn main() {
     strange();
     funny();
@@ -135,4 +147,5 @@ pub fn main() {
     fishy();
     union();
     special_characters();
+    punch_card();
 }
diff --git a/src/test/rustdoc-ui/unused.rs b/src/test/rustdoc-ui/unused.rs
new file mode 100644 (file)
index 0000000..8b53098
--- /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.
+
+// compile-pass
+
+// This test purpose is to check that unused_imports lint isn't fired
+// by rustdoc. Why would it? Because when rustdoc is running, it uses
+// "everybody-loops" which replaces parts of code with "loop {}" to get
+// huge performance improvements.
+
+#![deny(unused_imports)]
+
+use std::fs::File;
+
+pub fn f() {
+    let _: File;
+}
diff --git a/src/test/rustdoc/constructor-imports.rs b/src/test/rustdoc/constructor-imports.rs
new file mode 100644 (file)
index 0000000..c170ead
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "foo"]
+
+pub mod a {
+    pub struct Foo;
+    pub enum Bar {
+        Baz,
+    }
+}
+
+// @count 'foo/index.html' '//*[code="pub use a::Foo;"]' 1
+#[doc(no_inline)]
+pub use a::Foo;
+// @count 'foo/index.html' '//*[code="pub use a::Bar::Baz;"]' 1
+#[doc(no_inline)]
+pub use a::Bar::Baz;
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/rustdoc/short-dockblock.rs b/src/test/rustdoc/short-dockblock.rs
new file mode 100644 (file)
index 0000000..cb36110
--- /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.
+
+#![crate_name = "foo"]
+
+// @has foo/index.html '//*[@class="docblock-short"]/p' 'fooo'
+// @!has foo/index.html '//*[@class="docblock-short"]/p/h1' 'fooo'
+// @has foo/fn.foo.html '//h1[@id="fooo"]/a[@href="#fooo"]' 'fooo'
+
+/// # fooo
+///
+/// foo
+pub fn foo() {}
+
+// @has foo/index.html '//*[@class="docblock-short"]/p' 'mooood'
+// @!has foo/index.html '//*[@class="docblock-short"]/p/h2' 'mooood'
+// @has foo/foo/index.html '//h2[@id="mooood"]/a[@href="#mooood"]' 'mooood'
+
+/// ## mooood
+///
+/// foo mod
+pub mod foo {}
+
+// @has foo/index.html '//*[@class="docblock-short"]/p/a[@href=\
+//                      "https://nougat.world"]/code' 'nougat'
+
+/// [`nougat`](https://nougat.world)
+pub struct Bar;
diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/generate-mod.rs b/src/test/ui-fulldeps/proc-macro/auxiliary/generate-mod.rs
new file mode 100644 (file)
index 0000000..6a8d545
--- /dev/null
@@ -0,0 +1,54 @@
+// 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.
+
+// run-pass
+// no-prefer-dynamic
+
+#![feature(proc_macro)]
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro]
+pub fn check(_: TokenStream) -> TokenStream {
+    "
+    type Alias = FromOutside; // OK
+    struct Outer;
+    mod inner {
+        type Alias = FromOutside; // `FromOutside` shouldn't be available from here
+        type Inner = Outer; // `Outer` shouldn't be available from here
+    }
+    ".parse().unwrap()
+}
+
+#[proc_macro_attribute]
+pub fn check_attr(_: TokenStream, _: TokenStream) -> TokenStream {
+    "
+    type AliasAttr = FromOutside; // OK
+    struct OuterAttr;
+    mod inner_attr {
+        type Alias = FromOutside; // `FromOutside` shouldn't be available from here
+        type Inner = OuterAttr; // `OuterAttr` shouldn't be available from here
+    }
+    ".parse().unwrap()
+}
+
+#[proc_macro_derive(CheckDerive)]
+pub fn check_derive(_: TokenStream) -> TokenStream {
+    "
+    type AliasDerive = FromOutside; // OK
+    struct OuterDerive;
+    mod inner_derive {
+        type Alias = FromOutside; // `FromOutside` shouldn't be available from here
+        type Inner = OuterDerive; // `OuterDerive` shouldn't be available from here
+    }
+    ".parse().unwrap()
+}
diff --git a/src/test/ui-fulldeps/proc-macro/generate-mod.rs b/src/test/ui-fulldeps/proc-macro/generate-mod.rs
new file mode 100644 (file)
index 0000000..ff64421
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Modules generated by transparent proc macros still acts as barriers for names (issue #50504).
+
+// aux-build:generate-mod.rs
+
+#![feature(proc_macro, proc_macro_gen, proc_macro_path_invoc)]
+
+extern crate generate_mod;
+
+struct FromOutside;
+
+generate_mod::check!(); //~ ERROR cannot find type `FromOutside` in this scope
+                        //~| ERROR cannot find type `Outer` in this scope
+
+#[generate_mod::check_attr] //~ ERROR cannot find type `FromOutside` in this scope
+                            //~| ERROR cannot find type `OuterAttr` in this scope
+struct S;
+
+#[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside` in this scope
+                                     //~| WARN cannot find type `OuterDerive` in this scope
+                                     //~| WARN this was previously accepted
+                                     //~| WARN this was previously accepted
+struct Z;
+
+fn main() {}
diff --git a/src/test/ui-fulldeps/proc-macro/generate-mod.stderr b/src/test/ui-fulldeps/proc-macro/generate-mod.stderr
new file mode 100644 (file)
index 0000000..c024aef
--- /dev/null
@@ -0,0 +1,46 @@
+error[E0412]: cannot find type `FromOutside` in this scope
+  --> $DIR/generate-mod.rs:21:1
+   |
+LL | generate_mod::check!(); //~ ERROR cannot find type `FromOutside` in this scope
+   | ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
+
+error[E0412]: cannot find type `Outer` in this scope
+  --> $DIR/generate-mod.rs:21:1
+   |
+LL | generate_mod::check!(); //~ ERROR cannot find type `FromOutside` in this scope
+   | ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
+
+error[E0412]: cannot find type `FromOutside` in this scope
+  --> $DIR/generate-mod.rs:24:1
+   |
+LL | #[generate_mod::check_attr] //~ ERROR cannot find type `FromOutside` in this scope
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
+
+error[E0412]: cannot find type `OuterAttr` in this scope
+  --> $DIR/generate-mod.rs:24:1
+   |
+LL | #[generate_mod::check_attr] //~ ERROR cannot find type `FromOutside` in this scope
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
+
+warning: cannot find type `FromOutside` in this scope
+  --> $DIR/generate-mod.rs:28:10
+   |
+LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside` in this scope
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
+   |
+   = note: #[warn(proc_macro_derive_resolution_fallback)] on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #50504 <https://github.com/rust-lang/rust/issues/50504>
+
+warning: cannot find type `OuterDerive` in this scope
+  --> $DIR/generate-mod.rs:28:10
+   |
+LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside` in this scope
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #50504 <https://github.com/rust-lang/rust/issues/50504>
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui-fulldeps/proc-macro/invalid-attributes.rs b/src/test/ui-fulldeps/proc-macro/invalid-attributes.rs
new file mode 100644 (file)
index 0000000..c06f98e
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+#![feature(proc_macro)]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro = "test"] //~ ERROR: does not take any arguments
+pub fn a(a: TokenStream) -> TokenStream { a }
+
+#[proc_macro()] //~ ERROR: does not take any arguments
+pub fn c(a: TokenStream) -> TokenStream { a }
+
+#[proc_macro(x)] //~ ERROR: does not take any arguments
+pub fn d(a: TokenStream) -> TokenStream { a }
+
+#[proc_macro_attribute = "test"] //~ ERROR: does not take any arguments
+pub fn e(_: TokenStream, a: TokenStream) -> TokenStream { a }
+
+#[proc_macro_attribute()] //~ ERROR: does not take any arguments
+pub fn g(_: TokenStream, a: TokenStream) -> TokenStream { a }
+
+#[proc_macro_attribute(x)] //~ ERROR: does not take any arguments
+pub fn h(_: TokenStream, a: TokenStream) -> TokenStream { a }
diff --git a/src/test/ui-fulldeps/proc-macro/invalid-attributes.stderr b/src/test/ui-fulldeps/proc-macro/invalid-attributes.stderr
new file mode 100644 (file)
index 0000000..c480bcb
--- /dev/null
@@ -0,0 +1,38 @@
+error: `#[proc_macro]` attribute does not take any arguments
+  --> $DIR/invalid-attributes.rs:20:1
+   |
+LL | #[proc_macro = "test"] //~ ERROR: does not take any arguments
+   | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[proc_macro]` attribute does not take any arguments
+  --> $DIR/invalid-attributes.rs:23:1
+   |
+LL | #[proc_macro()] //~ ERROR: does not take any arguments
+   | ^^^^^^^^^^^^^^^
+
+error: `#[proc_macro]` attribute does not take any arguments
+  --> $DIR/invalid-attributes.rs:26:1
+   |
+LL | #[proc_macro(x)] //~ ERROR: does not take any arguments
+   | ^^^^^^^^^^^^^^^^
+
+error: `#[proc_macro_attribute]` attribute does not take any arguments
+  --> $DIR/invalid-attributes.rs:29:1
+   |
+LL | #[proc_macro_attribute = "test"] //~ ERROR: does not take any arguments
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[proc_macro_attribute]` attribute does not take any arguments
+  --> $DIR/invalid-attributes.rs:32:1
+   |
+LL | #[proc_macro_attribute()] //~ ERROR: does not take any arguments
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[proc_macro_attribute]` attribute does not take any arguments
+  --> $DIR/invalid-attributes.rs:35:1
+   |
+LL | #[proc_macro_attribute(x)] //~ ERROR: does not take any arguments
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
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`.
diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs
new file mode 100644 (file)
index 0000000..da36f49
--- /dev/null
@@ -0,0 +1,137 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//compile-flags: -Z borrowck=mir
+
+#![feature(slice_patterns)]
+
+fn nop(_s: &[& i32]) {}
+fn nop_subslice(_s: &[i32]) {}
+
+fn const_index_ok(s: &mut [i32]) {
+    if let [ref first, ref second, _, ref fourth, ..] = *s {
+        if let [_, _, ref mut third, ..] = *s {
+            nop(&[first, second, third, fourth]);
+        }
+    }
+}
+
+fn const_index_err(s: &mut [i32]) {
+    if let [ref first, ref second, ..] = *s {
+        if let [_, ref mut  second2, ref mut third, ..] = *s { //~ERROR
+            nop(&[first, second, second2, third]);
+        }
+    }
+}
+
+fn const_index_from_end_ok(s: &mut [i32]) {
+    if let [.., ref fourth, ref third, _, ref first] = *s {
+        if let [.., ref mut second, _] = *s {
+            nop(&[first, second, third, fourth]);
+        }
+    }
+}
+
+fn const_index_from_end_err(s: &mut [i32]) {
+    if let [.., ref fourth, ref third, _, ref first] = *s {
+        if let [.., ref mut third2, _, _] = *s { //~ERROR
+            nop(&[first, third, third2, fourth]);
+        }
+    }
+}
+
+fn const_index_mixed(s: &mut [i32]) {
+    if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s {
+        if let [ref mut from_begin0, ..] = *s {
+            nop(&[from_begin0, from_end1, from_end3, from_end4]);
+        }
+        if let [_, ref mut from_begin1, ..] = *s { //~ERROR
+            nop(&[from_begin1, from_end1, from_end3, from_end4]);
+        }
+        if let [_, _, ref mut from_begin2, ..] = *s { //~ERROR
+            nop(&[from_begin2, from_end1, from_end3, from_end4]);
+        }
+        if let [_, _, _, ref mut from_begin3, ..] = *s { //~ERROR
+            nop(&[from_begin3, from_end1, from_end3, from_end4]);
+        }
+    }
+    if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s {
+        if let [.., ref mut from_end1] = *s {
+            nop(&[from_begin0, from_begin1, from_begin3, from_end1]);
+        }
+        if let [.., ref mut from_end2, _] = *s { //~ERROR
+            nop(&[from_begin0, from_begin1, from_begin3, from_end2]);
+        }
+        if let [.., ref mut from_end3, _,  _] = *s { //~ERROR
+            nop(&[from_begin0, from_begin1, from_begin3, from_end3]);
+        }
+        if let [.., ref mut from_end4, _, _, _] = *s { //~ERROR
+            nop(&[from_begin0, from_begin1, from_begin3, from_end4]);
+        }
+    }
+}
+
+fn const_index_and_subslice_ok(s: &mut [i32]) {
+    if let [ref first, ref second, ..] = *s {
+        if let [_, _, ref mut tail..] = *s {
+            nop(&[first, second]);
+            nop_subslice(tail);
+        }
+    }
+}
+
+fn const_index_and_subslice_err(s: &mut [i32]) {
+    if let [ref first, ref second, ..] = *s {
+        if let [_, ref mut tail..] = *s { //~ERROR
+            nop(&[first, second]);
+            nop_subslice(tail);
+        }
+    }
+}
+
+fn const_index_and_subslice_from_end_ok(s: &mut [i32]) {
+    if let [.., ref second, ref first] = *s {
+        if let [ref mut tail.., _, _] = *s {
+            nop(&[first, second]);
+            nop_subslice(tail);
+        }
+    }
+}
+
+fn const_index_and_subslice_from_end_err(s: &mut [i32]) {
+    if let [.., ref second, ref first] = *s {
+        if let [ref mut tail.., _] = *s { //~ERROR
+            nop(&[first, second]);
+            nop_subslice(tail);
+        }
+    }
+}
+
+fn subslices(s: &mut [i32]) {
+    if let [_, _, _, ref s1..] = *s {
+        if let [ref mut s2.., _, _, _] = *s { //~ERROR
+            nop_subslice(s1);
+            nop_subslice(s2);
+        }
+    }
+}
+
+fn main() {
+    let mut v = [1,2,3,4];
+    const_index_ok(&mut v);
+    const_index_err(&mut v);
+    const_index_from_end_ok(&mut v);
+    const_index_from_end_err(&mut v);
+    const_index_and_subslice_ok(&mut v);
+    const_index_and_subslice_err(&mut v);
+    const_index_and_subslice_from_end_ok(&mut v);
+    const_index_and_subslice_from_end_err(&mut v);
+    subslices(&mut v);
+}
diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr
new file mode 100644 (file)
index 0000000..16d401e
--- /dev/null
@@ -0,0 +1,119 @@
+error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-slice-pattern-element-loan.rs:28:20
+   |
+LL |     if let [ref first, ref second, ..] = *s {
+   |                        ---------- immutable borrow occurs here
+LL |         if let [_, ref mut  second2, ref mut third, ..] = *s { //~ERROR
+   |                    ^^^^^^^^^^^^^^^^ mutable borrow occurs here
+LL |             nop(&[first, second, second2, third]);
+   |                          ------ borrow later used here
+
+error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-slice-pattern-element-loan.rs:44:21
+   |
+LL |     if let [.., ref fourth, ref third, _, ref first] = *s {
+   |                             --------- immutable borrow occurs here
+LL |         if let [.., ref mut third2, _, _] = *s { //~ERROR
+   |                     ^^^^^^^^^^^^^^ mutable borrow occurs here
+LL |             nop(&[first, third, third2, fourth]);
+   |                          ----- borrow later used here
+
+error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-slice-pattern-element-loan.rs:55:20
+   |
+LL |     if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s {
+   |                    ------------- immutable borrow occurs here
+...
+LL |         if let [_, ref mut from_begin1, ..] = *s { //~ERROR
+   |                    ^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
+LL |             nop(&[from_begin1, from_end1, from_end3, from_end4]);
+   |                                                      --------- borrow later used here
+
+error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-slice-pattern-element-loan.rs:58:23
+   |
+LL |     if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s {
+   |                                   ------------- immutable borrow occurs here
+...
+LL |         if let [_, _, ref mut from_begin2, ..] = *s { //~ERROR
+   |                       ^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
+LL |             nop(&[from_begin2, from_end1, from_end3, from_end4]);
+   |                                           --------- borrow later used here
+
+error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-slice-pattern-element-loan.rs:61:26
+   |
+LL |     if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s {
+   |                                   ------------- immutable borrow occurs here
+...
+LL |         if let [_, _, _, ref mut from_begin3, ..] = *s { //~ERROR
+   |                          ^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
+LL |             nop(&[from_begin3, from_end1, from_end3, from_end4]);
+   |                                           --------- borrow later used here
+
+error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-slice-pattern-element-loan.rs:69:21
+   |
+LL |     if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s {
+   |                                                  --------------- immutable borrow occurs here
+...
+LL |         if let [.., ref mut from_end2, _] = *s { //~ERROR
+   |                     ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
+LL |             nop(&[from_begin0, from_begin1, from_begin3, from_end2]);
+   |                                             ----------- borrow later used here
+
+error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-slice-pattern-element-loan.rs:72:21
+   |
+LL |     if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s {
+   |                                                  --------------- immutable borrow occurs here
+...
+LL |         if let [.., ref mut from_end3, _,  _] = *s { //~ERROR
+   |                     ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
+LL |             nop(&[from_begin0, from_begin1, from_begin3, from_end3]);
+   |                                             ----------- borrow later used here
+
+error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-slice-pattern-element-loan.rs:75:21
+   |
+LL |     if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s {
+   |                              --------------- immutable borrow occurs here
+...
+LL |         if let [.., ref mut from_end4, _, _, _] = *s { //~ERROR
+   |                     ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
+LL |             nop(&[from_begin0, from_begin1, from_begin3, from_end4]);
+   |                                ----------- borrow later used here
+
+error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-slice-pattern-element-loan.rs:92:20
+   |
+LL |     if let [ref first, ref second, ..] = *s {
+   |                        ---------- immutable borrow occurs here
+LL |         if let [_, ref mut tail..] = *s { //~ERROR
+   |                    ^^^^^^^^^^^^ mutable borrow occurs here
+LL |             nop(&[first, second]);
+   |                          ------ borrow later used here
+
+error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-slice-pattern-element-loan.rs:110:17
+   |
+LL |     if let [.., ref second, ref first] = *s {
+   |                 ---------- immutable borrow occurs here
+LL |         if let [ref mut tail.., _] = *s { //~ERROR
+   |                 ^^^^^^^^^^^^ mutable borrow occurs here
+LL |             nop(&[first, second]);
+   |                          ------ borrow later used here
+
+error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-slice-pattern-element-loan.rs:119:17
+   |
+LL |     if let [_, _, _, ref s1..] = *s {
+   |                      ------ immutable borrow occurs here
+LL |         if let [ref mut s2.., _, _, _] = *s { //~ERROR
+   |                 ^^^^^^^^^^ mutable borrow occurs here
+LL |             nop_subslice(s1);
+   |                          -- borrow later used here
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0502`.
index a008a408d97112116774c66e4b3234f24c7896d1..68a039262c129310dba029023d6ee39b3cf5844e 100644 (file)
@@ -4,11 +4,15 @@ warning: not reporting region error due to nll
 LL |     give_any(|y| x = Some(y));
    |                           ^
 
-error: free region `` does not outlive free region `'_#2r`
-  --> $DIR/issue-45983.rs:17:27
+error: unsatisfied lifetime constraints
+  --> $DIR/issue-45983.rs:17:18
    |
+LL |     let x = None;
+   |         - lifetime `'2` appears in the type of `x`
 LL |     give_any(|y| x = Some(y));
-   |                           ^
+   |               -  ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
+   |               |
+   |               lifetime `'1` appears in this argument
 
 error[E0594]: cannot assign to immutable item `x`
   --> $DIR/issue-45983.rs:17:18
index 84c6236eb0ae87c0e7c4f53cac0c8d45af014fd2..5904e98753694a894369ed34ec88fae166766fb8 100644 (file)
@@ -4,11 +4,17 @@ warning: not reporting region error due to nll
 LL |     let mut lines_to_use: Vec<&CrateId> = Vec::new();
    |                               ^
 
-error: free region `` does not outlive free region `'_#2r`
+error: unsatisfied lifetime constraints
   --> $DIR/issue-7573.rs:32:9
    |
+LL |     let mut lines_to_use: Vec<&CrateId> = Vec::new();
+   |         ---------------- lifetime `'2` appears in the type of `lines_to_use`
+LL |         //~^ NOTE cannot infer an appropriate lifetime
+LL |     let push_id = |installed_id: &CrateId| {
+   |                                  - let's call the lifetime of this reference `'1`
+...
 LL |         lines_to_use.push(installed_id);
-   |         ^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
 
 error: aborting due to previous error
 
index ee3970aa8fd8f09425b01ea1c46d043d462f2c94..4f7843b72489c9524f7a9178c0e6917c7a5d833b 100644 (file)
@@ -4,11 +4,15 @@ warning: not reporting region error due to nll
 LL |     with_int(|y| x = Some(y));
    |                           ^
 
-error: free region `` does not outlive free region `'_#2r`
-  --> $DIR/regions-escape-bound-fn-2.rs:18:27
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-escape-bound-fn-2.rs:18:18
    |
+LL |     let mut x = None;
+   |         ----- lifetime `'2` appears in the type of `x`
 LL |     with_int(|y| x = Some(y));
-   |                           ^
+   |               -  ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
+   |               |
+   |               lifetime `'1` appears in this argument
 
 error: aborting due to previous error
 
index 07a4ab1dbb1abc5f16f25fcc207c315af7fd5125..9b107ae08b477ef2040d040dbcb5cd92da96ea7b 100644 (file)
@@ -4,11 +4,15 @@ warning: not reporting region error due to nll
 LL |     with_int(|y| x = Some(y));
    |                      ^^^^^^^
 
-error: free region `` does not outlive free region `'_#2r`
-  --> $DIR/regions-escape-bound-fn.rs:18:27
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-escape-bound-fn.rs:18:18
    |
+LL |     let mut x: Option<&isize> = None;
+   |         ----- lifetime `'2` appears in the type of `x`
 LL |     with_int(|y| x = Some(y));
-   |                           ^
+   |               -  ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
+   |               |
+   |               lifetime `'1` appears in this argument
 
 error: aborting due to previous error
 
index 14c255ef52778f249b5b46a470fad71beac3852e..8095330154d4c87ad819935c9444b487015d1387 100644 (file)
@@ -4,11 +4,15 @@ warning: not reporting region error due to nll
 LL |     with_int(&mut |y| x = Some(y));
    |                           ^^^^^^^
 
-error: free region `` does not outlive free region `'_#2r`
-  --> $DIR/regions-escape-unboxed-closure.rs:16:32
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-escape-unboxed-closure.rs:16:23
    |
+LL |     let mut x: Option<&isize> = None;
+   |         ----- lifetime `'2` appears in the type of `x`
 LL |     with_int(&mut |y| x = Some(y));
-   |                                ^
+   |                    -  ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
+   |                    |
+   |                    lifetime `'1` appears in this argument
 
 error: aborting due to previous error
 
index 3a280f85e76949e0e862df6135838f7a74e1ecf4..d6673f6a8a6fb6b77b506d79f4438ac9f11378a4 100644 (file)
@@ -4,9 +4,10 @@ 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).
+   = note: WellFormed(Self: Bar) :- Implemented(Self: Bar), WellFormed(Self: Foo), WellFormed(Self: Foo).
 
 error: program clause dump
   --> $DIR/lower_env1.rs:19:1
@@ -14,11 +15,14 @@ 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).
    = note: Implemented(Self: std::marker::Sized) :- FromEnv(Self: std::marker::Sized).
+   = note: WellFormed(Self: Bar) :- Implemented(Self: Bar), WellFormed(Self: Foo), WellFormed(Self: Foo).
+   = note: WellFormed(Self: Foo) :- Implemented(Self: Foo).
+   = note: WellFormed(Self: std::marker::Sized) :- Implemented(Self: std::marker::Sized).
 
 error: aborting due to 2 previous errors
 
index 55cd9699b06164de3fc62518a0c2c3666748d854..c4e768415d60b5501ff5156f6c8a26b8bbab1b0d 100644 (file)
@@ -8,6 +8,7 @@ LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
    = note: FromEnv(T: std::marker::Sized) :- FromEnv(Self: Foo<S, T, U>).
    = note: FromEnv(U: std::marker::Sized) :- FromEnv(Self: Foo<S, T, U>).
    = note: Implemented(Self: Foo<S, T, U>) :- FromEnv(Self: Foo<S, T, U>).
+   = note: WellFormed(Self: Foo<S, T, U>) :- Implemented(Self: Foo<S, T, U>), WellFormed(S: std::marker::Sized), WellFormed(T: std::marker::Sized), WellFormed(U: std::marker::Sized).
 
 error: aborting due to previous error
 
index ea275d647fa7c143fb66a355d8853c1355906656..afb2cd4b563329aa8e07f57de163ac70aeb9aa34 100644 (file)
@@ -8,6 +8,7 @@ LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
    = note: FromEnv(F: std::ops::Fn<(&'a (u8, u16),)>) :- FromEnv(Self: Foo<F>).
    = note: Implemented(Self: Foo<F>) :- FromEnv(Self: Foo<F>).
    = note: ProjectionEq(<F as std::ops::FnOnce<(&'a (u8, u16),)>>::Output == &'a u8) :- FromEnv(Self: Foo<F>).
+   = note: WellFormed(Self: Foo<F>) :- Implemented(Self: Foo<F>), WellFormed(F: std::marker::Sized), forall<> { WellFormed(F: std::ops::Fn<(&'a (u8, u16),)>) }, forall<> { ProjectionEq(<F as std::ops::FnOnce<(&'a (u8, u16),)>>::Output == &'a u8) }.
 
 error: aborting due to previous error
 
index 68bc2ddf2930ebf3276b15d7393eba89f6f1fb3f..5ea397d424b63986b885c9c10fb5f5bf7a768611 100644 (file)
@@ -11,6 +11,7 @@ LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
    = note: Implemented(Self: Foo<'a, 'b, S, T, U>) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
    = note: RegionOutlives('a : 'b) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
    = note: TypeOutlives(U : 'b) :- FromEnv(Self: Foo<'a, 'b, S, T, U>).
+   = note: WellFormed(Self: Foo<'a, 'b, S, T, U>) :- Implemented(Self: Foo<'a, 'b, S, T, U>), WellFormed(S: std::marker::Sized), WellFormed(T: std::marker::Sized), WellFormed(S: std::fmt::Debug), WellFormed(T: std::borrow::Borrow<U>), RegionOutlives('a : 'b), TypeOutlives(U : 'b).
 
 error: aborting due to previous error
 
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 bbae80e16abde58b1914acc0b9fea094c062561c..c8c8ef8215ae28a7a2a9cfdd392a01cba6132735 100644 (file)
@@ -22,23 +22,37 @@ warning: not reporting region error due to nll
 LL |         f = Some(x);
    |             ^^^^^^^
 
-error: free region `` does not outlive free region `'_#2r`
-  --> $DIR/expect-region-supply-region.rs:28:18
+error: unsatisfied lifetime constraints
+  --> $DIR/expect-region-supply-region.rs:28:9
    |
+LL |     let mut f: Option<&u32> = None;
+   |         ----- lifetime `'2` appears in the type of `f`
+LL |     closure_expecting_bound(|x| {
+   |                              - lifetime `'1` appears in this argument
 LL |         f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure
-   |                  ^
+   |         ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
 
-error: free region `` does not outlive free region `'_#2r`
-  --> $DIR/expect-region-supply-region.rs:38:18
+error: unsatisfied lifetime constraints
+  --> $DIR/expect-region-supply-region.rs:38:9
    |
+LL |     let mut f: Option<&u32> = None;
+   |         ----- lifetime `'2` appears in the type of `f`
+LL |     closure_expecting_bound(|x: &u32| {
+   |                                 - let's call the lifetime of this reference `'1`
 LL |         f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure
-   |                  ^
+   |         ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
 
-error: free region `` does not outlive free region `'_#2r`
-  --> $DIR/expect-region-supply-region.rs:52:18
+error: unsatisfied lifetime constraints
+  --> $DIR/expect-region-supply-region.rs:52:9
    |
+LL |     let mut f: Option<&u32> = None;
+   |         ----- lifetime `'2` appears in the type of `f`
+...
+LL |     closure_expecting_bound(|x: &'x u32| {
+   |                                 - let's call the lifetime of this reference `'1`
+...
 LL |         f = Some(x);
-   |                  ^
+   |         ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
 
 error: aborting due to 3 previous errors
 
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/const-eval/infinite_loop.rs b/src/test/ui/const-eval/infinite_loop.rs
new file mode 100644 (file)
index 0000000..a1f8ab7
--- /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.
+
+#![feature(const_let)]
+
+fn main() {
+    // Tests the Collatz conjecture with an incorrect base case (0 instead of 1).
+    // The value of `n` will loop indefinitely (4 - 2 - 1 - 4).
+    let _ = [(); {
+        //~^ WARNING Constant evaluating a complex constant, this might take some time
+        //~| ERROR could not evaluate repeat length
+        let mut n = 113383; // #20 in https://oeis.org/A006884
+        while n != 0 { //~ ERROR constant contains unimplemented expression type
+            n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
+        }
+        n
+    }];
+}
diff --git a/src/test/ui/const-eval/infinite_loop.stderr b/src/test/ui/const-eval/infinite_loop.stderr
new file mode 100644 (file)
index 0000000..f69aae2
--- /dev/null
@@ -0,0 +1,41 @@
+error[E0019]: constant contains unimplemented expression type
+  --> $DIR/infinite_loop.rs:20:9
+   |
+LL | /         while n != 0 { //~ ERROR constant contains unimplemented expression type
+LL | |             n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
+LL | |         }
+   | |_________^
+
+warning: Constant evaluating a complex constant, this might take some time
+  --> $DIR/infinite_loop.rs:16:18
+   |
+LL |       let _ = [(); {
+   |  __________________^
+LL | |         //~^ WARNING Constant evaluating a complex constant, this might take some time
+LL | |         //~| ERROR could not evaluate repeat length
+LL | |         let mut n = 113383; // #20 in https://oeis.org/A006884
+...  |
+LL | |         n
+LL | |     }];
+   | |_____^
+
+error[E0080]: could not evaluate repeat length
+  --> $DIR/infinite_loop.rs:16:18
+   |
+LL |       let _ = [(); {
+   |  __________________^
+LL | |         //~^ WARNING Constant evaluating a complex constant, this might take some time
+LL | |         //~| ERROR could not evaluate repeat length
+LL | |         let mut n = 113383; // #20 in https://oeis.org/A006884
+LL | |         while n != 0 { //~ ERROR constant contains unimplemented expression type
+LL | |             n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
+   | |                    ---------- duplicate interpreter state observed here, const evaluation will never terminate
+LL | |         }
+LL | |         n
+LL | |     }];
+   | |_____^
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0019, E0080.
+For more information about an error, try `rustc --explain E0019`.
index c0a367604c374be88f353433d4c2b54b5b47420d..39ac969b80e98e6f9fbf83924e12b27491ccc6b0 100644 (file)
 use std::fmt::Debug;
 
 const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 
 const CONST_FOO: str = *"foo";
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 
 static STATIC_1: Debug+Sync = *(&1 as &(Debug+Sync));
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 
 static STATIC_BAR: str = *"bar";
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 
 fn main() {
     println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR);
index d6fc5391ba83111c1f1c3f55461d65b3e99951dc..e0b31510260ddc4f9430572d051531a581422760 100644 (file)
@@ -1,4 +1,4 @@
-error[E0277]: the size for value values of type `(dyn std::fmt::Debug + std::marker::Sync + 'static)` cannot be known at compilation time
+error[E0277]: the size for values of type `(dyn std::fmt::Debug + std::marker::Sync + 'static)` cannot be known at compilation time
   --> $DIR/const-unsized.rs:13:29
    |
 LL | const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
@@ -8,7 +8,7 @@ LL | const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: constant expressions must have a statically known size
 
-error[E0277]: the size for value values of type `str` cannot be known at compilation time
+error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/const-unsized.rs:16:24
    |
 LL | const CONST_FOO: str = *"foo";
@@ -18,7 +18,7 @@ LL | const CONST_FOO: str = *"foo";
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: constant expressions must have a statically known size
 
-error[E0277]: the size for value values of type `(dyn std::fmt::Debug + std::marker::Sync + 'static)` cannot be known at compilation time
+error[E0277]: the size for values of type `(dyn std::fmt::Debug + std::marker::Sync + 'static)` cannot be known at compilation time
   --> $DIR/const-unsized.rs:19:31
    |
 LL | static STATIC_1: Debug+Sync = *(&1 as &(Debug+Sync));
@@ -28,7 +28,7 @@ LL | static STATIC_1: Debug+Sync = *(&1 as &(Debug+Sync));
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: constant expressions must have a statically known size
 
-error[E0277]: the size for value values of type `str` cannot be known at compilation time
+error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/const-unsized.rs:22:26
    |
 LL | static STATIC_BAR: str = *"bar";
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 ec31f5d05d787f6413bb19afeeeb32b4a5b8a6e9..addbbf4434f4f99cda802fd5f319acefb0642d90 100644 (file)
@@ -10,18 +10,18 @@ error[E0017]: references in statics may only refer to immutable values
 LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
    |                                       ^^^^^^ statics require immutable values
 
-error[E0017]: references in statics may only refer to immutable values
-  --> $DIR/E0017.rs:17:38
-   |
-LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
-   |                                      ^^^^^^ statics require immutable values
-
 error[E0596]: cannot borrow immutable item `X` as mutable
   --> $DIR/E0017.rs:15:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
    |                                       ^^^^^^ cannot borrow as mutable
 
+error[E0017]: references in statics may only refer to immutable values
+  --> $DIR/E0017.rs:17:38
+   |
+LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
+   |                                      ^^^^^^ statics require immutable values
+
 error: aborting due to 4 previous errors
 
 Some errors occurred: E0017, E0596.
index dc57a6274445f1eb64de577649f9a6b1dcf388dd..9be80f8f21baa4dcb6c8b62f2fa0a5c9cd035679 100644 (file)
@@ -1,8 +1,10 @@
-error[E0133]: call to unsafe function requires unsafe function or block
+error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
   --> $DIR/E0133.rs:14:5
    |
 LL |     f();
    |     ^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error: aborting due to previous error
 
index 95f10e7206f92ec7816fbe2d564f9f4d88bd7333..80cb5eb7a4bbc6e5ce3187384e1d618b5a41d9fa 100644 (file)
@@ -21,7 +21,7 @@ fn some_func<T: Foo>(foo: T) {
 }
 
 fn f(p: Path) { }
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 
 fn main() {
     some_func(5i32);
index ca5b0d2b987d6ac2c06c43c844ba070acd334c71..3ea057d79229d34cbd2cd668f78fabd263e8c9da 100644 (file)
@@ -1,4 +1,4 @@
-error[E0277]: the size for value values of type `[u8]` cannot be known at compilation time
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
   --> $DIR/E0277.rs:23:6
    |
 LL | fn f(p: Path) { }
index 6a4bd6b31a116675fb6b32c51c6a5a9fa18b7473..0238ca6b623da26ab44c7c91d11c7f624c785c50 100644 (file)
@@ -10,18 +10,18 @@ error[E0017]: references in statics may only refer to immutable values
 LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
    |                                       ^^^^^^ statics require immutable values
 
-error[E0017]: references in statics may only refer to immutable values
-  --> $DIR/E0388.rs:17:38
-   |
-LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
-   |                                      ^^^^^^ statics require immutable values
-
 error[E0596]: cannot borrow immutable item `X` as mutable
   --> $DIR/E0388.rs:15:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
    |                                       ^^^^^^ cannot borrow as mutable
 
+error[E0017]: references in statics may only refer to immutable values
+  --> $DIR/E0388.rs:17:38
+   |
+LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
+   |                                      ^^^^^^ statics require immutable values
+
 error: aborting due to 4 previous errors
 
 Some errors occurred: E0017, E0596.
index 5ae6afa7b17e274255daa5e811637a9c99fb7236..9c7e3db67a611a55676afa41b85e1ec1671e59ca 100644 (file)
@@ -4,11 +4,15 @@ warning: not reporting region error due to nll
 LL |     invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR E0495
    |     ^^^^^^
 
-error: free region `` does not outlive free region `'_#2r`
+error: unsatisfied lifetime constraints
   --> $DIR/E0621-does-not-trigger-for-closures.rs:25:26
    |
 LL |     invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR E0495
-   |                          ^^^^^
+   |                ----------^^^^^-----------------
+   |                |   |     |
+   |                |   |     free region requires that `'1` must outlive `'2`
+   |                |   lifetime `'1` appears in this argument
+   |                lifetime `'2` appears in return type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gate-tool_lints.rs b/src/test/ui/feature-gate-tool_lints.rs
new file mode 100644 (file)
index 0000000..3ef6798
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[warn(clippy::decimal_literal_representation)]
+//~^ ERROR scoped lint `clippy::decimal_literal_representation` is experimental
+fn main() {
+    let a = 65_535;
+}
diff --git a/src/test/ui/feature-gate-tool_lints.stderr b/src/test/ui/feature-gate-tool_lints.stderr
new file mode 100644 (file)
index 0000000..8019b1e
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0658]: scoped lint `clippy::decimal_literal_representation` is experimental (see issue #44690)
+  --> $DIR/feature-gate-tool_lints.rs:11:8
+   |
+LL | #[warn(clippy::decimal_literal_representation)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(tool_lints)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
index 19a6a8637957eb91de7eb2e4c15ea9d9ab5ae67d..52963671da9fb1c21c97b62e9767b96ca26484a1 100644 (file)
@@ -87,7 +87,7 @@ LL | | }
    = help: see issue #48214
    = help: add #![feature(trivial_bounds)] to the crate attributes to enable
 
-error[E0277]: the size for value values of type `str` cannot be known at compilation time
+error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/feature-gate-trivial_bounds.rs:62:1
    |
 LL | struct TwoStrs(str, str) where str: Sized; //~ ERROR
@@ -98,7 +98,7 @@ LL | struct TwoStrs(str, str) where str: Sized; //~ ERROR
    = help: see issue #48214
    = help: add #![feature(trivial_bounds)] to the crate attributes to enable
 
-error[E0277]: the size for value values of type `(dyn A + 'static)` cannot be known at compilation time
+error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time
   --> $DIR/feature-gate-trivial_bounds.rs:65:1
    |
 LL | / fn unsized_local() where Dst<A>: Sized { //~ ERROR
@@ -112,7 +112,7 @@ LL | | }
    = help: see issue #48214
    = help: add #![feature(trivial_bounds)] to the crate attributes to enable
 
-error[E0277]: the size for value values of type `str` cannot be known at compilation time
+error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/feature-gate-trivial_bounds.rs:69:1
    |
 LL | / fn return_str() -> str where str: Sized { //~ ERROR
index 02830a49f530fa41f033de8e2d72094ba119d8c4..5430f6b5825eb7b98eef187d2466fb293e4a18c6 100644 (file)
@@ -1,4 +1,4 @@
-error[E0658]: experimental attribute (see issue #51088)
+error[E0658]: experimental attribute (see issue #52090)
   --> $DIR/feature-gate-wasm_import_module.rs:11:1
    |
 LL | #[wasm_import_module = "test"] //~ ERROR: experimental
index efaee4095c1487a925c9437c992776004632c9a4..461da94dde0d07a52d3ac7d45e7ef4be395d3af0 100644 (file)
@@ -15,9 +15,9 @@
 fn main() {
    let s = String::from("foo");
    let mut gen = move || {
-   //~^ ERROR the size for value values of type
+   //~^ ERROR the size for values of type
        yield s[..];
    };
    unsafe { gen.resume(); }
-   //~^ ERROR the size for value values of type
+   //~^ ERROR the size for values of type
 }
index 2938268a804ae1dfeb598a8dfbc6fa506920ed3e..dfccd7c4d230b761eb9d86208589cc89273d83da 100644 (file)
@@ -1,9 +1,9 @@
-error[E0277]: the size for value values of type `str` cannot be known at compilation time
+error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/sized-yield.rs:17:26
    |
 LL |      let mut gen = move || {
    |  __________________________^
-LL | |    //~^ ERROR the size for value values of type
+LL | |    //~^ ERROR the size for values of type
 LL | |        yield s[..];
 LL | |    };
    | |____^ doesn't have a size known at compile-time
@@ -12,7 +12,7 @@ LL | |    };
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: the yield type of a generator must have a statically known size
 
-error[E0277]: the size for value values of type `str` cannot be known at compilation time
+error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/sized-yield.rs:21:17
    |
 LL |    unsafe { gen.resume(); }
diff --git a/src/test/ui/hygiene/arguments.rs b/src/test/ui/hygiene/arguments.rs
new file mode 100644 (file)
index 0000000..958133e
--- /dev/null
@@ -0,0 +1,27 @@
+// 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.
+
+// ignore-pretty pretty-printing is unhygienic
+
+#![feature(decl_macro)]
+
+macro m($t:ty, $e:expr) {
+    mod foo {
+        #[allow(unused)]
+        struct S;
+        pub(super) fn f(_: $t) {}
+    }
+    foo::f($e);
+}
+
+fn main() {
+    struct S;
+    m!(S, S); //~ ERROR cannot find type `S` in this scope
+}
diff --git a/src/test/ui/hygiene/arguments.stderr b/src/test/ui/hygiene/arguments.stderr
new file mode 100644 (file)
index 0000000..1b0c23e
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `S` in this scope
+  --> $DIR/arguments.rs:26:8
+   |
+LL |     m!(S, S); //~ ERROR cannot find type `S` in this scope
+   |        ^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
index 90409857deadcff726cf6d448c785344db44355e..2b2108558a0f385908c02d0b9b75a3f1afd8badd 100644 (file)
 
 #![feature(decl_macro, rustc_attrs)]
 
+macro genmod($FromOutside: ident, $Outer: ident) {
+    type A = $FromOutside;
+    struct $Outer;
+    mod inner {
+        type A = $FromOutside; // `FromOutside` shouldn't be available from here
+        type Inner = $Outer; // `Outer` shouldn't be available from here
+    }
+}
+
 #[rustc_transparent_macro]
-macro genmod() {
-    mod m {
-        type A = S; //~ ERROR cannot find type `S` in this scope
+macro genmod_transparent() {
+    type A = FromOutside;
+    struct Outer;
+    mod inner {
+        type A = FromOutside; //~ ERROR cannot find type `FromOutside` in this scope
+        type Inner = Outer; //~ ERROR cannot find type `Outer` in this scope
     }
 }
 
-struct S;
+macro_rules! genmod_legacy { () => {
+    type A = FromOutside;
+    struct Outer;
+    mod inner {
+        type A = FromOutside; //~ ERROR cannot find type `FromOutside` in this scope
+        type Inner = Outer; //~ ERROR cannot find type `Outer` in this scope
+    }
+}}
 
-genmod!();
+fn check() {
+    struct FromOutside;
+    genmod!(FromOutside, Outer); //~ ERROR cannot find type `FromOutside` in this scope
+                                 //~| ERROR cannot find type `Outer` in this scope
+}
+
+fn check_transparent() {
+    struct FromOutside;
+    genmod_transparent!();
+}
+
+fn check_legacy() {
+    struct FromOutside;
+    genmod_legacy!();
+}
index e79f8528c2cd7a42de0ca5064ab731190832cb70..0c5905c5acb4fdc9ba2f93595feabfc269f30b66 100644 (file)
@@ -1,17 +1,56 @@
-error[E0412]: cannot find type `S` in this scope
-  --> $DIR/generate-mod.rs:18:18
+error[E0412]: cannot find type `FromOutside` in this scope
+  --> $DIR/generate-mod.rs:45:13
    |
-LL |         type A = S; //~ ERROR cannot find type `S` in this scope
-   |                  ^ did you mean `A`?
+LL |     genmod!(FromOutside, Outer); //~ ERROR cannot find type `FromOutside` in this scope
+   |             ^^^^^^^^^^^ not found in this scope
+
+error[E0412]: cannot find type `Outer` in this scope
+  --> $DIR/generate-mod.rs:45:26
+   |
+LL |     genmod!(FromOutside, Outer); //~ ERROR cannot find type `FromOutside` in this scope
+   |                          ^^^^^ not found in this scope
+
+error[E0412]: cannot find type `FromOutside` in this scope
+  --> $DIR/generate-mod.rs:29:18
+   |
+LL |         type A = FromOutside; //~ ERROR cannot find type `FromOutside` in this scope
+   |                  ^^^^^^^^^^^ not found in this scope
+...
+LL |     genmod_transparent!();
+   |     ---------------------- in this macro invocation
+
+error[E0412]: cannot find type `Outer` in this scope
+  --> $DIR/generate-mod.rs:30:22
+   |
+LL |         type Inner = Outer; //~ ERROR cannot find type `Outer` in this scope
+   |                      ^^^^^ not found in this scope
+...
+LL |     genmod_transparent!();
+   |     ---------------------- in this macro invocation
+
+error[E0412]: cannot find type `FromOutside` in this scope
+  --> $DIR/generate-mod.rs:38:18
+   |
+LL |         type A = FromOutside; //~ ERROR cannot find type `FromOutside` in this scope
+   |                  ^^^^^^^^^^^ not found in this scope
+...
+LL |     genmod_legacy!();
+   |     ----------------- in this macro invocation
+
+error[E0412]: cannot find type `Outer` in this scope
+  --> $DIR/generate-mod.rs:39:22
+   |
+LL |         type Inner = Outer; //~ ERROR cannot find type `Outer` in this scope
+   |                      ^^^^^ not found in this scope
 ...
-LL | genmod!();
-   | ---------- in this macro invocation
+LL |     genmod_legacy!();
+   |     ----------------- in this macro invocation
 
 error[E0601]: `main` function not found in crate `generate_mod`
    |
    = note: consider adding a `main` function to `$DIR/generate-mod.rs`
 
-error: aborting due to 2 previous errors
+error: aborting due to 7 previous errors
 
 Some errors occurred: E0412, E0601.
 For more information about an error, try `rustc --explain E0412`.
index 7ba217061c66ee986911556a844bc7a0a52b94a0..9785ce6c0048eae04227e9dc0a34130237f751b9 100644 (file)
@@ -57,12 +57,26 @@ fn g() {
                 }
             }
         }
+        macro n_with_super($j:ident) {
+            mod test {
+                use super::*;
+                fn g() {
+                    let _: u32 = $i();
+                    let _: () = f();
+                    super::$j();
+                }
+            }
+        }
 
-        n!(f);
+        n!(f); //~ ERROR cannot find function `f` in this scope
+        n_with_super!(f);
         mod test2 {
             super::n! {
                 f //~ ERROR cannot find function `f` in this scope
             }
+            super::n_with_super! {
+                f
+            }
         }
     }
 }
index d77242e135ddec03b20fcf351460d2385ceffd61..7df2e31f9a752f79edac498a4564590ebd7f61a5 100644 (file)
@@ -30,13 +30,23 @@ LL | use bar::g;
    |
 LL | use foo::test2::test::g;
    |
-LL | use foo::test::g;
+LL | use foo::test2::test::g;
    |
 LL | use foo::test::g;
    |
+and 2 other candidates
+
+error[E0425]: cannot find function `f` in this scope
+  --> $DIR/globs.rs:71:12
+   |
+LL | n!(f);
+   | ------ in this macro invocation
+...
+LL |         n!(f); //~ ERROR cannot find function `f` in this scope
+   |            ^ not found in this scope
 
 error[E0425]: cannot find function `f` in this scope
-  --> $DIR/globs.rs:64:17
+  --> $DIR/globs.rs:75:17
    |
 LL | n!(f);
    | ------ in this macro invocation
@@ -44,6 +54,6 @@ LL | n!(f);
 LL |                 f //~ ERROR cannot find function `f` in this scope
    |                 ^ not found in this scope
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0425`.
index 7099316d694a2d4921bab1ce0c8887d6f2b232c9..4c0b3a5d93120efb01a67e854ff0980cdac80b05 100644 (file)
@@ -10,17 +10,19 @@ warning: not reporting region error due to nll
 LL |         self.x.iter().map(|a| a.0)
    |                ^^^^
 
-error: free region `` does not outlive free region `'static`
+error: unsatisfied lifetime constraints
   --> $DIR/static-return-lifetime-infered.rs:17:9
    |
+LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
+   |                         - let's call the lifetime of this reference `'1`
 LL |         self.x.iter().map(|a| a.0)
-   |         ^^^^^^^^^^^^^
+   |         ^^^^^^ cast requires that `'1` must outlive `'static`
 
-error: free region `'a` does not outlive free region `'static`
+error: unsatisfied lifetime constraints
   --> $DIR/static-return-lifetime-infered.rs:21:9
    |
 LL |         self.x.iter().map(|a| a.0)
-   |         ^^^^^^^^^^^^^
+   |         ^^^^^^ cast requires that `'a` must outlive `'static`
 
 error: aborting due to 2 previous errors
 
index 4cf7feddd46541376fbe52cd6b875e5cdf82d895..19e10ba6da8b99ec52b83297ab71d9998dff3dd2 100644 (file)
@@ -4,11 +4,11 @@ warning: not reporting region error due to nll
 LL |     static_val(x); //~ ERROR cannot infer
    |                ^
 
-error: free region `'a` does not outlive free region `'static`
+error: unsatisfied lifetime constraints
   --> $DIR/dyn-trait.rs:32:5
    |
 LL |     static_val(x); //~ ERROR cannot infer
-   |     ^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^ argument requires that `'a` must outlive `'static`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/include-macros/file.txt b/src/test/ui/include-macros/file.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/test/ui/include-macros/mismatched-types.rs b/src/test/ui/include-macros/mismatched-types.rs
new file mode 100644 (file)
index 0000000..aca1b07
--- /dev/null
@@ -0,0 +1,14 @@
+// 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() {
+    let b: &[u8] = include_str!("file.txt");    //~ ERROR mismatched types
+    let s: &str = include_bytes!("file.txt");   //~ ERROR mismatched types
+}
diff --git a/src/test/ui/include-macros/mismatched-types.stderr b/src/test/ui/include-macros/mismatched-types.stderr
new file mode 100644 (file)
index 0000000..05286f2
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+  --> $DIR/mismatched-types.rs:12:20
+   |
+LL |     let b: &[u8] = include_str!("file.txt");    //~ ERROR mismatched types
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^ expected slice, found str
+   |
+   = note: expected type `&[u8]`
+              found type `&'static str`
+
+error[E0308]: mismatched types
+  --> $DIR/mismatched-types.rs:13:19
+   |
+LL |     let s: &str = include_bytes!("file.txt");   //~ ERROR mismatched types
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected str, found array of 0 elements
+   |
+   = note: expected type `&str`
+              found type `&'static [u8; 0]`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issue-27060.rs b/src/test/ui/issue-27060.rs
new file mode 100644 (file)
index 0000000..f88c213
--- /dev/null
@@ -0,0 +1,43 @@
+// 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.
+
+#[repr(packed)]
+pub struct Good {
+    data: &'static u32,
+    data2: [&'static u32; 2],
+    aligned: [u8; 32],
+}
+
+#[repr(packed)]
+pub struct JustArray {
+    array: [u32]
+}
+
+#[deny(safe_packed_borrows)]
+fn main() {
+    let good = Good {
+        data: &0,
+        data2: [&0, &0],
+        aligned: [0; 32]
+    };
+
+    unsafe {
+        let _ = &good.data; // ok
+        let _ = &good.data2[0]; // ok
+    }
+
+    let _ = &good.data; //~ ERROR borrow of packed field is unsafe
+                        //~| hard error
+    let _ = &good.data2[0]; //~ ERROR borrow of packed field is unsafe
+                            //~| hard error
+    let _ = &*good.data; // ok, behind a pointer
+    let _ = &good.aligned; // ok, has align 1
+    let _ = &good.aligned[2]; // ok, has align 1
+}
diff --git a/src/test/ui/issue-27060.stderr b/src/test/ui/issue-27060.stderr
new file mode 100644 (file)
index 0000000..bd01f75
--- /dev/null
@@ -0,0 +1,27 @@
+error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
+  --> $DIR/issue-27060.rs:36:13
+   |
+LL |     let _ = &good.data; //~ ERROR borrow of packed field is unsafe
+   |             ^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/issue-27060.rs:23:8
+   |
+LL | #[deny(safe_packed_borrows)]
+   |        ^^^^^^^^^^^^^^^^^^^
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
+   = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
+
+error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
+  --> $DIR/issue-27060.rs:38:13
+   |
+LL |     let _ = &good.data2[0]; //~ ERROR borrow of packed field is unsafe
+   |             ^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
+   = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
+
+error: aborting due to 2 previous errors
+
index 3b468a882054433e4023d6a94575294a754bc12f..aef0d9cd1d8c6bba1267a8490c8d56e38a2acf09 100644 (file)
@@ -1,8 +1,10 @@
-error[E0133]: call to unsafe function requires unsafe function or block
+error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
   --> $DIR/issue-28776.rs:14:5
    |
 LL |     (&ptr::write)(1 as *mut _, 42);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error: aborting due to previous error
 
index f6847097dbe980798fad5ee8e1366730216b1413..c64d5c68a79b0f1f69bb7c3b315510515e06d608 100644 (file)
@@ -3,6 +3,8 @@ error: expected item, found `;`
    |
 LL | }; //~ ERROR expected item, found `;`
    |  ^ help: consider removing this semicolon
+   |
+   = help: braced struct declarations are not followed by a semicolon
 
 error: aborting due to previous error
 
index a9eb33f01e3e014a90b7cc107defa3fe45006c51..32a9783e9c213137c4ec9064c12aaa6586d26ca5 100644 (file)
@@ -2,10 +2,9 @@ error[E0597]: borrowed value does not live long enough
   --> $DIR/issue-47184.rs:14:44
    |
 LL |     let _vec: Vec<&'static String> = vec![&String::new()];
-   |                                            ^^^^^^^^^^^^^ temporary value does not live long enough
-LL |     //~^ ERROR borrowed value does not live long enough [E0597]
-LL | }
-   | - temporary value only lives until here
+   |                                            ^^^^^^^^^^^^^ - temporary value only lives until here
+   |                                            |
+   |                                            temporary value does not live long enough
    |
    = note: borrowed value must be valid for the static lifetime...
 
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`.
index 578ff4ab9d4ad0a3ade41d7d5793270a6f1b74c5..0bfb060f84416783187b263866d6aa886b2d34f2 100644 (file)
@@ -3,6 +3,10 @@ error: expected a literal
    |
 LL |     println!(3 + 4); //~ ERROR expected a literal
    |              ^^^^^
+help: you might be missing a string literal to format with
+   |
+LL |     println!("{}", 3 + 4); //~ ERROR expected a literal
+   |              ^^^^^^^^^^^
 
 error: aborting due to previous error
 
index d76c4a015a2c2f5236ee0b5598f54d28d4110dba..6be6bb4391ae67068fccabf4023274da6e273075 100644 (file)
@@ -60,7 +60,7 @@ fn main()
 
     let _ = 42usize as *const [u8]; //~ ERROR is invalid
     let _ = v as *const [u8]; //~ ERROR cannot cast
-    let _ = fat_v as *const Foo; //~ ERROR the size for value values of type
+    let _ = fat_v as *const Foo; //~ ERROR the size for values of type
     let _ = foo as *const str; //~ ERROR is invalid
     let _ = foo as *mut str; //~ ERROR is invalid
     let _ = main as *mut str; //~ ERROR is invalid
@@ -69,7 +69,7 @@ fn main()
     let _ = fat_sv as usize; //~ ERROR is invalid
 
     let a : *const str = "hello";
-    let _ = a as *const Foo; //~ ERROR the size for value values of type
+    let _ = a as *const Foo; //~ ERROR the size for values of type
 
     // check no error cascade
     let _ = main.f as *const u32; //~ ERROR no field
index 9335795f6b8f322c0d3d0e6355f6ff61d0a025c1..ef877d6e04e07cb14646bbd492e6794787496eae 100644 (file)
@@ -216,20 +216,20 @@ LL |     let _ = cf as *const Bar; //~ ERROR is invalid
    |
    = note: vtable kinds may not match
 
-error[E0277]: the size for value values of type `[u8]` cannot be known at compilation time
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
   --> $DIR/cast-rfc0401.rs:63:13
    |
-LL |     let _ = fat_v as *const Foo; //~ ERROR the size for value values of type
+LL |     let _ = fat_v as *const Foo; //~ ERROR the size for values of type
    |             ^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `[u8]`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: required for the cast to the object type `dyn Foo`
 
-error[E0277]: the size for value values of type `str` cannot be known at compilation time
+error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/cast-rfc0401.rs:72:13
    |
-LL |     let _ = a as *const Foo; //~ ERROR the size for value values of type
+LL |     let _ = a as *const Foo; //~ ERROR the size for values of type
    |             ^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
diff --git a/src/test/ui/missing-alloc_error_handler.rs b/src/test/ui/missing-alloc_error_handler.rs
new file mode 100644 (file)
index 0000000..3842d48
--- /dev/null
@@ -0,0 +1,33 @@
+// 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.
+
+// compile-flags: -C panic=abort
+// no-prefer-dynamic
+
+#![no_std]
+#![crate_type = "staticlib"]
+#![feature(panic_implementation, alloc_error_handler, alloc)]
+
+#[panic_implementation]
+fn panic(_: &core::panic::PanicInfo) -> ! {
+    loop {}
+}
+
+extern crate alloc;
+
+#[global_allocator]
+static A: MyAlloc = MyAlloc;
+
+struct MyAlloc;
+
+unsafe impl core::alloc::GlobalAlloc for MyAlloc {
+    unsafe fn alloc(&self, _: core::alloc::Layout) -> *mut u8 { 0 as _ }
+    unsafe fn dealloc(&self, _: *mut u8, _: core::alloc::Layout) {}
+}
diff --git a/src/test/ui/missing-alloc_error_handler.stderr b/src/test/ui/missing-alloc_error_handler.stderr
new file mode 100644 (file)
index 0000000..5489b2c
--- /dev/null
@@ -0,0 +1,4 @@
+error: `#[alloc_error_handler]` function required, but not found
+
+error: aborting due to previous error
+
index 24282631b7eead69381a764e5c5f34852b39ed05..c949dcb635aad5ccbc0bf998cb06531515e109b1 100644 (file)
 
 #![no_std]
 #![crate_type = "staticlib"]
-#![feature(panic_implementation, lang_items, alloc)]
+#![feature(panic_implementation, alloc_error_handler, alloc)]
 
 #[panic_implementation]
 fn panic(_: &core::panic::PanicInfo) -> ! {
     loop {}
 }
 
-#[lang = "oom"]
-fn oom() {}
+#[alloc_error_handler]
+fn oom(_: core::alloc::Layout) -> ! {
+    loop {}
+}
 
 extern crate alloc;
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
+
index 1e168028c7c9a9c48f2be595d7eb6026ae445ccf..78208d6d7db7d0c0f7df7bab15af4735dd88333f 100644 (file)
@@ -34,7 +34,7 @@ fn test() {
     {
         let y = 22;
         let mut closure = expect_sig(|p, y| *p = y);
-        //~^ ERROR does not outlive free region
+        //~^ ERROR
         //~| WARNING not reporting region error due to nll
         closure(&mut p, &y);
     }
index 067b5ebc6c4addc7740103e23446f6eb8baff3db..d6f542183603ec522f9cce71ea9312659b47a7c9 100644 (file)
@@ -4,11 +4,14 @@ warning: not reporting region error due to nll
 LL |         let mut closure = expect_sig(|p, y| *p = y);
    |                                                  ^
 
-error: free region `ReFree(DefId(0/1:9 ~ escape_argument_callee[317d]::test[0]::{{closure}}[0]), BrAnon(3))` does not outlive free region `ReFree(DefId(0/1:9 ~ escape_argument_callee[317d]::test[0]::{{closure}}[0]), BrAnon(2))`
+error: unsatisfied lifetime constraints
   --> $DIR/escape-argument-callee.rs:36:45
    |
 LL |         let mut closure = expect_sig(|p, y| *p = y);
-   |                                             ^^^^^^
+   |                                       -  -  ^^^^^^ free region requires that `'1` must outlive `'2`
+   |                                       |  |
+   |                                       |  lifetime `'1` appears in this argument
+   |                                       lifetime `'2` appears in this argument
 
 note: No external requirements
   --> $DIR/escape-argument-callee.rs:36:38
index e7ec0b9684d2c980d785f8b7a6093e6e521a6ae0..b879f9a33986d0b8c184a73f28d9378f38fa3aaa 100644 (file)
@@ -54,8 +54,7 @@ fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell
             // Only works if 'x: 'y:
             let p = x.get();
             //~^ WARN not reporting region error due to nll
-            //~| ERROR does not outlive free region
-            demand_y(x, y, p)
+            demand_y(x, y, p) //~ ERROR
         },
     );
 }
index c88f0efba6f4b6192f76692242950c6f6d08d91f..a7a50a3a029817e099b4a2433a4ac47608c4f135 100644 (file)
@@ -4,11 +4,16 @@ warning: not reporting region error due to nll
 LL |             let p = x.get();
    |                     ^^^^^^^
 
-error: free region `ReFree(DefId(0/1:20 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]::{{closure}}[0]), BrAnon(1))` does not outlive free region `ReFree(DefId(0/1:20 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]::{{closure}}[0]), BrAnon(2))`
-  --> $DIR/propagate-approximated-fail-no-postdom.rs:55:17
+error: unsatisfied lifetime constraints
+  --> $DIR/propagate-approximated-fail-no-postdom.rs:57:13
    |
-LL |             let p = x.get();
-   |                 ^
+LL |         |_outlives1, _outlives2, _outlives3, x, y| {
+   |          ----------              ---------- lifetime `'2` appears in this argument
+   |          |
+   |          lifetime `'1` appears in this argument
+...
+LL |             demand_y(x, y, p) //~ ERROR
+   |             ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
 
 note: No external requirements
   --> $DIR/propagate-approximated-fail-no-postdom.rs:53:9
@@ -17,8 +22,7 @@ LL | /         |_outlives1, _outlives2, _outlives3, x, y| {
 LL | |             // Only works if 'x: 'y:
 LL | |             let p = x.get();
 LL | |             //~^ WARN not reporting region error due to nll
-LL | |             //~| ERROR does not outlive free region
-LL | |             demand_y(x, y, p)
+LL | |             demand_y(x, y, p) //~ ERROR
 LL | |         },
    | |_________^
    |
index 5a71e75d4b2cd7e3d86f4af2adfa28896deb40b3..a8ab41cebacced2fd79e17c78990ff081618567a 100644 (file)
@@ -31,7 +31,7 @@ fn case1() {
     foo(cell, |cell_a, cell_x| {
         //~^ WARNING not reporting region error due to nll
         cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
-        //~^ ERROR argument requires that data must outlive free region
+        //~^ ERROR
     })
 }
 
index 656c1b46a3ce5341c55ecf0cd0dfd841d50ae0c5..96f3d6a6a533ab69ce8cde1c86487c072ed76632 100644 (file)
@@ -4,11 +4,16 @@ warning: not reporting region error due to nll
 LL |     foo(cell, |cell_a, cell_x| {
    |     ^^^
 
-error: argument requires that data must outlive free region `'_#1r`
-  --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:33:20
+error: unsatisfied lifetime constraints
+  --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:33:9
    |
+LL |     foo(cell, |cell_a, cell_x| {
+   |                ------  ------ lifetime `'1` appears in this argument
+   |                |
+   |                lifetime `'2` appears in this argument
+LL |         //~^ WARNING not reporting region error due to nll
 LL |         cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
-   |                    ^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
 
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:31:15
@@ -17,7 +22,7 @@ LL |       foo(cell, |cell_a, cell_x| {
    |  _______________^
 LL | |         //~^ WARNING not reporting region error due to nll
 LL | |         cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
-LL | |         //~^ ERROR argument requires that data must outlive free region
+LL | |         //~^ ERROR
 LL | |     })
    | |_____^
    |
index b25b0e25df2111ccad22c867b8a1d3a5993ed49c..26faccdde71aee990210966ee6eba507cc3dcb5c 100644 (file)
@@ -43,7 +43,7 @@ fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u3
 #[rustc_regions]
 fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-        //~^ ERROR argument requires that data must outlive free region
+        //~^ ERROR
 
         // Only works if 'x: 'y:
         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
index 40f215619c68904994ef8eff152bad23a7d577c0..f65e7161ca8c5e058654246bd5371a56c6d04097 100644 (file)
@@ -9,7 +9,7 @@ note: External requirements
    |
 LL |       establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
    |  _______________________________________________^
-LL | |         //~^ ERROR argument requires that data must outlive free region
+LL | |         //~^ ERROR
 LL | |
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
@@ -23,23 +23,23 @@ LL | |     });
    = note: number of external vids: 2
    = note: where '_#1r: '_#0r
 
-error: argument requires that data must outlive free region `ReStatic`
+error: unsatisfied lifetime constraints
   --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:5
    |
 LL | /     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-LL | |         //~^ ERROR argument requires that data must outlive free region
+LL | |         //~^ ERROR
 LL | |
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
 LL | |     });
-   | |______^
+   | |______^ argument requires that `'a` must outlive `'static`
 
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:44:1
    |
 LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
 LL | |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-LL | |         //~^ ERROR argument requires that data must outlive free region
+LL | |         //~^ ERROR
 LL | |
 ...  |
 LL | |     });
index db9951bcc0f213f7b774646f5ccda247908a5311..703d60371cdfc43f74cd8aab05859b243a6e9c2e 100644 (file)
@@ -46,7 +46,7 @@ fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u3
 #[rustc_regions]
 fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-        //~^ ERROR argument requires that data must outlive free region
+        //~^ ERROR
         // Only works if 'x: 'y:
         demand_y(x, y, x.get())
         //~^ WARNING not reporting region error due to nll
index d89ff028a504293fd01a6d71fb98eff02cc8e48e..f1b2c9f198d69d4474e2d29d4fb0e2eee48748da 100644 (file)
@@ -9,7 +9,7 @@ note: External requirements
    |
 LL |       establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
    |  _______________________________________________^
-LL | |         //~^ ERROR argument requires that data must outlive free region
+LL | |         //~^ ERROR
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
 LL | |         //~^ WARNING not reporting region error due to nll
@@ -23,23 +23,23 @@ LL | |     });
    = note: number of external vids: 3
    = note: where '_#1r: '_#0r
 
-error: argument requires that data must outlive free region `ReStatic`
+error: unsatisfied lifetime constraints
   --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:5
    |
 LL | /     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-LL | |         //~^ ERROR argument requires that data must outlive free region
+LL | |         //~^ ERROR
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
 LL | |         //~^ WARNING not reporting region error due to nll
 LL | |     });
-   | |______^
+   | |______^ argument requires that `'a` must outlive `'static`
 
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:47:1
    |
 LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
 LL | |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-LL | |         //~^ ERROR argument requires that data must outlive free region
+LL | |         //~^ ERROR
 LL | |         // Only works if 'x: 'y:
 ...  |
 LL | |     });
index 316268e7e726dffcc69eaf59e76320e3a857eeb5..4b1f5231b3e878bb4f49510a2352ff24873c89c1 100644 (file)
@@ -46,7 +46,7 @@ fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
         // Only works if 'x: 'y:
         demand_y(x, y, x.get())
         //~^ WARN not reporting region error due to nll
-        //~| ERROR argument requires that data must outlive free region
+        //~| ERROR
     });
 }
 
index 74c0576e03b628f5055a3926f9b88a4057988ec4..fb98c506c7d280a913b785441d731b06f4f7c1d7 100644 (file)
@@ -4,11 +4,16 @@ warning: not reporting region error due to nll
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: argument requires that data must outlive free region `ReFree(DefId(0/1:18 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]::{{closure}}[0]), BrAnon(2))`
+error: unsatisfied lifetime constraints
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:9
    |
+LL |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
+   |                                                ---------  - lifetime `'1` appears in this argument
+   |                                                |
+   |                                                lifetime `'2` appears in this argument
+LL |         // Only works if 'x: 'y:
 LL |         demand_y(x, y, x.get())
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
 
 note: No external requirements
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:45:47
@@ -18,7 +23,7 @@ LL |       establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
 LL | |         //~^ WARN not reporting region error due to nll
-LL | |         //~| ERROR argument requires that data must outlive free region
+LL | |         //~| ERROR
 LL | |     });
    | |_____^
    |
index afb61b221be942394a2e011734a7a0ae1fda1bda..62a20c1bfe76ef5893aed0c59338b6e420375fdf 100644 (file)
@@ -50,7 +50,7 @@ fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
         // Only works if 'x: 'y:
         demand_y(x, y, x.get())
         //~^ WARN not reporting region error due to nll
-        //~| ERROR does not outlive free region
+        //~| ERROR
     });
 }
 
index 2fd6ce50095fc15be47af685158640eef93c8a36..73d39a8502b6438060cf366c70aad478c2dd4daa 100644 (file)
@@ -4,11 +4,16 @@ warning: not reporting region error due to nll
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: free region `ReFree(DefId(0/1:18 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]::{{closure}}[0]), BrAnon(2))` does not outlive free region `ReFree(DefId(0/1:18 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]::{{closure}}[0]), BrAnon(4))`
-  --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:18
+error: unsatisfied lifetime constraints
+  --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:9
    |
+LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
+   |                                                ----------  ---------- lifetime `'2` appears in this argument
+   |                                                |
+   |                                                lifetime `'1` appears in this argument
+LL |         // Only works if 'x: 'y:
 LL |         demand_y(x, y, x.get())
-   |                  ^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
 
 note: No external requirements
   --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:49:47
@@ -18,7 +23,7 @@ LL |       establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x,
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
 LL | |         //~^ WARN not reporting region error due to nll
-LL | |         //~| ERROR does not outlive free region
+LL | |         //~| ERROR
 LL | |     });
    | |_____^
    |
index dedbd8df41b130ca8d771fcd71418e092cffa38e..b5e8c95bc13b7c0601021185f6da26584222ee29 100644 (file)
@@ -18,7 +18,7 @@
 fn foo<'a>(x: &'a u32) -> &'static u32 {
     &*x
         //~^ WARN not reporting region error due to nll
-        //~| ERROR does not outlive free region
+        //~| ERROR
 }
 
 fn main() { }
index 9520b446303c3fc8c06cef12e97ebb099734f082..d012dca25271c62af9e2a6ccd4fbfac91dd8bf9a 100644 (file)
@@ -4,11 +4,11 @@ warning: not reporting region error due to nll
 LL |     &*x
    |     ^^^
 
-error: free region `ReFree(DefId(0/0:3 ~ region_lbr_named_does_not_outlive_static[317d]::foo[0]), BrNamed(crate0:DefIndex(1:9), 'a))` does not outlive free region `ReStatic`
+error: unsatisfied lifetime constraints
   --> $DIR/region-lbr-named-does-not-outlive-static.rs:19:5
    |
 LL |     &*x
-   |     ^^^
+   |     ^^^ free region requires that `'a` must outlive `'static`
 
 error: aborting due to previous error
 
index 60f82ca0eefb9a9a5add36cfb845cdb9739a6bd5..d88729d04d95bb733c777a33d89af9b8fdc52607 100644 (file)
@@ -20,7 +20,7 @@
 fn test() {
     expect_sig(|a, b| b); // ought to return `a`
     //~^ WARN not reporting region error due to nll
-    //~| ERROR does not outlive free region
+    //~| ERROR
 }
 
 fn expect_sig<F>(f: F) -> F
index 04ff4aaadf875bc036b78aa8a53a65af70f7b214..5724cdbd8c95be1fb5f557863315c69626baacdf 100644 (file)
@@ -4,11 +4,14 @@ warning: not reporting region error due to nll
 LL |     expect_sig(|a, b| b); // ought to return `a`
    |                       ^
 
-error: free region `ReFree(DefId(0/1:9 ~ return_wrong_bound_region[317d]::test[0]::{{closure}}[0]), BrAnon(2))` does not outlive free region `ReFree(DefId(0/1:9 ~ return_wrong_bound_region[317d]::test[0]::{{closure}}[0]), BrAnon(1))`
+error: unsatisfied lifetime constraints
   --> $DIR/return-wrong-bound-region.rs:21:23
    |
 LL |     expect_sig(|a, b| b); // ought to return `a`
-   |                       ^
+   |                 -  -  ^ free region requires that `'1` must outlive `'2`
+   |                 |  |
+   |                 |  lifetime `'1` appears in this argument
+   |                 lifetime `'2` appears in this argument
 
 note: No external requirements
   --> $DIR/return-wrong-bound-region.rs:21:16
@@ -27,7 +30,7 @@ note: No external requirements
 LL | / fn test() {
 LL | |     expect_sig(|a, b| b); // ought to return `a`
 LL | |     //~^ WARN not reporting region error due to nll
-LL | |     //~| ERROR does not outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
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`.
index dd69e18652c9afc598ffeb6050598a55b560acaf..75194bf55bc9f1a3b9864d3648790578ea782852 100644 (file)
@@ -55,6 +55,18 @@ LL | |     }
 LL | | }
    | |_^
 
+error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir)
+  --> $DIR/get_default.rs:45:17
+   |
+LL |         match map.get() {
+   |               --- immutable borrow occurs here
+LL |             Some(v) => {
+LL |                 map.set(String::new()); // Both AST and MIR error here
+   |                 ^^^ mutable borrow occurs here
+...
+LL |                 return v;
+   |                        - borrow later used here
+
 error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir)
   --> $DIR/get_default.rs:51:17
    |
@@ -76,18 +88,6 @@ LL | |     }
 LL | | }
    | |_^
 
-error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir)
-  --> $DIR/get_default.rs:45:17
-   |
-LL |         match map.get() {
-   |               --- immutable borrow occurs here
-LL |             Some(v) => {
-LL |                 map.set(String::new()); // Both AST and MIR error here
-   |                 ^^^ mutable borrow occurs here
-...
-LL |                 return v;
-   |                        - borrow later used here
-
 error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0502`.
index 6f7644da3d34964d151463a27483184f49ba84ea..7c5527ae1e7b1fa15b5a7287c958740fef8bbd3f 100644 (file)
@@ -18,5 +18,5 @@ fn use_val<'a>(val: &'a u8) -> &'a u8 {
 
 fn main() {
     let orig: u8 = 5;
-    move || use_val(&orig); //~ ERROR free region `` does not outlive free region `'_#1r`
+    move || use_val(&orig); //~ ERROR
 }
index 29385d9b2430fe347b084a5f713b8e97ac9d1dc4..7bdac345e9047a881e2c7555d0067b4131bfa34e 100644 (file)
@@ -1,8 +1,12 @@
-error: free region `` does not outlive free region `'_#1r`
-  --> $DIR/issue-48238.rs:21:21
+error: unsatisfied lifetime constraints
+  --> $DIR/issue-48238.rs:21:13
    |
-LL |     move || use_val(&orig); //~ ERROR free region `` does not outlive free region `'_#1r`
-   |                     ^^^^^
+LL |     move || use_val(&orig); //~ ERROR
+   |     --------^^^^^^^^^^^^^^
+   |     |       |
+   |     |       argument requires that `'1` must outlive `'2`
+   |     lifetime `'1` represents the closure body
+   |     lifetime `'2` appears in return type
 
 error: aborting due to previous error
 
index a41af168c3e4e5ef2d936290536a6cae0a95ef8c..beb2ff79e902b474179806c25ea2ac70fc30ae8f 100644 (file)
@@ -22,7 +22,7 @@ fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
     for<'b> &'b T: A,
     <&'static T as A>::X: Sized
 {
-    let _x = *s; //~ ERROR assignment requires that data must outlive free region `'static`
+    let _x = *s; //~ ERROR
 }
 
 fn main() {}
index de69f8cfbcb6e07878ae7927059e8e6bdd485464..48862166f897f6507e7af8ba33814339002d15c0 100644 (file)
@@ -1,8 +1,8 @@
-error: assignment requires that data must outlive free region `'static`
+error: unsatisfied lifetime constraints
   --> $DIR/issue-50716.rs:25:14
    |
-LL |     let _x = *s; //~ ERROR assignment requires that data must outlive free region `'static`
-   |              ^^
+LL |     let _x = *s; //~ ERROR
+   |              ^^ assignment requires that `'a` must outlive `'static`
 
 error: aborting due to previous error
 
index 3832be6288aef3965da8af08fc9bcffcd7dc6f2c..0a8801a3c4d6d1ad9c3098d700563059f4ff558a 100644 (file)
@@ -55,7 +55,7 @@ fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
     with_signature(cell, t, |cell, t| require(cell, t));
     //~^ WARNING not reporting region error due to nll
     //~| ERROR the parameter type `T` may not live long enough
-    //~| ERROR argument requires that data must outlive free region
+    //~| ERROR
 }
 
 #[rustc_regions]
@@ -67,7 +67,7 @@ fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
     with_signature(cell, t, |cell, t| require(cell, t));
     //~^ WARNING not reporting region error due to nll
     //~| ERROR the parameter type `T` may not live long enough
-    //~| ERROR argument requires that data must outlive free region
+    //~| ERROR
 }
 
 #[rustc_regions]
@@ -89,7 +89,7 @@ fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
     with_signature(cell, t, |cell, t| require(cell, t));
     //~^ WARNING not reporting region error due to nll
     //~| ERROR the parameter type `T` may not live long enough
-    //~| ERROR argument requires that data must outlive free region
+    //~| ERROR
 }
 
 #[rustc_regions]
index 898c995e09b9d6b3269457d230672bdb0d1bf4dc..b84ee4de5a3cc953b6c7b0ffaca387e99146b9d0 100644 (file)
@@ -40,11 +40,11 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |
    = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`...
 
-error: argument requires that data must outlive free region `ReFree(DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`
+error: unsatisfied lifetime constraints
   --> $DIR/projection-one-region-closure.rs:55:5
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
 
 note: No external requirements
   --> $DIR/projection-one-region-closure.rs:51:1
@@ -54,7 +54,7 @@ LL | | where
 LL | |     T: Anything<'b>,
 LL | | {
 ...  |
-LL | |     //~| ERROR argument requires that data must outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
@@ -88,11 +88,11 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |
    = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...
 
-error: argument requires that data must outlive free region `ReEarlyBound(0, 'a)`
+error: unsatisfied lifetime constraints
   --> $DIR/projection-one-region-closure.rs:67:5
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
 
 note: No external requirements
   --> $DIR/projection-one-region-closure.rs:62:1
@@ -102,7 +102,7 @@ LL | | where
 LL | |     T: Anything<'b>,
 LL | |     'a: 'a,
 ...  |
-LL | |     //~| ERROR argument requires that data must outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
@@ -137,11 +137,11 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |
    = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...
 
-error: argument requires that data must outlive free region `ReEarlyBound(0, 'a)`
+error: unsatisfied lifetime constraints
   --> $DIR/projection-one-region-closure.rs:89:5
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
 
 note: No external requirements
   --> $DIR/projection-one-region-closure.rs:74:1
@@ -151,7 +151,7 @@ LL | | where
 LL | |     T: Anything<'b>,
 LL | |     T::AssocType: 'a,
 ...  |
-LL | |     //~| ERROR argument requires that data must outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
index da76193459b30a54b47524ae06071d1ddbe5d0f5..6317d6eca1f1de29a400aa1e0dd17a5a00fe6b85 100644 (file)
@@ -46,7 +46,7 @@ fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
 {
     with_signature(cell, t, |cell, t| require(cell, t));
     //~^ WARNING not reporting region error due to nll
-    //~| ERROR argument requires that data must outlive free region
+    //~| ERROR
 }
 
 #[rustc_regions]
@@ -57,7 +57,7 @@ fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
 {
     with_signature(cell, t, |cell, t| require(cell, t));
     //~^ WARNING not reporting region error due to nll
-    //~| ERROR argument requires that data must outlive free region
+    //~| ERROR
 }
 
 #[rustc_regions]
@@ -78,7 +78,7 @@ fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
 
     with_signature(cell, t, |cell, t| require(cell, t));
     //~^ WARNING not reporting region error due to nll
-    //~| ERROR argument requires that data must outlive free region
+    //~| ERROR
 }
 
 #[rustc_regions]
index be11c6249f0ba0dfb04bc96536ef04bee2d5564c..42ecd6f986075130d1e6da857d4d502cd84b99ff 100644 (file)
@@ -31,11 +31,11 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 3
    = note: where '_#1r: '_#2r
 
-error: argument requires that data must outlive free region `ReFree(DefId(0/0:8 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`
+error: unsatisfied lifetime constraints
   --> $DIR/projection-one-region-trait-bound-closure.rs:47:5
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-closure.rs:43:1
@@ -45,7 +45,7 @@ LL | | where
 LL | |     T: Anything<'b>,
 LL | | {
 ...  |
-LL | |     //~| ERROR argument requires that data must outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
@@ -70,11 +70,11 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 4
    = note: where '_#2r: '_#3r
 
-error: argument requires that data must outlive free region `ReEarlyBound(0, 'a)`
+error: unsatisfied lifetime constraints
   --> $DIR/projection-one-region-trait-bound-closure.rs:58:5
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-closure.rs:53:1
@@ -84,7 +84,7 @@ LL | | where
 LL | |     T: Anything<'b>,
 LL | |     'a: 'a,
 ...  |
-LL | |     //~| ERROR argument requires that data must outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
@@ -110,11 +110,11 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 4
    = note: where '_#2r: '_#3r
 
-error: argument requires that data must outlive free region `ReEarlyBound(0, 'a)`
+error: unsatisfied lifetime constraints
   --> $DIR/projection-one-region-trait-bound-closure.rs:79:5
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-closure.rs:64:1
@@ -124,7 +124,7 @@ LL | | where
 LL | |     T: Anything<'b>,
 LL | |     T::AssocType: 'a,
 ...  |
-LL | |     //~| ERROR argument requires that data must outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
index 5e481a9626f08166ff50ac80ce86775041be1a2f..2552054fd5f423553516446fd04ae4f971f176c0 100644 (file)
@@ -107,7 +107,7 @@ fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
 {
     with_signature(cell, t, |cell, t| require(cell, t));
     //~^ WARNING not reporting region error due to nll
-    //~| ERROR argument requires that data must outlive free region
+    //~| ERROR
 }
 
 #[rustc_regions]
index 546384e8545e3fa357693fdb593d944a68bb72c2..b0f823ad3d56b52500550c879b6219c433997943 100644 (file)
@@ -239,11 +239,11 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 3
    = note: where <T as Anything<ReClosureBound('_#1r), ReClosureBound('_#1r)>>::AssocType: '_#2r
 
-error: argument requires that data must outlive free region `ReFree(DefId(0/0:13 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]), BrNamed(crate0:DefIndex(1:43), 'a))`
+error: unsatisfied lifetime constraints
   --> $DIR/projection-two-region-trait-bound-closure.rs:108:5
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
 
 note: No external requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:104:1
@@ -253,7 +253,7 @@ LL | | where
 LL | |     T: Anything<'b, 'b>,
 LL | | {
 ...  |
-LL | |     //~| ERROR argument requires that data must outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
index ca854f9f70122c2b4750bac48c658447f6fa7a13..5e465ca18f4c03b3a21d492428657d51f93e210a 100644 (file)
@@ -12,6 +12,6 @@ trait I {}
 type K = I+'static;
 
 fn foo(_x: K) {}
-//~^ ERROR the size for value values of type
+//~^ ERROR the size for values of type
 
 fn main() {}
index 72bd270165fd09240f7bf584f4fff4466e0e96f5..7c1ebc353ac75383e0ee091783845cb4c1528d17 100644 (file)
@@ -1,4 +1,4 @@
-error[E0277]: the size for value values of type `(dyn I + 'static)` cannot be known at compilation time
+error[E0277]: the size for values of type `(dyn I + 'static)` cannot be known at compilation time
   --> $DIR/issue-5035-2.rs:14:8
    |
 LL | fn foo(_x: K) {}
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`.
diff --git a/src/test/ui/rfc-2093-infer-outlives/cross-crate.rs b/src/test/ui/rfc-2093-infer-outlives/cross-crate.rs
new file mode 100644 (file)
index 0000000..0167399
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+#![feature(rustc_attrs)]
+#![feature(infer_outlives_requirements)]
+
+#[rustc_outlives]
+struct Foo<'a, T> { //~ ERROR 15:1: 17:2: rustc_outlives
+    bar: std::slice::IterMut<'a, T>
+}
+
+fn main() {}
+
diff --git a/src/test/ui/rfc-2093-infer-outlives/cross-crate.stderr b/src/test/ui/rfc-2093-infer-outlives/cross-crate.stderr
new file mode 100644 (file)
index 0000000..a90643a
--- /dev/null
@@ -0,0 +1,12 @@
+error: rustc_outlives
+  --> $DIR/cross-crate.rs:15:1
+   |
+LL | / struct Foo<'a, T> { //~ ERROR 15:1: 17:2: rustc_outlives
+LL | |     bar: std::slice::IterMut<'a, T>
+LL | | }
+   | |_^
+   |
+   = note: T : 'a
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rust-2018/issue-52202-use-suggestions.rs b/src/test/ui/rust-2018/issue-52202-use-suggestions.rs
new file mode 100644 (file)
index 0000000..5acd19c
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: --edition 2018
+
+// The local `use` suggestion should start with `crate::` (but the
+// standard-library suggestions should not, obviously).
+
+mod plumbing {
+    pub struct Drain;
+}
+
+fn main() {
+    let _d = Drain {};
+    //~^ ERROR cannot find struct, variant or union type `Drain` in this scope
+}
diff --git a/src/test/ui/rust-2018/issue-52202-use-suggestions.stderr b/src/test/ui/rust-2018/issue-52202-use-suggestions.stderr
new file mode 100644 (file)
index 0000000..95158db
--- /dev/null
@@ -0,0 +1,20 @@
+error[E0422]: cannot find struct, variant or union type `Drain` in this scope
+  --> $DIR/issue-52202-use-suggestions.rs:21:14
+   |
+LL |     let _d = Drain {};
+   |              ^^^^^ not found in this scope
+help: possible candidates are found in other modules, you can import them into scope
+   |
+LL | use crate::plumbing::Drain;
+   |
+LL | use std::collections::binary_heap::Drain;
+   |
+LL | use std::collections::hash_map::Drain;
+   |
+LL | use std::collections::hash_set::Drain;
+   |
+and 3 other candidates
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0422`.
index fee0d7feb6d367ab41c0b3732550b642f425c2ac..cbb9d0429c616350bcf11d035b5a382bf0cfa39d 100644 (file)
@@ -1,7 +1,7 @@
-error[E0597]: `b1` does not live long enough
-  --> $DIR/dropck_arr_cycle_checked.rs:111:24
+error[E0597]: `b3` does not live long enough
+  --> $DIR/dropck_arr_cycle_checked.rs:105:24
    |
-LL |     b3.a[0].v.set(Some(&b1));
+LL |     b1.a[1].v.set(Some(&b3));
    |                        ^^^ borrowed value does not live long enough
 ...
 LL | }
@@ -22,10 +22,10 @@ LL | }
    | borrowed value only lives until here
    | borrow later used here, when `b1` is dropped
 
-error[E0597]: `b3` does not live long enough
-  --> $DIR/dropck_arr_cycle_checked.rs:105:24
+error[E0597]: `b1` does not live long enough
+  --> $DIR/dropck_arr_cycle_checked.rs:111:24
    |
-LL |     b1.a[1].v.set(Some(&b3));
+LL |     b3.a[0].v.set(Some(&b1));
    |                        ^^^ borrowed value does not live long enough
 ...
 LL | }
index 86a4f0e13b512b07312eb58c389e10b8d4ce59ee..37fffe886e30950cc2882aec517ece53f6b9812a 100644 (file)
@@ -1,9 +1,9 @@
-error[E0597]: `d1` does not live long enough
-  --> $DIR/dropck_direct_cycle_with_drop.rs:48:19
+error[E0597]: `d2` does not live long enough
+  --> $DIR/dropck_direct_cycle_with_drop.rs:46:19
    |
-LL |     d2.p.set(Some(&d1));
+LL |     d1.p.set(Some(&d2));
    |                   ^^^ borrowed value does not live long enough
-LL |     //~^ ERROR `d1` does not live long enough
+...
 LL | }
    | -
    | |
@@ -12,12 +12,12 @@ LL | }
    |
    = note: values in a scope are dropped in the opposite order they are defined
 
-error[E0597]: `d2` does not live long enough
-  --> $DIR/dropck_direct_cycle_with_drop.rs:46:19
+error[E0597]: `d1` does not live long enough
+  --> $DIR/dropck_direct_cycle_with_drop.rs:48:19
    |
-LL |     d1.p.set(Some(&d2));
+LL |     d2.p.set(Some(&d1));
    |                   ^^^ borrowed value does not live long enough
-...
+LL |     //~^ ERROR `d1` does not live long enough
 LL | }
    | -
    | |
index b7f8b85f46cee83f7027c80e5a3178695dc00765..13bd1f54198212077863744198898998f925bef6 100644 (file)
@@ -1,7 +1,7 @@
-error[E0597]: `c1` does not live long enough
-  --> $DIR/dropck_vec_cycle_checked.rs:121:24
+error[E0597]: `c3` does not live long enough
+  --> $DIR/dropck_vec_cycle_checked.rs:115:24
    |
-LL |     c3.v[0].v.set(Some(&c1));
+LL |     c1.v[1].v.set(Some(&c3));
    |                        ^^^ borrowed value does not live long enough
 ...
 LL | }
@@ -22,10 +22,10 @@ LL | }
    | borrowed value only lives until here
    | borrow later used here, when `c1` is dropped
 
-error[E0597]: `c3` does not live long enough
-  --> $DIR/dropck_vec_cycle_checked.rs:115:24
+error[E0597]: `c1` does not live long enough
+  --> $DIR/dropck_vec_cycle_checked.rs:121:24
    |
-LL |     c1.v[1].v.set(Some(&c3));
+LL |     c3.v[0].v.set(Some(&c1));
    |                        ^^^ borrowed value does not live long enough
 ...
 LL | }
index 389adb231c4228ddb7f9b611cc7913fd150dbf9c..100b4c1292f44ad73c36be2c8ea02c36fb600d69 100644 (file)
@@ -1,21 +1,21 @@
-error[E0597]: `c1` does not live long enough
-  --> $DIR/vec-must-not-hide-type-from-dropck.rs:129:24
+error[E0597]: `c2` does not live long enough
+  --> $DIR/vec-must-not-hide-type-from-dropck.rs:127:24
    |
-LL |     c2.v[0].v.set(Some(&c1));
+LL |     c1.v[0].v.set(Some(&c2));
    |                        ^^^ borrowed value does not live long enough
-LL |     //~^ ERROR `c1` does not live long enough
+...
 LL | }
    | -
    | |
    | borrowed value only lives until here
    | borrow later used here, when `c1` is dropped
 
-error[E0597]: `c2` does not live long enough
-  --> $DIR/vec-must-not-hide-type-from-dropck.rs:127:24
+error[E0597]: `c1` does not live long enough
+  --> $DIR/vec-must-not-hide-type-from-dropck.rs:129:24
    |
-LL |     c1.v[0].v.set(Some(&c2));
+LL |     c2.v[0].v.set(Some(&c1));
    |                        ^^^ borrowed value does not live long enough
-...
+LL |     //~^ ERROR `c1` does not live long enough
 LL | }
    | -
    | |
diff --git a/src/test/ui/suggestions/issue-51515.rs b/src/test/ui/suggestions/issue-51515.rs
new file mode 100644 (file)
index 0000000..3e0a3b7
--- /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.
+
+#![feature(nll)]
+
+fn main() {
+    let foo = &16;
+    //~^ HELP consider changing this to be a mutable reference
+    //~| SUGGESTION &mut 16
+    *foo = 32;
+    //~^ ERROR cannot assign to `*foo` which is behind a `&` reference
+    let bar = foo;
+    //~^ HELP consider changing this to be a mutable reference
+    //~| SUGGESTION &mut i32
+    *bar = 64;
+    //~^ ERROR cannot assign to `*bar` which is behind a `&` reference
+}
diff --git a/src/test/ui/suggestions/issue-51515.stderr b/src/test/ui/suggestions/issue-51515.stderr
new file mode 100644 (file)
index 0000000..3e7349b
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0594]: cannot assign to `*foo` which is behind a `&` reference
+  --> $DIR/issue-51515.rs:17:5
+   |
+LL |     let foo = &16;
+   |               --- help: consider changing this to be a mutable reference: `&mut 16`
+...
+LL |     *foo = 32;
+   |     ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
+
+error[E0594]: cannot assign to `*bar` which is behind a `&` reference
+  --> $DIR/issue-51515.rs:22:5
+   |
+LL |     let bar = foo;
+   |         --- help: consider changing this to be a mutable reference: `&mut i32`
+...
+LL |     *bar = 64;
+   |     ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0594`.
diff --git a/src/test/ui/suggestions/issue-52049.nll.stderr b/src/test/ui/suggestions/issue-52049.nll.stderr
new file mode 100644 (file)
index 0000000..6f71f16
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/issue-52049.rs:16:10
+   |
+LL |     foo(&unpromotable(5u32));
+   |          ^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/suggestions/issue-52049.rs b/src/test/ui/suggestions/issue-52049.rs
new file mode 100644 (file)
index 0000000..daff225
--- /dev/null
@@ -0,0 +1,18 @@
+// 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(_: &'static u32) {}
+
+fn unpromotable<T>(t: T) -> T { t }
+
+fn main() {
+    foo(&unpromotable(5u32));
+}
+//~^^ ERROR borrowed value does not live long enough
diff --git a/src/test/ui/suggestions/issue-52049.stderr b/src/test/ui/suggestions/issue-52049.stderr
new file mode 100644 (file)
index 0000000..e1e5010
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/issue-52049.rs:16:10
+   |
+LL |     foo(&unpromotable(5u32));
+   |          ^^^^^^^^^^^^^^^^^^ - temporary value only lives until here
+   |          |
+   |          temporary value does not live long enough
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
index 8fbab4022327171feb87ce682c25b0f7d3154273..9d6cf5fe598c5d28d5ad0104e5b1ab8b2657e21d 100644 (file)
@@ -15,7 +15,7 @@ fn main() {
   let u: &str = if true { s[..2] } else { s };
   //~^ ERROR mismatched types
   let v = s[..2];
-  //~^ ERROR the size for value values of type
+  //~^ ERROR the size for values of type
   let w: &str = s[..2];
   //~^ ERROR mismatched types
 }
index 5af936eec5bb6881e1d58a1b8ff8ef758a2d7a9e..e0576cee8f56ea06e1802b5452ef22b38a7af5fb 100644 (file)
@@ -19,7 +19,7 @@ LL |   let u: &str = if true { s[..2] } else { s };
    = note: expected type `&str`
               found type `str`
 
-error[E0277]: the size for value values of type `str` cannot be known at compilation time
+error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/str-array-assignment.rs:17:7
    |
 LL |   let v = s[..2];
diff --git a/src/test/ui/tool_lints.rs b/src/test/ui/tool_lints.rs
new file mode 100644 (file)
index 0000000..71f90b1
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(tool_lints)]
+
+#[warn(foo::bar)]
+//~^ ERROR an unknown tool name found in scoped lint: `foo::bar`
+fn main() {}
diff --git a/src/test/ui/tool_lints.stderr b/src/test/ui/tool_lints.stderr
new file mode 100644 (file)
index 0000000..16468df
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
+  --> $DIR/tool_lints.rs:13:8
+   |
+LL | #[warn(foo::bar)]
+   |        ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0710`.
index 432df4382227819854f806f70bc6e9cb68cce869..0b7b6e6167867b08e4ea7e17a71e7fdde84223c7 100644 (file)
@@ -1,8 +1,10 @@
-error[E0133]: dereference of raw pointer requires unsafe function or block
+error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
   --> $DIR/trait-safety-fn-body.rs:21:9
    |
 LL |         *self += 1;
    |         ^^^^^^^^^^ dereference of raw pointer
+   |
+   = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
 
 error: aborting due to previous error
 
index dd74f4f4797272400bc36dd0bd7f6dd9ccee42d0..a43b75d2fe8bd48237f7adef10381280f16f87ae 100644 (file)
 fn check<T: Iterator, U: ?Sized>() {
     // suggest a where-clause, if needed
     mem::size_of::<U>();
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 
     mem::size_of::<Misc<U>>();
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 
     // ... even if T occurs as a type parameter
 
@@ -36,10 +36,10 @@ fn check<T: Iterator, U: ?Sized>() {
     // ... and also not if the error is not related to the type
 
     mem::size_of::<[T]>();
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 
     mem::size_of::<[&U]>();
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn main() {
index feb31ae22d8ca9b01fc81c982287d6b0c01ed4a9..f62e43e2a467928ff3a1a38818bd76a625dcb3c0 100644 (file)
@@ -1,4 +1,4 @@
-error[E0277]: the size for value values of type `U` cannot be known at compilation time
+error[E0277]: the size for values of type `U` cannot be known at compilation time
   --> $DIR/trait-suggest-where-clause.rs:17:5
    |
 LL |     mem::size_of::<U>();
@@ -9,7 +9,7 @@ LL |     mem::size_of::<U>();
    = help: consider adding a `where U: std::marker::Sized` bound
    = note: required by `std::mem::size_of`
 
-error[E0277]: the size for value values of type `U` cannot be known at compilation time
+error[E0277]: the size for values of type `U` cannot be known at compilation time
   --> $DIR/trait-suggest-where-clause.rs:20:5
    |
 LL |     mem::size_of::<Misc<U>>();
@@ -47,7 +47,7 @@ LL |     <Misc<_> as From<T>>::from;
    |
    = note: required by `std::convert::From::from`
 
-error[E0277]: the size for value values of type `[T]` cannot be known at compilation time
+error[E0277]: the size for values of type `[T]` cannot be known at compilation time
   --> $DIR/trait-suggest-where-clause.rs:38:5
    |
 LL |     mem::size_of::<[T]>();
@@ -57,7 +57,7 @@ LL |     mem::size_of::<[T]>();
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: required by `std::mem::size_of`
 
-error[E0277]: the size for value values of type `[&U]` cannot be known at compilation time
+error[E0277]: the size for values of type `[&U]` cannot be known at compilation time
   --> $DIR/trait-suggest-where-clause.rs:41:5
    |
 LL |     mem::size_of::<[&U]>();
index d08574c3d878967d533fd7c36f6a4b5f8e1547fb..960123b5d3a08cfed505a742ccc3505380eaf9b1 100644 (file)
@@ -1,4 +1,4 @@
-error[E0277]: the size for value values of type `str` cannot be known at compilation time
+error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/trivial-bounds-leak.rs:22:25
    |
 LL | fn cant_return_str() -> str { //~ ERROR
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 49f9044b19b248c13836a364263640eee72a4c65..6385578698cf745b75258d60065ab5effa5bfdd6 100644 (file)
@@ -22,11 +22,14 @@ warning: not reporting region error due to nll
 LL |     Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
-error: cast requires that data must outlive free region `'static`
+error: unsatisfied lifetime constraints
   --> $DIR/dyn-trait-underscore.rs:18:5
    |
+LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
+   |                - let's call the lifetime of this reference `'1`
+LL |     //                      ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
 LL |     Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
 
 error: aborting due to previous error
 
index 15822ae42998c5769acd0670067bdaba22396ed1..66d6632ff5aa0d4a4c40e6f7ae4c27c6d0b9919b 100644 (file)
 
 union Foo<T: ?Sized> {
     value: T,
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 struct Foo2<T: ?Sized> {
     value: T,
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     t: u32,
 }
 
 enum Foo3<T: ?Sized> {
     Value(T),
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 fn main() {}
index c6b7cf4e078233c5bc6cdb86696ddc5856d01e97..2b1f4b4e8f31c3f9d029b34d85c31c7d8eac5250 100644 (file)
@@ -1,4 +1,4 @@
-error[E0277]: the size for value values of type `T` cannot be known at compilation time
+error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> $DIR/union-sized-field.rs:14:5
    |
 LL |     value: T,
@@ -9,7 +9,7 @@ LL |     value: T,
    = help: consider adding a `where T: std::marker::Sized` bound
    = note: no field of a union may have a dynamically sized type
 
-error[E0277]: the size for value values of type `T` cannot be known at compilation time
+error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> $DIR/union-sized-field.rs:19:5
    |
 LL |     value: T,
@@ -20,7 +20,7 @@ LL |     value: T,
    = help: consider adding a `where T: std::marker::Sized` bound
    = note: only the last field of a struct may have a dynamically sized type
 
-error[E0277]: the size for value values of type `T` cannot be known at compilation time
+error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> $DIR/union-sized-field.rs:25:11
    |
 LL |     Value(T),
index 270b90ec3fcbe90fe4470c3436d665bc19503d08..d4b3ed687e5e43b956c595f7004e9f29cb1d9e00 100644 (file)
@@ -1,8 +1,10 @@
-error[E0133]: call to unsafe function requires unsafe function or block
+error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
   --> $DIR/unsafe-const-fn.rs:19:18
    |
 LL | const VAL: u32 = dummy(0xFFFF);
    |                  ^^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error: aborting due to previous error
 
index 9082ea4abddbdd669ad4a3c86539e84c83ee33fd..dadcc4206c30413abfa65919f6cb799e75cefc6f 100644 (file)
@@ -31,53 +31,53 @@ trait PathHelper4 {}
 enum E<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized> {
     // parameter
     VA(W),
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VB{x: X},
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VC(isize, Y),
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VD{u: isize, x: Z},
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 
     // slice / str
     VE([u8]),
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VF{x: str},
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VG(isize, [f32]),
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VH{u: isize, x: [u32]},
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 
     // unsized struct
     VI(Path1),
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VJ{x: Path2},
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VK(isize, Path3),
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VL{u: isize, x: Path4},
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 
     // plain trait
     VM(Foo),
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VN{x: Bar},
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VO(isize, FooBar),
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VP{u: isize, x: BarFoo},
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 
     // projected
     VQ(<&'static [i8] as Deref>::Target),
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VR{x: <&'static [char] as Deref>::Target},
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VS(isize, <&'static [f64] as Deref>::Target),
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
     VT{u: isize, x: <&'static [i32] as Deref>::Target},
-    //~^ ERROR the size for value values of type
+    //~^ ERROR the size for values of type
 }
 
 
index 1f30c815d30a8be7bba90b1ecee850bfa4bddff6..47d75f338516bc1e67dfa571e44536825b05230a 100644 (file)
@@ -1,4 +1,4 @@
-error[E0277]: the size for value values of type `W` cannot be known at compilation time
+error[E0277]: the size for values of type `W` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:33:8
    |
 LL |     VA(W),
@@ -9,7 +9,7 @@ LL |     VA(W),
    = help: consider adding a `where W: std::marker::Sized` bound
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `X` cannot be known at compilation time
+error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:35:8
    |
 LL |     VB{x: X},
@@ -20,7 +20,7 @@ LL |     VB{x: X},
    = help: consider adding a `where X: std::marker::Sized` bound
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `Y` cannot be known at compilation time
+error[E0277]: the size for values of type `Y` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:37:15
    |
 LL |     VC(isize, Y),
@@ -31,7 +31,7 @@ LL |     VC(isize, Y),
    = help: consider adding a `where Y: std::marker::Sized` bound
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `Z` cannot be known at compilation time
+error[E0277]: the size for values of type `Z` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:39:18
    |
 LL |     VD{u: isize, x: Z},
@@ -42,7 +42,7 @@ LL |     VD{u: isize, x: Z},
    = help: consider adding a `where Z: std::marker::Sized` bound
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `[u8]` cannot be known at compilation time
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:43:8
    |
 LL |     VE([u8]),
@@ -52,7 +52,7 @@ LL |     VE([u8]),
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `str` cannot be known at compilation time
+error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:45:8
    |
 LL |     VF{x: str},
@@ -62,7 +62,7 @@ LL |     VF{x: str},
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `[f32]` cannot be known at compilation time
+error[E0277]: the size for values of type `[f32]` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:47:15
    |
 LL |     VG(isize, [f32]),
@@ -72,7 +72,7 @@ LL |     VG(isize, [f32]),
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `[u32]` cannot be known at compilation time
+error[E0277]: the size for values of type `[u32]` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:49:18
    |
 LL |     VH{u: isize, x: [u32]},
@@ -82,7 +82,7 @@ LL |     VH{u: isize, x: [u32]},
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `(dyn Foo + 'static)` cannot be known at compilation time
+error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:63:8
    |
 LL |     VM(Foo),
@@ -92,7 +92,7 @@ LL |     VM(Foo),
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `(dyn Bar + 'static)` cannot be known at compilation time
+error[E0277]: the size for values of type `(dyn Bar + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:65:8
    |
 LL |     VN{x: Bar},
@@ -102,7 +102,7 @@ LL |     VN{x: Bar},
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `(dyn FooBar + 'static)` cannot be known at compilation time
+error[E0277]: the size for values of type `(dyn FooBar + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:67:15
    |
 LL |     VO(isize, FooBar),
@@ -112,7 +112,7 @@ LL |     VO(isize, FooBar),
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `(dyn BarFoo + 'static)` cannot be known at compilation time
+error[E0277]: the size for values of type `(dyn BarFoo + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:69:18
    |
 LL |     VP{u: isize, x: BarFoo},
@@ -122,7 +122,7 @@ LL |     VP{u: isize, x: BarFoo},
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `[i8]` cannot be known at compilation time
+error[E0277]: the size for values of type `[i8]` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:73:8
    |
 LL |     VQ(<&'static [i8] as Deref>::Target),
@@ -132,7 +132,7 @@ LL |     VQ(<&'static [i8] as Deref>::Target),
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `[char]` cannot be known at compilation time
+error[E0277]: the size for values of type `[char]` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:75:8
    |
 LL |     VR{x: <&'static [char] as Deref>::Target},
@@ -142,7 +142,7 @@ LL |     VR{x: <&'static [char] as Deref>::Target},
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `[f64]` cannot be known at compilation time
+error[E0277]: the size for values of type `[f64]` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:77:15
    |
 LL |     VS(isize, <&'static [f64] as Deref>::Target),
@@ -152,7 +152,7 @@ LL |     VS(isize, <&'static [f64] as Deref>::Target),
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `[i32]` cannot be known at compilation time
+error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:79:18
    |
 LL |     VT{u: isize, x: <&'static [i32] as Deref>::Target},
@@ -162,7 +162,7 @@ LL |     VT{u: isize, x: <&'static [i32] as Deref>::Target},
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `(dyn PathHelper1 + 'static)` cannot be known at compilation time
+error[E0277]: the size for values of type `(dyn PathHelper1 + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:53:8
    |
 LL |     VI(Path1),
@@ -173,7 +173,7 @@ LL |     VI(Path1),
    = note: required because it appears within the type `Path1`
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `(dyn PathHelper2 + 'static)` cannot be known at compilation time
+error[E0277]: the size for values of type `(dyn PathHelper2 + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:55:8
    |
 LL |     VJ{x: Path2},
@@ -184,7 +184,7 @@ LL |     VJ{x: Path2},
    = note: required because it appears within the type `Path2`
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `(dyn PathHelper3 + 'static)` cannot be known at compilation time
+error[E0277]: the size for values of type `(dyn PathHelper3 + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:57:15
    |
 LL |     VK(isize, Path3),
@@ -195,7 +195,7 @@ LL |     VK(isize, Path3),
    = note: required because it appears within the type `Path3`
    = note: no field of an enum variant may have a dynamically sized type
 
-error[E0277]: the size for value values of type `(dyn PathHelper4 + 'static)` cannot be known at compilation time
+error[E0277]: the size for values of type `(dyn PathHelper4 + 'static)` cannot be known at compilation time
   --> $DIR/unsized-enum2.rs:59:18
    |
 LL |     VL{u: isize, x: Path4},
index 4a1ba1736c2ed16ee99917d74e607758bb3f4bde..c2f0687a5a994e3dbc8ec257b4812e25c2c5a433 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",
@@ -260,6 +261,7 @@ fn build(&mut self) {
         self.rust_version = self.version("rust", "x86_64-unknown-linux-gnu");
         self.cargo_version = self.version("cargo", "x86_64-unknown-linux-gnu");
         self.rls_version = self.version("rls", "x86_64-unknown-linux-gnu");
+        self.clippy_version = self.version("clippy", "x86_64-unknown-linux-gnu");
         self.rustfmt_version = self.version("rustfmt", "x86_64-unknown-linux-gnu");
         self.llvm_tools_version = self.version("llvm-tools", "x86_64-unknown-linux-gnu");
 
index 5699afe508d62924f6b38b19dc98296ad33d1659..af9e40c26b4ea2ebd6f31ee86ee61d5ac1c74eb0 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 5699afe508d62924f6b38b19dc98296ad33d1659
+Subproject commit af9e40c26b4ea2ebd6f31ee86ee61d5ac1c74eb0
index 141f79f8440229f705f47f06c47b46a44d65584b..aad450ef923091ba4699891df0fe518f0d3686f6 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 141f79f8440229f705f47f06c47b46a44d65584b
+Subproject commit aad450ef923091ba4699891df0fe518f0d3686f6
index 780387580232aee715604633a7cdec96e4147191..582ba5adfe529c4d8ed7e31fb6429d5f11314d83 100644 (file)
@@ -6,7 +6,7 @@ version = "0.0.0"
 [dependencies]
 diff = "0.1.10"
 env_logger = { version = "0.5", default-features = false }
-filetime = "0.1"
+filetime = "0.2"
 getopts = "0.2"
 log = "0.4"
 regex = "0.2"
index 408eda5ba5bb58aa6d19848ac6be270c2a15ee4d..59ddc16715d3b6e52ad8264e894a84e2f5bdeb08 100644 (file)
@@ -519,9 +519,8 @@ fn print_source(&self, src: String, pretty_type: &str) -> ProcRes {
 
     fn compare_source(&self, expected: &str, actual: &str) {
         if expected != actual {
-            self.error("pretty-printed source does not match expected source");
-            println!(
-                "\n\
+            self.fatal(&format!(
+                "pretty-printed source does not match expected source\n\
                  expected:\n\
                  ------------------------------------------\n\
                  {}\n\
@@ -531,7 +530,7 @@ fn compare_source(&self, expected: &str, actual: &str) {
                  {}\n\
                  ------------------------------------------\n\
                  \n",
-                expected, actual
+                expected, actual)
             );
         }
     }
index b87873eaceb75cf9342d5273f01ba2c020f61ca8..8214ccf861d538671b0a1436dbf4538dc4a64d09 160000 (submodule)
@@ -1 +1 @@
-Subproject commit b87873eaceb75cf9342d5273f01ba2c020f61ca8
+Subproject commit 8214ccf861d538671b0a1436dbf4538dc4a64d09
index 7d0bc550b0899a13a56c81eb2d5064abd0bcf385..6b4238b46595de1660a95887b287ddabe62726ea 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 7d0bc550b0899a13a56c81eb2d5064abd0bcf385
+Subproject commit 6b4238b46595de1660a95887b287ddabe62726ea
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).
index 87edd75ecf26c9084969f431bb5e363693a8a4ca..5e5992517d3591e2708d4ca6b155dfcbdf3344b9 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 87edd75ecf26c9084969f431bb5e363693a8a4ca
+Subproject commit 5e5992517d3591e2708d4ca6b155dfcbdf3344b9
index 6f03d09268b91ce0c8cc284c60b7f35901062064..942d27202ecd56f794ee5cf83b618391a33cd87a 100644 (file)
@@ -47,6 +47,7 @@
     "selectors",          // MPL-2.0, rustdoc
     "clippy_lints",       // MPL-2.0, rls
     "colored",            // MPL-2.0, rustfmt
+    "ordslice",           // Apache-2.0, rls
 ];
 
 /// Which crates to check against the whitelist?
@@ -58,7 +59,6 @@
 /// Whitelist of crates rustc is allowed to depend on. Avoid adding to the list if possible.
 static WHITELIST: &'static [Crate] = &[
     Crate("aho-corasick"),
-    Crate("ar"),
     Crate("arrayvec"),
     Crate("atty"),
     Crate("backtrace"),