]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #58931 - estebank:elide-receiver-tyerr, r=varkor
authorPietro Albini <pietro@pietroalbini.org>
Fri, 8 Mar 2019 08:42:03 +0000 (09:42 +0100)
committerGitHub <noreply@github.com>
Fri, 8 Mar 2019 08:42:03 +0000 (09:42 +0100)
Elide invalid method receiver error when it contains TyErr

Fix #58712.

297 files changed:
Cargo.lock
RELEASES.md
appveyor.yml
src/bootstrap/bin/rustc.rs
src/bootstrap/bootstrap.py
src/bootstrap/builder.rs
src/bootstrap/channel.rs
src/bootstrap/check.rs
src/bootstrap/compile.rs
src/bootstrap/dist.rs
src/bootstrap/doc.rs
src/bootstrap/lib.rs
src/bootstrap/tool.rs
src/ci/docker/dist-x86_64-netbsd/Dockerfile
src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh
src/doc/edition-guide
src/liballoc/macros.rs
src/liballoc/vec.rs
src/libcore/benches/iter.rs
src/libcore/intrinsics.rs
src/libcore/iter/adapters/mod.rs
src/libcore/macros.rs
src/libcore/marker.rs
src/libcore/mem.rs
src/libcore/num/mod.rs
src/libcore/option.rs
src/libcore/pin.rs
src/libcore/str/mod.rs
src/libcore/sync/atomic.rs
src/librustc/Cargo.toml
src/librustc/hir/check_attr.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/collector.rs
src/librustc/hir/map/mod.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/canonical/mod.rs
src/librustc/infer/canonical/query_response.rs
src/librustc/infer/combine.rs
src/librustc/infer/error_reporting/mod.rs
src/librustc/infer/mod.rs
src/librustc/infer/nll_relate/mod.rs
src/librustc/infer/opaque_types/mod.rs
src/librustc/infer/outlives/obligations.rs
src/librustc/lib.rs
src/librustc/lint/mod.rs
src/librustc/middle/dead.rs
src/librustc/middle/entry.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/reachable.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc/mir/interpret/value.rs
src/librustc/mir/mod.rs
src/librustc/session/config.rs
src/librustc/session/filesearch.rs
src/librustc/session/mod.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/mod.rs
src/librustc/traits/object_safety.rs
src/librustc/traits/on_unimplemented.rs
src/librustc/ty/context.rs
src/librustc/ty/flags.rs
src/librustc/ty/fold.rs
src/librustc/ty/layout.rs
src/librustc/ty/mod.rs
src/librustc/ty/query/job.rs
src/librustc/ty/relate.rs
src/librustc/ty/structural_impls.rs
src/librustc/ty/sty.rs
src/librustc/ty/subst.rs
src/librustc/ty/util.rs
src/librustc/util/ppaux.rs
src/librustc/util/profiling.rs
src/librustc_borrowck/borrowck/check_loans.rs
src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
src/librustc_borrowck/borrowck/gather_loans/lifetime.rs
src/librustc_borrowck/borrowck/gather_loans/mod.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_codegen_llvm/callee.rs
src/librustc_codegen_llvm/lib.rs
src/librustc_codegen_ssa/Cargo.toml
src/librustc_codegen_ssa/back/symbol_export.rs
src/librustc_codegen_ssa/back/write.rs
src/librustc_codegen_ssa/lib.rs
src/librustc_codegen_ssa/mir/mod.rs
src/librustc_codegen_ssa/mir/operand.rs
src/librustc_codegen_ssa/mir/rvalue.rs
src/librustc_codegen_ssa/traits/backend.rs
src/librustc_codegen_utils/symbol_names.rs
src/librustc_data_structures/Cargo.toml
src/librustc_data_structures/jobserver.rs [new file with mode: 0644]
src/librustc_data_structures/lib.rs
src/librustc_data_structures/macros.rs
src/librustc_driver/Cargo.toml
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_driver/pretty.rs
src/librustc_driver/test.rs
src/librustc_interface/proc_macro_decls.rs
src/librustc_lint/builtin.rs
src/librustc_lint/types.rs
src/librustc_macros/Cargo.toml [new file with mode: 0644]
src/librustc_macros/src/hash_stable.rs [new file with mode: 0644]
src/librustc_macros/src/lib.rs [new file with mode: 0644]
src/librustc_metadata/creader.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/foreign_modules.rs
src/librustc_metadata/index_builder.rs
src/librustc_metadata/locator.rs
src/librustc_metadata/native_libs.rs
src/librustc_metadata/schema.rs
src/librustc_mir/borrow_check/nll/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/values.rs
src/librustc_mir/borrow_check/nll/renumber.rs
src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs
src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs [deleted file]
src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/build/expr/as_place.rs
src/librustc_mir/build/expr/as_rvalue.rs
src/librustc_mir/build/expr/category.rs
src/librustc_mir/build/expr/into.rs
src/librustc_mir/build/mod.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/cx/mod.rs
src/librustc_mir/hair/mod.rs
src/librustc_mir/hair/pattern/_match.rs
src/librustc_mir/hair/pattern/check_match.rs
src/librustc_mir/interpret/cast.rs
src/librustc_mir/interpret/operand.rs
src/librustc_mir/monomorphize/collector.rs
src/librustc_mir/monomorphize/item.rs
src/librustc_mir/monomorphize/partitioning.rs
src/librustc_mir/shim.rs
src/librustc_mir/transform/check_unsafety.rs
src/librustc_mir/transform/generator.rs
src/librustc_mir/transform/inline.rs
src/librustc_mir/transform/mod.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/qualify_min_const_fn.rs
src/librustc_mir/util/liveness.rs
src/librustc_passes/layout_test.rs
src/librustc_passes/rvalue_promotion.rs
src/librustc_plugin/build.rs
src/librustc_privacy/lib.rs
src/librustc_target/spec/armv6_unknown_freebsd.rs [new file with mode: 0644]
src/librustc_target/spec/armv7_unknown_freebsd.rs [new file with mode: 0644]
src/librustc_target/spec/mod.rs
src/librustc_traits/chalk_context/mod.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/demand.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/intrinsic.rs
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/method/mod.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/upvar.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/check_unused.rs
src/librustc_typeck/coherence/inherent_impls.rs
src/librustc_typeck/coherence/inherent_impls_overlap.rs
src/librustc_typeck/coherence/orphan.rs
src/librustc_typeck/coherence/unsafety.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/constrained_type_params.rs
src/librustc_typeck/diagnostics.rs
src/librustc_typeck/impl_wf_check.rs
src/librustc_typeck/outlives/implicit_infer.rs
src/librustc_typeck/outlives/mod.rs
src/librustc_typeck/outlives/test.rs
src/librustc_typeck/outlives/utils.rs
src/librustc_typeck/variance/constraints.rs
src/librustc_typeck/variance/terms.rs
src/librustc_typeck/variance/test.rs
src/librustdoc/clean/mod.rs
src/librustdoc/core.rs
src/librustdoc/doctree.rs
src/librustdoc/visit_ast.rs
src/libstd/collections/hash/map.rs
src/libstd/io/buffered.rs
src/libstd/io/impls.rs
src/libstd/io/stdio.rs
src/libstd/lib.rs
src/libstd/macros.rs
src/libstd/panicking.rs
src/libstd/sys/windows/ext/fs.rs
src/libstd/sys/windows/fs.rs
src/libstd/thread/local.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/stage0.txt
src/test/debuginfo/generators.rs
src/test/incremental/cyclic-trait-hierarchy.rs [new file with mode: 0644]
src/test/pretty/fn-variadic.rs [new file with mode: 0644]
src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile
src/test/run-pass/generator/issue-57084.rs [new file with mode: 0644]
src/test/run-pass/generator/issue-58888.rs [new file with mode: 0644]
src/test/run-pass/issues/issue-58435-ice-with-assoc-const.rs [new file with mode: 0644]
src/test/run-pass/threads-sendsync/sync-send-iterators-in-libcollections.rs
src/test/ui-fulldeps/auxiliary/lint_tool_test.rs
src/test/ui-fulldeps/hash-stable-is-unstable.rs [new file with mode: 0644]
src/test/ui-fulldeps/hash-stable-is-unstable.stderr [new file with mode: 0644]
src/test/ui/always-inhabited-union-ref.stderr
src/test/ui/block-result/issue-5500.stderr
src/test/ui/check_match/issue-35609.stderr
src/test/ui/const-generics/const-expression-parameter.rs
src/test/ui/const-generics/const-expression-parameter.stderr
src/test/ui/const-generics/const-fn-with-const-param.rs
src/test/ui/const-generics/const-fn-with-const-param.stderr
src/test/ui/const-generics/const-param-before-other-params.rs
src/test/ui/const-generics/const-param-before-other-params.stderr
src/test/ui/const-generics/const-param-from-outer-fn.rs
src/test/ui/const-generics/const-param-from-outer-fn.stderr
src/test/ui/const-generics/const-parameter-uppercase-lint.rs
src/test/ui/const-generics/const-parameter-uppercase-lint.stderr
src/test/ui/consts/match_ice.stderr
src/test/ui/derives/deriving-with-repr-packed.stderr
src/test/ui/diverging-tuple-parts-39485.stderr
src/test/ui/empty/empty-never-array.stderr
src/test/ui/error-codes/E0004-2.stderr
src/test/ui/error-codes/E0004.stderr
src/test/ui/exhaustive_integer_patterns.stderr
src/test/ui/feature-gates/feature-gate-const_generics.rs
src/test/ui/feature-gates/feature-gate-const_generics.stderr
src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr
src/test/ui/issues/issue-15129.stderr
src/test/ui/issues/issue-2111.stderr
src/test/ui/issues/issue-30240.stderr
src/test/ui/issues/issue-3096-1.stderr
src/test/ui/issues/issue-3096-2.stderr
src/test/ui/issues/issue-31561.stderr
src/test/ui/issues/issue-3601.stderr
src/test/ui/issues/issue-39362.stderr
src/test/ui/issues/issue-4321.stderr
src/test/ui/issues/issue-50582.rs [new file with mode: 0644]
src/test/ui/issues/issue-50582.stderr [new file with mode: 0644]
src/test/ui/issues/issue-58857.rs [new file with mode: 0644]
src/test/ui/issues/issue-58857.stderr [new file with mode: 0644]
src/test/ui/match/match-argm-statics-2.stderr
src/test/ui/match/match-byte-array-patterns-2.stderr
src/test/ui/match/match-non-exhaustive.stderr
src/test/ui/match/match-privately-empty.stderr
src/test/ui/match/match-slice-patterns.stderr
src/test/ui/missing/missing-items/issue-40221.stderr
src/test/ui/nll/issue-48697.rs
src/test/ui/nll/issue-48697.stderr [new file with mode: 0644]
src/test/ui/nll/promoted-bounds.rs [new file with mode: 0644]
src/test/ui/nll/promoted-bounds.stderr [new file with mode: 0644]
src/test/ui/nll/promoted-closure-pair.rs [new file with mode: 0644]
src/test/ui/nll/promoted-closure-pair.stderr [new file with mode: 0644]
src/test/ui/nll/type-check-pointer-coercions.rs [new file with mode: 0644]
src/test/ui/nll/type-check-pointer-coercions.stderr [new file with mode: 0644]
src/test/ui/nll/type-check-pointer-comparisons.rs [new file with mode: 0644]
src/test/ui/nll/type-check-pointer-comparisons.stderr [new file with mode: 0644]
src/test/ui/nll/user-annotations/promoted-annotation.rs [new file with mode: 0644]
src/test/ui/nll/user-annotations/promoted-annotation.stderr [new file with mode: 0644]
src/test/ui/non-exhaustive/non-exhaustive-float-range-match.stderr
src/test/ui/non-exhaustive/non-exhaustive-match-nested.stderr
src/test/ui/non-exhaustive/non-exhaustive-match.stderr
src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.stderr
src/test/ui/precise_pointer_size_matching.stderr
src/test/ui/rfc-2005-default-binding-mode/slice.stderr
src/test/ui/rfc-2008-non-exhaustive/enum.stderr
src/test/ui/structs/struct-like-enum-nonexhaustive.stderr
src/test/ui/suggestions/format-borrow.rs [new file with mode: 0644]
src/test/ui/suggestions/format-borrow.stderr [new file with mode: 0644]
src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs [new file with mode: 0644]
src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr [new file with mode: 0644]
src/test/ui/suggestions/unused-closure-argument.rs [new file with mode: 0644]
src/test/ui/suggestions/unused-closure-argument.stderr [new file with mode: 0644]
src/test/ui/tuple/tuple-struct-nonexhaustive.stderr
src/test/ui/uninhabited/uninhabited-irrefutable.stderr
src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
src/tools/clippy
src/tools/miri
src/tools/remote-test-client/src/main.rs
src/tools/remote-test-server/src/main.rs
src/tools/rustbook/src/main.rs
src/tools/tidy/src/deps.rs
src/tools/tidy/src/features.rs
src/tools/tidy/src/lib.rs

index 381322bc421d4b5ad872b1cfca8972e19d59c06e..ad4af76f4b3823606697981b39154755de4a7496 100644 (file)
@@ -374,7 +374,7 @@ dependencies = [
  "clippy-mini-macro-test 0.2.0",
  "clippy_dev 0.0.1",
  "clippy_lints 0.0.212",
- "compiletest_rs 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiletest_rs 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -493,7 +493,7 @@ dependencies = [
 
 [[package]]
 name = "compiletest_rs"
-version = "0.3.18"
+version = "0.3.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -508,6 +508,7 @@ dependencies = [
  "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tester 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1590,7 +1591,7 @@ dependencies = [
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiletest_rs 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiletest_rs 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "directories 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2076,7 +2077,7 @@ name = "rand_chacha"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2098,7 +2099,7 @@ name = "rand_hc"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2123,7 +2124,7 @@ name = "rand_xorshift"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2358,12 +2359,13 @@ dependencies = [
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "polonius-engine 0.6.2 (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)",
+ "rustc-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-rayon-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_apfloat 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_fs_util 0.0.0",
+ "rustc_macros 0.1.0",
  "rustc_target 0.0.0",
  "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
@@ -2409,8 +2411,8 @@ dependencies = [
  "rustc-ap-rustc_cratesio_shim 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-serialize 373.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)",
+ "rustc-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-rayon-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2508,23 +2510,23 @@ dependencies = [
 
 [[package]]
 name = "rustc-rayon"
-version = "0.1.1"
+version = "0.1.2"
 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)",
  "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-rayon-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-rayon-core"
-version = "0.1.1"
+version = "0.1.2"
 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.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.46 (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.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2624,6 +2626,7 @@ dependencies = [
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc-demangle 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_allocator 0.0.0",
@@ -2672,11 +2675,13 @@ dependencies = [
  "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
+ "jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.7.1 (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)",
+ "rustc-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-rayon-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_cratesio_shim 0.0.0",
  "serialize 0.0.0",
  "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2692,7 +2697,7 @@ dependencies = [
  "graphviz 0.0.0",
  "log 0.4.6 (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-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_allocator 0.0.0",
  "rustc_borrowck 0.0.0",
  "rustc_codegen_utils 0.0.0",
@@ -2758,7 +2763,7 @@ version = "0.0.0"
 dependencies = [
  "log 0.4.6 (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-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_allocator 0.0.0",
  "rustc_borrowck 0.0.0",
  "rustc_codegen_utils 0.0.0",
@@ -2813,6 +2818,16 @@ dependencies = [
  "core 0.0.0",
 ]
 
+[[package]]
+name = "rustc_macros"
+version = "0.1.0"
+dependencies = [
+ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "rustc_metadata"
 version = "0.0.0"
@@ -3435,6 +3450,15 @@ dependencies = [
 name = "term"
 version = "0.0.0"
 
+[[package]]
+name = "term"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "term"
 version = "0.5.1"
@@ -3471,6 +3495,16 @@ dependencies = [
  "term 0.0.0",
 ]
 
+[[package]]
+name = "tester"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "textwrap"
 version = "0.10.0"
@@ -3996,7 +4030,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "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 compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6711d51cb46744dd8305293cc3fbc392aaff7a8f5095a7c4fae1e5113ef07c96"
-"checksum compiletest_rs 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0d76d4322a40f6b0db7259d4f2c8a65ed8b0d84fce0bbc61b98cf47f8ec6eec3"
+"checksum compiletest_rs 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "56c799b1f7142badf3b047b4c1f2074cc96b6b784fb2432f2ed9c87da0a03749"
 "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
 "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887"
 "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
@@ -4190,8 +4224,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rustc-ap-syntax_pos 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e4f88a1213562373cee9de5a1d77bbf16dd706030304af041c9733492fcc952"
 "checksum rustc-demangle 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "82ae957aa1b3055d8e086486723c0ccd3d7b8fa190ae8fa2e35543b6171c810e"
 "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-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d98c51d9cbbe810c8b6693236d3412d8cd60513ff27a3e1b6af483dca0af544"
+"checksum rustc-rayon-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "526e7b6d2707a5b9bec3927d424ad70fa3cfc68e0ac1b75e46cdbbc95adc5108"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 "checksum rustc_tools_util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c5a95edfa0c893236ae4778bb7c4752760e4c0d245e19b5eff33c5aa5eb9dc"
 "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
@@ -4232,9 +4266,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "a303ba60a099fcd2aaa646b14d2724591a96a75283e4b7ed3d1a1658909d9ae2"
 "checksum tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2"
 "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 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
+"checksum tester 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e812cb26c597f86a49b26dbb58b878bd2a2b4b93fc069dc39499228fe556ff6"
 "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
 "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
 "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
index 841467b69c9866438db0f012fa791e5c4ae89362..4cda02c5c2ebed35030a79de4d68abca20ffac5b 100644 (file)
@@ -4,10 +4,10 @@ Version 1.33.0 (2019-02-28)
 Language
 --------
 - [You can now use the `cfg(target_vendor)` attribute.][57465] E.g.
-  `#[cfg(target_vendor="linux")] fn main() { println!("Hello Linux!"); }`
+  `#[cfg(target_vendor="apple")] fn main() { println!("Hello Apple!"); }`
 - [Integer patterns such as in a match expression can now be exhaustive.][56362]
   E.g. You can have match statement on a `u8` that covers `0..=255` and
-  you would no longer be required to have a `_ => unreachable!()` case. 
+  you would no longer be required to have a `_ => unreachable!()` case.
 - [You can now have multiple patterns in `if let` and `while let`
   expressions.][57532] You can do this with the same syntax as a `match`
   expression. E.g.
@@ -51,8 +51,7 @@ Language
   // Allowed as there is only one `Read` in the module.
   pub trait Read {}
   ```
-- [`extern` functions will now abort by default when panicking.][55982]
-  This was previously undefined behaviour.
+- [You may now use `Rc`, `Arc`, and `Pin` as method receivers][56805].
 
 Compiler
 --------
@@ -109,27 +108,30 @@ Compatibility Notes
   are now deprecated in the standard library, and their usage will now produce a warning.
   Please use the `str::{trim_start, trim_end, trim_start_matches, trim_end_matches}`
   methods instead.
+- The `Error::cause` method has been deprecated in favor of `Error::source` which supports
+  downcasting.
 
-[57615]: https://github.com/rust-lang/rust/pull/57615/
-[57465]: https://github.com/rust-lang/rust/pull/57465/
-[57532]: https://github.com/rust-lang/rust/pull/57532/
-[57535]: https://github.com/rust-lang/rust/pull/57535/
-[57566]: https://github.com/rust-lang/rust/pull/57566/
+[55982]: https://github.com/rust-lang/rust/pull/55982/
+[56303]: https://github.com/rust-lang/rust/pull/56303/
+[56351]: https://github.com/rust-lang/rust/pull/56351/
+[56362]: https://github.com/rust-lang/rust/pull/56362
+[56642]: https://github.com/rust-lang/rust/pull/56642/
+[56769]: https://github.com/rust-lang/rust/pull/56769/
+[56805]: https://github.com/rust-lang/rust/pull/56805
+[56947]: https://github.com/rust-lang/rust/pull/56947/
+[57049]: https://github.com/rust-lang/rust/pull/57049/
+[57067]: https://github.com/rust-lang/rust/pull/57067/
+[57105]: https://github.com/rust-lang/rust/pull/57105
 [57130]: https://github.com/rust-lang/rust/pull/57130/
 [57167]: https://github.com/rust-lang/rust/pull/57167/
 [57175]: https://github.com/rust-lang/rust/pull/57175/
 [57234]: https://github.com/rust-lang/rust/pull/57234/
 [57332]: https://github.com/rust-lang/rust/pull/57332/
-[56947]: https://github.com/rust-lang/rust/pull/56947/
-[57049]: https://github.com/rust-lang/rust/pull/57049/
-[57067]: https://github.com/rust-lang/rust/pull/57067/
-[56769]: https://github.com/rust-lang/rust/pull/56769/
-[56642]: https://github.com/rust-lang/rust/pull/56642/
-[56303]: https://github.com/rust-lang/rust/pull/56303/
-[56351]: https://github.com/rust-lang/rust/pull/56351/
-[55982]: https://github.com/rust-lang/rust/pull/55982/
-[56362]: https://github.com/rust-lang/rust/pull/56362
-[57105]: https://github.com/rust-lang/rust/pull/57105
+[57465]: https://github.com/rust-lang/rust/pull/57465/
+[57532]: https://github.com/rust-lang/rust/pull/57532/
+[57535]: https://github.com/rust-lang/rust/pull/57535/
+[57566]: https://github.com/rust-lang/rust/pull/57566/
+[57615]: https://github.com/rust-lang/rust/pull/57615/
 [cargo/6484]: https://github.com/rust-lang/cargo/pull/6484/
 [`unix::FileExt::read_exact_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.read_exact_at
 [`unix::FileExt::write_all_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.write_all_at
@@ -170,7 +172,7 @@ Language
 - [You can now match against literals in macros with the `literal`
   specifier.][56072] This will match against a literal of any type.
   E.g. `1`, `'A'`, `"Hello World"`
-- [Self can now be used as a constructor and pattern for unit and tuple structs.][56365] E.g. 
+- [Self can now be used as a constructor and pattern for unit and tuple structs.][56365] E.g.
   ```rust
   struct Point(i32, i32);
 
@@ -460,7 +462,7 @@ Version 1.31.0 (2018-12-06)
 
 Language
 --------
-- ðŸŽ‰ [This version marks the release of the 2018 edition of Rust.][54057] ðŸŽ‰ 
+- ðŸŽ‰ [This version marks the release of the 2018 edition of Rust.][54057] ðŸŽ‰
 - [New lifetime elision rules now allow for eliding lifetimes in functions and
   impl headers.][54778] E.g. `impl<'a> Reader for BufReader<'a> {}` can now be
   `impl Reader for BufReader<'_> {}`. Lifetimes are still required to be defined
index 3a0cb8b4fceeafd8fcc81cb47852f9bf1646b301..d70ad54b1c812ee6ef9b293cbfa9f434f4fb882b 100644 (file)
@@ -5,11 +5,6 @@ environment:
   # server goes down presumably. See #43333 for more info
   CARGO_HTTP_CHECK_REVOKE: false
 
-  # Execute the builds on GCE instead of Hyper-V. Those builders have a 3-4
-  # minute startup overhead, but AppVeyor support recommended this as a
-  # possible solution for #58160 (spurious 259 exit codes)
-  appveyor_build_worker_cloud: gce
-
   matrix:
   # 32/64 bit MSVC tests
   - MSYS_BITS: 64
index 70e4a69a07d440169b041ce6f4faf93a4f71fc66..ca86aeb8100a9e6a52e44e313355163e55b5f649 100644 (file)
@@ -109,6 +109,12 @@ fn main() {
 
         cmd.arg("-Zexternal-macro-backtrace");
 
+        // Link crates to the proc macro crate for the target, but use a host proc macro crate
+        // to actually run the macros
+        if env::var_os("RUST_DUAL_PROC_MACROS").is_some() {
+            cmd.arg("-Zdual-proc-macros");
+        }
+
         // When we build Rust dylibs they're all intended for intermediate
         // usage, so make sure we pass the -Cprefer-dynamic flag instead of
         // linking all deps statically into the dylib.
@@ -258,13 +264,6 @@ fn main() {
             }
         }
 
-        // Force all crates compiled by this compiler to (a) be unstable and (b)
-        // allow the `rustc_private` feature to link to other unstable crates
-        // also in the sysroot.
-        if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() {
-            cmd.arg("-Z").arg("force-unstable-if-unmarked");
-        }
-
         if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") {
             cmd.arg("--remap-path-prefix").arg(&map);
         }
@@ -284,6 +283,14 @@ fn main() {
         }
     }
 
+    // Force all crates compiled by this compiler to (a) be unstable and (b)
+    // allow the `rustc_private` feature to link to other unstable crates
+    // also in the sysroot. We also do this for host crates, since those
+    // may be proc macros, in which case we might ship them.
+    if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() && (stage != "0" || target.is_some()) {
+        cmd.arg("-Z").arg("force-unstable-if-unmarked");
+    }
+
     if env::var_os("RUSTC_PARALLEL_COMPILER").is_some() {
         cmd.arg("--cfg").arg("parallel_compiler");
     }
index c98d8b8ecf4370b12412f1ebcd96ab571dad3cae..8af7aa4856c381c196466407833370e7841c7ac1 100644 (file)
@@ -262,6 +262,10 @@ def default_build_triple():
         cputype = 'arm'
         if ostype == 'linux-android':
             ostype = 'linux-androideabi'
+        elif ostype == 'unknown-freebsd':
+            cputype = subprocess.check_output(
+                ['uname', '-p']).strip().decode(default_encoding)
+            ostype = 'unknown-freebsd'
     elif cputype == 'armv6l':
         cputype = 'arm'
         if ostype == 'linux-android':
index 7e6c0a9f52aa21bb1d6f28edd335ff34203f81c5..eb1a2a59fa3c52590de053f125b07b86f1904476 100644 (file)
@@ -812,6 +812,17 @@ pub fn cargo(
             cargo.env("RUST_CHECK", "1");
         }
 
+        match mode {
+            Mode::Std | Mode::Test | Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolTest=> {},
+            Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
+                // Build proc macros both for the host and the target
+                if target != compiler.host && cmd != "check" {
+                    cargo.arg("-Zdual-proc-macros");
+                    cargo.env("RUST_DUAL_PROC_MACROS", "1");
+                }
+            },
+        }
+
         cargo.arg("-j").arg(self.jobs().to_string());
         // Remove make-related flags to ensure Cargo can correctly set things up
         cargo.env_remove("MAKEFLAGS");
index 0b2f62485c9ee18094047e27b3c2b9e205d007bc..aa683161b6547fe5a47f102c9b6eb1078998bda4 100644 (file)
@@ -14,7 +14,7 @@
 use crate::config::Config;
 
 // The version number
-pub const CFG_RELEASE_NUM: &str = "1.34.0";
+pub const CFG_RELEASE_NUM: &str = "1.35.0";
 
 pub struct GitInfo {
     inner: Option<Info>,
index 20370372082b94ef009ab1408ad143ff28423799..a30b465698e2a263b40b10f7ef6b7a33dd3442a4 100644 (file)
@@ -42,7 +42,8 @@ fn run(self, builder: &Builder<'_>) {
                   true);
 
         let libdir = builder.sysroot_libdir(compiler, target);
-        add_to_sysroot(&builder, &libdir, &libstd_stamp(builder, compiler, target));
+        let hostdir = builder.sysroot_libdir(compiler, compiler.host);
+        add_to_sysroot(&builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
     }
 }
 
@@ -88,7 +89,8 @@ fn run(self, builder: &Builder<'_>) {
                   true);
 
         let libdir = builder.sysroot_libdir(compiler, target);
-        add_to_sysroot(&builder, &libdir, &librustc_stamp(builder, compiler, target));
+        let hostdir = builder.sysroot_libdir(compiler, compiler.host);
+        add_to_sysroot(&builder, &libdir, &hostdir, &librustc_stamp(builder, compiler, target));
     }
 }
 
@@ -175,7 +177,8 @@ fn run(self, builder: &Builder<'_>) {
                   true);
 
         let libdir = builder.sysroot_libdir(compiler, target);
-        add_to_sysroot(builder, &libdir, &libtest_stamp(builder, compiler, target));
+        let hostdir = builder.sysroot_libdir(compiler, compiler.host);
+        add_to_sysroot(builder, &libdir, &hostdir, &libtest_stamp(builder, compiler, target));
     }
 }
 
@@ -222,7 +225,8 @@ fn run(self, builder: &Builder<'_>) {
                   true);
 
         let libdir = builder.sysroot_libdir(compiler, target);
-        add_to_sysroot(&builder, &libdir, &rustdoc_stamp(builder, compiler, target));
+        let hostdir = builder.sysroot_libdir(compiler, compiler.host);
+        add_to_sysroot(&builder, &libdir, &hostdir, &rustdoc_stamp(builder, compiler, target));
         builder.cargo(compiler, Mode::ToolRustc, target, "clean");
     }
 }
index 249a18318904831ff362d09da4ed8854858b4d5f..9498dbb59523294c9a1ec26fca48757fb4245939 100644 (file)
@@ -224,7 +224,8 @@ fn run(self, builder: &Builder<'_>) {
                 target_compiler.host,
                 target));
         let libdir = builder.sysroot_libdir(target_compiler, target);
-        add_to_sysroot(builder, &libdir, &libstd_stamp(builder, compiler, target));
+        let hostdir = builder.sysroot_libdir(target_compiler, compiler.host);
+        add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
 
         if builder.config.sanitizers && compiler.stage != 0 && target == "x86_64-apple-darwin" {
             // The sanitizers are only built in stage1 or above, so the dylibs will
@@ -431,8 +432,12 @@ fn run(self, builder: &Builder<'_>) {
                 &compiler.host,
                 target_compiler.host,
                 target));
-        add_to_sysroot(builder, &builder.sysroot_libdir(target_compiler, target),
-                    &libtest_stamp(builder, compiler, target));
+        add_to_sysroot(
+            builder,
+            &builder.sysroot_libdir(target_compiler, target),
+            &builder.sysroot_libdir(target_compiler, compiler.host),
+            &libtest_stamp(builder, compiler, target)
+        );
 
         builder.cargo(target_compiler, Mode::ToolTest, target, "clean");
     }
@@ -496,8 +501,8 @@ fn run(self, builder: &Builder<'_>) {
             return;
         }
 
-        // Ensure that build scripts have a std to link against.
-        builder.ensure(Std {
+        // Ensure that build scripts and proc macros have a std / libproc_macro to link against.
+        builder.ensure(Test {
             compiler: builder.compiler(self.compiler.stage, builder.config.build),
             target: builder.config.build,
         });
@@ -592,8 +597,12 @@ fn run(self, builder: &Builder<'_>) {
                  &compiler.host,
                  target_compiler.host,
                  target));
-        add_to_sysroot(builder, &builder.sysroot_libdir(target_compiler, target),
-                       &librustc_stamp(builder, compiler, target));
+        add_to_sysroot(
+            builder,
+            &builder.sysroot_libdir(target_compiler, target),
+            &builder.sysroot_libdir(target_compiler, compiler.host),
+            &librustc_stamp(builder, compiler, target)
+        );
         builder.cargo(target_compiler, Mode::ToolRustc, target, "clean");
     }
 }
@@ -1015,10 +1024,20 @@ fn run(self, builder: &Builder<'_>) -> Compiler {
 ///
 /// For a particular stage this will link the file listed in `stamp` into the
 /// `sysroot_dst` provided.
-pub fn add_to_sysroot(builder: &Builder<'_>, sysroot_dst: &Path, stamp: &Path) {
+pub fn add_to_sysroot(
+    builder: &Builder<'_>,
+    sysroot_dst: &Path,
+    sysroot_host_dst: &Path,
+    stamp: &Path
+) {
     t!(fs::create_dir_all(&sysroot_dst));
-    for path in builder.read_stamp_file(stamp) {
-        builder.copy(&path, &sysroot_dst.join(path.file_name().unwrap()));
+    t!(fs::create_dir_all(&sysroot_host_dst));
+    for (path, host) in builder.read_stamp_file(stamp) {
+        if host {
+            builder.copy(&path, &sysroot_host_dst.join(path.file_name().unwrap()));
+        } else {
+            builder.copy(&path, &sysroot_dst.join(path.file_name().unwrap()));
+        }
     }
 }
 
@@ -1047,8 +1066,14 @@ pub fn run_cargo(builder: &Builder<'_>,
     let mut deps = Vec::new();
     let mut toplevel = Vec::new();
     let ok = stream_cargo(builder, cargo, &mut |msg| {
-        let filenames = match msg {
-            CargoMessage::CompilerArtifact { filenames, .. } => filenames,
+        let (filenames, crate_types) = match msg {
+            CargoMessage::CompilerArtifact {
+                filenames,
+                target: CargoTarget {
+                    crate_types,
+                },
+                ..
+            } => (filenames, crate_types),
             _ => return,
         };
         for filename in filenames {
@@ -1063,15 +1088,19 @@ pub fn run_cargo(builder: &Builder<'_>,
             let filename = Path::new(&*filename);
 
             // If this was an output file in the "host dir" we don't actually
-            // worry about it, it's not relevant for us.
+            // worry about it, it's not relevant for us
             if filename.starts_with(&host_root_dir) {
+                // Unless it's a proc macro used in the compiler
+                if crate_types.iter().any(|t| t == "proc-macro") {
+                    deps.push((filename.to_path_buf(), true));
+                }
                 continue;
             }
 
             // If this was output in the `deps` dir then this is a precise file
             // name (hash included) so we start tracking it.
             if filename.starts_with(&target_deps_dir) {
-                deps.push(filename.to_path_buf());
+                deps.push((filename.to_path_buf(), false));
                 continue;
             }
 
@@ -1124,10 +1153,10 @@ pub fn run_cargo(builder: &Builder<'_>,
             let candidate = format!("{}.lib", path_to_add);
             let candidate = PathBuf::from(candidate);
             if candidate.exists() {
-                deps.push(candidate);
+                deps.push((candidate, false));
             }
         }
-        deps.push(path_to_add.into());
+        deps.push((path_to_add.into(), false));
     }
 
     // Now we want to update the contents of the stamp file, if necessary. First
@@ -1140,12 +1169,13 @@ pub fn run_cargo(builder: &Builder<'_>,
     let mut new_contents = Vec::new();
     let mut max = None;
     let mut max_path = None;
-    for dep in deps.iter() {
+    for (dep, proc_macro) in deps.iter() {
         let mtime = mtime(dep);
         if Some(mtime) > max {
             max = Some(mtime);
             max_path = Some(dep.clone());
         }
+        new_contents.extend(if *proc_macro { b"h" } else { b"t" });
         new_contents.extend(dep.to_str().unwrap().as_bytes());
         new_contents.extend(b"\0");
     }
@@ -1157,7 +1187,7 @@ pub fn run_cargo(builder: &Builder<'_>,
     if contents_equal && max <= stamp_mtime {
         builder.verbose(&format!("not updating {:?}; contents equal and {:?} <= {:?}",
                 stamp, max, stamp_mtime));
-        return deps
+        return deps.into_iter().map(|(d, _)| d).collect()
     }
     if max > stamp_mtime {
         builder.verbose(&format!("updating {:?} as {:?} changed", stamp, max_path));
@@ -1165,7 +1195,7 @@ pub fn run_cargo(builder: &Builder<'_>,
         builder.verbose(&format!("updating {:?} as deps changed", stamp));
     }
     t!(fs::write(&stamp, &new_contents));
-    deps
+    deps.into_iter().map(|(d, _)| d).collect()
 }
 
 pub fn stream_cargo(
@@ -1211,6 +1241,11 @@ pub fn stream_cargo(
     status.success()
 }
 
+#[derive(Deserialize)]
+pub struct CargoTarget<'a> {
+    crate_types: Vec<Cow<'a, str>>,
+}
+
 #[derive(Deserialize)]
 #[serde(tag = "reason", rename_all = "kebab-case")]
 pub enum CargoMessage<'a> {
@@ -1218,6 +1253,7 @@ pub enum CargoMessage<'a> {
         package_id: Cow<'a, str>,
         features: Vec<Cow<'a, str>>,
         filenames: Vec<Cow<'a, str>>,
+        target: CargoTarget<'a>,
     },
     BuildScriptExecuted {
         package_id: Cow<'a, str>,
index 2dae3f9135d8448a2d9a598b0adc430aa825cb4d..2c40dd6d2961d49ab6838708ef7b05516cef5563 100644 (file)
@@ -904,6 +904,8 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
             "src/stdsimd",
             "src/libproc_macro",
             "src/tools/rustc-std-workspace-core",
+            "src/librustc",
+            "src/libsyntax",
         ];
 
         copy_src_dirs(builder, &std_src_dirs[..], &[], &dst_src);
index 40f0e5ede8bd7ce41a90d8265024d237ae383910..e0ad0422a6ce30acc69cb07828af0c36cb2c285d 100644 (file)
@@ -60,7 +60,7 @@ fn run(self, builder: &Builder<'_>) {
 // NOTE: When adding a book here, make sure to ALSO build the book by
 // adding a build step in `src/bootstrap/builder.rs`!
 book!(
-    EditionGuide, "src/doc/edition-guide", "edition-guide", RustbookVersion::MdBook1;
+    EditionGuide, "src/doc/edition-guide", "edition-guide", RustbookVersion::MdBook2;
     EmbeddedBook, "src/doc/embedded-book", "embedded-book", RustbookVersion::MdBook2;
     Nomicon, "src/doc/nomicon", "nomicon", RustbookVersion::MdBook1;
     Reference, "src/doc/reference", "reference", RustbookVersion::MdBook1;
index 84e2c5aab54a33bfb4926c865512eb3d36e95f60..9317a40545eac9f2b4c208223bc92c31c0227e1b 100644 (file)
@@ -1129,7 +1129,7 @@ fn in_tree_crates(&self, root: &str) -> Vec<&Crate> {
         ret
     }
 
-    fn read_stamp_file(&self, stamp: &Path) -> Vec<PathBuf> {
+    fn read_stamp_file(&self, stamp: &Path) -> Vec<(PathBuf, bool)> {
         if self.config.dry_run {
             return Vec::new();
         }
@@ -1142,8 +1142,9 @@ fn read_stamp_file(&self, stamp: &Path) -> Vec<PathBuf> {
             if part.is_empty() {
                 continue
             }
-            let path = PathBuf::from(t!(str::from_utf8(part)));
-            paths.push(path);
+            let host = part[0] as char == 'h';
+            let path = PathBuf::from(t!(str::from_utf8(&part[1..])));
+            paths.push((path, host));
         }
         paths
     }
index fc1a17d54667540c7c5681f8866124721dd76720..9dbcacf70262c131f32a6608a6d8e0c9665f329f 100644 (file)
@@ -91,7 +91,8 @@ fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
                 compile::CargoMessage::CompilerArtifact {
                     package_id,
                     features,
-                    filenames
+                    filenames,
+                    target: _,
                 } => {
                     (package_id, features, filenames)
                 }
index 4fe7e2cca2b6009577b7a51179d2ed9e8168e400..44b1aaa24b19d9747bf4a8ed81cba44533ee7f70 100644 (file)
@@ -3,23 +3,8 @@ FROM ubuntu:16.04
 COPY scripts/cross-apt-packages.sh /scripts/
 RUN sh /scripts/cross-apt-packages.sh
 
-# Ubuntu 16.04 (this container) ships with make 4, but something in the
-# toolchains we build below chokes on that, so go back to make 3
-COPY scripts/make3.sh /scripts/
-RUN sh /scripts/make3.sh
-
-COPY scripts/crosstool-ng.sh /scripts/
-RUN sh /scripts/crosstool-ng.sh
-
-COPY scripts/rustbuild-setup.sh /scripts/
-RUN sh /scripts/rustbuild-setup.sh
-USER rustbuild
-WORKDIR /tmp
-
 COPY dist-x86_64-netbsd/build-netbsd-toolchain.sh /tmp/
-RUN ./build-netbsd-toolchain.sh
-
-USER root
+RUN /tmp/build-netbsd-toolchain.sh
 
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
@@ -33,6 +18,5 @@ ENV \
 
 ENV HOSTS=x86_64-unknown-netbsd
 
-ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs \
-  --set llvm.allow-old-toolchain
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
index ac92d68a1f501804c5617cf443deaa6bac542bad..b5377c64b1f546a0b3470d4db5fbfd152903bf4f 100755 (executable)
@@ -28,15 +28,15 @@ mkdir -p /x-tools/x86_64-unknown-netbsd/sysroot
 URL=https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror
 
 # Originally from ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-$BSD/source/sets/*.tgz
-curl $URL/2017-03-17-netbsd-src.tgz | tar xzf -
-curl $URL/2017-03-17-netbsd-gnusrc.tgz | tar xzf -
-curl $URL/2017-03-17-netbsd-sharesrc.tgz | tar xzf -
-curl $URL/2017-03-17-netbsd-syssrc.tgz | tar xzf -
+curl $URL/2018-03-01-netbsd-src.tgz | tar xzf -
+curl $URL/2018-03-01-netbsd-gnusrc.tgz | tar xzf -
+curl $URL/2018-03-01-netbsd-sharesrc.tgz | tar xzf -
+curl $URL/2018-03-01-netbsd-syssrc.tgz | tar xzf -
 
 # Originally from ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-$BSD/amd64/binary/sets/*.tgz
-curl $URL/2017-03-17-netbsd-base.tgz | \
+curl $URL/2018-03-01-netbsd-base.tgz | \
   tar xzf - -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib ./lib
-curl $URL/2017-03-17-netbsd-comp.tgz | \
+curl $URL/2018-03-01-netbsd-comp.tgz | \
   tar xzf - -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib
 
 cd usr/src
index 419edb885ec1a98c0747b3907003d79e3e6b93a9..5f3cc2a5618700efcde3bc00799744f21fa9ad2e 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 419edb885ec1a98c0747b3907003d79e3e6b93a9
+Subproject commit 5f3cc2a5618700efcde3bc00799744f21fa9ad2e
index eb3410078513de3e25a945caaf58645462afab1f..dd128e096f952c521c67816020ecdbddee54c012 100644 (file)
@@ -34,8 +34,7 @@
 #[cfg(not(test))]
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(stage0), allow_internal_unstable(box_syntax))]
-#[cfg_attr(stage0, allow_internal_unstable)]
+#[allow_internal_unstable(box_syntax)]
 macro_rules! vec {
     ($elem:expr; $n:expr) => (
         $crate::vec::from_elem($elem, $n)
index 229dafc5fdc3a7d8fc7f6145e081eccad7ce906b..947ce354ae711b279e4d8d830799466cb97fb95b 100644 (file)
@@ -1260,7 +1260,7 @@ pub fn split_off(&mut self, at: usize) -> Self {
     /// This method uses a closure to create new values on every push. If
     /// you'd rather [`Clone`] a given value, use [`resize`]. If you want
     /// to use the [`Default`] trait to generate values, you can pass
-    /// [`Default::default()`] as the second argument..
+    /// [`Default::default()`] as the second argument.
     ///
     /// # Examples
     ///
index fe852e42b5cd3721b959734652956a4c100b63b1..1dd2bd3ee78aa67a548bb6625d4703109b396f1b 100644 (file)
@@ -185,13 +185,13 @@ fn $bench_ref_sum(b: &mut Bencher) {
 bench_sums! {
     bench_filter_sum,
     bench_filter_ref_sum,
-    (0i64..1000000).filter(|x| x % 2 == 0)
+    (0i64..1000000).filter(|x| x % 3 == 0)
 }
 
 bench_sums! {
     bench_filter_chain_sum,
     bench_filter_chain_ref_sum,
-    (0i64..1000000).chain(0..1000000).filter(|x| x % 2 == 0)
+    (0i64..1000000).chain(0..1000000).filter(|x| x % 3 == 0)
 }
 
 bench_sums! {
@@ -306,3 +306,31 @@ fn bench_skip_then_zip(b: &mut Bencher) {
         assert_eq!(s, 2009900);
     });
 }
+
+#[bench]
+fn bench_filter_count(b: &mut Bencher) {
+    b.iter(|| {
+        (0i64..1000000).map(black_box).filter(|x| x % 3 == 0).count()
+    })
+}
+
+#[bench]
+fn bench_filter_ref_count(b: &mut Bencher) {
+    b.iter(|| {
+        (0i64..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count()
+    })
+}
+
+#[bench]
+fn bench_filter_chain_count(b: &mut Bencher) {
+    b.iter(|| {
+        (0i64..1000000).chain(0..1000000).map(black_box).filter(|x| x % 3 == 0).count()
+    })
+}
+
+#[bench]
+fn bench_filter_chain_ref_count(b: &mut Bencher) {
+    b.iter(|| {
+        (0i64..1000000).chain(0..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count()
+    })
+}
index e6098b1b24cc0b9a3d6ce9b9fd3b13d4573b589c..75a33394e3d2f6edb4f74ec08415c8348a7b292b 100644 (file)
@@ -1282,13 +1282,11 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `saturating_add` method. For example,
     /// [`std::u32::saturating_add`](../../std/primitive.u32.html#method.saturating_add)
-    #[cfg(not(stage0))]
     pub fn saturating_add<T>(a: T, b: T) -> T;
     /// Computes `a - b`, while saturating at numeric bounds.
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `saturating_sub` method. For example,
     /// [`std::u32::saturating_sub`](../../std/primitive.u32.html#method.saturating_sub)
-    #[cfg(not(stage0))]
     pub fn saturating_sub<T>(a: T, b: T) -> T;
 
     /// Returns the value of the discriminant for the variant in 'v',
index bca1b76dbb97514acd74de7a0a130533cbf548c6..d4ad22c16bbfa697458af3c5d2e7882be0588bc8 100644 (file)
@@ -681,12 +681,7 @@ impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
 
     #[inline]
     fn next(&mut self) -> Option<I::Item> {
-        for x in &mut self.iter {
-            if (self.predicate)(&x) {
-                return Some(x);
-            }
-        }
-        None
+        self.try_for_each(Err).err()
     }
 
     #[inline]
@@ -707,12 +702,9 @@ fn size_hint(&self) -> (usize, Option<usize>) {
     // Using the branchless version will also simplify the LLVM byte code, thus
     // leaving more budget for LLVM optimizations.
     #[inline]
-    fn count(mut self) -> usize {
-        let mut count = 0;
-        for x in &mut self.iter {
-            count += (self.predicate)(&x) as usize;
-        }
-        count
+    fn count(self) -> usize {
+        let mut predicate = self.predicate;
+        self.iter.map(|x| predicate(&x) as usize).sum()
     }
 
     #[inline]
@@ -746,12 +738,7 @@ impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
 {
     #[inline]
     fn next_back(&mut self) -> Option<I::Item> {
-        for x in self.iter.by_ref().rev() {
-            if (self.predicate)(&x) {
-                return Some(x);
-            }
-        }
-        None
+        self.try_rfold((), |_, x| Err(x)).err()
     }
 
     #[inline]
@@ -820,12 +807,7 @@ impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
 
     #[inline]
     fn next(&mut self) -> Option<B> {
-        for x in self.iter.by_ref() {
-            if let Some(y) = (self.f)(x) {
-                return Some(y);
-            }
-        }
-        None
+        self.try_for_each(Err).err()
     }
 
     #[inline]
@@ -863,12 +845,7 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
 {
     #[inline]
     fn next_back(&mut self) -> Option<B> {
-        for x in self.iter.by_ref().rev() {
-            if let Some(y) = (self.f)(x) {
-                return Some(y);
-            }
-        }
-        None
+        self.try_rfold((), |_, x| Err(x)).err()
     }
 
     #[inline]
index fdbfa56000b8ebbc32c5fafea80c1e78cee8f152..b052f59b0f5c2ae07f2f178764012852fae66ac5 100644 (file)
@@ -1,7 +1,6 @@
 /// Entry point of thread panic. For details, see `std::macros`.
 #[macro_export]
-#[cfg_attr(not(stage0), allow_internal_unstable(core_panic, __rust_unstable_column))]
-#[cfg_attr(stage0, allow_internal_unstable)]
+#[allow_internal_unstable(core_panic, __rust_unstable_column)]
 #[stable(feature = "core", since = "1.6.0")]
 macro_rules! panic {
     () => (
@@ -422,8 +421,7 @@ macro_rules! write {
 /// ```
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(stage0, allow_internal_unstable)]
-#[cfg_attr(not(stage0), allow_internal_unstable(format_args_nl))]
+#[allow_internal_unstable(format_args_nl)]
 macro_rules! writeln {
     ($dst:expr) => (
         write!($dst, "\n")
index 29606cb19038f46dd402b7cc86afd7a1ec9c05b3..9b1ead7edd68b03d6dd4cd7bc1b8f6ede6e32ab3 100644 (file)
@@ -636,7 +636,7 @@ unsafe impl<T: ?Sized> Freeze for &mut T {}
 /// [`Pin<P>`]: ../pin/struct.Pin.html
 /// [`pin module`]: ../../std/pin/index.html
 #[stable(feature = "pin", since = "1.33.0")]
-#[cfg_attr(not(stage0), lang = "unpin")]
+#[lang = "unpin"]
 pub auto trait Unpin {}
 
 /// A marker type which does not implement `Unpin`.
index f41d293e80ad3da86b45c6a069734d50eff5a892..94f342e7e8efc6a575184b89027e5a7ce28a2a74 100644 (file)
@@ -900,10 +900,16 @@ pub fn discriminant<T>(v: &T) -> Discriminant<T> {
     }
 }
 
+// FIXME: Reference `MaybeUninit` from these docs, once that is stable.
 /// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
 ///
 /// This wrapper is 0-cost.
 ///
+/// `ManuallyDrop<T>` is subject to the same layout optimizations as `T`.
+/// As a consequence, it has *no effect* on the assumptions that the compiler makes
+/// about all values being initialized at their type.  In particular, initializing
+/// a `ManuallyDrop<&mut T>` with [`mem::zeroed`] is undefined behavior.
+///
 /// # Examples
 ///
 /// This wrapper helps with explicitly documenting the drop order dependencies between fields of
@@ -935,6 +941,8 @@ pub fn discriminant<T>(v: &T) -> Discriminant<T> {
 ///     }
 /// }
 /// ```
+///
+/// [`mem::zeroed`]: fn.zeroed.html
 #[stable(feature = "manually_drop", since = "1.20.0")]
 #[lang = "manually_drop"]
 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
index 6708a195f88c53fdeaa508ff63d0607c7ce0de59..502e3de8c637d2a49075a4268d72044628fa4f64 100644 (file)
@@ -874,33 +874,6 @@ pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
 
 Basic usage:
 
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
-assert_eq!(", stringify!($SelfT), "::max_value().saturating_add(100), ", stringify!($SelfT),
-"::max_value());",
-$EndFeature, "
-```"),
-            #[stable(feature = "rust1", since = "1.0.0")]
-            #[inline]
-            #[cfg(stage0)]
-            pub fn saturating_add(self, rhs: Self) -> Self {
-                match self.checked_add(rhs) {
-                    Some(x) => x,
-                    None if rhs >= 0 => Self::max_value(),
-                    None => Self::min_value(),
-                }
-            }
-
-        }
-
-        doc_comment! {
-            concat!("Saturating integer addition. Computes `self + rhs`, saturating at the numeric
-bounds instead of overflowing.
-
-# Examples
-
-Basic usage:
-
 ```
 ", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
 assert_eq!(", stringify!($SelfT), "::max_value().saturating_add(100), ", stringify!($SelfT),
@@ -911,37 +884,11 @@ pub fn saturating_add(self, rhs: Self) -> Self {
             #[stable(feature = "rust1", since = "1.0.0")]
             #[rustc_const_unstable(feature = "const_saturating_int_methods")]
             #[inline]
-            #[cfg(not(stage0))]
             pub const fn saturating_add(self, rhs: Self) -> Self {
                 intrinsics::saturating_add(self, rhs)
             }
         }
 
-        doc_comment! {
-            concat!("Saturating integer subtraction. Computes `self - rhs`, saturating at the
-numeric bounds instead of overflowing.
-
-# Examples
-
-Basic usage:
-
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(127), -27);
-assert_eq!(", stringify!($SelfT), "::min_value().saturating_sub(100), ", stringify!($SelfT),
-"::min_value());",
-$EndFeature, "
-```"),
-            #[stable(feature = "rust1", since = "1.0.0")]
-            #[inline]
-            #[cfg(stage0)]
-            pub fn saturating_sub(self, rhs: Self) -> Self {
-                match self.checked_sub(rhs) {
-                    Some(x) => x,
-                    None if rhs >= 0 => Self::min_value(),
-                    None => Self::max_value(),
-                }
-            }
-        }
 
         doc_comment! {
             concat!("Saturating integer subtraction. Computes `self - rhs`, saturating at the
@@ -960,7 +907,6 @@ pub fn saturating_sub(self, rhs: Self) -> Self {
             #[stable(feature = "rust1", since = "1.0.0")]
             #[rustc_const_unstable(feature = "const_saturating_int_methods")]
             #[inline]
-            #[cfg(not(stage0))]
             pub const fn saturating_sub(self, rhs: Self) -> Self {
                 intrinsics::saturating_sub(self, rhs)
             }
@@ -2780,29 +2726,6 @@ pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
 
 Basic usage:
 
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
-assert_eq!(200u8.saturating_add(127), 255);", $EndFeature, "
-```"),
-            #[stable(feature = "rust1", since = "1.0.0")]
-            #[inline]
-            #[cfg(stage0)]
-            pub fn saturating_add(self, rhs: Self) -> Self {
-                match self.checked_add(rhs) {
-                    Some(x) => x,
-                    None => Self::max_value(),
-                }
-            }
-        }
-
-        doc_comment! {
-            concat!("Saturating integer addition. Computes `self + rhs`, saturating at
-the numeric bounds instead of overflowing.
-
-# Examples
-
-Basic usage:
-
 ```
 ", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
 assert_eq!(200u8.saturating_add(127), 255);", $EndFeature, "
@@ -2811,7 +2734,6 @@ pub fn saturating_add(self, rhs: Self) -> Self {
             #[stable(feature = "rust1", since = "1.0.0")]
             #[rustc_const_unstable(feature = "const_saturating_int_methods")]
             #[inline]
-            #[cfg(not(stage0))]
             pub const fn saturating_add(self, rhs: Self) -> Self {
                 intrinsics::saturating_add(self, rhs)
             }
@@ -2825,29 +2747,6 @@ pub const fn saturating_add(self, rhs: Self) -> Self {
 
 Basic usage:
 
-```
-", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(27), 73);
-assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);", $EndFeature, "
-```"),
-            #[stable(feature = "rust1", since = "1.0.0")]
-            #[inline]
-            #[cfg(stage0)]
-            pub fn saturating_sub(self, rhs: Self) -> Self {
-                match self.checked_sub(rhs) {
-                    Some(x) => x,
-                    None => Self::min_value(),
-                }
-            }
-        }
-
-        doc_comment! {
-            concat!("Saturating integer subtraction. Computes `self - rhs`, saturating
-at the numeric bounds instead of overflowing.
-
-# Examples
-
-Basic usage:
-
 ```
 ", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(27), 73);
 assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);", $EndFeature, "
@@ -2855,7 +2754,6 @@ pub fn saturating_sub(self, rhs: Self) -> Self {
             #[stable(feature = "rust1", since = "1.0.0")]
             #[rustc_const_unstable(feature = "const_saturating_int_methods")]
             #[inline]
-            #[cfg(not(stage0))]
             pub const fn saturating_sub(self, rhs: Self) -> Self {
                 intrinsics::saturating_sub(self, rhs)
             }
index 60aed7ce09d7f1c825c4c6512ad3ea58aeef5d4d..46dfe28da622c451f8e4c3fe9fa54d927e151227 100644 (file)
@@ -1286,7 +1286,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
     /// # Examples
     ///
     /// Here is an example which increments every integer in a vector.
-    /// `We use the checked variant of `add` that returns `None` when the
+    /// We use the checked variant of `add` that returns `None` when the
     /// calculation would result in an overflow.
     ///
     /// ```
index f9f20dcea9e2ea86f5493232a28062ed6e0742dc..fb78f5e5a238424764e7460bbbdc450d6dd7e7a1 100644 (file)
 //!     had a method `fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T>`.
 //!     Then we could do the following:
 //!     ```compile_fail
-//!     fn exploit_ref_cell<T>(rc: Pin<&mut RefCell<T>) {
+//!     fn exploit_ref_cell<T>(rc: Pin<&mut RefCell<T>>) {
 //!         { let p = rc.as_mut().get_pin_mut(); } // Here we get pinned access to the `T`.
 //!         let rc_shr: &RefCell<T> = rc.into_ref().get_ref();
 //!         let b = rc_shr.borrow_mut();
 // implementations, are allowed because they all only use `&P`, so they cannot move
 // the value behind `pointer`.
 #[stable(feature = "pin", since = "1.33.0")]
-#[cfg_attr(not(stage0), lang = "pin")]
+#[lang = "pin"]
 #[fundamental]
 #[repr(transparent)]
 #[derive(Copy, Clone, Hash, Eq, Ord)]
index 8b51d8465141afbd0c1b898e1358086217460463..53334adadb856d83a4888393c5fc00a5663a0a0d 100644 (file)
@@ -3965,7 +3965,7 @@ pub fn make_ascii_lowercase(&mut self) {
         me.make_ascii_lowercase()
     }
 
-    /// Return an iterator that escapes each char in `s` with [`char::escape_debug`].
+    /// Return an iterator that escapes each char in `self` with [`char::escape_debug`].
     ///
     /// Note: only extended grapheme codepoints that begin the string will be
     /// escaped.
@@ -4013,7 +4013,7 @@ pub fn escape_debug(&self) -> EscapeDebug {
         }
     }
 
-    /// Return an iterator that escapes each char in `s` with [`char::escape_default`].
+    /// Return an iterator that escapes each char in `self` with [`char::escape_default`].
     ///
     /// [`char::escape_default`]: ../std/primitive.char.html#method.escape_default
     ///
@@ -4051,7 +4051,7 @@ pub fn escape_default(&self) -> EscapeDefault {
         EscapeDefault { inner: self.chars().flat_map(CharEscapeDefault) }
     }
 
-    /// Return an iterator that escapes each char in `s` with [`char::escape_unicode`].
+    /// Return an iterator that escapes each char in `self` with [`char::escape_unicode`].
     ///
     /// [`char::escape_unicode`]: ../std/primitive.char.html#method.escape_unicode
     ///
index d0ee5fa9e6b316d172030e1f9ea95b92951599c2..04a49d253015f439913b542367db8a5a02cdff3a 100644 (file)
@@ -290,15 +290,11 @@ pub enum Ordering {
 /// [`AtomicBool`]: struct.AtomicBool.html
 #[cfg(target_has_atomic = "8")]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(stage0), rustc_deprecated(
+#[rustc_deprecated(
     since = "1.34.0",
     reason = "the `new` function is now preferred",
     suggestion = "AtomicBool::new(false)",
-))]
-#[cfg_attr(stage0, rustc_deprecated(
-    since = "1.34.0",
-    reason = "the `new` function is now preferred",
-))]
+)]
 pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
 
 #[cfg(target_has_atomic = "8")]
@@ -1158,15 +1154,11 @@ pub struct $atomic_type {
 
         /// An atomic integer initialized to `0`.
         #[$stable_init_const]
-        #[cfg_attr(stage0, rustc_deprecated(
-            since = "1.34.0",
-            reason = "the `new` function is now preferred",
-        ))]
-        #[cfg_attr(not(stage0), rustc_deprecated(
+        #[rustc_deprecated(
             since = "1.34.0",
             reason = "the `new` function is now preferred",
             suggestion = $atomic_new,
-        ))]
+        )]
         pub const $atomic_init: $atomic_type = $atomic_type::new(0);
 
         #[$stable]
index e3557132a1252b770742a619efa1d930869d94ad..31e10c19c7a60599351cd664673d9cb8f0fa60dd 100644 (file)
@@ -20,10 +20,11 @@ num_cpus = "1.0"
 scoped-tls = "1.0"
 log = { version = "0.4", features = ["release_max_level_info", "std"] }
 polonius-engine = "0.6.2"
-rustc-rayon = "0.1.1"
-rustc-rayon-core = "0.1.1"
+rustc-rayon = "0.1.2"
+rustc-rayon-core = "0.1.2"
 rustc_apfloat = { path = "../librustc_apfloat" }
 rustc_target = { path = "../librustc_target" }
+rustc_macros = { path = "../librustc_macros" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 errors = { path = "../librustc_errors", package = "rustc_errors" }
 serialize = { path = "../libserialize" }
index ddc1eebe645ae4b3cbba047bea93ec7f47cd3749..8b304007a3572bbc5ca5bc9cd12edf11911c6ff9 100644 (file)
@@ -94,7 +94,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
     /// Checks any attribute.
     fn check_attributes(&self, item: &hir::Item, target: Target) {
         if target == Target::Fn || target == Target::Const {
-            self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id(item.id));
+            self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id_from_hir_id(item.hir_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")
                 .span_label(item.span, "not a function")
index a97ea7da7f19cbf3d175a03322039e34ddad38ff..52ad800e81c6abf65e693802bccd980925a6d70f 100644 (file)
@@ -469,8 +469,8 @@ fn visit_item(&mut self, item: &'lcx Item) {
 
             fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
                 self.lctx.with_hir_id_owner(item.id, |lctx| {
-                    let id = hir::TraitItemId { node_id: item.id };
                     let hir_item = lctx.lower_trait_item(item);
+                    let id = hir::TraitItemId { hir_id: hir_item.hir_id };
                     lctx.trait_items.insert(id, hir_item);
                     lctx.modules.get_mut(&lctx.current_module).unwrap().trait_items.insert(id);
                 });
@@ -480,8 +480,8 @@ fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
 
             fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
                 self.lctx.with_hir_id_owner(item.id, |lctx| {
-                    let id = hir::ImplItemId { node_id: item.id };
                     let hir_item = lctx.lower_impl_item(item);
+                    let id = hir::ImplItemId { hir_id: hir_item.hir_id };
                     lctx.impl_items.insert(id, hir_item);
                     lctx.modules.get_mut(&lctx.current_module).unwrap().impl_items.insert(id);
                 });
@@ -1414,7 +1414,6 @@ fn lower_existential_impl_trait(
 
             trace!("exist ty def index: {:#?}", exist_ty_def_index);
             let exist_ty_item = hir::Item {
-                id: exist_ty_id.node_id,
                 hir_id: exist_ty_id.hir_id,
                 ident: keywords::Invalid.ident(),
                 attrs: Default::default(),
@@ -2675,7 +2674,7 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat
     fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
         match *vdata {
             VariantData::Struct(ref fields, id) => {
-                let LoweredNodeId { node_id, hir_id } = self.lower_node_id(id);
+                let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(id);
 
                 hir::VariantData::Struct(
                     fields
@@ -2683,12 +2682,11 @@ fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
                         .enumerate()
                         .map(|f| self.lower_struct_field(f))
                         .collect(),
-                    node_id,
                     hir_id,
                 )
             },
             VariantData::Tuple(ref fields, id) => {
-                let LoweredNodeId { node_id, hir_id } = self.lower_node_id(id);
+                let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(id);
 
                 hir::VariantData::Tuple(
                     fields
@@ -2696,14 +2694,13 @@ fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
                         .enumerate()
                         .map(|f| self.lower_struct_field(f))
                         .collect(),
-                    node_id,
                     hir_id,
                 )
             },
             VariantData::Unit(id) => {
-                let LoweredNodeId { node_id, hir_id } = self.lower_node_id(id);
+                let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(id);
 
-                hir::VariantData::Unit(node_id, hir_id)
+                hir::VariantData::Unit(hir_id)
             },
         }
     }
@@ -2743,11 +2740,10 @@ fn lower_poly_trait_ref(
     }
 
     fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField {
-        let LoweredNodeId { node_id, hir_id } = self.lower_node_id(f.id);
+        let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(f.id);
 
         hir::StructField {
             span: f.span,
-            id: node_id,
             hir_id,
             ident: match f.ident {
                 Some(ident) => ident,
@@ -3129,7 +3125,6 @@ fn lower_use_tree(
                         this.insert_item(
                             new_id.node_id,
                             hir::Item {
-                                id: new_id.node_id,
                                 hir_id: new_id.hir_id,
                                 ident,
                                 attrs: attrs.clone(),
@@ -3235,7 +3230,6 @@ fn lower_use_tree(
                         this.insert_item(
                             new_id,
                             hir::Item {
-                                id: new_id,
                                 hir_id: new_hir_id,
                                 ident,
                                 attrs: attrs.clone(),
@@ -3369,7 +3363,7 @@ fn lower_trait_item_ref(&mut self, i: &TraitItem) -> hir::TraitItemRef {
             TraitItemKind::Macro(..) => unimplemented!(),
         };
         hir::TraitItemRef {
-            id: hir::TraitItemId { node_id: i.id },
+            id: hir::TraitItemId { hir_id: self.lower_node_id(i.id).hir_id },
             ident: i.ident,
             span: i.span,
             defaultness: self.lower_defaultness(Defaultness::Default, has_default),
@@ -3433,7 +3427,7 @@ fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
 
     fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
         hir::ImplItemRef {
-            id: hir::ImplItemId { node_id: i.id },
+            id: hir::ImplItemId { hir_id: self.lower_node_id(i.id).hir_id },
             ident: i.ident,
             span: i.span,
             vis: self.lower_visibility(&i.vis, Some(i.id)),
@@ -3535,10 +3529,9 @@ pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
 
         let node = self.lower_item_kind(i.id, &mut ident, &attrs, &mut vis, &i.node);
 
-        let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id);
+        let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(i.id);
 
         Some(hir::Item {
-            id: node_id,
             hir_id,
             ident,
             attrs,
@@ -3552,7 +3545,6 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id);
         let def_id = self.resolver.definitions().local_def_id(node_id);
         hir::ForeignItem {
-            id: node_id,
             hir_id,
             ident: i.ident,
             attrs: self.lower_attrs(&i.attrs),
@@ -3746,12 +3738,11 @@ fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
                 let fs = fields
                     .iter()
                     .map(|f| {
-                        let LoweredNodeId { node_id, hir_id } = self.next_id();
+                        let LoweredNodeId { node_id: _, hir_id } = self.next_id();
 
                         Spanned {
                             span: f.span,
                             node: hir::FieldPat {
-                                id: node_id,
                                 hir_id,
                                 ident: f.node.ident,
                                 pat: self.lower_pat(&f.node.pat),
@@ -3783,9 +3774,8 @@ fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
             PatKind::Mac(_) => panic!("Shouldn't exist here"),
         };
 
-        let LoweredNodeId { node_id, hir_id } = self.lower_node_id(p.id);
+        let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(p.id);
         P(hir::Pat {
-            id: node_id,
             hir_id,
             node,
             span: p.span,
@@ -4359,7 +4349,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let iter = self.str_to_ident("iter");
 
                 let next_ident = self.str_to_ident("__next");
-                let next_pat = self.pat_ident_binding_mode(
+                let (next_pat, next_pat_nid) = self.pat_ident_binding_mode(
                     desugared_span,
                     next_ident,
                     hir::BindingAnnotation::Mutable,
@@ -4368,9 +4358,9 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 // `::std::option::Option::Some(val) => next = val`
                 let pat_arm = {
                     let val_ident = self.str_to_ident("val");
-                    let val_pat = self.pat_ident(pat.span, val_ident);
-                    let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat.id));
-                    let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat.id));
+                    let (val_pat, val_pat_nid) = self.pat_ident(pat.span, val_ident);
+                    let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat_nid));
+                    let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat_nid));
                     let assign = P(self.expr(
                         pat.span,
                         hir::ExprKind::Assign(next_expr, val_expr),
@@ -4389,7 +4379,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 };
 
                 // `mut iter`
-                let iter_pat = self.pat_ident_binding_mode(
+                let (iter_pat, iter_pat_nid) = self.pat_ident_binding_mode(
                     desugared_span,
                     iter,
                     hir::BindingAnnotation::Mutable
@@ -4397,7 +4387,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
 
                 // `match ::std::iter::Iterator::next(&mut iter) { ... }`
                 let match_expr = {
-                    let iter = P(self.expr_ident(head_sp, iter, iter_pat.id));
+                    let iter = P(self.expr_ident(head_sp, iter, iter_pat_nid));
                     let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter);
                     let next_path = &["iter", "Iterator", "next"];
                     let next_path = P(self.expr_std_path(head_sp, next_path, None, ThinVec::new()));
@@ -4421,7 +4411,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     span: head_sp,
                 };
 
-                let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat.id));
+                let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat_nid));
 
                 // `let mut __next`
                 let next_let = self.stmt_let_pat(
@@ -4548,11 +4538,11 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 // `Ok(val) => #[allow(unreachable_code)] val,`
                 let ok_arm = {
                     let val_ident = self.str_to_ident("val");
-                    let val_pat = self.pat_ident(e.span, val_ident);
+                    let (val_pat, val_pat_nid) = self.pat_ident(e.span, val_ident);
                     let val_expr = P(self.expr_ident_with_attrs(
                         e.span,
                         val_ident,
-                        val_pat.id,
+                        val_pat_nid,
                         ThinVec::from(attrs.clone()),
                     ));
                     let ok_pat = self.pat_ok(e.span, val_pat);
@@ -4564,12 +4554,12 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 //              return Try::from_error(From::from(err)),`
                 let err_arm = {
                     let err_ident = self.str_to_ident("err");
-                    let err_local = self.pat_ident(e.span, err_ident);
+                    let (err_local, err_local_nid) = self.pat_ident(e.span, err_ident);
                     let from_expr = {
                         let path = &["convert", "From", "from"];
                         let from = P(self.expr_std_path(
                                 e.span, path, None, ThinVec::new()));
-                        let err_expr = self.expr_ident(e.span, err_ident, err_local.id);
+                        let err_expr = self.expr_ident(e.span, err_ident, err_local_nid);
 
                         self.expr_call(e.span, from, hir_vec![err_expr])
                     };
@@ -4917,15 +4907,15 @@ fn stmt_let(
         ident: Ident,
         ex: P<hir::Expr>,
     ) -> (hir::Stmt, NodeId) {
-        let pat = if mutbl {
+        let (pat, pat_nid) = if mutbl {
             self.pat_ident_binding_mode(sp, ident, hir::BindingAnnotation::Mutable)
         } else {
             self.pat_ident(sp, ident)
         };
-        let pat_id = pat.id;
+
         (
             self.stmt_let_pat(sp, Some(ex), pat, hir::LocalSource::Normal),
-            pat_id,
+            pat_nid,
         )
     }
 
@@ -4983,7 +4973,7 @@ fn pat_std_enum(
         self.pat(span, pt)
     }
 
-    fn pat_ident(&mut self, span: Span, ident: Ident) -> P<hir::Pat> {
+    fn pat_ident(&mut self, span: Span, ident: Ident) -> (P<hir::Pat>, NodeId) {
         self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated)
     }
 
@@ -4992,15 +4982,17 @@ fn pat_ident_binding_mode(
         span: Span,
         ident: Ident,
         bm: hir::BindingAnnotation,
-    ) -> P<hir::Pat> {
+    ) -> (P<hir::Pat>, NodeId) {
         let LoweredNodeId { node_id, hir_id } = self.next_id();
 
-        P(hir::Pat {
-            id: node_id,
-            hir_id,
-            node: hir::PatKind::Binding(bm, node_id, hir_id, ident.with_span_pos(span), None),
-            span,
-        })
+        (
+            P(hir::Pat {
+                hir_id,
+                node: hir::PatKind::Binding(bm, node_id, hir_id, ident.with_span_pos(span), None),
+                span,
+            }),
+            node_id
+        )
     }
 
     fn pat_wild(&mut self, span: Span) -> P<hir::Pat> {
@@ -5008,9 +5000,8 @@ fn pat_wild(&mut self, span: Span) -> P<hir::Pat> {
     }
 
     fn pat(&mut self, span: Span, pat: hir::PatKind) -> P<hir::Pat> {
-        let LoweredNodeId { node_id, hir_id } = self.next_id();
+        let LoweredNodeId { node_id: _, hir_id } = self.next_id();
         P(hir::Pat {
-            id: node_id,
             hir_id,
             node: pat,
             span,
index 0425d5a5023849e6eff623bb1a2a9c805f118825..9f39d648df1bfcf08df8590669cf482eb94ef6b1 100644 (file)
@@ -356,7 +356,7 @@ fn visit_nested_body(&mut self, id: BodyId) {
     fn visit_item(&mut self, i: &'hir Item) {
         debug!("visit_item: {:?}", i);
         debug_assert_eq!(i.hir_id.owner,
-                         self.definitions.opt_def_index(i.id).unwrap());
+                         self.definitions.opt_def_index(self.hir_to_node_id[&i.hir_id]).unwrap());
         self.with_dep_node_owner(i.hir_id.owner, i, |this| {
             this.insert(i.span, i.hir_id, Node::Item(i));
             this.with_parent(i.hir_id, |this| {
index 66e814f06609cf636ee94bd4623360528da63c92..21a9ed5ebe03a15d11efec49dc8b6edb23516c16 100644 (file)
@@ -319,7 +319,7 @@ pub fn describe_def(&self, node_id: NodeId) -> Option<Def> {
 
         match node {
             Node::Item(item) => {
-                let def_id = || self.local_def_id(item.id);
+                let def_id = || self.local_def_id_from_hir_id(item.hir_id);
 
                 match item.node {
                     ItemKind::Static(_, m, _) => Some(Def::Static(def_id(), m == MutMutable)),
@@ -341,7 +341,7 @@ pub fn describe_def(&self, node_id: NodeId) -> Option<Def> {
                 }
             }
             Node::ForeignItem(item) => {
-                let def_id = self.local_def_id(item.id);
+                let def_id = self.local_def_id_from_hir_id(item.hir_id);
                 match item.node {
                     ForeignItemKind::Fn(..) => Some(Def::Fn(def_id)),
                     ForeignItemKind::Static(_, m) => Some(Def::Static(def_id, m)),
@@ -366,11 +366,11 @@ pub fn describe_def(&self, node_id: NodeId) -> Option<Def> {
                 }
             }
             Node::Variant(variant) => {
-                let def_id = self.local_def_id(variant.node.data.id());
+                let def_id = self.local_def_id_from_hir_id(variant.node.data.hir_id());
                 Some(Def::Variant(def_id))
             }
             Node::StructCtor(variant) => {
-                let def_id = self.local_def_id(variant.id());
+                let def_id = self.local_def_id_from_hir_id(variant.hir_id());
                 Some(Def::StructCtor(def_id, def::CtorKind::from_hir(variant)))
             }
             Node::AnonConst(_) |
@@ -427,7 +427,7 @@ pub fn krate(&self) -> &'hir Crate {
     }
 
     pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem {
-        self.read(id.node_id);
+        self.read_by_hir_id(id.hir_id);
 
         // N.B., intentionally bypass `self.forest.krate()` so that we
         // do not trigger a read of the whole krate here
@@ -435,7 +435,7 @@ pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem {
     }
 
     pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem {
-        self.read(id.node_id);
+        self.read_by_hir_id(id.hir_id);
 
         // N.B., intentionally bypass `self.forest.krate()` so that we
         // do not trigger a read of the whole krate here
@@ -618,11 +618,11 @@ pub fn visit_item_likes_in_module<V>(&self, module: DefId, visitor: &mut V)
         }
 
         for id in &module.trait_items {
-            visitor.visit_trait_item(self.expect_trait_item(id.node_id));
+            visitor.visit_trait_item(self.expect_trait_item_by_hir_id(id.hir_id));
         }
 
         for id in &module.impl_items {
-            visitor.visit_impl_item(self.expect_impl_item(id.node_id));
+            visitor.visit_impl_item(self.expect_impl_item_by_hir_id(id.hir_id));
         }
     }
 
index 3ba4efba9186cad8425e8fa587162966995b53bc..4b5670af138581ded1684e067c82e3f8ea5ffb86 100644 (file)
@@ -32,6 +32,7 @@
 
 use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync};
 use rustc_data_structures::thin_vec::ThinVec;
+use rustc_macros::HashStable;
 
 use serialize::{self, Encoder, Encodable, Decoder, Decodable};
 use std::collections::{BTreeSet, BTreeMap};
@@ -149,7 +150,7 @@ pub struct ItemLocalId { .. }
 
 pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX;
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Copy)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Copy, HashStable)]
 pub struct Lifetime {
     pub hir_id: HirId,
     pub span: Span,
@@ -834,7 +835,6 @@ pub struct Block {
 
 #[derive(Clone, RustcEncodable, RustcDecodable)]
 pub struct Pat {
-    pub id: NodeId,
     pub hir_id: HirId,
     pub node: PatKind,
     pub span: Span,
@@ -842,7 +842,7 @@ pub struct Pat {
 
 impl fmt::Debug for Pat {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "pat({}: {})", self.id,
+        write!(f, "pat({}: {})", self.hir_id,
                print::to_string(print::NO_ANN, |s| s.print_pat(self)))
     }
 }
@@ -897,7 +897,6 @@ pub fn walk<F>(&self, mut it: F) -> bool
 /// except `is_shorthand` is true.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct FieldPat {
-    pub id: NodeId,
     pub hir_id: HirId,
     /// The identifier for the field.
     pub ident: Ident,
@@ -1659,7 +1658,7 @@ pub struct MethodSig {
 // so it can fetched later.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Debug)]
 pub struct TraitItemId {
-    pub node_id: NodeId,
+    pub hir_id: HirId,
 }
 
 /// Represents an item declaration within a trait declaration,
@@ -1704,7 +1703,7 @@ pub enum TraitItemKind {
 // so it can fetched later.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Debug)]
 pub struct ImplItemId {
-    pub node_id: NodeId,
+    pub hir_id: HirId,
 }
 
 /// Represents anything within an `impl` block
@@ -2132,7 +2131,6 @@ pub struct StructField {
     pub span: Span,
     pub ident: Ident,
     pub vis: Visibility,
-    pub id: NodeId,
     pub hir_id: HirId,
     pub ty: P<Ty>,
     pub attrs: HirVec<Attribute>,
@@ -2159,9 +2157,9 @@ pub fn is_positional(&self) -> bool {
 /// Id of the whole struct lives in `Item`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum VariantData {
-    Struct(HirVec<StructField>, NodeId, HirId),
-    Tuple(HirVec<StructField>, NodeId, HirId),
-    Unit(NodeId, HirId),
+    Struct(HirVec<StructField>, HirId),
+    Tuple(HirVec<StructField>, HirId),
+    Unit(HirId),
 }
 
 impl VariantData {
@@ -2171,18 +2169,11 @@ pub fn fields(&self) -> &[StructField] {
             _ => &[],
         }
     }
-    pub fn id(&self) -> NodeId {
-        match *self {
-            VariantData::Struct(_, id, ..)
-            | VariantData::Tuple(_, id, ..)
-            | VariantData::Unit(id, ..) => id,
-        }
-    }
     pub fn hir_id(&self) -> HirId {
         match *self {
-            VariantData::Struct(_, _, hir_id)
-            | VariantData::Tuple(_, _, hir_id)
-            | VariantData::Unit(_, hir_id) => hir_id,
+            VariantData::Struct(_, hir_id)
+            | VariantData::Tuple(_, hir_id)
+            | VariantData::Unit(hir_id) => hir_id,
         }
     }
     pub fn is_struct(&self) -> bool {
@@ -2222,7 +2213,6 @@ pub struct ItemId {
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Item {
     pub ident: Ident,
-    pub id: NodeId,
     pub hir_id: HirId,
     pub attrs: HirVec<Attribute>,
     pub node: ItemKind,
@@ -2379,7 +2369,6 @@ pub struct ForeignItem {
     pub ident: Ident,
     pub attrs: HirVec<Attribute>,
     pub node: ForeignItemKind,
-    pub id: NodeId,
     pub hir_id: HirId,
     pub span: Span,
     pub vis: Visibility,
index af1cce5e354545eba6188386568c892de07771b0..d8d4157e20ec93e300a86af1d2c162869ab55553 100644 (file)
@@ -116,11 +116,11 @@ fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
         let hir::TraitItemId {
-            node_id
+            hir_id
         } = * self;
 
         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-            node_id.hash_stable(hcx, hasher);
+            hir_id.hash_stable(hcx, hasher);
         })
     }
 }
@@ -130,11 +130,11 @@ fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
         let hir::ImplItemId {
-            node_id
+            hir_id
         } = * self;
 
         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-            node_id.hash_stable(hcx, hasher);
+            hir_id.hash_stable(hcx, hasher);
         })
     }
 }
@@ -157,12 +157,6 @@ fn hash_stable<W: StableHasherResult>(&self,
     ident
 });
 
-impl_stable_hash_for!(struct hir::Lifetime {
-    hir_id,
-    span,
-    name
-});
-
 impl_stable_hash_for!(struct hir::Path {
     span,
     def,
@@ -421,7 +415,6 @@ fn hash_stable<W: StableHasherResult>(&self,
 });
 
 impl_stable_hash_for!(struct hir::Pat {
-    id -> _,
     hir_id -> _,
     node,
     span,
@@ -430,7 +423,6 @@ fn hash_stable<W: StableHasherResult>(&self,
 impl_stable_hash_for_spanned!(hir::FieldPat);
 
 impl_stable_hash_for!(struct hir::FieldPat {
-    id -> _,
     hir_id -> _,
     ident -> (ident.name),
     pat,
@@ -838,16 +830,15 @@ fn hash_stable<W: StableHasherResult>(&self,
     span,
     ident -> (ident.name),
     vis,
-    id,
     hir_id,
     ty,
     attrs
 });
 
 impl_stable_hash_for!(enum hir::VariantData {
-    Struct(fields, id, hir_id),
-    Tuple(fields, id, hir_id),
-    Unit(id, hir_id)
+    Struct(fields, hir_id),
+    Tuple(fields, hir_id),
+    Unit(hir_id)
 });
 
 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
@@ -857,7 +848,6 @@ fn hash_stable<W: StableHasherResult>(&self,
         let hir::Item {
             ident,
             ref attrs,
-            id: _,
             hir_id: _,
             ref node,
             ref vis,
@@ -932,7 +922,6 @@ fn hash_stable<W: StableHasherResult>(&self,
     ident -> (ident.name),
     attrs,
     node,
-    id,
     hir_id,
     span,
     vis
index 41b78ee50965506a071430575a5024d79f5bac8c..ba47116434f8d12440365a7d7a997bdc9fe5766f 100644 (file)
@@ -378,6 +378,7 @@ fn hash_stable<W: StableHasherResult>(&self,
     ReifyFnPointer,
     ClosureFnPointer,
     UnsafeFnPointer,
+    MutToConstPointer,
     Unsize
 });
 
index f77a88128f252ef36deb2a9665d78a087547da56..21988de90183a0a9df91bd6d830f76e9941b6f28 100644 (file)
@@ -74,6 +74,7 @@ fn hash_stable<W: StableHasherResult>(&self,
         match self {
             ty::subst::UnpackedKind::Lifetime(lt) => lt.hash_stable(hcx, hasher),
             ty::subst::UnpackedKind::Type(ty) => ty.hash_stable(hcx, hasher),
+            ty::subst::UnpackedKind::Const(ct) => ct.hash_stable(hcx, hasher),
         }
     }
 }
@@ -134,6 +135,15 @@ fn hash_stable<W: StableHasherResult>(&self,
     }
 }
 
+impl<'gcx, 'tcx> HashStable<StableHashingContext<'gcx>> for ty::ConstVid<'tcx> {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'gcx>,
+                                          hasher: &mut StableHasher<W>) {
+        self.index.hash_stable(hcx, hasher);
+    }
+}
+
 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::BoundVar {
     #[inline]
     fn hash_stable<W: StableHasherResult>(&self,
@@ -297,6 +307,14 @@ fn hash_stable<W: StableHasherResult>(&self,
     }
 }
 
+impl_stable_hash_for!(
+    impl<'tcx> for enum ty::InferConst<'tcx> [ ty::InferConst ] {
+        Var(vid),
+        Fresh(i),
+        Canonical(debruijn, var),
+    }
+);
+
 impl_stable_hash_for!(enum ty::VariantDiscr {
     Explicit(def_id),
     Relative(distance)
@@ -310,11 +328,14 @@ fn hash_stable<W: StableHasherResult>(&self,
 
 impl_stable_hash_for!(
     impl<'tcx> for enum mir::interpret::ConstValue<'tcx> [ mir::interpret::ConstValue ] {
+        Param(param),
+        Infer(infer),
         Scalar(val),
         Slice(a, b),
         ByRef(ptr, alloc),
     }
 );
+
 impl_stable_hash_for!(struct crate::mir::interpret::RawConst<'tcx> {
     alloc_id,
     ty,
@@ -518,6 +539,7 @@ impl<'tcx, O> for enum mir::interpret::EvalErrorKind<'tcx, O>
 impl_stable_hash_for!(enum ty::GenericParamDefKind {
     Lifetime,
     Type { has_default, object_lifetime_default, synthetic },
+    Const,
 });
 
 impl_stable_hash_for!(
@@ -736,6 +758,11 @@ fn hash_stable<W: StableHasherResult>(&self,
     }
 }
 
+impl_stable_hash_for!(struct ty::ParamConst {
+    index,
+    name
+});
+
 impl_stable_hash_for!(struct ty::ParamTy {
     idx,
     name
index 613e153ae33d4c73d0659f4c230aa715a3c594a4..0d067d1de856aa4572eb7411d4e1c5d1935a60ac 100644 (file)
@@ -443,6 +443,9 @@ pub fn make_identity<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
                     UnpackedKind::Lifetime(..) => tcx.mk_region(
                         ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i))
                     ).into(),
+                    UnpackedKind::Const(..) => {
+                        unimplemented!() // FIXME(const_generics)
+                    }
                 })
                 .collect()
         }
index aef0152b6ed7332764057c554fcdc6b65c09cd43..008882fd50036fc6c0df553fd73735c1dbd2d282 100644 (file)
@@ -315,6 +315,10 @@ pub fn instantiate_nll_query_response_and_region_obligations<R>(
                     obligations.extend(ok.into_obligations());
                 }
 
+                (UnpackedKind::Const(..), UnpackedKind::Const(..)) => {
+                    unimplemented!() // FIXME(const_generics)
+                }
+
                 _ => {
                     bug!(
                         "kind mismatch, cannot unify {:?} and {:?}",
@@ -473,6 +477,9 @@ fn query_response_substitution_guess<R>(
                         opt_values[br.assert_bound_var()] = Some(*original_value);
                     }
                 }
+                UnpackedKind::Const(..) => {
+                    unimplemented!() // FIXME(const_generics)
+                }
             }
         }
 
@@ -568,6 +575,11 @@ fn query_region_constraints_into_obligations<'a>(
                                 ty::OutlivesPredicate(t1, r2)
                             )
                         ),
+                        UnpackedKind::Const(..) => {
+                            // Consts cannot outlive one another, so we don't expect to
+                            // ecounter this branch.
+                            span_bug!(cause.span, "unexpected const outlives {:?}", constraint);
+                        }
                     }
                 )
             })
@@ -602,6 +614,9 @@ fn unify_canonical_vars(
                         obligations
                             .extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations());
                     }
+                    (UnpackedKind::Const(..), UnpackedKind::Const(..)) => {
+                        unimplemented!() // FIXME(const_generics)
+                    }
                     _ => {
                         bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,);
                     }
index 6ef902a47dc8d768c931156e9a8b2bf485979acf..885b439ef1ca58c44c7eb4cfce5f05f438c7e327 100644 (file)
@@ -449,7 +449,7 @@ fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
 
                             let origin = *variables.var_origin(vid);
                             let new_var_id = variables.new_var(self.for_universe, false, origin);
-                            let u = self.tcx().mk_var(new_var_id);
+                            let u = self.tcx().mk_ty_var(new_var_id);
                             debug!("generalize: replacing original vid={:?} with new={:?}",
                                    vid, u);
                             return Ok(u);
index 3dace2f2e89b0ba7655c8643e492831264695dd5..c7936534aad2e00d0cc8689a97e5ec99b0cd1c95 100644 (file)
@@ -691,17 +691,11 @@ fn strip_generic_default_params(
     ) -> SubstsRef<'tcx> {
         let generics = self.tcx.generics_of(def_id);
         let mut num_supplied_defaults = 0;
-        let mut type_params = generics
-            .params
-            .iter()
-            .rev()
-            .filter_map(|param| match param.kind {
-                ty::GenericParamDefKind::Lifetime => None,
-                ty::GenericParamDefKind::Type { has_default, .. } => {
-                    Some((param.def_id, has_default))
-                }
-            })
-            .peekable();
+        let mut type_params = generics.params.iter().rev().filter_map(|param| match param.kind {
+            ty::GenericParamDefKind::Lifetime => None,
+            ty::GenericParamDefKind::Type { has_default, .. } => Some((param.def_id, has_default)),
+            ty::GenericParamDefKind::Const => None, // FIXME(const_generics:defaults)
+        }).peekable();
         let has_default = {
             let has_default = type_params.peek().map(|(_, has_default)| has_default);
             *has_default.unwrap_or(&false)
index 84ad742d3c9722e4f252e90df12d3e225eaa23ff..cc1c439f3bd94fbc7a4a4e65b146eaec8ab6c270 100644 (file)
@@ -656,7 +656,7 @@ pub fn unsolved_variables(&self) -> Vec<Ty<'tcx>> {
         type_variables
             .unsolved_variables()
             .into_iter()
-            .map(|t| self.tcx.mk_var(t))
+            .map(|t| self.tcx.mk_ty_var(t))
             .chain(
                 (0..int_unification_table.len())
                     .map(|i| ty::IntVid { index: i as u32 })
@@ -981,7 +981,7 @@ pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyV
     }
 
     pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
-        self.tcx.mk_var(self.next_ty_var_id(false, origin))
+        self.tcx.mk_ty_var(self.next_ty_var_id(false, origin))
     }
 
     pub fn next_ty_var_in_universe(
@@ -992,11 +992,11 @@ pub fn next_ty_var_in_universe(
         let vid = self.type_variables
             .borrow_mut()
             .new_var(universe, false, origin);
-        self.tcx.mk_var(vid)
+        self.tcx.mk_ty_var(vid)
     }
 
     pub fn next_diverging_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
-        self.tcx.mk_var(self.next_ty_var_id(true, origin))
+        self.tcx.mk_ty_var(self.next_ty_var_id(true, origin))
     }
 
     pub fn next_int_var_id(&self) -> IntVid {
@@ -1081,7 +1081,10 @@ pub fn var_for_def(&self, span: Span, param: &ty::GenericParamDef) -> Kind<'tcx>
                     TypeVariableOrigin::TypeParameterDefinition(span, param.name),
                 );
 
-                self.tcx.mk_var(ty_var_id).into()
+                self.tcx.mk_ty_var(ty_var_id).into()
+            }
+            GenericParamDefKind::Const { .. } => {
+                unimplemented!() // FIXME(const_generics)
             }
         }
     }
index f37e24b292e0351e172ad633fdc068df1ea75c3b..7140af36acbdc4191a0133b85f35f323b250b863 100644 (file)
@@ -310,7 +310,7 @@ fn relate_ty_var(
             ty::Projection(projection_ty)
                 if D::normalization() == NormalizationStrategy::Lazy =>
             {
-                return Ok(self.relate_projection_ty(projection_ty, self.infcx.tcx.mk_var(vid)));
+                return Ok(self.relate_projection_ty(projection_ty, self.infcx.tcx.mk_ty_var(vid)));
             }
 
             _ => (),
@@ -764,7 +764,7 @@ fn tys(&mut self, a: Ty<'tcx>, _: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
                             // the universe `_universe`.
                             let new_var_id = variables.new_var(self.universe, false, origin);
 
-                            let u = self.tcx().mk_var(new_var_id);
+                            let u = self.tcx().mk_ty_var(new_var_id);
                             debug!(
                                 "generalize: replacing original vid={:?} with new={:?}",
                                 vid,
index 159bc1ceae26c2329ca0f152d10f2cd9002b4dbd..1b7ecc7c3a67cedc41a125ecae7f34b2d77cc3b1 100644 (file)
@@ -381,10 +381,15 @@ pub fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
                         substs,
                         item_def_id: _,
                     }) => {
-                        for r in substs.regions() {
-                            bound_region(r);
+                        for k in substs {
+                            match k.unpack() {
+                                UnpackedKind::Lifetime(lt) => bound_region(lt),
+                                UnpackedKind::Type(ty) => types.push(ty),
+                                UnpackedKind::Const(_) => {
+                                    // Const parameters don't impose constraints.
+                                }
+                            }
                         }
-                        types.extend(substs.types());
                     }
 
                     Component::EscapingProjection(more_components) => {
index bbda3d2fdbf84d9ac15ebb7d186ac0e7cd65fd52..ee66032848519887c0454b0290946d6fd872c398 100644 (file)
@@ -67,6 +67,7 @@
 use crate::traits::ObligationCause;
 use crate::ty::outlives::Component;
 use crate::ty::{self, Region, Ty, TyCtxt, TypeFoldable};
+use crate::ty::subst::UnpackedKind;
 
 impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
     /// Registers that the given region obligation must be resolved
@@ -430,13 +431,18 @@ fn projection_must_outlive(
         if approx_env_bounds.is_empty() && trait_bounds.is_empty() && needs_infer {
             debug!("projection_must_outlive: no declared bounds");
 
-            for component_ty in projection_ty.substs.types() {
-                self.type_must_outlive(origin.clone(), component_ty, region);
-            }
-
-            for r in projection_ty.substs.regions() {
-                self.delegate
-                    .push_sub_region_constraint(origin.clone(), region, r);
+            for k in projection_ty.substs {
+                match k.unpack() {
+                    UnpackedKind::Lifetime(lt) => {
+                        self.delegate.push_sub_region_constraint(origin.clone(), region, lt);
+                    }
+                    UnpackedKind::Type(ty) => {
+                        self.type_must_outlive(origin.clone(), ty, region);
+                    }
+                    UnpackedKind::Const(_) => {
+                        // Const parameters don't impose constraints.
+                    }
+                }
             }
 
             return;
index 205ea6126fc59b511139d4741bfeb809aca2bac3..6adfaa53946ac29615932017d041d8d49fd83840 100644 (file)
@@ -141,14 +141,8 @@ pub mod util {
     pub mod bug;
 }
 
-// A private module so that macro-expanded idents like
-// `::rustc::lint::Lint` will also work in `rustc` itself.
-//
-// `libstd` uses the same trick.
-#[doc(hidden)]
-mod rustc {
-    pub use crate::lint;
-}
+// Allows macros to refer to this crate as `::rustc`
+extern crate self as rustc;
 
 // FIXME(#27438): right now the unit tests of librustc don't refer to any actual
 //                functions generated in librustc_data_structures (all
index dd003e44bea09d8bba7acb41ca40af89e46ac595..496ff568b31b4d5a775a0f1f1382dfa477a9fff6 100644 (file)
@@ -132,14 +132,22 @@ macro_rules! declare_lint {
 
 #[macro_export]
 macro_rules! declare_tool_lint {
-    ($vis: vis $tool: ident ::$NAME: ident, $Level: ident, $desc: expr) => (
-        declare_tool_lint!{$vis $tool::$NAME, $Level, $desc, false}
+    (
+        $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level: ident, $desc: expr
+    ) => (
+        declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, false}
     );
-    ($vis: vis $tool: ident ::$NAME: ident, $Level: ident, $desc: expr,
-     report_in_external_macro: $rep: expr) => (
-         declare_tool_lint!{$vis $tool::$NAME, $Level, $desc, $rep}
+    (
+        $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr,
+        report_in_external_macro: $rep:expr
+    ) => (
+         declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, $rep}
     );
-    ($vis: vis $tool: ident ::$NAME: ident, $Level: ident, $desc: expr, $external: expr) => (
+    (
+        $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr,
+        $external:expr
+    ) => (
+        $(#[$attr])*
         $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
             name: &concat!(stringify!($tool), "::", stringify!($NAME)),
             default_level: $crate::lint::$Level,
index 3b607127d8628a1afedba18529ed986edb1cd59a..8ffd119f95c0ba9a2062391b4ea4dedd9b9661dc 100644 (file)
@@ -152,7 +152,7 @@ fn visit_node(&mut self, node: Node<'tcx>) {
             Node::Item(item) => {
                 match item.node {
                     hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
-                        let def_id = self.tcx.hir().local_def_id(item.id);
+                        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
                         let def = self.tcx.adt_def(def_id);
                         self.repr_has_repr_c = def.repr.c();
 
@@ -376,7 +376,7 @@ fn visit_item(&mut self, item: &hir::Item) {
                             has_allow_dead_code_or_lang_attr(self.tcx,
                                                              impl_item.hir_id,
                                                              &impl_item.attrs) {
-                        self.worklist.push(self.tcx.hir().node_to_hir_id(impl_item_ref.id.node_id));
+                        self.worklist.push(impl_item_ref.id.hir_id);
                     }
                 }
             }
@@ -465,7 +465,7 @@ fn should_warn_about_item(&mut self, item: &hir::Item) -> bool {
     }
 
     fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool {
-        let field_type = self.tcx.type_of(self.tcx.hir().local_def_id(field.id));
+        let field_type = self.tcx.type_of(self.tcx.hir().local_def_id_from_hir_id(field.hir_id));
         !field.is_positional()
             && !self.symbol_is_live(field.hir_id)
             && !field_type.is_phantom_data()
index 2d0e6c3917bb84822fa6c060941dd968dfd85c31..c20454a8822cd65915aadf872bd6246a4c99d4d8 100644 (file)
@@ -2,11 +2,10 @@
 use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
 use crate::session::{config, Session};
 use crate::session::config::EntryFnType;
-use syntax::ast::NodeId;
 use syntax::attr;
 use syntax::entry::EntryPointType;
 use syntax_pos::Span;
-use crate::hir::{Item, ItemKind, ImplItem, TraitItem};
+use crate::hir::{HirId, Item, ItemKind, ImplItem, TraitItem};
 use crate::hir::itemlikevisit::ItemLikeVisitor;
 use crate::ty::TyCtxt;
 use crate::ty::query::Providers;
@@ -17,22 +16,22 @@ struct EntryContext<'a, 'tcx: 'a> {
     map: &'a hir_map::Map<'tcx>,
 
     // The top-level function called 'main'
-    main_fn: Option<(NodeId, Span)>,
+    main_fn: Option<(HirId, Span)>,
 
     // The function that has attribute named 'main'
-    attr_main_fn: Option<(NodeId, Span)>,
+    attr_main_fn: Option<(HirId, Span)>,
 
     // The function that has the attribute 'start' on it
-    start_fn: Option<(NodeId, Span)>,
+    start_fn: Option<(HirId, Span)>,
 
     // The functions that one might think are 'main' but aren't, e.g.
     // main functions not defined at the top level. For diagnostics.
-    non_main_fns: Vec<(NodeId, Span)> ,
+    non_main_fns: Vec<(HirId, Span)> ,
 }
 
 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
     fn visit_item(&mut self, item: &'tcx Item) {
-        let def_id = self.map.local_def_id(item.id);
+        let def_id = self.map.local_def_id_from_hir_id(item.hir_id);
         let def_key = self.map.def_key(def_id);
         let at_root = def_key.parent == Some(CRATE_DEF_INDEX);
         find_item(item, self, at_root);
@@ -106,18 +105,18 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
     match entry_point_type(item, at_root) {
         EntryPointType::MainNamed => {
             if ctxt.main_fn.is_none() {
-                ctxt.main_fn = Some((item.id, item.span));
+                ctxt.main_fn = Some((item.hir_id, item.span));
             } else {
                 span_err!(ctxt.session, item.span, E0136,
                           "multiple 'main' functions");
             }
         },
         EntryPointType::OtherMain => {
-            ctxt.non_main_fns.push((item.id, item.span));
+            ctxt.non_main_fns.push((item.hir_id, item.span));
         },
         EntryPointType::MainAttr => {
             if ctxt.attr_main_fn.is_none() {
-                ctxt.attr_main_fn = Some((item.id, item.span));
+                ctxt.attr_main_fn = Some((item.hir_id, item.span));
             } else {
                 struct_span_err!(ctxt.session, item.span, E0137,
                                  "multiple functions with a #[main] attribute")
@@ -128,7 +127,7 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
         },
         EntryPointType::Start => {
             if ctxt.start_fn.is_none() {
-                ctxt.start_fn = Some((item.id, item.span));
+                ctxt.start_fn = Some((item.hir_id, item.span));
             } else {
                 struct_span_err!(ctxt.session, item.span, E0138, "multiple 'start' functions")
                     .span_label(ctxt.start_fn.unwrap().1, "previous `start` function here")
@@ -144,12 +143,12 @@ fn configure_main(
     tcx: TyCtxt<'_, '_, '_>,
     visitor: &EntryContext<'_, '_>,
 ) -> Option<(DefId, EntryFnType)> {
-    if let Some((node_id, _)) = visitor.start_fn {
-        Some((tcx.hir().local_def_id(node_id), EntryFnType::Start))
-    } else if let Some((node_id, _)) = visitor.attr_main_fn {
-        Some((tcx.hir().local_def_id(node_id), EntryFnType::Main))
-    } else if let Some((node_id, _)) = visitor.main_fn {
-        Some((tcx.hir().local_def_id(node_id), EntryFnType::Main))
+    if let Some((hir_id, _)) = visitor.start_fn {
+        Some((tcx.hir().local_def_id_from_hir_id(hir_id), EntryFnType::Start))
+    } else if let Some((hir_id, _)) = visitor.attr_main_fn {
+        Some((tcx.hir().local_def_id_from_hir_id(hir_id), EntryFnType::Main))
+    } else if let Some((hir_id, _)) = visitor.main_fn {
+        Some((tcx.hir().local_def_id_from_hir_id(hir_id), EntryFnType::Main))
     } else {
         // No main function
         let mut err = struct_err!(tcx.sess, E0601,
index 7fc01e302a7d2c22e131117fed35a817fa166994..6e8b661b7b895b1714730e47c8c1b13148734175 100644 (file)
@@ -19,7 +19,6 @@
 use crate::hir::{self, PatKind};
 use rustc_data_structures::sync::Lrc;
 use std::rc::Rc;
-use syntax::ast;
 use syntax::ptr::P;
 use syntax_pos::Span;
 use crate::util::nodemap::ItemLocalSet;
@@ -74,7 +73,7 @@ fn borrow(&mut self,
 
     // The local variable `id` is declared but not initialized.
     fn decl_without_init(&mut self,
-                         id: ast::NodeId,
+                         id: hir::HirId,
                          span: Span);
 
     // The path at `cmt` is being assigned to.
@@ -609,8 +608,7 @@ fn walk_local(&mut self, local: &hir::Local) {
         match local.init {
             None => {
                 local.pat.each_binding(|_, hir_id, span, _| {
-                    let node_id = self.mc.tcx.hir().hir_to_node_id(hir_id);
-                    self.delegate.decl_without_init(node_id, span);
+                    self.delegate.decl_without_init(hir_id, span);
                 })
             }
 
index 3f9230ab551d55b82ae9a5002cd6cc1bd8ae117a..7626310ea4eb3e3cf95d304e6723de1d0a1fe7d5 100644 (file)
@@ -98,7 +98,7 @@ fn visit_item(&mut self, item: &hir::Item) {
             match self.item_refs.get(&*value.as_str()).cloned() {
                 // Known lang item with attribute on correct target.
                 Some((item_index, expected_target)) if actual_target == expected_target => {
-                    let def_id = self.tcx.hir().local_def_id(item.id);
+                    let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
                     self.collect_item(item_index, def_id);
                 },
                 // Known lang item with attribute on incorrect target.
index 76933a6e3484b02194d3341ba3b2bd0b6748c696..97f747c94a4123bdfea5d3146acc11d8b2f0fed6 100644 (file)
@@ -379,9 +379,22 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
     let body = ir.tcx.hir().body(body_id);
 
     for arg in &body.arguments {
+        let is_shorthand = match arg.pat.node {
+            crate::hir::PatKind::Struct(..) => true,
+            _ => false,
+        };
         arg.pat.each_binding(|_bm, hir_id, _x, ident| {
             debug!("adding argument {:?}", hir_id);
-            fn_maps.add_variable(Arg(hir_id, ident.name));
+            let var = if is_shorthand {
+                Local(LocalInfo {
+                    id: hir_id,
+                    name: ident.name,
+                    is_shorthand: true,
+                })
+            } else {
+                Arg(hir_id, ident.name)
+            };
+            fn_maps.add_variable(var);
         })
     };
 
index 822a42b374f38fc5a13e9b7d65e34776eff2be3d..a3e8598194e790550f12d5a3ff5f08a412a571b7 100644 (file)
@@ -88,7 +88,7 @@ pub enum Categorization<'tcx> {
     ThreadLocal(ty::Region<'tcx>),       // value that cannot move, but still restricted in scope
     StaticItem,
     Upvar(Upvar),                        // upvar referenced by closure env
-    Local(ast::NodeId),                  // local variable
+    Local(hir::HirId),                   // local variable
     Deref(cmt<'tcx>, PointerKind<'tcx>), // deref of a ptr
     Interior(cmt<'tcx>, InteriorKind),   // something interior: field, tuple, etc
     Downcast(cmt<'tcx>, DefId),          // selects a particular enum variant (*1)
@@ -198,9 +198,9 @@ pub struct cmt_<'tcx> {
 pub type cmt<'tcx> = Rc<cmt_<'tcx>>;
 
 pub enum ImmutabilityBlame<'tcx> {
-    ImmLocal(ast::NodeId),
+    ImmLocal(hir::HirId),
     ClosureEnv(LocalDefId),
-    LocalDeref(ast::NodeId),
+    LocalDeref(hir::HirId),
     AdtFieldDeref(&'tcx ty::AdtDef, &'tcx ty::FieldDef)
 }
 
@@ -230,8 +230,8 @@ pub fn immutability_blame(&self) -> Option<ImmutabilityBlame<'tcx>> {
             Categorization::Deref(ref base_cmt, BorrowedPtr(ty::ImmBorrow, _)) => {
                 // try to figure out where the immutable reference came from
                 match base_cmt.cat {
-                    Categorization::Local(node_id) =>
-                        Some(ImmutabilityBlame::LocalDeref(node_id)),
+                    Categorization::Local(hir_id) =>
+                        Some(ImmutabilityBlame::LocalDeref(hir_id)),
                     Categorization::Interior(ref base_cmt, InteriorField(field_index)) => {
                         base_cmt.resolve_field(field_index.0).map(|(adt_def, field_def)| {
                             ImmutabilityBlame::AdtFieldDeref(adt_def, field_def)
@@ -247,8 +247,8 @@ pub fn immutability_blame(&self) -> Option<ImmutabilityBlame<'tcx>> {
                     _ => None
                 }
             }
-            Categorization::Local(node_id) => {
-                Some(ImmutabilityBlame::ImmLocal(node_id))
+            Categorization::Local(hir_id) => {
+                Some(ImmutabilityBlame::ImmLocal(hir_id))
             }
             Categorization::Rvalue(..) |
             Categorization::Upvar(..) |
@@ -741,7 +741,7 @@ pub fn cat_def(&self,
                 Ok(cmt_ {
                     hir_id,
                     span,
-                    cat: Categorization::Local(vid),
+                    cat: Categorization::Local(self.tcx.hir().node_to_hir_id(vid)),
                     mutbl: MutabilityCategory::from_local(self.tcx, self.tables, vid),
                     ty: expr_ty,
                     note: NoteNone
@@ -1495,7 +1495,7 @@ pub fn descriptive_string(&self, tcx: TyCtxt<'_, '_, '_>) -> Cow<'static, str> {
                 "non-place".into()
             }
             Categorization::Local(vid) => {
-                if tcx.hir().is_argument(vid) {
+                if tcx.hir().is_argument(tcx.hir().hir_to_node_id(vid)) {
                     "argument"
                 } else {
                     "local variable"
index cffbc2eaa40ce7a2168b90e35d817d9daf14bb87..086b3a318e6b6e9f004c196da728a895aaeae220 100644 (file)
 use crate::ty::query::Providers;
 use crate::middle::privacy;
 use crate::session::config;
-use crate::util::nodemap::{NodeSet, FxHashSet};
+use crate::util::nodemap::{HirIdSet, FxHashSet};
 
 use rustc_target::spec::abi::Abi;
-use syntax::ast;
 use crate::hir;
 use crate::hir::def_id::LOCAL_CRATE;
 use crate::hir::intravisit::{Visitor, NestedVisitorMap};
@@ -37,7 +36,7 @@ fn item_might_be_inlined(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     match item.node {
         hir::ItemKind::Impl(..) |
         hir::ItemKind::Fn(..) => {
-            let generics = tcx.generics_of(tcx.hir().local_def_id(item.id));
+            let generics = tcx.generics_of(tcx.hir().local_def_id_from_hir_id(item.hir_id));
             generics.requires_monomorphization(tcx)
         }
         _ => false,
@@ -70,10 +69,10 @@ struct ReachableContext<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
     // The set of items which must be exported in the linkage sense.
-    reachable_symbols: NodeSet,
+    reachable_symbols: HirIdSet,
     // A worklist of item IDs. Each item ID in this worklist will be inlined
     // and will be scanned for further references.
-    worklist: Vec<ast::NodeId>,
+    worklist: Vec<hir::HirId>,
     // Whether any output of this compilation is a library
     any_library: bool,
 }
@@ -104,27 +103,28 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
 
         match def {
             Some(Def::Local(node_id)) | Some(Def::Upvar(node_id, ..)) => {
-                self.reachable_symbols.insert(node_id);
+                let hir_id = self.tcx.hir().node_to_hir_id(node_id);
+                self.reachable_symbols.insert(hir_id);
             }
             Some(def) => {
-                if let Some((node_id, def_id)) = def.opt_def_id().and_then(|def_id| {
-                    self.tcx.hir().as_local_node_id(def_id).map(|node_id| (node_id, def_id))
+                if let Some((hir_id, def_id)) = def.opt_def_id().and_then(|def_id| {
+                    self.tcx.hir().as_local_hir_id(def_id).map(|hir_id| (hir_id, def_id))
                 }) {
                     if self.def_id_represents_local_inlined_item(def_id) {
-                        self.worklist.push(node_id);
+                        self.worklist.push(hir_id);
                     } else {
                         match def {
                             // If this path leads to a constant, then we need to
                             // recurse into the constant to continue finding
                             // items that are reachable.
                             Def::Const(..) | Def::AssociatedConst(..) => {
-                                self.worklist.push(node_id);
+                                self.worklist.push(hir_id);
                             }
 
                             // If this wasn't a static, then the destination is
                             // surely reachable.
                             _ => {
-                                self.reachable_symbols.insert(node_id);
+                                self.reachable_symbols.insert(hir_id);
                             }
                         }
                     }
@@ -204,14 +204,14 @@ fn propagate(&mut self) {
                 continue
             }
 
-            if let Some(ref item) = self.tcx.hir().find(search_item) {
+            if let Some(ref item) = self.tcx.hir().find_by_hir_id(search_item) {
                 self.propagate_node(item, search_item);
             }
         }
     }
 
     fn propagate_node(&mut self, node: &Node<'tcx>,
-                      search_item: ast::NodeId) {
+                      search_item: hir::HirId) {
         if !self.any_library {
             // If we are building an executable, only explicitly extern
             // types need to be exported.
@@ -221,7 +221,7 @@ fn propagate_node(&mut self, node: &Node<'tcx>,
                 } else {
                     false
                 };
-                let def_id = self.tcx.hir().local_def_id(item.id);
+                let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
                 let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
                 let is_extern = codegen_attrs.contains_extern_indicator();
                 let std_internal = codegen_attrs.flags.contains(
@@ -242,7 +242,7 @@ fn propagate_node(&mut self, node: &Node<'tcx>,
             Node::Item(item) => {
                 match item.node {
                     hir::ItemKind::Fn(.., body) => {
-                        let def_id = self.tcx.hir().local_def_id(item.id);
+                        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
                         if item_might_be_inlined(self.tcx,
                                                  &item,
                                                  self.tcx.codegen_fn_attrs(def_id)) {
@@ -295,7 +295,7 @@ fn propagate_node(&mut self, node: &Node<'tcx>,
                         self.visit_nested_body(body);
                     }
                     hir::ImplItemKind::Method(_, body) => {
-                        let did = self.tcx.hir().get_parent_did(search_item);
+                        let did = self.tcx.hir().get_parent_did_by_hir_id(search_item);
                         if method_might_be_inlined(self.tcx, impl_item, did) {
                             self.visit_nested_body(body)
                         }
@@ -317,7 +317,7 @@ fn propagate_node(&mut self, node: &Node<'tcx>,
             _ => {
                 bug!(
                     "found unexpected node kind in worklist: {} ({:?})",
-                    self.tcx.hir().node_to_string(search_item),
+                    self.tcx.hir().hir_to_string(search_item),
                     node,
                 );
             }
@@ -336,7 +336,7 @@ fn propagate_node(&mut self, node: &Node<'tcx>,
 struct CollectPrivateImplItemsVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     access_levels: &'a privacy::AccessLevels,
-    worklist: &'a mut Vec<ast::NodeId>,
+    worklist: &'a mut Vec<hir::HirId>,
 }
 
 impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> {
@@ -344,17 +344,18 @@ fn visit_item(&mut self, item: &hir::Item) {
         // Anything which has custom linkage gets thrown on the worklist no
         // matter where it is in the crate, along with "special std symbols"
         // which are currently akin to allocator symbols.
-        let def_id = self.tcx.hir().local_def_id(item.id);
+        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
         let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
         if codegen_attrs.contains_extern_indicator() ||
             codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
-            self.worklist.push(item.id);
+            self.worklist.push(item.hir_id);
         }
 
         // We need only trait impls here, not inherent impls, and only non-exported ones
         if let hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) = item.node {
-            if !self.access_levels.is_reachable(item.id) {
-                self.worklist.extend(impl_item_refs.iter().map(|r| r.id.node_id));
+            let node_id = self.tcx.hir().hir_to_node_id(item.hir_id);
+            if !self.access_levels.is_reachable(node_id) {
+                self.worklist.extend(impl_item_refs.iter().map(|ii_ref| ii_ref.id.hir_id));
 
                 let trait_def_id = match trait_ref.path.def {
                     Def::Trait(def_id) => def_id,
@@ -368,11 +369,11 @@ fn visit_item(&mut self, item: &hir::Item) {
                 let provided_trait_methods = self.tcx.provided_trait_methods(trait_def_id);
                 self.worklist.reserve(provided_trait_methods.len());
                 for default_method in provided_trait_methods {
-                    let node_id = self.tcx
-                                      .hir()
-                                      .as_local_node_id(default_method.def_id)
-                                      .unwrap();
-                    self.worklist.push(node_id);
+                    let hir_id = self.tcx
+                                     .hir()
+                                     .as_local_hir_id(default_method.def_id)
+                                     .unwrap();
+                    self.worklist.push(hir_id);
                 }
             }
         }
@@ -388,7 +389,7 @@ fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
 // We introduce a new-type here, so we can have a specialized HashStable
 // implementation for it.
 #[derive(Clone)]
-pub struct ReachableSet(pub Lrc<NodeSet>);
+pub struct ReachableSet(pub Lrc<HirIdSet>);
 
 fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> ReachableSet {
     debug_assert!(crate_num == LOCAL_CRATE);
@@ -412,11 +413,12 @@ fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) ->
     //         If other crates link to us, they're going to expect to be able to
     //         use the lang items, so we need to be sure to mark them as
     //         exported.
-    reachable_context.worklist.extend(access_levels.map.iter().map(|(id, _)| *id));
+    reachable_context.worklist.extend(
+        access_levels.map.iter().map(|(id, _)| tcx.hir().node_to_hir_id(*id)));
     for item in tcx.lang_items().items().iter() {
         if let Some(did) = *item {
-            if let Some(node_id) = tcx.hir().as_local_node_id(did) {
-                reachable_context.worklist.push(node_id);
+            if let Some(hir_id) = tcx.hir().as_local_hir_id(did) {
+                reachable_context.worklist.push(hir_id);
             }
         }
     }
index dd44e19bc7df9c371b84f3065ed2dac6986ca117..d2bec1070f9215e409a5269af8123d3fa86175a6 100644 (file)
@@ -13,7 +13,7 @@
 
 use crate::rustc::lint;
 use crate::session::Session;
-use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet, NodeMap};
+use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet};
 use errors::{Applicability, DiagnosticBuilder};
 use rustc_data_structures::sync::Lrc;
 use std::borrow::Cow;
@@ -204,7 +204,7 @@ struct NamedRegionMap {
 
     // For each type and trait definition, maps type parameters
     // to the trait object lifetime defaults computed from them.
-    pub object_lifetime_defaults: NodeMap<Vec<ObjectLifetimeDefault>>,
+    pub object_lifetime_defaults: HirIdMap<Vec<ObjectLifetimeDefault>>,
 }
 
 /// See [`NamedRegionMap`].
@@ -395,8 +395,7 @@ fn resolve_lifetimes<'tcx>(
             .or_default();
         Lrc::get_mut(map).unwrap().insert(hir_id.local_id);
     }
-    for (k, v) in named_region_map.object_lifetime_defaults {
-        let hir_id = tcx.hir().node_to_hir_id(k);
+    for (hir_id, v) in named_region_map.object_lifetime_defaults {
         let map = rl.object_lifetime_defaults
             .entry(hir_id.owner_local_def_id())
             .or_default();
@@ -672,13 +671,14 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
                         // In the future, this should be fixed and this error should be removed.
                         let def = self.map.defs.get(&lifetime.hir_id).cloned();
                         if let Some(Region::LateBound(_, def_id, _)) = def {
-                            if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) {
+                            if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
                                 // Ensure that the parent of the def is an item, not HRTB
-                                let parent_id = self.tcx.hir().get_parent_node(node_id);
-                                let parent_impl_id = hir::ImplItemId { node_id: parent_id };
-                                let parent_trait_id = hir::TraitItemId { node_id: parent_id };
+                                let parent_id = self.tcx.hir().get_parent_node_by_hir_id(hir_id);
+                                let parent_impl_id = hir::ImplItemId { hir_id: parent_id };
+                                let parent_trait_id = hir::TraitItemId { hir_id: parent_id };
                                 let krate = self.tcx.hir().forest.krate();
-                                if !(krate.items.contains_key(&parent_id)
+                                let parent_node_id = self.tcx.hir().hir_to_node_id(parent_id);
+                                if !(krate.items.contains_key(&parent_node_id)
                                     || krate.impl_items.contains_key(&parent_impl_id)
                                     || krate.trait_items.contains_key(&parent_trait_id))
                                 {
@@ -1266,8 +1266,8 @@ fn check_if_label_shadows_lifetime(
 
 fn compute_object_lifetime_defaults(
     tcx: TyCtxt<'_, '_, '_>,
-) -> NodeMap<Vec<ObjectLifetimeDefault>> {
-    let mut map = NodeMap::default();
+) -> HirIdMap<Vec<ObjectLifetimeDefault>> {
+    let mut map = HirIdMap::default();
     for item in tcx.hir().krate().items.values() {
         match item.node {
             hir::ItemKind::Struct(_, ref generics)
@@ -1311,7 +1311,7 @@ fn compute_object_lifetime_defaults(
                     tcx.sess.span_err(item.span, &object_lifetime_default_reprs);
                 }
 
-                map.insert(item.id, result);
+                map.insert(item.hir_id, result);
             }
             _ => {}
         }
@@ -1959,7 +1959,7 @@ fn visit_segment_args(&mut self, def: Def, depth: usize, generic_args: &'tcx hir
             };
 
             let map = &self.map;
-            let unsubst = if let Some(id) = self.tcx.hir().as_local_node_id(def_id) {
+            let unsubst = if let Some(id) = self.tcx.hir().as_local_hir_id(def_id) {
                 &map.object_lifetime_defaults[&id]
             } else {
                 let tcx = self.tcx;
@@ -1974,7 +1974,7 @@ fn visit_segment_args(&mut self, def: Def, depth: usize, generic_args: &'tcx hir
                                     object_lifetime_default,
                                     ..
                                 } => Some(object_lifetime_default),
-                                GenericParamDefKind::Lifetime => None,
+                                GenericParamDefKind::Lifetime | GenericParamDefKind::Const => None,
                             })
                             .collect()
                     })
@@ -2073,10 +2073,9 @@ fn visit_fn_like_elision(&mut self, inputs: &'tcx [hir::Ty], output: Option<&'tc
                     .expect_item_by_hir_id(self.tcx.hir().get_parent_item(parent))
                     .node
                 {
-                    let parent_node_id = self.tcx.hir().hir_to_node_id(parent);
                     assoc_item_kind = trait_items
                         .iter()
-                        .find(|ti| ti.id.node_id == parent_node_id)
+                        .find(|ti| ti.id.hir_id == parent)
                         .map(|ti| ti.kind);
                 }
                 match *m {
@@ -2095,10 +2094,9 @@ fn visit_fn_like_elision(&mut self, inputs: &'tcx [hir::Ty], output: Option<&'tc
                     .node
                 {
                     impl_self = Some(self_ty);
-                    let parent_node_id = self.tcx.hir().hir_to_node_id(parent);
                     assoc_item_kind = impl_items
                         .iter()
-                        .find(|ii| ii.id.node_id == parent_node_id)
+                        .find(|ii| ii.id.hir_id == parent)
                         .map(|ii| ii.kind);
                 }
                 Some(body)
@@ -2398,7 +2396,7 @@ fn report_elision_failure(
 
             let help_name = if let Some(body) = parent {
                 let arg = &self.tcx.hir().body(body).arguments[index];
-                format!("`{}`", self.tcx.hir().node_to_pretty_string(arg.pat.id))
+                format!("`{}`", self.tcx.hir().hir_to_pretty_string(arg.pat.hir_id))
             } else {
                 format!("argument {}", index + 1)
             };
index 3c1b49e2dde6c29740d9a16210b718b71201315e..aa23924486165c0222608ea9d1f383d7a9530815 100644 (file)
@@ -317,10 +317,9 @@ struct MissingStabilityAnnotations<'a, 'tcx: 'a> {
 impl<'a, 'tcx: 'a> MissingStabilityAnnotations<'a, 'tcx> {
     fn check_missing_stability(&self, hir_id: HirId, span: Span, name: &str) {
         let stab = self.tcx.stability().local_stability(hir_id);
-        let node_id = self.tcx.hir().hir_to_node_id(hir_id);
         let is_error = !self.tcx.sess.opts.test &&
                         stab.is_none() &&
-                        self.access_levels.is_reachable(node_id);
+                        self.access_levels.is_reachable(self.tcx.hir().hir_to_node_id(hir_id));
         if is_error {
             self.tcx.sess.span_err(
                 span,
@@ -762,7 +761,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                 // compiler-generated `extern crate` items have a dummy span.
                 if item.span.is_dummy() { return }
 
-                let def_id = self.tcx.hir().local_def_id(item.id);
+                let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
                 let cnum = match self.tcx.extern_mod_stmt_cnum(def_id) {
                     Some(cnum) => cnum,
                     None => return,
@@ -792,7 +791,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
             // There's no good place to insert stability check for non-Copy unions,
             // so semi-randomly perform it here in stability.rs
             hir::ItemKind::Union(..) if !self.tcx.features().untagged_unions => {
-                let def_id = self.tcx.hir().local_def_id(item.id);
+                let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
                 let adt_def = self.tcx.adt_def(def_id);
                 let ty = self.tcx.type_of(def_id);
 
index 956182fc8b275bd680e06f2ac85287deb3cc61ef..dbbeda3e578e46af8851d698f88a589e954a8f74 100644 (file)
@@ -1,6 +1,6 @@
 use std::fmt;
 
-use crate::ty::{Ty, layout::{HasDataLayout, Size}};
+use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size}};
 
 use super::{EvalResult, Pointer, PointerArithmetic, Allocation, AllocId, sign_extend, truncate};
 
@@ -17,6 +17,12 @@ pub struct RawConst<'tcx> {
 /// match the `LocalState` optimizations for easy conversions between `Value` and `ConstValue`.
 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
 pub enum ConstValue<'tcx> {
+    /// A const generic parameter.
+    Param(ParamConst),
+
+    /// Infer the value of the const.
+    Infer(InferConst<'tcx>),
+
     /// Used only for types with `layout::abi::Scalar` ABI and ZSTs.
     ///
     /// Not using the enum `Value` to encode that this must not be `Undef`.
@@ -43,6 +49,8 @@ impl<'tcx> ConstValue<'tcx> {
     #[inline]
     pub fn try_to_scalar(&self) -> Option<Scalar> {
         match *self {
+            ConstValue::Param(_) |
+            ConstValue::Infer(_) |
             ConstValue::ByRef(..) |
             ConstValue::Slice(..) => None,
             ConstValue::Scalar(val) => Some(val),
index b6f5ff25c8fb87b41536a4d48fb78f1ee8112320..0462bb802312a494c138142d60b56dc1e881309f 100644 (file)
@@ -2237,6 +2237,9 @@ pub enum CastKind {
     /// Converts safe fn() to unsafe fn()
     UnsafeFnPointer,
 
+    /// Coerces *mut T to *const T, preserving T.
+    MutToConstPointer,
+
     /// "Unsize" -- convert a thin-or-fat pointer to a fat pointer.
     /// codegen must figure out the details once full monomorphization
     /// is known. For example, this could be used to cast from a
index 99eee4b559a5cc93af4543c0b17a71bb229b72b5..a4c587b5ca76195d762e40935e06cced35bd5851 100644 (file)
@@ -1232,6 +1232,8 @@ fn parse_merge_functions(slot: &mut Option<MergeFunctions>, v: Option<&str>) ->
          Use with RUST_REGION_GRAPH=help for more info"),
     parse_only: bool = (false, parse_bool, [UNTRACKED],
         "parse only; do not compile, assemble, or link"),
+    dual_proc_macros: bool = (false, parse_bool, [TRACKED],
+        "load proc macros for both target and host, but only link to the target"),
     no_codegen: bool = (false, parse_bool, [TRACKED],
         "run all passes except codegen; no output"),
     treat_err_as_bug: bool = (false, parse_bool, [TRACKED],
@@ -1405,9 +1407,7 @@ fn parse_merge_functions(slot: &mut Option<MergeFunctions>, v: Option<&str>) ->
     crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED],
         "inject the given attribute in the crate"),
     self_profile: bool = (false, parse_bool, [UNTRACKED],
-        "run the self profiler"),
-    profile_json: bool = (false, parse_bool, [UNTRACKED],
-        "output a json file with profiler results"),
+        "run the self profiler and output the raw event data"),
     emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
         "emits a section containing stack size metadata"),
     plt: Option<bool> = (None, parse_opt_bool, [TRACKED],
index 77f190e281229bb314cc46a14151dc410f900102..cf09d45ca38fc3556ac6d3760496ff8160848798 100644 (file)
@@ -18,6 +18,7 @@ pub enum FileMatch {
 
 // A module for searching for libraries
 
+#[derive(Clone)]
 pub struct FileSearch<'a> {
     sysroot: &'a Path,
     triple: &'a str,
index 5b9b70edc680990be7dc55ea7d950b5a164bd532..774bc8b450b594eba6d185a94adf811c1b767f72 100644 (file)
@@ -34,7 +34,8 @@
 
 use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple};
 use rustc_data_structures::flock;
-use jobserver::Client;
+use rustc_data_structures::jobserver;
+use ::jobserver::Client;
 
 use std;
 use std::cell::{self, Cell, RefCell};
@@ -43,7 +44,9 @@
 use std::io::Write;
 use std::path::PathBuf;
 use std::time::Duration;
-use std::sync::mpsc;
+use std::sync::{Arc, mpsc};
+
+use parking_lot::Mutex as PlMutex;
 
 mod code_stats;
 pub mod config;
@@ -126,11 +129,8 @@ pub struct Session {
     /// Used by `-Z profile-queries` in `util::common`.
     pub profile_channel: Lock<Option<mpsc::Sender<ProfileQueriesMsg>>>,
 
-    /// Used by `-Z self-profile`.
-    pub self_profiling_active: bool,
-
-    /// Used by `-Z self-profile`.
-    pub self_profiling: Lock<SelfProfiler>,
+    /// Used by -Z self-profile
+    pub self_profiling: Option<Arc<PlMutex<SelfProfiler>>>,
 
     /// Some measurements that are being gathered during compilation.
     pub perf_stats: PerfStats,
@@ -833,27 +833,23 @@ pub fn incr_comp_session_dir_opt(&self) -> Option<cell::Ref<'_, PathBuf>> {
     #[inline(never)]
     #[cold]
     fn profiler_active<F: FnOnce(&mut SelfProfiler) -> ()>(&self, f: F) {
-        let mut profiler = self.self_profiling.borrow_mut();
-        f(&mut profiler);
+        match &self.self_profiling {
+            None => bug!("profiler_active() called but there was no profiler active"),
+            Some(profiler) => {
+                let mut p = profiler.lock();
+
+                f(&mut p);
+            }
+        }
     }
 
     #[inline(always)]
     pub fn profiler<F: FnOnce(&mut SelfProfiler) -> ()>(&self, f: F) {
-        if unlikely!(self.self_profiling_active) {
+        if unlikely!(self.self_profiling.is_some()) {
             self.profiler_active(f)
         }
     }
 
-    pub fn print_profiler_results(&self) {
-        let mut profiler = self.self_profiling.borrow_mut();
-        profiler.print_results(&self.opts);
-    }
-
-    pub fn save_json_results(&self) {
-        let profiler = self.self_profiling.borrow();
-        profiler.save_results(&self.opts);
-    }
-
     pub fn print_perf_stats(&self) {
         println!(
             "Total time spent computing symbol hashes:      {}",
@@ -1135,6 +1131,10 @@ pub fn build_session_(
     source_map: Lrc<source_map::SourceMap>,
     driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
 ) -> Session {
+    let self_profiler =
+        if sopts.debugging_opts.self_profile { Some(Arc::new(PlMutex::new(SelfProfiler::new()))) }
+        else { None };
+
     let host_triple = TargetTriple::from_triple(config::host_triple());
     let host = Target::search(&host_triple).unwrap_or_else(|e|
         span_diagnostic
@@ -1184,9 +1184,6 @@ pub fn build_session_(
         CguReuseTracker::new_disabled()
     };
 
-    let self_profiling_active = sopts.debugging_opts.self_profile ||
-                                sopts.debugging_opts.profile_json;
-
     let sess = Session {
         target: target_cfg,
         host,
@@ -1215,8 +1212,7 @@ pub fn build_session_(
         imported_macro_spans: OneThread::new(RefCell::new(FxHashMap::default())),
         incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)),
         cgu_reuse_tracker,
-        self_profiling_active,
-        self_profiling: Lock::new(SelfProfiler::new()),
+        self_profiling: self_profiler,
         profile_channel: Lock::new(None),
         perf_stats: PerfStats {
             symbol_hash_time: Lock::new(Duration::from_secs(0)),
@@ -1230,32 +1226,7 @@ pub fn build_session_(
         optimization_fuel,
         print_fuel_crate,
         print_fuel,
-        // Note that this is unsafe because it may misinterpret file descriptors
-        // on Unix as jobserver file descriptors. We hopefully execute this near
-        // the beginning of the process though to ensure we don't get false
-        // positives, or in other words we try to execute this before we open
-        // any file descriptors ourselves.
-        //
-        // Pick a "reasonable maximum" if we don't otherwise have
-        // a jobserver in our environment, capping out at 32 so we
-        // don't take everything down by hogging the process run queue.
-        // The fixed number is used to have deterministic compilation
-        // across machines.
-        //
-        // Also note that we stick this in a global because there could be
-        // multiple `Session` instances in this process, and the jobserver is
-        // per-process.
-        jobserver: unsafe {
-            static mut GLOBAL_JOBSERVER: *mut Client = 0 as *mut _;
-            static INIT: std::sync::Once = std::sync::ONCE_INIT;
-            INIT.call_once(|| {
-                let client = Client::from_env().unwrap_or_else(|| {
-                    Client::new(32).expect("failed to create jobserver")
-                });
-                GLOBAL_JOBSERVER = Box::into_raw(Box::new(client));
-            });
-            (*GLOBAL_JOBSERVER).clone()
-        },
+        jobserver: jobserver::client(),
         has_global_allocator: Once::new(),
         has_panic_handler: Once::new(),
         driver_lint_caps,
index 3eb49092fed1d6af4f4abc02a83ece899ff6c8b8..2f6cbacbd4a9dc480af076181df122d02bdcc61f 100644 (file)
@@ -389,7 +389,8 @@ fn on_unimplemented_note(
 
         for param in generics.params.iter() {
             let value = match param.kind {
-                GenericParamDefKind::Type {..} => {
+                GenericParamDefKind::Type { .. } |
+                GenericParamDefKind::Const => {
                     trait_ref.substs[param.index as usize].to_string()
                 },
                 GenericParamDefKind::Lifetime => continue,
@@ -598,11 +599,12 @@ fn get_parent_trait_ref(&self, code: &ObligationCauseCode<'tcx>) -> Option<Strin
         }
     }
 
-    pub fn report_selection_error(&self,
-                                  obligation: &PredicateObligation<'tcx>,
-                                  error: &SelectionError<'tcx>,
-                                  fallback_has_occurred: bool)
-    {
+    pub fn report_selection_error(
+        &self,
+        obligation: &PredicateObligation<'tcx>,
+        error: &SelectionError<'tcx>,
+        fallback_has_occurred: bool,
+    ) {
         let span = obligation.cause.span;
 
         let mut err = match *error {
@@ -672,6 +674,7 @@ pub fn report_selection_error(&self,
 
                         self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err);
                         self.suggest_remove_reference(&obligation, &mut err, &trait_ref);
+                        self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref);
 
                         // Try to report a help message
                         if !trait_ref.has_infer_types() &&
@@ -900,9 +903,11 @@ pub fn report_selection_error(&self,
 
     /// When encountering an assignment of an unsized trait, like `let x = ""[..];`, provide a
     /// suggestion to borrow the initializer in order to use have a slice instead.
-    fn suggest_borrow_on_unsized_slice(&self,
-                                       code: &ObligationCauseCode<'tcx>,
-                                       err: &mut DiagnosticBuilder<'tcx>) {
+    fn suggest_borrow_on_unsized_slice(
+        &self,
+        code: &ObligationCauseCode<'tcx>,
+        err: &mut DiagnosticBuilder<'tcx>,
+    ) {
         if let &ObligationCauseCode::VariableType(node_id) = code {
             let parent_node = self.tcx.hir().get_parent_node(node_id);
             if let Some(Node::Local(ref local)) = self.tcx.hir().find(parent_node) {
@@ -924,10 +929,12 @@ fn suggest_borrow_on_unsized_slice(&self,
 
     /// Whenever references are used by mistake, like `for (i, e) in &vec.iter().enumerate()`,
     /// suggest removing these references until we reach a type that implements the trait.
-    fn suggest_remove_reference(&self,
-                                obligation: &PredicateObligation<'tcx>,
-                                err: &mut DiagnosticBuilder<'tcx>,
-                                trait_ref: &ty::Binder<ty::TraitRef<'tcx>>) {
+    fn suggest_remove_reference(
+        &self,
+        obligation: &PredicateObligation<'tcx>,
+        err: &mut DiagnosticBuilder<'tcx>,
+        trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
+    ) {
         let trait_ref = trait_ref.skip_binder();
         let span = obligation.cause.span;
 
@@ -969,6 +976,40 @@ fn suggest_remove_reference(&self,
         }
     }
 
+    fn suggest_semicolon_removal(
+        &self,
+        obligation: &PredicateObligation<'tcx>,
+        err: &mut DiagnosticBuilder<'tcx>,
+        span: Span,
+        trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
+    ) {
+        let hir = self.tcx.hir();
+        let parent_node = hir.get_parent_node(
+            hir.hir_to_node_id(obligation.cause.body_id),
+        );
+        let node = hir.find(parent_node);
+        if let Some(hir::Node::Item(hir::Item {
+            node: hir::ItemKind::Fn(decl, _, _, body_id),
+            ..
+        })) = node {
+            let body = hir.body(*body_id);
+            if let hir::ExprKind::Block(blk, _) = &body.value.node {
+                if decl.output.span().overlaps(span) && blk.expr.is_none() &&
+                    "()" == &trait_ref.self_ty().to_string()
+                {
+                    // FIXME(estebank): When encountering a method with a trait
+                    // bound not satisfied in the return type with a body that has
+                    // no return, suggest removal of semicolon on last statement.
+                    // Once that is added, close #54771.
+                    if let Some(ref stmt) = blk.stmts.last() {
+                        let sp = self.tcx.sess.source_map().end_point(stmt.span);
+                        err.span_label(sp, "consider removing this semicolon");
+                    }
+                }
+            }
+        }
+    }
+
     /// Given some node representing a fn-like thing in the HIR map,
     /// returns a span and `ArgKind` information that describes the
     /// arguments it expects. This can be supplied to
index ee7893a27de7dd6caad1226c9feff3498437fac1..32bb7f186938a7ea7ccafba09f39ee1c34a8407d 100644 (file)
@@ -1010,7 +1010,8 @@ fn vtable_methods<'a, 'tcx>(
                     InternalSubsts::for_item(tcx, def_id, |param, _|
                         match param.kind {
                             GenericParamDefKind::Lifetime => tcx.types.re_erased.into(),
-                            GenericParamDefKind::Type {..} => {
+                            GenericParamDefKind::Type { .. } |
+                            GenericParamDefKind::Const => {
                                 trait_ref.substs[param.index as usize]
                             }
                         }
index b2079c2516935c5e1c11b125b29608d72de7e310..e7a5138e6893c5384875dd00dfb263e40a528c06 100644 (file)
@@ -310,7 +310,8 @@ fn virtual_call_violation_for_method(self,
         }
 
         // We can't monomorphize things like `fn foo<A>(...)`.
-        if self.generics_of(method.def_id).own_counts().types != 0 {
+        let own_counts = self.generics_of(method.def_id).own_counts();
+        if own_counts.types + own_counts.consts != 0 {
             return Some(MethodViolationCode::Generic);
         }
 
index f61c32614cc931847700973c160074ef25b08314..c86fd0d52b901ce62fe3fb64dea452b8f73cb001 100644 (file)
@@ -280,7 +280,8 @@ pub fn format(&self,
         let generics = tcx.generics_of(trait_ref.def_id);
         let generic_map = generics.params.iter().filter_map(|param| {
             let value = match param.kind {
-                GenericParamDefKind::Type {..} => {
+                GenericParamDefKind::Type { .. } |
+                GenericParamDefKind::Const => {
                     trait_ref.substs[param.index as usize].to_string()
                 },
                 GenericParamDefKind::Lifetime => return None
index 1983dfbd4b7d16f06ae37b07deb8741d5b073e75..f6e6067bb6fc8ebf103049c98c2b2b994689ee41 100644 (file)
@@ -21,8 +21,8 @@
 use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
 use crate::middle::stability;
 use crate::mir::{self, Mir, interpret, ProjectionKind};
-use crate::mir::interpret::Allocation;
-use crate::ty::subst::{Kind, InternalSubsts, Subst, SubstsRef};
+use crate::mir::interpret::{ConstValue, Allocation};
+use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, Subst};
 use crate::ty::ReprOptions;
 use crate::traits;
 use crate::traits::{Clause, Clauses, GoalKind, Goal, Goals};
@@ -31,8 +31,9 @@
 use crate::ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const, LazyConst};
 use crate::ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate};
 use crate::ty::RegionKind;
-use crate::ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
+use crate::ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid, ConstVid};
 use crate::ty::TyKind::*;
+use crate::ty::{InferConst, ParamConst};
 use crate::ty::GenericParamDefKind;
 use crate::ty::layout::{LayoutDetails, TargetDataLayout, VariantIdx};
 use crate::ty::query;
@@ -59,7 +60,6 @@
 use std::fmt;
 use std::mem;
 use std::ops::{Deref, Bound};
-use std::ptr;
 use std::iter;
 use std::sync::mpsc;
 use std::sync::Arc;
@@ -171,7 +171,7 @@ fn intern_ty(
 
                 // Make sure we don't end up with inference
                 // types/regions in the global interner
-                if ptr::eq(local, global) {
+                if ptr_eq(local, global) {
                     bug!("Attempted to intern `{:?}` which contains \
                         inference types/regions in the global type context",
                         &ty_struct);
@@ -873,6 +873,18 @@ pub fn is_identity(&self) -> bool {
                             }
                             _ => false,
                         },
+
+                        UnpackedKind::Const(ct) => match ct {
+                            ty::LazyConst::Evaluated(ty::Const {
+                                val: ConstValue::Infer(InferConst::Canonical(debruijn, b)),
+                                ..
+                            }) => {
+                                // We only allow a `ty::INNERMOST` index in substitutions.
+                                assert_eq!(*debruijn, ty::INNERMOST);
+                                cvar == *b
+                            }
+                            _ => false,
+                        },
                     }
                 })
             },
@@ -1163,7 +1175,7 @@ pub fn lift_to_global<T: ?Sized + Lift<'gcx>>(self, value: &T) -> Option<T::Lift
 
     /// Returns `true` if self is the same as self.global_tcx().
     fn is_global(self) -> bool {
-        ptr::eq(self.interners, &self.global_interners)
+        ptr_eq(self.interners, &self.global_interners)
     }
 
     /// Creates a type context and call the closure with a `TyCtxt` reference
@@ -1817,12 +1829,11 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
 }
 
 pub mod tls {
-    use super::{GlobalCtxt, TyCtxt};
+    use super::{GlobalCtxt, TyCtxt, ptr_eq};
 
     use std::fmt;
     use std::mem;
     use std::marker::PhantomData;
-    use std::ptr;
     use syntax_pos;
     use crate::ty::query;
     use errors::{Diagnostic, TRACK_DIAGNOSTICS};
@@ -2065,7 +2076,7 @@ pub fn with_related_context<'a, 'gcx, 'tcx1, F, R>(tcx: TyCtxt<'a, 'gcx, 'tcx1>,
     {
         with_context(|context| {
             unsafe {
-                assert!(ptr::eq(context.tcx.gcx, tcx.gcx));
+                assert!(ptr_eq(context.tcx.gcx, tcx.gcx));
                 let context: &ImplicitCtxt<'_, '_, '_> = mem::transmute(context);
                 f(context)
             }
@@ -2083,8 +2094,8 @@ pub fn with_fully_related_context<'a, 'gcx, 'tcx, F, R>(tcx: TyCtxt<'a, 'gcx, 't
     {
         with_context(|context| {
             unsafe {
-                assert!(ptr::eq(context.tcx.gcx, tcx.gcx));
-                assert!(ptr::eq(context.tcx.interners, tcx.interners));
+                assert!(ptr_eq(context.tcx.gcx, tcx.gcx));
+                assert!(ptr_eq(context.tcx.interners, tcx.interners));
                 let context: &ImplicitCtxt<'_, '_, '_> = mem::transmute(context);
                 f(context)
             }
@@ -2122,15 +2133,19 @@ mod inner {
             #[derive(Copy, Clone)]
             struct DebugStat {
                 total: usize,
-                region_infer: usize,
+                lt_infer: usize,
                 ty_infer: usize,
-                both_infer: usize,
+                ct_infer: usize,
+                all_infer: usize,
             }
 
             pub fn go(tcx: TyCtxt<'_, '_, '_>) {
                 let mut total = DebugStat {
                     total: 0,
-                    region_infer: 0, ty_infer: 0, both_infer: 0,
+                    lt_infer: 0,
+                    ty_infer: 0,
+                    ct_infer: 0,
+                    all_infer: 0,
                 };
                 $(let mut $variant = total;)*
 
@@ -2141,31 +2156,35 @@ pub fn go(tcx: TyCtxt<'_, '_, '_>) {
                         ty::Error => /* unimportant */ continue,
                         $(ty::$variant(..) => &mut $variant,)*
                     };
-                    let region = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
+                    let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
                     let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
+                    let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
 
                     variant.total += 1;
                     total.total += 1;
-                    if region { total.region_infer += 1; variant.region_infer += 1 }
+                    if lt { total.lt_infer += 1; variant.lt_infer += 1 }
                     if ty { total.ty_infer += 1; variant.ty_infer += 1 }
-                    if region && ty { total.both_infer += 1; variant.both_infer += 1 }
+                    if ct { total.ct_infer += 1; variant.ct_infer += 1 }
+                    if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
                 }
-                println!("Ty interner             total           ty region  both");
+                println!("Ty interner             total           ty lt ct all");
                 $(println!("    {:18}: {uses:6} {usespc:4.1}%, \
-                            {ty:4.1}% {region:5.1}% {both:4.1}%",
-                           stringify!($variant),
-                           uses = $variant.total,
-                           usespc = $variant.total as f64 * 100.0 / total.total as f64,
-                           ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
-                           region = $variant.region_infer as f64 * 100.0  / total.total as f64,
-                           both = $variant.both_infer as f64 * 100.0  / total.total as f64);
-                  )*
+                            {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
+                    stringify!($variant),
+                    uses = $variant.total,
+                    usespc = $variant.total as f64 * 100.0 / total.total as f64,
+                    ty = $variant.ty_infer as f64 * 100.0  / total.total as f64,
+                    lt = $variant.lt_infer as f64 * 100.0  / total.total as f64,
+                    ct = $variant.ct_infer as f64 * 100.0  / total.total as f64,
+                    all = $variant.all_infer as f64 * 100.0  / total.total as f64);
+                )*
                 println!("                  total {uses:6}        \
-                          {ty:4.1}% {region:5.1}% {both:4.1}%",
-                         uses = total.total,
-                         ty = total.ty_infer as f64 * 100.0  / total.total as f64,
-                         region = total.region_infer as f64 * 100.0  / total.total as f64,
-                         both = total.both_infer as f64 * 100.0  / total.total as f64)
+                          {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%",
+                    uses = total.total,
+                    ty = total.ty_infer as f64 * 100.0  / total.total as f64,
+                    lt = total.lt_infer as f64 * 100.0  / total.total as f64,
+                    ct = total.ct_infer as f64 * 100.0  / total.total as f64,
+                    all = total.all_infer as f64 * 100.0  / total.total as f64)
             }
         }
 
@@ -2520,7 +2539,10 @@ pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
         let adt_def = self.adt_def(def_id);
         let substs = InternalSubsts::for_item(self, def_id, |param, substs| {
             match param.kind {
-                GenericParamDefKind::Lifetime => bug!(),
+                GenericParamDefKind::Lifetime |
+                GenericParamDefKind::Const => {
+                    bug!()
+                }
                 GenericParamDefKind::Type { has_default, .. } => {
                     if param.index == 0 {
                         ty.into()
@@ -2661,10 +2683,18 @@ pub fn mk_generator_witness(self, types: ty::Binder<&'tcx List<Ty<'tcx>>>) -> Ty
     }
 
     #[inline]
-    pub fn mk_var(self, v: TyVid) -> Ty<'tcx> {
+    pub fn mk_ty_var(self, v: TyVid) -> Ty<'tcx> {
         self.mk_infer(TyVar(v))
     }
 
+    #[inline]
+    pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> &'tcx LazyConst<'tcx> {
+        self.mk_lazy_const(LazyConst::Evaluated(ty::Const {
+            val: ConstValue::Infer(InferConst::Var(v)),
+            ty,
+        }))
+    }
+
     #[inline]
     pub fn mk_int_var(self, v: IntVid) -> Ty<'tcx> {
         self.mk_infer(IntVar(v))
@@ -2687,6 +2717,19 @@ pub fn mk_ty_param(self,
         self.mk_ty(Param(ParamTy { idx: index, name: name }))
     }
 
+    #[inline]
+    pub fn mk_const_param(
+        self,
+        index: u32,
+        name: InternedString,
+        ty: Ty<'tcx>
+    ) -> &'tcx LazyConst<'tcx> {
+        self.mk_lazy_const(LazyConst::Evaluated(ty::Const {
+            val: ConstValue::Param(ParamConst { index, name }),
+            ty,
+        }))
+    }
+
     #[inline]
     pub fn mk_self_type(self) -> Ty<'tcx> {
         self.mk_ty_param(0, keywords::SelfUpper.name().as_interned_str())
@@ -2697,7 +2740,10 @@ pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> Kind<'tcx> {
             GenericParamDefKind::Lifetime => {
                 self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into()
             }
-            GenericParamDefKind::Type {..} => self.mk_ty_param(param.index, param.name).into(),
+            GenericParamDefKind::Type { .. } => self.mk_ty_param(param.index, param.name).into(),
+            GenericParamDefKind::Const => {
+                self.mk_const_param(param.index, param.name, self.type_of(param.def_id)).into()
+            }
         }
     }
 
@@ -2970,6 +3016,12 @@ fn intern_with<I: Iterator<Item=Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> S
     }
 }
 
+// We are comparing types with different invariant lifetimes, so `ptr::eq`
+// won't work for us.
+fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
+    t as *const () == u as *const ()
+}
+
 pub fn provide(providers: &mut ty::query::Providers<'_>) {
     providers.in_scope_traits_map = |tcx, id| tcx.gcx.trait_map.get(&id).cloned();
     providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).cloned();
index 2b12dcca93ad7c7a1022c66d3030aaf90b9b5336..64ceb9729ed15374b47619090ece88830606c6be 100644 (file)
@@ -1,5 +1,6 @@
-use crate::ty::subst::SubstsRef;
-use crate::ty::{self, Ty, TypeFlags, TypeFoldable};
+use crate::ty::subst::{SubstsRef, UnpackedKind};
+use crate::ty::{self, Ty, TypeFlags, TypeFoldable, InferConst};
+use crate::mir::interpret::ConstValue;
 
 #[derive(Debug)]
 pub struct FlagComputation {
@@ -232,6 +233,21 @@ fn add_region(&mut self, r: ty::Region<'_>) {
         }
     }
 
+    fn add_const(&mut self, c: &ty::LazyConst<'_>) {
+        match c {
+            ty::LazyConst::Unevaluated(_, substs) => self.add_substs(substs),
+            // Only done to add the binder for the type. The type flags are
+            // included in `Const::type_flags`.
+            ty::LazyConst::Evaluated(ty::Const { ty, val }) => {
+                self.add_ty(ty);
+                if let ConstValue::Infer(InferConst::Canonical(debruijn, _)) = val {
+                    self.add_binder(*debruijn)
+                }
+            }
+        }
+        self.add_flags(c.type_flags());
+    }
+
     fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
         self.add_substs(projection.substs);
         self.add_ty(projection.ty);
@@ -242,12 +258,12 @@ fn add_projection_ty(&mut self, projection_ty: &ty::ProjectionTy<'_>) {
     }
 
     fn add_substs(&mut self, substs: SubstsRef<'_>) {
-        for ty in substs.types() {
-            self.add_ty(ty);
-        }
-
-        for r in substs.regions() {
-            self.add_region(r);
+        for kind in substs {
+            match kind.unpack() {
+                UnpackedKind::Type(ty) => self.add_ty(ty),
+                UnpackedKind::Lifetime(lt) => self.add_region(lt),
+                UnpackedKind::Const(ct) => self.add_const(ct),
+            }
         }
     }
 }
index aa4d1e5ea90cbf9609df79e989be33a606d481a9..7f77d037bb6a1a715711d8f81e4979720adbd130 100644 (file)
@@ -91,7 +91,9 @@ fn has_infer_types(&self) -> bool {
         self.has_type_flags(TypeFlags::HAS_TY_INFER)
     }
     fn needs_infer(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
+        self.has_type_flags(
+            TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER | TypeFlags::HAS_CT_INFER
+        )
     }
     fn has_placeholders(&self) -> bool {
         self.has_type_flags(TypeFlags::HAS_RE_PLACEHOLDER | TypeFlags::HAS_TY_PLACEHOLDER)
@@ -117,7 +119,7 @@ fn has_erasable_regions(&self) -> bool {
     }
 
     /// Indicates whether this value references only 'global'
-    /// types/lifetimes that are the same regardless of what fn we are
+    /// generic parameters that are the same regardless of what fn we are
     /// in. This is used for caching.
     fn is_global(&self) -> bool {
         !self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES)
@@ -841,14 +843,13 @@ fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
     }
 
     fn visit_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> bool {
-        if let ty::LazyConst::Unevaluated(..) = c {
-            let projection_flags = TypeFlags::HAS_NORMALIZABLE_PROJECTION |
-                TypeFlags::HAS_PROJECTION;
-            if projection_flags.intersects(self.flags) {
-                return true;
-            }
+        let flags = c.type_flags();
+        debug!("HasTypeFlagsVisitor: c={:?} c.flags={:?} self.flags={:?}", c, flags, self.flags);
+        if flags.intersects(self.flags) {
+            true
+        } else {
+            c.super_visit_with(self)
         }
-        c.super_visit_with(self)
     }
 }
 
index 6c507c0015d7bcaa19e51ccc260b2bdc310a9e0e..7d2b21b9aecdaed1f0c8e579f001907204ea2a22 100644 (file)
@@ -1176,14 +1176,20 @@ enum StructKind {
 
     /// This is invoked by the `layout_raw` query to record the final
     /// layout of each type.
-    #[inline]
+    #[inline(always)]
     fn record_layout_for_printing(&self, layout: TyLayout<'tcx>) {
-        // If we are running with `-Zprint-type-sizes`, record layouts for
-        // dumping later. Ignore layouts that are done with non-empty
-        // environments or non-monomorphic layouts, as the user only wants
-        // to see the stuff resulting from the final codegen session.
+        // If we are running with `-Zprint-type-sizes`, maybe record layouts
+        // for dumping later.
+        if self.tcx.sess.opts.debugging_opts.print_type_sizes {
+            self.record_layout_for_printing_outlined(layout)
+        }
+    }
+
+    fn record_layout_for_printing_outlined(&self, layout: TyLayout<'tcx>) {
+        // Ignore layouts that are done with non-empty environments or
+        // non-monomorphic layouts, as the user only wants to see the stuff
+        // resulting from the final codegen session.
         if
-            !self.tcx.sess.opts.debugging_opts.print_type_sizes ||
             layout.ty.has_param_types() ||
             layout.ty.has_self_ty() ||
             !self.param_env.caller_bounds.is_empty()
@@ -1191,10 +1197,6 @@ fn record_layout_for_printing(&self, layout: TyLayout<'tcx>) {
             return;
         }
 
-        self.record_layout_for_printing_outlined(layout)
-    }
-
-    fn record_layout_for_printing_outlined(&self, layout: TyLayout<'tcx>) {
         // (delay format until we actually need it)
         let record = |kind, packed, opt_discr_size, variants| {
             let type_desc = format!("{:?}", layout.ty);
index 5243c4dbfd209ea6787857c5697a5adc2d762203..a649e312b434590d22209264293939bbc2c32ec8 100644 (file)
 
 pub use self::sty::{Binder, BoundTy, BoundTyKind, BoundVar, DebruijnIndex, INNERMOST};
 pub use self::sty::{FnSig, GenSig, CanonicalPolyFnSig, PolyFnSig, PolyGenSig};
-pub use self::sty::{InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
+pub use self::sty::{InferTy, ParamTy, ParamConst, InferConst, ProjectionTy, ExistentialPredicate};
 pub use self::sty::{ClosureSubsts, GeneratorSubsts, UpvarSubsts, TypeAndMut};
 pub use self::sty::{TraitRef, TyKind, PolyTraitRef};
 pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
 pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const, LazyConst};
 pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
 pub use self::sty::RegionKind;
-pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid};
+pub use self::sty::{TyVid, IntVid, FloatVid, ConstVid, RegionVid};
 pub use self::sty::BoundRegion::*;
 pub use self::sty::InferTy::*;
 pub use self::sty::RegionKind::*;
@@ -260,7 +260,7 @@ fn parent(self, id: DefId) -> Option<DefId> {
 }
 
 impl Visibility {
-    pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt<'_, '_, '_>) -> Self {
+    pub fn from_hir(visibility: &hir::Visibility, id: hir::HirId, tcx: TyCtxt<'_, '_, '_>) -> Self {
         match visibility.node {
             hir::VisibilityKind::Public => Visibility::Public,
             hir::VisibilityKind::Crate(_) => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
@@ -271,7 +271,7 @@ pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt<'_, '_, '_
                 def => Visibility::Restricted(def.def_id()),
             },
             hir::VisibilityKind::Inherited => {
-                Visibility::Restricted(tcx.hir().get_module_parent(id))
+                Visibility::Restricted(tcx.hir().get_module_parent_by_hir_id(id))
             }
         }
     }
@@ -451,6 +451,8 @@ pub struct TypeFlags: u32 {
 
         const HAS_TY_PLACEHOLDER = 1 << 14;
 
+        const HAS_CT_INFER = 1 << 15;
+
         const NEEDS_SUBST        = TypeFlags::HAS_PARAMS.bits |
                                    TypeFlags::HAS_SELF.bits |
                                    TypeFlags::HAS_RE_EARLY_BOUND.bits;
@@ -462,6 +464,7 @@ pub struct TypeFlags: u32 {
                                   TypeFlags::HAS_SELF.bits |
                                   TypeFlags::HAS_TY_INFER.bits |
                                   TypeFlags::HAS_RE_INFER.bits |
+                                  TypeFlags::HAS_CT_INFER.bits |
                                   TypeFlags::HAS_RE_PLACEHOLDER.bits |
                                   TypeFlags::HAS_RE_EARLY_BOUND.bits |
                                   TypeFlags::HAS_FREE_REGIONS.bits |
@@ -837,7 +840,8 @@ pub enum GenericParamDefKind {
         has_default: bool,
         object_lifetime_default: ObjectLifetimeDefault,
         synthetic: Option<hir::SyntheticTyParamKind>,
-    }
+    },
+    Const,
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable)]
@@ -880,6 +884,7 @@ pub fn to_bound_region(&self) -> ty::BoundRegion {
 pub struct GenericParamCount {
     pub lifetimes: usize,
     pub types: usize,
+    pub consts: usize,
 }
 
 /// Information about the formal type/lifetime parameters associated
@@ -915,6 +920,7 @@ pub fn own_counts(&self) -> GenericParamCount {
             match param.kind {
                 GenericParamDefKind::Lifetime => own_counts.lifetimes += 1,
                 GenericParamDefKind::Type { .. } => own_counts.types += 1,
+                GenericParamDefKind::Const => own_counts.consts += 1,
             };
         }
 
@@ -924,7 +930,7 @@ pub fn own_counts(&self) -> GenericParamCount {
     pub fn requires_monomorphization(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
         for param in &self.params {
             match param.kind {
-                GenericParamDefKind::Type { .. } => return true,
+                GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => return true,
                 GenericParamDefKind::Lifetime => {}
             }
         }
@@ -944,7 +950,7 @@ pub fn region_param(&'tcx self,
         if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
             let param = &self.params[index as usize];
             match param.kind {
-                ty::GenericParamDefKind::Lifetime => param,
+                GenericParamDefKind::Lifetime => param,
                 _ => bug!("expected lifetime parameter, but found another generic parameter")
             }
         } else {
@@ -961,7 +967,7 @@ pub fn type_param(&'tcx self,
         if let Some(index) = param.idx.checked_sub(self.parent_count as u32) {
             let param = &self.params[index as usize];
             match param.kind {
-                ty::GenericParamDefKind::Type {..} => param,
+                GenericParamDefKind::Type { .. } => param,
                 _ => bug!("expected type parameter, but found another generic parameter")
             }
         } else {
@@ -969,6 +975,23 @@ pub fn type_param(&'tcx self,
                .type_param(param, tcx)
         }
     }
+
+    /// Returns the `ConstParameterDef` associated with this `ParamConst`.
+    pub fn const_param(&'tcx self,
+                       param: &ParamConst,
+                       tcx: TyCtxt<'a, 'gcx, 'tcx>)
+                       -> &GenericParamDef {
+        if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
+            let param = &self.params[index as usize];
+            match param.kind {
+                GenericParamDefKind::Const => param,
+                _ => bug!("expected const parameter, but found another generic parameter")
+            }
+        } else {
+            tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
+                .const_param(param, tcx)
+        }
+    }
 }
 
 /// Bounds on generics.
@@ -2727,7 +2750,7 @@ fn associated_item_from_trait_item_ref(self,
                                            parent_vis: &hir::Visibility,
                                            trait_item_ref: &hir::TraitItemRef)
                                            -> AssociatedItem {
-        let def_id = self.hir().local_def_id(trait_item_ref.id.node_id);
+        let def_id = self.hir().local_def_id_from_hir_id(trait_item_ref.id.hir_id);
         let (kind, has_self) = match trait_item_ref.kind {
             hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false),
             hir::AssociatedItemKind::Method { has_self } => {
@@ -2741,7 +2764,7 @@ fn associated_item_from_trait_item_ref(self,
             ident: trait_item_ref.ident,
             kind,
             // Visibility of trait items is inherited from their traits.
-            vis: Visibility::from_hir(parent_vis, trait_item_ref.id.node_id, self),
+            vis: Visibility::from_hir(parent_vis, trait_item_ref.id.hir_id, self),
             defaultness: trait_item_ref.defaultness,
             def_id,
             container: TraitContainer(parent_def_id),
@@ -2753,7 +2776,7 @@ fn associated_item_from_impl_item_ref(self,
                                           parent_def_id: DefId,
                                           impl_item_ref: &hir::ImplItemRef)
                                           -> AssociatedItem {
-        let def_id = self.hir().local_def_id(impl_item_ref.id.node_id);
+        let def_id = self.hir().local_def_id_from_hir_id(impl_item_ref.id.hir_id);
         let (kind, has_self) = match impl_item_ref.kind {
             hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false),
             hir::AssociatedItemKind::Method { has_self } => {
@@ -2767,7 +2790,7 @@ fn associated_item_from_impl_item_ref(self,
             ident: impl_item_ref.ident,
             kind,
             // Visibility of trait impl items doesn't matter.
-            vis: ty::Visibility::from_hir(&impl_item_ref.vis, impl_item_ref.id.node_id, self),
+            vis: ty::Visibility::from_hir(&impl_item_ref.vis, impl_item_ref.id.hir_id, self),
             defaultness: impl_item_ref.defaultness,
             def_id,
             container: ImplContainer(parent_def_id),
@@ -3037,13 +3060,13 @@ pub fn with_freevars<T, F>(self, fid: NodeId, f: F) -> T where
 }
 
 fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> AssociatedItem {
-    let id = tcx.hir().as_local_node_id(def_id).unwrap();
-    let parent_id = tcx.hir().get_parent(id);
-    let parent_def_id = tcx.hir().local_def_id(parent_id);
-    let parent_item = tcx.hir().expect_item(parent_id);
+    let id = tcx.hir().as_local_hir_id(def_id).unwrap();
+    let parent_id = tcx.hir().get_parent_item(id);
+    let parent_def_id = tcx.hir().local_def_id_from_hir_id(parent_id);
+    let parent_item = tcx.hir().expect_item_by_hir_id(parent_id);
     match parent_item.node {
         hir::ItemKind::Impl(.., ref impl_item_refs) => {
-            if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.node_id == id) {
+            if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.hir_id == id) {
                 let assoc_item = tcx.associated_item_from_impl_item_ref(parent_def_id,
                                                                         impl_item_ref);
                 debug_assert_eq!(assoc_item.def_id, def_id);
@@ -3052,7 +3075,7 @@ fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Asso
         }
 
         hir::ItemKind::Trait(.., ref trait_item_refs) => {
-            if let Some(trait_item_ref) = trait_item_refs.iter().find(|i| i.id.node_id == id) {
+            if let Some(trait_item_ref) = trait_item_refs.iter().find(|i| i.id.hir_id == id) {
                 let assoc_item = tcx.associated_item_from_trait_item_ref(parent_def_id,
                                                                          &parent_item.vis,
                                                                          trait_item_ref);
@@ -3106,13 +3129,13 @@ fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         hir::ItemKind::Trait(.., ref trait_item_refs) => {
             trait_item_refs.iter()
                            .map(|trait_item_ref| trait_item_ref.id)
-                           .map(|id| tcx.hir().local_def_id(id.node_id))
+                           .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
                            .collect()
         }
         hir::ItemKind::Impl(.., ref impl_item_refs) => {
             impl_item_refs.iter()
                           .map(|impl_item_ref| impl_item_ref.id)
-                          .map(|id| tcx.hir().local_def_id(id.node_id))
+                          .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
                           .collect()
         }
         hir::ItemKind::TraitAlias(..) => vec![],
index 22211468412c1f1551d65b1df4457273de942327..8e68c9fa30431c13789630c95e6a37aa838f0f64 100644 (file)
@@ -7,6 +7,7 @@
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::{Lock, LockGuard, Lrc, Weak};
 use rustc_data_structures::OnDrop;
+use rustc_data_structures::jobserver;
 use syntax_pos::Span;
 
 use crate::ty::tls;
@@ -198,7 +199,11 @@ fn r#await(&self, waiter: &Lrc<QueryWaiter<'tcx>>) {
             // we have to be in the `wait` call. This is ensured by the deadlock handler
             // getting the self.info lock.
             rayon_core::mark_blocked();
+            jobserver::release_thread();
             waiter.condvar.wait(&mut info);
+            // Release the lock before we potentially block in `acquire_thread`
+            mem::drop(info);
+            jobserver::acquire_thread();
         }
     }
 
index 2940757fa905be45e68db9baa12418123ca595c8..3a31801b3be39f2c0728007f0319d6e89d810317 100644 (file)
@@ -705,6 +705,9 @@ fn relate<'a, 'gcx, R>(
             (UnpackedKind::Type(unpacked), x) => {
                 bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
             }
+            (UnpackedKind::Const(_), _) => {
+                unimplemented!() // FIXME(const_generics)
+            }
         }
     }
 }
index f1a465e1f1724b384b1c7df0dbe0671a73965f9b..f9eb336a4a3e2def619c58c7678b937e3d7fcc23 100644 (file)
@@ -5,12 +5,13 @@
 
 use crate::mir::ProjectionKind;
 use crate::mir::interpret::ConstValue;
-use crate::ty::{self, Lift, Ty, TyCtxt};
+use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst};
 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use smallvec::SmallVec;
 use crate::mir::interpret;
 
+use std::marker::PhantomData;
 use std::rc::Rc;
 
 ///////////////////////////////////////////////////////////////////////////
@@ -49,6 +50,7 @@
     crate::ty::BoundRegion,
     crate::ty::ClosureKind,
     crate::ty::IntVarValue,
+    crate::ty::ParamConst,
     crate::ty::ParamTy,
     crate::ty::UniverseIndex,
     crate::ty::Variance,
@@ -503,6 +505,14 @@ impl<'a, 'tcx> Lift<'tcx> for ConstValue<'a> {
     type Lifted = ConstValue<'tcx>;
     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
         match *self {
+            ConstValue::Param(param) => Some(ConstValue::Param(param)),
+            ConstValue::Infer(infer) => {
+                Some(ConstValue::Infer(match infer {
+                    InferConst::Var(vid) => InferConst::Var(vid.lift_to_tcx(tcx)?),
+                    InferConst::Fresh(i) => InferConst::Fresh(i),
+                    InferConst::Canonical(debrujin, var) => InferConst::Canonical(debrujin, var),
+                }))
+            }
             ConstValue::Scalar(x) => Some(ConstValue::Scalar(x)),
             ConstValue::Slice(x, y) => Some(ConstValue::Slice(x, y)),
             ConstValue::ByRef(ptr, alloc) => Some(ConstValue::ByRef(
@@ -512,6 +522,16 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
     }
 }
 
+impl<'a, 'tcx> Lift<'tcx> for ConstVid<'a> {
+    type Lifted = ConstVid<'tcx>;
+    fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
+        Some(ConstVid {
+            index: self.index,
+            phantom: PhantomData,
+        })
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // TypeFoldable implementations.
 //
index 3fd2e38a3d3e51cd10baca00a68b8bd20bbf766c..1aa4ca7ff97abd3d34f36fd058e26b36972f7bbc 100644 (file)
@@ -16,6 +16,7 @@
 use smallvec::SmallVec;
 use std::iter;
 use std::cmp::Ordering;
+use std::marker::PhantomData;
 use rustc_target::spec::abi;
 use syntax::ast::{self, Ident};
 use syntax::symbol::{keywords, InternedString};
@@ -1061,6 +1062,26 @@ pub fn is_self(&self) -> bool {
     }
 }
 
+#[derive(Copy, Clone, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
+pub struct ParamConst {
+    pub index: u32,
+    pub name: InternedString,
+}
+
+impl<'a, 'gcx, 'tcx> ParamConst {
+    pub fn new(index: u32, name: InternedString) -> ParamConst {
+        ParamConst { index, name }
+    }
+
+    pub fn for_def(def: &ty::GenericParamDef) -> ParamConst {
+        ParamConst::new(def.index, def.name)
+    }
+
+    pub fn to_const(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx LazyConst<'tcx> {
+        tcx.mk_const_param(self.index, self.name, ty)
+    }
+}
+
 /// A [De Bruijn index][dbi] is a standard means of representing
 /// regions (and perhaps later types) in a higher-ranked setting. In
 /// particular, imagine a type like this:
@@ -1229,6 +1250,12 @@ pub struct TyVid {
     pub index: u32,
 }
 
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+pub struct ConstVid<'tcx> {
+    pub index: u32,
+    pub phantom: PhantomData<&'tcx ()>,
+}
+
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
 pub struct IntVid {
     pub index: u32,
@@ -2083,6 +2110,22 @@ pub fn assert_usize(self, tcx: TyCtxt<'_, '_, '_>) -> Option<u64> {
     pub fn unwrap_usize(&self, tcx: TyCtxt<'_, '_, '_>) -> u64 {
         self.assert_usize(tcx).expect("expected `LazyConst` to contain a usize")
     }
+
+    pub fn type_flags(&self) -> TypeFlags {
+        // FIXME(const_generics): incorporate substs flags.
+        let flags = match self {
+            LazyConst::Unevaluated(..) => {
+                TypeFlags::HAS_NORMALIZABLE_PROJECTION | TypeFlags::HAS_PROJECTION
+            }
+            LazyConst::Evaluated(c) => {
+                c.type_flags()
+            }
+        };
+
+        debug!("type_flags({:?}) = {:?}", self, flags);
+
+        flags
+    }
 }
 
 /// Typed constant value.
@@ -2198,6 +2241,44 @@ pub fn unwrap_usize(&self, tcx: TyCtxt<'_, '_, '_>) -> u64 {
         self.assert_usize(tcx).unwrap_or_else(||
             bug!("expected constant usize, got {:#?}", self))
     }
+
+    pub fn type_flags(&self) -> TypeFlags {
+        let mut flags = self.ty.flags;
+
+        match self.val {
+            ConstValue::Param(_) => {
+                flags |= TypeFlags::HAS_FREE_LOCAL_NAMES;
+                flags |= TypeFlags::HAS_PARAMS;
+            }
+            ConstValue::Infer(infer) => {
+                flags |= TypeFlags::HAS_FREE_LOCAL_NAMES;
+                flags |= TypeFlags::HAS_CT_INFER;
+                match infer {
+                    InferConst::Fresh(_) |
+                    InferConst::Canonical(_, _) => {}
+                    InferConst::Var(_) => {
+                        flags |= TypeFlags::KEEP_IN_LOCAL_TCX;
+                    }
+                }
+            }
+            _ => {}
+        }
+
+        debug!("type_flags({:?}) = {:?}", self, flags);
+
+        flags
+    }
 }
 
 impl<'tcx> serialize::UseSpecializedDecodable for &'tcx LazyConst<'tcx> {}
+
+/// An inference variable for a const, for use in const generics.
+#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
+pub enum InferConst<'tcx> {
+    /// Infer the value of the const.
+    Var(ConstVid<'tcx>),
+    /// A fresh const variable. See `infer::freshen` for more details.
+    Fresh(u32),
+    /// Canonicalized const variable, used only when preparing a trait query.
+    Canonical(DebruijnIndex, BoundVar),
+}
index 450fab81661fc72336319c4298ca548ff3b220bf..35c6f980cd9342d77969dbf8f4603f2f8c86821f 100644 (file)
@@ -2,8 +2,9 @@
 
 use crate::hir::def_id::DefId;
 use crate::infer::canonical::Canonical;
-use crate::ty::{self, Lift, List, Ty, TyCtxt};
+use crate::ty::{self, Lift, List, Ty, TyCtxt, InferConst, ParamConst};
 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
+use crate::mir::interpret::ConstValue;
 
 use serialize::{self, Encodable, Encoder, Decodable, Decoder};
 use syntax_pos::{Span, DUMMY_SP};
 use std::num::NonZeroUsize;
 
 /// An entity in the Rust type system, which can be one of
-/// several kinds (only types and lifetimes for now).
+/// several kinds (types, lifetimes, and consts).
 /// To reduce memory usage, a `Kind` is a interned pointer,
 /// with the lowest 2 bits being reserved for a tag to
-/// indicate the type (`Ty` or `Region`) it points to.
+/// indicate the type (`Ty`, `Region`, or `Const`) it points to.
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Kind<'tcx> {
     ptr: NonZeroUsize,
-    marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>)>
+    marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, &'tcx ty::LazyConst<'tcx>)>
 }
 
 const TAG_MASK: usize = 0b11;
 const TYPE_TAG: usize = 0b00;
 const REGION_TAG: usize = 0b01;
+const CONST_TAG: usize = 0b10;
 
 #[derive(Debug, RustcEncodable, RustcDecodable, PartialEq, Eq, PartialOrd, Ord)]
 pub enum UnpackedKind<'tcx> {
     Lifetime(ty::Region<'tcx>),
     Type(Ty<'tcx>),
+    Const(&'tcx ty::LazyConst<'tcx>),
 }
 
 impl<'tcx> UnpackedKind<'tcx> {
@@ -50,6 +53,11 @@ fn pack(self) -> Kind<'tcx> {
                 assert_eq!(mem::align_of_val(ty) & TAG_MASK, 0);
                 (TYPE_TAG, ty as *const _ as usize)
             }
+            UnpackedKind::Const(ct) => {
+                // Ensure we can use the tag bits.
+                assert_eq!(mem::align_of_val(ct) & TAG_MASK, 0);
+                (CONST_TAG, ct as *const _ as usize)
+            }
         };
 
         Kind {
@@ -85,6 +93,12 @@ fn from(ty: Ty<'tcx>) -> Kind<'tcx> {
     }
 }
 
+impl<'tcx> From<&'tcx ty::LazyConst<'tcx>> for Kind<'tcx> {
+    fn from(c: &'tcx ty::LazyConst<'tcx>) -> Kind<'tcx> {
+        UnpackedKind::Const(c).pack()
+    }
+}
+
 impl<'tcx> Kind<'tcx> {
     #[inline]
     pub fn unpack(self) -> UnpackedKind<'tcx> {
@@ -93,6 +107,7 @@ pub fn unpack(self) -> UnpackedKind<'tcx> {
             match ptr & TAG_MASK {
                 REGION_TAG => UnpackedKind::Lifetime(&*((ptr & !TAG_MASK) as *const _)),
                 TYPE_TAG => UnpackedKind::Type(&*((ptr & !TAG_MASK) as *const _)),
+                CONST_TAG => UnpackedKind::Const(&*((ptr & !TAG_MASK) as *const _)),
                 _ => intrinsics::unreachable()
             }
         }
@@ -104,6 +119,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self.unpack() {
             UnpackedKind::Lifetime(lt) => write!(f, "{:?}", lt),
             UnpackedKind::Type(ty) => write!(f, "{:?}", ty),
+            UnpackedKind::Const(ct) => write!(f, "{:?}", ct),
         }
     }
 }
@@ -113,6 +129,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self.unpack() {
             UnpackedKind::Lifetime(lt) => write!(f, "{}", lt),
             UnpackedKind::Type(ty) => write!(f, "{}", ty),
+            UnpackedKind::Const(ct) => write!(f, "{}", ct),
         }
     }
 }
@@ -122,8 +139,9 @@ impl<'a, 'tcx> Lift<'tcx> for Kind<'a> {
 
     fn lift_to_tcx<'cx, 'gcx>(&self, tcx: TyCtxt<'cx, 'gcx, 'tcx>) -> Option<Self::Lifted> {
         match self.unpack() {
-            UnpackedKind::Lifetime(a) => a.lift_to_tcx(tcx).map(|a| a.into()),
-            UnpackedKind::Type(a) => a.lift_to_tcx(tcx).map(|a| a.into()),
+            UnpackedKind::Lifetime(lt) => lt.lift_to_tcx(tcx).map(|lt| lt.into()),
+            UnpackedKind::Type(ty) => ty.lift_to_tcx(tcx).map(|ty| ty.into()),
+            UnpackedKind::Const(ct) => ct.lift_to_tcx(tcx).map(|ct| ct.into()),
         }
     }
 }
@@ -133,6 +151,7 @@ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F)
         match self.unpack() {
             UnpackedKind::Lifetime(lt) => lt.fold_with(folder).into(),
             UnpackedKind::Type(ty) => ty.fold_with(folder).into(),
+            UnpackedKind::Const(ct) => ct.fold_with(folder).into(),
         }
     }
 
@@ -140,6 +159,7 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
         match self.unpack() {
             UnpackedKind::Lifetime(lt) => lt.visit_with(visitor),
             UnpackedKind::Type(ty) => ty.visit_with(visitor),
+            UnpackedKind::Const(ct) => ct.visit_with(visitor),
         }
     }
 }
@@ -195,6 +215,15 @@ pub fn bound_vars_for_item(
                         ty::BoundRegion::BrNamed(param.def_id, param.name)
                     )).into()
                 }
+
+                ty::GenericParamDefKind::Const => {
+                    tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const {
+                        val: ConstValue::Infer(
+                            InferConst::Canonical(ty::INNERMOST, ty::BoundVar::from(param.index))
+                        ),
+                        ty: tcx.type_of(def_id),
+                    })).into()
+                }
             }
         })
     }
@@ -283,6 +312,29 @@ pub fn regions(&'a self) -> impl DoubleEndedIterator<Item = ty::Region<'tcx>> +
         })
     }
 
+    #[inline]
+    pub fn consts(&'a self) -> impl DoubleEndedIterator<Item = &'tcx ty::LazyConst<'tcx>> + 'a {
+        self.iter().filter_map(|k| {
+            if let UnpackedKind::Const(ct) = k.unpack() {
+                Some(ct)
+            } else {
+                None
+            }
+        })
+    }
+
+    #[inline]
+    pub fn non_erasable_generics(
+        &'a self
+    ) -> impl DoubleEndedIterator<Item = UnpackedKind<'tcx>> + 'a {
+        self.iter().filter_map(|k| {
+            match k.unpack() {
+                UnpackedKind::Lifetime(_) => None,
+                generic => Some(generic),
+            }
+        })
+    }
+
     #[inline]
     pub fn type_at(&self, i: usize) -> Ty<'tcx> {
         if let UnpackedKind::Type(ty) = self[i].unpack() {
@@ -301,6 +353,15 @@ pub fn region_at(&self, i: usize) -> ty::Region<'tcx> {
         }
     }
 
+    #[inline]
+    pub fn const_at(&self, i: usize) -> &'tcx ty::LazyConst<'tcx> {
+        if let UnpackedKind::Const(ct) = self[i].unpack() {
+            ct
+        } else {
+            bug!("expected const for param #{} in {:?}", i, self);
+        }
+    }
+
     #[inline]
     pub fn type_for_def(&self, def: &ty::GenericParamDef) -> Kind<'tcx> {
         self.type_at(def.index as usize).into()
@@ -469,6 +530,21 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
 
         return t1;
     }
+
+    fn fold_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
+        if !c.needs_subst() {
+            return c;
+        }
+
+        if let ty::LazyConst::Evaluated(ty::Const {
+            val: ConstValue::Param(p),
+            ..
+        }) = c {
+            self.const_for_param(*p, c)
+        } else {
+            c.super_fold_with(self)
+        }
+    }
 }
 
 impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
@@ -494,6 +570,34 @@ fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
         self.shift_vars_through_binders(ty)
     }
 
+    fn const_for_param(
+        &self,
+        p: ParamConst,
+        source_cn: &'tcx ty::LazyConst<'tcx>
+    ) -> &'tcx ty::LazyConst<'tcx> {
+        // Look up the const in the substitutions. It really should be in there.
+        let opt_cn = self.substs.get(p.index as usize).map(|k| k.unpack());
+        let cn = match opt_cn {
+            Some(UnpackedKind::Const(cn)) => cn,
+            _ => {
+                let span = self.span.unwrap_or(DUMMY_SP);
+                span_bug!(
+                    span,
+                    "Const parameter `{:?}` ({:?}/{}) out of range \
+                     when substituting (root type={:?}) substs={:?}",
+                    p,
+                    source_cn,
+                    p.index,
+                    self.root_ty,
+                    self.substs,
+                );
+            }
+        };
+
+        // FIXME(const_generics): shift const through binders
+        cn
+    }
+
     /// It is sometimes necessary to adjust the De Bruijn indices during substitution. This occurs
     /// when we are substituting a type with escaping bound vars into a context where we have
     /// passed through binders. That's quite a mouthful. Let's see an example:
index 4ad3ffaa93da4f41685391e2cd138b519e2a9549..fb0d1e2080b06483c7921722b38ff73a824ebdbb 100644 (file)
@@ -12,6 +12,7 @@
 use crate::ty::query::TyCtxtAt;
 use crate::ty::TyKind::*;
 use crate::ty::layout::{Integer, IntegerExt};
+use crate::mir::interpret::ConstValue;
 use crate::util::common::ErrorReported;
 use crate::middle::lang_items;
 
@@ -495,8 +496,16 @@ pub fn destructor_constraints(self, def: &'tcx ty::AdtDef)
                     }) => {
                         !impl_generics.type_param(pt, self).pure_wrt_drop
                     }
-                    UnpackedKind::Lifetime(_) | UnpackedKind::Type(_) => {
-                        // not a type or region param - this should be reported
+                    UnpackedKind::Const(&ty::LazyConst::Evaluated(ty::Const {
+                        val: ConstValue::Param(ref pc),
+                        ..
+                    })) => {
+                        !impl_generics.const_param(pc, self).pure_wrt_drop
+                    }
+                    UnpackedKind::Lifetime(_) |
+                    UnpackedKind::Type(_) |
+                    UnpackedKind::Const(_) => {
+                        // Not a type, const or region param: this should be reported
                         // as an error.
                         false
                     }
@@ -587,15 +596,18 @@ pub fn closure_env_ty(self,
         Some(ty::Binder::bind(env_ty))
     }
 
-    /// Given the `DefId` of some item that has no type parameters, make
+    /// Given the `DefId` of some item that has no type or const parameters, make
     /// a suitable "empty substs" for it.
     pub fn empty_substs_for_def_id(self, item_def_id: DefId) -> SubstsRef<'tcx> {
         InternalSubsts::for_item(self, item_def_id, |param, _| {
             match param.kind {
                 GenericParamDefKind::Lifetime => self.types.re_erased.into(),
-                GenericParamDefKind::Type {..} => {
+                GenericParamDefKind::Type { .. } => {
                     bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id)
                 }
+                GenericParamDefKind::Const { .. } => {
+                    bug!("empty_substs_for_def_id: {:?} has const parameters", item_def_id)
+                }
             }
         })
     }
index aecef3c5ec71e4d5439efd1718065508b0e1c1d2..cdc0c3371ebcd9218e178c8cd3915b1a66c4c296 100644 (file)
@@ -8,7 +8,8 @@
 use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple};
 use crate::ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque};
 use crate::ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer};
-use crate::ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind};
+use crate::ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind, ParamConst};
+use crate::mir::interpret::ConstValue;
 use crate::util::nodemap::FxHashSet;
 
 use std::cell::Cell;
@@ -478,6 +479,7 @@ fn parameterized<F: fmt::Write>(&mut self,
                         GenericParamDefKind::Type { has_default, .. } => {
                             Some((param.def_id, has_default))
                         }
+                        GenericParamDefKind::Const => None, // FIXME(const_generics:defaults)
                     }).peekable();
                 let has_default = {
                     let has_default = type_params.peek().map(|(_, has_default)| has_default);
@@ -571,6 +573,14 @@ fn parameterized<F: fmt::Write>(&mut self,
             )?;
         }
 
+        // FIXME(const_generics::defaults)
+        let consts = substs.consts();
+
+        for ct in consts {
+            start_or_continue(f, "<", ", ")?;
+            ct.print_display(f, self)?;
+        }
+
         start_or_continue(f, "", ">")?;
 
         // For values, also print their name and type parameters.
@@ -763,7 +773,8 @@ impl fmt::Debug for ty::GenericParamDef {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let type_name = match self.kind {
             ty::GenericParamDefKind::Lifetime => "Lifetime",
-            ty::GenericParamDefKind::Type {..} => "Type",
+            ty::GenericParamDefKind::Type { .. } => "Type",
+            ty::GenericParamDefKind::Const => "Const",
         };
         write!(f, "{}({}, {:?}, {})",
                type_name,
@@ -1088,6 +1099,12 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
+impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "_#{}f", self.index)
+    }
+}
+
 impl fmt::Debug for ty::IntVid {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "_#{}i", self.index)
@@ -1448,7 +1465,12 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                             write!(f, "_")?;
                         }
                         ty::LazyConst::Evaluated(c) => ty::tls::with(|tcx| {
-                            write!(f, "{}", c.unwrap_usize(tcx))
+                            match c.val {
+                                ConstValue::Infer(..) => write!(f, "_"),
+                                ConstValue::Param(ParamConst { name, .. }) =>
+                                    write!(f, "{}", name),
+                                _ => write!(f, "{}", c.unwrap_usize(tcx)),
+                            }
                         })?,
                     }
                     write!(f, "]")
@@ -1472,6 +1494,37 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
+define_print! {
+    ('tcx) ConstValue<'tcx>, (self, f, cx) {
+        display {
+            match self {
+                ConstValue::Infer(..) => write!(f, "_"),
+                ConstValue::Param(ParamConst { name, .. }) => write!(f, "{}", name),
+                _ => write!(f, "{:?}", self),
+            }
+        }
+    }
+}
+
+define_print! {
+    ('tcx) ty::Const<'tcx>, (self, f, cx) {
+        display {
+            write!(f, "{} : {}", self.val, self.ty)
+        }
+    }
+}
+
+define_print! {
+    ('tcx) ty::LazyConst<'tcx>, (self, f, cx) {
+        display {
+            match self {
+                ty::LazyConst::Unevaluated(..) => write!(f, "_ : _"),
+                ty::LazyConst::Evaluated(c) => write!(f, "{}", c),
+            }
+        }
+    }
+}
+
 define_print! {
     () ty::ParamTy, (self, f, cx) {
         display {
@@ -1483,6 +1536,17 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
+define_print! {
+    () ty::ParamConst, (self, f, cx) {
+        display {
+            write!(f, "{}", self.name)
+        }
+        debug {
+            write!(f, "{}/#{}", self.name, self.index)
+        }
+    }
+}
+
 define_print! {
     ('tcx, T: Print + fmt::Debug, U: Print + fmt::Debug) ty::OutlivesPredicate<T, U>,
     (self, f, cx) {
index c90bd12a3100f27ed3dffc933297c24cc35d39ba..c134d48f987be5ded1c711a6b0f8786545d30c8a 100644 (file)
@@ -1,10 +1,13 @@
-use std::collections::{BTreeMap, HashMap};
 use std::fs;
-use std::io::{self, Write};
+use std::io::{BufWriter, Write};
+use std::mem;
+use std::process;
 use std::thread::ThreadId;
-use std::time::Instant;
+use std::time::{Duration, Instant, SystemTime};
 
-use crate::session::config::{Options, OptLevel};
+use crate::session::config::Options;
+
+use rustc_data_structures::fx::FxHashMap;
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd)]
 pub enum ProfileCategory {
@@ -19,154 +22,55 @@ pub enum ProfileCategory {
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 pub enum ProfilerEvent {
-    QueryStart { query_name: &'static str, category: ProfileCategory, time: Instant },
-    QueryEnd { query_name: &'static str, category: ProfileCategory, time: Instant },
-    GenericActivityStart { category: ProfileCategory, time: Instant },
-    GenericActivityEnd { category: ProfileCategory, time: Instant },
-    QueryCacheHit { query_name: &'static str, category: ProfileCategory },
-    QueryCount { query_name: &'static str, category: ProfileCategory, count: usize },
-    IncrementalLoadResultStart { query_name: &'static str, time: Instant },
-    IncrementalLoadResultEnd { query_name: &'static str, time: Instant },
-    QueryBlockedStart { query_name: &'static str, category: ProfileCategory, time: Instant },
-    QueryBlockedEnd { query_name: &'static str, category: ProfileCategory, time: Instant },
+    QueryStart { query_name: &'static str, category: ProfileCategory, time: u64 },
+    QueryEnd { query_name: &'static str, category: ProfileCategory, time: u64 },
+    GenericActivityStart { category: ProfileCategory, time: u64 },
+    GenericActivityEnd { category: ProfileCategory, time: u64 },
+    IncrementalLoadResultStart { query_name: &'static str, time: u64 },
+    IncrementalLoadResultEnd { query_name: &'static str, time: u64 },
+    QueryCacheHit { query_name: &'static str, category: ProfileCategory, time: u64 },
+    QueryCount { query_name: &'static str, category: ProfileCategory, count: usize, time: u64 },
+    QueryBlockedStart { query_name: &'static str, category: ProfileCategory, time: u64 },
+    QueryBlockedEnd { query_name: &'static str, category: ProfileCategory, time: u64 },
 }
 
 impl ProfilerEvent {
-    fn is_start_event(&self) -> bool {
+    fn timestamp(&self) -> u64 {
         use self::ProfilerEvent::*;
 
         match self {
-            QueryStart { .. } |
-            GenericActivityStart { .. } |
-            IncrementalLoadResultStart { .. } |
-            QueryBlockedStart { .. } => true,
-
-            QueryEnd { .. } |
-            GenericActivityEnd { .. } |
-            QueryCacheHit { .. } |
-            QueryCount { .. } |
-            IncrementalLoadResultEnd { .. } |
-            QueryBlockedEnd { .. } => false,
-        }
-    }
-}
-
-pub struct SelfProfiler {
-    events: HashMap<ThreadId, Vec<ProfilerEvent>>,
-}
-
-struct CategoryResultData {
-    query_times: BTreeMap<&'static str, u64>,
-    query_cache_stats: BTreeMap<&'static str, (u64, u64)>, //(hits, total)
-}
-
-impl CategoryResultData {
-    fn new() -> CategoryResultData {
-        CategoryResultData {
-            query_times: BTreeMap::new(),
-            query_cache_stats: BTreeMap::new(),
-        }
-    }
-
-    fn total_time(&self) -> u64 {
-        self.query_times.iter().map(|(_, time)| time).sum()
-    }
-
-    fn total_cache_data(&self) -> (u64, u64) {
-        let (mut hits, mut total) = (0, 0);
-
-        for (_, (h, t)) in &self.query_cache_stats {
-            hits += h;
-            total += t;
+            QueryStart { time, .. } |
+            QueryEnd { time, .. } |
+            GenericActivityStart { time, .. } |
+            GenericActivityEnd { time, .. } |
+            QueryCacheHit { time, .. } |
+            QueryCount { time, .. } |
+            IncrementalLoadResultStart { time, .. } |
+            IncrementalLoadResultEnd { time, .. } |
+            QueryBlockedStart { time, .. } |
+            QueryBlockedEnd { time, .. } => *time
         }
-
-        (hits, total)
     }
 }
 
-impl Default for CategoryResultData {
-    fn default() -> CategoryResultData {
-        CategoryResultData::new()
-    }
-}
-
-struct CalculatedResults {
-    categories: BTreeMap<ProfileCategory, CategoryResultData>,
-    crate_name: Option<String>,
-    optimization_level: OptLevel,
-    incremental: bool,
-    verbose: bool,
+fn thread_id_to_u64(tid: ThreadId) -> u64 {
+    unsafe { mem::transmute::<ThreadId, u64>(tid) }
 }
 
-impl CalculatedResults {
-    fn new() -> CalculatedResults {
-        CalculatedResults {
-            categories: BTreeMap::new(),
-            crate_name: None,
-            optimization_level: OptLevel::No,
-            incremental: false,
-            verbose: false,
-        }
-    }
-
-    fn consolidate(mut cr1: CalculatedResults, cr2: CalculatedResults) -> CalculatedResults {
-        for (category, data) in cr2.categories {
-            let cr1_data = cr1.categories.entry(category).or_default();
-
-            for (query, time) in data.query_times {
-                *cr1_data.query_times.entry(query).or_default() += time;
-            }
-
-            for (query, (hits, total)) in data.query_cache_stats {
-                let (h, t) = cr1_data.query_cache_stats.entry(query).or_insert((0, 0));
-                *h += hits;
-                *t += total;
-            }
-        }
-
-        cr1
-    }
-
-    fn total_time(&self) -> u64 {
-        self.categories.iter().map(|(_, data)| data.total_time()).sum()
-    }
-
-    fn with_options(mut self, opts: &Options) -> CalculatedResults {
-        self.crate_name = opts.crate_name.clone();
-        self.optimization_level = opts.optimize;
-        self.incremental = opts.incremental.is_some();
-        self.verbose = opts.debugging_opts.verbose;
-
-        self
-    }
-}
-
-fn time_between_ns(start: Instant, end: Instant) -> u64 {
-    if start < end {
-        let time = end - start;
-        (time.as_secs() * 1_000_000_000) + (time.subsec_nanos() as u64)
-    } else {
-        debug!("time_between_ns: ignorning instance of end < start");
-        0
-    }
-}
-
-fn calculate_percent(numerator: u64, denominator: u64) -> f32 {
-    if denominator > 0 {
-        ((numerator as f32) / (denominator as f32)) * 100.0
-    } else {
-        0.0
-    }
+pub struct SelfProfiler {
+    events: FxHashMap<ThreadId, Vec<ProfilerEvent>>,
+    start_time: SystemTime,
+    start_instant: Instant,
 }
 
 impl SelfProfiler {
     pub fn new() -> SelfProfiler {
-        let mut profiler = SelfProfiler {
-            events: HashMap::new(),
+        let profiler = SelfProfiler {
+            events: Default::default(),
+            start_time: SystemTime::now(),
+            start_instant: Instant::now(),
         };
 
-        profiler.start_activity(ProfileCategory::Other);
-
         profiler
     }
 
@@ -174,7 +78,7 @@ pub fn new() -> SelfProfiler {
     pub fn start_activity(&mut self, category: ProfileCategory) {
         self.record(ProfilerEvent::GenericActivityStart {
             category,
-            time: Instant::now(),
+            time: self.get_time_from_start(),
         })
     }
 
@@ -182,7 +86,7 @@ pub fn start_activity(&mut self, category: ProfileCategory) {
     pub fn end_activity(&mut self, category: ProfileCategory) {
         self.record(ProfilerEvent::GenericActivityEnd {
             category,
-            time: Instant::now(),
+            time: self.get_time_from_start(),
         })
     }
 
@@ -197,6 +101,7 @@ pub fn record_computed_queries(
             query_name,
             category,
             count,
+            time: self.get_time_from_start(),
         })
     }
 
@@ -205,6 +110,7 @@ pub fn record_query_hit(&mut self, query_name: &'static str, category: ProfileCa
         self.record(ProfilerEvent::QueryCacheHit {
             query_name,
             category,
+            time: self.get_time_from_start(),
         })
     }
 
@@ -213,7 +119,7 @@ pub fn start_query(&mut self, query_name: &'static str, category: ProfileCategor
         self.record(ProfilerEvent::QueryStart {
             query_name,
             category,
-            time: Instant::now(),
+            time: self.get_time_from_start(),
         });
     }
 
@@ -222,7 +128,7 @@ pub fn end_query(&mut self, query_name: &'static str, category: ProfileCategory)
         self.record(ProfilerEvent::QueryEnd {
             query_name,
             category,
-            time: Instant::now(),
+            time: self.get_time_from_start(),
         })
     }
 
@@ -230,7 +136,7 @@ pub fn end_query(&mut self, query_name: &'static str, category: ProfileCategory)
     pub fn incremental_load_result_start(&mut self, query_name: &'static str) {
         self.record(ProfilerEvent::IncrementalLoadResultStart {
             query_name,
-            time: Instant::now(),
+            time: self.get_time_from_start(),
         })
     }
 
@@ -238,7 +144,7 @@ pub fn incremental_load_result_start(&mut self, query_name: &'static str) {
     pub fn incremental_load_result_end(&mut self, query_name: &'static str) {
         self.record(ProfilerEvent::IncrementalLoadResultEnd {
             query_name,
-            time: Instant::now(),
+            time: self.get_time_from_start(),
         })
     }
 
@@ -247,7 +153,7 @@ pub fn query_blocked_start(&mut self, query_name: &'static str, category: Profil
         self.record(ProfilerEvent::QueryBlockedStart {
             query_name,
             category,
-            time: Instant::now(),
+            time: self.get_time_from_start(),
         })
     }
 
@@ -256,7 +162,7 @@ pub fn query_blocked_end(&mut self, query_name: &'static str, category: ProfileC
         self.record(ProfilerEvent::QueryBlockedEnd {
             query_name,
             category,
-            time: Instant::now(),
+            time: self.get_time_from_start(),
         })
     }
 
@@ -268,208 +174,255 @@ fn record(&mut self, event: ProfilerEvent) {
         events.push(event);
     }
 
-    fn calculate_thread_results(events: &Vec<ProfilerEvent>) -> CalculatedResults {
-        use self::ProfilerEvent::*;
-
-        assert!(
-            events.last().map(|e| !e.is_start_event()).unwrap_or(true),
-            "there was an event running when calculate_reslts() was called"
-        );
-
-        let mut results = CalculatedResults::new();
-
-        //(event, child time to subtract)
-        let mut query_stack = Vec::new();
-
-        for event in events {
-            match event {
-                QueryStart { .. } | GenericActivityStart { .. } => {
-                    query_stack.push((event, 0));
-                },
-                QueryEnd { query_name, category, time: end_time } => {
-                    let previous_query = query_stack.pop();
-                    if let Some((QueryStart {
-                                    query_name: p_query_name,
-                                    time: start_time,
-                                    category: _ }, child_time_to_subtract)) = previous_query {
-                        assert_eq!(
-                            p_query_name,
-                            query_name,
-                            "Saw a query end but the previous query wasn't the corresponding start"
-                        );
-
-                        let time_ns = time_between_ns(*start_time, *end_time);
-                        let self_time_ns = time_ns - child_time_to_subtract;
-                        let result_data = results.categories.entry(*category).or_default();
+    #[inline]
+    fn get_time_from_start(&self) -> u64 {
+        let duration = Instant::now() - self.start_instant;
+        duration.as_nanos() as u64
+    }
 
-                        *result_data.query_times.entry(query_name).or_default() += self_time_ns;
+    pub fn dump_raw_events(&self, opts: &Options) {
+        use self::ProfilerEvent::*;
 
-                        if let Some((_, child_time_to_subtract)) = query_stack.last_mut() {
-                            *child_time_to_subtract += time_ns;
-                        }
-                    } else {
-                        bug!("Saw a query end but the previous event wasn't a query start");
-                    }
+        let pid = process::id();
+
+        let filename =
+            format!("{}.profile_events.json", opts.crate_name.clone().unwrap_or_default());
+
+        let mut file = BufWriter::new(fs::File::create(filename).unwrap());
+
+        let threads: Vec<_> =
+            self.events
+                .keys()
+                .into_iter()
+                .map(|tid| format!("{}", thread_id_to_u64(*tid)))
+                .collect();
+
+        write!(file,
+            "{{\
+                \"processes\": {{\
+                    \"{}\": {{\
+                        \"threads\": [{}],\
+                        \"crate_name\": \"{}\",\
+                        \"opt_level\": \"{:?}\",\
+                        \"incremental\": {}\
+                    }}\
+                }},\
+                \"events\": [\
+             ",
+            pid,
+            threads.join(","),
+            opts.crate_name.clone().unwrap_or_default(),
+            opts.optimize,
+            if opts.incremental.is_some() { "true" } else { "false" },
+        ).unwrap();
+
+        let mut is_first = true;
+        for (thread_id, events) in &self.events {
+            let thread_id = thread_id_to_u64(*thread_id);
+
+            for event in events {
+                if is_first {
+                    is_first = false;
+                } else {
+                    writeln!(file, ",").unwrap();
                 }
-                GenericActivityEnd { category, time: end_time } => {
-                    let previous_event = query_stack.pop();
-                    if let Some((GenericActivityStart {
-                                    category: previous_category,
-                                    time: start_time }, child_time_to_subtract)) = previous_event {
-                        assert_eq!(
-                            previous_category,
-                            category,
-                            "Saw an end but the previous event wasn't the corresponding start"
-                        );
-
-                        let time_ns = time_between_ns(*start_time, *end_time);
-                        let self_time_ns = time_ns - child_time_to_subtract;
-                        let result_data = results.categories.entry(*category).or_default();
-
-                        *result_data.query_times
-                            .entry("{time spent not running queries}")
-                            .or_default() += self_time_ns;
-
-                        if let Some((_, child_time_to_subtract)) = query_stack.last_mut() {
-                            *child_time_to_subtract += time_ns;
-                        }
-                    } else {
-                        bug!("Saw an activity end but the previous event wasn't an activity start");
-                    }
-                },
-                QueryCacheHit { category, query_name } => {
-                    let result_data = results.categories.entry(*category).or_default();
-
-                    let (hits, total) =
-                        result_data.query_cache_stats.entry(query_name).or_insert((0, 0));
-                    *hits += 1;
-                    *total += 1;
-                },
-                QueryCount { category, query_name, count } => {
-                    let result_data = results.categories.entry(*category).or_default();
-
-                    let (_, totals) =
-                        result_data.query_cache_stats.entry(query_name).or_insert((0, 0));
-                    *totals += *count as u64;
-                },
-                //we don't summarize incremental load result events in the simple output mode
-                IncrementalLoadResultStart { .. } | IncrementalLoadResultEnd { .. } => { },
-                //we don't summarize parallel query blocking in the simple output mode
-                QueryBlockedStart { .. } | QueryBlockedEnd { .. } => { },
-            }
-        }
 
-        //normalize the times to ms
-        for (_, data) in &mut results.categories {
-            for (_, time) in &mut data.query_times {
-                *time = *time / 1_000_000;
-            }
-        }
-
-        results
-    }
-
-    fn get_results(&self, opts: &Options) -> CalculatedResults {
-        self.events
-            .iter()
-            .map(|(_, r)| SelfProfiler::calculate_thread_results(r))
-            .fold(CalculatedResults::new(), CalculatedResults::consolidate)
-            .with_options(opts)
-    }
-
-    pub fn print_results(&mut self, opts: &Options) {
-        self.end_activity(ProfileCategory::Other);
-
-        let results = self.get_results(opts);
-
-        let total_time = results.total_time() as f32;
-
-        let out = io::stderr();
-        let mut lock = out.lock();
-
-        let crate_name = results.crate_name.map(|n| format!(" for {}", n)).unwrap_or_default();
-
-        writeln!(lock, "Self profiling results{}:", crate_name).unwrap();
-        writeln!(lock).unwrap();
-
-        writeln!(lock, "| Phase                                     | Time (ms)      \
-                        | Time (%) | Queries        | Hits (%)")
-            .unwrap();
-        writeln!(lock, "| ----------------------------------------- | -------------- \
-                        | -------- | -------------- | --------")
-            .unwrap();
-
-        let mut categories: Vec<_> = results.categories.iter().collect();
-        categories.sort_by_cached_key(|(_, d)| d.total_time());
-
-        for (category, data) in categories.iter().rev() {
-            let (category_hits, category_total) = data.total_cache_data();
-            let category_hit_percent = calculate_percent(category_hits, category_total);
-
-            writeln!(
-                lock,
-                "| {0: <41} | {1: >14} | {2: >8.2} | {3: >14} | {4: >8}",
-                format!("{:?}", category),
-                data.total_time(),
-                ((data.total_time() as f32) / total_time) * 100.0,
-                category_total,
-                format!("{:.2}", category_hit_percent),
-            ).unwrap();
-
-            //in verbose mode, show individual query data
-            if results.verbose {
-                //don't show queries that took less than 1ms
-                let mut times: Vec<_> = data.query_times.iter().filter(|(_, t)| **t > 0).collect();
-                times.sort_by(|(_, time1), (_, time2)| time2.cmp(time1));
-
-                for (query, time) in times {
-                    let (hits, total) = data.query_cache_stats.get(query).unwrap_or(&(0, 0));
-                    let hit_percent = calculate_percent(*hits, *total);
-
-                    writeln!(
-                        lock,
-                        "| - {0: <39} | {1: >14} | {2: >8.2} | {3: >14} | {4: >8}",
-                        query,
-                        time,
-                        ((*time as f32) / total_time) * 100.0,
-                        total,
-                        format!("{:.2}", hit_percent),
-                    ).unwrap();
+                let (secs, nanos) = {
+                    let time = self.start_time + Duration::from_nanos(event.timestamp());
+                    let time_since_unix =
+                        time.duration_since(SystemTime::UNIX_EPOCH).unwrap_or_default();
+                    (time_since_unix.as_secs(), time_since_unix.subsec_nanos())
+                };
+
+                match event {
+                    QueryStart { query_name, category, time: _ } =>
+                        write!(file,
+                            "{{ \
+                                \"QueryStart\": {{ \
+                                    \"query_name\": \"{}\",\
+                                    \"category\": \"{:?}\",\
+                                    \"time\": {{\
+                                        \"secs\": {},\
+                                        \"nanos\": {}\
+                                    }},\
+                                    \"thread_id\": {}\
+                                }}\
+                            }}",
+                            query_name,
+                            category,
+                            secs,
+                            nanos,
+                            thread_id,
+                        ).unwrap(),
+                    QueryEnd { query_name, category, time: _ } =>
+                        write!(file,
+                            "{{\
+                                \"QueryEnd\": {{\
+                                    \"query_name\": \"{}\",\
+                                    \"category\": \"{:?}\",\
+                                    \"time\": {{\
+                                        \"secs\": {},\
+                                        \"nanos\": {}\
+                                    }},\
+                                    \"thread_id\": {}\
+                                }}\
+                            }}",
+                            query_name,
+                            category,
+                            secs,
+                            nanos,
+                            thread_id,
+                        ).unwrap(),
+                    GenericActivityStart { category, time: _ } =>
+                        write!(file,
+                            "{{
+                                \"GenericActivityStart\": {{\
+                                    \"category\": \"{:?}\",\
+                                    \"time\": {{\
+                                        \"secs\": {},\
+                                        \"nanos\": {}\
+                                    }},\
+                                    \"thread_id\": {}\
+                                }}\
+                            }}",
+                            category,
+                            secs,
+                            nanos,
+                            thread_id,
+                        ).unwrap(),
+                    GenericActivityEnd { category, time: _ } =>
+                        write!(file,
+                            "{{\
+                                \"GenericActivityEnd\": {{\
+                                    \"category\": \"{:?}\",\
+                                    \"time\": {{\
+                                        \"secs\": {},\
+                                        \"nanos\": {}\
+                                    }},\
+                                    \"thread_id\": {}\
+                                }}\
+                            }}",
+                            category,
+                            secs,
+                            nanos,
+                            thread_id,
+                        ).unwrap(),
+                    QueryCacheHit { query_name, category, time: _ } =>
+                        write!(file,
+                            "{{\
+                                \"QueryCacheHit\": {{\
+                                    \"query_name\": \"{}\",\
+                                    \"category\": \"{:?}\",\
+                                    \"time\": {{\
+                                        \"secs\": {},\
+                                        \"nanos\": {}\
+                                    }},\
+                                    \"thread_id\": {}\
+                                }}\
+                            }}",
+                            query_name,
+                            category,
+                            secs,
+                            nanos,
+                            thread_id,
+                        ).unwrap(),
+                    QueryCount { query_name, category, count, time: _ } =>
+                        write!(file,
+                            "{{\
+                                \"QueryCount\": {{\
+                                    \"query_name\": \"{}\",\
+                                    \"category\": \"{:?}\",\
+                                    \"count\": {},\
+                                    \"time\": {{\
+                                        \"secs\": {},\
+                                        \"nanos\": {}\
+                                    }},\
+                                    \"thread_id\": {}\
+                                }}\
+                            }}",
+                            query_name,
+                            category,
+                            count,
+                            secs,
+                            nanos,
+                            thread_id,
+                        ).unwrap(),
+                    IncrementalLoadResultStart { query_name, time: _ } =>
+                        write!(file,
+                            "{{\
+                                \"IncrementalLoadResultStart\": {{\
+                                    \"query_name\": \"{}\",\
+                                    \"time\": {{\
+                                        \"secs\": {},\
+                                        \"nanos\": {}\
+                                    }},\
+                                    \"thread_id\": {}\
+                                }}\
+                            }}",
+                            query_name,
+                            secs,
+                            nanos,
+                            thread_id,
+                        ).unwrap(),
+                    IncrementalLoadResultEnd { query_name, time: _ } =>
+                        write!(file,
+                            "{{\
+                                \"IncrementalLoadResultEnd\": {{\
+                                    \"query_name\": \"{}\",\
+                                    \"time\": {{\
+                                        \"secs\": {},\
+                                        \"nanos\": {}\
+                                    }},\
+                                    \"thread_id\": {}\
+                                }}\
+                            }}",
+                            query_name,
+                            secs,
+                            nanos,
+                            thread_id,
+                        ).unwrap(),
+                    QueryBlockedStart { query_name, category, time: _ } =>
+                        write!(file,
+                            "{{\
+                                \"QueryBlockedStart\": {{\
+                                    \"query_name\": \"{}\",\
+                                    \"category\": \"{:?}\",\
+                                    \"time\": {{\
+                                        \"secs\": {},\
+                                        \"nanos\": {}\
+                                    }},\
+                                    \"thread_id\": {}\
+                                }}\
+                            }}",
+                            query_name,
+                            category,
+                            secs,
+                            nanos,
+                            thread_id,
+                        ).unwrap(),
+                    QueryBlockedEnd { query_name, category, time: _ } =>
+                        write!(file,
+                            "{{\
+                                \"QueryBlockedEnd\": {{\
+                                    \"query_name\": \"{}\",\
+                                    \"category\": \"{:?}\",\
+                                    \"time\": {{\
+                                        \"secs\": {},\
+                                        \"nanos\": {}\
+                                    }},\
+                                    \"thread_id\": {}\
+                                }}\
+                            }}",
+                            query_name,
+                            category,
+                            secs,
+                            nanos,
+                            thread_id,
+                        ).unwrap()
                 }
             }
         }
 
-        writeln!(lock).unwrap();
-        writeln!(lock, "Optimization level: {:?}", opts.optimize).unwrap();
-        writeln!(lock, "Incremental: {}", if results.incremental { "on" } else { "off" }).unwrap();
-    }
-
-    pub fn save_results(&self, opts: &Options) {
-        let results = self.get_results(opts);
-
-        let compilation_options =
-            format!("{{ \"optimization_level\": \"{:?}\", \"incremental\": {} }}",
-                    results.optimization_level,
-                    if results.incremental { "true" } else { "false" });
-
-        let mut category_data = String::new();
-
-        for (category, data) in &results.categories {
-            let (hits, total) = data.total_cache_data();
-            let hit_percent = calculate_percent(hits, total);
-
-            category_data.push_str(&format!("{{ \"category\": \"{:?}\", \"time_ms\": {}, \
-                                                \"query_count\": {}, \"query_hits\": {} }}",
-                                            category,
-                                            data.total_time(),
-                                            total,
-                                            format!("{:.2}", hit_percent)));
-        }
-
-        let json = format!("{{ \"category_data\": {}, \"compilation_options\": {} }}",
-                        category_data,
-                        compilation_options);
-
-        fs::write("self_profiler_results.json", json).unwrap();
+        write!(file, "] }}").unwrap();
     }
 }
index c74d7f00cf5169626e5f634b1ed84878aa97988b..bd854e3aa3c812597e77a46ec51a4d2c4704e812 100644 (file)
@@ -17,7 +17,6 @@
 use rustc::middle::mem_categorization::Categorization;
 use rustc::middle::region;
 use rustc::ty::{self, TyCtxt, RegionKind};
-use syntax::ast;
 use syntax_pos::Span;
 use rustc::hir;
 use rustc::hir::Node;
@@ -177,7 +176,7 @@ fn mutate(&mut self,
         self.check_assignment(assignment_id.local_id, assignment_span, assignee_cmt);
     }
 
-    fn decl_without_init(&mut self, _id: ast::NodeId, _span: Span) { }
+    fn decl_without_init(&mut self, _id: hir::HirId, _span: Span) { }
 }
 
 pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
@@ -887,11 +886,10 @@ fn check_assignment(&self,
         // Check for reassignments to (immutable) local variables. This
         // needs to be done here instead of in check_loans because we
         // depend on move data.
-        if let Categorization::Local(local_id) = assignee_cmt.cat {
+        if let Categorization::Local(hir_id) = assignee_cmt.cat {
             let lp = opt_loan_path(assignee_cmt).unwrap();
             self.move_data.each_assignment_of(assignment_id, &lp, |assign| {
                 if assignee_cmt.mutbl.is_mutable() {
-                    let hir_id = self.bccx.tcx.hir().node_to_hir_id(local_id);
                     self.bccx.used_mut_nodes.borrow_mut().insert(hir_id);
                 } else {
                     self.bccx.report_reassigned_immutable_variable(
index 6b050fd9ba2303236c566c9e21f6bff5ab376ea0..310a9a2ef8dad57320cae6f8fb42ed47640d2068 100644 (file)
@@ -11,7 +11,6 @@
 use rustc::ty::{self, Ty};
 
 use std::rc::Rc;
-use syntax::ast;
 use syntax_pos::Span;
 use rustc::hir::*;
 use rustc::hir::Node;
@@ -48,9 +47,9 @@ pub enum PatternSource<'tcx> {
 /// with a reference to the let
 fn get_pattern_source<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &Pat) -> PatternSource<'tcx> {
 
-    let parent = tcx.hir().get_parent_node(pat.id);
+    let parent = tcx.hir().get_parent_node_by_hir_id(pat.hir_id);
 
-    match tcx.hir().get(parent) {
+    match tcx.hir().get_by_hir_id(parent) {
         Node::Expr(ref e) => {
             // the enclosing expression must be a `match` or something else
             assert!(match e.node {
@@ -67,11 +66,10 @@ fn get_pattern_source<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &Pat) -> Patte
 
 pub fn gather_decl<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                              move_data: &MoveData<'tcx>,
-                             var_id: ast::NodeId,
+                             var_id: hir::HirId,
                              var_ty: Ty<'tcx>) {
     let loan_path = Rc::new(LoanPath::new(LpVar(var_id), var_ty));
-    let hir_id = bccx.tcx.hir().node_to_hir_id(var_id);
-    move_data.add_move(bccx.tcx, loan_path, hir_id.local_id, Declared);
+    move_data.add_move(bccx.tcx, loan_path, var_id.local_id, Declared);
 }
 
 pub fn gather_move_from_expr<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
index ae1d49afd4931d6cbf8f27a50e3049a48bfae59c..0e08b62668ac8f7d72c99b71c144e97e21027286 100644 (file)
@@ -104,8 +104,7 @@ fn scope(&self, cmt: &mc::cmt_<'tcx>) -> ty::Region<'tcx> {
             Categorization::Upvar(..) => {
                 self.bccx.tcx.mk_region(ty::ReScope(self.item_scope))
             }
-            Categorization::Local(local_id) => {
-                let hir_id = self.bccx.tcx.hir().node_to_hir_id(local_id);
+            Categorization::Local(hir_id) => {
                 self.bccx.tcx.mk_region(ty::ReScope(
                     self.bccx.region_scope_tree.var_scope(hir_id.local_id)))
             }
index 03af27997d3cbee7bdf7b4accd3f561ee603d89f..bf730ba41f42845b3100edd21fe05111df730bfe 100644 (file)
@@ -147,10 +147,10 @@ fn mutate(&mut self,
                                         assignee_cmt);
     }
 
-    fn decl_without_init(&mut self, id: ast::NodeId, _span: Span) {
+    fn decl_without_init(&mut self, id: hir::HirId, _span: Span) {
         let ty = self.bccx
                      .tables
-                     .node_type(self.bccx.tcx.hir().node_to_hir_id(id));
+                     .node_type(id);
         gather_moves::gather_decl(self.bccx, &self.move_data, id, ty);
     }
 }
@@ -438,9 +438,8 @@ pub fn mark_loan_path_as_mutated(&self, loan_path: &LoanPath<'_>) {
 
         while let Some(current_path) = wrapped_path {
             wrapped_path = match current_path.kind {
-                LpVar(local_id) => {
+                LpVar(hir_id) => {
                     if !through_borrow {
-                        let hir_id = self.bccx.tcx.hir().node_to_hir_id(local_id);
                         self.bccx.used_mut_nodes.borrow_mut().insert(hir_id);
                     }
                     None
index 31189a71bba82cf87e2bd1c2e02e7385c4bca74c..6d0efb163b8f7f9314614280a90627a9cb0321d9 100644 (file)
@@ -335,7 +335,7 @@ fn hash<H: Hasher>(&self, state: &mut H) {
 
 #[derive(PartialEq, Eq, Hash, Debug)]
 pub enum LoanPathKind<'tcx> {
-    LpVar(ast::NodeId),                         // `x` in README.md
+    LpVar(hir::HirId),                          // `x` in README.md
     LpUpvar(ty::UpvarId),                       // `x` captured by-value into closure
     LpDowncast(Rc<LoanPath<'tcx>>, DefId), // `x` downcast to particular enum variant
     LpExtend(Rc<LoanPath<'tcx>>, mc::MutabilityCategory, LoanPathElem<'tcx>)
@@ -417,8 +417,7 @@ fn closure_to_block(closure_id: LocalDefId,
 impl<'a, 'tcx> LoanPath<'tcx> {
     pub fn kill_scope(&self, bccx: &BorrowckCtxt<'a, 'tcx>) -> region::Scope {
         match self.kind {
-            LpVar(local_id) => {
-                let hir_id = bccx.tcx.hir().node_to_hir_id(local_id);
+            LpVar(hir_id) => {
                 bccx.region_scope_tree.var_scope(hir_id.local_id)
             }
             LpUpvar(upvar_id) => {
@@ -919,7 +918,7 @@ fn report_bckerr(&self, err: &BckError<'a, 'tcx>) {
                 self.note_immutability_blame(
                     &mut db,
                     err.cmt.immutability_blame(),
-                    self.tcx.hir().hir_to_node_id(err.cmt.hir_id)
+                    err.cmt.hir_id
                 );
                 db.emit();
                 self.signal_error();
@@ -1135,7 +1134,7 @@ pub fn report_aliasability_violation(&self,
         self.note_immutability_blame(
             &mut err,
             blame,
-            self.tcx.hir().hir_to_node_id(cmt.hir_id)
+            cmt.hir_id
         );
 
         if is_closure {
@@ -1175,8 +1174,8 @@ fn suggest_mut_for_immutable(&self, pty: &hir::Ty, is_implicit_self: bool) -> Op
         }
     }
 
-    fn local_binding_mode(&self, node_id: ast::NodeId) -> ty::BindingMode {
-        let pat = match self.tcx.hir().get(node_id) {
+    fn local_binding_mode(&self, hir_id: hir::HirId) -> ty::BindingMode {
+        let pat = match self.tcx.hir().get_by_hir_id(hir_id) {
             Node::Binding(pat) => pat,
             node => bug!("bad node for local: {:?}", node)
         };
@@ -1192,16 +1191,16 @@ fn local_binding_mode(&self, node_id: ast::NodeId) -> ty::BindingMode {
         }
     }
 
-    fn local_ty(&self, node_id: ast::NodeId) -> (Option<&hir::Ty>, bool) {
-        let parent = self.tcx.hir().get_parent_node(node_id);
-        let parent_node = self.tcx.hir().get(parent);
+    fn local_ty(&self, hir_id: hir::HirId) -> (Option<&hir::Ty>, bool) {
+        let parent = self.tcx.hir().get_parent_node_by_hir_id(hir_id);
+        let parent_node = self.tcx.hir().get_by_hir_id(parent);
 
         // The parent node is like a fn
         if let Some(fn_like) = FnLikeNode::from_node(parent_node) {
             // `nid`'s parent's `Body`
             let fn_body = self.tcx.hir().body(fn_like.body());
             // Get the position of `node_id` in the arguments list
-            let arg_pos = fn_body.arguments.iter().position(|arg| arg.pat.id == node_id);
+            let arg_pos = fn_body.arguments.iter().position(|arg| arg.pat.hir_id == hir_id);
             if let Some(i) = arg_pos {
                 // The argument's `Ty`
                 (Some(&fn_like.decl().inputs[i]),
@@ -1217,17 +1216,17 @@ fn local_ty(&self, node_id: ast::NodeId) -> (Option<&hir::Ty>, bool) {
     fn note_immutability_blame(&self,
                                db: &mut DiagnosticBuilder<'_>,
                                blame: Option<ImmutabilityBlame<'_>>,
-                               error_node_id: ast::NodeId) {
+                               error_hir_id: hir::HirId) {
         match blame {
             None => {}
             Some(ImmutabilityBlame::ClosureEnv(_)) => {}
-            Some(ImmutabilityBlame::ImmLocal(node_id)) => {
-                self.note_immutable_local(db, error_node_id, node_id)
+            Some(ImmutabilityBlame::ImmLocal(hir_id)) => {
+                self.note_immutable_local(db, error_hir_id, hir_id)
             }
-            Some(ImmutabilityBlame::LocalDeref(node_id)) => {
-                match self.local_binding_mode(node_id) {
+            Some(ImmutabilityBlame::LocalDeref(hir_id)) => {
+                match self.local_binding_mode(hir_id) {
                     ty::BindByReference(..) => {
-                        let let_span = self.tcx.hir().span(node_id);
+                        let let_span = self.tcx.hir().span_by_hir_id(hir_id);
                         let suggestion = suggest_ref_mut(self.tcx, let_span);
                         if let Some(replace_str) = suggestion {
                             db.span_suggestion(
@@ -1244,7 +1243,7 @@ fn note_immutability_blame(&self,
                         }
                     }
                     ty::BindByValue(..) => {
-                        if let (Some(local_ty), is_implicit_self) = self.local_ty(node_id) {
+                        if let (Some(local_ty), is_implicit_self) = self.local_ty(hir_id) {
                             if let Some(msg) =
                                  self.suggest_mut_for_immutable(local_ty, is_implicit_self) {
                                 db.span_label(local_ty.span, msg);
@@ -1273,12 +1272,12 @@ fn note_immutability_blame(&self,
      // not a mutable reference) or to avoid borrowing altogether
     fn note_immutable_local(&self,
                             db: &mut DiagnosticBuilder<'_>,
-                            borrowed_node_id: ast::NodeId,
-                            binding_node_id: ast::NodeId) {
-        let let_span = self.tcx.hir().span(binding_node_id);
-        if let ty::BindByValue(..) = self.local_binding_mode(binding_node_id) {
+                            borrowed_hir_id: hir::HirId,
+                            binding_hir_id: hir::HirId) {
+        let let_span = self.tcx.hir().span_by_hir_id(binding_hir_id);
+        if let ty::BindByValue(..) = self.local_binding_mode(binding_hir_id) {
             if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(let_span) {
-                let (ty, is_implicit_self) = self.local_ty(binding_node_id);
+                let (ty, is_implicit_self) = self.local_ty(binding_hir_id);
                 if is_implicit_self && snippet != "self" {
                     // avoid suggesting `mut &self`.
                     return
@@ -1291,9 +1290,9 @@ fn note_immutable_local(&self,
                     },
                 )) = ty.map(|t| &t.node)
                 {
-                    let borrow_expr_id = self.tcx.hir().get_parent_node(borrowed_node_id);
+                    let borrow_expr_id = self.tcx.hir().get_parent_node_by_hir_id(borrowed_hir_id);
                     db.span_suggestion(
-                        self.tcx.hir().span(borrow_expr_id),
+                        self.tcx.hir().span_by_hir_id(borrow_expr_id),
                         "consider removing the `&mut`, as it is an \
                         immutable binding to a mutable reference",
                         snippet,
@@ -1373,7 +1372,7 @@ fn note_and_explain_mutbl_error(&self, db: &mut DiagnosticBuilder<'_>, err: &Bck
                 if let Categorization::Deref(..) = err.cmt.cat {
                     db.span_label(*error_span, "cannot borrow as mutable");
                 } else if let Categorization::Local(local_id) = err.cmt.cat {
-                    let span = self.tcx.hir().span(local_id);
+                    let span = self.tcx.hir().span_by_hir_id(local_id);
                     if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
                         if snippet.starts_with("ref mut ") || snippet.starts_with("&mut ") {
                             db.span_label(*error_span, "cannot reborrow mutably");
@@ -1401,7 +1400,7 @@ pub fn append_loan_path_to_string(&self,
                 out.push_str(&self.tcx.hir().name_by_hir_id(id).as_str());
             }
             LpVar(id) => {
-                out.push_str(&self.tcx.hir().name(id).as_str());
+                out.push_str(&self.tcx.hir().name_by_hir_id(id).as_str());
             }
 
             LpDowncast(ref lp_base, variant_def_id) => {
@@ -1512,7 +1511,7 @@ impl<'tcx> fmt::Debug for LoanPath<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self.kind {
             LpVar(id) => {
-                write!(f, "$({})", ty::tls::with(|tcx| tcx.hir().node_to_string(id)))
+                write!(f, "$({})", ty::tls::with(|tcx| tcx.hir().hir_to_string(id)))
             }
 
             LpUpvar(ty::UpvarId{ var_path: ty::UpvarPath {hir_id: var_id}, closure_expr_id }) => {
@@ -1547,7 +1546,7 @@ impl<'tcx> fmt::Display for LoanPath<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self.kind {
             LpVar(id) => {
-                write!(f, "$({})", ty::tls::with(|tcx| tcx.hir().node_to_user_string(id)))
+                write!(f, "$({})", ty::tls::with(|tcx| tcx.hir().hir_to_user_string(id)))
             }
 
             LpUpvar(ty::UpvarId{ var_path: ty::UpvarPath { hir_id }, closure_expr_id: _ }) => {
index 43a5767e5c68d4fddfdbfbbac30a16954f3f168c..2d732adcb91381650d7114fd298098fb75e04cfb 100644 (file)
@@ -113,7 +113,7 @@ pub fn get_fn(
         unsafe {
             llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
 
-            let is_generic = instance.substs.types().next().is_some();
+            let is_generic = instance.substs.non_erasable_generics().next().is_some();
 
             if is_generic {
                 // This is a monomorphization. Its expected visibility depends
index 5b8c7461bcb60ed3aa667beb59b7bcc705c29b5e..258391ba8360fc99eecc1204d126860f964a9f7c 100644 (file)
@@ -123,9 +123,9 @@ fn write_metadata<'b, 'gcx>(
     ) -> EncodedMetadata {
         base::write_metadata(tcx, metadata)
     }
-    fn codegen_allocator(
+    fn codegen_allocator<'b, 'gcx>(
         &self,
-        tcx: TyCtxt<'_, '_, '_>,
+        tcx: TyCtxt<'b, 'gcx, 'gcx>,
         mods: &mut ModuleLlvm,
         kind: AllocatorKind
     ) {
index 0aba43580f1f6e0132c764db736c1a1f35ecea06..4702e34aa19e7fabe00b33304e339b3a47ea8d68 100644 (file)
@@ -19,6 +19,7 @@ memmap = "0.6"
 log = "0.4.5"
 libc = "0.2.44"
 jobserver = "0.1.11"
+parking_lot = "0.7"
 
 serialize = { path = "../libserialize" }
 syntax = { path = "../libsyntax" }
index 4b01e264f19eda5b38951da3aae6e105e548e569..336f41b784a81cf3793ec6c213e684e4bfaf35bc 100644 (file)
@@ -69,7 +69,7 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     let mut reachable_non_generics: DefIdMap<_> = tcx.reachable_set(LOCAL_CRATE).0
         .iter()
-        .filter_map(|&node_id| {
+        .filter_map(|&hir_id| {
             // We want to ignore some FFI functions that are not exposed from
             // this crate. Reachable FFI functions can be lumped into two
             // categories:
@@ -83,9 +83,9 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             //
             // As a result, if this id is an FFI item (foreign item) then we only
             // let it through if it's included statically.
-            match tcx.hir().get(node_id) {
+            match tcx.hir().get_by_hir_id(hir_id) {
                 Node::ForeignItem(..) => {
-                    let def_id = tcx.hir().local_def_id(node_id);
+                    let def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
                     if tcx.is_statically_included_foreign_item(def_id) {
                         Some(def_id)
                     } else {
@@ -105,7 +105,7 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     node: hir::ImplItemKind::Method(..),
                     ..
                 }) => {
-                    let def_id = tcx.hir().local_def_id(node_id);
+                    let def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
                     let generics = tcx.generics_of(def_id);
                     if !generics.requires_monomorphization(tcx) &&
                         // Functions marked with #[inline] are only ever codegened
@@ -263,7 +263,7 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 def: InstanceDef::Item(def_id),
                 substs,
             }) = mono_item {
-                if substs.types().next().is_some() {
+                if substs.non_erasable_generics().next().is_some() {
                     symbols.push((ExportedSymbol::Generic(def_id, substs),
                                   SymbolExportLevel::Rust));
                 }
@@ -343,8 +343,8 @@ fn upstream_monomorphizations_for_provider<'a, 'tcx>(
 }
 
 fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> bool {
-    if let Some(node_id) = tcx.hir().as_local_node_id(def_id) {
-        !tcx.reachable_set(LOCAL_CRATE).0.contains(&node_id)
+    if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) {
+        !tcx.reachable_set(LOCAL_CRATE).0.contains(&hir_id)
     } else {
         bug!("is_unreachable_local_definition called with non-local DefId: {:?}",
              def_id)
index 908ee95efcba3ffa0e1a92cf1f2216534ad35b17..4bccc2a6d1f7b7d06809b8fd0b644cc42fd213d4 100644 (file)
@@ -19,6 +19,7 @@
 use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc::ty::TyCtxt;
 use rustc::util::common::{time_depth, set_time_depth, print_time_passes_entry};
+use rustc::util::profiling::SelfProfiler;
 use rustc_fs_util::link_or_copy;
 use rustc_data_structures::svh::Svh;
 use rustc_errors::{Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId};
@@ -29,6 +30,7 @@
 use syntax_pos::MultiSpan;
 use syntax_pos::symbol::Symbol;
 use jobserver::{Client, Acquired};
+use parking_lot::Mutex as PlMutex;
 
 use std::any::Any;
 use std::fs;
@@ -201,6 +203,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
     // Resources needed when running LTO
     pub backend: B,
     pub time_passes: bool,
+    pub profiler: Option<Arc<PlMutex<SelfProfiler>>>,
     pub lto: Lto,
     pub no_landing_pads: bool,
     pub save_temps: bool,
@@ -254,6 +257,26 @@ pub fn config(&self, kind: ModuleKind) -> &ModuleConfig {
             ModuleKind::Allocator => &self.allocator_module_config,
         }
     }
+
+    #[inline(never)]
+    #[cold]
+    fn profiler_active<F: FnOnce(&mut SelfProfiler) -> ()>(&self, f: F) {
+        match &self.profiler {
+            None => bug!("profiler_active() called but there was no profiler active"),
+            Some(profiler) => {
+                let mut p = profiler.lock();
+
+                f(&mut p);
+            }
+        }
+    }
+
+    #[inline(always)]
+    pub fn profile<F: FnOnce(&mut SelfProfiler) -> ()>(&self, f: F) {
+        if unlikely!(self.profiler.is_some()) {
+            self.profiler_active(f)
+        }
+    }
 }
 
 fn generate_lto_work<B: ExtraBackendMethods>(
@@ -1033,6 +1056,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
         save_temps: sess.opts.cg.save_temps,
         opts: Arc::new(sess.opts.clone()),
         time_passes: sess.time_passes(),
+        profiler: sess.self_profiling.clone(),
         exported_symbols,
         plugin_passes: sess.plugin_llvm_passes.borrow().clone(),
         remark: sess.opts.cg.remark.clone(),
index f38b22aa0417129d342e03a1ffae6bafa8fd4fec..fec41936a238432314336d6f149669c70f51b5e0 100644 (file)
@@ -2,9 +2,11 @@
 
 #![feature(box_patterns)]
 #![feature(box_syntax)]
+#![feature(core_intrinsics)]
 #![feature(custom_attribute)]
 #![feature(libc)]
 #![feature(rustc_diagnostic_macros)]
+#![feature(stmt_expr_attributes)]
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
 #![allow(unused_attributes)]
@@ -20,6 +22,7 @@
 
 #[macro_use] extern crate log;
 #[macro_use] extern crate rustc;
+#[macro_use] extern crate rustc_data_structures;
 #[macro_use] extern crate syntax;
 
 use std::path::PathBuf;
index dc77d4673cd2a3594b3e9d4865925eb04a3dc7c4..a90dc356c92e830e01767dd3ab1a2d4e528f6eed 100644 (file)
@@ -659,15 +659,43 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
             };
             let upvar_tys = upvar_substs.upvar_tys(def_id, tcx);
 
-            for (i, (decl, ty)) in mir.upvar_decls.iter().zip(upvar_tys).enumerate() {
-                let byte_offset_of_var_in_env = closure_layout.fields.offset(i).bytes();
+            let extra_locals = {
+                let upvars = mir.upvar_decls
+                    .iter()
+                    .zip(upvar_tys)
+                    .enumerate()
+                    .map(|(i, (decl, ty))| (i, decl.debug_name, decl.by_ref, ty));
+
+                let generator_fields = mir.generator_layout.as_ref().map(|generator_layout| {
+                    let (def_id, gen_substs) = match closure_layout.ty.sty {
+                        ty::Generator(def_id, substs, _) => (def_id, substs),
+                        _ => bug!("generator layout without generator substs"),
+                    };
+                    let state_tys = gen_substs.state_tys(def_id, tcx);
+
+                    let upvar_count = mir.upvar_decls.len();
+                    generator_layout.fields
+                        .iter()
+                        .zip(state_tys)
+                        .enumerate()
+                        .filter_map(move |(i, (decl, ty))| {
+                            let ty = fx.monomorphize(&ty);
+                            decl.name.map(|name| (i + upvar_count + 1, name, false, ty))
+                        })
+                }).into_iter().flatten();
+
+                upvars.chain(generator_fields)
+            };
+
+            for (field, name, by_ref, ty) in extra_locals {
+                let byte_offset_of_var_in_env = closure_layout.fields.offset(field).bytes();
 
                 let ops = bx.debuginfo_upvar_decls_ops_sequence(byte_offset_of_var_in_env);
 
                 // The environment and the capture can each be indirect.
                 let mut ops = if env_ref { &ops[..] } else { &ops[1..] };
 
-                let ty = if let (true, &ty::Ref(_, ty, _)) = (decl.by_ref, &ty.sty) {
+                let ty = if let (true, &ty::Ref(_, ty, _)) = (by_ref, &ty.sty) {
                     ty
                 } else {
                     ops = &ops[..ops.len() - 1];
@@ -680,7 +708,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
                 };
                 bx.declare_local(
                     &fx.debug_context,
-                    decl.debug_name,
+                    name,
                     ty,
                     scope,
                     variable_access,
index 0a6549851f4462a03f92173cbd0d157f6d84a065..55a1eb016e0d0db1224b41b5b068d5440b80dd14 100644 (file)
@@ -76,6 +76,8 @@ pub fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         }
 
         let val = match val.val {
+            ConstValue::Param(_) => bug!("encountered a ConstValue::Param in codegen"),
+            ConstValue::Infer(_) => bug!("encountered a ConstValue::Infer in codegen"),
             ConstValue::Scalar(x) => {
                 let scalar = match layout.abi {
                     layout::Abi::Scalar(ref x) => x,
index b0c667a965daa3c79e071a107dac6c532daf5bad..b8131671320e1ed86db2e444e59d8d7ac26aba7a 100644 (file)
@@ -257,7 +257,8 @@ pub fn codegen_rvalue_operand(
                             }
                         }
                     }
-                    mir::CastKind::Misc if bx.cx().is_backend_scalar_pair(operand.layout) => {
+                    mir::CastKind::MutToConstPointer
+                    | mir::CastKind::Misc if bx.cx().is_backend_scalar_pair(operand.layout) => {
                         if let OperandValue::Pair(data_ptr, meta) = operand.val {
                             if bx.cx().is_backend_scalar_pair(cast) {
                                 let data_cast = bx.pointercast(data_ptr,
@@ -274,7 +275,8 @@ pub fn codegen_rvalue_operand(
                             bug!("Unexpected non-Pair operand")
                         }
                     }
-                    mir::CastKind::Misc => {
+                    mir::CastKind::MutToConstPointer
+                    | mir::CastKind::Misc => {
                         assert!(bx.cx().is_backend_immediate(cast));
                         let ll_t_out = bx.cx().immediate_backend_type(cast);
                         if operand.layout.abi.is_uninhabited() {
index 00eae9098e74fdd0abd4e77c8011c9adedcca4a3..a9e0eadb198a86f1fedea63c7b47f3763a6ede4d 100644 (file)
@@ -38,9 +38,9 @@ fn write_metadata<'b, 'gcx>(
         tcx: TyCtxt<'b, 'gcx, 'gcx>,
         metadata: &mut Self::Module,
     ) -> EncodedMetadata;
-    fn codegen_allocator(
+    fn codegen_allocator<'b, 'gcx>(
         &self,
-        tcx: TyCtxt<'_, '_, '_>,
+        tcx: TyCtxt<'b, 'gcx, 'gcx>,
         mods: &mut Self::Module,
         kind: AllocatorKind
     );
index f529cf30a62ea604ada3e4d05ef21304a820f28f..76e74e9e2b4640f219e22172c7482697a58b469a 100644 (file)
@@ -172,7 +172,7 @@ fn get_symbol_hash<'a, 'tcx>(
         assert!(!substs.needs_subst());
         substs.hash_stable(&mut hcx, &mut hasher);
 
-        let is_generic = substs.types().next().is_some();
+        let is_generic = substs.non_erasable_generics().next().is_some();
         let avoid_cross_crate_conflicts =
             // If this is an instance of a generic function, we also hash in
             // the ID of the instantiating crate. This avoids symbol conflicts
index 6aa262715ecf4f9321db656e5a17969ac891ee34..6002bf69b7069871ee9d75e4ab57c0d7edd81b83 100644 (file)
@@ -12,13 +12,15 @@ crate-type = ["dylib"]
 [dependencies]
 ena = "0.11"
 log = "0.4"
+jobserver_crate = { version = "0.1", package = "jobserver" }
+lazy_static = "1"
 rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
 serialize = { path = "../libserialize" }
 graphviz = { path = "../libgraphviz" }
 cfg-if = "0.1.2"
 stable_deref_trait = "1.0.0"
-rayon = { version = "0.1.1", package = "rustc-rayon" }
-rayon-core = { version = "0.1.1", package = "rustc-rayon-core" }
+rayon = { version = "0.1.2", package = "rustc-rayon" }
+rayon-core = { version = "0.1.2", package = "rustc-rayon-core" }
 rustc-hash = "1.0.1"
 smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
 
diff --git a/src/librustc_data_structures/jobserver.rs b/src/librustc_data_structures/jobserver.rs
new file mode 100644 (file)
index 0000000..48ac812
--- /dev/null
@@ -0,0 +1,156 @@
+use jobserver_crate::{Client, HelperThread, Acquired};
+use lazy_static::lazy_static;
+use std::sync::{Condvar, Arc, Mutex};
+use std::mem;
+
+#[derive(Default)]
+struct LockedProxyData {
+    /// The number of free thread tokens, this may include the implicit token given to the process
+    free: usize,
+
+    /// The number of threads waiting for a token
+    waiters: usize,
+
+    /// The number of tokens we requested from the server
+    requested: usize,
+
+    /// Stored tokens which will be dropped when we no longer need them
+    tokens: Vec<Acquired>,
+}
+
+impl LockedProxyData {
+    fn request_token(&mut self, thread: &Mutex<HelperThread>) {
+        self.requested += 1;
+        thread.lock().unwrap().request_token();
+    }
+
+    fn release_token(&mut self, cond_var: &Condvar) {
+        if self.waiters > 0 {
+            self.free += 1;
+            cond_var.notify_one();
+        } else {
+            if self.tokens.is_empty() {
+                // We are returning the implicit token
+                self.free += 1;
+            } else {
+                // Return a real token to the server
+                self.tokens.pop().unwrap();
+            }
+        }
+    }
+
+    fn take_token(&mut self, thread: &Mutex<HelperThread>) -> bool {
+        if self.free > 0 {
+            self.free -= 1;
+            self.waiters -= 1;
+
+            // We stole some token reqested by someone else
+            // Request another one
+            if self.requested + self.free < self.waiters {
+                self.request_token(thread);
+            }
+
+            true
+        } else {
+            false
+        }
+    }
+
+    fn new_requested_token(&mut self, token: Acquired, cond_var: &Condvar) {
+        self.requested -= 1;
+
+        // Does anything need this token?
+        if self.waiters > 0 {
+            self.free += 1;
+            self.tokens.push(token);
+            cond_var.notify_one();
+        } else {
+            // Otherwise we'll just drop it
+            mem::drop(token);
+        }
+    }
+}
+
+#[derive(Default)]
+struct ProxyData {
+    lock: Mutex<LockedProxyData>,
+    cond_var: Condvar,
+}
+
+/// A helper type which makes managing jobserver tokens easier.
+/// It also allows you to treat the implicit token given to the process
+/// in the same manner as requested tokens.
+struct Proxy {
+    thread: Mutex<HelperThread>,
+    data: Arc<ProxyData>,
+}
+
+lazy_static! {
+    // We can only call `from_env` once per process
+
+    // Note that this is unsafe because it may misinterpret file descriptors
+    // on Unix as jobserver file descriptors. We hopefully execute this near
+    // the beginning of the process though to ensure we don't get false
+    // positives, or in other words we try to execute this before we open
+    // any file descriptors ourselves.
+    //
+    // Pick a "reasonable maximum" if we don't otherwise have
+    // a jobserver in our environment, capping out at 32 so we
+    // don't take everything down by hogging the process run queue.
+    // The fixed number is used to have deterministic compilation
+    // across machines.
+    //
+    // Also note that we stick this in a global because there could be
+    // multiple rustc instances in this process, and the jobserver is
+    // per-process.
+    static ref GLOBAL_CLIENT: Client = unsafe {
+        Client::from_env().unwrap_or_else(|| {
+            Client::new(32).expect("failed to create jobserver")
+        })
+    };
+
+    static ref GLOBAL_PROXY: Proxy = {
+        let data = Arc::new(ProxyData::default());
+
+        Proxy {
+            data: data.clone(),
+            thread: Mutex::new(client().into_helper_thread(move |token| {
+                data.lock.lock().unwrap().new_requested_token(token.unwrap(), &data.cond_var);
+            }).unwrap()),
+        }
+    };
+}
+
+pub fn client() -> Client {
+    GLOBAL_CLIENT.clone()
+}
+
+pub fn acquire_thread() {
+    GLOBAL_PROXY.acquire_token();
+}
+
+pub fn release_thread() {
+    GLOBAL_PROXY.release_token();
+}
+
+impl Proxy {
+    fn release_token(&self) {
+        self.data.lock.lock().unwrap().release_token(&self.data.cond_var);
+    }
+
+    fn acquire_token(&self) {
+        let mut data = self.data.lock.lock().unwrap();
+        data.waiters += 1;
+        if data.take_token(&self.thread) {
+            return;
+        }
+        // Request a token for us
+        data.request_token(&self.thread);
+        loop {
+            data = self.data.cond_var.wait(data).unwrap();
+            if data.take_token(&self.thread) {
+                return;
+            }
+        }
+    }
+}
index 2bfb1b24a81b9629c4a7dbb524f6ae4344ede066..09482340b1a1d725a2a8f3b4068ca8ffd0ad73c8 100644 (file)
@@ -77,6 +77,7 @@ macro_rules! unlikely {
 pub mod graph;
 pub mod indexed_vec;
 pub mod interner;
+pub mod jobserver;
 pub mod obligation_forest;
 pub mod owning_ref;
 pub mod ptr_key;
index af1f2910461ecc9d203b35dff841589b44cc52e5..029e7267c8247d40e0e5c91e4292a57966aef2ee 100644 (file)
@@ -1,8 +1,7 @@
 /// A simple static assertion macro. The first argument should be a unique
 /// ALL_CAPS identifier that describes the condition.
 #[macro_export]
-#[cfg_attr(stage0, allow_internal_unstable)]
-#[cfg_attr(not(stage0), allow_internal_unstable(type_ascription))]
+#[allow_internal_unstable(type_ascription)]
 macro_rules! static_assert {
     ($name:ident: $test:expr) => {
         // Use the bool to access an array such that if the bool is false, the access
index 0b379ef662dde06dc6d7c2c502972d148fce100a..a77e497af7b8720f1bcee109eaa9b24cacdfe28f 100644 (file)
@@ -13,7 +13,7 @@ arena = { path = "../libarena" }
 graphviz = { path = "../libgraphviz" }
 log = "0.4"
 env_logger = { version = "0.5", default-features = false }
-rustc-rayon = "0.1.1"
+rustc-rayon = "0.1.2"
 scoped-tls = "1.0"
 rustc = { path = "../librustc" }
 rustc_allocator = { path = "../librustc_allocator" }
index f87a809e6c6eb1e3d6c7301892b1d8ff062a85ee..d3e295607c2b395b40dd1f222a8286f705bde98b 100644 (file)
@@ -17,6 +17,8 @@
 use rustc_borrowck as borrowck;
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
 use rustc_data_structures::sync::{self, Lock};
+#[cfg(parallel_compiler)]
+use rustc_data_structures::jobserver;
 use rustc_incremental;
 use rustc_metadata::creader::CrateLoader;
 use rustc_metadata::cstore::{self, CStore};
@@ -72,6 +74,8 @@ pub fn spawn_thread_pool<F: FnOnce(config::Options) -> R + sync::Send, R: sync::
     let gcx_ptr = &Lock::new(0);
 
     let config = ThreadPoolBuilder::new()
+        .acquire_thread_handler(jobserver::acquire_thread)
+        .release_thread_handler(jobserver::release_thread)
         .num_threads(Session::threads_from_count(opts.debugging_opts.threads))
         .deadlock_handler(|| unsafe { ty::query::handle_deadlock() })
         .stack_size(::STACK_SIZE);
@@ -345,14 +349,6 @@ macro_rules! controller_entry_point {
         sess.print_perf_stats();
     }
 
-    if sess.opts.debugging_opts.self_profile {
-        sess.print_profiler_results();
-    }
-
-    if sess.opts.debugging_opts.profile_json {
-        sess.save_json_results();
-    }
-
     controller_entry_point!(
         compilation_done,
         sess,
index 52dbb618d0d11ac5420bafb57e0ca936437869af..cc1b8916c1074401e87b08cea6b3843bca4f1258 100644 (file)
@@ -276,6 +276,10 @@ macro_rules! do_or_return {($expr: expr, $sess: expr) => {
                               &control)
     };
 
+    if sess.opts.debugging_opts.self_profile {
+        sess.profiler(|p| p.dump_raw_events(&sess.opts));
+    }
+
     (result, Some(sess))
 }
 
index ac2f6da0c608472f609485473f3817afbc14f21d..1750aa62dd5e0f9d43b82e5123be8ddb327d3989 100644 (file)
@@ -408,8 +408,8 @@ fn post(&self, s: &mut pprust_hir::State, node: pprust_hir::AnnNode) -> io::Resu
             pprust_hir::AnnNode::Name(_) => Ok(()),
             pprust_hir::AnnNode::Item(item) => {
                 s.s.space()?;
-                s.synth_comment(format!("node_id: {} hir local_id: {}",
-                                        item.id, item.hir_id.local_id.as_u32()))
+                s.synth_comment(format!("hir_id: {} hir local_id: {}",
+                                        item.hir_id, item.hir_id.local_id.as_u32()))
             }
             pprust_hir::AnnNode::SubItem(id) => {
                 s.s.space()?;
@@ -428,8 +428,8 @@ fn post(&self, s: &mut pprust_hir::State, node: pprust_hir::AnnNode) -> io::Resu
             }
             pprust_hir::AnnNode::Pat(pat) => {
                 s.s.space()?;
-                s.synth_comment(format!("pat node_id: {} hir local_id: {}",
-                                        pat.id, pat.hir_id.local_id.as_u32()))
+                s.synth_comment(format!("pat hir_id: {} hir local_id: {}",
+                                        pat.hir_id, pat.hir_id.local_id.as_u32()))
             }
         }
     }
index 309a9f7b5252253d8b974f95f6cb624fcb4118a2..65f8ce75bd1135d29e73f7591bbca5dd8d806b52 100644 (file)
@@ -249,7 +249,7 @@ pub fn create_simple_region_hierarchy(&mut self) {
     }
 
     #[allow(dead_code)] // this seems like it could be useful, even if we don't use it now
-    pub fn lookup_item(&self, names: &[String]) -> ast::NodeId {
+    pub fn lookup_item(&self, names: &[String]) -> hir::HirId {
         return match search_mod(self, &self.infcx.tcx.hir().krate().module, 0, names) {
             Some(id) => id,
             None => {
@@ -262,7 +262,7 @@ fn search_mod(
             m: &hir::Mod,
             idx: usize,
             names: &[String],
-        ) -> Option<ast::NodeId> {
+        ) -> Option<hir::HirId> {
             assert!(idx < names.len());
             for item in &m.item_ids {
                 let item = this.infcx.tcx.hir().expect_item(item.id);
@@ -273,9 +273,9 @@ fn search_mod(
             return None;
         }
 
-        fn search(this: &Env, it: &hir::Item, idx: usize, names: &[String]) -> Option<ast::NodeId> {
+        fn search(this: &Env, it: &hir::Item, idx: usize, names: &[String]) -> Option<hir::HirId> {
             if idx == names.len() {
-                return Some(it.id);
+                return Some(it.hir_id);
             }
 
             return match it.node {
index 093d15b7e3c577c4c9212bf4b1b658ff21057708..8ed03efd1a784ab8ca39ba712178d54d2e07e36d 100644 (file)
@@ -3,7 +3,6 @@
 use rustc::hir;
 use rustc::ty::TyCtxt;
 use rustc::ty::query::Providers;
-use syntax::ast;
 use syntax::attr;
 
 pub fn find<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> Option<DefId> {
@@ -19,17 +18,17 @@ fn proc_macro_decls_static<'tcx>(
     let mut finder = Finder { decls: None };
     tcx.hir().krate().visit_all_item_likes(&mut finder);
 
-    finder.decls.map(|id| tcx.hir().local_def_id(id))
+    finder.decls.map(|id| tcx.hir().local_def_id_from_hir_id(id))
 }
 
 struct Finder {
-    decls: Option<ast::NodeId>,
+    decls: Option<hir::HirId>,
 }
 
 impl<'v> ItemLikeVisitor<'v> for Finder {
     fn visit_item(&mut self, item: &hir::Item) {
         if attr::contains_name(&item.attrs, "rustc_proc_macro_decls") {
-            self.decls = Some(item.id);
+            self.decls = Some(item.hir_id);
         }
     }
 
index 4d484a64f47df3fc9df1e44490f4e800582b700d..641adec82cdd9e11d3e849445bc1bf43adee7339 100644 (file)
@@ -26,7 +26,7 @@
 use rustc::ty::{self, Ty};
 use rustc::{lint, util};
 use hir::Node;
-use util::nodemap::NodeSet;
+use util::nodemap::HirIdSet;
 use lint::{LateContext, LintContext, LintArray};
 use lint::{LintPass, LateLintPass, EarlyLintPass, EarlyContext};
 
@@ -137,7 +137,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
             hir::ItemKind::Enum(..) |
             hir::ItemKind::Struct(..) |
             hir::ItemKind::Union(..) => {
-                let def_id = cx.tcx.hir().local_def_id(it.id);
+                let def_id = cx.tcx.hir().local_def_id_from_hir_id(it.hir_id);
                 self.check_heap_type(cx, it.span, cx.tcx.type_of(def_id))
             }
             _ => ()
@@ -148,7 +148,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
             hir::ItemKind::Struct(ref struct_def, _) |
             hir::ItemKind::Union(ref struct_def, _) => {
                 for struct_field in struct_def.fields() {
-                    let def_id = cx.tcx.hir().local_def_id(struct_field.id);
+                    let def_id = cx.tcx.hir().local_def_id_from_hir_id(struct_field.hir_id);
                     self.check_heap_type(cx, struct_field.span,
                                          cx.tcx.type_of(def_id));
                 }
@@ -447,8 +447,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
                 if let hir::VisibilityKind::Inherited = it.vis.node {
                     self.private_traits.insert(it.hir_id);
                     for trait_item_ref in trait_item_refs {
-                        let hir_id = cx.tcx.hir().node_to_hir_id(trait_item_ref.id.node_id);
-                        self.private_traits.insert(hir_id);
+                        self.private_traits.insert(trait_item_ref.id.hir_id);
                     }
                     return;
                 }
@@ -464,9 +463,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
                         Some(Node::Item(item)) => {
                             if let hir::VisibilityKind::Inherited = item.vis.node {
                                 for impl_item_ref in impl_item_refs {
-                                    let hir_id = cx.tcx.hir().node_to_hir_id(
-                                        impl_item_ref.id.node_id);
-                                    self.private_traits.insert(hir_id);
+                                    self.private_traits.insert(impl_item_ref.id.hir_id);
                                 }
                             }
                         }
@@ -560,7 +557,8 @@ fn get_lints(&self) -> LintArray {
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations {
     fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
-        if !cx.access_levels.is_reachable(item.id) {
+        let node_id = cx.tcx.hir().hir_to_node_id(item.hir_id);
+        if !cx.access_levels.is_reachable(node_id) {
             return;
         }
         let (def, ty) = match item.node {
@@ -568,21 +566,21 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
-                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.id));
+                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id_from_hir_id(item.hir_id));
                 (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
             }
             hir::ItemKind::Union(_, ref ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
-                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.id));
+                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id_from_hir_id(item.hir_id));
                 (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
             }
             hir::ItemKind::Enum(_, ref ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
-                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.id));
+                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id_from_hir_id(item.hir_id));
                 (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
             }
             _ => return,
@@ -610,7 +608,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
 }
 
 pub struct MissingDebugImplementations {
-    impling_types: Option<NodeSet>,
+    impling_types: Option<HirIdSet>,
 }
 
 impl MissingDebugImplementations {
@@ -631,7 +629,8 @@ fn get_lints(&self) -> LintArray {
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations {
     fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
-        if !cx.access_levels.is_reachable(item.id) {
+        let node_id = cx.tcx.hir().hir_to_node_id(item.hir_id);
+        if !cx.access_levels.is_reachable(node_id) {
             return;
         }
 
@@ -648,11 +647,11 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
         };
 
         if self.impling_types.is_none() {
-            let mut impls = NodeSet::default();
+            let mut impls = HirIdSet::default();
             cx.tcx.for_each_impl(debug, |d| {
                 if let Some(ty_def) = cx.tcx.type_of(d).ty_adt_def() {
-                    if let Some(node_id) = cx.tcx.hir().as_local_node_id(ty_def.did) {
-                        impls.insert(node_id);
+                    if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(ty_def.did) {
+                        impls.insert(hir_id);
                     }
                 }
             });
@@ -661,7 +660,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
             debug!("{:?}", self.impling_types);
         }
 
-        if !self.impling_types.as_ref().unwrap().contains(&item.id) {
+        if !self.impling_types.as_ref().unwrap().contains(&item.hir_id) {
             cx.span_lint(MISSING_DEBUG_IMPLEMENTATIONS,
                          item.span,
                          "type does not implement `fmt::Debug`; consider adding #[derive(Debug)] \
@@ -858,7 +857,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
             _ => return,
         };
 
-        let def_id = cx.tcx.hir().local_def_id(it.id);
+        let def_id = cx.tcx.hir().local_def_id_from_hir_id(it.hir_id);
         let prfn = match cx.tcx.extern_mod_stmt_cnum(def_id) {
             Some(cnum) => cx.tcx.plugin_registrar_fn(cnum),
             None => {
@@ -1078,7 +1077,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnionsWithDropFields {
     fn check_item(&mut self, ctx: &LateContext<'_, '_>, item: &hir::Item) {
         if let hir::ItemKind::Union(ref vdata, _) = item.node {
             for field in vdata.fields() {
-                let field_ty = ctx.tcx.type_of(ctx.tcx.hir().local_def_id(field.id));
+                let field_ty = ctx.tcx.type_of(
+                    ctx.tcx.hir().local_def_id_from_hir_id(field.hir_id));
                 if field_ty.needs_drop(ctx.tcx, ctx.param_env) {
                     ctx.span_lint(UNIONS_WITH_DROP_FIELDS,
                                   field.span,
@@ -1357,7 +1357,7 @@ fn check_item(
 
 
         if cx.tcx.features().trivial_bounds {
-            let def_id = cx.tcx.hir().local_def_id(item.id);
+            let def_id = cx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
             let predicates = cx.tcx.predicates_of(def_id);
             for &(predicate, span) in &predicates.predicates {
                 let predicate_kind_name = match predicate {
@@ -1497,14 +1497,14 @@ fn matches_ellipsis_pat(pat: &ast::Pat) -> Option<(&P<Expr>, &P<Expr>, Span)> {
 }
 
 pub struct UnnameableTestItems {
-    boundary: ast::NodeId, // NodeId of the item under which things are not nameable
+    boundary: hir::HirId, // HirId of the item under which things are not nameable
     items_nameable: bool,
 }
 
 impl UnnameableTestItems {
     pub fn new() -> Self {
         Self {
-            boundary: ast::DUMMY_NODE_ID,
+            boundary: hir::DUMMY_HIR_ID,
             items_nameable: true
         }
     }
@@ -1526,7 +1526,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
             if let hir::ItemKind::Mod(..) = it.node {}
             else {
                 self.items_nameable = false;
-                self.boundary = it.id;
+                self.boundary = it.hir_id;
             }
             return;
         }
@@ -1541,7 +1541,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
     }
 
     fn check_item_post(&mut self, _cx: &LateContext<'_, '_>, it: &hir::Item) {
-        if !self.items_nameable && self.boundary == it.id {
+        if !self.items_nameable && self.boundary == it.hir_id {
             self.items_nameable = true;
         }
     }
@@ -1791,7 +1791,7 @@ fn consolidate_outlives_bound_spans(
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements {
     fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item) {
         let infer_static = cx.tcx.features().infer_static_outlives_requirements;
-        let def_id = cx.tcx.hir().local_def_id(item.id);
+        let def_id = cx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
         if let hir::ItemKind::Struct(_, ref generics) = item.node {
             let mut bound_count = 0;
             let mut lint_spans = Vec::new();
index 35489ab42e73038c056cea9f25597d1903155bca..4ad1a00afe97c2fec84f4a4f92dd4e0a987ad68c 100644 (file)
@@ -762,8 +762,8 @@ fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
         }
     }
 
-    fn check_foreign_fn(&mut self, id: ast::NodeId, decl: &hir::FnDecl) {
-        let def_id = self.cx.tcx.hir().local_def_id(id);
+    fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl) {
+        let def_id = self.cx.tcx.hir().local_def_id_from_hir_id(id);
         let sig = self.cx.tcx.fn_sig(def_id);
         let sig = self.cx.tcx.erase_late_bound_regions(&sig);
         let inputs = if sig.c_variadic {
@@ -786,8 +786,8 @@ fn check_foreign_fn(&mut self, id: ast::NodeId, decl: &hir::FnDecl) {
         }
     }
 
-    fn check_foreign_static(&mut self, id: ast::NodeId, span: Span) {
-        let def_id = self.cx.tcx.hir().local_def_id(id);
+    fn check_foreign_static(&mut self, id: hir::HirId, span: Span) {
+        let def_id = self.cx.tcx.hir().local_def_id_from_hir_id(id);
         let ty = self.cx.tcx.type_of(def_id);
         self.check_type_for_ffi_and_report_errors(span, ty);
     }
@@ -809,14 +809,14 @@ fn get_lints(&self) -> LintArray {
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
     fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem) {
         let mut vis = ImproperCTypesVisitor { cx };
-        let abi = cx.tcx.hir().get_foreign_abi(it.id);
+        let abi = cx.tcx.hir().get_foreign_abi_by_hir_id(it.hir_id);
         if abi != Abi::RustIntrinsic && abi != Abi::PlatformIntrinsic {
             match it.node {
                 hir::ForeignItemKind::Fn(ref decl, _, _) => {
-                    vis.check_foreign_fn(it.id, decl);
+                    vis.check_foreign_fn(it.hir_id, decl);
                 }
                 hir::ForeignItemKind::Static(ref ty, _) => {
-                    vis.check_foreign_static(it.id, ty.span);
+                    vis.check_foreign_static(it.hir_id, ty.span);
                 }
                 hir::ForeignItemKind::Type => ()
             }
@@ -839,7 +839,7 @@ fn get_lints(&self) -> LintArray {
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
     fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
         if let hir::ItemKind::Enum(ref enum_definition, _) = it.node {
-            let item_def_id = cx.tcx.hir().local_def_id(it.id);
+            let item_def_id = cx.tcx.hir().local_def_id_from_hir_id(it.hir_id);
             let t = cx.tcx.type_of(item_def_id);
             let ty = cx.tcx.erase_regions(&t);
             match cx.layout_of(ty) {
diff --git a/src/librustc_macros/Cargo.toml b/src/librustc_macros/Cargo.toml
new file mode 100644 (file)
index 0000000..2fe51a2
--- /dev/null
@@ -0,0 +1,14 @@
+[package]
+name = "rustc_macros"
+version = "0.1.0"
+authors = ["The Rust Project Developers"]
+edition = "2018"
+
+[lib]
+proc-macro = true
+
+[dependencies]
+synstructure = "0.10.1"
+syn = { version = "0.15.22", features = ["full"] }
+proc-macro2 = "0.4.24"
+quote = "0.6.10"
diff --git a/src/librustc_macros/src/hash_stable.rs b/src/librustc_macros/src/hash_stable.rs
new file mode 100644 (file)
index 0000000..6d7590c
--- /dev/null
@@ -0,0 +1,87 @@
+use synstructure;
+use syn::{self, Meta, NestedMeta, parse_quote};
+use proc_macro2::{self, Ident};
+use quote::quote;
+
+struct Attributes {
+    ignore: bool,
+    project: Option<Ident>,
+}
+
+fn parse_attributes(field: &syn::Field) -> Attributes {
+    let mut attrs = Attributes {
+        ignore: false,
+        project: None,
+    };
+    for attr in &field.attrs {
+        if let Ok(meta) = attr.parse_meta() {
+            if &meta.name().to_string() != "stable_hasher" {
+                continue;
+            }
+            let mut any_attr = false;
+            if let Meta::List(list) = meta {
+                for nested in list.nested.iter() {
+                    if let NestedMeta::Meta(meta) = nested {
+                        if &meta.name().to_string() == "ignore" {
+                            attrs.ignore = true;
+                            any_attr = true;
+                        }
+                        if &meta.name().to_string() == "project" {
+                            if let Meta::List(list) = meta {
+                                if let Some(nested) = list.nested.iter().next() {
+                                    if let NestedMeta::Meta(meta) = nested {
+                                        attrs.project = Some(meta.name());
+                                        any_attr = true;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            if !any_attr {
+                panic!("error parsing stable_hasher");
+            }
+        }
+    }
+    attrs
+}
+
+pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
+    let generic: syn::GenericParam = parse_quote!('__ctx);
+    s.add_bounds(synstructure::AddBounds::Generics);
+    s.add_impl_generic(generic);
+    let body = s.each(|bi| {
+        let attrs = parse_attributes(bi.ast());
+        if attrs.ignore {
+             quote!{}
+        } else if let Some(project) = attrs.project {
+            quote!{
+                &#bi.#project.hash_stable(__hcx, __hasher);
+            }
+        } else {
+            quote!{
+                #bi.hash_stable(__hcx, __hasher);
+            }
+        }
+    });
+
+    let discriminant = match s.ast().data {
+        syn::Data::Enum(_) => quote! {
+            ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
+        },
+        syn::Data::Struct(_) => quote! {},
+        syn::Data::Union(_) => panic!("cannot derive on union"),
+    };
+
+    s.bound_impl(quote!(::rustc_data_structures::stable_hasher::HashStable
+                        <::rustc::ich::StableHashingContext<'__ctx>>), quote!{
+        fn hash_stable<__W: ::rustc_data_structures::stable_hasher::StableHasherResult>(
+            &self,
+            __hcx: &mut ::rustc::ich::StableHashingContext<'__ctx>,
+            __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<__W>) {
+            #discriminant
+            match *self { #body }
+        }
+    })
+}
diff --git a/src/librustc_macros/src/lib.rs b/src/librustc_macros/src/lib.rs
new file mode 100644 (file)
index 0000000..cad3126
--- /dev/null
@@ -0,0 +1,8 @@
+#![feature(proc_macro_hygiene)]
+#![deny(rust_2018_idioms)]
+
+use synstructure::decl_derive;
+
+mod hash_stable;
+
+decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive);
index 6f2718381c2ec80661e33b14febd201fd1619dfc..36d9bf9f50dd59b7c2a48e704102e3fa27f3cb1d 100644 (file)
@@ -188,13 +188,15 @@ fn verify_no_symbol_conflicts(&self,
         });
     }
 
-    fn register_crate(&mut self,
-                      root: &Option<CratePaths>,
-                      ident: Symbol,
-                      span: Span,
-                      lib: Library,
-                      dep_kind: DepKind)
-                      -> (CrateNum, Lrc<cstore::CrateMetadata>) {
+    fn register_crate(
+        &mut self,
+        host_lib: Option<Library>,
+        root: &Option<CratePaths>,
+        ident: Symbol,
+        span: Span,
+        lib: Library,
+        dep_kind: DepKind
+    ) -> (CrateNum, Lrc<cstore::CrateMetadata>) {
         let crate_root = lib.metadata.get_root();
         info!("register crate `extern crate {} as {}`", crate_root.name, ident);
         self.verify_no_symbol_conflicts(span, &crate_root);
@@ -222,7 +224,16 @@ fn register_crate(&mut self,
         let dependencies: Vec<CrateNum> = cnum_map.iter().cloned().collect();
 
         let proc_macros = crate_root.proc_macro_decls_static.map(|_| {
-            self.load_derive_macros(&crate_root, dylib.clone().map(|p| p.0), span)
+            if self.sess.opts.debugging_opts.dual_proc_macros {
+                let host_lib = host_lib.unwrap();
+                self.load_derive_macros(
+                    &host_lib.metadata.get_root(),
+                    host_lib.dylib.clone().map(|p| p.0),
+                    span
+                )
+            } else {
+                self.load_derive_macros(&crate_root, dylib.clone().map(|p| p.0), span)
+            }
         });
 
         let def_path_table = record_time(&self.sess.perf_stats.decode_def_path_tables_time, || {
@@ -269,6 +280,61 @@ fn register_crate(&mut self,
         (cnum, cmeta)
     }
 
+    fn load_proc_macro<'b> (
+        &mut self,
+        locate_ctxt: &mut locator::Context<'b>,
+        path_kind: PathKind,
+    ) -> Option<(LoadResult, Option<Library>)>
+    where
+        'a: 'b
+    {
+        // Use a new locator Context so trying to load a proc macro doesn't affect the error
+        // message we emit
+        let mut proc_macro_locator = locate_ctxt.clone();
+
+        // Try to load a proc macro
+        proc_macro_locator.is_proc_macro = Some(true);
+
+        // Load the proc macro crate for the target
+        let (locator, target_result) = if self.sess.opts.debugging_opts.dual_proc_macros {
+            proc_macro_locator.reset();
+            let result = match self.load(&mut proc_macro_locator)? {
+                LoadResult::Previous(cnum) => return Some((LoadResult::Previous(cnum), None)),
+                LoadResult::Loaded(library) => Some(LoadResult::Loaded(library))
+            };
+            // Don't look for a matching hash when looking for the host crate.
+            // It won't be the same as the target crate hash
+            locate_ctxt.hash = None;
+            // Use the locate_ctxt when looking for the host proc macro crate, as that is required
+            // so we want it to affect the error message
+            (locate_ctxt, result)
+        } else {
+            (&mut proc_macro_locator, None)
+        };
+
+        // Load the proc macro crate for the host
+
+        locator.reset();
+        locator.is_proc_macro = Some(true);
+        locator.target = &self.sess.host;
+        locator.triple = TargetTriple::from_triple(config::host_triple());
+        locator.filesearch = self.sess.host_filesearch(path_kind);
+
+        let host_result = self.load(locator)?;
+
+        Some(if self.sess.opts.debugging_opts.dual_proc_macros {
+            let host_result = match host_result {
+                LoadResult::Previous(..) => {
+                    panic!("host and target proc macros must be loaded in lock-step")
+                }
+                LoadResult::Loaded(library) => library
+            };
+            (target_result.unwrap(), Some(host_result))
+        } else {
+            (host_result, None)
+        })
+    }
+
     fn resolve_crate<'b>(
         &'b mut self,
         root: &'b Option<CratePaths>,
@@ -282,7 +348,7 @@ fn resolve_crate<'b>(
     ) -> Result<(CrateNum, Lrc<cstore::CrateMetadata>), LoadError<'b>> {
         info!("resolving crate `extern crate {} as {}`", name, ident);
         let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
-            LoadResult::Previous(cnum)
+            (LoadResult::Previous(cnum), None)
         } else {
             info!("falling back to a load");
             let mut locate_ctxt = locator::Context {
@@ -294,7 +360,7 @@ fn resolve_crate<'b>(
                 extra_filename: extra_filename,
                 filesearch: self.sess.target_filesearch(path_kind),
                 target: &self.sess.target.target,
-                triple: &self.sess.opts.target_triple,
+                triple: self.sess.opts.target_triple.clone(),
                 root,
                 rejected_via_hash: vec![],
                 rejected_via_triple: vec![],
@@ -306,28 +372,14 @@ fn resolve_crate<'b>(
                 metadata_loader: &*self.cstore.metadata_loader,
             };
 
-            self.load(&mut locate_ctxt).or_else(|| {
+            self.load(&mut locate_ctxt).map(|r| (r, None)).or_else(|| {
                 dep_kind = DepKind::UnexportedMacrosOnly;
-
-                let mut proc_macro_locator = locator::Context {
-                    target: &self.sess.host,
-                    triple: &TargetTriple::from_triple(config::host_triple()),
-                    filesearch: self.sess.host_filesearch(path_kind),
-                    rejected_via_hash: vec![],
-                    rejected_via_triple: vec![],
-                    rejected_via_kind: vec![],
-                    rejected_via_version: vec![],
-                    rejected_via_filename: vec![],
-                    is_proc_macro: Some(true),
-                    ..locate_ctxt
-                };
-
-                self.load(&mut proc_macro_locator)
+                self.load_proc_macro(&mut locate_ctxt, path_kind)
             }).ok_or_else(move || LoadError::LocatorError(locate_ctxt))?
         };
 
         match result {
-            LoadResult::Previous(cnum) => {
+            (LoadResult::Previous(cnum), None) => {
                 let data = self.cstore.get_crate_data(cnum);
                 if data.root.proc_macro_decls_static.is_some() {
                     dep_kind = DepKind::UnexportedMacrosOnly;
@@ -337,9 +389,10 @@ fn resolve_crate<'b>(
                 });
                 Ok((cnum, data))
             }
-            LoadResult::Loaded(library) => {
-                Ok(self.register_crate(root, ident, span, library, dep_kind))
+            (LoadResult::Loaded(library), host_library) => {
+                Ok(self.register_crate(host_library, root, ident, span, library, dep_kind))
             }
+            _ => panic!()
         }
     }
 
@@ -355,7 +408,7 @@ fn load(&mut self, locate_ctxt: &mut locator::Context<'_>) -> Option<LoadResult>
         // don't want to match a host crate against an equivalent target one
         // already loaded.
         let root = library.metadata.get_root();
-        if locate_ctxt.triple == &self.sess.opts.target_triple {
+        if locate_ctxt.triple == self.sess.opts.target_triple {
             let mut result = LoadResult::Loaded(library);
             self.cstore.iter_crate_data(|cnum, data| {
                 if data.root.name == root.name && root.hash == data.root.hash {
@@ -451,9 +504,9 @@ fn resolve_crate_deps(&mut self,
     fn read_extension_crate(&mut self, span: Span, orig_name: Symbol, rename: Symbol)
                             -> ExtensionCrate {
         info!("read extension crate `extern crate {} as {}`", orig_name, rename);
-        let target_triple = &self.sess.opts.target_triple;
+        let target_triple = self.sess.opts.target_triple.clone();
         let host_triple = TargetTriple::from_triple(config::host_triple());
-        let is_cross = target_triple != &host_triple;
+        let is_cross = target_triple != host_triple;
         let mut target_only = false;
         let mut locate_ctxt = locator::Context {
             sess: self.sess,
@@ -464,7 +517,7 @@ fn read_extension_crate(&mut self, span: Span, orig_name: Symbol, rename: Symbol
             extra_filename: None,
             filesearch: self.sess.host_filesearch(PathKind::Crate),
             target: &self.sess.host,
-            triple: &host_triple,
+            triple: host_triple,
             root: &None,
             rejected_via_hash: vec![],
             rejected_via_triple: vec![],
index 1c4e3bc6a50e700e858ccb57d3d4c448fee572d4..6fe00a4ad2ff2607090912870fbc4bc2875e4aac 100644 (file)
@@ -648,7 +648,7 @@ pub fn get_type(&self, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
 
     pub fn get_stability(&self, id: DefIndex) -> Option<attr::Stability> {
         match self.is_proc_macro(id) {
-            true => None,
+            true => self.root.proc_macro_stability.clone(),
             false => self.entry(id).stability.map(|stab| stab.decode(self)),
         }
     }
index b4a71b887dc37a629fd73d5aa89218d160914c3e..683056c9b33a0348b4e4b000aaa2d7f68bface94 100644 (file)
@@ -29,7 +29,7 @@
 use std::path::Path;
 use rustc_data_structures::sync::Lrc;
 use std::u32;
-use syntax::ast::{self, CRATE_NODE_ID};
+use syntax::ast;
 use syntax::attr;
 use syntax::source_map::Spanned;
 use syntax::symbol::keywords;
@@ -314,7 +314,7 @@ fn encode_info_for_items(&mut self) -> Index {
         let vis = Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Public };
         index.record(DefId::local(CRATE_DEF_INDEX),
                      IsolatedEncoder::encode_info_for_mod,
-                     FromId(CRATE_NODE_ID, (&krate.module, &krate.attrs, &vis)));
+                     FromId(hir::CRATE_HIR_ID, (&krate.module, &krate.attrs, &vis)));
         let mut visitor = EncodeVisitor { index };
         krate.visit_all_item_likes(&mut visitor.as_deep_visitor());
         for macro_def in &krate.exported_macros {
@@ -490,7 +490,11 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
             } else {
                 None
             },
-
+            proc_macro_stability: if is_proc_macro {
+                tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).map(|stab| stab.clone())
+            } else {
+                None
+            },
             compiler_builtins: attr::contains_name(&attrs, "compiler_builtins"),
             needs_allocator: attr::contains_name(&attrs, "needs_allocator"),
             needs_panic_runtime: attr::contains_name(&attrs, "needs_panic_runtime"),
@@ -588,8 +592,8 @@ fn encode_enum_variant_info(&mut self,
             }
         };
 
-        let enum_id = tcx.hir().as_local_node_id(enum_did).unwrap();
-        let enum_vis = &tcx.hir().expect_item(enum_id).vis;
+        let enum_id = tcx.hir().as_local_hir_id(enum_did).unwrap();
+        let enum_vis = &tcx.hir().expect_item_by_hir_id(enum_id).vis;
 
         Entry {
             kind: EntryKind::Variant(self.lazy(&data)),
@@ -624,7 +628,7 @@ fn encode_info_for_mod(&mut self,
                                                                  &hir::Visibility)>)
                            -> Entry<'tcx> {
         let tcx = self.tcx;
-        let def_id = tcx.hir().local_def_id(id);
+        let def_id = tcx.hir().local_def_id_from_hir_id(id);
         debug!("IsolatedEncoder::encode_info_for_mod({:?})", def_id);
 
         let data = ModData {
@@ -714,8 +718,8 @@ fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<
             }
         };
 
-        let struct_id = tcx.hir().as_local_node_id(adt_def_id).unwrap();
-        let struct_vis = &tcx.hir().expect_item(struct_id).vis;
+        let struct_id = tcx.hir().as_local_hir_id(adt_def_id).unwrap();
+        let struct_vis = &tcx.hir().expect_item_by_hir_id(struct_id).vis;
         let mut ctor_vis = ty::Visibility::from_hir(struct_vis, struct_id, tcx);
         for field in &variant.fields {
             if ctor_vis.is_at_least(field.vis, tcx) {
@@ -1055,7 +1059,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                 EntryKind::Fn(self.lazy(&data))
             }
             hir::ItemKind::Mod(ref m) => {
-                return self.encode_info_for_mod(FromId(item.id, (m, &item.attrs, &item.vis)));
+                return self.encode_info_for_mod(FromId(item.hir_id, (m, &item.attrs, &item.vis)));
             }
             hir::ItemKind::ForeignMod(_) => EntryKind::ForeignMod,
             hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm,
@@ -1069,7 +1073,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                 // for methods, write all the stuff get_trait_method
                 // needs to know
                 let struct_ctor = if !struct_def.is_struct() {
-                    Some(tcx.hir().local_def_id(struct_def.id()).index)
+                    Some(tcx.hir().local_def_id_from_hir_id(struct_def.hir_id()).index)
                 } else {
                     None
                 };
@@ -1154,14 +1158,15 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
 
         Entry {
             kind,
-            visibility: self.lazy(&ty::Visibility::from_hir(&item.vis, item.id, tcx)),
+            visibility: self.lazy(&ty::Visibility::from_hir(&item.vis, item.hir_id, tcx)),
             span: self.lazy(&item.span),
             attributes: self.encode_attributes(&item.attrs),
             children: match item.node {
                 hir::ItemKind::ForeignMod(ref fm) => {
                     self.lazy_seq(fm.items
                         .iter()
-                        .map(|foreign_item| tcx.hir().local_def_id(foreign_item.id).index))
+                        .map(|foreign_item| tcx.hir().local_def_id_from_hir_id(
+                            foreign_item.hir_id).index))
                 }
                 hir::ItemKind::Enum(..) => {
                     let def = self.tcx.adt_def(def_id);
@@ -1609,7 +1614,7 @@ fn encode_info_for_foreign_item(&mut self,
 
         Entry {
             kind,
-            visibility: self.lazy(&ty::Visibility::from_hir(&nitem.vis, nitem.id, tcx)),
+            visibility: self.lazy(&ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, tcx)),
             span: self.lazy(&nitem.span),
             attributes: self.encode_attributes(&nitem.attrs),
             children: LazySeq::empty(),
@@ -1645,7 +1650,7 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
     }
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         intravisit::walk_item(self, item);
-        let def_id = self.index.tcx.hir().local_def_id(item.id);
+        let def_id = self.index.tcx.hir().local_def_id_from_hir_id(item.hir_id);
         match item.node {
             hir::ItemKind::ExternCrate(_) |
             hir::ItemKind::Use(..) => (), // ignore these
@@ -1655,7 +1660,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
     }
     fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) {
         intravisit::walk_foreign_item(self, ni);
-        let def_id = self.index.tcx.hir().local_def_id(ni.id);
+        let def_id = self.index.tcx.hir().local_def_id_from_hir_id(ni.hir_id);
         self.index.record(def_id,
                           IsolatedEncoder::encode_info_for_foreign_item,
                           (def_id, ni));
@@ -1741,7 +1746,7 @@ fn encode_info_for_expr(&mut self, expr: &hir::Expr) {
     /// so it's easier to do that here then to wait until we would encounter
     /// normally in the visitor walk.
     fn encode_addl_info_for_item(&mut self, item: &hir::Item) {
-        let def_id = self.tcx.hir().local_def_id(item.id);
+        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
         match item.node {
             hir::ItemKind::Static(..) |
             hir::ItemKind::Const(..) |
@@ -1771,7 +1776,7 @@ fn encode_addl_info_for_item(&mut self, item: &hir::Item) {
 
                 // If the struct has a constructor, encode it.
                 if !struct_def.is_struct() {
-                    let ctor_def_id = self.tcx.hir().local_def_id(struct_def.id());
+                    let ctor_def_id = self.tcx.hir().local_def_id_from_hir_id(struct_def.hir_id());
                     self.record(ctor_def_id,
                                 IsolatedEncoder::encode_struct_ctor,
                                 (def_id, ctor_def_id));
@@ -1806,7 +1811,7 @@ struct ImplVisitor<'a, 'tcx: 'a> {
 impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'a, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
         if let hir::ItemKind::Impl(..) = item.node {
-            let impl_id = self.tcx.hir().local_def_id(item.id);
+            let impl_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
             if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) {
                 self.impls
                     .entry(trait_ref.def_id)
index 2c03bd6659f277551567598a28a443320902908c..284f6796145a8a3487460ede44b661cd3e8e1c0d 100644 (file)
@@ -25,11 +25,11 @@ fn visit_item(&mut self, it: &'tcx hir::Item) {
         };
 
         let foreign_items = fm.items.iter()
-            .map(|it| self.tcx.hir().local_def_id(it.id))
+            .map(|it| self.tcx.hir().local_def_id_from_hir_id(it.hir_id))
             .collect();
         self.modules.push(ForeignModule {
             foreign_items,
-            def_id: self.tcx.hir().local_def_id(it.id),
+            def_id: self.tcx.hir().local_def_id_from_hir_id(it.hir_id),
         });
     }
 
index 3e2571fc0b39c0ffd2dc88d2c57fdcf523c40c37..8343171b99f4b6f38d5195592c7e123312429dd0 100644 (file)
@@ -215,10 +215,10 @@ fn read(&self, _tcx: TyCtxt<'_, '_, '_>) {}
 /// HIR node that doesn't carry its own ID. This will allow an
 /// arbitrary `T` to be passed in, but register a read on the given
 /// `NodeId`.
-pub struct FromId<T>(pub ast::NodeId, pub T);
+pub struct FromId<T>(pub hir::HirId, pub T);
 
 impl<T> DepGraphRead for FromId<T> {
     fn read(&self, tcx: TyCtxt<'_, '_, '_>) {
-        tcx.hir().read(self.0);
+        tcx.hir().read_by_hir_id(self.0);
     }
 }
index 6a1aada5ac7063d8a31825819c89ee3c02fe44d2..81878c4f687b6df0797527264ad082f2c71e679c 100644 (file)
 
 use log::{debug, info, warn};
 
+#[derive(Clone)]
 pub struct CrateMismatch {
     path: PathBuf,
     got: String,
 }
 
+#[derive(Clone)]
 pub struct Context<'a> {
     pub sess: &'a Session,
     pub span: Span,
@@ -258,7 +260,7 @@ pub struct Context<'a> {
     pub extra_filename: Option<&'a str>,
     // points to either self.sess.target.target or self.sess.host, must match triple
     pub target: &'a Target,
-    pub triple: &'a TargetTriple,
+    pub triple: TargetTriple,
     pub filesearch: FileSearch<'a>,
     pub root: &'a Option<CratePaths>,
     pub rejected_via_hash: Vec<CrateMismatch>,
@@ -302,6 +304,14 @@ fn paths(&self) -> Vec<PathBuf> {
 }
 
 impl<'a> Context<'a> {
+    pub fn reset(&mut self) {
+        self.rejected_via_hash.clear();
+        self.rejected_via_triple.clear();
+        self.rejected_via_kind.clear();
+        self.rejected_via_version.clear();
+        self.rejected_via_filename.clear();
+    }
+
     pub fn maybe_load_library_crate(&mut self) -> Option<Library> {
         let mut seen_paths = FxHashSet::default();
         match self.extra_filename {
@@ -399,7 +409,7 @@ pub fn report_errs(&mut self) -> ! {
                                            add);
 
             if (self.ident == "std" || self.ident == "core")
-                && self.triple != &TargetTriple::from_triple(config::host_triple()) {
+                && self.triple != TargetTriple::from_triple(config::host_triple()) {
                 err.note(&format!("the `{}` target may not be installed", self.triple));
             }
             err.span_label(self.span, "can't find crate");
@@ -718,7 +728,7 @@ fn crate_matches(&mut self, metadata: &MetadataBlob, libpath: &Path) -> Option<S
             }
         }
 
-        if &root.triple != self.triple {
+        if root.triple != self.triple {
             info!("Rejecting via crate triple: expected {} got {}",
                   self.triple,
                   root.triple);
index 118fb203c69a1ad3f6e50ce35503a5fdfc580a36..23898387cba4677680027793ec6fce3d0108b455 100644 (file)
@@ -56,7 +56,7 @@ fn visit_item(&mut self, it: &'tcx hir::Item) {
                 name: None,
                 kind: cstore::NativeUnknown,
                 cfg: None,
-                foreign_module: Some(self.tcx.hir().local_def_id(it.id)),
+                foreign_module: Some(self.tcx.hir().local_def_id_from_hir_id(it.hir_id)),
                 wasm_import_module: None,
             };
             let mut kind_specified = false;
index af79ea37dff55eb9010ce826109923ab024685b4..afeea9947b5e3ecb149f9f42ecc1c0f7cdd13410 100644 (file)
@@ -187,6 +187,7 @@ pub struct CrateRoot {
     pub has_default_lib_allocator: bool,
     pub plugin_registrar_fn: Option<DefIndex>,
     pub proc_macro_decls_static: Option<DefIndex>,
+    pub proc_macro_stability: Option<attr::Stability>,
 
     pub crate_deps: LazySeq<CrateDep>,
     pub dylib_dependency_formats: LazySeq<Option<LinkagePreference>>,
index 84fdbb9423e0a2259cb609b24fe2a0bfd19c580b..2d3800dd1dda86d28f87e2a8d312e39825ab71e6 100644 (file)
@@ -2,7 +2,6 @@
 use crate::borrow_check::location::{LocationIndex, LocationTable};
 use crate::borrow_check::nll::facts::AllFactsExt;
 use crate::borrow_check::nll::type_check::{MirTypeckResults, MirTypeckRegionConstraints};
-use crate::borrow_check::nll::type_check::liveness::liveness_map::NllLivenessMap;
 use crate::borrow_check::nll::region_infer::values::RegionValueElements;
 use crate::dataflow::indexes::BorrowIndex;
 use crate::dataflow::move_paths::MoveData;
index cc01f632e075cac4210a3b0b40c7169058a55d66..fdede054e15f304516dffe2c3c5d9f233c6363b7 100644 (file)
@@ -604,7 +604,14 @@ fn try_match_adt_and_generic_args<'hir>(
                     search_stack.push((ty, hir_ty));
                 }
 
-                (UnpackedKind::Lifetime(_), _) | (UnpackedKind::Type(_), _) => {
+                (UnpackedKind::Const(_ct), hir::GenericArg::Const(_hir_ct)) => {
+                    // Lifetimes cannot be found in consts, so we don't need
+                    // to search anything here.
+                }
+
+                (UnpackedKind::Lifetime(_), _)
+                | (UnpackedKind::Type(_), _)
+                | (UnpackedKind::Const(_), _) => {
                     // I *think* that HIR lowering should ensure this
                     // doesn't happen, even in erroneous
                     // programs. Else we should use delay-span-bug.
index 785f810d9415907fd89da70fae1e9c5fa3c62bdf..f0d3a0d2986e53bda4a3ae1b9e3aae5a0bc1c37d 100644 (file)
@@ -1357,7 +1357,6 @@ pub trait ClosureRegionRequirementsExt<'gcx, 'tcx> {
     fn apply_requirements(
         &self,
         tcx: TyCtxt<'_, 'gcx, 'tcx>,
-        location: Location,
         closure_def_id: DefId,
         closure_substs: SubstsRef<'tcx>,
     ) -> Vec<QueryRegionConstraint<'tcx>>;
@@ -1388,13 +1387,12 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi
     fn apply_requirements(
         &self,
         tcx: TyCtxt<'_, 'gcx, 'tcx>,
-        location: Location,
         closure_def_id: DefId,
         closure_substs: SubstsRef<'tcx>,
     ) -> Vec<QueryRegionConstraint<'tcx>> {
         debug!(
-            "apply_requirements(location={:?}, closure_def_id={:?}, closure_substs={:?})",
-            location, closure_def_id, closure_substs
+            "apply_requirements(closure_def_id={:?}, closure_substs={:?})",
+            closure_def_id, closure_substs
         );
 
         // Extract the values of the free regions in `closure_substs`
index ef27fdbde387fa0c17ad82d84041ceeebba88aa7..c4491778162f43ff66a6b258da102dc7105687ba 100644 (file)
@@ -154,10 +154,10 @@ impl<N: Idx> LivenessValues<N> {
     /// Creates a new set of "region values" that tracks causal information.
     /// Each of the regions in num_region_variables will be initialized with an
     /// empty set of points and no causal information.
-    crate fn new(elements: &Rc<RegionValueElements>) -> Self {
+    crate fn new(elements: Rc<RegionValueElements>) -> Self {
         Self {
-            elements: elements.clone(),
             points: SparseBitMatrix::new(elements.num_points),
+            elements: elements,
         }
     }
 
index eab9e0ae171ed229c8b14a4bd5f326634dcfaeea..0a0a88e694260c19dfa6ec995913d99e0fb10717 100644 (file)
@@ -47,6 +47,14 @@ fn renumber_regions<T>(&mut self, value: &T) -> T
 }
 
 impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
+    fn visit_mir(&mut self, mir: &mut Mir<'tcx>) {
+        for promoted in mir.promoted.iter_mut() {
+            self.visit_mir(promoted);
+        }
+
+        self.super_mir(mir);
+    }
+
     fn visit_ty(&mut self, ty: &mut Ty<'tcx>, ty_context: TyContext) {
         debug!("visit_ty(ty={:?}, ty_context={:?})", ty, ty_context);
 
index 1a72205ad7ae1ba0e3e4c7a7fb3e767b9a2c7d12..bef159e996b8778a60902d2a71d7c7116a992f5c 100644 (file)
@@ -99,6 +99,11 @@ pub(super) fn convert(&mut self, query_constraint: &QueryRegionConstraint<'tcx>)
                     param_env,
                 ).type_must_outlive(origin, t1, r2);
             }
+
+            UnpackedKind::Const(_) => {
+                // Consts cannot outlive one another, so we
+                // don't need to handle any relations here.
+            }
         }
     }
 
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs
deleted file mode 100644 (file)
index b9f9d83..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-//! For the NLL computation, we need to compute liveness, but only for those
-//! local variables whose types contain regions. The others are not of interest
-//! to us. This file defines a new index type (LiveVar) that indexes into
-//! a list of "variables whose type contain regions". It also defines a map from
-//! Local to LiveVar and vice versa -- this map can be given to the
-//! liveness code so that it only operates over variables with regions in their
-//! types, instead of all variables.
-
-use crate::borrow_check::nll::ToRegionVid;
-use crate::borrow_check::nll::facts::{AllFacts, AllFactsExt};
-use crate::util::liveness::LiveVariableMap;
-use rustc::mir::{Local, Mir};
-use rustc::ty::{RegionVid, TyCtxt};
-use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::indexed_vec::{Idx, IndexVec};
-
-/// Map between Local and LiveVar indices: the purpose of this
-/// map is to define the subset of local variables for which we need
-/// to do a liveness computation. We only need to compute whether a
-/// variable `X` is live if that variable contains some region `R` in
-/// its type where `R` is not known to outlive a free region (i.e.,
-/// where `R` may be valid for just a subset of the fn body).
-crate struct NllLivenessMap {
-    /// For each local variable, contains `Some(i)` if liveness is
-    /// needed for this variable.
-    pub from_local: IndexVec<Local, Option<LiveVar>>,
-
-    /// For each `LiveVar`, maps back to the original `Local` index.
-    pub to_local: IndexVec<LiveVar, Local>,
-}
-
-impl LiveVariableMap for NllLivenessMap {
-    fn from_local(&self, local: Local) -> Option<Self::LiveVar> {
-        self.from_local[local]
-    }
-
-    type LiveVar = LiveVar;
-
-    fn from_live_var(&self, local: Self::LiveVar) -> Local {
-        self.to_local[local]
-    }
-
-    fn num_variables(&self) -> usize {
-        self.to_local.len()
-    }
-}
-
-impl NllLivenessMap {
-    crate fn compute(
-        tcx: TyCtxt<'_, '_, 'tcx>,
-        free_regions: &FxHashSet<RegionVid>,
-        mir: &Mir<'tcx>,
-    ) -> Self {
-        let mut to_local = IndexVec::default();
-        let facts_enabled = AllFacts::enabled(tcx);
-        let from_local: IndexVec<Local, Option<_>> = mir.local_decls
-            .iter_enumerated()
-            .map(|(local, local_decl)| {
-                if tcx.all_free_regions_meet(&local_decl.ty, |r| {
-                    free_regions.contains(&r.to_region_vid())
-                }) && !facts_enabled {
-                    // If all the regions in the type are free regions
-                    // (or there are no regions), then we don't need
-                    // to track liveness for this variable.
-                    None
-                } else {
-                    Some(to_local.push(local))
-                }
-            })
-            .collect();
-
-        debug!("{} total variables", mir.local_decls.len());
-        debug!("{} variables need liveness", to_local.len());
-        debug!("{} regions outlive free regions", free_regions.len());
-
-        Self {
-            from_local,
-            to_local,
-        }
-    }
-
-    /// Returns `true` if there are no local variables that need liveness computation.
-    crate fn is_empty(&self) -> bool {
-        self.to_local.is_empty()
-    }
-}
-
-/// Index given to each local variable for which we need to
-/// compute liveness information. For many locals, we are able to
-/// skip liveness information: for example, those variables whose
-/// types contain no regions.
-newtype_index! {
-    pub struct LiveVar { .. }
-}
index e9765d2798cd73aa0ac3a5f8dae93f9519b0d963..9b8940098852c1bcb1f71aac390a8e31f57eadd3 100644 (file)
@@ -1,6 +1,5 @@
 use crate::borrow_check::nll::region_infer::values::{PointIndex, RegionValueElements};
-use crate::borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap};
-use crate::util::liveness::{categorize, DefUse, LiveVariableMap};
+use crate::util::liveness::{categorize, DefUse};
 use rustc::mir::visit::{PlaceContext, Visitor};
 use rustc::mir::{Local, Location, Mir};
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
@@ -9,26 +8,33 @@
 /// A map that cross references each local with the locations where it
 /// is defined (assigned), used, or dropped. Used during liveness
 /// computation.
-crate struct LocalUseMap<'me> {
-    liveness_map: &'me NllLivenessMap,
-
+///
+/// We keep track only of `Local`s we'll do the liveness analysis later,
+/// this means that our internal `IndexVec`s will only be sparsely populated.
+/// In the time-memory trade-off between keeping compact vectors with new
+/// indexes (and needing to continuously map the `Local` index to its compact
+/// counterpart) and having `IndexVec`s that we only use a fraction of, time
+/// (and code simplicity) was favored. The rationale is that we only keep
+/// a small number of `IndexVec`s throughout the entire analysis while, in
+/// contrast, we're accessing each `Local` *many* times.
+crate struct LocalUseMap {
     /// Head of a linked list of **definitions** of each variable --
     /// definition in this context means assignment, e.g., `x` is
     /// defined in `x = y` but not `y`; that first def is the head of
     /// a linked list that lets you enumerate all places the variable
     /// is assigned.
-    first_def_at: IndexVec<LiveVar, Option<AppearanceIndex>>,
+    first_def_at: IndexVec<Local, Option<AppearanceIndex>>,
 
     /// Head of a linked list of **uses** of each variable -- use in
     /// this context means that the existing value of the variable is
     /// read or modified. e.g., `y` is used in `x = y` but not `x`.
     /// Note that `DROP(x)` terminators are excluded from this list.
-    first_use_at: IndexVec<LiveVar, Option<AppearanceIndex>>,
+    first_use_at: IndexVec<Local, Option<AppearanceIndex>>,
 
     /// Head of a linked list of **drops** of each variable -- these
     /// are a special category of uses corresponding to the drop that
     /// we add for each local variable.
-    first_drop_at: IndexVec<LiveVar, Option<AppearanceIndex>>,
+    first_drop_at: IndexVec<Local, Option<AppearanceIndex>>,
 
     appearances: IndexVec<AppearanceIndex, Appearance>,
 }
@@ -50,52 +56,68 @@ fn next(elem: &Self) -> Option<AppearanceIndex> {
     }
 }
 
-impl LocalUseMap<'me> {
+impl LocalUseMap {
     crate fn build(
-        liveness_map: &'me NllLivenessMap,
+        live_locals: &Vec<Local>,
         elements: &RegionValueElements,
         mir: &Mir<'_>,
     ) -> Self {
-        let nones = IndexVec::from_elem_n(None, liveness_map.num_variables());
+        let nones = IndexVec::from_elem_n(None, mir.local_decls.len());
         let mut local_use_map = LocalUseMap {
-            liveness_map,
             first_def_at: nones.clone(),
             first_use_at: nones.clone(),
             first_drop_at: nones,
             appearances: IndexVec::new(),
         };
 
+        let mut locals_with_use_data: IndexVec<Local, bool> =
+            IndexVec::from_elem_n(false, mir.local_decls.len());
+        live_locals
+            .iter()
+            .for_each(|&local| locals_with_use_data[local] = true);
+
         LocalUseMapBuild {
             local_use_map: &mut local_use_map,
             elements,
-        }.visit_mir(mir);
+            locals_with_use_data,
+        }
+        .visit_mir(mir);
 
         local_use_map
     }
 
-    crate fn defs(&self, local: LiveVar) -> impl Iterator<Item = PointIndex> + '_ {
+    crate fn defs(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
         vll::iter(self.first_def_at[local], &self.appearances)
             .map(move |aa| self.appearances[aa].point_index)
     }
 
-    crate fn uses(&self, local: LiveVar) -> impl Iterator<Item = PointIndex> + '_ {
+    crate fn uses(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
         vll::iter(self.first_use_at[local], &self.appearances)
             .map(move |aa| self.appearances[aa].point_index)
     }
 
-    crate fn drops(&self, local: LiveVar) -> impl Iterator<Item = PointIndex> + '_ {
+    crate fn drops(&self, local: Local) -> impl Iterator<Item = PointIndex> + '_ {
         vll::iter(self.first_drop_at[local], &self.appearances)
             .map(move |aa| self.appearances[aa].point_index)
     }
 }
 
-struct LocalUseMapBuild<'me, 'map: 'me> {
-    local_use_map: &'me mut LocalUseMap<'map>,
+struct LocalUseMapBuild<'me> {
+    local_use_map: &'me mut LocalUseMap,
     elements: &'me RegionValueElements,
+
+    // Vector used in `visit_local` to signal which `Local`s do we need
+    // def/use/drop information on, constructed from `live_locals` (that
+    // contains the variables we'll do the liveness analysis for).
+    // This vector serves optimization purposes only: we could have
+    // obtained the same information from `live_locals` but we want to
+    // avoid repeatedly calling `Vec::contains()` (see `LocalUseMap` for
+    // the rationale on the time-memory trade-off we're favoring here).
+    locals_with_use_data: IndexVec<Local, bool>,
 }
 
-impl LocalUseMapBuild<'_, '_> {
-    fn insert_def(&mut self, local: LiveVar, location: Location) {
+impl LocalUseMapBuild<'_> {
+    fn insert_def(&mut self, local: Local, location: Location) {
         Self::insert(
             self.elements,
             &mut self.local_use_map.first_def_at[local],
@@ -104,7 +126,7 @@ fn insert_def(&mut self, local: LiveVar, location: Location) {
         );
     }
 
-    fn insert_use(&mut self, local: LiveVar, location: Location) {
+    fn insert_use(&mut self, local: Local, location: Location) {
         Self::insert(
             self.elements,
             &mut self.local_use_map.first_use_at[local],
@@ -113,7 +135,7 @@ fn insert_use(&mut self, local: LiveVar, location: Location) {
         );
     }
 
-    fn insert_drop(&mut self, local: LiveVar, location: Location) {
+    fn insert_drop(&mut self, local: Local, location: Location) {
         Self::insert(
             self.elements,
             &mut self.local_use_map.first_drop_at[local],
@@ -137,13 +159,13 @@ fn insert(
     }
 }
 
-impl Visitor<'tcx> for LocalUseMapBuild<'_, '_> {
+impl Visitor<'tcx> for LocalUseMapBuild<'_> {
     fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, location: Location) {
-        if let Some(local_with_region) = self.local_use_map.liveness_map.from_local(local) {
+        if self.locals_with_use_data[local] {
             match categorize(context) {
-                Some(DefUse::Def) => self.insert_def(local_with_region, location),
-                Some(DefUse::Use) => self.insert_use(local_with_region, location),
-                Some(DefUse::Drop) => self.insert_drop(local_with_region, location),
+                Some(DefUse::Def) => self.insert_def(local, location),
+                Some(DefUse::Use) => self.insert_use(local, location),
+                Some(DefUse::Drop) => self.insert_drop(local, location),
                 _ => (),
             }
         }
index 28a8cad8ca20059ff577517c3d296646bd4eddf6..960e75048fa1614d112fb2ec9d1a5da4862b320b 100644 (file)
@@ -1,19 +1,19 @@
 use crate::borrow_check::location::LocationTable;
-use crate::borrow_check::nll::region_infer::values::RegionValueElements;
 use crate::borrow_check::nll::constraints::ConstraintSet;
-use crate::borrow_check::nll::NllLivenessMap;
+use crate::borrow_check::nll::facts::{AllFacts, AllFactsExt};
+use crate::borrow_check::nll::region_infer::values::RegionValueElements;
 use crate::borrow_check::nll::universal_regions::UniversalRegions;
+use crate::borrow_check::nll::ToRegionVid;
 use crate::dataflow::move_paths::MoveData;
-use crate::dataflow::MaybeInitializedPlaces;
 use crate::dataflow::FlowAtLocation;
-use rustc::mir::Mir;
-use rustc::ty::RegionVid;
+use crate::dataflow::MaybeInitializedPlaces;
+use rustc::mir::{Local, Mir};
+use rustc::ty::{RegionVid, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
 use std::rc::Rc;
 
 use super::TypeChecker;
 
-crate mod liveness_map;
 mod local_use_map;
 mod trace;
 
@@ -34,16 +34,71 @@ pub(super) fn generate<'gcx, 'tcx>(
     location_table: &LocationTable,
 ) {
     debug!("liveness::generate");
-    let free_regions = {
-        let borrowck_context = typeck.borrowck_context.as_ref().unwrap();
-        regions_that_outlive_free_regions(
-            typeck.infcx.num_region_vars(),
-            &borrowck_context.universal_regions,
-            &borrowck_context.constraints.outlives_constraints,
-        )
+
+    let live_locals: Vec<Local> = if AllFacts::enabled(typeck.tcx()) {
+        // If "dump facts from NLL analysis" was requested perform
+        // the liveness analysis for all `Local`s. This case opens
+        // the possibility of the variables being analyzed in `trace`
+        // to be *any* `Local`, not just the "live" ones, so we can't
+        // make any assumptions past this point as to the characteristics
+        // of the `live_locals`.
+        // FIXME: Review "live" terminology past this point, we should
+        // not be naming the `Local`s as live.
+        mir.local_decls.indices().collect()
+    } else {
+        let free_regions = {
+            let borrowck_context = typeck.borrowck_context.as_ref().unwrap();
+            regions_that_outlive_free_regions(
+                typeck.infcx.num_region_vars(),
+                &borrowck_context.universal_regions,
+                &borrowck_context.constraints.outlives_constraints,
+            )
+        };
+        compute_live_locals(typeck.tcx(), &free_regions, mir)
     };
-    let liveness_map = NllLivenessMap::compute(typeck.tcx(), &free_regions, mir);
-    trace::trace(typeck, mir, elements, flow_inits, move_data, &liveness_map, location_table);
+
+    if !live_locals.is_empty() {
+        trace::trace(
+            typeck,
+            mir,
+            elements,
+            flow_inits,
+            move_data,
+            live_locals,
+            location_table,
+        );
+    }
+}
+
+// The purpose of `compute_live_locals` is to define the subset of `Local`
+// variables for which we need to do a liveness computation. We only need
+// to compute whether a variable `X` is live if that variable contains
+// some region `R` in its type where `R` is not known to outlive a free
+// region (i.e., where `R` may be valid for just a subset of the fn body).
+fn compute_live_locals(
+    tcx: TyCtxt<'_, '_, 'tcx>,
+    free_regions: &FxHashSet<RegionVid>,
+    mir: &Mir<'tcx>,
+) -> Vec<Local> {
+    let live_locals: Vec<Local> = mir
+        .local_decls
+        .iter_enumerated()
+        .filter_map(|(local, local_decl)| {
+            if tcx.all_free_regions_meet(&local_decl.ty, |r| {
+                free_regions.contains(&r.to_region_vid())
+            }) {
+                None
+            } else {
+                Some(local)
+            }
+        })
+        .collect();
+
+    debug!("{} total variables", mir.local_decls.len());
+    debug!("{} variables need liveness", live_locals.len());
+    debug!("{} regions outlive free regions", free_regions.len());
+
+    live_locals
 }
 
 /// Computes all regions that are (currently) known to outlive free
index 4a0b4b7c205c65a93db5a10126f30cb6e68feec7..f0df7070e6b5ab41799f5d965dd014ab0849b719 100644 (file)
@@ -1,13 +1,11 @@
 use crate::borrow_check::location::LocationTable;
 use crate::borrow_check::nll::region_infer::values::{self, PointIndex, RegionValueElements};
-use crate::borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap};
 use crate::borrow_check::nll::type_check::liveness::local_use_map::LocalUseMap;
 use crate::borrow_check::nll::type_check::NormalizeLocation;
 use crate::borrow_check::nll::type_check::TypeChecker;
 use crate::dataflow::move_paths::indexes::MovePathIndex;
 use crate::dataflow::move_paths::MoveData;
 use crate::dataflow::{FlowAtLocation, FlowsAtLocation, MaybeInitializedPlaces};
-use crate::util::liveness::LiveVariableMap;
 use rustc::infer::canonical::QueryRegionConstraint;
 use rustc::mir::{BasicBlock, ConstraintCategory, Local, Location, Mir};
 use rustc::traits::query::dropck_outlives::DropckOutlivesResult;
@@ -38,16 +36,12 @@ pub(super) fn trace(
     elements: &Rc<RegionValueElements>,
     flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
     move_data: &MoveData<'tcx>,
-    liveness_map: &NllLivenessMap,
+    live_locals: Vec<Local>,
     location_table: &LocationTable,
 ) {
     debug!("trace()");
 
-    if liveness_map.is_empty() {
-        return;
-    }
-
-    let local_use_map = &LocalUseMap::build(liveness_map, elements, mir);
+    let local_use_map = &LocalUseMap::build(&live_locals, elements, mir);
 
     let cx = LivenessContext {
         typeck,
@@ -56,12 +50,11 @@ pub(super) fn trace(
         elements,
         local_use_map,
         move_data,
-        liveness_map,
         drop_data: FxHashMap::default(),
         location_table,
     };
 
-    LivenessResults::new(cx).compute_for_all_locals();
+    LivenessResults::new(cx).compute_for_all_locals(live_locals);
 }
 
 /// Contextual state for the type-liveness generator.
@@ -93,10 +86,7 @@ struct LivenessContext<'me, 'typeck, 'flow, 'gcx, 'tcx>
 
     /// Index indicating where each variable is assigned, used, or
     /// dropped.
-    local_use_map: &'me LocalUseMap<'me>,
-
-    /// Map tracking which variables need liveness computation.
-    liveness_map: &'me NllLivenessMap,
+    local_use_map: &'me LocalUseMap,
 
     /// Maps between a MIR Location and a LocationIndex
     location_table: &'me LocationTable,
@@ -148,15 +138,12 @@ fn new(cx: LivenessContext<'me, 'typeck, 'flow, 'gcx, 'tcx>) -> Self {
         }
     }
 
-    fn compute_for_all_locals(&mut self) {
-        for live_local in self.cx.liveness_map.to_local.indices() {
-            let local = self.cx.liveness_map.from_live_var(live_local);
-            debug!("local={:?} live_local={:?}", local, live_local);
-
+    fn compute_for_all_locals(&mut self, live_locals: Vec<Local>) {
+        for local in live_locals {
             self.reset_local_state();
-            self.add_defs_for(live_local);
-            self.compute_use_live_points_for(live_local);
-            self.compute_drop_live_points_for(live_local);
+            self.add_defs_for(local);
+            self.compute_use_live_points_for(local);
+            self.compute_drop_live_points_for(local);
 
             let local_ty = self.cx.mir.local_decls[local].ty;
 
@@ -185,8 +172,8 @@ fn reset_local_state(&mut self) {
     }
 
     /// Adds the definitions of `local` into `self.defs`.
-    fn add_defs_for(&mut self, live_local: LiveVar) {
-        for def in self.cx.local_use_map.defs(live_local) {
+    fn add_defs_for(&mut self, local: Local) {
+        for def in self.cx.local_use_map.defs(local) {
             debug!("- defined at {:?}", def);
             self.defs.insert(def);
         }
@@ -194,14 +181,14 @@ fn add_defs_for(&mut self, live_local: LiveVar) {
 
     /// Computes all points where local is "use live" -- meaning its
     /// current value may be used later (except by a drop). This is
-    /// done by walking backwards from each use of `live_local` until we
+    /// done by walking backwards from each use of `local` until we
     /// find a `def` of local.
     ///
-    /// Requires `add_defs_for(live_local)` to have been executed.
-    fn compute_use_live_points_for(&mut self, live_local: LiveVar) {
-        debug!("compute_use_live_points_for(live_local={:?})", live_local);
+    /// Requires `add_defs_for(local)` to have been executed.
+    fn compute_use_live_points_for(&mut self, local: Local) {
+        debug!("compute_use_live_points_for(local={:?})", local);
 
-        self.stack.extend(self.cx.local_use_map.uses(live_local));
+        self.stack.extend(self.cx.local_use_map.uses(local));
         while let Some(p) = self.stack.pop() {
             if self.defs.contains(p) {
                 continue;
@@ -224,15 +211,14 @@ fn compute_use_live_points_for(&mut self, live_local: LiveVar) {
     ///
     /// Requires `compute_use_live_points_for` and `add_defs_for` to
     /// have been executed.
-    fn compute_drop_live_points_for(&mut self, live_local: LiveVar) {
-        debug!("compute_drop_live_points_for(live_local={:?})", live_local);
+    fn compute_drop_live_points_for(&mut self, local: Local) {
+        debug!("compute_drop_live_points_for(local={:?})", local);
 
-        let local = self.cx.liveness_map.from_live_var(live_local);
         let mpi = self.cx.move_data.rev_lookup.find_local(local);
         debug!("compute_drop_live_points_for: mpi = {:?}", mpi);
 
         // Find the drops where `local` is initialized.
-        for drop_point in self.cx.local_use_map.drops(live_local) {
+        for drop_point in self.cx.local_use_map.drops(local) {
             let location = self.cx.elements.to_location(drop_point);
             debug_assert_eq!(self.cx.mir.terminator_loc(location.block), location,);
 
index cf054c2d05505d73586b92d33403bed420f46318..5b444ab9690ca7dcb76be567974639aa7097b78f 100644 (file)
@@ -27,6 +27,7 @@
 use rustc::infer::canonical::QueryRegionConstraint;
 use rustc::infer::outlives::env::RegionBoundPairs;
 use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin};
+use rustc::infer::type_variable::TypeVariableOrigin;
 use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
 use rustc::mir::tcx::PlaceTy;
 use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext};
 use rustc::ty::subst::{Subst, SubstsRef, UnpackedKind, UserSubsts};
 use rustc::ty::{
     self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind, UserType,
-    CanonicalUserTypeAnnotation, UserTypeAnnotationIndex,
+    CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
+    UserTypeAnnotationIndex,
 };
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use rustc::ty::layout::VariantIdx;
 use std::rc::Rc;
-use std::{fmt, iter};
+use std::{fmt, iter, mem};
 use syntax_pos::{Span, DUMMY_SP};
 
 macro_rules! span_mirbug {
@@ -124,7 +126,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
     let mut constraints = MirTypeckRegionConstraints {
         placeholder_indices: PlaceholderIndices::default(),
         placeholder_index_to_region: IndexVec::default(),
-        liveness_constraints: LivenessValues::new(elements),
+        liveness_constraints: LivenessValues::new(elements.clone()),
         outlives_constraints: ConstraintSet::default(),
         closure_bounds_mapping: Default::default(),
         type_tests: Vec::default(),
@@ -253,7 +255,7 @@ enum FieldAccessError {
 /// is a problem.
 struct TypeVerifier<'a, 'b: 'a, 'gcx: 'tcx, 'tcx: 'b> {
     cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>,
-    mir: &'a Mir<'tcx>,
+    mir: &'b Mir<'tcx>,
     last_span: Span,
     mir_def_id: DefId,
     errors_reported: bool,
@@ -283,7 +285,7 @@ fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
                 location.to_locations(),
                 ConstraintCategory::Boring,
             ) {
-                let annotation = &self.mir.user_type_annotations[annotation_index];
+                let annotation = &self.cx.user_type_annotations[annotation_index];
                 span_mirbug!(
                     self,
                     constant,
@@ -385,7 +387,7 @@ fn visit_mir(&mut self, mir: &Mir<'tcx>) {
 }
 
 impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
-    fn new(cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>, mir: &'a Mir<'tcx>) -> Self {
+    fn new(cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>, mir: &'b Mir<'tcx>) -> Self {
         TypeVerifier {
             mir,
             mir_def_id: cx.mir_def_id,
@@ -454,19 +456,31 @@ fn sanitize_place(
             Place::Base(PlaceBase::Local(index)) => PlaceTy::Ty {
                 ty: self.mir.local_decls[index].ty,
             },
-            Place::Base(PlaceBase::Promoted(box (_index, sty))) => {
+            Place::Base(PlaceBase::Promoted(box (index, sty))) => {
                 let sty = self.sanitize_type(place, sty);
-                // FIXME -- promoted MIR return types reference
-                // various "free regions" (e.g., scopes and things)
-                // that they ought not to do. We have to figure out
-                // how best to handle that -- probably we want treat
-                // promoted MIR much like closures, renumbering all
-                // their free regions and propagating constraints
-                // upwards. We have the same acyclic guarantees, so
-                // that should be possible. But for now, ignore them.
-                //
-                // let promoted_mir = &self.mir.promoted[index];
-                // promoted_mir.return_ty()
+
+                if !self.errors_reported {
+                    let promoted_mir = &self.mir.promoted[index];
+                    self.sanitize_promoted(promoted_mir, location);
+
+                    let promoted_ty = promoted_mir.return_ty();
+
+                    if let Err(terr) = self.cx.eq_types(
+                        sty,
+                        promoted_ty,
+                        location.to_locations(),
+                        ConstraintCategory::Boring,
+                    ) {
+                        span_mirbug!(
+                            self,
+                            place,
+                            "bad promoted type ({:?}: {:?}): {:?}",
+                            promoted_ty,
+                            sty,
+                            terr
+                        );
+                    };
+                }
                 PlaceTy::Ty { ty: sty }
             }
             Place::Base(PlaceBase::Static(box Static { def_id, ty: sty })) => {
@@ -533,6 +547,72 @@ fn sanitize_place(
         place_ty
     }
 
+    fn sanitize_promoted(&mut self, promoted_mir: &'b Mir<'tcx>, location: Location) {
+        // Determine the constraints from the promoted MIR by running the type
+        // checker on the promoted MIR, then transfer the constraints back to
+        // the main MIR, changing the locations to the provided location.
+
+        let parent_mir = mem::replace(&mut self.mir, promoted_mir);
+
+        let all_facts = &mut None;
+        let mut constraints = Default::default();
+        let mut closure_bounds = Default::default();
+        if let Some(ref mut bcx) = self.cx.borrowck_context {
+            // Don't try to add borrow_region facts for the promoted MIR
+            mem::swap(bcx.all_facts, all_facts);
+
+            // Use a new sets of constraints and closure bounds so that we can
+            // modify their locations.
+            mem::swap(&mut bcx.constraints.outlives_constraints, &mut constraints);
+            mem::swap(&mut bcx.constraints.closure_bounds_mapping, &mut closure_bounds);
+        };
+
+        self.visit_mir(promoted_mir);
+
+        if !self.errors_reported {
+            // if verifier failed, don't do further checks to avoid ICEs
+            self.cx.typeck_mir(promoted_mir);
+        }
+
+        self.mir = parent_mir;
+        // Merge the outlives constraints back in, at the given location.
+        if let Some(ref mut base_bcx) = self.cx.borrowck_context {
+            mem::swap(base_bcx.all_facts, all_facts);
+            mem::swap(&mut base_bcx.constraints.outlives_constraints, &mut constraints);
+            mem::swap(&mut base_bcx.constraints.closure_bounds_mapping, &mut closure_bounds);
+
+            let locations = location.to_locations();
+            for constraint in constraints.iter() {
+                let mut constraint = *constraint;
+                constraint.locations = locations;
+                if let ConstraintCategory::Return
+                    | ConstraintCategory::UseAsConst
+                    | ConstraintCategory::UseAsStatic = constraint.category
+                {
+                    // "Returning" from a promoted is an assigment to a
+                    // temporary from the user's point of view.
+                    constraint.category = ConstraintCategory::Boring;
+                }
+                base_bcx.constraints.outlives_constraints.push(constraint)
+            }
+
+            if !closure_bounds.is_empty() {
+                let combined_bounds_mapping = closure_bounds
+                    .into_iter()
+                    .flat_map(|(_, value)| value)
+                    .collect();
+                let existing = base_bcx
+                    .constraints
+                    .closure_bounds_mapping
+                    .insert(location, combined_bounds_mapping);
+                assert!(
+                    existing.is_none(),
+                    "Multiple promoteds/closures at the same location."
+                );
+            }
+        }
+    }
+
     fn sanitize_projection(
         &mut self,
         base: PlaceTy<'tcx>,
@@ -738,7 +818,9 @@ struct TypeChecker<'a, 'gcx: 'tcx, 'tcx: 'a> {
     infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
     param_env: ty::ParamEnv<'gcx>,
     last_span: Span,
-    mir: &'a Mir<'tcx>,
+    /// User type annotations are shared between the main MIR and the MIR of
+    /// all of the promoted items.
+    user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
     mir_def_id: DefId,
     region_bound_pairs: &'a RegionBoundPairs<'tcx>,
     implicit_region_bound: Option<ty::Region<'tcx>>,
@@ -893,8 +975,8 @@ fn new(
         let mut checker = Self {
             infcx,
             last_span: DUMMY_SP,
-            mir,
             mir_def_id,
+            user_type_annotations: &mir.user_type_annotations,
             param_env,
             region_bound_pairs,
             implicit_region_bound,
@@ -910,9 +992,9 @@ fn new(
     fn check_user_type_annotations(&mut self) {
         debug!(
             "check_user_type_annotations: user_type_annotations={:?}",
-             self.mir.user_type_annotations
+             self.user_type_annotations
         );
-        for user_annotation in &self.mir.user_type_annotations {
+        for user_annotation in self.user_type_annotations {
             let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
             let (annotation, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars(
                 span, user_ty
@@ -1095,7 +1177,7 @@ fn relate_type_and_user_type(
             a, v, user_ty, locations,
         );
 
-        let annotated_type = self.mir.user_type_annotations[user_ty.base].inferred_ty;
+        let annotated_type = self.user_type_annotations[user_ty.base].inferred_ty;
         let mut curr_projected_ty = PlaceTy::from_ty(annotated_type);
 
         let tcx = self.infcx.tcx;
@@ -1281,7 +1363,7 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca
                         location.to_locations(),
                         ConstraintCategory::Boring,
                     ) {
-                        let annotation = &mir.user_type_annotations[annotation_index];
+                        let annotation = &self.user_type_annotations[annotation_index];
                         span_mirbug!(
                             self,
                             stmt,
@@ -1340,7 +1422,7 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca
                     Locations::All(stmt.source_info.span),
                     ConstraintCategory::TypeAnnotation,
                 ) {
-                    let annotation = &mir.user_type_annotations[projection.base];
+                    let annotation = &self.user_type_annotations[projection.base];
                     span_mirbug!(
                         self,
                         stmt,
@@ -1993,15 +2075,163 @@ fn check_rvalue(&mut self, mir: &Mir<'tcx>, rvalue: &Rvalue<'tcx>, location: Loc
                         );
                     }
 
-                    CastKind::Misc => {}
+                    CastKind::MutToConstPointer => {
+                        let ty_from = match op.ty(mir, tcx).sty {
+                            ty::RawPtr(ty::TypeAndMut {
+                                ty: ty_from,
+                                mutbl: hir::MutMutable,
+                            }) => ty_from,
+                            _ => {
+                                span_mirbug!(
+                                    self,
+                                    rvalue,
+                                    "unexpected base type for cast {:?}",
+                                    ty,
+                                );
+                                return;
+                            }
+                        };
+                        let ty_to = match ty.sty {
+                            ty::RawPtr(ty::TypeAndMut {
+                                ty: ty_to,
+                                mutbl: hir::MutImmutable,
+                            }) => ty_to,
+                            _ => {
+                                span_mirbug!(
+                                    self,
+                                    rvalue,
+                                    "unexpected target type for cast {:?}",
+                                    ty,
+                                );
+                                return;
+                            }
+                        };
+                        if let Err(terr) = self.sub_types(
+                            ty_from,
+                            ty_to,
+                            location.to_locations(),
+                            ConstraintCategory::Cast,
+                        ) {
+                            span_mirbug!(
+                                self,
+                                rvalue,
+                                "relating {:?} with {:?} yields {:?}",
+                                ty_from,
+                                ty_to,
+                                terr
+                            )
+                        }
+                    }
+
+                    CastKind::Misc => {
+                        if let ty::Ref(_, mut ty_from, _) = op.ty(mir, tcx).sty {
+                            let (mut ty_to, mutability) = if let ty::RawPtr(ty::TypeAndMut {
+                                ty: ty_to,
+                                mutbl,
+                            }) = ty.sty {
+                                (ty_to, mutbl)
+                            } else {
+                                span_mirbug!(
+                                    self,
+                                    rvalue,
+                                    "invalid cast types {:?} -> {:?}",
+                                    op.ty(mir, tcx),
+                                    ty,
+                                );
+                                return;
+                            };
+
+                            // Handle the direct cast from `&[T; N]` to `*const T` by unwrapping
+                            // any array we find.
+                            while let ty::Array(ty_elem_from, _) = ty_from.sty {
+                                ty_from = ty_elem_from;
+                                if let ty::Array(ty_elem_to, _) = ty_to.sty {
+                                    ty_to = ty_elem_to;
+                                } else {
+                                    break;
+                                }
+                            }
+
+                            if let hir::MutMutable = mutability {
+                                if let Err(terr) = self.eq_types(
+                                    ty_from,
+                                    ty_to,
+                                    location.to_locations(),
+                                    ConstraintCategory::Cast,
+                                ) {
+                                    span_mirbug!(
+                                        self,
+                                        rvalue,
+                                        "equating {:?} with {:?} yields {:?}",
+                                        ty_from,
+                                        ty_to,
+                                        terr
+                                    )
+                                }
+                            } else {
+                                if let Err(terr) = self.sub_types(
+                                    ty_from,
+                                    ty_to,
+                                    location.to_locations(),
+                                    ConstraintCategory::Cast,
+                                ) {
+                                    span_mirbug!(
+                                        self,
+                                        rvalue,
+                                        "relating {:?} with {:?} yields {:?}",
+                                        ty_from,
+                                        ty_to,
+                                        terr
+                                    )
+                                }
+                            }
+                        }
+                    }
                 }
             }
 
             Rvalue::Ref(region, _borrow_kind, borrowed_place) => {
-                self.add_reborrow_constraint(location, region, borrowed_place);
+                self.add_reborrow_constraint(mir, location, region, borrowed_place);
+            }
+
+            Rvalue::BinaryOp(BinOp::Eq, left, right)
+            | Rvalue::BinaryOp(BinOp::Ne, left, right)
+            | Rvalue::BinaryOp(BinOp::Lt, left, right)
+            | Rvalue::BinaryOp(BinOp::Le, left, right)
+            | Rvalue::BinaryOp(BinOp::Gt, left, right)
+            | Rvalue::BinaryOp(BinOp::Ge, left, right) => {
+                let ty_left = left.ty(mir, tcx);
+                if let ty::RawPtr(_) | ty::FnPtr(_) = ty_left.sty {
+                    let ty_right = right.ty(mir, tcx);
+                    let common_ty = self.infcx.next_ty_var(
+                        TypeVariableOrigin::MiscVariable(mir.source_info(location).span),
+                    );
+                    self.sub_types(
+                        common_ty,
+                        ty_left,
+                        location.to_locations(),
+                        ConstraintCategory::Boring
+                    ).unwrap_or_else(|err| {
+                        bug!("Could not equate type variable with {:?}: {:?}", ty_left, err)
+                    });
+                    if let Err(terr) = self.sub_types(
+                        common_ty,
+                        ty_right,
+                        location.to_locations(),
+                        ConstraintCategory::Boring
+                    ) {
+                        span_mirbug!(
+                            self,
+                            rvalue,
+                            "unexpected comparison types {:?} and {:?} yields {:?}",
+                            ty_left,
+                            ty_right,
+                            terr
+                        )
+                    }
+                }
             }
 
-            // FIXME: These other cases have to be implemented in future PRs
             Rvalue::Use(..)
             | Rvalue::Len(..)
             | Rvalue::BinaryOp(..)
@@ -2097,6 +2327,7 @@ fn check_aggregate_rvalue(
     /// - `borrowed_place`: the place `P` being borrowed
     fn add_reborrow_constraint(
         &mut self,
+        mir: &Mir<'tcx>,
         location: Location,
         borrow_region: ty::Region<'tcx>,
         borrowed_place: &Place<'tcx>,
@@ -2146,7 +2377,7 @@ fn add_reborrow_constraint(
             match *elem {
                 ProjectionElem::Deref => {
                     let tcx = self.infcx.tcx;
-                    let base_ty = base.ty(self.mir, tcx).to_ty(tcx);
+                    let base_ty = base.ty(mir, tcx).to_ty(tcx);
 
                     debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
                     match base_ty.sty {
@@ -2275,7 +2506,7 @@ fn prove_closure_bounds(
     ) -> ty::InstantiatedPredicates<'tcx> {
         if let Some(closure_region_requirements) = tcx.mir_borrowck(def_id).closure_requirements {
             let closure_constraints =
-                closure_region_requirements.apply_requirements(tcx, location, def_id, substs);
+                closure_region_requirements.apply_requirements(tcx, def_id, substs);
 
             if let Some(ref mut borrowck_context) = self.borrowck_context {
                 let bounds_mapping = closure_constraints
@@ -2302,7 +2533,7 @@ fn prove_closure_bounds(
                                     ),
                                 ))
                             }
-                            UnpackedKind::Type(_) => None,
+                            UnpackedKind::Type(_) | UnpackedKind::Const(_) => None,
                         }
                     })
                     .collect();
index 3bea88024b3f93e11f319f40e4dcfa18e543c558..20b95c363f5f7f9b875dff9127386cbf74079958 100644 (file)
@@ -196,6 +196,7 @@ fn expr_as_place(
             | ExprKind::ReifyFnPointer { .. }
             | ExprKind::ClosureFnPointer { .. }
             | ExprKind::UnsafeFnPointer { .. }
+            | ExprKind::MutToConstPointer { .. }
             | ExprKind::Unsize { .. }
             | ExprKind::Repeat { .. }
             | ExprKind::Borrow { .. }
index b00d1c612edf38c0bee77e94c7e79f6ef38a951a..f1a82ecef1b1d60a7b7be427fe186b1bbe3290c7 100644 (file)
@@ -147,8 +147,6 @@ fn expr_as_rvalue(
                 block.and(Rvalue::Use(Operand::Move(Place::Base(PlaceBase::Local(result)))))
             }
             ExprKind::Cast { source } => {
-                let source = this.hir.mirror(source);
-
                 let source = unpack!(block = this.as_operand(block, scope, source));
                 block.and(Rvalue::Cast(CastKind::Misc, source, expr.ty))
             }
@@ -168,6 +166,10 @@ fn expr_as_rvalue(
                 let source = unpack!(block = this.as_operand(block, scope, source));
                 block.and(Rvalue::Cast(CastKind::ClosureFnPointer, source, expr.ty))
             }
+            ExprKind::MutToConstPointer { source } => {
+                let source = unpack!(block = this.as_operand(block, scope, source));
+                block.and(Rvalue::Cast(CastKind::MutToConstPointer, source, expr.ty))
+            }
             ExprKind::Unsize { source } => {
                 let source = unpack!(block = this.as_operand(block, scope, source));
                 block.and(Rvalue::Cast(CastKind::Unsize, source, expr.ty))
index ca7d435e62229aeb2b785d2692953558da8e6015..c8c30ac3ce4d075a0c2238e1193a844a4a2a2695 100644 (file)
@@ -62,6 +62,7 @@ pub fn of<'tcx>(ek: &ExprKind<'tcx>) -> Option<Category> {
             | ExprKind::ReifyFnPointer { .. }
             | ExprKind::ClosureFnPointer { .. }
             | ExprKind::UnsafeFnPointer { .. }
+            | ExprKind::MutToConstPointer { .. }
             | ExprKind::Unsize { .. }
             | ExprKind::Repeat { .. }
             | ExprKind::Borrow { .. }
index d9839e0c6ec5a88871f146d3999637869062067c..4d0418beea4dd72bd6c4c7ced88835573452e64b 100644 (file)
@@ -383,6 +383,7 @@ pub fn into_expr(
             | ExprKind::ReifyFnPointer { .. }
             | ExprKind::ClosureFnPointer { .. }
             | ExprKind::UnsafeFnPointer { .. }
+            | ExprKind::MutToConstPointer { .. }
             | ExprKind::Unsize { .. }
             | ExprKind::Repeat { .. }
             | ExprKind::Borrow { .. }
index e4f85887841ebcc4f488ecb7f0860f028c326fb0..61ead366a87c52121bd843b59e4b2c97dd0369ad 100644 (file)
@@ -229,7 +229,7 @@ fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                      -> Mir<'tcx>
 {
     let span = tcx.hir().span(ctor_id);
-    if let hir::VariantData::Tuple(ref fields, ctor_id, _) = *v {
+    if let hir::VariantData::Tuple(ref fields, ctor_id) = *v {
         tcx.infer_ctxt().enter(|infcx| {
             let mut mir = shim::build_adt_ctor(&infcx, ctor_id, fields, span);
 
@@ -245,7 +245,7 @@ fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             };
 
             mir_util::dump_mir(tcx, None, "mir_map", &0,
-                               MirSource::item(tcx.hir().local_def_id(ctor_id)),
+                               MirSource::item(tcx.hir().local_def_id_from_hir_id(ctor_id)),
                                &mir, |_, _| Ok(()) );
 
             mir
index 0751af9b12affe41a2868170cbeb9e566bc153a8..e70756ad2f251869d047f6f6ce5b959ffffa2269 100644 (file)
@@ -5,7 +5,7 @@
 use crate::hair::util::UserAnnotatedTyHelpers;
 use rustc_data_structures::indexed_vec::Idx;
 use rustc::hir::def::{Def, CtorKind};
-use rustc::mir::interpret::{GlobalId, ErrorHandled};
+use rustc::mir::interpret::{GlobalId, ErrorHandled, ConstValue};
 use rustc::ty::{self, AdtKind, Ty};
 use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability};
 use rustc::ty::cast::CastKind as TyCastKind;
@@ -89,7 +89,7 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             ExprKind::NeverToAny { source: expr.to_ref() }
         }
         Adjust::MutToConstPointer => {
-            ExprKind::Cast { source: expr.to_ref() }
+            ExprKind::MutToConstPointer { source: expr.to_ref() }
         }
         Adjust::Deref(None) => {
             // Adjust the span from the block, to the last expression of the
@@ -699,7 +699,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                 };
 
                 let source = if let Some((did, offset, var_ty)) = var {
-                    let mk_const = |literal| Expr {
+                    let mk_lazy_const = |literal| Expr {
                         temp_lifetime,
                         ty: var_ty,
                         span: expr.span,
@@ -708,7 +708,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                             user_ty: None
                         },
                     }.to_ref();
-                    let offset = mk_const(ty::LazyConst::Evaluated(ty::Const::from_bits(
+                    let offset = mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bits(
                         cx.tcx,
                         offset as u128,
                         cx.param_env.and(var_ty),
@@ -718,7 +718,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                             // in case we are offsetting from a computed discriminant
                             // and not the beginning of discriminants (which is always `0`)
                             let substs = InternalSubsts::identity_for_item(cx.tcx(), did);
-                            let lhs = mk_const(ty::LazyConst::Unevaluated(did, substs));
+                            let lhs = mk_lazy_const(ty::LazyConst::Unevaluated(did, substs));
                             let bin = ExprKind::Binary {
                                 op: BinOp::Add,
                                 lhs,
@@ -925,7 +925,26 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                 ))),
                 user_ty,
             }
-        },
+        }
+
+        Def::ConstParam(def_id) => {
+            let node_id = cx.tcx.hir().as_local_node_id(def_id).unwrap();
+            let item_id = cx.tcx.hir().get_parent_node(node_id);
+            let item_def_id = cx.tcx.hir().local_def_id(item_id);
+            let generics = cx.tcx.generics_of(item_def_id);
+            let index = generics.param_def_id_to_index[&cx.tcx.hir().local_def_id(node_id)];
+            let name = cx.tcx.hir().name(node_id).as_interned_str();
+            let val = ConstValue::Param(ty::ParamConst::new(index, name));
+            ExprKind::Literal {
+                literal: cx.tcx.mk_lazy_const(
+                    ty::LazyConst::Evaluated(ty::Const {
+                        val,
+                        ty: cx.tables().node_type(expr.hir_id),
+                    })
+                ),
+                user_ty: None,
+            }
+        }
 
         Def::Const(def_id) |
         Def::AssociatedConst(def_id) => {
index 70f04fb892866814111092e3af74106b6f4a9323..8b16eeeea23c0513743a93004d93ac3113a85a36 100644 (file)
@@ -153,7 +153,7 @@ pub fn const_eval_literal(
 
     pub fn pattern_from_hir(&mut self, p: &hir::Pat) -> Pattern<'tcx> {
         let tcx = self.tcx.global_tcx();
-        let p = match tcx.hir().get(p.id) {
+        let p = match tcx.hir().get_by_hir_id(p.hir_id) {
             Node::Pat(p) | Node::Binding(p) => p,
             node => bug!("pattern became {:?}", node)
         };
index 2efdacd7622c91868e2851f4afcc8a712f4864d8..6707b01ccc11bed7e6f04381256906bbcf14919e 100644 (file)
@@ -190,6 +190,9 @@ pub enum ExprKind<'tcx> {
     UnsafeFnPointer {
         source: ExprRef<'tcx>,
     },
+    MutToConstPointer {
+        source: ExprRef<'tcx>,
+    },
     Unsize {
         source: ExprRef<'tcx>,
     },
index 9e9a5d0f82ada34712aef90aba9b42f339919e01..60eb30e075339bb9ad18a85db40ccbc6c8678202 100644 (file)
@@ -539,7 +539,6 @@ fn push_wild_constructor<'a>(
         self.apply_constructor(cx, ctor, ty)
     }
 
-
     /// Constructs a partial witness for a pattern given a list of
     /// patterns expanded by the specialization step.
     ///
index 0f151cd688df9792182c9dc46f222a62420f7444..9af513a90905e32db0e0db9e2d40e9d1bef65ffd 100644 (file)
@@ -10,7 +10,7 @@
 use rustc::middle::mem_categorization::cmt_;
 use rustc::middle::region;
 use rustc::session::Session;
-use rustc::ty::{self, Ty, TyCtxt};
+use rustc::ty::{self, Ty, TyCtxt, TyKind};
 use rustc::ty::subst::{InternalSubsts, SubstsRef};
 use rustc::lint;
 use rustc_errors::{Applicability, DiagnosticBuilder};
@@ -24,7 +24,6 @@
 use smallvec::smallvec;
 use std::slice;
 
-use syntax::ast;
 use syntax::ptr::P;
 use syntax_pos::{Span, DUMMY_SP, MultiSpan};
 
@@ -204,25 +203,51 @@ fn check_match(
             // is uninhabited.
             let pat_ty = self.tables.node_type(scrut.hir_id);
             let module = self.tcx.hir().get_module_parent_by_hir_id(scrut.hir_id);
+            let mut def_span = None;
+            let mut missing_variants = vec![];
             if inlined_arms.is_empty() {
                 let scrutinee_is_uninhabited = if self.tcx.features().exhaustive_patterns {
                     self.tcx.is_ty_uninhabited_from(module, pat_ty)
                 } else {
                     match pat_ty.sty {
                         ty::Never => true,
-                        ty::Adt(def, _) => def.variants.is_empty(),
+                        ty::Adt(def, _) => {
+                            def_span = self.tcx.hir().span_if_local(def.did);
+                            if def.variants.len() < 4 && !def.variants.is_empty() {
+                                // keep around to point at the definition of non-covered variants
+                                missing_variants = def.variants.iter()
+                                    .map(|variant| variant.ident)
+                                    .collect();
+                            }
+                            def.variants.is_empty()
+                        },
                         _ => false
                     }
                 };
                 if !scrutinee_is_uninhabited {
                     // We know the type is inhabited, so this must be wrong
-                    let mut err = create_e0004(self.tcx.sess, scrut.span,
-                                               format!("non-exhaustive patterns: type `{}` \
-                                                        is non-empty",
-                                                       pat_ty));
-                    span_help!(&mut err, scrut.span,
-                               "ensure that all possible cases are being handled, \
-                                possibly by adding wildcards or more match arms");
+                    let mut err = create_e0004(
+                        self.tcx.sess,
+                        scrut.span,
+                        format!("non-exhaustive patterns: {}", match missing_variants.len() {
+                            0 => format!("type `{}` is non-empty", pat_ty),
+                            1 => format!(
+                                "pattern `{}` of type `{}` is not handled",
+                                missing_variants[0].name,
+                                pat_ty,
+                            ),
+                            _ => format!("multiple patterns of type `{}` are not handled", pat_ty),
+                        }),
+                    );
+                    err.help("ensure that all possible cases are being handled, \
+                              possibly by adding wildcards or more match arms");
+                    if let Some(sp) = def_span {
+                        err.span_label(sp, format!("`{}` defined here", pat_ty));
+                    }
+                    // point at the definition of non-covered enum variants
+                    for variant in &missing_variants {
+                        err.span_label(variant.span, "variant not covered");
+                    }
                     err.emit();
                 }
                 // If the type *is* uninhabited, it's vacuously exhaustive
@@ -241,7 +266,7 @@ fn check_match(
     }
 
     fn check_irrefutable(&self, pat: &'tcx Pat, origin: &str) {
-        let module = self.tcx.hir().get_module_parent(pat.id);
+        let module = self.tcx.hir().get_module_parent_by_hir_id(pat.hir_id);
         MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| {
             let mut patcx = PatternContext::new(self.tcx,
                                                 self.param_env.and(self.identity_substs),
@@ -264,7 +289,7 @@ fn check_irrefutable(&self, pat: &'tcx Pat, origin: &str) {
             };
 
             let pattern_string = witness[0].single_pattern().to_string();
-            let mut diag = struct_span_err!(
+            let mut err = struct_span_err!(
                 self.tcx.sess, pat.span, E0005,
                 "refutable pattern in {}: `{}` not covered",
                 origin, pattern_string
@@ -277,8 +302,13 @@ fn check_irrefutable(&self, pat: &'tcx Pat, origin: &str) {
                 }
                 _ => format!("pattern `{}` not covered", pattern_string),
             };
-            diag.span_label(pat.span, label_msg);
-            diag.emit();
+            err.span_label(pat.span, label_msg);
+            if let ty::Adt(def, _) = pattern_ty.sty {
+                if let Some(sp) = self.tcx.hir().span_if_local(def.did){
+                    err.span_label(sp, format!("`{}` defined here", pattern_ty));
+                }
+            }
+            err.emit();
         });
     }
 }
@@ -332,10 +362,11 @@ fn pat_is_catchall(pat: &Pat) -> bool {
 }
 
 // Check for unreachable patterns
-fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
-                        arms: &[(Vec<(&'a Pattern<'tcx>, &hir::Pat)>, Option<&hir::Expr>)],
-                        source: hir::MatchSource)
-{
+fn check_arms<'a, 'tcx>(
+    cx: &mut MatchCheckCtxt<'a, 'tcx>,
+    arms: &[(Vec<(&'a Pattern<'tcx>, &hir::Pat)>, Option<&hir::Expr>)],
+    source: hir::MatchSource,
+) {
     let mut seen = Matrix::empty();
     let mut catchall = None;
     for (arm_index, &(ref pats, guard)) in arms.iter().enumerate() {
@@ -411,10 +442,12 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
     }
 }
 
-fn check_exhaustive<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
-                              scrut_ty: Ty<'tcx>,
-                              sp: Span,
-                              matrix: &Matrix<'p, 'tcx>) {
+fn check_exhaustive<'p, 'a: 'p, 'tcx: 'a>(
+    cx: &mut MatchCheckCtxt<'a, 'tcx>,
+    scrut_ty: Ty<'tcx>,
+    sp: Span,
+    matrix: &Matrix<'p, 'tcx>,
+) {
     let wild_pattern = Pattern {
         ty: scrut_ty,
         span: DUMMY_SP,
@@ -448,11 +481,26 @@ fn check_exhaustive<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                 1 => format!("pattern {} not covered", joined_patterns),
                 _ => format!("patterns {} not covered", joined_patterns),
             };
-            create_e0004(cx.tcx.sess, sp,
-                            format!("non-exhaustive patterns: {} not covered",
-                                    joined_patterns))
-                .span_label(sp, label_text)
-                .emit();
+            let mut err = create_e0004(cx.tcx.sess, sp, format!(
+                "non-exhaustive patterns: {} not covered",
+                joined_patterns,
+            ));
+            err.span_label(sp, label_text);
+            // point at the definition of non-covered enum variants
+            if let ty::Adt(def, _) = scrut_ty.sty {
+                if let Some(sp) = cx.tcx.hir().span_if_local(def.did){
+                    err.span_label(sp, format!("`{}` defined here", scrut_ty));
+                }
+            }
+            let patterns = witnesses.iter().map(|p| (**p).clone()).collect::<Vec<Pattern<'_>>>();
+            if patterns.len() < 4 {
+                for sp in maybe_point_at_variant(cx, &scrut_ty.sty, patterns.as_slice()) {
+                    err.span_label(sp, "not covered");
+                }
+            }
+            err.help("ensure that all possible cases are being handled, \
+                      possibly by adding wildcards or more match arms");
+            err.emit();
         }
         NotUseful => {
             // This is good, wildcard pattern isn't reachable
@@ -461,10 +509,49 @@ fn check_exhaustive<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
     }
 }
 
+fn maybe_point_at_variant(
+    cx: &mut MatchCheckCtxt<'a, 'tcx>,
+    sty: &TyKind<'tcx>,
+    patterns: &[Pattern<'_>],
+) -> Vec<Span> {
+    let mut covered = vec![];
+    if let ty::Adt(def, _) = sty {
+        // Don't point at variants that have already been covered due to other patterns to avoid
+        // visual clutter
+        for pattern in patterns {
+            let pk: &PatternKind<'_> = &pattern.kind;
+            if let PatternKind::Variant { adt_def, variant_index, subpatterns, .. } = pk {
+                if adt_def.did == def.did {
+                    let sp = def.variants[*variant_index].ident.span;
+                    if covered.contains(&sp) {
+                        continue;
+                    }
+                    covered.push(sp);
+                    let subpatterns = subpatterns.iter()
+                        .map(|field_pattern| field_pattern.pattern.clone())
+                        .collect::<Vec<_>>();
+                    covered.extend(
+                        maybe_point_at_variant(cx, sty, subpatterns.as_slice()),
+                    );
+                }
+            }
+            if let PatternKind::Leaf { subpatterns } = pk {
+                let subpatterns = subpatterns.iter()
+                    .map(|field_pattern| field_pattern.pattern.clone())
+                    .collect::<Vec<_>>();
+                covered.extend(maybe_point_at_variant(cx, sty, subpatterns.as_slice()));
+            }
+        }
+    }
+    covered
+}
+
 // Legality of move bindings checking
-fn check_legality_of_move_bindings(cx: &MatchVisitor<'_, '_>,
-                                   has_guard: bool,
-                                   pats: &[P<Pat>]) {
+fn check_legality_of_move_bindings(
+    cx: &MatchVisitor<'_, '_>,
+    has_guard: bool,
+    pats: &[P<Pat>],
+) {
     let mut by_ref_span = None;
     for pat in pats {
         pat.each_binding(|_, hir_id, span, _path| {
@@ -586,7 +673,7 @@ fn borrow(&mut self,
             ty::ImmBorrow | ty::UniqueImmBorrow => {}
         }
     }
-    fn decl_without_init(&mut self, _: ast::NodeId, _: Span) {}
+    fn decl_without_init(&mut self, _: hir::HirId, _: Span) {}
     fn mutate(&mut self, _: hir::HirId, span: Span, _: &cmt_<'_>, mode: MutateMode) {
         match mode {
             MutateMode::JustWrite | MutateMode::WriteAndRead => {
index ce62d79e585a8bbf32d5695216950f18f73424e0..73c73cc23dcf0cc90dd98f0440075c0882aab228 100644 (file)
@@ -33,7 +33,7 @@ pub fn cast(
                 self.unsize_into(src, dest)?;
             }
 
-            Misc => {
+            Misc | MutToConstPointer => {
                 let src = self.read_immediate(src)?;
 
                 if self.type_is_fat_ptr(src.layout.ty) {
index 979595d6c00095b5b40631aad1c199bc02abac18..206eaaf1787c5ad0fbfee138837a4970d72f3500 100644 (file)
@@ -589,11 +589,12 @@ pub(super) fn eval_operands(
         val: ty::Const<'tcx>,
         layout: Option<TyLayout<'tcx>>,
     ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
+        let val = self.monomorphize(val)?;
         let layout = from_known_layout(layout, || {
-            let ty = self.monomorphize(val.ty)?;
-            self.layout_of(ty)
+            self.layout_of(val.ty)
         })?;
         let op = match val.val {
+            ConstValue::Param(_) | ConstValue::Infer(_) => bug!(),
             ConstValue::ByRef(ptr, alloc) => {
                 // We rely on mutability being set correctly in that allocation to prevent writes
                 // where none should happen -- and for `static mut`, we copy on demand anyway.
index a58c69f636d41886292ff989d06282289bfad361..4350bfcdc7a96978af07ba2242aa83ba2bd1c13b 100644 (file)
@@ -466,7 +466,16 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                      instance: Instance<'tcx>)
 {
     let type_length = instance.substs.types().flat_map(|ty| ty.walk()).count();
-    debug!(" => type length={}", type_length);
+    let const_length = instance.substs.consts()
+        .flat_map(|ct| {
+            let ty = match ct {
+                ty::LazyConst::Evaluated(ct) => ct.ty,
+                ty::LazyConst::Unevaluated(def_id, _) => tcx.type_of(*def_id),
+            };
+            ty.walk()
+        })
+        .count();
+    debug!(" => type length={}, const length={}", type_length, const_length);
 
     // Rust code can easily create exponentially-long types using only a
     // polynomial recursion depth. Even with the default recursion
@@ -475,7 +484,9 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     //
     // Bail out in these cases to avoid that bad user experience.
     let type_length_limit = *tcx.sess.type_length_limit.get();
-    if type_length > type_length_limit {
+    // We include the const length in the type length, as it's better
+    // to be overly conservative.
+    if type_length + const_length > type_length_limit {
         // The instance name is already known to be too long for rustc. Use
         // `{:.64}` to avoid blasting the user's terminal with thousands of
         // lines of type-name.
@@ -490,7 +501,7 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
         diag.note(&format!(
             "consider adding a `#![type_length_limit=\"{}\"]` attribute to your crate",
-            type_length_limit*2));
+            type_length_limit * 2));
         diag.emit();
         tcx.sess.abort_if_errors();
     }
@@ -759,10 +770,10 @@ fn is_available_upstream_generic<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             return false
         }
 
-        // If this instance has no type parameters, it cannot be a shared
+        // If this instance has non-erasable parameters, it cannot be a shared
         // monomorphization. Non-generic instances are already handled above
         // by `is_reachable_non_generic()`
-        if substs.types().next().is_none() {
+        if substs.non_erasable_generics().next().is_none() {
             return false
         }
 
@@ -952,7 +963,7 @@ fn visit_item(&mut self, item: &'v hir::Item) {
             hir::ItemKind::Union(_, ref generics) => {
                 if generics.params.is_empty() {
                     if self.mode == MonoItemCollectionMode::Eager {
-                        let def_id = self.tcx.hir().local_def_id(item.id);
+                        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
                         debug!("RootCollector: ADT drop-glue for {}",
                                def_id_to_string(self.tcx, def_id));
 
@@ -964,11 +975,12 @@ fn visit_item(&mut self, item: &'v hir::Item) {
             hir::ItemKind::GlobalAsm(..) => {
                 debug!("RootCollector: ItemKind::GlobalAsm({})",
                        def_id_to_string(self.tcx,
-                                        self.tcx.hir().local_def_id(item.id)));
-                self.output.push(MonoItem::GlobalAsm(item.id));
+                                        self.tcx.hir().local_def_id_from_hir_id(item.hir_id)));
+                let node_id = self.tcx.hir().hir_to_node_id(item.hir_id);
+                self.output.push(MonoItem::GlobalAsm(node_id));
             }
             hir::ItemKind::Static(..) => {
-                let def_id = self.tcx.hir().local_def_id(item.id);
+                let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
                 debug!("RootCollector: ItemKind::Static({})",
                        def_id_to_string(self.tcx, def_id));
                 self.output.push(MonoItem::Static(def_id));
@@ -978,7 +990,7 @@ fn visit_item(&mut self, item: &'v hir::Item) {
                 // actually used somewhere. Just declaring them is insufficient.
 
                 // but even just declaring them must collect the items they refer to
-                let def_id = self.tcx.hir().local_def_id(item.id);
+                let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
 
                 let instance = Instance::mono(self.tcx, def_id);
                 let cid = GlobalId {
@@ -992,7 +1004,7 @@ fn visit_item(&mut self, item: &'v hir::Item) {
                 }
             }
             hir::ItemKind::Fn(..) => {
-                let def_id = self.tcx.hir().local_def_id(item.id);
+                let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
                 self.push_if_root(def_id);
             }
         }
@@ -1097,7 +1109,7 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 }
             }
 
-            let impl_def_id = tcx.hir().local_def_id(item.id);
+            let impl_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id);
 
             debug!("create_mono_items_for_default_impls(item={})",
                    def_id_to_string(tcx, impl_def_id));
@@ -1112,14 +1124,16 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                         continue;
                     }
 
-                    if tcx.generics_of(method.def_id).own_counts().types != 0 {
+                    let counts = tcx.generics_of(method.def_id).own_counts();
+                    if counts.types + counts.consts != 0 {
                         continue;
                     }
 
                     let substs = InternalSubsts::for_item(tcx, method.def_id, |param, _| {
                         match param.kind {
                             GenericParamDefKind::Lifetime => tcx.types.re_erased.into(),
-                            GenericParamDefKind::Type {..} => {
+                            GenericParamDefKind::Type { .. } |
+                            GenericParamDefKind::Const => {
                                 trait_ref.substs[param.index as usize]
                             }
                         }
index 059af2dbba944710f23d5e815e6c3d451acf35c8..f0d19ec8bf2fa71ca70a7976b3d1c510b3897aca 100644 (file)
@@ -1,8 +1,9 @@
 use crate::monomorphize::Instance;
 use rustc::hir;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::mir::interpret::ConstValue;
 use rustc::session::config::OptLevel;
-use rustc::ty::{self, Ty, TyCtxt, ClosureSubsts, GeneratorSubsts};
+use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts, LazyConst, ParamConst};
 use rustc::ty::subst::{SubstsRef, InternalSubsts};
 use syntax::ast;
 use syntax::attr::InlineAttr;
@@ -44,7 +45,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
     fn is_generic_fn(&self) -> bool {
         match *self.as_mono_item() {
             MonoItem::Fn(ref instance) => {
-                instance.substs.types().next().is_some()
+                instance.substs.non_erasable_generics().next().is_some()
             }
             MonoItem::Static(..) |
             MonoItem::GlobalAsm(..) => false,
@@ -267,7 +268,7 @@ pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) {
             ty::Float(ast::FloatTy::F64) => output.push_str("f64"),
             ty::Adt(adt_def, substs) => {
                 self.push_def_path(adt_def.did, output);
-                self.push_type_params(substs, iter::empty(), output, debug);
+                self.push_generic_params(substs, iter::empty(), output, debug);
             },
             ty::Tuple(component_types) => {
                 output.push('(');
@@ -312,7 +313,7 @@ pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) {
             ty::Dynamic(ref trait_data, ..) => {
                 if let Some(principal) = trait_data.principal() {
                     self.push_def_path(principal.def_id(), output);
-                    self.push_type_params(
+                    self.push_generic_params(
                         principal.skip_binder().substs,
                         trait_data.projection_bounds(),
                         output,
@@ -373,7 +374,7 @@ pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) {
                 self.push_def_path(def_id, output);
                 let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id));
                 let substs = substs.truncate_to(self.tcx, generics);
-                self.push_type_params(substs, iter::empty(), output, debug);
+                self.push_generic_params(substs, iter::empty(), output, debug);
             }
             ty::Error |
             ty::Bound(..) |
@@ -394,6 +395,24 @@ pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) {
         }
     }
 
+    // FIXME(const_generics): handle debug printing.
+    pub fn push_const_name(&self, c: &LazyConst<'tcx>, output: &mut String, debug: bool) {
+        match c {
+            LazyConst::Unevaluated(..) => output.push_str("_: _"),
+            LazyConst::Evaluated(Const { ty, val }) => {
+                match val {
+                    ConstValue::Infer(..) => output.push_str("_"),
+                    ConstValue::Param(ParamConst { name, .. }) => {
+                        write!(output, "{}", name).unwrap();
+                    }
+                    _ => write!(output, "{:?}", c).unwrap(),
+                }
+                output.push_str(": ");
+                self.push_type_name(ty, output, debug);
+            }
+        }
+    }
+
     pub fn push_def_path(&self,
                          def_id: DefId,
                          output: &mut String) {
@@ -421,15 +440,15 @@ pub fn push_def_path(&self,
         output.pop();
     }
 
-    fn push_type_params<I>(&self,
-                            substs: SubstsRef<'tcx>,
-                            projections: I,
-                            output: &mut String,
-                            debug: bool)
-        where I: Iterator<Item=ty::PolyExistentialProjection<'tcx>>
-    {
+    fn push_generic_params<I>(
+        &self,
+        substs: SubstsRef<'tcx>,
+        projections: I,
+        output: &mut String,
+        debug: bool,
+    ) where I: Iterator<Item=ty::PolyExistentialProjection<'tcx>> {
         let mut projections = projections.peekable();
-        if substs.types().next().is_none() && projections.peek().is_none() {
+        if substs.non_erasable_generics().next().is_none() && projections.peek().is_none() {
             return;
         }
 
@@ -449,6 +468,11 @@ fn push_type_params<I>(&self,
             output.push_str(", ");
         }
 
+        for const_parameter in substs.consts() {
+            self.push_const_name(const_parameter, output, debug);
+            output.push_str(", ");
+        }
+
         output.pop();
         output.pop();
 
@@ -460,6 +484,6 @@ pub fn push_instance_as_string(&self,
                                    output: &mut String,
                                    debug: bool) {
         self.push_def_path(instance.def_id(), output);
-        self.push_type_params(instance.substs, iter::empty(), output, debug);
+        self.push_generic_params(instance.substs, iter::empty(), output, debug);
     }
 }
index f342017603ed60501328d73d9b9e04fbab92fce3..f98bc476aafec872d40e0c85e67d20e92b795cb7 100644 (file)
@@ -448,7 +448,7 @@ fn mono_item_visibility(
         return Visibility::Hidden
     }
 
-    let is_generic = instance.substs.types().next().is_some();
+    let is_generic = instance.substs.non_erasable_generics().next().is_some();
 
     // Upstream `DefId` instances get different handling than local ones
     if !def_id.is_local() {
index adc328f1033ecaf0ed68217a56abf21318de0109..1c6b1450be86230e2b40507023a6063d1db740d0 100644 (file)
@@ -2,7 +2,7 @@
 use rustc::hir::def_id::DefId;
 use rustc::infer;
 use rustc::mir::*;
-use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind};
+use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::layout::VariantIdx;
 use rustc::ty::subst::{Subst, InternalSubsts};
 use rustc::ty::query::Providers;
@@ -10,7 +10,6 @@
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 
 use rustc_target::spec::abi::Abi;
-use syntax::ast;
 use syntax_pos::Span;
 
 use std::fmt;
@@ -451,12 +450,7 @@ fn make_clone_call(
     ) {
         let tcx = self.tcx;
 
-        let substs = InternalSubsts::for_item(tcx, self.def_id, |param, _| {
-            match param.kind {
-                GenericParamDefKind::Lifetime => tcx.types.re_erased.into(),
-                GenericParamDefKind::Type {..} => ty.into(),
-            }
-        });
+        let substs = tcx.mk_substs_trait(ty, &[]);
 
         // `func == Clone::clone(&ty) -> ty`
         let func_ty = tcx.mk_fn_def(self.def_id, substs);
@@ -855,14 +849,14 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
-                                      ctor_id: ast::NodeId,
+                                      ctor_id: hir::HirId,
                                       fields: &[hir::StructField],
                                       span: Span)
                                       -> Mir<'tcx>
 {
     let tcx = infcx.tcx;
     let gcx = tcx.global_tcx();
-    let def_id = tcx.hir().local_def_id(ctor_id);
+    let def_id = tcx.hir().local_def_id_from_hir_id(ctor_id);
     let param_env = gcx.param_env(def_id);
 
     // Normalize the sig.
index a8816720b28bd6f4dfa8b2868ddba4482954513d..047731e3fe6a7bea4bd04ba1c6e9af9de64352bb 100644 (file)
@@ -558,9 +558,10 @@ fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: D
 
     // FIXME: when we make this a hard error, this should have its
     // own error code.
-    let message = if tcx.generics_of(def_id).own_counts().types != 0 {
+    let counts = tcx.generics_of(def_id).own_counts();
+    let message = if counts.types + counts.consts != 0 {
         "#[derive] can't be used on a #[repr(packed)] struct with \
-         type parameters (error E0133)".to_string()
+         type or const parameters (error E0133)".to_string()
     } else {
         "#[derive] can't be used on a #[repr(packed)] struct that \
          does not derive Copy (error E0133)".to_string()
index c455d38cebce85fff4b824b8325372e6ddc585d6..6a71b58152822c9452040ea41bc7aa4dd6a9beb5 100644 (file)
@@ -68,7 +68,7 @@
 use crate::dataflow::{do_dataflow, DebugFormatted, state_for_location};
 use crate::dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals};
 use crate::util::dump_mir;
-use crate::util::liveness::{self, IdentityMap};
+use crate::util::liveness;
 
 pub struct StateTransform;
 
@@ -148,7 +148,7 @@ struct SuspensionPoint {
     state: u32,
     resume: BasicBlock,
     drop: Option<BasicBlock>,
-    storage_liveness: liveness::LiveVarSet<Local>,
+    storage_liveness: liveness::LiveVarSet,
 }
 
 struct TransformVisitor<'a, 'tcx: 'a> {
@@ -165,7 +165,7 @@ struct TransformVisitor<'a, 'tcx: 'a> {
 
     // A map from a suspension point in a block to the locals which have live storage at that point
     // FIXME(eddyb) This should use `IndexVec<BasicBlock, Option<_>>`.
-    storage_liveness: FxHashMap<BasicBlock, liveness::LiveVarSet<Local>>,
+    storage_liveness: FxHashMap<BasicBlock, liveness::LiveVarSet>,
 
     // A list of suspension points, generated during the transform
     suspension_points: Vec<SuspensionPoint>,
@@ -358,7 +358,7 @@ fn replace_result_variable<'tcx>(
     new_ret_local
 }
 
-struct StorageIgnored(liveness::LiveVarSet<Local>);
+struct StorageIgnored(liveness::LiveVarSet);
 
 impl<'tcx> Visitor<'tcx> for StorageIgnored {
     fn visit_statement(&mut self,
@@ -379,8 +379,8 @@ fn locals_live_across_suspend_points(
     source: MirSource<'tcx>,
     movable: bool,
 ) -> (
-    liveness::LiveVarSet<Local>,
-    FxHashMap<BasicBlock, liveness::LiveVarSet<Local>>,
+    liveness::LiveVarSet,
+    FxHashMap<BasicBlock, liveness::LiveVarSet>,
 ) {
     let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
     let node_id = tcx.hir().as_local_node_id(source.def_id()).unwrap();
@@ -414,14 +414,12 @@ fn locals_live_across_suspend_points(
     let mut set = liveness::LiveVarSet::new_empty(mir.local_decls.len());
     let mut liveness = liveness::liveness_of_locals(
         mir,
-        &IdentityMap::new(mir),
     );
     liveness::dump_mir(
         tcx,
         "generator_liveness",
         source,
         mir,
-        &IdentityMap::new(mir),
         &liveness,
     );
 
@@ -491,7 +489,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             mir: &mut Mir<'tcx>)
     -> (FxHashMap<Local, (Ty<'tcx>, usize)>,
         GeneratorLayout<'tcx>,
-        FxHashMap<BasicBlock, liveness::LiveVarSet<Local>>)
+        FxHashMap<BasicBlock, liveness::LiveVarSet>)
 {
     // Use a liveness analysis to compute locals which are live across a suspension point
     let (live_locals, storage_liveness) = locals_live_across_suspend_points(tcx,
index 4cdef015b53ff0697aee3e7bd0ca74045e950d02..918375e426b7df606f30588a8b64a972fdf6be63 100644 (file)
@@ -259,7 +259,7 @@ fn should_inline(&self,
         // inlining. This is to ensure that the final crate doesn't have MIR that
         // reference unexported symbols
         if callsite.callee.is_local() {
-            if callsite.substs.types().count() == 0 && !hinted {
+            if callsite.substs.non_erasable_generics().count() == 0 && !hinted {
                 debug!("    callee is an exported function - not inlining");
                 return false;
             }
index c1bb31a49a4b5369fc1f1274ff291375ce194088..8f5fc6963771a87c1889172a10d9430b7c6d8229 100644 (file)
@@ -80,8 +80,8 @@ fn visit_variant_data(&mut self,
                               _: &'tcx hir::Generics,
                               _: hir::HirId,
                               _: Span) {
-            if let hir::VariantData::Tuple(_, node_id, _) = *v {
-                self.set.insert(self.tcx.hir().local_def_id(node_id));
+            if let hir::VariantData::Tuple(_, hir_id) = *v {
+                self.set.insert(self.tcx.hir().local_def_id_from_hir_id(hir_id));
             }
             intravisit::walk_struct_def(self, v)
         }
index d41098e2881a63cf7ce7d967e6ab2ac185a6c9b7..20e5c0a23bc4b8ecd578e61bcf274720e1664e68 100644 (file)
@@ -1095,6 +1095,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
             Rvalue::Cast(CastKind::UnsafeFnPointer, ..) |
             Rvalue::Cast(CastKind::ClosureFnPointer, ..) |
             Rvalue::Cast(CastKind::Unsize, ..) |
+            Rvalue::Cast(CastKind::MutToConstPointer, ..) |
             Rvalue::Discriminant(..) |
             Rvalue::Len(_) |
             Rvalue::Ref(..) |
index 6c44fac10f59de98e9f4acdd736bd27d55baa4f2..f82e536ab254957b42968a7496c84f61f330605e 100644 (file)
@@ -152,6 +152,9 @@ fn check_rvalue(
                 _ => check_operand(tcx, mir, operand, span),
             }
         }
+        Rvalue::Cast(CastKind::MutToConstPointer, operand, _) => {
+            check_operand(tcx, mir, operand, span)
+        }
         Rvalue::Cast(CastKind::UnsafeFnPointer, _, _) |
         Rvalue::Cast(CastKind::ClosureFnPointer, _, _) |
         Rvalue::Cast(CastKind::ReifyFnPointer, _, _) => Err((
index dcbd9aa9af2258210442c11165ff9ede8b440034..9cda6cfdacbe3eab231eaae1eb1922366ba37f7a 100644 (file)
@@ -39,7 +39,7 @@
 use crate::transform::MirSource;
 use crate::util::pretty::{dump_enabled, write_basic_block, write_mir_intro};
 
-pub type LiveVarSet<V> = BitSet<V>;
+pub type LiveVarSet = BitSet<Local>;
 
 /// This gives the result of the liveness analysis at the boundary of
 /// basic blocks.
 /// liveness for. This is often `Local`, in which case we computed
 /// liveness for all variables -- but it can also be some other type,
 /// which indicates a subset of the variables within the graph.
-pub struct LivenessResult<V: Idx> {
+pub struct LivenessResult {
     /// Live variables on exit to each basic block. This is equal to
     /// the union of the `ins` for each successor.
-    pub outs: IndexVec<BasicBlock, LiveVarSet<V>>,
-}
-
-/// Defines the mapping to/from the MIR local variables (`Local`) to
-/// the "live variable indices" we are using in a particular
-/// computation.
-pub trait LiveVariableMap {
-    type LiveVar;
-
-    fn from_local(&self, local: Local) -> Option<Self::LiveVar>;
-    fn from_live_var(&self, local: Self::LiveVar) -> Local;
-    fn num_variables(&self) -> usize;
-}
-
-#[derive(Debug)]
-pub struct IdentityMap<'a, 'tcx: 'a> {
-    mir: &'a Mir<'tcx>,
-}
-
-impl<'a, 'tcx> IdentityMap<'a, 'tcx> {
-    pub fn new(mir: &'a Mir<'tcx>) -> Self {
-        Self { mir }
-    }
-}
-
-impl<'a, 'tcx> LiveVariableMap for IdentityMap<'a, 'tcx> {
-    type LiveVar = Local;
-
-    fn from_local(&self, local: Local) -> Option<Self::LiveVar> {
-        Some(local)
-    }
-
-    fn from_live_var(&self, local: Self::LiveVar) -> Local {
-        local
-    }
-
-    fn num_variables(&self) -> usize {
-        self.mir.local_decls.len()
-    }
+    pub outs: IndexVec<BasicBlock, LiveVarSet>,
 }
 
 /// Computes which local variables are live within the given function
 /// `mir`. The liveness mode `mode` determines what sorts of uses are
 /// considered to make a variable live (e.g., do drops count?).
-pub fn liveness_of_locals<'tcx, V: Idx>(
+pub fn liveness_of_locals<'tcx>(
     mir: &Mir<'tcx>,
-    map: &impl LiveVariableMap<LiveVar = V>,
-) -> LivenessResult<V> {
-    let num_live_vars = map.num_variables();
+) -> LivenessResult {
+    let num_live_vars = mir.local_decls.len();
 
-    let def_use: IndexVec<_, DefsUses<V>> = mir
+    let def_use: IndexVec<_, DefsUses> = mir
         .basic_blocks()
         .iter()
-        .map(|b| block(map, b, num_live_vars))
+        .map(|b| block(b, num_live_vars))
         .collect();
 
-    let mut outs: IndexVec<_, LiveVarSet<V>> = mir
+    let mut outs: IndexVec<_, LiveVarSet> = mir
         .basic_blocks()
         .indices()
         .map(|_| LiveVarSet::new_empty(num_live_vars))
@@ -211,27 +172,23 @@ pub fn categorize<'tcx>(context: PlaceContext<'tcx>) -> Option<DefUse> {
     }
 }
 
-struct DefsUsesVisitor<'lv, V, M>
-where
-    V: Idx,
-    M: LiveVariableMap<LiveVar = V> + 'lv,
+struct DefsUsesVisitor
 {
-    map: &'lv M,
-    defs_uses: DefsUses<V>,
+    defs_uses: DefsUses,
 }
 
 #[derive(Eq, PartialEq, Clone)]
-struct DefsUses<V: Idx> {
-    defs: LiveVarSet<V>,
-    uses: LiveVarSet<V>,
+struct DefsUses {
+    defs: LiveVarSet,
+    uses: LiveVarSet,
 }
 
-impl<V: Idx> DefsUses<V> {
-    fn apply(&self, bits: &mut LiveVarSet<V>) -> bool {
+impl DefsUses {
+    fn apply(&self, bits: &mut LiveVarSet) -> bool {
         bits.subtract(&self.defs) | bits.union(&self.uses)
     }
 
-    fn add_def(&mut self, index: V) {
+    fn add_def(&mut self, index: Local) {
         // If it was used already in the block, remove that use
         // now that we found a definition.
         //
@@ -245,7 +202,7 @@ fn add_def(&mut self, index: V) {
         self.defs.insert(index);
     }
 
-    fn add_use(&mut self, index: V) {
+    fn add_use(&mut self, index: Local) {
         // Inverse of above.
         //
         // Example:
@@ -261,29 +218,22 @@ fn add_use(&mut self, index: V) {
     }
 }
 
-impl<'tcx, 'lv, V, M> Visitor<'tcx> for DefsUsesVisitor<'lv, V, M>
-where
-    V: Idx,
-    M: LiveVariableMap<LiveVar = V>,
+impl<'tcx> Visitor<'tcx> for DefsUsesVisitor
 {
     fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
-        if let Some(v_index) = self.map.from_local(local) {
-            match categorize(context) {
-                Some(DefUse::Def) => self.defs_uses.add_def(v_index),
-                Some(DefUse::Use) | Some(DefUse::Drop) => self.defs_uses.add_use(v_index),
-                _ => (),
-            }
+        match categorize(context) {
+            Some(DefUse::Def) => self.defs_uses.add_def(local),
+            Some(DefUse::Use) | Some(DefUse::Drop) => self.defs_uses.add_use(local),
+            _ => (),
         }
     }
 }
 
-fn block<'tcx, V: Idx>(
-    map: &impl LiveVariableMap<LiveVar = V>,
+fn block<'tcx>(
     b: &BasicBlockData<'tcx>,
     locals: usize,
-) -> DefsUses<V> {
+) -> DefsUses {
     let mut visitor = DefsUsesVisitor {
-        map,
         defs_uses: DefsUses {
             defs: LiveVarSet::new_empty(locals),
             uses: LiveVarSet::new_empty(locals),
@@ -305,13 +255,12 @@ fn block<'tcx, V: Idx>(
     visitor.defs_uses
 }
 
-pub fn dump_mir<'a, 'tcx, V: Idx>(
+pub fn dump_mir<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     pass_name: &str,
     source: MirSource<'tcx>,
     mir: &Mir<'tcx>,
-    map: &impl LiveVariableMap<LiveVar = V>,
-    result: &LivenessResult<V>,
+    result: &LivenessResult,
 ) {
     if !dump_enabled(tcx, pass_name, source) {
         return;
@@ -320,17 +269,16 @@ pub fn dump_mir<'a, 'tcx, V: Idx>(
         // see notes on #41697 below
         tcx.item_path_str(source.def_id())
     });
-    dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, map, result);
+    dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, result);
 }
 
-fn dump_matched_mir_node<'a, 'tcx, V: Idx>(
+fn dump_matched_mir_node<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     pass_name: &str,
     node_path: &str,
     source: MirSource<'tcx>,
     mir: &Mir<'tcx>,
-    map: &dyn LiveVariableMap<LiveVar = V>,
-    result: &LivenessResult<V>,
+    result: &LivenessResult,
 ) {
     let mut file_path = PathBuf::new();
     file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
@@ -342,25 +290,23 @@ fn dump_matched_mir_node<'a, 'tcx, V: Idx>(
         writeln!(file, "// source = {:?}", source)?;
         writeln!(file, "// pass_name = {}", pass_name)?;
         writeln!(file, "")?;
-        write_mir_fn(tcx, source, mir, map, &mut file, result)?;
+        write_mir_fn(tcx, source, mir, &mut file, result)?;
         Ok(())
     });
 }
 
-pub fn write_mir_fn<'a, 'tcx, V: Idx>(
+pub fn write_mir_fn<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     src: MirSource<'tcx>,
     mir: &Mir<'tcx>,
-    map: &dyn LiveVariableMap<LiveVar = V>,
     w: &mut dyn Write,
-    result: &LivenessResult<V>,
+    result: &LivenessResult,
 ) -> io::Result<()> {
     write_mir_intro(tcx, src, mir, w)?;
     for block in mir.basic_blocks().indices() {
-        let print = |w: &mut dyn Write, prefix, result: &IndexVec<BasicBlock, LiveVarSet<V>>| {
+        let print = |w: &mut dyn Write, prefix, result: &IndexVec<BasicBlock, LiveVarSet>| {
             let live: Vec<String> = result[block]
                 .iter()
-                .map(|v| map.from_live_var(v))
                 .map(|local| format!("{:?}", local))
                 .collect();
             writeln!(w, "{} {{{}}}", prefix, live.join(", "))
index d21707c578b2ac536e1813357216e990faeb9ebb..7fe3f5a36d850178804d2f06119005aebd31b24d 100644 (file)
@@ -27,7 +27,7 @@ struct VarianceTest<'a, 'tcx: 'a> {
 
 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for VarianceTest<'a, 'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
-        let item_def_id = self.tcx.hir().local_def_id(item.id);
+        let item_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
 
         if let ItemKind::Ty(..) = item.node {
             for attr in self.tcx.get_attrs(item_def_id).iter() {
index 6b8e37b3b31330b2ecd5d7ba0e9aad410b73f409..edd658254467f95a7da1721b7f2c5b43f36e104a 100644 (file)
@@ -26,7 +26,6 @@
 use rustc::util::nodemap::{ItemLocalSet, HirIdSet};
 use rustc::hir;
 use rustc_data_structures::sync::Lrc;
-use syntax::ast;
 use syntax_pos::{Span, DUMMY_SP};
 use log::debug;
 use Promotability::*;
@@ -677,7 +676,7 @@ fn borrow(&mut self,
         }
     }
 
-    fn decl_without_init(&mut self, _id: ast::NodeId, _span: Span) {}
+    fn decl_without_init(&mut self, _id: hir::HirId, _span: Span) {}
     fn mutate(&mut self,
               _assignment_id: hir::HirId,
               _assignment_span: Span,
index c1ba4d7b3d8674483081b55e1979580aa48a912a..31018a7cd7a3ca7969627a4fe3038687c32d8e57 100644 (file)
@@ -1,6 +1,5 @@
 //! Used by `rustc` when compiling a plugin crate.
 
-use syntax::ast;
 use syntax::attr;
 use syntax_pos::Span;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
@@ -10,7 +9,7 @@
 use rustc::ty::query::Providers;
 
 struct RegistrarFinder {
-    registrars: Vec<(ast::NodeId, Span)> ,
+    registrars: Vec<(hir::HirId, Span)> ,
 }
 
 impl<'v> ItemLikeVisitor<'v> for RegistrarFinder {
@@ -18,7 +17,7 @@ fn visit_item(&mut self, item: &hir::Item) {
         if let hir::ItemKind::Fn(..) = item.node {
             if attr::contains_name(&item.attrs,
                                    "plugin_registrar") {
-                self.registrars.push((item.id, item.span));
+                self.registrars.push((item.hir_id, item.span));
             }
         }
     }
@@ -47,8 +46,8 @@ fn plugin_registrar_fn<'tcx>(
     match finder.registrars.len() {
         0 => None,
         1 => {
-            let (node_id, _) = finder.registrars.pop().unwrap();
-            Some(tcx.hir().local_def_id(node_id))
+            let (hir_id, _) = finder.registrars.pop().unwrap();
+            Some(tcx.hir().local_def_id_from_hir_id(hir_id))
         },
         _ => {
             let diagnostic = tcx.sess.diagnostic();
index 4a73f86ef6fe9dd25e08afef0215a8cac8962724..a9f05eb60db18f17fa559454e9de97c368fbbfb2 100644 (file)
@@ -24,7 +24,7 @@
 use rustc::util::nodemap::HirIdSet;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::Lrc;
-use syntax::ast::{self, DUMMY_NODE_ID, Ident};
+use syntax::ast::Ident;
 use syntax::attr;
 use syntax::symbol::keywords;
 use syntax_pos::Span;
@@ -220,16 +220,16 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
 
 fn def_id_visibility<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                                -> (ty::Visibility, Span, &'static str) {
-    match tcx.hir().as_local_node_id(def_id) {
-        Some(node_id) => {
-            let vis = match tcx.hir().get(node_id) {
+    match tcx.hir().as_local_hir_id(def_id) {
+        Some(hir_id) => {
+            let vis = match tcx.hir().get_by_hir_id(hir_id) {
                 Node::Item(item) => &item.vis,
                 Node::ForeignItem(foreign_item) => &foreign_item.vis,
                 Node::TraitItem(..) | Node::Variant(..) => {
-                    return def_id_visibility(tcx, tcx.hir().get_parent_did(node_id));
+                    return def_id_visibility(tcx, tcx.hir().get_parent_did_by_hir_id(hir_id));
                 }
                 Node::ImplItem(impl_item) => {
-                    match tcx.hir().get(tcx.hir().get_parent(node_id)) {
+                    match tcx.hir().get_by_hir_id(tcx.hir().get_parent_item(hir_id)) {
                         Node::Item(item) => match &item.node {
                             hir::ItemKind::Impl(.., None, _, _) => &impl_item.vis,
                             hir::ItemKind::Impl(.., Some(trait_ref), _, _)
@@ -240,16 +240,16 @@ fn def_id_visibility<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                     }
                 }
                 Node::StructCtor(vdata) => {
-                    let struct_node_id = tcx.hir().get_parent(node_id);
-                    let item = match tcx.hir().get(struct_node_id) {
+                    let struct_hir_id = tcx.hir().get_parent_item(hir_id);
+                    let item = match tcx.hir().get_by_hir_id(struct_hir_id) {
                         Node::Item(item) => item,
                         node => bug!("unexpected node kind: {:?}", node),
                     };
                     let (mut ctor_vis, mut span, mut descr) =
-                        (ty::Visibility::from_hir(&item.vis, struct_node_id, tcx),
+                        (ty::Visibility::from_hir(&item.vis, struct_hir_id, tcx),
                          item.vis.span, item.vis.node.descr());
                     for field in vdata.fields() {
-                        let field_vis = ty::Visibility::from_hir(&field.vis, node_id, tcx);
+                        let field_vis = ty::Visibility::from_hir(&field.vis, hir_id, tcx);
                         if ctor_vis.is_at_least(field_vis, tcx) {
                             ctor_vis = field_vis;
                             span = field.vis.span;
@@ -260,7 +260,7 @@ fn def_id_visibility<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                     // If the structure is marked as non_exhaustive then lower the
                     // visibility to within the crate.
                     if ctor_vis == ty::Visibility::Public {
-                        let adt_def = tcx.adt_def(tcx.hir().get_parent_did(node_id));
+                        let adt_def = tcx.adt_def(tcx.hir().get_parent_did_by_hir_id(hir_id));
                         if adt_def.non_enum_variant().is_field_list_non_exhaustive() {
                             ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
                             span = attr::find_by_name(&item.attrs, "non_exhaustive").unwrap().span;
@@ -277,7 +277,7 @@ fn def_id_visibility<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
                 }
                 node => bug!("unexpected node kind: {:?}", node)
             };
-            (ty::Visibility::from_hir(vis, node_id, tcx), vis.span, vis.node.descr())
+            (ty::Visibility::from_hir(vis, hir_id, tcx), vis.span, vis.node.descr())
         }
         None => {
             let vis = tcx.visibility(def_id);
@@ -349,10 +349,10 @@ trait VisibilityLike: Sized {
 
     // Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to
     // associated types for which we can't determine visibility precisely.
-    fn of_impl<'a, 'tcx>(node_id: ast::NodeId, tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    fn of_impl<'a, 'tcx>(hir_id: hir::HirId, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          access_levels: &'a AccessLevels) -> Self {
         let mut find = FindMin { tcx, access_levels, min: Self::MAX };
-        let def_id = tcx.hir().local_def_id(node_id);
+        let def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
         find.visit(tcx.type_of(def_id));
         if let Some(trait_ref) = tcx.impl_trait_ref(def_id) {
             find.visit_trait(trait_ref);
@@ -409,16 +409,18 @@ struct ReachEverythingInTheInterfaceVisitor<'b, 'a: 'b, 'tcx: 'a> {
 }
 
 impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
-    fn get(&self, id: ast::NodeId) -> Option<AccessLevel> {
-        self.access_levels.map.get(&id).cloned()
+    fn get(&self, id: hir::HirId) -> Option<AccessLevel> {
+        let node_id = self.tcx.hir().hir_to_node_id(id);
+        self.access_levels.map.get(&node_id).cloned()
     }
 
     // Updates node level and returns the updated level.
-    fn update(&mut self, id: ast::NodeId, level: Option<AccessLevel>) -> Option<AccessLevel> {
+    fn update(&mut self, id: hir::HirId, level: Option<AccessLevel>) -> Option<AccessLevel> {
         let old_level = self.get(id);
         // Accessibility levels can only grow.
         if level > old_level {
-            self.access_levels.map.insert(id, level.unwrap());
+            let node_id = self.tcx.hir().hir_to_node_id(id);
+            self.access_levels.map.insert(node_id, level.unwrap());
             self.changed = true;
             level
         } else {
@@ -426,11 +428,11 @@ fn update(&mut self, id: ast::NodeId, level: Option<AccessLevel>) -> Option<Acce
         }
     }
 
-    fn reach(&mut self, item_id: ast::NodeId, access_level: Option<AccessLevel>)
+    fn reach(&mut self, item_id: hir::HirId, access_level: Option<AccessLevel>)
              -> ReachEverythingInTheInterfaceVisitor<'_, 'a, 'tcx> {
         ReachEverythingInTheInterfaceVisitor {
             access_level: cmp::min(access_level, Some(AccessLevel::Reachable)),
-            item_def_id: self.tcx.hir().local_def_id(item_id),
+            item_def_id: self.tcx.hir().local_def_id_from_hir_id(item_id),
             ev: self,
         }
     }
@@ -464,7 +466,7 @@ fn update_visibility_of_intermediate_use_statements(&mut self, segments: &[hir::
                         let def_id = self.tcx.hir().local_def_id(item_id.id);
                         if !self.tcx.hygienic_eq(segment.ident, item.ident, def_id) { continue; }
                         if let hir::ItemKind::Use(..) = item.node {
-                            self.update(item.id, Some(AccessLevel::Exported));
+                            self.update(item.hir_id, Some(AccessLevel::Exported));
                         }
                     }
                 }
@@ -483,7 +485,7 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         let inherited_item_level = match item.node {
             hir::ItemKind::Impl(..) =>
-                Option::<AccessLevel>::of_impl(item.id, self.tcx, &self.access_levels),
+                Option::<AccessLevel>::of_impl(item.hir_id, self.tcx, &self.access_levels),
             // Foreign modules inherit level from parents.
             hir::ItemKind::ForeignMod(..) => self.prev_level,
             // Other `pub` items inherit levels from parents.
@@ -498,44 +500,44 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
         };
 
         // Update level of the item itself.
-        let item_level = self.update(item.id, inherited_item_level);
+        let item_level = self.update(item.hir_id, inherited_item_level);
 
         // Update levels of nested things.
         match item.node {
             hir::ItemKind::Enum(ref def, _) => {
                 for variant in &def.variants {
-                    let variant_level = self.update(variant.node.data.id(), item_level);
+                    let variant_level = self.update(variant.node.data.hir_id(), item_level);
                     for field in variant.node.data.fields() {
-                        self.update(field.id, variant_level);
+                        self.update(field.hir_id, variant_level);
                     }
                 }
             }
             hir::ItemKind::Impl(.., ref trait_ref, _, ref impl_item_refs) => {
                 for impl_item_ref in impl_item_refs {
                     if trait_ref.is_some() || impl_item_ref.vis.node.is_pub() {
-                        self.update(impl_item_ref.id.node_id, item_level);
+                        self.update(impl_item_ref.id.hir_id, item_level);
                     }
                 }
             }
             hir::ItemKind::Trait(.., ref trait_item_refs) => {
                 for trait_item_ref in trait_item_refs {
-                    self.update(trait_item_ref.id.node_id, item_level);
+                    self.update(trait_item_ref.id.hir_id, item_level);
                 }
             }
             hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => {
                 if !def.is_struct() {
-                    self.update(def.id(), item_level);
+                    self.update(def.hir_id(), item_level);
                 }
                 for field in def.fields() {
                     if field.vis.node.is_pub() {
-                        self.update(field.id, item_level);
+                        self.update(field.hir_id, item_level);
                     }
                 }
             }
             hir::ItemKind::ForeignMod(ref foreign_mod) => {
                 for foreign_item in &foreign_mod.items {
                     if foreign_item.vis.node.is_pub() {
-                        self.update(foreign_item.id, item_level);
+                        self.update(foreign_item.hir_id, item_level);
                     }
                 }
             }
@@ -572,21 +574,21 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                 // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
                 // reachable if they are returned via `impl Trait`, even from private functions.
                 let exist_level = cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait));
-                self.reach(item.id, exist_level).generics().predicates().ty();
+                self.reach(item.hir_id, exist_level).generics().predicates().ty();
             }
             // Visit everything.
             hir::ItemKind::Const(..) | hir::ItemKind::Static(..) |
             hir::ItemKind::Fn(..) | hir::ItemKind::Ty(..) => {
                 if item_level.is_some() {
-                    self.reach(item.id, item_level).generics().predicates().ty();
+                    self.reach(item.hir_id, item_level).generics().predicates().ty();
                 }
             }
             hir::ItemKind::Trait(.., ref trait_item_refs) => {
                 if item_level.is_some() {
-                    self.reach(item.id, item_level).generics().predicates();
+                    self.reach(item.hir_id, item_level).generics().predicates();
 
                     for trait_item_ref in trait_item_refs {
-                        let mut reach = self.reach(trait_item_ref.id.node_id, item_level);
+                        let mut reach = self.reach(trait_item_ref.id.hir_id, item_level);
                         reach.generics().predicates();
 
                         if trait_item_ref.kind == AssociatedItemKind::Type &&
@@ -600,18 +602,18 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
             }
             hir::ItemKind::TraitAlias(..) => {
                 if item_level.is_some() {
-                    self.reach(item.id, item_level).generics().predicates();
+                    self.reach(item.hir_id, item_level).generics().predicates();
                 }
             }
             // Visit everything except for private impl items.
             hir::ItemKind::Impl(.., ref impl_item_refs) => {
                 if item_level.is_some() {
-                    self.reach(item.id, item_level).generics().predicates().ty().trait_ref();
+                    self.reach(item.hir_id, item_level).generics().predicates().ty().trait_ref();
 
                     for impl_item_ref in impl_item_refs {
-                        let impl_item_level = self.get(impl_item_ref.id.node_id);
+                        let impl_item_level = self.get(impl_item_ref.id.hir_id);
                         if impl_item_level.is_some() {
-                            self.reach(impl_item_ref.id.node_id, impl_item_level)
+                            self.reach(impl_item_ref.id.hir_id, impl_item_level)
                                 .generics().predicates().ty();
                         }
                     }
@@ -621,26 +623,26 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
             // Visit everything, but enum variants have their own levels.
             hir::ItemKind::Enum(ref def, _) => {
                 if item_level.is_some() {
-                    self.reach(item.id, item_level).generics().predicates();
+                    self.reach(item.hir_id, item_level).generics().predicates();
                 }
                 for variant in &def.variants {
-                    let variant_level = self.get(variant.node.data.id());
+                    let variant_level = self.get(variant.node.data.hir_id());
                     if variant_level.is_some() {
                         for field in variant.node.data.fields() {
-                            self.reach(field.id, variant_level).ty();
+                            self.reach(field.hir_id, variant_level).ty();
                         }
                         // Corner case: if the variant is reachable, but its
                         // enum is not, make the enum reachable as well.
-                        self.update(item.id, variant_level);
+                        self.update(item.hir_id, variant_level);
                     }
                 }
             }
             // Visit everything, but foreign items have their own levels.
             hir::ItemKind::ForeignMod(ref foreign_mod) => {
                 for foreign_item in &foreign_mod.items {
-                    let foreign_item_level = self.get(foreign_item.id);
+                    let foreign_item_level = self.get(foreign_item.hir_id);
                     if foreign_item_level.is_some() {
-                        self.reach(foreign_item.id, foreign_item_level)
+                        self.reach(foreign_item.hir_id, foreign_item_level)
                             .generics().predicates().ty();
                     }
                 }
@@ -649,11 +651,11 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
             hir::ItemKind::Struct(ref struct_def, _) |
             hir::ItemKind::Union(ref struct_def, _) => {
                 if item_level.is_some() {
-                    self.reach(item.id, item_level).generics().predicates();
+                    self.reach(item.hir_id, item_level).generics().predicates();
                     for field in struct_def.fields() {
-                        let field_level = self.get(field.id);
+                        let field_level = self.get(field.hir_id);
                         if field_level.is_some() {
-                            self.reach(field.id, field_level).ty();
+                            self.reach(field.hir_id, field_level).ty();
                         }
                     }
                 }
@@ -683,8 +685,8 @@ fn visit_mod(&mut self, m: &'tcx hir::Mod, _sp: Span, id: hir::HirId) {
                 for export in exports.iter() {
                     if export.vis == ty::Visibility::Public {
                         if let Some(def_id) = export.def.opt_def_id() {
-                            if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) {
-                                self.update(node_id, Some(AccessLevel::Exported));
+                            if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
+                                self.update(hir_id, Some(AccessLevel::Exported));
                             }
                         }
                     }
@@ -696,10 +698,8 @@ fn visit_mod(&mut self, m: &'tcx hir::Mod, _sp: Span, id: hir::HirId) {
     }
 
     fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
-        let node_id = self.tcx.hir().hir_to_node_id(md.hir_id);
-
         if md.legacy {
-            self.update(node_id, Some(AccessLevel::Public));
+            self.update(md.hir_id, Some(AccessLevel::Public));
             return
         }
 
@@ -707,38 +707,39 @@ fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
             self.tcx,
             self.tcx.hir().local_def_id_from_hir_id(md.hir_id)
         ).unwrap();
-        let mut module_id = self.tcx.hir().as_local_node_id(module_did).unwrap();
+        let mut module_id = self.tcx.hir().as_local_hir_id(module_did).unwrap();
         let level = if md.vis.node.is_pub() { self.get(module_id) } else { None };
-        let level = self.update(node_id, level);
+        let level = self.update(md.hir_id, level);
         if level.is_none() {
             return
         }
 
         loop {
-            let module = if module_id == ast::CRATE_NODE_ID {
+            let module = if module_id == hir::CRATE_HIR_ID {
                 &self.tcx.hir().krate().module
             } else if let hir::ItemKind::Mod(ref module) =
-                          self.tcx.hir().expect_item(module_id).node {
+                          self.tcx.hir().expect_item_by_hir_id(module_id).node {
                 module
             } else {
                 unreachable!()
             };
             for id in &module.item_ids {
-                self.update(id.id, level);
+                let hir_id = self.tcx.hir().node_to_hir_id(id.id);
+                self.update(hir_id, level);
             }
-            let def_id = self.tcx.hir().local_def_id(module_id);
+            let def_id = self.tcx.hir().local_def_id_from_hir_id(module_id);
             if let Some(exports) = self.tcx.module_exports(def_id) {
                 for export in exports.iter() {
-                    if let Some(node_id) = self.tcx.hir().as_local_node_id(export.def.def_id()) {
-                        self.update(node_id, level);
+                    if let Some(hir_id) = self.tcx.hir().as_local_hir_id(export.def.def_id()) {
+                        self.update(hir_id, level);
                     }
                 }
             }
 
-            if module_id == ast::CRATE_NODE_ID {
+            if module_id == hir::CRATE_HIR_ID {
                 break
             }
-            module_id = self.tcx.hir().get_parent_node(module_id);
+            module_id = self.tcx.hir().get_parent_node_by_hir_id(module_id);
         }
     }
 }
@@ -747,12 +748,15 @@ impl<'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'_, 'a, 'tcx> {
     fn generics(&mut self) -> &mut Self {
         for param in &self.ev.tcx.generics_of(self.item_def_id).params {
             match param.kind {
+                GenericParamDefKind::Lifetime => {}
                 GenericParamDefKind::Type { has_default, .. } => {
                     if has_default {
                         self.visit(self.ev.tcx.type_of(param.def_id));
                     }
                 }
-                GenericParamDefKind::Lifetime => {}
+                GenericParamDefKind::Const => {
+                    self.visit(self.ev.tcx.type_of(param.def_id));
+                }
             }
         }
         self
@@ -779,8 +783,8 @@ fn trait_ref(&mut self) -> &mut Self {
 impl<'a, 'tcx> DefIdVisitor<'a, 'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'a, 'tcx> {
     fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { self.ev.tcx }
     fn visit_def_id(&mut self, def_id: DefId, _kind: &str, _descr: &dyn fmt::Display) -> bool {
-        if let Some(node_id) = self.ev.tcx.hir().as_local_node_id(def_id) {
-            self.ev.update(node_id, self.access_level);
+        if let Some(hir_id) = self.ev.tcx.hir().as_local_hir_id(def_id) {
+            self.ev.update(hir_id, self.access_level);
         }
         false
     }
@@ -796,7 +800,7 @@ fn visit_def_id(&mut self, def_id: DefId, _kind: &str, _descr: &dyn fmt::Display
 struct NamePrivacyVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
-    current_item: ast::NodeId,
+    current_item: hir::HirId,
     empty_tables: &'a ty::TypeckTables<'tcx>,
 }
 
@@ -808,7 +812,7 @@ fn check_field(&mut self,
                    def: &'tcx ty::AdtDef, // definition of the struct or enum
                    field: &'tcx ty::FieldDef) { // definition of the field
         let ident = Ident::new(keywords::Invalid.name(), use_ctxt);
-        let current_hir = self.tcx.hir().node_to_hir_id(self.current_item);
+        let current_hir = self.current_item;
         let def_id = self.tcx.adjust_ident(ident, def.did, current_hir).1;
         if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) {
             struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private",
@@ -839,7 +843,7 @@ fn visit_nested_body(&mut self, body: hir::BodyId) {
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
-        let orig_current_item = mem::replace(&mut self.current_item, item.id);
+        let orig_current_item = mem::replace(&mut self.current_item, item.hir_id);
         let orig_tables =
             mem::replace(&mut self.tables, item_tables(self.tcx, item.hir_id, self.empty_tables));
         intravisit::walk_item(self, item);
@@ -1110,8 +1114,8 @@ fn visit_local(&mut self, local: &'tcx hir::Local) {
 
     // Check types in item interfaces.
     fn visit_item(&mut self, item: &'tcx hir::Item) {
-        let orig_current_item =
-            mem::replace(&mut self.current_item, self.tcx.hir().local_def_id(item.id));
+        let orig_current_item = mem::replace(&mut self.current_item,
+            self.tcx.hir().local_def_id_from_hir_id(item.hir_id));
         let orig_in_body = mem::replace(&mut self.in_body, false);
         let orig_tables =
             mem::replace(&mut self.tables, item_tables(self.tcx, item.hir_id, self.empty_tables));
@@ -1190,10 +1194,11 @@ fn path_is_private_type(&self, path: &hir::Path) -> bool {
         }
     }
 
-    fn trait_is_public(&self, trait_id: ast::NodeId) -> bool {
+    fn trait_is_public(&self, trait_id: hir::HirId) -> bool {
         // FIXME: this would preferably be using `exported_items`, but all
         // traits are exported currently (see `EmbargoVisitor.exported_trait`).
-        self.access_levels.is_public(trait_id)
+        let node_id = self.tcx.hir().hir_to_node_id(trait_id);
+        self.access_levels.is_public(node_id)
     }
 
     fn check_generic_bound(&mut self, bound: &hir::GenericBound) {
@@ -1204,8 +1209,9 @@ fn check_generic_bound(&mut self, bound: &hir::GenericBound) {
         }
     }
 
-    fn item_is_public(&self, id: &ast::NodeId, vis: &hir::Visibility) -> bool {
-        self.access_levels.is_reachable(*id) || vis.node.is_pub()
+    fn item_is_public(&self, id: &hir::HirId, vis: &hir::Visibility) -> bool {
+        let node_id = self.tcx.hir().hir_to_node_id(*id);
+        self.access_levels.is_reachable(node_id) || vis.node.is_pub()
     }
 }
 
@@ -1253,7 +1259,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
             hir::ItemKind::ForeignMod(_) => {}
 
             hir::ItemKind::Trait(.., ref bounds, _) => {
-                if !self.trait_is_public(item.id) {
+                if !self.trait_is_public(item.hir_id) {
                     return
                 }
 
@@ -1295,8 +1301,8 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                                               |tr| {
                         let did = tr.path.def.def_id();
 
-                        if let Some(node_id) = self.tcx.hir().as_local_node_id(did) {
-                            self.trait_is_public(node_id)
+                        if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) {
+                            self.trait_is_public(hir_id)
                         } else {
                             true // external traits must be public
                         }
@@ -1318,9 +1324,9 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                                      match impl_item.node {
                                          hir::ImplItemKind::Const(..) |
                                          hir::ImplItemKind::Method(..) => {
-                                             let node_id = self.tcx.hir().hir_to_node_id(
-                                                impl_item.hir_id);
-                                             self.access_levels.is_reachable(node_id)
+                                             self.access_levels.is_reachable(
+                                                self.tcx.hir().hir_to_node_id(
+                                                    impl_item_ref.id.hir_id))
                                          }
                                          hir::ImplItemKind::Existential(..) |
                                          hir::ImplItemKind::Type(_) => false,
@@ -1342,11 +1348,10 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                                 // don't erroneously report errors for private
                                 // types in private items.
                                 let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
-                                let node_id = self.tcx.hir().hir_to_node_id(impl_item.hir_id);
                                 match impl_item.node {
                                     hir::ImplItemKind::Const(..) |
                                     hir::ImplItemKind::Method(..)
-                                        if self.item_is_public(&node_id, &impl_item.vis) =>
+                                        if self.item_is_public(&impl_item.hir_id, &impl_item.vis) =>
                                     {
                                         intravisit::walk_impl_item(self, impl_item)
                                     }
@@ -1387,7 +1392,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                     // methods will be visible as `Public::foo`.
                     let mut found_pub_static = false;
                     for impl_item_ref in impl_item_refs {
-                        if self.item_is_public(&impl_item_ref.id.node_id, &impl_item_ref.vis) {
+                        if self.item_is_public(&impl_item_ref.id.hir_id, &impl_item_ref.vis) {
                             let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                             match impl_item_ref.kind {
                                 AssociatedItemKind::Const => {
@@ -1414,7 +1419,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
             hir::ItemKind::Ty(..) => return,
 
             // Not at all public, so we don't care.
-            _ if !self.item_is_public(&item.id, &item.vis) => {
+            _ if !self.item_is_public(&item.hir_id, &item.vis) => {
                 return;
             }
 
@@ -1450,7 +1455,8 @@ fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
     }
 
     fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem) {
-        if self.access_levels.is_reachable(item.id) {
+        let node_id = self.tcx.hir().hir_to_node_id(item.hir_id);
+        if self.access_levels.is_reachable(node_id) {
             intravisit::walk_foreign_item(self, item)
         }
     }
@@ -1468,7 +1474,8 @@ fn visit_variant(&mut self,
                      v: &'tcx hir::Variant,
                      g: &'tcx hir::Generics,
                      item_id: hir::HirId) {
-        if self.access_levels.is_reachable(v.node.data.id()) {
+        let node_id = self.tcx.hir().hir_to_node_id(v.node.data.hir_id());
+        if self.access_levels.is_reachable(node_id) {
             self.in_variant = true;
             intravisit::walk_variant(self, v, g, item_id);
             self.in_variant = false;
@@ -1513,12 +1520,15 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
     fn generics(&mut self) -> &mut Self {
         for param in &self.tcx.generics_of(self.item_def_id).params {
             match param.kind {
+                GenericParamDefKind::Lifetime => {}
                 GenericParamDefKind::Type { has_default, .. } => {
                     if has_default {
                         self.visit(self.tcx.type_of(param.def_id));
                     }
                 }
-                GenericParamDefKind::Lifetime => {}
+                GenericParamDefKind::Const => {
+                    self.visit(self.tcx.type_of(param.def_id));
+                }
             }
         }
         self
@@ -1671,7 +1681,7 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         let tcx = self.tcx;
-        let item_visibility = ty::Visibility::from_hir(&item.vis, item.id, tcx);
+        let item_visibility = ty::Visibility::from_hir(&item.vis, item.hir_id, tcx);
 
         match item.node {
             // Crates are always public.
@@ -1696,8 +1706,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                 self.check(item.hir_id, item_visibility).generics().predicates();
 
                 for trait_item_ref in trait_item_refs {
-                    let hir_id = tcx.hir().node_to_hir_id(trait_item_ref.id.node_id);
-                    self.check_trait_or_impl_item(hir_id, trait_item_ref.kind,
+                    self.check_trait_or_impl_item(trait_item_ref.id.hir_id, trait_item_ref.kind,
                                                   trait_item_ref.defaultness, item_visibility);
                 }
             }
@@ -1716,7 +1725,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
             // Subitems of foreign modules have their own publicity.
             hir::ItemKind::ForeignMod(ref foreign_mod) => {
                 for foreign_item in &foreign_mod.items {
-                    let vis = ty::Visibility::from_hir(&foreign_item.vis, item.id, tcx);
+                    let vis = ty::Visibility::from_hir(&foreign_item.vis, item.hir_id, tcx);
                     self.check(foreign_item.hir_id, vis).generics().predicates().ty();
                 }
             }
@@ -1726,7 +1735,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                 self.check(item.hir_id, item_visibility).generics().predicates();
 
                 for field in struct_def.fields() {
-                    let field_visibility = ty::Visibility::from_hir(&field.vis, item.id, tcx);
+                    let field_visibility = ty::Visibility::from_hir(&field.vis, item.hir_id, tcx);
                     self.check(field.hir_id, min(item_visibility, field_visibility, tcx)).ty();
                 }
             }
@@ -1735,17 +1744,18 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
             // A trait impl is public when both its type and its trait are public
             // Subitems of trait impls have inherited publicity.
             hir::ItemKind::Impl(.., ref trait_ref, _, ref impl_item_refs) => {
-                let impl_vis = ty::Visibility::of_impl(item.id, tcx, &Default::default());
+                let impl_vis = ty::Visibility::of_impl(item.hir_id, tcx, &Default::default());
                 self.check(item.hir_id, impl_vis).generics().predicates();
                 for impl_item_ref in impl_item_refs {
                     let impl_item = tcx.hir().impl_item(impl_item_ref.id);
                     let impl_item_vis = if trait_ref.is_none() {
-                        min(ty::Visibility::from_hir(&impl_item.vis, item.id, tcx), impl_vis, tcx)
+                        min(ty::Visibility::from_hir(&impl_item.vis, item.hir_id, tcx),
+                            impl_vis,
+                            tcx)
                     } else {
                         impl_vis
                     };
-                    let hir_id = tcx.hir().node_to_hir_id(impl_item_ref.id.node_id);
-                    self.check_trait_or_impl_item(hir_id, impl_item_ref.kind,
+                    self.check_trait_or_impl_item(impl_item_ref.id.hir_id, impl_item_ref.kind,
                                                   impl_item_ref.defaultness, impl_item_vis);
                 }
             }
@@ -1773,7 +1783,7 @@ fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
     let mut visitor = NamePrivacyVisitor {
         tcx,
         tables: &empty_tables,
-        current_item: DUMMY_NODE_ID,
+        current_item: hir::DUMMY_HIR_ID,
         empty_tables: &empty_tables,
     };
     let (module, span, node_id) = tcx.hir().get_module(module_def_id);
@@ -1827,7 +1837,7 @@ fn privacy_access_levels<'tcx>(
             break
         }
     }
-    visitor.update(ast::CRATE_NODE_ID, Some(AccessLevel::Public));
+    visitor.update(hir::CRATE_HIR_ID, Some(AccessLevel::Public));
 
     {
         let mut visitor = ObsoleteVisiblePrivateTypesVisitor {
diff --git a/src/librustc_target/spec/armv6_unknown_freebsd.rs b/src/librustc_target/spec/armv6_unknown_freebsd.rs
new file mode 100644 (file)
index 0000000..39886a1
--- /dev/null
@@ -0,0 +1,24 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    let base = super::freebsd_base::opts();
+    Ok(Target {
+        llvm_target: "armv6-unknown-freebsd-gnueabihf".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+        target_os: "freebsd".to_string(),
+        target_env: "gnueabihf".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+
+        options: TargetOptions {
+            features: "+v6,+vfp2".to_string(),
+            max_atomic_width: Some(64),
+            abi_blacklist: super::arm_base::abi_blacklist(),
+            .. base
+        }
+    })
+}
diff --git a/src/librustc_target/spec/armv7_unknown_freebsd.rs b/src/librustc_target/spec/armv7_unknown_freebsd.rs
new file mode 100644 (file)
index 0000000..ba63fd2
--- /dev/null
@@ -0,0 +1,24 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    let base = super::freebsd_base::opts();
+    Ok(Target {
+        llvm_target: "armv7-unknown-freebsd-gnueabihf".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+        target_os: "freebsd".to_string(),
+        target_env: "gnueabihf".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+
+        options: TargetOptions {
+            features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(),
+            max_atomic_width: Some(64),
+            abi_blacklist: super::arm_base::abi_blacklist(),
+            .. base
+        }
+    })
+}
index bef2afc7b6292db5530e23008ab3e45fe9597234..2824d9cb6c3bbb380d6de5cb5f6965738ed4758c 100644 (file)
@@ -376,6 +376,8 @@ fn $module() {
     ("aarch64-linux-android", aarch64_linux_android),
 
     ("aarch64-unknown-freebsd", aarch64_unknown_freebsd),
+    ("armv6-unknown-freebsd", armv6_unknown_freebsd),
+    ("armv7-unknown-freebsd", armv7_unknown_freebsd),
     ("i686-unknown-freebsd", i686_unknown_freebsd),
     ("powerpc64-unknown-freebsd", powerpc64_unknown_freebsd),
     ("x86_64-unknown-freebsd", x86_64_unknown_freebsd),
index a326d84725ab431d0771e627793fd5547985b512..6420f20a3ea2904d02ce0d73636f35539cf189f4 100644 (file)
     InEnvironment,
     ChalkCanonicalGoal,
 };
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, TyCtxt, InferConst};
 use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use rustc::ty::query::Providers;
 use rustc::ty::subst::{Kind, UnpackedKind};
 use rustc_data_structures::sync::Lrc;
+use rustc::mir::interpret::ConstValue;
 use syntax_pos::DUMMY_SP;
 
 use std::fmt::{self, Debug};
@@ -287,6 +288,16 @@ fn is_trivial_substitution(
                     }
                     _ => false,
                 },
+                UnpackedKind::Const(ct) => match ct {
+                    ty::LazyConst::Evaluated(ty::Const {
+                        val: ConstValue::Infer(InferConst::Canonical(debruijn, bound_ct)),
+                        ..
+                    }) => {
+                        debug_assert_eq!(*debruijn, ty::INNERMOST);
+                        cvar == *bound_ct
+                    }
+                    _ => false,
+                }
             })
     }
 
index 5dbcf908020b0505a6b3c33014bd8220fb946719..be708c78a0dd138b95e5cfd660eb9b6f2a41ebfc 100644 (file)
@@ -3,7 +3,7 @@
 //! instance of `AstConv`.
 
 use errors::{Applicability, DiagnosticId};
-use crate::hir::{self, GenericArg, GenericArgs};
+use crate::hir::{self, GenericArg, GenericArgs, ExprKind};
 use crate::hir::def::Def;
 use crate::hir::def_id::DefId;
 use crate::hir::HirVec;
@@ -16,6 +16,7 @@
 use rustc::ty::{GenericParamDef, GenericParamDefKind};
 use rustc::ty::subst::{Kind, Subst, InternalSubsts, SubstsRef};
 use rustc::ty::wf::object_region_bounds;
+use rustc::mir::interpret::ConstValue;
 use rustc_data_structures::sync::Lrc;
 use rustc_target::spec::abi;
 use crate::require_c_abi_if_c_variadic;
@@ -273,6 +274,7 @@ fn check_generic_arg_count(
         let param_counts = def.own_counts();
         let arg_counts = args.own_counts();
         let infer_lifetimes = position != GenericArgPosition::Type && arg_counts.lifetimes == 0;
+        let infer_consts = position != GenericArgPosition::Type && arg_counts.consts == 0;
 
         let mut defaults: ty::GenericParamCount = Default::default();
         for param in &def.params {
@@ -281,6 +283,9 @@ fn check_generic_arg_count(
                 GenericParamDefKind::Type { has_default, .. } => {
                     defaults.types += has_default as usize
                 }
+                GenericParamDefKind::Const => {
+                    // FIXME(const_generics:defaults)
+                }
             };
         }
 
@@ -311,11 +316,15 @@ fn check_generic_arg_count(
             }
         }
 
-        let check_kind_count = |kind,
-                                required,
-                                permitted,
-                                provided,
-                                offset| {
+        let check_kind_count = |kind, required, permitted, provided, offset| {
+            debug!(
+                "check_kind_count: kind: {} required: {} permitted: {} provided: {} offset: {}",
+                kind,
+                required,
+                permitted,
+                provided,
+                offset
+            );
             // We enforce the following: `required` <= `provided` <= `permitted`.
             // For kinds without defaults (i.e., lifetimes), `required == permitted`.
             // For other kinds (i.e., types), `permitted` may be greater than `required`.
@@ -384,6 +393,17 @@ fn check_generic_arg_count(
                 0,
             );
         }
+        // FIXME(const_generics:defaults)
+        if !infer_consts || arg_counts.consts > param_counts.consts {
+            check_kind_count(
+                "const",
+                param_counts.consts,
+                param_counts.consts,
+                arg_counts.consts,
+                arg_counts.lifetimes + arg_counts.types,
+            );
+        }
+        // Note that type errors are currently be emitted *after* const errors.
         if !infer_types
             || arg_counts.types > param_counts.types - defaults.types - has_self as usize {
             check_kind_count(
@@ -495,7 +515,8 @@ pub fn create_substs_for_generic_args<'a, 'b>(
                     (Some(&arg), Some(&param)) => {
                         match (arg, &param.kind) {
                             (GenericArg::Lifetime(_), GenericParamDefKind::Lifetime)
-                            | (GenericArg::Type(_), GenericParamDefKind::Type { .. }) => {
+                            | (GenericArg::Type(_), GenericParamDefKind::Type { .. })
+                            | (GenericArg::Const(_), GenericParamDefKind::Const) => {
                                 substs.push(provided_kind(param, arg));
                                 args.next();
                                 params.next();
@@ -606,6 +627,9 @@ fn create_substs_for_ast_path(&self,
                     (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
                         self.ast_ty_to_ty(&ty).into()
                     }
+                    (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
+                        self.ast_const_to_const(&ct.value, tcx.type_of(param.def_id)).into()
+                    }
                     _ => unreachable!(),
                 }
             },
@@ -654,6 +678,11 @@ fn create_substs_for_ast_path(&self,
                             tcx.types.err.into()
                         }
                     }
+                    GenericParamDefKind::Const => {
+                        // FIXME(const_generics:defaults)
+                        // We've already errored above about the mismatch.
+                        tcx.types.err.into()
+                    }
                 }
             },
         );
@@ -1609,6 +1638,7 @@ pub fn def_ids_for_path_segments(&self,
             // Case 3. Reference to a top-level value.
             Def::Fn(def_id) |
             Def::Const(def_id) |
+            Def::ConstParam(def_id) |
             Def::Static(def_id, _) => {
                 path_segs.push(PathSeg(def_id, last));
             }
@@ -1797,10 +1827,7 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
                 self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, def, segment, false).0
             }
             hir::TyKind::Array(ref ty, ref length) => {
-                let length_def_id = tcx.hir().local_def_id_from_hir_id(length.hir_id);
-                let substs = InternalSubsts::identity_for_item(tcx, length_def_id);
-                let length = ty::LazyConst::Unevaluated(length_def_id, substs);
-                let length = tcx.mk_lazy_const(length);
+                let length = self.ast_const_to_const(length, tcx.types.usize);
                 let array_ty = tcx.mk_ty(ty::Array(self.ast_ty_to_ty(&ty), length));
                 self.normalize_ty(ast_ty.span, array_ty)
             }
@@ -1837,6 +1864,42 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
         result_ty
     }
 
+    pub fn ast_const_to_const(
+        &self,
+        ast_const: &hir::AnonConst,
+        ty: Ty<'tcx>
+    ) -> &'tcx ty::LazyConst<'tcx> {
+        debug!("ast_const_to_const(id={:?}, ast_const={:?})", ast_const.hir_id, ast_const);
+
+        let tcx = self.tcx();
+        let def_id = tcx.hir().local_def_id_from_hir_id(ast_const.hir_id);
+
+        let mut lazy_const = ty::LazyConst::Unevaluated(
+            def_id,
+            InternalSubsts::identity_for_item(tcx, def_id),
+        );
+
+        let expr = &tcx.hir().body(ast_const.body).value;
+        if let ExprKind::Path(ref qpath) = expr.node {
+            if let hir::QPath::Resolved(_, ref path) = qpath {
+                if let Def::ConstParam(def_id) = path.def {
+                    let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+                    let item_id = tcx.hir().get_parent_node(node_id);
+                    let item_def_id = tcx.hir().local_def_id(item_id);
+                    let generics = tcx.generics_of(item_def_id);
+                    let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)];
+                    let name = tcx.hir().name(node_id).as_interned_str();
+                    lazy_const = ty::LazyConst::Evaluated(ty::Const {
+                        val: ConstValue::Param(ty::ParamConst::new(index, name)),
+                        ty,
+                    })
+                }
+            }
+        };
+
+        tcx.mk_lazy_const(lazy_const)
+    }
+
     pub fn impl_trait_ty_to_ty(
         &self,
         def_id: DefId,
index db89b32be7b68d109acbc19f557bdcb747d495de..f7396cbd42f2ff87ecc0e3a3b4a6f68f40ab3bef 100644 (file)
@@ -99,11 +99,13 @@ fn check_closure(
         let substs = base_substs.extend_to(self.tcx,expr_def_id, |param, _| {
             match param.kind {
                 GenericParamDefKind::Lifetime => {
-                    span_bug!(expr.span, "closure has region param")
+                    span_bug!(expr.span, "closure has lifetime param")
                 }
-                GenericParamDefKind::Type {..} => {
-                    self.infcx
-                        .next_ty_var(TypeVariableOrigin::ClosureSynthetic(expr.span)).into()
+                GenericParamDefKind::Type { .. } => {
+                    self.infcx.next_ty_var(TypeVariableOrigin::ClosureSynthetic(expr.span)).into()
+                }
+                GenericParamDefKind::Const => {
+                    span_bug!(expr.span, "closure has const param")
                 }
             }
         });
index e061a5304eb28dbe9f2ccf1230678bdef6ad452d..32640d7d9a886dabcfe31af17dbf0cc6882a5907 100644 (file)
@@ -6,7 +6,7 @@
 use rustc::ty::error::{ExpectedFound, TypeError};
 use rustc::ty::subst::{Subst, InternalSubsts, SubstsRef};
 use rustc::util::common::ErrorReported;
-use errors::Applicability;
+use errors::{Applicability, DiagnosticId};
 
 use syntax_pos::Span;
 
@@ -576,55 +576,78 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     Ok(())
 }
 
-fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                        impl_m: &ty::AssociatedItem,
-                                        impl_m_span: Span,
-                                        trait_m: &ty::AssociatedItem,
-                                        trait_item_span: Option<Span>)
-                                        -> Result<(), ErrorReported> {
-    let impl_m_generics = tcx.generics_of(impl_m.def_id);
-    let trait_m_generics = tcx.generics_of(trait_m.def_id);
-    let num_impl_m_type_params = impl_m_generics.own_counts().types;
-    let num_trait_m_type_params = trait_m_generics.own_counts().types;
-
-    if num_impl_m_type_params != num_trait_m_type_params {
-        let impl_m_node_id = tcx.hir().as_local_node_id(impl_m.def_id).unwrap();
-        let impl_m_item = tcx.hir().expect_impl_item(impl_m_node_id);
-        let span = if impl_m_item.generics.params.is_empty()
-            || impl_m_item.generics.span.is_dummy()  // impl Trait in argument position (#55374)
-        {
-            impl_m_span
-        } else {
-            impl_m_item.generics.span
-        };
+fn compare_number_of_generics<'a, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    impl_: &ty::AssociatedItem,
+    impl_span: Span,
+    trait_: &ty::AssociatedItem,
+    trait_span: Option<Span>,
+) -> Result<(), ErrorReported> {
+    let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts();
+    let impl_own_counts = tcx.generics_of(impl_.def_id).own_counts();
+
+    let matchings = [
+        ("type", trait_own_counts.types, impl_own_counts.types),
+        ("const", trait_own_counts.consts, impl_own_counts.consts),
+    ];
+
+    let mut err_occurred = false;
+    for &(kind, trait_count, impl_count) in &matchings {
+        if impl_count != trait_count {
+            err_occurred = true;
+
+            let impl_node_id = tcx.hir().as_local_node_id(impl_.def_id).unwrap();
+            let impl_item = tcx.hir().expect_impl_item(impl_node_id);
+            let span = if impl_item.generics.params.is_empty()
+                || impl_item.generics.span.is_dummy() { // argument position impl Trait (#55374)
+                impl_span
+            } else {
+                impl_item.generics.span
+            };
 
-        let mut err = struct_span_err!(tcx.sess, span, E0049,
-            "method `{}` has {} but its trait declaration has {}",
-            trait_m.ident,
-            potentially_plural_count(num_impl_m_type_params, "type parameter"),
-            potentially_plural_count(num_trait_m_type_params, "type parameter")
-        );
+            let mut err = tcx.sess.struct_span_err_with_code(
+                span,
+                &format!(
+                    "method `{}` has {} {kind} parameter{} but its trait \
+                     declaration has {} {kind} parameter{}",
+                    trait_.ident,
+                    impl_count,
+                    if impl_count != 1 { "s" } else { "" },
+                    trait_count,
+                    if trait_count != 1 { "s" } else { "" },
+                    kind = kind,
+                ),
+                DiagnosticId::Error("E0049".into()),
+            );
 
-        let mut suffix = None;
+            let mut suffix = None;
 
-        if let Some(span) = trait_item_span {
-            err.span_label(span, format!("expected {}",
-                potentially_plural_count(num_trait_m_type_params, "type parameter")));
-        } else {
-            suffix = Some(format!(", expected {}", num_trait_m_type_params));
-        }
-
-        err.span_label(span,
-                       format!("found {}{}",
-                           potentially_plural_count(num_impl_m_type_params, "type parameter"),
-                           suffix.as_ref().map(|s| &s[..]).unwrap_or("")));
+            if let Some(span) = trait_span {
+                err.span_label(
+                    span,
+                    format!("expected {} {} parameter{}", trait_count, kind,
+                        if trait_count != 1 { "s" } else { "" })
+                );
+            } else {
+                suffix = Some(format!(", expected {}", trait_count));
+            }
 
-        err.emit();
+            err.span_label(
+                span,
+                format!("found {} {} parameter{}{}", impl_count, kind,
+                    if impl_count != 1 { "s" } else { "" },
+                    suffix.unwrap_or_else(|| String::new())),
+            );
 
-        return Err(ErrorReported);
+            err.emit();
+        }
     }
 
-    Ok(())
+    if err_occurred {
+        Err(ErrorReported)
+    } else {
+        Ok(())
+    }
 }
 
 fn compare_number_of_method_arguments<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -725,12 +748,12 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let trait_m_generics = tcx.generics_of(trait_m.def_id);
     let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| match param.kind {
         GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
-        GenericParamDefKind::Lifetime => None,
+        GenericParamDefKind::Lifetime | GenericParamDefKind::Const => None,
     });
     let trait_m_type_params = trait_m_generics.params.iter().filter_map(|param| {
         match param.kind {
             GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
-            GenericParamDefKind::Lifetime => None,
+            GenericParamDefKind::Lifetime | GenericParamDefKind::Const => None,
         }
     });
     for ((impl_def_id, impl_synthetic), (trait_def_id, trait_synthetic))
@@ -760,11 +783,11 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             .source_map()
                             .span_to_snippet(trait_span)
                             .ok()?;
-                        let trait_m = tcx.hir().as_local_node_id(trait_m.def_id)?;
-                        let trait_m = tcx.hir().trait_item(hir::TraitItemId { node_id: trait_m });
+                        let trait_m = tcx.hir().as_local_hir_id(trait_m.def_id)?;
+                        let trait_m = tcx.hir().trait_item(hir::TraitItemId { hir_id: trait_m });
 
-                        let impl_m = tcx.hir().as_local_node_id(impl_m.def_id)?;
-                        let impl_m = tcx.hir().impl_item(hir::ImplItemId { node_id: impl_m });
+                        let impl_m = tcx.hir().as_local_hir_id(impl_m.def_id)?;
+                        let impl_m = tcx.hir().impl_item(hir::ImplItemId { hir_id: impl_m });
 
                         // in case there are no generics, take the spot between the function name
                         // and the opening paren of the argument list
@@ -805,8 +828,8 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 (None, Some(hir::SyntheticTyParamKind::ImplTrait)) => {
                     err.span_label(impl_span, "expected `impl Trait`, found generic parameter");
                     (|| {
-                        let impl_m = tcx.hir().as_local_node_id(impl_m.def_id)?;
-                        let impl_m = tcx.hir().impl_item(hir::ImplItemId { node_id: impl_m });
+                        let impl_m = tcx.hir().as_local_hir_id(impl_m.def_id)?;
+                        let impl_m = tcx.hir().impl_item(hir::ImplItemId { hir_id: impl_m });
                         let input_tys = match impl_m.node {
                             hir::ImplItemKind::Method(ref sig, _) => &sig.decl.inputs,
                             _ => unreachable!(),
index f736e7ac29d080b266c25d6305600178ef8103a1..32ca854b2774469cf9effc8436bbbfb29a2f0189 100644 (file)
@@ -367,6 +367,15 @@ pub fn check_ref(&self,
                         // Maybe remove `&`?
                         hir::ExprKind::AddrOf(_, ref expr) => {
                             if !cm.span_to_filename(expr.span).is_real() {
+                                if let Ok(code) = cm.span_to_snippet(sp) {
+                                    if code.chars().next() == Some('&') {
+                                        return Some((
+                                            sp,
+                                            "consider removing the borrow",
+                                            code[1..].to_string()),
+                                        );
+                                    }
+                                }
                                 return None;
                             }
                             if let Ok(code) = cm.span_to_snippet(expr.span) {
index 12c7484f0f9213c672d99995067c5cbfbf94925f..2184555a07d34e19c7892f392ab32af1bc4de623 100644 (file)
@@ -313,6 +313,9 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>(
         match kind.unpack() {
             UnpackedKind::Lifetime(r) => rcx.sub_regions(origin(), parent_scope, r),
             UnpackedKind::Type(ty) => rcx.type_must_outlive(origin(), ty, parent_scope),
+            UnpackedKind::Const(_) => {
+                // Generic consts don't add constraints.
+            }
         }
     }
     Ok(())
index 924ced2e2a3c77c1cd76729e63734ebd2384fd82..40c60caffa42d8eb7dd81d67af010c49b924e428 100644 (file)
@@ -22,7 +22,7 @@ fn equate_intrinsic_type<'a, 'tcx>(
     inputs: Vec<Ty<'tcx>>,
     output: Ty<'tcx>,
 ) {
-    let def_id = tcx.hir().local_def_id(it.id);
+    let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
 
     match it.node {
         hir::ForeignItemKind::Fn(..) => {}
index 996d6cfd5683069cbce19ebaed5c5995f2baa638..e0b96ae884f3a7e7d2b496d8128ca4744c1191c2 100644 (file)
@@ -341,6 +341,9 @@ fn instantiate_method_substs(
                     (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
                         self.to_ty(ty).into()
                     }
+                    (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
+                        self.to_const(&ct.value, self.tcx.type_of(param.def_id)).into()
+                    }
                     _ => unreachable!(),
                 }
             },
index d81d24e6d2b0356eeac16de309e01ca7aea47c3c..8f27b5b7dc81f746f4048976ebcef9c66534464b 100644 (file)
@@ -283,8 +283,8 @@ pub fn lookup_method_in_trait(&self,
         // Construct a trait-reference `self_ty : Trait<input_tys>`
         let substs = InternalSubsts::for_item(self.tcx, trait_def_id, |param, _| {
             match param.kind {
-                GenericParamDefKind::Lifetime => {}
-                GenericParamDefKind::Type {..} => {
+                GenericParamDefKind::Lifetime | GenericParamDefKind::Const => {}
+                GenericParamDefKind::Type { .. } => {
                     if param.index == 0 {
                         return self_ty.into();
                     } else if let Some(ref input_types) = opt_input_types {
index a4624eebcba830e11304c9c43a7cd03c9394b042..efae870c3c3a9a8dc93ef663cee3f3026c05fe2a 100644 (file)
@@ -1528,7 +1528,10 @@ fn xform_method_sig(&self,
                             // `impl_self_ty()` for an explanation.
                             self.tcx.types.re_erased.into()
                         }
-                        GenericParamDefKind::Type {..} => self.var_for_def(self.span, param),
+                        GenericParamDefKind::Type { .. }
+                        | GenericParamDefKind::Const => {
+                            self.var_for_def(self.span, param)
+                        }
                     }
                 }
             });
@@ -1545,10 +1548,13 @@ fn fresh_item_substs(&self, def_id: DefId) -> SubstsRef<'tcx> {
         InternalSubsts::for_item(self.tcx, def_id, |param, _| {
             match param.kind {
                 GenericParamDefKind::Lifetime => self.tcx.types.re_erased.into(),
-                GenericParamDefKind::Type {..} => {
+                GenericParamDefKind::Type { .. } => {
                     self.next_ty_var(TypeVariableOrigin::SubstitutionPlaceholder(
                         self.tcx.def_span(def_id))).into()
                 }
+                GenericParamDefKind::Const { .. } => {
+                    unimplemented!() // FIXME(const_generics)
+                }
             }
         })
     }
index c15cb1e5bb15140cd804318bd6ac44388ad7229a..4bf6471a6293cc3764768dff2a00576a5452dd51 100644 (file)
@@ -732,7 +732,7 @@ struct Visitor<'a, 'tcx: 'a> {
     impl<'v, 'a, 'tcx> itemlikevisit::ItemLikeVisitor<'v> for Visitor<'a, 'tcx> {
         fn visit_item(&mut self, i: &'v hir::Item) {
             if let hir::ItemKind::Trait(..) = i.node {
-                let def_id = self.map.local_def_id(i.id);
+                let def_id = self.map.local_def_id_from_hir_id(i.hir_id);
                 self.traits.push(def_id);
             }
         }
index 80ffe441561013c5553f9ac483d9532c0b64046f..301d7d3ac5623f61cca545cf4bc920bb7ff171a5 100644 (file)
@@ -1008,9 +1008,10 @@ fn visit_pat(&mut self, p: &'gcx hir::Pat) {
         if let PatKind::Binding(_, _, _, ident, _) = p.node {
             let var_ty = self.assign(p.span, p.hir_id, None);
 
+            let node_id = self.fcx.tcx.hir().hir_to_node_id(p.hir_id);
             if !self.fcx.tcx.features().unsized_locals {
                 self.fcx.require_type_is_sized(var_ty, p.span,
-                                               traits::VariableType(p.id));
+                                               traits::VariableType(node_id));
             }
 
             debug!("Pattern binding {} is assigned to {} with type {:?}",
@@ -1289,9 +1290,9 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
 }
 
 fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                          id: ast::NodeId,
+                          id: hir::HirId,
                           span: Span) {
-    let def_id = tcx.hir().local_def_id(id);
+    let def_id = tcx.hir().local_def_id_from_hir_id(id);
     let def = tcx.adt_def(def_id);
     def.destructor(tcx); // force the destructor to be evaluated
     check_representable(tcx, span, def_id);
@@ -1305,9 +1306,9 @@ fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                         id: ast::NodeId,
+                         id: hir::HirId,
                          span: Span) {
-    let def_id = tcx.hir().local_def_id(id);
+    let def_id = tcx.hir().local_def_id_from_hir_id(id);
     let def = tcx.adt_def(def_id);
     def.destructor(tcx); // force the destructor to be evaluated
     check_representable(tcx, span, def_id);
@@ -1338,28 +1339,28 @@ fn check_opaque<'a, 'tcx>(
 
 pub fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) {
     debug!(
-        "check_item_type(it.id={}, it.name={})",
-        it.id,
-        tcx.item_path_str(tcx.hir().local_def_id(it.id))
+        "check_item_type(it.hir_id={}, it.name={})",
+        it.hir_id,
+        tcx.item_path_str(tcx.hir().local_def_id_from_hir_id(it.hir_id))
     );
     let _indenter = indenter();
     match it.node {
         // Consts can play a role in type-checking, so they are included here.
         hir::ItemKind::Static(..) => {
-            let def_id = tcx.hir().local_def_id(it.id);
+            let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
             tcx.typeck_tables_of(def_id);
             maybe_check_static_with_link_section(tcx, def_id, it.span);
         }
         hir::ItemKind::Const(..) => {
-            tcx.typeck_tables_of(tcx.hir().local_def_id(it.id));
+            tcx.typeck_tables_of(tcx.hir().local_def_id_from_hir_id(it.hir_id));
         }
         hir::ItemKind::Enum(ref enum_definition, _) => {
-            check_enum(tcx, it.span, &enum_definition.variants, it.id);
+            check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
         }
         hir::ItemKind::Fn(..) => {} // entirely within check_item_body
         hir::ItemKind::Impl(.., ref impl_item_refs) => {
-            debug!("ItemKind::Impl {} with id {}", it.ident, it.id);
-            let impl_def_id = tcx.hir().local_def_id(it.id);
+            debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
+            let impl_def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
             if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
                 check_impl_items_against_trait(
                     tcx,
@@ -1373,23 +1374,23 @@ pub fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Ite
             }
         }
         hir::ItemKind::Trait(..) => {
-            let def_id = tcx.hir().local_def_id(it.id);
+            let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
             check_on_unimplemented(tcx, def_id, it);
         }
         hir::ItemKind::Struct(..) => {
-            check_struct(tcx, it.id, it.span);
+            check_struct(tcx, it.hir_id, it.span);
         }
         hir::ItemKind::Union(..) => {
-            check_union(tcx, it.id, it.span);
+            check_union(tcx, it.hir_id, it.span);
         }
         hir::ItemKind::Existential(..) => {
-            let def_id = tcx.hir().local_def_id(it.id);
+            let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
 
             let substs = InternalSubsts::identity_for_item(tcx, def_id);
             check_opaque(tcx, def_id, substs, it.span);
         }
         hir::ItemKind::Ty(..) => {
-            let def_id = tcx.hir().local_def_id(it.id);
+            let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
             let pty_ty = tcx.type_of(def_id);
             let generics = tcx.generics_of(def_id);
             check_bounds_are_used(tcx, &generics, pty_ty);
@@ -1407,7 +1408,7 @@ pub fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Ite
                 }
             } else {
                 for item in &m.items {
-                    let generics = tcx.generics_of(tcx.hir().local_def_id(item.id));
+                    let generics = tcx.generics_of(tcx.hir().local_def_id_from_hir_id(item.hir_id));
                     if generics.params.len() - generics.own_counts().lifetimes != 0 {
                         let mut err = struct_span_err!(
                             tcx.sess,
@@ -1476,7 +1477,7 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_, '_, '_>, id: DefId, span
 fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                     trait_def_id: DefId,
                                     item: &hir::Item) {
-    let item_def_id = tcx.hir().local_def_id(item.id);
+    let item_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id);
     // an error would be reported if this fails.
     let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
 }
@@ -1842,8 +1843,8 @@ fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: De
 pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             sp: Span,
                             vs: &'tcx [hir::Variant],
-                            id: ast::NodeId) {
-    let def_id = tcx.hir().local_def_id(id);
+                            id: hir::HirId) {
+    let def_id = tcx.hir().local_def_id_from_hir_id(id);
     let def = tcx.adt_def(def_id);
     def.destructor(tcx); // force the destructor to be evaluated
 
@@ -2436,6 +2437,10 @@ pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
         ty
     }
 
+    pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
+        AstConv::ast_const_to_const(self, ast_c, ty)
+    }
+
     // If the type given by the user has free regions, save it for later, since
     // NLL would like to enforce those. Also pass in types that involve
     // projections, since those can resolve to `'static` bounds (modulo #54940,
@@ -5500,6 +5505,9 @@ pub fn instantiate_value_path(&self,
                     (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
                         self.to_ty(ty).into()
                     }
+                    (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
+                        self.to_const(&ct.value, self.tcx.type_of(param.def_id)).into()
+                    }
                     _ => unreachable!(),
                 }
             },
@@ -5527,6 +5535,11 @@ pub fn instantiate_value_path(&self,
                             self.var_for_def(span, param)
                         }
                     }
+                    GenericParamDefKind::Const => {
+                        // FIXME(const_generics:defaults)
+                        // No const parameters were provided, we have to infer them.
+                        self.var_for_def(span, param)
+                    }
                 }
             },
         );
@@ -5684,11 +5697,19 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                        generics: &ty::Generics,
                                        ty: Ty<'tcx>) {
     let own_counts = generics.own_counts();
-    debug!("check_bounds_are_used(n_tps={}, ty={:?})", own_counts.types, ty);
+    debug!(
+        "check_bounds_are_used(n_tys={}, n_cts={}, ty={:?})",
+        own_counts.types,
+        own_counts.consts,
+        ty
+    );
+
+    // FIXME(const_generics): we probably want to check the bounds for const parameters too.
 
     if own_counts.types == 0 {
         return;
     }
+
     // Make a vector of booleans initially false, set to true when used.
     let mut types_used = vec![false; own_counts.types];
 
index b549986777c84dcbd7f1da5fefc36db5d1ae48d2..a03d33a3ef5bc4842849e3ee8d4b0cecbf350167 100644 (file)
@@ -81,7 +81,7 @@
 use rustc::infer::outlives::env::OutlivesEnvironment;
 use rustc::infer::{self, RegionObligation, SuppressRegionErrors};
 use rustc::ty::adjustment;
-use rustc::ty::subst::SubstsRef;
+use rustc::ty::subst::{SubstsRef, UnpackedKind};
 use rustc::ty::{self, Ty};
 
 use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
@@ -1407,13 +1407,19 @@ fn substs_wf_in_scope(
 
         let origin = infer::ParameterInScope(origin, expr_span);
 
-        for region in substs.regions() {
-            self.sub_regions(origin.clone(), expr_region, region);
-        }
-
-        for ty in substs.types() {
-            let ty = self.resolve_type(ty);
-            self.type_must_outlive(origin.clone(), ty, expr_region);
+        for kind in substs {
+            match kind.unpack() {
+                UnpackedKind::Lifetime(lt) => {
+                    self.sub_regions(origin.clone(), expr_region, lt);
+                }
+                UnpackedKind::Type(ty) => {
+                    let ty = self.resolve_type(ty);
+                    self.type_must_outlive(origin.clone(), ty, expr_region);
+                }
+                UnpackedKind::Const(_) => {
+                    // Const parameters don't impose constraints.
+                }
+            }
         }
     }
 }
index bf6f4482e746d48807ad994dc655c281b9a936fd..89e8b2b840d1fee0e5c7ed9392f271a87fd9984b 100644 (file)
@@ -635,7 +635,7 @@ fn borrow(
         }
     }
 
-    fn decl_without_init(&mut self, _id: ast::NodeId, _span: Span) {}
+    fn decl_without_init(&mut self, _id: hir::HirId, _span: Span) {}
 
     fn mutate(
         &mut self,
index 1c764b724898654cd411ed6cdefebe62df91cd17..388e8282ee3a3aaa5db328983e6f3697b7eab02b 100644 (file)
@@ -6,6 +6,7 @@
 use rustc::ty::{self, Lift, Ty, TyCtxt, TyKind, GenericParamDefKind, TypeFoldable, ToPredicate};
 use rustc::ty::subst::{Subst, InternalSubsts};
 use rustc::util::nodemap::{FxHashSet, FxHashMap};
+use rustc::mir::interpret::ConstValue;
 use rustc::middle::lang_items;
 use rustc::infer::opaque_types::may_define_existential_type;
 
@@ -241,7 +242,7 @@ fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 {
     for_item(tcx, item).with_fcx(|fcx, fcx_tcx| {
         let variants = lookup_fields(fcx);
-        let def_id = fcx.tcx.hir().local_def_id(item.id);
+        let def_id = fcx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
         let packed = fcx.tcx.adt_def(def_id).repr.packed();
 
         for variant in &variants {
@@ -302,9 +303,9 @@ fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
-    debug!("check_trait: {:?}", item.id);
+    debug!("check_trait: {:?}", item.hir_id);
 
-    let trait_def_id = tcx.hir().local_def_id(item.id);
+    let trait_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id);
 
     let trait_def = tcx.trait_def(trait_def_id);
     if trait_def.is_marker {
@@ -326,7 +327,7 @@ fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
 
 fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
     for_item(tcx, item).with_fcx(|fcx, tcx| {
-        let def_id = fcx.tcx.hir().local_def_id(item.id);
+        let def_id = fcx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
         let sig = fcx.tcx.fn_sig(def_id);
         let sig = fcx.normalize_associated_types_in(item.span, &sig);
         let mut implied_bounds = vec![];
@@ -376,7 +377,7 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     debug!("check_impl: {:?}", item);
 
     for_item(tcx, item).with_fcx(|fcx, tcx| {
-        let item_def_id = fcx.tcx.hir().local_def_id(item.id);
+        let item_def_id = fcx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
 
         match *ast_trait_ref {
             Some(ref ast_trait_ref) => {
@@ -436,7 +437,7 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
     // struct Foo<T = Vec<[u32]>> { .. }
     // Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
     for param in &generics.params {
-        if let GenericParamDefKind::Type {..} = param.kind {
+        if let GenericParamDefKind::Type { .. } = param.kind {
             if is_our_default(&param) {
                 let ty = fcx.tcx.type_of(param.def_id);
                 // ignore dependent defaults -- that is, where the default of one type
@@ -464,7 +465,7 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
                 // All regions are identity.
                 fcx.tcx.mk_param_from_def(param)
             }
-            GenericParamDefKind::Type {..} => {
+            GenericParamDefKind::Type { .. } => {
                 // If the param has a default,
                 if is_our_default(param) {
                     let default_ty = fcx.tcx.type_of(param.def_id);
@@ -477,6 +478,10 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
                 // Mark unwanted params as err.
                 fcx.tcx.types.err.into()
             }
+            GenericParamDefKind::Const => {
+                // FIXME(const_generics:defaults)
+                fcx.tcx.types.err.into()
+            }
         }
     });
     // Now we build the substituted predicates.
@@ -497,6 +502,16 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
             fn visit_region(&mut self, _: ty::Region<'tcx>) -> bool {
                 true
             }
+
+            fn visit_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> bool {
+                if let ty::LazyConst::Evaluated(ty::Const {
+                    val: ConstValue::Param(param),
+                    ..
+                }) = c {
+                    self.params.insert(param.index);
+                }
+                c.super_visit_with(self)
+            }
         }
         let mut param_count = CountParams::default();
         let has_region = pred.visit_with(&mut param_count);
@@ -617,11 +632,10 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
                         for (subst, param) in substs.iter().zip(&generics.params) {
                             match subst.unpack() {
                                 ty::subst::UnpackedKind::Type(ty) => match ty.sty {
-                                    ty::Param(..) => {},
+                                    ty::Param(..) => {}
                                     // prevent `fn foo() -> Foo<u32>` from being defining
                                     _ => {
-                                        tcx
-                                            .sess
+                                        tcx.sess
                                             .struct_span_err(
                                                 span,
                                                 "non-defining existential type use \
@@ -636,8 +650,9 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
                                                 ),
                                             )
                                             .emit();
-                                    },
-                                }, // match ty
+                                    }
+                                }
+
                                 ty::subst::UnpackedKind::Lifetime(region) => {
                                     let param_span = tcx.def_span(param.def_id);
                                     if let ty::ReStatic = region {
@@ -658,7 +673,31 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
                                     } else {
                                         seen.entry(region).or_default().push(param_span);
                                     }
-                                },
+                                }
+
+                                ty::subst::UnpackedKind::Const(ct) => match ct {
+                                    ty::LazyConst::Evaluated(ty::Const {
+                                        val: ConstValue::Param(_),
+                                        ..
+                                    }) => {}
+                                    _ => {
+                                        tcx.sess
+                                            .struct_span_err(
+                                                span,
+                                                "non-defining existential type use \
+                                                in defining scope",
+                                            )
+                                            .span_note(
+                                                tcx.def_span(param.def_id),
+                                                &format!(
+                                                    "used non-generic const {} for \
+                                                    generic parameter",
+                                                    ty,
+                                                ),
+                                            )
+                                            .emit();
+                                    }
+                                }
                             } // match subst
                         } // for (subst, param)
                         for (_, spans) in seen {
@@ -889,7 +928,7 @@ fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                            item: &hir::Item,
                                            hir_generics: &hir::Generics)
 {
-    let item_def_id = tcx.hir().local_def_id(item.id);
+    let item_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id);
     let ty = tcx.type_of(item_def_id);
     if tcx.has_error_field(ty) {
         return;
@@ -944,7 +983,9 @@ fn reject_shadowing_parameters(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) {
     let parent = tcx.generics_of(generics.parent.unwrap());
     let impl_params: FxHashMap<_, _> = parent.params.iter().flat_map(|param| match param.kind {
         GenericParamDefKind::Lifetime => None,
-        GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
+        GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => {
+            Some((param.name, param.def_id))
+        }
     }).collect();
 
     for method_param in &generics.params {
@@ -1020,7 +1061,7 @@ pub fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>)
 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckTypeWellFormedVisitor<'a, 'tcx> {
     fn visit_item(&mut self, i: &'tcx hir::Item) {
         debug!("visit_item: {:?}", i);
-        let def_id = self.tcx.hir().local_def_id(i.id);
+        let def_id = self.tcx.hir().local_def_id_from_hir_id(i.hir_id);
         self.tcx.ensure().check_item_well_formed(def_id);
     }
 
@@ -1052,7 +1093,7 @@ struct AdtField<'tcx> {
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     fn non_enum_variant(&self, struct_def: &hir::VariantData) -> AdtVariant<'tcx> {
         let fields = struct_def.fields().iter().map(|field| {
-            let field_ty = self.tcx.type_of(self.tcx.hir().local_def_id(field.id));
+            let field_ty = self.tcx.type_of(self.tcx.hir().local_def_id_from_hir_id(field.hir_id));
             let field_ty = self.normalize_associated_types_in(field.span,
                                                               &field_ty);
             AdtField { ty: field_ty, span: field.span }
index 4c6d7710009bf9dd502c5b7931c571f8021c6b44..6079f12936b5cf0fde634627ddf93f4eea7fdb33 100644 (file)
@@ -212,7 +212,7 @@ struct ExternCrateToLint {
 impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CollectExternCrateVisitor<'a, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
         if let hir::ItemKind::ExternCrate(orig_name) = item.node {
-            let extern_crate_def_id = self.tcx.hir().local_def_id(item.id);
+            let extern_crate_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
             self.crates_to_lint.push(
                 ExternCrateToLint {
                     def_id: extern_crate_def_id,
index 93cc86423ace314ac1a494ca3021996da3da5552..d167c7fcafbe4807ce8f7a0bf7bb44623e14c730 100644 (file)
@@ -85,7 +85,7 @@ fn visit_item(&mut self, item: &hir::Item) {
             _ => return
         };
 
-        let def_id = self.tcx.hir().local_def_id(item.id);
+        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
         let self_ty = self.tcx.type_of(def_id);
         let lang_items = self.tcx.lang_items();
         match self_ty.sty {
@@ -288,7 +288,7 @@ fn check_def_id(&mut self, item: &hir::Item, def_id: DefId) {
             // Add the implementation to the mapping from implementation to base
             // type def ID, if there is a base type for this implementation and
             // the implementation does not have any associated traits.
-            let impl_def_id = self.tcx.hir().local_def_id(item.id);
+            let impl_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
             let mut rc_vec = self.impls_map.inherent_impls
                                            .entry(def_id)
                                            .or_default();
index a51f45a6ff8f3e30785723838b6672e7784e8cb1..832c172e97c18e79f089d82e1fbc47558f864b41 100644 (file)
@@ -120,7 +120,7 @@ fn visit_item(&mut self, item: &'v hir::Item) {
             hir::ItemKind::Struct(..) |
             hir::ItemKind::Trait(..) |
             hir::ItemKind::Union(..) => {
-                let type_def_id = self.tcx.hir().local_def_id(item.id);
+                let type_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
                 self.check_for_overlapping_inherent_impls(type_def_id);
             }
             _ => {}
index b776a980b7c9797aeb1cc024164675071d95459e..c875b856f3a4f1805af5a3eccc8871ee04e5d676 100644 (file)
@@ -22,11 +22,11 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
     /// to prevent inundating the user with a bunch of similar error
     /// reports.
     fn visit_item(&mut self, item: &hir::Item) {
-        let def_id = self.tcx.hir().local_def_id(item.id);
+        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
         // "Trait" impl
         if let hir::ItemKind::Impl(.., Some(_), _, _) = item.node {
             debug!("coherence2::orphan check: trait impl {}",
-                   self.tcx.hir().node_to_string(item.id));
+                   self.tcx.hir().hir_to_string(item.hir_id));
             let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
             let trait_def_id = trait_ref.def_id;
             let cm = self.tcx.sess.source_map();
index 81ef4de3d80e58146eb67eec6f8a03e7295a2acf..0b1de510aa4bde686ef7ef797222e39457481bef 100644 (file)
@@ -21,7 +21,8 @@ fn check_unsafety_coherence(&mut self,
                                 unsafety: hir::Unsafety,
                                 polarity: hir::ImplPolarity)
     {
-        if let Some(trait_ref) = self.tcx.impl_trait_ref(self.tcx.hir().local_def_id(item.id)) {
+        let local_did = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        if let Some(trait_ref) = self.tcx.impl_trait_ref(local_did) {
             let trait_def = self.tcx.trait_def(trait_ref.def_id);
             let unsafe_attr = impl_generics.and_then(|generics| {
                 generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle")
index 16102ad4cde30703d8715138d4bfcc32651fabaf..eb4bbe880693b77b50cfc5912f6656f0de2772de 100644 (file)
@@ -118,7 +118,7 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
-        convert_item(self.tcx, item.id);
+        convert_item(self.tcx, item.hir_id);
         intravisit::walk_item(self, item);
     }
 
@@ -397,10 +397,10 @@ fn is_param<'a, 'tcx>(
     }
 }
 
-fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
-    let it = tcx.hir().expect_item(item_id);
-    debug!("convert: item {} with id {}", it.ident, it.id);
-    let def_id = tcx.hir().local_def_id(item_id);
+fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: hir::HirId) {
+    let it = tcx.hir().expect_item_by_hir_id(item_id);
+    debug!("convert: item {} with id {}", it.ident, it.hir_id);
+    let def_id = tcx.hir().local_def_id_from_hir_id(item_id);
     match it.node {
         // These don't define types.
         hir::ItemKind::ExternCrate(_)
@@ -409,7 +409,7 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
         | hir::ItemKind::GlobalAsm(_) => {}
         hir::ItemKind::ForeignMod(ref foreign_mod) => {
             for item in &foreign_mod.items {
-                let def_id = tcx.hir().local_def_id(item.id);
+                let def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id);
                 tcx.generics_of(def_id);
                 tcx.type_of(def_id);
                 tcx.predicates_of(def_id);
@@ -447,14 +447,14 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
             tcx.predicates_of(def_id);
 
             for f in struct_def.fields() {
-                let def_id = tcx.hir().local_def_id(f.id);
+                let def_id = tcx.hir().local_def_id_from_hir_id(f.hir_id);
                 tcx.generics_of(def_id);
                 tcx.type_of(def_id);
                 tcx.predicates_of(def_id);
             }
 
             if !struct_def.is_struct() {
-                convert_variant_ctor(tcx, struct_def.id());
+                convert_variant_ctor(tcx, struct_def.hir_id());
             }
         }
 
@@ -510,8 +510,8 @@ fn convert_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_item_id: hir::H
     }
 }
 
-fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ctor_id: ast::NodeId) {
-    let def_id = tcx.hir().local_def_id(ctor_id);
+fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ctor_id: hir::HirId) {
+    let def_id = tcx.hir().local_def_id_from_hir_id(ctor_id);
     tcx.generics_of(def_id);
     tcx.type_of(def_id);
     tcx.predicates_of(def_id);
@@ -555,7 +555,7 @@ fn convert_enum_variant_types<'a, 'tcx>(
         );
 
         for f in variant.node.data.fields() {
-            let def_id = tcx.hir().local_def_id(f.id);
+            let def_id = tcx.hir().local_def_id_from_hir_id(f.hir_id);
             tcx.generics_of(def_id);
             tcx.type_of(def_id);
             tcx.predicates_of(def_id);
@@ -563,7 +563,7 @@ fn convert_enum_variant_types<'a, 'tcx>(
 
         // Convert the ctor, if any. This also registers the variant as
         // an item.
-        convert_variant_ctor(tcx, variant.node.data.id());
+        convert_variant_ctor(tcx, variant.node.data.hir_id());
     }
 }
 
@@ -577,12 +577,12 @@ fn convert_variant<'a, 'tcx>(
     attribute_def_id: DefId
 ) -> ty::VariantDef {
     let mut seen_fields: FxHashMap<ast::Ident, Span> = Default::default();
-    let node_id = tcx.hir().as_local_node_id(did).unwrap();
+    let hir_id = tcx.hir().as_local_hir_id(did).unwrap();
     let fields = def
         .fields()
         .iter()
         .map(|f| {
-            let fid = tcx.hir().local_def_id(f.id);
+            let fid = tcx.hir().local_def_id_from_hir_id(f.hir_id);
             let dup_span = seen_fields.get(&f.ident.modern()).cloned();
             if let Some(prev_span) = dup_span {
                 struct_span_err!(
@@ -601,7 +601,7 @@ fn convert_variant<'a, 'tcx>(
             ty::FieldDef {
                 did: fid,
                 ident: f.ident,
-                vis: ty::Visibility::from_hir(&f.vis, node_id, tcx),
+                vis: ty::Visibility::from_hir(&f.vis, hir_id, tcx),
             }
         })
         .collect();
@@ -634,7 +634,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
                 def.variants
                     .iter()
                     .map(|v| {
-                        let did = tcx.hir().local_def_id(v.node.data.id());
+                        let did = tcx.hir().local_def_id_from_hir_id(v.node.data.hir_id());
                         let discr = if let Some(ref e) = v.node.disr_expr {
                             distance_from_explicit = 0;
                             ty::VariantDiscr::Explicit(tcx.hir().local_def_id_from_hir_id(e.hir_id))
@@ -652,7 +652,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
         ItemKind::Struct(ref def, _) => {
             // Use separate constructor id for unit/tuple structs and reuse did for braced structs.
             let ctor_id = if !def.is_struct() {
-                Some(tcx.hir().local_def_id(def.id()))
+                Some(tcx.hir().local_def_id_from_hir_id(def.hir_id()))
             } else {
                 None
             };
@@ -937,12 +937,12 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty
                     //
                     // Something of a hack: use the node id for the trait, also as
                     // the node id for the Self type parameter.
-                    let param_id = item.id;
+                    let param_id = item.hir_id;
 
                     opt_self = Some(ty::GenericParamDef {
                         index: 0,
                         name: keywords::SelfUpper.name().as_interned_str(),
-                        def_id: tcx.hir().local_def_id(param_id),
+                        def_id: tcx.hir().local_def_id_from_hir_id(param_id),
                         pure_wrt_drop: false,
                         kind: ty::GenericParamDefKind::Type {
                             has_default: false,
@@ -1004,67 +1004,65 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty
         ast_generics
             .params
             .iter()
-            .filter_map(|param| match param.kind {
-                GenericParamKind::Type {
-                    ref default,
-                    synthetic,
-                    ..
-                } => {
-                    if param.name.ident().name == keywords::SelfUpper.name() {
-                        span_bug!(
-                            param.span,
-                            "`Self` should not be the name of a regular parameter"
-                        );
-                    }
-
-                    if !allow_defaults && default.is_some() {
-                        if !tcx.features().default_type_parameter_fallback {
-                            tcx.lint_hir(
-                                lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
-                                param.hir_id,
+            .filter_map(|param| {
+                let kind = match param.kind {
+                    GenericParamKind::Type {
+                        ref default,
+                        synthetic,
+                        ..
+                    } => {
+                        if param.name.ident().name == keywords::SelfUpper.name() {
+                            span_bug!(
                                 param.span,
-                                &format!(
-                                    "defaults for type parameters are only allowed in \
-                                     `struct`, `enum`, `type`, or `trait` definitions."
-                                ),
+                                "`Self` should not be the name of a regular parameter"
                             );
                         }
-                    }
 
-                    let ty_param = ty::GenericParamDef {
-                        index: type_start + i as u32,
-                        name: param.name.ident().as_interned_str(),
-                        def_id: tcx.hir().local_def_id_from_hir_id(param.hir_id),
-                        pure_wrt_drop: param.pure_wrt_drop,
-                        kind: ty::GenericParamDefKind::Type {
+                        if !allow_defaults && default.is_some() {
+                            if !tcx.features().default_type_parameter_fallback {
+                                tcx.lint_hir(
+                                    lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
+                                    param.hir_id,
+                                    param.span,
+                                    &format!(
+                                        "defaults for type parameters are only allowed in \
+                                        `struct`, `enum`, `type`, or `trait` definitions."
+                                    ),
+                                );
+                            }
+                        }
+
+                        ty::GenericParamDefKind::Type {
                             has_default: default.is_some(),
                             object_lifetime_default: object_lifetime_defaults
                                 .as_ref()
                                 .map_or(rl::Set1::Empty, |o| o[i]),
                             synthetic,
-                        },
-                    };
-                    i += 1;
-                    Some(ty_param)
-                }
-                GenericParamKind::Const { .. } => {
-                    if param.name.ident().name == keywords::SelfUpper.name() {
-                        span_bug!(
-                            param.span,
-                            "`Self` should not be the name of a regular parameter",
-                        );
+                        }
                     }
+                    GenericParamKind::Const { .. } => {
+                        if param.name.ident().name == keywords::SelfUpper.name() {
+                            span_bug!(
+                                param.span,
+                                "`Self` should not be the name of a regular parameter",
+                            );
+                        }
 
-                    // Emit an error, but skip the parameter rather than aborting to
-                    // continue to get other errors.
-                    tcx.sess.struct_span_err(
-                        param.span,
-                        "const generics in any position are currently unsupported",
-                    ).emit();
-                    None
-                }
-                _ => None,
-            }),
+                        ty::GenericParamDefKind::Const
+                    }
+                    _ => return None,
+                };
+
+                let param_def = ty::GenericParamDef {
+                    index: type_start + i as u32,
+                    name: param.name.ident().as_interned_str(),
+                    def_id: tcx.hir().local_def_id_from_hir_id(param.hir_id),
+                    pure_wrt_drop: param.pure_wrt_drop,
+                    kind,
+                };
+                i += 1;
+                Some(param_def)
+            })
     );
 
     // provide junk type parameter defs - the only place that
@@ -1284,44 +1282,111 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
             tcx.mk_closure(def_id, substs)
         }
 
-        Node::AnonConst(_) => match tcx.hir().get_by_hir_id(
-            tcx.hir().get_parent_node_by_hir_id(hir_id))
-        {
-            Node::Ty(&hir::Ty {
-                node: hir::TyKind::Array(_, ref constant),
-                ..
-            })
-            | Node::Ty(&hir::Ty {
-                node: hir::TyKind::Typeof(ref constant),
-                ..
-            })
-            | Node::Expr(&hir::Expr {
-                node: ExprKind::Repeat(_, ref constant),
-                ..
-            }) if constant.hir_id == hir_id =>
-            {
-                tcx.types.usize
-            }
+        Node::AnonConst(_) => {
+            let parent_node = tcx.hir().get_by_hir_id(tcx.hir().get_parent_node_by_hir_id(hir_id));
+            match parent_node {
+                Node::Ty(&hir::Ty {
+                    node: hir::TyKind::Array(_, ref constant),
+                    ..
+                })
+                | Node::Ty(&hir::Ty {
+                    node: hir::TyKind::Typeof(ref constant),
+                    ..
+                })
+                | Node::Expr(&hir::Expr {
+                    node: ExprKind::Repeat(_, ref constant),
+                    ..
+                }) if constant.hir_id == hir_id =>
+                {
+                    tcx.types.usize
+                }
 
-            Node::Variant(&Spanned {
-                node:
-                    VariantKind {
-                        disr_expr: Some(ref e),
-                        ..
-                    },
-                ..
-            }) if e.hir_id == hir_id =>
-            {
-                tcx.adt_def(tcx.hir().get_parent_did_by_hir_id(hir_id))
-                    .repr
-                    .discr_type()
-                    .to_ty(tcx)
-            }
+                Node::Variant(&Spanned {
+                    node:
+                        VariantKind {
+                            disr_expr: Some(ref e),
+                            ..
+                        },
+                    ..
+                }) if e.hir_id == hir_id =>
+                {
+                    tcx.adt_def(tcx.hir().get_parent_did_by_hir_id(hir_id))
+                        .repr
+                        .discr_type()
+                        .to_ty(tcx)
+                }
 
-            x => {
-                bug!("unexpected const parent in type_of_def_id(): {:?}", x);
+                Node::Ty(&hir::Ty { node: hir::TyKind::Path(_), .. }) |
+                Node::Expr(&hir::Expr { node: ExprKind::Struct(..), .. }) |
+                Node::Expr(&hir::Expr { node: ExprKind::Path(_), .. }) => {
+                    let path = match parent_node {
+                        Node::Ty(&hir::Ty { node: hir::TyKind::Path(ref path), .. }) |
+                        Node::Expr(&hir::Expr { node: ExprKind::Path(ref path), .. }) => {
+                            path
+                        }
+                        Node::Expr(&hir::Expr { node: ExprKind::Struct(ref path, ..), .. }) => {
+                            &*path
+                        }
+                        _ => unreachable!(),
+                    };
+
+                    match path {
+                        QPath::Resolved(_, ref path) => {
+                            let mut arg_index = 0;
+                            let mut found_const = false;
+                            for seg in &path.segments {
+                                if let Some(generic_args) = &seg.args {
+                                    let args = &generic_args.args;
+                                    for arg in args {
+                                        if let GenericArg::Const(ct) = arg {
+                                            if ct.value.hir_id == hir_id {
+                                                found_const = true;
+                                                break;
+                                            }
+                                            arg_index += 1;
+                                        }
+                                    }
+                                }
+                            }
+                            // Sanity check to make sure everything is as expected.
+                            if !found_const {
+                                bug!("no arg matching AnonConst in path")
+                            }
+                            match path.def {
+                                // We've encountered an `AnonConst` in some path, so we need to
+                                // figure out which generic parameter it corresponds to and return
+                                // the relevant type.
+                                Def::Struct(def_id)
+                                | Def::Union(def_id)
+                                | Def::Enum(def_id)
+                                | Def::Fn(def_id) => {
+                                    let generics = tcx.generics_of(def_id);
+                                    let mut param_index = 0;
+                                    for param in &generics.params {
+                                        if let ty::GenericParamDefKind::Const = param.kind {
+                                            if param_index == arg_index {
+                                                return tcx.type_of(param.def_id);
+                                            }
+                                            param_index += 1;
+                                        }
+                                    }
+                                    // This is no generic parameter associated with the arg. This is
+                                    // probably from an extra arg where one is not needed.
+                                    return tcx.types.err;
+                                }
+                                Def::Err => tcx.types.err,
+                                x => bug!("unexpected const parent path def {:?}", x),
+                            }
+                        }
+                        x => bug!("unexpected const parent path {:?}", x),
+                    }
+                }
+
+                x => {
+                    bug!("unexpected const parent in type_of_def_id(): {:?}", x);
+                }
             }
-        },
+        }
 
         Node::GenericParam(param) => match &param.kind {
             hir::GenericParamKind::Type { default: Some(ref ty), .. } |
@@ -1477,7 +1542,7 @@ fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'thi
             intravisit::NestedVisitorMap::All(&self.tcx.hir())
         }
         fn visit_item(&mut self, it: &'tcx Item) {
-            let def_id = self.tcx.hir().local_def_id(it.id);
+            let def_id = self.tcx.hir().local_def_id_from_hir_id(it.hir_id);
             // the existential type itself or its children are not within its reveal scope
             if def_id != self.def_id {
                 self.check(def_id);
@@ -1577,7 +1642,7 @@ fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::PolyFnSig
             let ty = tcx.type_of(tcx.hir().get_parent_did(node_id));
             let inputs = fields
                 .iter()
-                .map(|f| tcx.type_of(tcx.hir().local_def_id(f.id)));
+                .map(|f| tcx.type_of(tcx.hir().local_def_id_from_hir_id(f.hir_id)));
             ty::Binder::bind(tcx.mk_fn_sig(
                 inputs,
                 ty,
index 6a530f454d2b3ac59d296b38486ff4c3487e72ba..4b922c3403886c5e851f144c44c5028e283cf350 100644 (file)
@@ -1,6 +1,7 @@
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::fold::{TypeFoldable, TypeVisitor};
 use rustc::util::nodemap::FxHashSet;
+use rustc::mir::interpret::ConstValue;
 use syntax::source_map::Span;
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
@@ -14,6 +15,10 @@ impl From<ty::EarlyBoundRegion> for Parameter {
     fn from(param: ty::EarlyBoundRegion) -> Self { Parameter(param.index) }
 }
 
+impl From<ty::ParamConst> for Parameter {
+    fn from(param: ty::ParamConst) -> Self { Parameter(param.index) }
+}
+
 /// Returns the set of parameters constrained by the impl header.
 pub fn parameters_for_impl<'tcx>(impl_self_ty: Ty<'tcx>,
                                  impl_trait_ref: Option<ty::TraitRef<'tcx>>)
@@ -72,6 +77,16 @@ fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
         }
         false
     }
+
+    fn visit_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> bool {
+        if let ty::LazyConst::Evaluated(ty::Const {
+            val: ConstValue::Param(data),
+            ..
+        }) = c {
+            self.parameters.push(Parameter::from(*data));
+        }
+        false
+    }
 }
 
 pub fn identify_constrained_type_params<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>,
index feff79dc3f5089308cc37564db91c3e83100d62c..399cd6f890c25d171f086624852524615d67a967 100644 (file)
@@ -423,7 +423,7 @@ fn foo() {} // ok!
 
 E0049: r##"
 This error indicates that an attempted implementation of a trait method
-has the wrong number of type parameters.
+has the wrong number of type or const parameters.
 
 For example, the trait below has a method `foo` with a type parameter `T`,
 but the implementation of `foo` for the type `Bar` is missing this parameter:
@@ -1032,6 +1032,7 @@ enum NightsWatch {}
 ```
 "##,
 
+// FIXME(const_generics:docs): example of inferring const parameter.
 E0087: r##"
 #### Note: this error code is no longer emitted by the compiler.
 
@@ -1152,8 +1153,8 @@ fn main() {
 "##,
 
 E0091: r##"
-You gave an unnecessary type parameter in a type alias. Erroneous code
-example:
+You gave an unnecessary type or const parameter in a type alias. Erroneous
+code example:
 
 ```compile_fail,E0091
 type Foo<T> = u32; // error: type parameter `T` is unused
@@ -1161,7 +1162,7 @@ fn main() {
 type Foo<A,B> = Box<A>; // error: type parameter `B` is unused
 ```
 
-Please check you didn't write too many type parameters. Example:
+Please check you didn't write too many parameters. Example:
 
 ```
 type Foo = u32; // ok!
index ed39874eeaadafa880f0b5fd0c6574e609651af8..5677f2c94d8e26f6402a6cfbbd84fc06d02b22ce 100644 (file)
@@ -79,7 +79,7 @@ struct ImplWfCheck<'a, 'tcx: 'a> {
 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for ImplWfCheck<'a, 'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         if let hir::ItemKind::Impl(.., ref impl_item_refs) = item.node {
-            let impl_def_id = self.tcx.hir().local_def_id(item.id);
+            let impl_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
             enforce_impl_params_are_constrained(self.tcx,
                                                 impl_def_id,
                                                 impl_item_refs);
@@ -108,7 +108,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     // Disallow unconstrained lifetimes, but only if they appear in assoc types.
     let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs.iter()
-        .map(|item_ref| tcx.hir().local_def_id(item_ref.id.node_id))
+        .map(|item_ref| tcx.hir().local_def_id_from_hir_id(item_ref.id.hir_id))
         .filter(|&def_id| {
             let item = tcx.associated_item(def_id);
             item.kind == ty::AssociatedKind::Type && item.defaultness.has_value()
@@ -120,7 +120,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     for param in &impl_generics.params {
         match param.kind {
             // Disallow ANY unconstrained type parameters.
-            ty::GenericParamDefKind::Type {..} => {
+            ty::GenericParamDefKind::Type { .. } => {
                 let param_ty = ty::ParamTy::for_def(param);
                 if !input_parameters.contains(&ctp::Parameter::from(param_ty)) {
                     report_unused_parameter(tcx,
@@ -139,6 +139,15 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                             &param.name.to_string());
                 }
             }
+            ty::GenericParamDefKind::Const => {
+                let param_ct = ty::ParamConst::for_def(param);
+                if !input_parameters.contains(&ctp::Parameter::from(param_ct)) {
+                    report_unused_parameter(tcx,
+                                           tcx.def_span(param.def_id),
+                                           "const",
+                                           &param_ct.to_string());
+                }
+            }
         }
     }
 
index 6c56e9991c8a81db1c0ee4f9ae05e6ab8e83193c..b560f3b4979208e18b892538a73e6c3cdd951e2e 100644 (file)
@@ -52,16 +52,16 @@ pub struct InferVisitor<'cx, 'tcx: 'cx> {
 
 impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for InferVisitor<'cx, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
-        let item_did = self.tcx.hir().local_def_id(item.id);
+        let item_did = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
 
         debug!("InferVisitor::visit_item(item={:?})", item_did);
 
-        let node_id = self
+        let hir_id = self
             .tcx
             .hir()
-            .as_local_node_id(item_did)
+            .as_local_hir_id(item_did)
             .expect("expected local def-id");
-        let item = match self.tcx.hir().get(node_id) {
+        let item = match self.tcx.hir().get_by_hir_id(hir_id) {
             Node::Item(item) => item,
             _ => bug!(),
         };
index b3634d37cc2b8553620e3e1f17711046b6b98f0b..1ab414c1f015f292ae3a5172260713a7d3bca018 100644 (file)
@@ -98,14 +98,22 @@ fn inferred_outlives_crate<'tcx>(
         .map(|(&def_id, set)| {
             let vec: Vec<ty::Predicate<'tcx>> = set
                 .iter()
-                .map(
+                .filter_map(
                     |ty::OutlivesPredicate(kind1, region2)| match kind1.unpack() {
-                        UnpackedKind::Type(ty1) => ty::Predicate::TypeOutlives(ty::Binder::bind(
-                            ty::OutlivesPredicate(ty1, region2),
-                        )),
-                        UnpackedKind::Lifetime(region1) => ty::Predicate::RegionOutlives(
-                            ty::Binder::bind(ty::OutlivesPredicate(region1, region2)),
-                        ),
+                        UnpackedKind::Type(ty1) => {
+                            Some(ty::Predicate::TypeOutlives(ty::Binder::bind(
+                                ty::OutlivesPredicate(ty1, region2)
+                            )))
+                        }
+                        UnpackedKind::Lifetime(region1) => {
+                            Some(ty::Predicate::RegionOutlives(
+                                ty::Binder::bind(ty::OutlivesPredicate(region1, region2))
+                            ))
+                        }
+                        UnpackedKind::Const(_) => {
+                            // Generic consts don't impose any constraints.
+                            None
+                        }
                     },
                 ).collect();
             (def_id, Lrc::new(vec))
index cbeb7f7b6919460dcb93f102c712423cc56cc228..e10c8361207186d15e32b4b7aaeee89a690fa840 100644 (file)
@@ -14,7 +14,7 @@ struct OutlivesTest<'a, 'tcx: 'a> {
 
 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for OutlivesTest<'a, 'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
-        let item_def_id = self.tcx.hir().local_def_id(item.id);
+        let item_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
 
         // For unit testing: check for a special "rustc_outlives"
         // attribute and report an error with various results if found.
index c886c7a4ffce5fdd3717aa6313a60e35c512f72d..ee552ca9cbb251c669eb5c518c528fcc2be44efb 100644 (file)
@@ -118,6 +118,10 @@ pub fn insert_outlives_predicate<'tcx>(
             }
             required_predicates.insert(ty::OutlivesPredicate(kind, outlived_region));
         }
+
+        UnpackedKind::Const(_) => {
+            // Generic consts don't impose any constraints.
+        }
     }
 }
 
index d8d93b462a900b4328285b0594c0304636a83114..49d11150689a99d078e106a74bcea4fb3c3edd89 100644 (file)
@@ -4,7 +4,8 @@
 //! We walk the set of items and, for each member, generate new constraints.
 
 use hir::def_id::DefId;
-use rustc::ty::subst::{UnpackedKind, SubstsRef};
+use rustc::mir::interpret::ConstValue;
+use rustc::ty::subst::{SubstsRef, UnpackedKind};
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::hir;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
@@ -229,12 +230,19 @@ fn add_constraints_from_invariant_substs(&mut self,
 
         // Trait are always invariant so we can take advantage of that.
         let variance_i = self.invariant(variance);
-        for ty in substs.types() {
-            self.add_constraints_from_ty(current, ty, variance_i);
-        }
 
-        for region in substs.regions() {
-            self.add_constraints_from_region(current, region, variance_i);
+        for k in substs {
+            match k.unpack() {
+                UnpackedKind::Lifetime(lt) => {
+                    self.add_constraints_from_region(current, lt, variance_i)
+                }
+                UnpackedKind::Type(ty) => {
+                    self.add_constraints_from_ty(current, ty, variance_i)
+                }
+                UnpackedKind::Const(ct) => {
+                    self.add_constraints_from_const(current, ct, variance_i)
+                }
+            }
         }
     }
 
@@ -267,7 +275,11 @@ fn add_constraints_from_ty(&mut self,
                 self.add_constraints_from_mt(current, &ty::TypeAndMut { ty, mutbl }, variance);
             }
 
-            ty::Array(typ, _) |
+            ty::Array(typ, len) => {
+                self.add_constraints_from_ty(current, typ, variance);
+                self.add_constraints_from_const(current, len, variance);
+            }
+
             ty::Slice(typ) => {
                 self.add_constraints_from_ty(current, typ, variance);
             }
@@ -383,6 +395,9 @@ fn add_constraints_from_substs(&mut self,
                 UnpackedKind::Type(ty) => {
                     self.add_constraints_from_ty(current, ty, variance_i)
                 }
+                UnpackedKind::Const(ct) => {
+                    self.add_constraints_from_const(current, ct, variance_i)
+                }
             }
         }
     }
@@ -434,6 +449,26 @@ fn add_constraints_from_region(&mut self,
         }
     }
 
+    fn add_constraints_from_const(
+        &mut self,
+        current: &CurrentItem,
+        ct: &ty::LazyConst<'tcx>,
+        variance: VarianceTermPtr<'a>
+    ) {
+        debug!(
+            "add_constraints_from_const(ct={:?}, variance={:?})",
+            ct,
+            variance
+        );
+
+        if let ty::LazyConst::Evaluated(ct) = ct {
+            self.add_constraints_from_ty(current, ct.ty, variance);
+            if let ConstValue::Param(ref data) = ct.val {
+                self.add_constraint(current, data.index, variance);
+            }
+        }
+    }
+
     /// Adds constraints appropriate for a mutability-type pair
     /// appearing in a context with ambient variance `variance`
     fn add_constraints_from_mt(&mut self,
index e564a8658fcaba8a4fde306acfe1a25331b0d326..50c8d5adfa3702d255dcddf5bd5a8a0ca0ed5986 100644 (file)
@@ -128,7 +128,7 @@ fn add_inferreds_for_item(&mut self, id: hir::HirId) {
 impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for TermsContext<'a, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
         debug!("add_inferreds for item {}",
-               self.tcx.hir().node_to_string(item.id));
+               self.tcx.hir().hir_to_string(item.hir_id));
 
         match item.node {
             hir::ItemKind::Struct(ref struct_def, _) |
index 0f566e6ded973c4a6ee7167921fa35d991f384b5..d04b1b276a2cc9156a7a9583f76b2e266825e435 100644 (file)
@@ -12,7 +12,7 @@ struct VarianceTest<'a, 'tcx: 'a> {
 
 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for VarianceTest<'a, 'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
-        let item_def_id = self.tcx.hir().local_def_id(item.id);
+        let item_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
 
         // For unit testing: check for a special "rustc_variance"
         // attribute and report an error with various results if found.
index d88d0dab4f0ebb5bfd2950eba7e1621ce1fb9a70..5d0d76507bd071eb3e7c0fb328f21c1af6ae4d4e 100644 (file)
@@ -1482,6 +1482,9 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> GenericParamDef {
                     synthetic: None,
                 })
             }
+            ty::GenericParamDefKind::Const { .. } => {
+                unimplemented!() // FIXME(const_generics)
+            }
         };
 
         GenericParamDef {
@@ -1629,6 +1632,9 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Generics {
                 }
                 Some(param.clean(cx))
             }
+            ty::GenericParamDefKind::Const { .. } => {
+                unimplemented!() // FIXME(const_generics)
+            }
         }).collect::<Vec<GenericParamDef>>();
 
         let mut where_predicates = preds.predicates.iter()
@@ -1678,6 +1684,9 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Generics {
                         .flat_map(|param| match param.kind {
                             ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
                             ty::GenericParamDefKind::Type { .. } => None,
+                            ty::GenericParamDefKind::Const { .. } => {
+                                unimplemented!() // FIXME(const_generics)
+                            }
                         }).chain(simplify::ty_params(stripped_typarams).into_iter())
                         .collect(),
             where_predicates: simplify::where_clauses(cx, where_predicates),
@@ -1725,7 +1734,7 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Item {
             (self.generics.clean(cx), (&self.decl, self.body).clean(cx))
         });
 
-        let did = cx.tcx.hir().local_def_id(self.id);
+        let did = cx.tcx.hir().local_def_id_from_hir_id(self.id);
         let constness = if cx.tcx.is_min_const_fn(did) {
             hir::Constness::Const
         } else {
@@ -1932,7 +1941,7 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: attrs,
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -1962,7 +1971,7 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs,
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -2913,14 +2922,16 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Type {
 
 impl Clean<Item> for hir::StructField {
     fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Item {
+        let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id);
+
         Item {
             name: Some(self.ident.name).clean(cx),
             attrs: self.attrs.clean(cx),
             source: self.span.clean(cx),
             visibility: self.vis.clean(cx),
-            stability: get_stability(cx, cx.tcx.hir().local_def_id(self.id)),
-            deprecation: get_deprecation(cx, cx.tcx.hir().local_def_id(self.id)),
-            def_id: cx.tcx.hir().local_def_id(self.id),
+            stability: get_stability(cx, local_did),
+            deprecation: get_deprecation(cx, local_did),
+            def_id: local_did,
             inner: StructFieldItem(self.ty.clean(cx)),
         }
     }
@@ -2992,7 +3003,7 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3012,7 +3023,7 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3059,7 +3070,7 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3086,7 +3097,7 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Item {
             visibility: None,
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(self.def.id()),
+            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.def.hir_id()),
             inner: VariantItem(Variant {
                 kind: self.def.clean(cx),
             }),
@@ -3375,7 +3386,7 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(self.id.clone()),
+            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3399,7 +3410,7 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(self.id.clone()),
+            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3450,7 +3461,7 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3475,7 +3486,7 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3589,7 +3600,7 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Vec<Item> {
             name: None,
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3819,14 +3830,16 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Item {
             }
         };
 
+        let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id);
+
         Item {
             name: Some(self.ident.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.span.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(self.id),
+            def_id: local_did,
             visibility: self.vis.clean(cx),
-            stability: get_stability(cx, cx.tcx.hir().local_def_id(self.id)),
-            deprecation: get_deprecation(cx, cx.tcx.hir().local_def_id(self.id)),
+            stability: get_stability(cx, local_did),
+            deprecation: get_deprecation(cx, local_did),
             inner,
         }
     }
@@ -4034,7 +4047,7 @@ fn clean(&self, cx: &DocContext<'_, '_, '_>) -> Item {
             visibility: Some(Public),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
             inner: ProcMacroItem(ProcMacro {
                 kind: self.kind,
                 helpers: self.helpers.clean(cx),
index fdb071638b7993245b7dc66bb6a9097fac1d7a13..07cfdde4a4e9d0ba83679105405d984ef57b2407 100644 (file)
@@ -221,6 +221,9 @@ pub fn generics_to_path_params(&self, generics: ty::Generics) -> hir::GenericArg
                 ty::GenericParamDefKind::Type { .. } => {
                     args.push(hir::GenericArg::Type(self.ty_param_to_ty(param.clone())));
                 }
+                ty::GenericParamDefKind::Const { .. } => {
+                    unimplemented!() // FIXME(const_generics)
+                }
             }
         }
 
index e8458385739df64ed13258dc52aa0af7c800c93f..9c54b40b422aedd3fbe713f0599b5b8a8838fa0a 100644 (file)
@@ -89,7 +89,7 @@ pub struct Struct {
     pub vis: hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
-    pub id: NodeId,
+    pub id: hir::HirId,
     pub struct_type: StructType,
     pub name: Name,
     pub generics: hir::Generics,
@@ -102,7 +102,7 @@ pub struct Union {
     pub vis: hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
-    pub id: NodeId,
+    pub id: hir::HirId,
     pub struct_type: StructType,
     pub name: Name,
     pub generics: hir::Generics,
@@ -118,7 +118,7 @@ pub struct Enum {
     pub variants: hir::HirVec<Variant>,
     pub generics: hir::Generics,
     pub attrs: hir::HirVec<ast::Attribute>,
-    pub id: NodeId,
+    pub id: hir::HirId,
     pub whence: Span,
     pub name: Name,
 }
@@ -135,7 +135,7 @@ pub struct Variant {
 pub struct Function {
     pub decl: hir::FnDecl,
     pub attrs: hir::HirVec<ast::Attribute>,
-    pub id: NodeId,
+    pub id: hir::HirId,
     pub name: Name,
     pub vis: hir::Visibility,
     pub stab: Option<attr::Stability>,
@@ -150,7 +150,7 @@ pub struct Typedef {
     pub ty: P<hir::Ty>,
     pub gen: hir::Generics,
     pub name: Name,
-    pub id: ast::NodeId,
+    pub id: hir::HirId,
     pub attrs: hir::HirVec<ast::Attribute>,
     pub whence: Span,
     pub vis: hir::Visibility,
@@ -161,7 +161,7 @@ pub struct Typedef {
 pub struct Existential {
     pub exist_ty: hir::ExistTy,
     pub name: Name,
-    pub id: ast::NodeId,
+    pub id: hir::HirId,
     pub attrs: hir::HirVec<ast::Attribute>,
     pub whence: Span,
     pub vis: hir::Visibility,
@@ -179,7 +179,7 @@ pub struct Static {
     pub vis: hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
-    pub id: ast::NodeId,
+    pub id: hir::HirId,
     pub whence: Span,
 }
 
@@ -191,7 +191,7 @@ pub struct Constant {
     pub vis: hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
-    pub id: ast::NodeId,
+    pub id: hir::HirId,
     pub whence: Span,
 }
 
@@ -203,7 +203,7 @@ pub struct Trait {
     pub generics: hir::Generics,
     pub bounds: hir::HirVec<hir::GenericBound>,
     pub attrs: hir::HirVec<ast::Attribute>,
-    pub id: ast::NodeId,
+    pub id: hir::HirId,
     pub whence: Span,
     pub vis: hir::Visibility,
     pub stab: Option<attr::Stability>,
@@ -215,7 +215,7 @@ pub struct TraitAlias {
     pub generics: hir::Generics,
     pub bounds: hir::HirVec<hir::GenericBound>,
     pub attrs: hir::HirVec<ast::Attribute>,
-    pub id: ast::NodeId,
+    pub id: hir::HirId,
     pub whence: Span,
     pub vis: hir::Visibility,
     pub stab: Option<attr::Stability>,
@@ -236,7 +236,7 @@ pub struct Impl {
     pub vis: hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
-    pub id: ast::NodeId,
+    pub id: hir::HirId,
 }
 
 // For Macro we store the DefId instead of the NodeId, since we also create
@@ -263,7 +263,7 @@ pub struct ExternCrate {
 
 pub struct Import {
     pub name: Name,
-    pub id: NodeId,
+    pub id: hir::HirId,
     pub vis: hir::Visibility,
     pub attrs: hir::HirVec<ast::Attribute>,
     pub path: hir::Path,
@@ -273,7 +273,7 @@ pub struct Import {
 
 pub struct ProcMacro {
     pub name: Name,
-    pub id: NodeId,
+    pub id: hir::HirId,
     pub kind: MacroKind,
     pub helpers: Vec<Name>,
     pub attrs: hir::HirVec<ast::Attribute>,
index b791bfc11e01ad3f0e35e2f66c6e7ea99f93f67a..c1bd1d83a5b00b17ed9c7f387ba0a3a42ced2e71 100644 (file)
@@ -101,7 +101,7 @@ pub fn visit_variant_data(&mut self, item: &hir::Item,
         debug!("Visiting struct");
         let struct_type = struct_type_from_def(&*sd);
         Struct {
-            id: item.id,
+            id: item.hir_id,
             struct_type,
             name,
             vis: item.vis.clone(),
@@ -120,7 +120,7 @@ pub fn visit_union_data(&mut self, item: &hir::Item,
         debug!("Visiting union");
         let struct_type = struct_type_from_def(&*sd);
         Union {
-            id: item.id,
+            id: item.hir_id,
             struct_type,
             name,
             vis: item.vis.clone(),
@@ -152,7 +152,7 @@ pub fn visit_enum_def(&mut self, it: &hir::Item,
             depr: self.deprecation(it.hir_id),
             generics: params.clone(),
             attrs: it.attrs.clone(),
-            id: it.id,
+            id: it.hir_id,
             whence: it.span,
         }
     }
@@ -202,7 +202,7 @@ pub fn visit_fn(&mut self, om: &mut Module, item: &hir::Item,
 
                 om.proc_macros.push(ProcMacro {
                     name,
-                    id: item.id,
+                    id: item.hir_id,
                     kind,
                     helpers,
                     attrs: item.attrs.clone(),
@@ -213,7 +213,7 @@ pub fn visit_fn(&mut self, om: &mut Module, item: &hir::Item,
             }
             None => {
                 om.fns.push(Function {
-                    id: item.id,
+                    id: item.hir_id,
                     vis: item.vis.clone(),
                     stab: self.stability(item.hir_id),
                     depr: self.deprecation(item.hir_id),
@@ -262,7 +262,7 @@ pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec<ast::Attribu
     ///
     /// Returns `true` if the target has been inlined.
     fn maybe_inline_local(&mut self,
-                          id: ast::NodeId,
+                          id: hir::HirId,
                           def: Def,
                           renamed: Option<ast::Ident>,
                           glob: bool,
@@ -291,7 +291,7 @@ fn inherits_doc_hidden(cx: &core::DocContext<'_, '_, '_>, mut node: ast::NodeId)
             return false;
         };
 
-        let use_attrs = tcx.hir().attrs(id);
+        let use_attrs = tcx.hir().attrs_by_hir_id(id);
         // Don't inline `doc(hidden)` imports so they can be stripped at a later stage.
         let is_no_inline = use_attrs.lists("doc").has_word("no_inline") ||
                            use_attrs.lists("doc").has_word("hidden");
@@ -357,7 +357,7 @@ fn inherits_doc_hidden(cx: &core::DocContext<'_, '_, '_>, mut node: ast::NodeId)
             Node::ForeignItem(it) if !glob => {
                 // Generate a fresh `extern {}` block if we want to inline a foreign item.
                 om.foreigns.push(hir::ForeignMod {
-                    abi: tcx.hir().get_foreign_abi(it.id),
+                    abi: tcx.hir().get_foreign_abi_by_hir_id(it.hir_id),
                     items: vec![hir::ForeignItem {
                         ident: renamed.unwrap_or(it.ident),
                         .. it.clone()
@@ -381,7 +381,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
         let ident = renamed.unwrap_or(item.ident);
 
         if item.vis.node.is_pub() {
-            let def_id = self.cx.tcx.hir().local_def_id(item.id);
+            let def_id = self.cx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
             self.store_path(def_id);
         }
 
@@ -401,7 +401,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
             _ if self.inlining && !item.vis.node.is_pub() => {}
             hir::ItemKind::GlobalAsm(..) => {}
             hir::ItemKind::ExternCrate(orig_name) => {
-                let def_id = self.cx.tcx.hir().local_def_id(item.id);
+                let def_id = self.cx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
                 om.extern_crates.push(ExternCrate {
                     cnum: self.cx.tcx.extern_mod_stmt_cnum(def_id)
                                 .unwrap_or(LOCAL_CRATE),
@@ -436,7 +436,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
                         }
                     });
                     let ident = if is_glob { None } else { Some(ident) };
-                    if self.maybe_inline_local(item.id,
+                    if self.maybe_inline_local(item.hir_id,
                                                path.def,
                                                ident,
                                                is_glob,
@@ -448,7 +448,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
 
                 om.imports.push(Import {
                     name: ident.name,
-                    id: item.id,
+                    id: item.hir_id,
                     vis: item.vis.clone(),
                     attrs: item.attrs.clone(),
                     path: (**path).clone(),
@@ -477,7 +477,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
                     ty: ty.clone(),
                     gen: gen.clone(),
                     name: ident.name,
-                    id: item.id,
+                    id: item.hir_id,
                     attrs: item.attrs.clone(),
                     whence: item.span,
                     vis: item.vis.clone(),
@@ -490,7 +490,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
                 let t = Existential {
                     exist_ty: exist_ty.clone(),
                     name: ident.name,
-                    id: item.id,
+                    id: item.hir_id,
                     attrs: item.attrs.clone(),
                     whence: item.span,
                     vis: item.vis.clone(),
@@ -504,7 +504,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
                     type_: ty.clone(),
                     mutability: mut_.clone(),
                     expr: exp.clone(),
-                    id: item.id,
+                    id: item.hir_id,
                     name: ident.name,
                     attrs: item.attrs.clone(),
                     whence: item.span,
@@ -518,7 +518,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
                 let s = Constant {
                     type_: ty.clone(),
                     expr: exp.clone(),
-                    id: item.id,
+                    id: item.hir_id,
                     name: ident.name,
                     attrs: item.attrs.clone(),
                     whence: item.span,
@@ -539,7 +539,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
                     items,
                     generics: gen.clone(),
                     bounds: b.iter().cloned().collect(),
-                    id: item.id,
+                    id: item.hir_id,
                     attrs: item.attrs.clone(),
                     whence: item.span,
                     vis: item.vis.clone(),
@@ -553,7 +553,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
                     name: ident.name,
                     generics: gen.clone(),
                     bounds: b.iter().cloned().collect(),
-                    id: item.id,
+                    id: item.hir_id,
                     attrs: item.attrs.clone(),
                     whence: item.span,
                     vis: item.vis.clone(),
@@ -585,7 +585,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
                         for_: ty.clone(),
                         items,
                         attrs: item.attrs.clone(),
-                        id: item.id,
+                        id: item.hir_id,
                         whence: item.span,
                         vis: item.vis.clone(),
                         stab: self.stability(item.hir_id),
index a51847c92b51e2bf964969843501f55c867afd9e..928de29b297fced40874c6617baec89b206c4d63 100644 (file)
@@ -2341,6 +2341,11 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
     elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl<'a, K: 'a + Send, V: 'a + Send> Send for OccupiedEntry<'a, K, V> {}
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl<'a, K: 'a + Sync, V: 'a + Sync> Sync for OccupiedEntry<'a, K, V> {}
+
 #[stable(feature= "debug_hash_map", since = "1.12.0")]
 impl<K: Debug, V: Debug> Debug for OccupiedEntry<'_, K, V> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -2362,6 +2367,11 @@ pub struct VacantEntry<'a, K: 'a, V: 'a> {
     elem: VacantEntryState<K, V, &'a mut RawTable<K, V>>,
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl<'a, K: 'a + Send, V: 'a + Send> Send for VacantEntry<'a, K, V> {}
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl<'a, K: 'a + Sync, V: 'a + Sync> Sync for VacantEntry<'a, K, V> {}
+
 #[stable(feature= "debug_hash_map", since = "1.12.0")]
 impl<K: Debug, V> Debug for VacantEntry<'_, K, V> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
index 559a54d3c8aca0e2fb732f374b339fc7abe0b19e..a14c10d0b61e9cee6dc91a1cb48a32d67f6084e9 100644 (file)
@@ -101,7 +101,9 @@ pub fn with_capacity(cap: usize, inner: R) -> BufReader<R> {
             }
         }
     }
+}
 
+impl<R> BufReader<R> {
     /// Gets a reference to the underlying reader.
     ///
     /// It is inadvisable to directly read from the underlying reader.
index bd3d0a4163869b5266736a2a011754896d766ba0..b286e4016da7fc58dcd38dfb9a2027d9ecc9f7ba 100644 (file)
@@ -165,6 +165,20 @@ fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
     }
 }
 
+// Used by panicking::default_hook
+#[cfg(test)]
+/// This impl is only used by printing logic, so any error returned is always
+/// of kind `Other`, and should be ignored.
+impl Write for Box<dyn (::realstd::io::Write) + Send> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        (**self).write(buf).map_err(|_| ErrorKind::Other.into())
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        (**self).flush().map_err(|_| ErrorKind::Other.into())
+    }
+}
+
 // =============================================================================
 // In-memory buffer implementations
 
index 13bf357e2eb8f45adbab532c95bf7c9110bcee97..589fb455a191c9c2ddb15a284d5b2eab8e8fe092 100644 (file)
@@ -1,3 +1,5 @@
+#![cfg_attr(test, allow(unused))]
+
 use crate::io::prelude::*;
 
 use crate::cell::RefCell;
     }
 }
 
+/// Stderr used by eprint! and eprintln! macros, and panics
+thread_local! {
+    static LOCAL_STDERR: RefCell<Option<Box<dyn Write + Send>>> = {
+        RefCell::new(None)
+    }
+}
+
 /// A handle to a raw instance of the standard input stream of this process.
 ///
 /// This handle is not synchronized or buffered in any fashion. Constructed via
@@ -668,7 +677,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            issue = "0")]
 #[doc(hidden)]
 pub fn set_panic(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Send>> {
-    use crate::panicking::LOCAL_STDERR;
     use crate::mem;
     LOCAL_STDERR.with(move |slot| {
         mem::replace(&mut *slot.borrow_mut(), sink)
@@ -740,6 +748,7 @@ fn print_to<T>(
            reason = "implementation detail which may disappear or be replaced at any time",
            issue = "0")]
 #[doc(hidden)]
+#[cfg(not(test))]
 pub fn _print(args: fmt::Arguments) {
     print_to(args, &LOCAL_STDOUT, stdout, "stdout");
 }
@@ -748,11 +757,14 @@ pub fn _print(args: fmt::Arguments) {
            reason = "implementation detail which may disappear or be replaced at any time",
            issue = "0")]
 #[doc(hidden)]
+#[cfg(not(test))]
 pub fn _eprint(args: fmt::Arguments) {
-    use crate::panicking::LOCAL_STDERR;
     print_to(args, &LOCAL_STDERR, stderr, "stderr");
 }
 
+#[cfg(test)]
+pub use realstd::io::{_eprint, _print};
+
 #[cfg(test)]
 mod tests {
     use crate::panic::{UnwindSafe, RefUnwindSafe};
index 32a168619dfb3267cdac4f39e3084fe5ddd05a26..e31680f23f1da47bcc37f2c2aeca6ddcbd977ec2 100644 (file)
 // std may use features in a platform-specific way
 #![allow(unused_features)]
 
-#![cfg_attr(test, feature(test, update_panic_count))]
+#![cfg_attr(test, feature(print_internals, set_stdio, test, update_panic_count))]
 #![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"),
             feature(global_asm, range_contains, slice_index_methods,
                     decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))]
index 281641c3c12321f0b5f3248c17b53d9eeeffe880..9d0eb2e6b1cefc5f015926a39095afb7df53dd0c 100644 (file)
@@ -53,8 +53,7 @@
 /// ```
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(stage0, allow_internal_unstable)]
-#[cfg_attr(not(stage0), allow_internal_unstable(__rust_unstable_column, libstd_sys_internals))]
+#[allow_internal_unstable(__rust_unstable_column, libstd_sys_internals)]
 macro_rules! panic {
     () => ({
         panic!("explicit panic")
@@ -112,8 +111,7 @@ macro_rules! panic {
 /// ```
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(stage0, allow_internal_unstable)]
-#[cfg_attr(not(stage0), allow_internal_unstable(print_internals))]
+#[allow_internal_unstable(print_internals)]
 macro_rules! print {
     ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
 }
@@ -145,8 +143,7 @@ macro_rules! print {
 /// ```
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(stage0, allow_internal_unstable)]
-#[cfg_attr(not(stage0), allow_internal_unstable(print_internals, format_args_nl))]
+#[allow_internal_unstable(print_internals, format_args_nl)]
 macro_rules! println {
     () => (print!("\n"));
     ($($arg:tt)*) => ({
@@ -177,8 +174,7 @@ macro_rules! println {
 /// ```
 #[macro_export]
 #[stable(feature = "eprint", since = "1.19.0")]
-#[cfg_attr(stage0, allow_internal_unstable)]
-#[cfg_attr(not(stage0), allow_internal_unstable(print_internals))]
+#[allow_internal_unstable(print_internals)]
 macro_rules! eprint {
     ($($arg:tt)*) => ($crate::io::_eprint(format_args!($($arg)*)));
 }
@@ -206,8 +202,7 @@ macro_rules! eprint {
 /// ```
 #[macro_export]
 #[stable(feature = "eprint", since = "1.19.0")]
-#[cfg_attr(stage0, allow_internal_unstable)]
-#[cfg_attr(not(stage0), allow_internal_unstable(print_internals, format_args_nl))]
+#[allow_internal_unstable(print_internals, format_args_nl)]
 macro_rules! eprintln {
     () => (eprint!("\n"));
     ($($arg:tt)*) => ({
@@ -330,8 +325,7 @@ macro_rules! dbg {
 /// A macro to await on an async call.
 #[macro_export]
 #[unstable(feature = "await_macro", issue = "50547")]
-#[cfg_attr(stage0, allow_internal_unstable)]
-#[cfg_attr(not(stage0), allow_internal_unstable(gen_future, generators))]
+#[allow_internal_unstable(gen_future, generators)]
 #[allow_internal_unsafe]
 macro_rules! r#await {
     ($e:expr) => { {
index 868b309686cf61e47086d729aa0af97c438ab096..eae885602d3e7877b96a0125ac8c5e0df4968f59 100644 (file)
@@ -7,13 +7,9 @@
 //! * Executing a panic up to doing the actual implementation
 //! * Shims around "try"
 
-use core::panic::BoxMeUp;
-use core::panic::{PanicInfo, Location};
-
-use crate::io::prelude::*;
+use core::panic::{BoxMeUp, PanicInfo, Location};
 
 use crate::any::Any;
-use crate::cell::RefCell;
 use crate::fmt;
 use crate::intrinsics;
 use crate::mem;
 use crate::sys_common::util;
 use crate::thread;
 
-thread_local! {
-    pub static LOCAL_STDERR: RefCell<Option<Box<dyn Write + Send>>> = {
-        RefCell::new(None)
-    }
-}
+#[cfg(not(test))]
+use crate::io::set_panic;
+// make sure to use the stderr output configured
+// by libtest in the real copy of std
+#[cfg(test)]
+use realstd::io::set_panic;
 
 // Binary interface to the panic runtime that the standard library depends on.
 //
@@ -205,12 +202,11 @@ fn default_hook(info: &PanicInfo) {
         }
     };
 
-    if let Some(mut local) = LOCAL_STDERR.with(|s| s.borrow_mut().take()) {
-       write(&mut *local);
-       let mut s = Some(local);
-       LOCAL_STDERR.with(|slot| {
-           *slot.borrow_mut() = s.take();
-       });
+    if let Some(mut local) = set_panic(None) {
+        // NB. In `cfg(test)` this uses the forwarding impl
+        // for `Box<dyn (::realstd::io::Write) + Send>`.
+        write(&mut local);
+        set_panic(Some(local));
     } else if let Some(mut out) = panic_output() {
         write(&mut out);
     }
index b6da59502806b7f016cc63d18171fd745dd23fe5..268a14ff0aabb58fa9af5f2e3c97bfc408a9bad5 100644 (file)
@@ -220,13 +220,27 @@ pub trait OpenOptionsExt {
     /// the specified value (or combines it with `custom_flags` and `attributes`
     /// to set the `dwFlagsAndAttributes` for [`CreateFile`]).
     ///
-    /// By default, `security_qos_flags` is set to `SECURITY_ANONYMOUS`. For
-    /// information about possible values, see [Impersonation Levels] on the
-    /// Windows Dev Center site.
-    ///
+    /// By default `security_qos_flags` is not set. It should be specified when
+    /// opening a named pipe, to control to which degree a server process can
+    /// act on behalf of a client process (security impersonation level).
+    ///
+    /// When `security_qos_flags` is not set a malicious program can gain the
+    /// elevated privileges of a privileged Rust process when it allows opening
+    /// user-specified paths, by tricking it into opening a named pipe. So
+    /// arguably `security_qos_flags` should also be set when opening arbitrary
+    /// paths. However the bits can then conflict with other flags, specifically
+    /// `FILE_FLAG_OPEN_NO_RECALL`.
+    ///
+    /// For information about possible values, see [Impersonation Levels] on the
+    /// Windows Dev Center site. The `SECURITY_SQOS_PRESENT` flag is set
+    /// automatically when using this method.
+
     /// # Examples
     ///
     /// ```no_run
+    /// # #[cfg(for_demonstration_only)]
+    /// extern crate winapi;
+    /// # mod winapi { pub const SECURITY_IDENTIFICATION: u32 = 0; }
     /// use std::fs::OpenOptions;
     /// use std::os::windows::prelude::*;
     ///
@@ -235,9 +249,9 @@ pub trait OpenOptionsExt {
     ///     .create(true)
     ///
     ///     // Sets the flag value to `SecurityIdentification`.
-    ///     .security_qos_flags(1)
+    ///     .security_qos_flags(winapi::SECURITY_IDENTIFICATION)
     ///
-    ///     .open("foo.txt");
+    ///     .open(r"\\.\pipe\MyPipe");
     /// ```
     ///
     /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
index f19c111f09aa2ed4da8bb319bc37d62c1a0ef098..daf8aae24dde5b61b50bd5172fca300e5cbdb31b 100644 (file)
@@ -191,7 +191,11 @@ pub fn new() -> OpenOptions {
     pub fn access_mode(&mut self, access_mode: u32) { self.access_mode = Some(access_mode); }
     pub fn share_mode(&mut self, share_mode: u32) { self.share_mode = share_mode; }
     pub fn attributes(&mut self, attrs: u32) { self.attributes = attrs; }
-    pub fn security_qos_flags(&mut self, flags: u32) { self.security_qos_flags = flags; }
+    pub fn security_qos_flags(&mut self, flags: u32) {
+        // We have to set `SECURITY_SQOS_PRESENT` here, because one of the valid flags we can
+        // receive is `SECURITY_ANONYMOUS = 0x0`, which we can't check for later on.
+        self.security_qos_flags = flags | c::SECURITY_SQOS_PRESENT;
+    }
     pub fn security_attributes(&mut self, attrs: c::LPSECURITY_ATTRIBUTES) {
         self.security_attributes = attrs as usize;
     }
@@ -239,7 +243,6 @@ fn get_flags_and_attributes(&self) -> c::DWORD {
         self.custom_flags |
         self.attributes |
         self.security_qos_flags |
-        if self.security_qos_flags != 0 { c::SECURITY_SQOS_PRESENT } else { 0 } |
         if self.create_new { c::FILE_FLAG_OPEN_REPARSE_POINT } else { 0 }
     }
 }
index d1f53734d30e31ea63cbcb2942a0b51a66cd006e..7ad6b124e3a384c1f57543d2230e4b0f513421de 100644 (file)
 /// });
 ///
 /// // each thread starts out with the initial value of 1
-/// thread::spawn(move|| {
+/// let t = thread::spawn(move|| {
 ///     FOO.with(|f| {
 ///         assert_eq!(*f.borrow(), 1);
 ///         *f.borrow_mut() = 3;
 ///     });
 /// });
 ///
+/// // wait for the thread to complete and bail out on panic
+/// t.join().unwrap();
+///
 /// // we retain our original value of 2 despite the child thread
 /// FOO.with(|f| {
 ///     assert_eq!(*f.borrow(), 2);
@@ -126,8 +129,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// [`std::thread::LocalKey`]: ../std/thread/struct.LocalKey.html
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(stage0, allow_internal_unstable)]
-#[cfg_attr(not(stage0), allow_internal_unstable(thread_local_internals))]
+#[allow_internal_unstable(thread_local_internals)]
 macro_rules! thread_local {
     // empty (base case for the recursion)
     () => {};
@@ -149,10 +151,7 @@ macro_rules! thread_local {
            reason = "should not be necessary",
            issue = "0")]
 #[macro_export]
-#[cfg_attr(stage0, allow_internal_unstable)]
-#[cfg_attr(not(stage0), allow_internal_unstable(
-    thread_local_internals, cfg_target_thread_local, thread_local,
-))]
+#[allow_internal_unstable(thread_local_internals, cfg_target_thread_local, thread_local)]
 #[allow_internal_unsafe]
 macro_rules! __thread_local_inner {
     (@key $(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $init:expr) => {
index fd5038a8614f25823cf6c0aee5bd3664701d119d..1606bd591bd21e09733c30e862feefcfcde618b7 100644 (file)
@@ -1803,7 +1803,7 @@ fn parse_remaining_bounds(&mut self, generic_params: Vec<GenericParam>, path: as
         let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
         if parse_plus {
             self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
-            bounds.append(&mut self.parse_generic_bounds(None)?);
+            bounds.append(&mut self.parse_generic_bounds(Some(self.prev_span))?);
         }
         Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
     }
@@ -5523,6 +5523,7 @@ fn parse_generic_bounds_common(&mut self,
         let mut bounds = Vec::new();
         let mut negative_bounds = Vec::new();
         let mut last_plus_span = None;
+        let mut was_negative = false;
         loop {
             // This needs to be synchronized with `Token::can_begin_bound`.
             let is_bound_start = self.check_path() || self.check_lifetime() ||
@@ -5567,9 +5568,10 @@ fn parse_generic_bounds_common(&mut self,
                     }
                     let poly_span = lo.to(self.prev_span);
                     if is_negative {
-                        negative_bounds.push(
-                            last_plus_span.or(colon_span).unwrap()
-                                .to(poly_span));
+                        was_negative = true;
+                        if let Some(sp) = last_plus_span.or(colon_span) {
+                            negative_bounds.push(sp.to(poly_span));
+                        }
                     } else {
                         let poly_trait = PolyTraitRef::new(lifetime_defs, path, poly_span);
                         let modifier = if question.is_some() {
@@ -5591,26 +5593,28 @@ fn parse_generic_bounds_common(&mut self,
             }
         }
 
-        if !negative_bounds.is_empty() {
+        if !negative_bounds.is_empty() || was_negative {
             let plural = negative_bounds.len() > 1;
             let mut err = self.struct_span_err(negative_bounds,
                                                "negative trait bounds are not supported");
-            let bound_list = colon_span.unwrap().to(self.prev_span);
-            let mut new_bound_list = String::new();
-            if !bounds.is_empty() {
-                let mut snippets = bounds.iter().map(|bound| bound.span())
-                    .map(|span| self.sess.source_map().span_to_snippet(span));
-                while let Some(Ok(snippet)) = snippets.next() {
-                    new_bound_list.push_str(" + ");
-                    new_bound_list.push_str(&snippet);
-                }
-                new_bound_list = new_bound_list.replacen(" +", ":", 1);
-            }
-            err.span_suggestion_short(bound_list,
-                                      &format!("remove the trait bound{}",
-                                              if plural { "s" } else { "" }),
-                                      new_bound_list,
-                                      Applicability::MachineApplicable);
+            if let Some(bound_list) = colon_span {
+                let bound_list = bound_list.to(self.prev_span);
+                let mut new_bound_list = String::new();
+                if !bounds.is_empty() {
+                    let mut snippets = bounds.iter().map(|bound| bound.span())
+                        .map(|span| self.sess.source_map().span_to_snippet(span));
+                    while let Some(Ok(snippet)) = snippets.next() {
+                        new_bound_list.push_str(" + ");
+                        new_bound_list.push_str(&snippet);
+                    }
+                    new_bound_list = new_bound_list.replacen(" +", ":", 1);
+                }
+                err.span_suggestion_short(bound_list,
+                                        &format!("remove the trait bound{}",
+                                                if plural { "s" } else { "" }),
+                                        new_bound_list,
+                                        Applicability::MachineApplicable);
+            }
             err.emit();
         }
 
@@ -5646,7 +5650,7 @@ fn parse_ty_param(&mut self,
 
         // Parse optional colon and param bounds.
         let bounds = if self.eat(&token::Colon) {
-            self.parse_generic_bounds(None)?
+            self.parse_generic_bounds(Some(self.prev_span))?
         } else {
             Vec::new()
         };
@@ -6091,7 +6095,7 @@ fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> {
                 // or with mandatory equality sign and the second type.
                 let ty = self.parse_ty()?;
                 if self.eat(&token::Colon) {
-                    let bounds = self.parse_generic_bounds(None)?;
+                    let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
                     where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
                         ast::WhereBoundPredicate {
                             span: lo.to(self.prev_span),
@@ -7643,7 +7647,7 @@ fn parse_existential_or_alias(
         tps.where_clause = self.parse_where_clause()?;
         let alias = if existential {
             self.expect(&token::Colon)?;
-            let bounds = self.parse_generic_bounds(None)?;
+            let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
             AliasKind::Existential(bounds)
         } else {
             self.expect(&token::Eq)?;
index 942bd96939173bf20f4e100f6cb6833617d75b20..49e3fad4af0ffdc76671655f3379319ec69a1551 100644 (file)
@@ -2814,9 +2814,6 @@ pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl)
         -> io::Result<()> {
         self.popen()?;
         self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, false))?;
-        if decl.c_variadic {
-            self.s.word(", ...")?;
-        }
         self.pclose()?;
 
         self.print_fn_output(decl)
index a93ee6bc604a4bd0e2f8ff2cfd20087cb8644fc5..274c0f90442f6bac0872b6be4a3a7cbfb1d776fd 100644 (file)
@@ -12,7 +12,7 @@
 # source tarball for a stable release you'll likely see `1.x.0` for rustc and
 # `0.x.0` for Cargo where they were released on `date`.
 
-date: 2019-02-17
+date: 2019-02-27
 rustc: beta
 cargo: beta
 
index b56d222e0e01e5baea0b5ea6f42dbcfd5cb0720b..35a67217f16718c45dd897c4b00ceaa647b8d5d8 100644 (file)
@@ -7,6 +7,8 @@
 // gdb-command:run
 // gdb-command:print a
 // gdb-check:$1 = 5
+// gdb-command:print d
+// gdb-check:$2 = 6
 
 // === LLDB TESTS ==================================================================================
 
 // lldb-command:print a
 // lldbg-check:(int) $0 = 5
 // lldbr-check:(int) a = 5
+// lldb-command:print d
+// lldbg-check:(int) $1 = 6
+// lldbr-check:(int) d = 6
 
-#![feature(omit_gdb_pretty_printer_section, generators, generator_trait, pin)]
+#![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
 #![omit_gdb_pretty_printer_section]
 
 use std::ops::Generator;
 fn main() {
     let mut a = 5;
     let mut b = || {
+        let d = 6;
         yield;
         _zzz(); // #break
-        a = 6;
+        a = d;
     };
     Pin::new(&mut b).resume();
     Pin::new(&mut b).resume();
diff --git a/src/test/incremental/cyclic-trait-hierarchy.rs b/src/test/incremental/cyclic-trait-hierarchy.rs
new file mode 100644 (file)
index 0000000..4102eb3
--- /dev/null
@@ -0,0 +1,14 @@
+// Adapated from rust-lang/rust#58813
+
+// revisions: rpass1 cfail2
+
+#[cfg(rpass1)]
+pub trait T2 { }
+#[cfg(cfail2)]
+pub trait T2: T1 { }
+//[cfail2]~^ ERROR cycle detected when computing the supertraits of `T2`
+//[cfail2]~| ERROR cycle detected when computing the supertraits of `T2`
+
+pub trait T1: T2 { }
+
+fn main() { }
diff --git a/src/test/pretty/fn-variadic.rs b/src/test/pretty/fn-variadic.rs
new file mode 100644 (file)
index 0000000..d499be4
--- /dev/null
@@ -0,0 +1,15 @@
+// Check that `fn foo(x: i32, ...)` does not print as `fn foo(x: i32, ..., ...)`.
+// See issue #58853.
+
+// pp-exact
+#![feature(c_variadic)]
+
+extern "C" {
+    pub fn foo(x: i32, ...);
+}
+
+pub unsafe extern "C" fn bar(_: i32, mut ap: ...) -> usize {
+    ap.arg::<usize>()
+}
+
+fn main() { }
index b3c5fb2d79647bffde8f7bb8add1530e9e9c2727..3f74a17e0bb98ecd711feaf8cb893cf15c76162b 100644 (file)
@@ -9,17 +9,17 @@ all: cpp-executable rust-executable
 
 cpp-executable:
        $(RUSTC) -Clinker-plugin-lto=on -o $(TMPDIR)/librustlib-xlto.a -Copt-level=2 -Ccodegen-units=1 ./rustlib.rs
-       $(CLANG) -flto=thin -fuse-ld=lld -L $(TMPDIR) -lrustlib-xlto -o $(TMPDIR)/cmain ./cmain.c -O3
+       $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) $(CLANG) -flto=thin -fuse-ld=lld -L $(TMPDIR) -lrustlib-xlto -o $(TMPDIR)/cmain ./cmain.c -O3
        # Make sure we don't find a call instruction to the function we expect to
        # always be inlined.
-       llvm-objdump -d $(TMPDIR)/cmain | $(CGREP) -v -e "call.*rust_always_inlined"
+       $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-objdump -d $(TMPDIR)/cmain | $(CGREP) -v -e "call.*rust_always_inlined"
        # As a sanity check, make sure we do find a call instruction to a
        # non-inlined function
-       llvm-objdump -d $(TMPDIR)/cmain | $(CGREP) -e "call.*rust_never_inlined"
+       $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-objdump -d $(TMPDIR)/cmain | $(CGREP) -e "call.*rust_never_inlined"
 
 rust-executable:
-       $(CLANG) ./clib.c -flto=thin -c -o $(TMPDIR)/clib.o -O2
+       $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) $(CLANG) ./clib.c -flto=thin -c -o $(TMPDIR)/clib.o -O2
        (cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o)
        $(RUSTC) -Clinker-plugin-lto=on -L$(TMPDIR) -Copt-level=2 -Clinker=$(CLANG) -Clink-arg=-fuse-ld=lld ./main.rs -o $(TMPDIR)/rsmain
-       llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -e "call.*c_never_inlined"
-       llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -v -e "call.*c_always_inlined"
+       $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -e "call.*c_never_inlined"
+       $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -v -e "call.*c_always_inlined"
diff --git a/src/test/run-pass/generator/issue-57084.rs b/src/test/run-pass/generator/issue-57084.rs
new file mode 100644 (file)
index 0000000..8aaa6a0
--- /dev/null
@@ -0,0 +1,28 @@
+// This issue reproduces an ICE on compile (E.g. fails on 2018-12-19 nightly).
+// "cannot relate bound region: ReLateBound(DebruijnIndex(1), BrAnon(1)) <= '_#1r"
+// run-pass
+// edition:2018
+#![feature(generators,generator_trait)]
+use std::ops::Generator;
+
+fn with<F>(f: F) -> impl Generator<Yield=(), Return=()>
+where F: Fn() -> ()
+{
+    move || {
+        loop {
+            match f() {
+                _ => yield,
+            }
+        }
+    }
+}
+
+fn main() {
+    let data = &vec![1];
+    || {
+        let _to_pin = with(move || println!("{:p}", data));
+        loop {
+            yield
+        }
+    };
+}
diff --git a/src/test/run-pass/generator/issue-58888.rs b/src/test/run-pass/generator/issue-58888.rs
new file mode 100644 (file)
index 0000000..43b37a9
--- /dev/null
@@ -0,0 +1,27 @@
+// run-pass
+// compile-flags: -g
+
+#![feature(generators, generator_trait)]
+
+use std::ops::Generator;
+
+struct Database;
+
+impl Database {
+    fn get_connection(&self) -> impl Iterator<Item = ()> {
+        Some(()).into_iter()
+    }
+
+    fn check_connection(&self) -> impl Generator<Yield = (), Return = ()> + '_ {
+        move || {
+            let iter = self.get_connection();
+            for i in iter {
+                yield i
+            }
+        }
+    }
+}
+
+fn main() {
+    Database.check_connection();
+}
diff --git a/src/test/run-pass/issues/issue-58435-ice-with-assoc-const.rs b/src/test/run-pass/issues/issue-58435-ice-with-assoc-const.rs
new file mode 100644 (file)
index 0000000..94e2b25
--- /dev/null
@@ -0,0 +1,17 @@
+// The const-evaluator was at one point ICE'ing while trying to
+// evaluate the body of `fn id` during the `s.id()` call in main.
+
+struct S<T>(T);
+
+impl<T> S<T> {
+    const ID: fn(&S<T>) -> &S<T> = |s| s;
+    pub fn id(&self) -> &Self {
+        Self::ID(self) // This, plus call below ...
+    }
+}
+
+fn main() {
+    let s = S(10u32);
+    assert!(S::<u32>::ID(&s).0 == 10); // Works fine
+    assert!(s.id().0 == 10); // ... causes compiler to panic
+}
index 812cf89751efdfcb49653fbb85705213460cb06f..fd53bb607f79d46bf7d1d5c18d8e3db769371b8a 100644 (file)
@@ -53,6 +53,7 @@ fn main() {
     is_sync_send!(BTreeSet::<usize>::new(), union(&BTreeSet::<usize>::new()));
 
     all_sync_send!(HashMap::<usize, usize>::new(), iter, iter_mut, drain, into_iter, keys, values);
+    is_sync_send!(HashMap::<usize, usize>::new(), entry(0));
     all_sync_send!(HashSet::<usize>::new(), iter, drain, into_iter);
     is_sync_send!(HashSet::<usize>::new(), difference(&HashSet::<usize>::new()));
     is_sync_send!(HashSet::<usize>::new(), symmetric_difference(&HashSet::<usize>::new()));
index 1a9bd9e66dbacdc68665c15c28683996c889486c..d25a5ea374627dbf5ec62eff4467088c2eb42ecb 100644 (file)
 use rustc_plugin::Registry;
 use syntax::ast;
 declare_tool_lint!(pub clippy::TEST_LINT, Warn, "Warn about stuff");
-declare_tool_lint!(pub clippy::TEST_GROUP, Warn, "Warn about other stuff");
+declare_tool_lint!(
+    /// Some docs
+    pub clippy::TEST_GROUP,
+    Warn, "Warn about other stuff"
+);
 
 struct Pass;
 
diff --git a/src/test/ui-fulldeps/hash-stable-is-unstable.rs b/src/test/ui-fulldeps/hash-stable-is-unstable.rs
new file mode 100644 (file)
index 0000000..9f67f64
--- /dev/null
@@ -0,0 +1,15 @@
+// ignore-stage1
+
+extern crate rustc_data_structures;
+//~^ use of unstable library feature 'rustc_private'
+extern crate rustc;
+//~^ use of unstable library feature 'rustc_private'
+extern crate rustc_macros;
+//~^ use of unstable library feature 'rustc_private'
+
+use rustc_macros::HashStable;
+//~^ use of unstable library feature 'rustc_private'
+
+#[derive(HashStable)]
+//~^ use of unstable library feature 'rustc_private'
+struct Test;
diff --git a/src/test/ui-fulldeps/hash-stable-is-unstable.stderr b/src/test/ui-fulldeps/hash-stable-is-unstable.stderr
new file mode 100644 (file)
index 0000000..e700720
--- /dev/null
@@ -0,0 +1,48 @@
+error[E0601]: `main` function not found in crate `hash_stable_is_unstable`
+   |
+   = note: consider adding a `main` function to `$DIR/hash-stable-is-unstable.rs`
+
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? (see issue #27812)
+  --> $DIR/hash-stable-is-unstable.rs:3:1
+   |
+LL | extern crate rustc_data_structures;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(rustc_private)] to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? (see issue #27812)
+  --> $DIR/hash-stable-is-unstable.rs:5:1
+   |
+LL | extern crate rustc;
+   | ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(rustc_private)] to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? (see issue #27812)
+  --> $DIR/hash-stable-is-unstable.rs:7:1
+   |
+LL | extern crate rustc_macros;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(rustc_private)] to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? (see issue #27812)
+  --> $DIR/hash-stable-is-unstable.rs:10:5
+   |
+LL | use rustc_macros::HashStable;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(rustc_private)] to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? (see issue #27812)
+  --> $DIR/hash-stable-is-unstable.rs:13:10
+   |
+LL | #[derive(HashStable)]
+   |          ^^^^^^^^^^
+   |
+   = help: add #![feature(rustc_private)] to the crate attributes to enable
+
+error: aborting due to 6 previous errors
+
+Some errors occurred: E0601, E0658.
+For more information about an error, try `rustc --explain E0601`.
index 212f5d7c525f5907786826b461ce533bcf16d766..792ab6f59a43966382f1b7c3d73610f2b19e2ddf 100644 (file)
@@ -4,11 +4,7 @@ error[E0004]: non-exhaustive patterns: type `&'static !` is non-empty
 LL |     match uninhab_ref() {
    |           ^^^^^^^^^^^^^
    |
-help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-  --> $DIR/always-inhabited-union-ref.rs:23:11
-   |
-LL |     match uninhab_ref() {
-   |           ^^^^^^^^^^^^^
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: type `Foo` is non-empty
   --> $DIR/always-inhabited-union-ref.rs:27:11
@@ -16,11 +12,7 @@ error[E0004]: non-exhaustive patterns: type `Foo` is non-empty
 LL |     match uninhab_union() {
    |           ^^^^^^^^^^^^^^^
    |
-help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-  --> $DIR/always-inhabited-union-ref.rs:27:11
-   |
-LL |     match uninhab_union() {
-   |           ^^^^^^^^^^^^^^^
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to 2 previous errors
 
index 0d9c9d8143d31ecb36aca217c8058f1cb35e37dc..6a13b31fe932ff2a8636927edadd8d50a5049f04 100644 (file)
@@ -4,7 +4,10 @@ error[E0308]: mismatched types
 LL | fn main() {
    |           - expected `()` because of default return type
 LL |     &panic!()
-   |     ^^^^^^^^^ expected (), found reference
+   |     ^^^^^^^^^
+   |     |
+   |     expected (), found reference
+   |     help: consider removing the borrow: `panic!()`
    |
    = note: expected type `()`
               found type `&_`
index 7a517e856cbe21eafd9460c25d4e74ffd403d5c9..54e5c988f8ccc76c1d175b29e6074d8964029fce 100644 (file)
@@ -3,48 +3,70 @@ error[E0004]: non-exhaustive patterns: `(B, _)`, `(C, _)`, `(D, _)` and 2 more n
    |
 LL |     match (A, ()) { //~ ERROR non-exhaustive
    |           ^^^^^^^ patterns `(B, _)`, `(C, _)`, `(D, _)` and 2 more not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `(_, B)`, `(_, C)`, `(_, D)` and 2 more not covered
   --> $DIR/issue-35609.rs:14:11
    |
 LL |     match (A, A) { //~ ERROR non-exhaustive
    |           ^^^^^^ patterns `(_, B)`, `(_, C)`, `(_, D)` and 2 more not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
   --> $DIR/issue-35609.rs:18:11
    |
 LL |     match ((A, ()), ()) { //~ ERROR non-exhaustive
    |           ^^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
   --> $DIR/issue-35609.rs:22:11
    |
 LL |     match ((A, ()), A) { //~ ERROR non-exhaustive
    |           ^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
   --> $DIR/issue-35609.rs:26:11
    |
 LL |     match ((A, ()), ()) { //~ ERROR non-exhaustive
    |           ^^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `S(B, _)`, `S(C, _)`, `S(D, _)` and 2 more not covered
   --> $DIR/issue-35609.rs:31:11
    |
+LL | struct S(Enum, ());
+   | ------------------- `S` defined here
+...
 LL |     match S(A, ()) { //~ ERROR non-exhaustive
    |           ^^^^^^^^ patterns `S(B, _)`, `S(C, _)`, `S(D, _)` and 2 more not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `Sd { x: B, .. }`, `Sd { x: C, .. }`, `Sd { x: D, .. }` and 2 more not covered
   --> $DIR/issue-35609.rs:35:11
    |
+LL | struct Sd { x: Enum, y: () }
+   | ---------------------------- `Sd` defined here
+...
 LL |     match (Sd { x: A, y: () }) { //~ ERROR non-exhaustive
    |           ^^^^^^^^^^^^^^^^^^^^ patterns `Sd { x: B, .. }`, `Sd { x: C, .. }`, `Sd { x: D, .. }` and 2 more not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered
   --> $DIR/issue-35609.rs:39:11
    |
 LL |     match Some(A) { //~ ERROR non-exhaustive
    |           ^^^^^^^ patterns `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to 8 previous errors
 
index f4e9008dbd0f1563f7d8e4c211fd317d5624d112..662c7b767bae06e550891842d1deac0e556947dc 100644 (file)
@@ -1,23 +1,22 @@
 #![feature(const_generics)]
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
 
-fn u32_identity<const X: u32>() -> u32 {
-    //~^ ERROR const generics in any position are currently unsupported
+fn i32_identity<const X: i32>() -> i32 {
     5
 }
 
 fn foo_a() {
-    u32_identity::<-1>(); //~ ERROR expected identifier, found `<-`
+    i32_identity::<-1>(); //~ ERROR expected identifier, found `<-`
 }
 
 fn foo_b() {
-    u32_identity::<1 + 2>(); //~ ERROR expected one of `,` or `>`, found `+`
+    i32_identity::<1 + 2>(); //~ ERROR expected one of `,` or `>`, found `+`
 }
 
 fn foo_c() {
-    u32_identity::< -1 >(); // ok
+    i32_identity::< -1 >(); // ok
 }
 
 fn main() {
-    u32_identity::<5>(); // ok
+    i32_identity::<5>(); // ok
 }
index 1dd3a960316d99eea2e3b75ff826e263eab85faa..2741d621256220d1fc04646ecacd9b633830f979 100644 (file)
@@ -1,13 +1,13 @@
 error: expected identifier, found `<-`
-  --> $DIR/const-expression-parameter.rs:10:19
+  --> $DIR/const-expression-parameter.rs:9:19
    |
-LL |     u32_identity::<-1>(); //~ ERROR expected identifier, found `<-`
+LL |     i32_identity::<-1>(); //~ ERROR expected identifier, found `<-`
    |                   ^^ expected identifier
 
 error: expected one of `,` or `>`, found `+`
-  --> $DIR/const-expression-parameter.rs:14:22
+  --> $DIR/const-expression-parameter.rs:13:22
    |
-LL |     u32_identity::<1 + 2>(); //~ ERROR expected one of `,` or `>`, found `+`
+LL |     i32_identity::<1 + 2>(); //~ ERROR expected one of `,` or `>`, found `+`
    |                      ^ expected one of `,` or `>` here
 
 warning: the feature `const_generics` is incomplete and may cause the compiler to crash
@@ -16,11 +16,5 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t
 LL | #![feature(const_generics)]
    |            ^^^^^^^^^^^^^^
 
-error: const generics in any position are currently unsupported
-  --> $DIR/const-expression-parameter.rs:4:23
-   |
-LL | fn u32_identity<const X: u32>() -> u32 {
-   |                       ^
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
index 052d723d96edb21ac59cb053f5df4451095c9701..f36bf3875c34999bf57b84c5faf530c8a20d28e8 100644 (file)
@@ -3,7 +3,6 @@
 
 const fn const_u32_identity<const X: u32>() -> u32 {
     //~^ ERROR const parameters are not permitted in `const fn`
-    //~^^ ERROR const generics in any position are currently unsupported
     X
 }
 
index a08ebfb0d9766565029bba2a93332d92fa3e7455..94d2afa25b4f0f79d7fd461dc79f67bd3bc76fa3 100644 (file)
@@ -9,16 +9,9 @@ error: const parameters are not permitted in `const fn`
    |
 LL | / const fn const_u32_identity<const X: u32>() -> u32 {
 LL | |     //~^ ERROR const parameters are not permitted in `const fn`
-LL | |     //~^^ ERROR const generics in any position are currently unsupported
 LL | |     X
 LL | | }
    | |_^
 
-error: const generics in any position are currently unsupported
-  --> $DIR/const-fn-with-const-param.rs:4:35
-   |
-LL | const fn const_u32_identity<const X: u32>() -> u32 {
-   |                                   ^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
index 47f826789e03e2d75b6494e8c142d8d1982aa0b3..188b5dce31ea80e6211ae53b70d646c93ac73d6b 100644 (file)
@@ -1,14 +1,12 @@
 #![feature(const_generics)]
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
 
-fn foo<const X: (), T>(_: T) {
+fn foo<const X: (), T>(_: &T) {
     //~^ ERROR type parameters must be declared prior to const parameters
-    //~^^ ERROR const generics in any position are currently unsupported
 }
 
 fn bar<const X: (), 'a>(_: &'a ()) {
     //~^ ERROR lifetime parameters must be declared prior to const parameters
-    //~^^ ERROR const generics in any position are currently unsupported
 }
 
 fn main() {}
index a43415d0e5a43227cb1201632793c712e7e43e53..78f129e79ea24363b8123a97c23e0babd7772351 100644 (file)
@@ -7,26 +7,14 @@ LL | #![feature(const_generics)]
 error: type parameters must be declared prior to const parameters
   --> $DIR/const-param-before-other-params.rs:4:21
    |
-LL | fn foo<const X: (), T>(_: T) {
+LL | fn foo<const X: (), T>(_: &T) {
    |       --------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const X: ()>`
 
 error: lifetime parameters must be declared prior to const parameters
-  --> $DIR/const-param-before-other-params.rs:9:21
+  --> $DIR/const-param-before-other-params.rs:8:21
    |
 LL | fn bar<const X: (), 'a>(_: &'a ()) {
    |       --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>`
 
-error: const generics in any position are currently unsupported
-  --> $DIR/const-param-before-other-params.rs:4:14
-   |
-LL | fn foo<const X: (), T>(_: T) {
-   |              ^
-
-error: const generics in any position are currently unsupported
-  --> $DIR/const-param-before-other-params.rs:9:14
-   |
-LL | fn bar<const X: (), 'a>(_: &'a ()) {
-   |              ^
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
index 5a8dd92086f8597c42561cd983ae984c423ddedc..6534bcf5ce64c91bad8eb7c288860f9209e1f5fe 100644 (file)
@@ -2,7 +2,6 @@
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
 
 fn foo<const X: u32>() {
-    //~^ ERROR const generics in any position are currently unsupported
     fn bar() -> u32 {
         X //~ ERROR can't use generic parameters from outer function
     }
index b238b3a2aa453b692b93b10446fe23c2911f6df5..f40b527d716079d773f2a540321e32ccdb28216a 100644 (file)
@@ -5,22 +5,15 @@ LL | #![feature(const_generics)]
    |            ^^^^^^^^^^^^^^
 
 error[E0401]: can't use generic parameters from outer function
-  --> $DIR/const-param-from-outer-fn.rs:7:9
+  --> $DIR/const-param-from-outer-fn.rs:6:9
    |
 LL | fn foo<const X: u32>() {
    |              - const variable from outer function
-LL |     //~^ ERROR const generics in any position are currently unsupported
 LL |     fn bar() -> u32 {
    |        --- try adding a local generic parameter in this method instead
 LL |         X //~ ERROR can't use generic parameters from outer function
    |         ^ use of generic parameter from outer function
 
-error: const generics in any position are currently unsupported
-  --> $DIR/const-param-from-outer-fn.rs:4:14
-   |
-LL | fn foo<const X: u32>() {
-   |              ^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0401`.
index 37fe9af98b3df4a6f39f5304912d375f86a759fa..164205dd75cbc6749cc2af478e3b9a396ee06c59 100644 (file)
@@ -4,5 +4,7 @@
 #![deny(non_upper_case_globals)]
 
 fn noop<const x: u32>() {
-    //~^ ERROR const generics in any position are currently unsupported
+    //~^ ERROR const parameter `x` should have an upper case name
 }
+
+fn main() {}
index 9683e91cef30c05bb44d516f557ee8949e049b49..190798d202bead803980e7d480304278ee235d52 100644 (file)
@@ -4,16 +4,17 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t
 LL | #![feature(const_generics)]
    |            ^^^^^^^^^^^^^^
 
-error[E0601]: `main` function not found in crate `const_parameter_uppercase_lint`
-   |
-   = note: consider adding a `main` function to `$DIR/const-parameter-uppercase-lint.rs`
-
-error: const generics in any position are currently unsupported
+error: const parameter `x` should have an upper case name
   --> $DIR/const-parameter-uppercase-lint.rs:6:15
    |
 LL | fn noop<const x: u32>() {
-   |               ^
+   |               ^ help: convert the identifier to upper case: `X`
+   |
+note: lint level defined here
+  --> $DIR/const-parameter-uppercase-lint.rs:4:9
+   |
+LL | #![deny(non_upper_case_globals)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0601`.
index e6e04e2c4627687d8388b124e7df0bdf431533da..d9840231695975002985fc1daab6e338aabadcaf 100644 (file)
@@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `&S` not covered
    |
 LL |     match C { //~ ERROR non-exhaustive
    |           ^ pattern `&S` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index 4ab14a1df84dbc0a54122803f99576d2126b10a3..9d96908a05620cb1a1a436618ae2d3be351019de 100644 (file)
@@ -1,4 +1,4 @@
-error: #[derive] can't be used on a #[repr(packed)] struct with type parameters (error E0133)
+error: #[derive] can't be used on a #[repr(packed)] struct with type or const parameters (error E0133)
   --> $DIR/deriving-with-repr-packed.rs:8:16
    |
 LL | #[derive(Copy, Clone, PartialEq, Eq)]
@@ -12,7 +12,7 @@ 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>
 
-error: #[derive] can't be used on a #[repr(packed)] struct with type parameters (error E0133)
+error: #[derive] can't be used on a #[repr(packed)] struct with type or const parameters (error E0133)
   --> $DIR/deriving-with-repr-packed.rs:8:23
    |
 LL | #[derive(Copy, Clone, PartialEq, Eq)]
index c399650d3258b950db82ff31fe48c18475880905..3457549a752392ce928ee309650deca03392297f 100644 (file)
@@ -1,13 +1,19 @@
 error[E0308]: mismatched types
   --> $DIR/diverging-tuple-parts-39485.rs:8:5
    |
-LL | fn g() {
-   |        - help: try adding a return type: `-> &_`
 LL |     &panic!() //~ ERROR mismatched types
    |     ^^^^^^^^^ expected (), found reference
    |
    = note: expected type `()`
               found type `&_`
+help: try adding a return type
+   |
+LL | fn g() -> &_ {
+   |        ^^^^^
+help: consider removing the borrow
+   |
+LL |     panic!() //~ ERROR mismatched types
+   |     ^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/diverging-tuple-parts-39485.rs:12:5
index e409f14d6ce97272fdc1512afec1029012a36c8c..f1be4a6edec5f51a714e9756586625d59c920769 100644 (file)
@@ -1,8 +1,15 @@
 error[E0005]: refutable pattern in local binding: `T(_, _)` not covered
   --> $DIR/empty-never-array.rs:10:9
    |
-LL |     let Helper::U(u) = Helper::T(t, []);
-   |         ^^^^^^^^^^^^ pattern `T(_, _)` not covered
+LL | / enum Helper<T, U> {
+LL | |     T(T, [!; 0]),
+LL | |     #[allow(dead_code)]
+LL | |     U(U),
+LL | | }
+   | |_- `Helper<T, U>` defined here
+...
+LL |       let Helper::U(u) = Helper::T(t, []);
+   |           ^^^^^^^^^^^^ pattern `T(_, _)` not covered
 
 error: aborting due to previous error
 
index 8b262cc6eb7843245489dc577a18c0c2c881619d..c8732852a71ee06e64e9711b20b639fbc4d06628 100644 (file)
@@ -1,14 +1,10 @@
-error[E0004]: non-exhaustive patterns: type `std::option::Option<i32>` is non-empty
+error[E0004]: non-exhaustive patterns: multiple patterns of type `std::option::Option<i32>` are not handled
   --> $DIR/E0004-2.rs:4:11
    |
 LL |     match x { } //~ ERROR E0004
    |           ^
    |
-help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-  --> $DIR/E0004-2.rs:4:11
-   |
-LL |     match x { } //~ ERROR E0004
-   |           ^
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index a66dd929032009f2de5e668eaf98de9ede78392f..123f4b2f1b71d630b3869ee30ec7422f01121473 100644 (file)
@@ -1,8 +1,17 @@
 error[E0004]: non-exhaustive patterns: `HastaLaVistaBaby` not covered
   --> $DIR/E0004.rs:9:11
    |
-LL |     match x { //~ ERROR E0004
-   |           ^ pattern `HastaLaVistaBaby` not covered
+LL | / enum Terminator {
+LL | |     HastaLaVistaBaby,
+   | |     ---------------- not covered
+LL | |     TalkToMyHand,
+LL | | }
+   | |_- `Terminator` defined here
+...
+LL |       match x { //~ ERROR E0004
+   |             ^ pattern `HastaLaVistaBaby` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index 7b873f7ba4259192dd2b3b256c44fdc4f46bc596..d9513710d4463ec688b9d2a80c7931d8659e6b93 100644 (file)
@@ -15,12 +15,16 @@ error[E0004]: non-exhaustive patterns: `128u8..=255u8` not covered
    |
 LL |     match x { //~ ERROR non-exhaustive patterns
    |           ^ pattern `128u8..=255u8` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `11u8..=19u8`, `31u8..=34u8`, `36u8..=69u8` and 1 more not covered
   --> $DIR/exhaustive_integer_patterns.rs:33:11
    |
 LL |     match x { //~ ERROR non-exhaustive patterns
    |           ^ patterns `11u8..=19u8`, `31u8..=34u8`, `36u8..=69u8` and 1 more not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: unreachable pattern
   --> $DIR/exhaustive_integer_patterns.rs:44:9
@@ -33,54 +37,72 @@ error[E0004]: non-exhaustive patterns: `-128i8..=-8i8`, `-6i8`, `121i8..=124i8`
    |
 LL |     match x { //~ ERROR non-exhaustive patterns
    |           ^ patterns `-128i8..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `-128i8` not covered
   --> $DIR/exhaustive_integer_patterns.rs:82:11
    |
 LL |     match 0i8 { //~ ERROR non-exhaustive patterns
    |           ^^^ pattern `-128i8` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `0i16` not covered
   --> $DIR/exhaustive_integer_patterns.rs:90:11
    |
 LL |     match 0i16 { //~ ERROR non-exhaustive patterns
    |           ^^^^ pattern `0i16` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `128u8..=255u8` not covered
   --> $DIR/exhaustive_integer_patterns.rs:108:11
    |
 LL |     match 0u8 { //~ ERROR non-exhaustive patterns
    |           ^^^ pattern `128u8..=255u8` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `(0u8, Some(_))` and `(2u8..=255u8, Some(_))` not covered
   --> $DIR/exhaustive_integer_patterns.rs:120:11
    |
 LL |     match (0u8, Some(())) { //~ ERROR non-exhaustive patterns
    |           ^^^^^^^^^^^^^^^ patterns `(0u8, Some(_))` and `(2u8..=255u8, Some(_))` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `(126u8..=127u8, false)` not covered
   --> $DIR/exhaustive_integer_patterns.rs:125:11
    |
 LL |     match (0u8, true) { //~ ERROR non-exhaustive patterns
    |           ^^^^^^^^^^^ pattern `(126u8..=127u8, false)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `340282366920938463463374607431768211455u128` not covered
   --> $DIR/exhaustive_integer_patterns.rs:145:11
    |
 LL |     match 0u128 { //~ ERROR non-exhaustive patterns
    |           ^^^^^ pattern `340282366920938463463374607431768211455u128` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `5u128..=340282366920938463463374607431768211455u128` not covered
   --> $DIR/exhaustive_integer_patterns.rs:149:11
    |
 LL |     match 0u128 { //~ ERROR non-exhaustive patterns
    |           ^^^^^ pattern `5u128..=340282366920938463463374607431768211455u128` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `0u128..=3u128` not covered
   --> $DIR/exhaustive_integer_patterns.rs:153:11
    |
 LL |     match 0u128 { //~ ERROR non-exhaustive patterns
    |           ^^^^^ pattern `0u128..=3u128` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to 13 previous errors
 
index 907e00b11e556de804542779b70276ce5ccf75a2..fe1ded1c4bbc4bba7e8b86d954a113a51a1d59ad 100644 (file)
@@ -1,7 +1,5 @@
 fn foo<const X: ()>() {} //~ ERROR const generics are unstable
-//~^ const generics in any position are currently unsupported
 
 struct Foo<const X: usize>([(); X]); //~ ERROR const generics are unstable
-//~^ const generics in any position are currently unsupported
 
 fn main() {}
index 3ab1aa2367f1c637eecf4d3428f6204da7d6492b..bd86a4197a76e7c46aa7d502d3bb474c06dbf90f 100644 (file)
@@ -7,25 +7,13 @@ LL | fn foo<const X: ()>() {} //~ ERROR const generics are unstable
    = help: add #![feature(const_generics)] to the crate attributes to enable
 
 error[E0658]: const generics are unstable (see issue #44580)
-  --> $DIR/feature-gate-const_generics.rs:4:18
+  --> $DIR/feature-gate-const_generics.rs:3:18
    |
 LL | struct Foo<const X: usize>([(); X]); //~ ERROR const generics are unstable
    |                  ^
    |
    = help: add #![feature(const_generics)] to the crate attributes to enable
 
-error: const generics in any position are currently unsupported
-  --> $DIR/feature-gate-const_generics.rs:1:14
-   |
-LL | fn foo<const X: ()>() {} //~ ERROR const generics are unstable
-   |              ^
-
-error: const generics in any position are currently unsupported
-  --> $DIR/feature-gate-const_generics.rs:4:18
-   |
-LL | struct Foo<const X: usize>([(); X]); //~ ERROR const generics are unstable
-   |                  ^
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
index 5806f6f039157cbeaf91ee0b5f82208af7aa8054..fd1e5392e69e49ff1f45a776af115e39a308cbd0 100644 (file)
@@ -3,12 +3,16 @@ error[E0004]: non-exhaustive patterns: `_` not covered
    |
 LL |     match 0usize { //~ERROR non-exhaustive patterns: `_` not covered
    |           ^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/feature-gate-precise_pointer_size_matching.rs:10:11
    |
 LL |     match 0isize { //~ERROR non-exhaustive patterns: `_` not covered
    |           ^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to 2 previous errors
 
index 7ee369085202bc4db625073b9ef75e0295161c04..b93fa14db0387b8568ec70acffab4d8e08ce36eb 100644 (file)
@@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `(T1(()), V2(_))` not covered
    |
 LL |     match (T::T1(()), V::V2(true)) {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `(T1(()), V2(_))` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index 348ad153c8099369626ff4b7677ecf01790cef04..90fdb48ea625d3dbacf51c22843dcdcab34193db 100644 (file)
@@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `(None, None)` not covered
    |
 LL |   match (a,b) {
    |         ^^^^^ pattern `(None, None)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index 973c59c58526b7a26912d7ff42845253718719d7..bc538abf3bdf012db517b77377745b43d09de6b3 100644 (file)
@@ -3,12 +3,16 @@ error[E0004]: non-exhaustive patterns: `&_` not covered
    |
 LL |     match "world" { //~ ERROR non-exhaustive patterns: `&_`
    |           ^^^^^^^ pattern `&_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `&_` not covered
   --> $DIR/issue-30240.rs:6:11
    |
 LL |     match "world" { //~ ERROR non-exhaustive patterns: `&_`
    |           ^^^^^^^ pattern `&_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to 2 previous errors
 
index 7ced0d36805dd728e8ecd1cf8eca253109527592..fee58474031e993174659af3d4000d8d1299a6bc 100644 (file)
@@ -4,11 +4,7 @@ error[E0004]: non-exhaustive patterns: type `()` is non-empty
 LL |     match () { } //~ ERROR non-exhaustive
    |           ^^
    |
-help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-  --> $DIR/issue-3096-1.rs:2:11
-   |
-LL |     match () { } //~ ERROR non-exhaustive
-   |           ^^
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index df876794489567db1d426a0dfefb7590ffd2e31d..93119d377441f7061ad045a2df91cac946f2adc7 100644 (file)
@@ -4,11 +4,7 @@ error[E0004]: non-exhaustive patterns: type `*const Bottom` is non-empty
 LL |     match x { } //~ ERROR non-exhaustive patterns
    |           ^
    |
-help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-  --> $DIR/issue-3096-2.rs:5:11
-   |
-LL |     match x { } //~ ERROR non-exhaustive patterns
-   |           ^
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index c95fc36cea6e8e09d634a576a79b62bc09af68ed..246137aeee05c5ba137edb35a12619723ebe3662 100644 (file)
@@ -1,8 +1,15 @@
 error[E0005]: refutable pattern in local binding: `Bar` not covered
   --> $DIR/issue-31561.rs:8:9
    |
-LL |     let Thing::Foo(y) = Thing::Foo(1);
-   |         ^^^^^^^^^^^^^ pattern `Bar` not covered
+LL | / enum Thing {
+LL | |     Foo(u8),
+LL | |     Bar,
+LL | |     Baz
+LL | | }
+   | |_- `Thing` defined here
+...
+LL |       let Thing::Foo(y) = Thing::Foo(1);
+   |           ^^^^^^^^^^^^^ pattern `Bar` not covered
 
 error: aborting due to previous error
 
index 0b5242ee528dd3d7fb3dee1d0183c2593e9f883d..85b534434342b6f45e308b575eafd778a84b232d 100644 (file)
@@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `_` not covered
    |
 LL |         box NodeKind::Element(ed) => match ed.kind { //~ ERROR non-exhaustive patterns
    |                                            ^^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index 06385127e94fe26ac33fda1ebf30e24aa77fa12e..55cd14a5c1e0899d80f8ee104750aa32d28ea81e 100644 (file)
@@ -1,8 +1,15 @@
 error[E0004]: non-exhaustive patterns: `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered
   --> $DIR/issue-39362.rs:10:11
    |
-LL |     match f {
-   |           ^ patterns `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered
+LL | / enum Foo {
+LL | |     Bar { bar: Bar, id: usize }
+LL | | }
+   | |_- `Foo` defined here
+...
+LL |       match f {
+   |             ^ patterns `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index 7817fdcbce99cf6032a1b6e9e39409fc5e084e83..731e63fbb2b049fbdad60904f8fc7d383258490a 100644 (file)
@@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `(true, false)` not covered
    |
 LL |     println!("foo {:}", match tup { //~ ERROR non-exhaustive patterns: `(true, false)` not covered
    |                               ^^^ pattern `(true, false)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-50582.rs b/src/test/ui/issues/issue-50582.rs
new file mode 100644 (file)
index 0000000..1358e0b
--- /dev/null
@@ -0,0 +1,4 @@
+fn main() {
+    Vec::<[(); 1 + for x in 0..1 {}]>::new();
+    //~^ ERROR cannot add
+}
diff --git a/src/test/ui/issues/issue-50582.stderr b/src/test/ui/issues/issue-50582.stderr
new file mode 100644 (file)
index 0000000..226f5a3
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0277]: cannot add `()` to `{integer}`
+  --> $DIR/issue-50582.rs:2:18
+   |
+LL |     Vec::<[(); 1 + for x in 0..1 {}]>::new();
+   |                  ^ no implementation for `{integer} + ()`
+   |
+   = help: the trait `std::ops::Add<()>` is not implemented for `{integer}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-58857.rs b/src/test/ui/issues/issue-58857.rs
new file mode 100644 (file)
index 0000000..392e4ea
--- /dev/null
@@ -0,0 +1,7 @@
+struct Conj<A> {a : A}
+trait Valid {}
+
+impl<A: !Valid> Conj<A>{}
+//~^ ERROR negative trait bounds are not supported
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-58857.stderr b/src/test/ui/issues/issue-58857.stderr
new file mode 100644 (file)
index 0000000..040e9eb
--- /dev/null
@@ -0,0 +1,8 @@
+error: negative trait bounds are not supported
+  --> $DIR/issue-58857.rs:4:7
+   |
+LL | impl<A: !Valid> Conj<A>{}
+   |       ^^^^^^^^ help: remove the trait bound
+
+error: aborting due to previous error
+
index 3e6f22ab8751392eaab3641e9f334f8b10cc99fd..8c54e030823af0298d9b141f64606d95e62fdb48 100644 (file)
@@ -3,18 +3,30 @@ error[E0004]: non-exhaustive patterns: `(true, false)` not covered
    |
 LL |     match (true, false) {
    |           ^^^^^^^^^^^^^ pattern `(true, false)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `Some(Some(West))` not covered
   --> $DIR/match-argm-statics-2.rs:29:11
    |
 LL |     match Some(Some(North)) {
    |           ^^^^^^^^^^^^^^^^^ pattern `Some(Some(West))` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `Foo { bar: Some(North), baz: NewBool(true) }` not covered
   --> $DIR/match-argm-statics-2.rs:48:11
    |
-LL |     match (Foo { bar: Some(North), baz: NewBool(true) }) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { bar: Some(North), baz: NewBool(true) }` not covered
+LL | / struct Foo {
+LL | |     bar: Option<Direction>,
+LL | |     baz: NewBool
+LL | | }
+   | |_- `Foo` defined here
+...
+LL |       match (Foo { bar: Some(North), baz: NewBool(true) }) {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { bar: Some(North), baz: NewBool(true) }` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to 3 previous errors
 
index 4030cd39448a06d71f19a429800b5831795bfe2c..83dbecfcac6574bacc0a68eae11b9a7ebe8b584e 100644 (file)
@@ -3,12 +3,16 @@ error[E0004]: non-exhaustive patterns: `&[_, _, _, _]` not covered
    |
 LL |     match buf { //~ ERROR non-exhaustive
    |           ^^^ pattern `&[_, _, _, _]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `&[]`, `&[_]`, `&[_, _]` and 3 more not covered
   --> $DIR/match-byte-array-patterns-2.rs:10:11
    |
 LL |     match buf { //~ ERROR non-exhaustive
    |           ^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 3 more not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to 2 previous errors
 
index ab5ab18c3283a3e28707c07bfa22861f7538c194..9921e4f63b641d1ea248f0de0838cdf17ddfed2b 100644 (file)
@@ -3,12 +3,16 @@ error[E0004]: non-exhaustive patterns: `-2147483648i32..=0i32` and `2i32..=21474
    |
 LL |     match 0 { 1 => () } //~ ERROR non-exhaustive patterns
    |           ^ patterns `-2147483648i32..=0i32` and `2i32..=2147483647i32` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/match-non-exhaustive.rs:3:11
    |
 LL |     match 0 { 0 if false => () } //~ ERROR non-exhaustive patterns
    |           ^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to 2 previous errors
 
index 23ca64e50af783456456b77b38fa8ffaa422e8e4..f79d180a1b8b5c0f82765f868c761e1ff6950d62 100644 (file)
@@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not co
    |
 LL |     match private::DATA {
    |           ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index 2b817498aba9f1614030b11548ca0c61f9cb189c..24769db34c9322f252d1917967674717fc3448bb 100644 (file)
@@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `&[_, Some(_), None, _]` not covered
    |
 LL |     match list {
    |           ^^^^ pattern `&[_, Some(_), None, _]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index 437fb7bbc31316226588a7bf9a39a270010b7e65..9e4ce7c81b70eefc858c4ea342d1985d8e6efa85 100644 (file)
@@ -1,8 +1,16 @@
 error[E0004]: non-exhaustive patterns: `C(QA)` not covered
   --> $DIR/issue-40221.rs:11:11
    |
-LL |     match proto { //~ ERROR non-exhaustive patterns
-   |           ^^^^^ pattern `C(QA)` not covered
+LL | / enum P {
+LL | |     C(PC),
+   | |     - not covered
+LL | | }
+   | |_- `P` defined here
+...
+LL |       match proto { //~ ERROR non-exhaustive patterns
+   |             ^^^^^ pattern `C(QA)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index c60c265b813b805682ecb40a5eb08f586f0c6d93..ececd6fccd84bc75dedc371a24f1e7ca864eff3a 100644 (file)
@@ -1,14 +1,12 @@
 // Regression test for #48697
 
-// compile-pass
-
 #![feature(nll)]
 
 fn foo(x: &i32) -> &i32 {
     let z = 4;
     let f = &|y| y;
     let k = f(&z);
-    f(x)
+    f(x) //~ cannot return value referencing local variable
 }
 
 fn main() {}
diff --git a/src/test/ui/nll/issue-48697.stderr b/src/test/ui/nll/issue-48697.stderr
new file mode 100644 (file)
index 0000000..16b46c1
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0515]: cannot return value referencing local variable `z`
+  --> $DIR/issue-48697.rs:9:5
+   |
+LL |     let k = f(&z);
+   |               -- `z` is borrowed here
+LL |     f(x) //~ cannot return value referencing local variable
+   |     ^^^^ returns a value referencing data owned by the current function
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0515`.
diff --git a/src/test/ui/nll/promoted-bounds.rs b/src/test/ui/nll/promoted-bounds.rs
new file mode 100644 (file)
index 0000000..59b21cf
--- /dev/null
@@ -0,0 +1,27 @@
+#![feature(nll)]
+
+fn shorten_lifetime<'a, 'b, 'min>(a: &'a i32, b: &'b i32) -> &'min i32
+where
+    'a: 'min,
+    'b: 'min,
+{
+    if *a < *b {
+        &a
+    } else {
+        &b
+    }
+}
+
+fn main() {
+    let promoted_fn_item_ref = &shorten_lifetime;
+
+    let a = &5;
+    let ptr = {
+        let l = 3;
+        let b = &l; //~ ERROR does not live long enough
+        let c = promoted_fn_item_ref(a, b);
+        c
+    };
+
+    println!("ptr = {:?}", ptr);
+}
diff --git a/src/test/ui/nll/promoted-bounds.stderr b/src/test/ui/nll/promoted-bounds.stderr
new file mode 100644 (file)
index 0000000..9798f23
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0597]: `l` does not live long enough
+  --> $DIR/promoted-bounds.rs:21:17
+   |
+LL |     let ptr = {
+   |         --- borrow later stored here
+LL |         let l = 3;
+LL |         let b = &l; //~ ERROR does not live long enough
+   |                 ^^ borrowed value does not live long enough
+...
+LL |     };
+   |     - `l` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/nll/promoted-closure-pair.rs b/src/test/ui/nll/promoted-closure-pair.rs
new file mode 100644 (file)
index 0000000..7b3bbad
--- /dev/null
@@ -0,0 +1,12 @@
+// Check that we handle multiple closures in the same promoted constant.
+
+#![feature(nll)]
+
+fn foo() -> &'static i32 {
+    let z = 0;
+    let p = &(|y| y, |y| y);
+    p.0(&z);
+    p.1(&z)         //~ ERROR cannot return
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/promoted-closure-pair.stderr b/src/test/ui/nll/promoted-closure-pair.stderr
new file mode 100644 (file)
index 0000000..5f4a603
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0515]: cannot return value referencing local variable `z`
+  --> $DIR/promoted-closure-pair.rs:9:5
+   |
+LL |     p.1(&z)         //~ ERROR cannot return
+   |     ^^^^--^
+   |     |   |
+   |     |   `z` is borrowed here
+   |     returns a value referencing data owned by the current function
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0515`.
diff --git a/src/test/ui/nll/type-check-pointer-coercions.rs b/src/test/ui/nll/type-check-pointer-coercions.rs
new file mode 100644 (file)
index 0000000..b6a25ed
--- /dev/null
@@ -0,0 +1,39 @@
+#![feature(nll)]
+
+fn shared_to_const<'a, 'b>(x: &&'a i32) -> *const &'b i32 {
+    x   //~ ERROR
+}
+
+fn unique_to_const<'a, 'b>(x: &mut &'a i32) -> *const &'b i32 {
+    x   //~ ERROR
+}
+
+fn unique_to_mut<'a, 'b>(x: &mut &'a i32) -> *mut &'b i32 {
+    // Two errors because *mut is invariant
+    x   //~ ERROR
+        //~| ERROR
+}
+
+fn mut_to_const<'a, 'b>(x: *mut &'a i32) -> *const &'b i32 {
+    x   //~ ERROR
+}
+
+fn array_elem<'a, 'b>(x: &'a i32) -> *const &'b i32 {
+    let z = &[x; 3];
+    let y = z as *const &i32;
+    y   //~ ERROR
+}
+
+fn array_coerce<'a, 'b>(x: &'a i32) -> *const [&'b i32; 3] {
+    let z = &[x; 3];
+    let y = z as *const [&i32; 3];
+    y   //~ ERROR
+}
+
+fn nested_array<'a, 'b>(x: &'a i32) -> *const [&'b i32; 2] {
+    let z = &[[x; 2]; 3];
+    let y = z as *const [&i32; 2];
+    y   //~ ERROR
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/type-check-pointer-coercions.stderr b/src/test/ui/nll/type-check-pointer-coercions.stderr
new file mode 100644 (file)
index 0000000..3b8d994
--- /dev/null
@@ -0,0 +1,87 @@
+error: lifetime may not live long enough
+  --> $DIR/type-check-pointer-coercions.rs:4:5
+   |
+LL | fn shared_to_const<'a, 'b>(x: &&'a i32) -> *const &'b i32 {
+   |                    --  -- lifetime `'b` defined here
+   |                    |
+   |                    lifetime `'a` defined here
+LL |     x   //~ ERROR
+   |     ^ returning this value requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+  --> $DIR/type-check-pointer-coercions.rs:8:5
+   |
+LL | fn unique_to_const<'a, 'b>(x: &mut &'a i32) -> *const &'b i32 {
+   |                    --  -- lifetime `'b` defined here
+   |                    |
+   |                    lifetime `'a` defined here
+LL |     x   //~ ERROR
+   |     ^ returning this value requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+  --> $DIR/type-check-pointer-coercions.rs:13:5
+   |
+LL | fn unique_to_mut<'a, 'b>(x: &mut &'a i32) -> *mut &'b i32 {
+   |                  --  -- lifetime `'b` defined here
+   |                  |
+   |                  lifetime `'a` defined here
+LL |     // Two errors because *mut is invariant
+LL |     x   //~ ERROR
+   |     ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+
+error: lifetime may not live long enough
+  --> $DIR/type-check-pointer-coercions.rs:13:5
+   |
+LL | fn unique_to_mut<'a, 'b>(x: &mut &'a i32) -> *mut &'b i32 {
+   |                  --  -- lifetime `'b` defined here
+   |                  |
+   |                  lifetime `'a` defined here
+LL |     // Two errors because *mut is invariant
+LL |     x   //~ ERROR
+   |     ^ returning this value requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+  --> $DIR/type-check-pointer-coercions.rs:18:5
+   |
+LL | fn mut_to_const<'a, 'b>(x: *mut &'a i32) -> *const &'b i32 {
+   |                 --  -- lifetime `'b` defined here
+   |                 |
+   |                 lifetime `'a` defined here
+LL |     x   //~ ERROR
+   |     ^ returning this value requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+  --> $DIR/type-check-pointer-coercions.rs:24:5
+   |
+LL | fn array_elem<'a, 'b>(x: &'a i32) -> *const &'b i32 {
+   |               --  -- lifetime `'b` defined here
+   |               |
+   |               lifetime `'a` defined here
+...
+LL |     y   //~ ERROR
+   |     ^ returning this value requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+  --> $DIR/type-check-pointer-coercions.rs:30:5
+   |
+LL | fn array_coerce<'a, 'b>(x: &'a i32) -> *const [&'b i32; 3] {
+   |                 --  -- lifetime `'b` defined here
+   |                 |
+   |                 lifetime `'a` defined here
+...
+LL |     y   //~ ERROR
+   |     ^ returning this value requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+  --> $DIR/type-check-pointer-coercions.rs:36:5
+   |
+LL | fn nested_array<'a, 'b>(x: &'a i32) -> *const [&'b i32; 2] {
+   |                 --  -- lifetime `'b` defined here
+   |                 |
+   |                 lifetime `'a` defined here
+...
+LL |     y   //~ ERROR
+   |     ^ returning this value requires that `'a` must outlive `'b`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/ui/nll/type-check-pointer-comparisons.rs b/src/test/ui/nll/type-check-pointer-comparisons.rs
new file mode 100644 (file)
index 0000000..3c90035
--- /dev/null
@@ -0,0 +1,33 @@
+#![feature(nll)]
+
+// Check that we assert that pointers have a common subtype for comparisons
+
+fn compare_const<'a, 'b>(x: *const &mut &'a i32, y: *const &mut &'b i32) {
+    x == y;
+    //~^ ERROR lifetime may not live long enough
+    //~| ERROR lifetime may not live long enough
+}
+
+fn compare_mut<'a, 'b>(x: *mut &'a i32, y: *mut &'b i32) {
+    x == y;
+    //~^ ERROR lifetime may not live long enough
+    //~| ERROR lifetime may not live long enough
+}
+
+fn compare_fn_ptr<'a, 'b, 'c>(f: fn(&'c mut &'a i32), g: fn(&'c mut &'b i32)) {
+    f == g;
+    //~^ ERROR lifetime may not live long enough
+    //~| ERROR lifetime may not live long enough
+}
+
+fn compare_hr_fn_ptr<'a>(f: fn(&'a i32), g: fn(&i32)) {
+    // Ideally this should compile with the operands swapped as well, but HIR
+    // type checking prevents it (and stops compilation) for now.
+    f == g; // OK
+}
+
+fn compare_const_fn_ptr<'a>(f: *const fn(&'a i32), g: *const fn(&i32)) {
+    f == g; // OK
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/type-check-pointer-comparisons.stderr b/src/test/ui/nll/type-check-pointer-comparisons.stderr
new file mode 100644 (file)
index 0000000..c0a994c
--- /dev/null
@@ -0,0 +1,62 @@
+error: lifetime may not live long enough
+  --> $DIR/type-check-pointer-comparisons.rs:6:5
+   |
+LL | fn compare_const<'a, 'b>(x: *const &mut &'a i32, y: *const &mut &'b i32) {
+   |                  --  -- lifetime `'b` defined here
+   |                  |
+   |                  lifetime `'a` defined here
+LL |     x == y;
+   |     ^ requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+  --> $DIR/type-check-pointer-comparisons.rs:6:10
+   |
+LL | fn compare_const<'a, 'b>(x: *const &mut &'a i32, y: *const &mut &'b i32) {
+   |                  --  -- lifetime `'b` defined here
+   |                  |
+   |                  lifetime `'a` defined here
+LL |     x == y;
+   |          ^ requires that `'b` must outlive `'a`
+
+error: lifetime may not live long enough
+  --> $DIR/type-check-pointer-comparisons.rs:12:5
+   |
+LL | fn compare_mut<'a, 'b>(x: *mut &'a i32, y: *mut &'b i32) {
+   |                --  -- lifetime `'b` defined here
+   |                |
+   |                lifetime `'a` defined here
+LL |     x == y;
+   |     ^ requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+  --> $DIR/type-check-pointer-comparisons.rs:12:10
+   |
+LL | fn compare_mut<'a, 'b>(x: *mut &'a i32, y: *mut &'b i32) {
+   |                --  -- lifetime `'b` defined here
+   |                |
+   |                lifetime `'a` defined here
+LL |     x == y;
+   |          ^ requires that `'b` must outlive `'a`
+
+error: lifetime may not live long enough
+  --> $DIR/type-check-pointer-comparisons.rs:18:5
+   |
+LL | fn compare_fn_ptr<'a, 'b, 'c>(f: fn(&'c mut &'a i32), g: fn(&'c mut &'b i32)) {
+   |                   --  -- lifetime `'b` defined here
+   |                   |
+   |                   lifetime `'a` defined here
+LL |     f == g;
+   |     ^ requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+  --> $DIR/type-check-pointer-comparisons.rs:18:10
+   |
+LL | fn compare_fn_ptr<'a, 'b, 'c>(f: fn(&'c mut &'a i32), g: fn(&'c mut &'b i32)) {
+   |                   --  -- lifetime `'b` defined here
+   |                   |
+   |                   lifetime `'a` defined here
+LL |     f == g;
+   |          ^ requires that `'b` must outlive `'a`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/nll/user-annotations/promoted-annotation.rs b/src/test/ui/nll/user-annotations/promoted-annotation.rs
new file mode 100644 (file)
index 0000000..fa2d2fb
--- /dev/null
@@ -0,0 +1,12 @@
+// Test that type annotations are checked in promoted constants correctly.
+
+#![feature(nll)]
+
+fn foo<'a>() {
+    let x = 0;
+    let f = &drop::<&'a i32>;
+    f(&x);
+    //~^ ERROR `x` does not live long enough
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/user-annotations/promoted-annotation.stderr b/src/test/ui/nll/user-annotations/promoted-annotation.stderr
new file mode 100644 (file)
index 0000000..144af1e
--- /dev/null
@@ -0,0 +1,17 @@
+error[E0597]: `x` does not live long enough
+  --> $DIR/promoted-annotation.rs:8:7
+   |
+LL | fn foo<'a>() {
+   |        -- lifetime `'a` defined here
+LL |     let x = 0;
+LL |     let f = &drop::<&'a i32>;
+   |             ---------------- assignment requires that `x` is borrowed for `'a`
+LL |     f(&x);
+   |       ^^ borrowed value does not live long enough
+LL |     //~^ ERROR `x` does not live long enough
+LL | }
+   | - `x` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
index 2e285afb3804e614b2d3ca24c9a4b0ae0193d0bc..03215f72ebcd47a1aadb14894d25497be4f665e1 100644 (file)
@@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `_` not covered
    |
 LL |     match 0.0 { //~ ERROR non-exhaustive patterns
    |           ^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index b2551c8dcf2ae9ad37587bf98c36fb2a6e068d96..d5beac4b716338c0c902362f047f3e4911c7d547 100644 (file)
@@ -3,12 +3,22 @@ error[E0004]: non-exhaustive patterns: `(Some(&[]), Err(_))` not covered
    |
 LL |     match (l1, l2) { //~ ERROR non-exhaustive patterns: `(Some(&[]), Err(_))` not covered
    |           ^^^^^^^^ pattern `(Some(&[]), Err(_))` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `A(C)` not covered
   --> $DIR/non-exhaustive-match-nested.rs:17:11
    |
+LL | enum T { A(U), B }
+   | ------------------
+   | |        |
+   | |        not covered
+   | `T` defined here
+...
 LL |     match x { //~ ERROR non-exhaustive patterns: `A(C)` not covered
    |           ^ pattern `A(C)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to 2 previous errors
 
index 8d2a73b2c6dcc743a31fd094f9a4430d4f44f88e..112e18432b440dafd0b73f688cee4ac9fce2b975 100644 (file)
@@ -1,50 +1,78 @@
 error[E0004]: non-exhaustive patterns: `A` not covered
   --> $DIR/non-exhaustive-match.rs:8:11
    |
+LL | enum T { A, B }
+   | ---------------
+   | |        |
+   | |        not covered
+   | `T` defined here
+...
 LL |     match x { T::B => { } } //~ ERROR non-exhaustive patterns: `A` not covered
    |           ^ pattern `A` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `false` not covered
   --> $DIR/non-exhaustive-match.rs:9:11
    |
 LL |     match true { //~ ERROR non-exhaustive patterns: `false` not covered
    |           ^^^^ pattern `false` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `Some(_)` not covered
   --> $DIR/non-exhaustive-match.rs:12:11
    |
 LL |     match Some(10) { //~ ERROR non-exhaustive patterns: `Some(_)` not covered
    |           ^^^^^^^^ pattern `Some(_)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)` and `(_, _, 5i32..=2147483647i32)` not covered
   --> $DIR/non-exhaustive-match.rs:15:11
    |
 LL |     match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)`
    |           ^^^^^^^^^ patterns `(_, _, -2147483648i32..=3i32)` and `(_, _, 5i32..=2147483647i32)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `(A, A)` not covered
   --> $DIR/non-exhaustive-match.rs:19:11
    |
 LL |     match (T::A, T::A) { //~ ERROR non-exhaustive patterns: `(A, A)` not covered
    |           ^^^^^^^^^^^^ pattern `(A, A)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `B` not covered
   --> $DIR/non-exhaustive-match.rs:23:11
    |
+LL | enum T { A, B }
+   | ---------------
+   | |           |
+   | |           not covered
+   | `T` defined here
+...
 LL |     match T::A { //~ ERROR non-exhaustive patterns: `B` not covered
    |           ^^^^ pattern `B` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
   --> $DIR/non-exhaustive-match.rs:34:11
    |
 LL |     match *vec { //~ ERROR non-exhaustive patterns: `[]` not covered
    |           ^^^^ pattern `[]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `[_, _, _, _]` not covered
   --> $DIR/non-exhaustive-match.rs:47:11
    |
 LL |     match *vec { //~ ERROR non-exhaustive patterns: `[_, _, _, _]` not covered
    |           ^^^^ pattern `[_, _, _, _]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to 8 previous errors
 
index d3a06e7b4b6f8b844de30b773b40b7628d4443a6..a0b497dd4c0ba12da984e3e19d19eddccbbf011b 100644 (file)
@@ -1,44 +1,94 @@
 error[E0004]: non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered
   --> $DIR/non-exhaustive-pattern-witness.rs:9:11
    |
-LL |     match (Foo { first: true, second: None }) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { first: false, second: Some([_, _, _, _]) }` not covered
+LL | / struct Foo {
+LL | |     first: bool,
+LL | |     second: Option<[usize; 4]>
+LL | | }
+   | |_- `Foo` defined here
+...
+LL |       match (Foo { first: true, second: None }) {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { first: false, second: Some([_, _, _, _]) }` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `Red` not covered
   --> $DIR/non-exhaustive-pattern-witness.rs:25:11
    |
-LL |     match Color::Red {
-   |           ^^^^^^^^^^ pattern `Red` not covered
+LL | / enum Color {
+LL | |     Red,
+   | |     --- not covered
+LL | |     Green,
+LL | |     CustomRGBA { a: bool, r: u8, g: u8, b: u8 }
+LL | | }
+   | |_- `Color` defined here
+...
+LL |       match Color::Red {
+   |             ^^^^^^^^^^ pattern `Red` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `East`, `South` and `West` not covered
   --> $DIR/non-exhaustive-pattern-witness.rs:37:11
    |
-LL |     match Direction::North {
-   |           ^^^^^^^^^^^^^^^^ patterns `East`, `South` and `West` not covered
+LL | / enum Direction {
+LL | |     North, East, South, West
+   | |            ----  -----  ---- not covered
+   | |            |     |
+   | |            |     not covered
+   | |            not covered
+LL | | }
+   | |_- `Direction` defined here
+...
+LL |       match Direction::North {
+   |             ^^^^^^^^^^^^^^^^ patterns `East`, `South` and `West` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `Second`, `Third`, `Fourth` and 8 more not covered
   --> $DIR/non-exhaustive-pattern-witness.rs:48:11
    |
-LL |     match ExcessiveEnum::First {
-   |           ^^^^^^^^^^^^^^^^^^^^ patterns `Second`, `Third`, `Fourth` and 8 more not covered
+LL | / enum ExcessiveEnum {
+LL | |     First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, Tenth, Eleventh, Twelfth
+LL | | }
+   | |_- `ExcessiveEnum` defined here
+...
+LL |       match ExcessiveEnum::First {
+   |             ^^^^^^^^^^^^^^^^^^^^ patterns `Second`, `Third`, `Fourth` and 8 more not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered
   --> $DIR/non-exhaustive-pattern-witness.rs:56:11
    |
-LL |     match Color::Red {
-   |           ^^^^^^^^^^ pattern `CustomRGBA { a: true, .. }` not covered
+LL | / enum Color {
+LL | |     Red,
+LL | |     Green,
+LL | |     CustomRGBA { a: bool, r: u8, g: u8, b: u8 }
+   | |     ---------- not covered
+LL | | }
+   | |_- `Color` defined here
+...
+LL |       match Color::Red {
+   |             ^^^^^^^^^^ pattern `CustomRGBA { a: true, .. }` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `[Second(true), Second(false)]` not covered
   --> $DIR/non-exhaustive-pattern-witness.rs:72:11
    |
 LL |     match *x {
    |           ^^ pattern `[Second(true), Second(false)]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `((), false)` not covered
   --> $DIR/non-exhaustive-pattern-witness.rs:85:11
    |
 LL |     match ((), false) {
    |           ^^^^^^^^^^^ pattern `((), false)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to 7 previous errors
 
index 4acbec6c7ff1a4aaacd55e5bd04583534592a7df..a8906a43003ae64bc86458dd009700ed1d566e50 100644 (file)
@@ -3,12 +3,16 @@ error[E0004]: non-exhaustive patterns: `$ISIZE_MIN..=-6isize` and `21isize..=$IS
    |
 LL |     match 0isize { //~ ERROR non-exhaustive patterns
    |           ^^^^^^ patterns `$ISIZE_MIN..=-6isize` and `21isize..=$ISIZE_MAX` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `0usize` and `21usize..=$USIZE_MAX` not covered
   --> $DIR/precise_pointer_size_matching.rs:29:11
    |
 LL |     match 0usize { //~ ERROR non-exhaustive patterns
    |           ^^^^^^ patterns `0usize` and `21usize..=$USIZE_MAX` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to 2 previous errors
 
index 1dfad0d31896c1d021a94339a577d296b2e38d75..e24c8f155590176057fc321cc9b19e8fab653664 100644 (file)
@@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `&[]` not covered
    |
 LL |     match sl { //~ ERROR non-exhaustive patterns
    |           ^^ pattern `&[]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index acce9779067a617200a0ce96b0a5545c5a933a9f..b5c1a4ebba4ac4981360f537ac96eed4b18d75f6 100644 (file)
@@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `_` not covered
    |
 LL |     match enum_unit {
    |           ^^^^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index d651ea0b4e2d761f30c8e7c630fb26ae12200a0b..0aa85eb7253e8e0b43f0874669f2f65fbc6f270e 100644 (file)
@@ -1,8 +1,17 @@
 error[E0004]: non-exhaustive patterns: `B { x: Some(_) }` not covered
   --> $DIR/struct-like-enum-nonexhaustive.rs:8:11
    |
-LL |     match x {   //~ ERROR non-exhaustive patterns
-   |           ^ pattern `B { x: Some(_) }` not covered
+LL | / enum A {
+LL | |     B { x: Option<isize> },
+   | |     - not covered
+LL | |     C
+LL | | }
+   | |_- `A` defined here
+...
+LL |       match x {   //~ ERROR non-exhaustive patterns
+   |             ^ pattern `B { x: Some(_) }` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/format-borrow.rs b/src/test/ui/suggestions/format-borrow.rs
new file mode 100644 (file)
index 0000000..63930e7
--- /dev/null
@@ -0,0 +1,6 @@
+fn main() {
+    let a: String = &String::from("a");
+    //~^ ERROR mismatched types
+    let b: String = &format!("b");
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/suggestions/format-borrow.stderr b/src/test/ui/suggestions/format-borrow.stderr
new file mode 100644 (file)
index 0000000..44bb11f
--- /dev/null
@@ -0,0 +1,27 @@
+error[E0308]: mismatched types
+  --> $DIR/format-borrow.rs:2:21
+   |
+LL |     let a: String = &String::from("a");
+   |                     ^^^^^^^^^^^^^^^^^^
+   |                     |
+   |                     expected struct `std::string::String`, found reference
+   |                     help: consider removing the borrow: `String::from("a")`
+   |
+   = note: expected type `std::string::String`
+              found type `&std::string::String`
+
+error[E0308]: mismatched types
+  --> $DIR/format-borrow.rs:4:21
+   |
+LL |     let b: String = &format!("b");
+   |                     ^^^^^^^^^^^^^
+   |                     |
+   |                     expected struct `std::string::String`, found reference
+   |                     help: consider removing the borrow: `format!("b")`
+   |
+   = note: expected type `std::string::String`
+              found type `&std::string::String`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs
new file mode 100644 (file)
index 0000000..e72a2d8
--- /dev/null
@@ -0,0 +1,7 @@
+trait Bar {}
+impl Bar for u8 {}
+fn foo() -> impl Bar {
+    5; //~^ ERROR the trait bound `(): Bar` is not satisfied
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr
new file mode 100644 (file)
index 0000000..f26fb14
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0277]: the trait bound `(): Bar` is not satisfied
+  --> $DIR/impl-trait-return-trailing-semicolon.rs:3:13
+   |
+LL | fn foo() -> impl Bar {
+   |             ^^^^^^^^ the trait `Bar` is not implemented for `()`
+LL |     5; //~^ ERROR the trait bound `(): Bar` is not satisfied
+   |      - consider removing this semicolon
+   |
+   = note: the return type of a function must have a statically known size
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/unused-closure-argument.rs b/src/test/ui/suggestions/unused-closure-argument.rs
new file mode 100644 (file)
index 0000000..677003e
--- /dev/null
@@ -0,0 +1,20 @@
+#![deny(unused_variables)]
+
+struct Point {
+    x: i32,
+    y: i32,
+}
+
+fn main() {
+    let points = vec!(Point { x: 1, y: 2 }, Point { x: 3, y: 4 });
+
+    let _: i32 = points.iter()
+        .map(|Point { x, y }| y)
+        //~^ ERROR unused variable
+        .sum();
+
+    let _: i32 = points.iter()
+        .map(|x| 4)
+        //~^ ERROR unused variable
+        .sum();
+}
diff --git a/src/test/ui/suggestions/unused-closure-argument.stderr b/src/test/ui/suggestions/unused-closure-argument.stderr
new file mode 100644 (file)
index 0000000..5cfdd79
--- /dev/null
@@ -0,0 +1,20 @@
+error: unused variable: `x`
+  --> $DIR/unused-closure-argument.rs:12:23
+   |
+LL |         .map(|Point { x, y }| y)
+   |                       ^ help: try ignoring the field: `x: _`
+   |
+note: lint level defined here
+  --> $DIR/unused-closure-argument.rs:1:9
+   |
+LL | #![deny(unused_variables)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: unused variable: `x`
+  --> $DIR/unused-closure-argument.rs:17:15
+   |
+LL |         .map(|x| 4)
+   |               ^ help: consider prefixing with an underscore: `_x`
+
+error: aborting due to 2 previous errors
+
index 8d627fc2a8d725f1ca67b4a15b2e129f5a3aed4e..58d0862be6d2195471c5c48e769069b7f3d9d142 100644 (file)
@@ -1,8 +1,13 @@
 error[E0004]: non-exhaustive patterns: `Foo(_, _)` not covered
   --> $DIR/tuple-struct-nonexhaustive.rs:5:11
    |
+LL | struct Foo(isize, isize);
+   | ------------------------- `Foo` defined here
+...
 LL |     match x {   //~ ERROR non-exhaustive
    |           ^ pattern `Foo(_, _)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error: aborting due to previous error
 
index 63819bf949bd368cdf0eed39bb650c2e1356ed97..2424252af2ad3209714fc1644601ed60642e5681 100644 (file)
@@ -1,8 +1,16 @@
 error[E0005]: refutable pattern in local binding: `A(_)` not covered
   --> $DIR/uninhabited-irrefutable.rs:27:9
    |
-LL |     let Foo::D(_y) = x; //~ ERROR refutable pattern in local binding: `A(_)` not covered
-   |         ^^^^^^^^^^ pattern `A(_)` not covered
+LL | / enum Foo {
+LL | |     A(foo::SecretlyEmpty),
+LL | |     B(foo::NotSoSecretlyEmpty),
+LL | |     C(NotSoSecretlyEmpty),
+LL | |     D(u32),
+LL | | }
+   | |_- `Foo` defined here
+...
+LL |       let Foo::D(_y) = x; //~ ERROR refutable pattern in local binding: `A(_)` not covered
+   |           ^^^^^^^^^^ pattern `A(_)` not covered
 
 error: aborting due to previous error
 
index b88dcc9aea435050cdaa7c1aa54175f81ad29749..fec95ca149431c5ecb34b002fd55ae4a969b0524 100644 (file)
@@ -3,6 +3,8 @@ error[E0004]: non-exhaustive patterns: `Err(_)` not covered
    |
 LL |     let _ = match x {   //~ ERROR non-exhaustive
    |                   ^ pattern `Err(_)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: type `&Void` is non-empty
   --> $DIR/uninhabited-matches-feature-gated.rs:10:19
@@ -10,11 +12,7 @@ error[E0004]: non-exhaustive patterns: type `&Void` is non-empty
 LL |     let _ = match x {}; //~ ERROR non-exhaustive
    |                   ^
    |
-help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-  --> $DIR/uninhabited-matches-feature-gated.rs:10:19
-   |
-LL |     let _ = match x {}; //~ ERROR non-exhaustive
-   |                   ^
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty
   --> $DIR/uninhabited-matches-feature-gated.rs:13:19
@@ -22,11 +20,7 @@ error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty
 LL |     let _ = match x {}; //~ ERROR non-exhaustive
    |                   ^
    |
-help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-  --> $DIR/uninhabited-matches-feature-gated.rs:13:19
-   |
-LL |     let _ = match x {}; //~ ERROR non-exhaustive
-   |                   ^
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty
   --> $DIR/uninhabited-matches-feature-gated.rs:16:19
@@ -34,23 +28,23 @@ error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty
 LL |     let _ = match x {}; //~ ERROR non-exhaustive
    |                   ^
    |
-help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-  --> $DIR/uninhabited-matches-feature-gated.rs:16:19
-   |
-LL |     let _ = match x {}; //~ ERROR non-exhaustive
-   |                   ^
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `&[_]` not covered
   --> $DIR/uninhabited-matches-feature-gated.rs:19:19
    |
 LL |     let _ = match x {   //~ ERROR non-exhaustive
    |                   ^ pattern `&[_]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `Err(_)` not covered
   --> $DIR/uninhabited-matches-feature-gated.rs:27:19
    |
 LL |     let _ = match x {   //~ ERROR non-exhaustive
    |                   ^ pattern `Err(_)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0005]: refutable pattern in local binding: `Err(_)` not covered
   --> $DIR/uninhabited-matches-feature-gated.rs:32:9
index 7bc2e1d60d23a2f6a31d7a04d40171372d80b5b3..caccf8bd4c3d490d6a4cf329a3411bbf68753642 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 7bc2e1d60d23a2f6a31d7a04d40171372d80b5b3
+Subproject commit caccf8bd4c3d490d6a4cf329a3411bbf68753642
index 724be298a1e12593dbc3786cafc307627e46e802..e3527fdba7178120a6398e76aa4b3908b10ef85e 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 724be298a1e12593dbc3786cafc307627e46e802
+Subproject commit e3527fdba7178120a6398e76aa4b3908b10ef85e
index cb9dac27ce49157c4cf252d8df5b86c2f8fa026e..f42de44176787b0baca7946af970c9ed53b2688a 100644 (file)
@@ -1,3 +1,5 @@
+#![deny(rust_2018_idioms)]
+
 /// This is a small client program intended to pair with `remote-test-server` in
 /// this repository. This client connects to the server over TCP and is used to
 /// push artifacts and run tests on the server instead of locally.
@@ -15,7 +17,7 @@
 use std::thread;
 use std::time::Duration;
 
-const REMOTE_ADDR_ENV: &'static str = "TEST_DEVICE_ADDR";
+const REMOTE_ADDR_ENV: &str = "TEST_DEVICE_ADDR";
 
 macro_rules! t {
     ($e:expr) => (match $e {
index 750eea3a28aef1a35ec3e39b7f7ea420e05598e0..e1270489d315fbc9ec8ac0415d17720649892122 100644 (file)
@@ -1,3 +1,5 @@
+#![deny(rust_2018_idioms)]
+
 /// This is a small server which is intended to run inside of an emulator or
 /// on a remote test device. This server pairs with the `remote-test-client`
 /// program in this repository. The `remote-test-client` connects to this
@@ -120,7 +122,7 @@ struct RemoveOnDrop<'a> {
     inner: &'a Path,
 }
 
-impl<'a> Drop for RemoveOnDrop<'a> {
+impl Drop for RemoveOnDrop<'_> {
     fn drop(&mut self) {
         t!(fs::remove_dir_all(self.inner));
     }
index 5a6246347cc030d6d28ff047b3596dcdb5ce8f82..cfc1bc6d414e40a1892946cb59537b880b2e8015 100644 (file)
@@ -1,4 +1,5 @@
-//
+#![deny(rust_2018_idioms)]
+
 use clap::{crate_version};
 
 use std::env;
@@ -68,7 +69,7 @@ fn main() {
 }
 
 // Build command implementation
-pub fn build_1(args: &ArgMatches) -> Result1<()> {
+pub fn build_1(args: &ArgMatches<'_>) -> Result1<()> {
     let book_dir = get_book_dir(args);
     let mut book = MDBook1::load(&book_dir)?;
 
@@ -85,7 +86,7 @@ pub fn build_1(args: &ArgMatches) -> Result1<()> {
 }
 
 // Build command implementation
-pub fn build_2(args: &ArgMatches) -> Result2<()> {
+pub fn build_2(args: &ArgMatches<'_>) -> Result2<()> {
     let book_dir = get_book_dir(args);
     let mut book = MDBook2::load(&book_dir)?;
 
@@ -101,7 +102,7 @@ pub fn build_2(args: &ArgMatches) -> Result2<()> {
     Ok(())
 }
 
-fn get_book_dir(args: &ArgMatches) -> PathBuf {
+fn get_book_dir(args: &ArgMatches<'_>) -> PathBuf {
     if let Some(dir) = args.value_of("dir") {
         // Check if path is relative from current dir, or absolute...
         let p = Path::new(dir);
index 94dd5478e5297474ee7c30006387ebb4128f1b7b..d7683aae841cdd923b157b8f1e4dfaa43eb890db 100644 (file)
 ];
 
 /// Which crates to check against the whitelist?
-const WHITELIST_CRATES: &[CrateVersion] = &[
+const WHITELIST_CRATES: &[CrateVersion<'_>] = &[
     CrateVersion("rustc", "0.0.0"),
     CrateVersion("rustc_codegen_llvm", "0.0.0"),
 ];
 
 /// Whitelist of crates rustc is allowed to depend on. Avoid adding to the list if possible.
-const WHITELIST: &[Crate] = &[
+const WHITELIST: &[Crate<'_>] = &[
     Crate("adler32"),
     Crate("aho-corasick"),
     Crate("arrayvec"),
     Crate("smallvec"),
     Crate("stable_deref_trait"),
     Crate("syn"),
+    Crate("synstructure"),
     Crate("tempfile"),
     Crate("termcolor"),
     Crate("terminon"),
@@ -183,7 +184,7 @@ struct ResolveNode {
 #[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Debug, Hash)]
 struct CrateVersion<'a>(&'a str, &'a str); // (name, version)
 
-impl<'a> Crate<'a> {
+impl Crate<'_> {
     pub fn id_str(&self) -> String {
         format!("{} ", self.0)
     }
@@ -330,10 +331,10 @@ fn get_deps(path: &Path, cargo: &Path) -> Resolve {
 
 /// Checks the dependencies of the given crate from the given cargo metadata to see if they are on
 /// the whitelist. Returns a list of illegal dependencies.
-fn check_crate_whitelist<'a, 'b>(
-    whitelist: &'a HashSet<Crate>,
+fn check_crate_whitelist<'a>(
+    whitelist: &'a HashSet<Crate<'_>>,
     resolve: &'a Resolve,
-    visited: &'b mut BTreeSet<CrateVersion<'a>>,
+    visited: &mut BTreeSet<CrateVersion<'a>>,
     krate: CrateVersion<'a>,
     must_be_on_whitelist: bool,
 ) -> BTreeSet<Crate<'a>> {
@@ -378,7 +379,7 @@ fn check_crate_duplicate(resolve: &Resolve, bad: &mut bool) {
         // to accidentally sneak into our dependency graph, in order to ensure we keep our CI times
         // under control.
 
-        // "cargo", // FIXME(#53005)
+        "cargo",
         "rustc-ap-syntax",
     ];
     let mut name_to_id: HashMap<_, Vec<_>> = HashMap::new();
index 7126c0c2f6ecf1639e8c9d4e04be3addbdfe1f5f..1eab217027c8a7a99963d707dbcd365e8154b7f4 100644 (file)
@@ -22,7 +22,7 @@ pub enum Status {
 }
 
 impl fmt::Display for Status {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let as_str = match *self {
             Status::Stable => "stable",
             Status::Unstable => "unstable",
index 022c53f909c759d0066c99f312fa97079e00003b..c4a1246ffdf555f6915db7668551a8659c5cffab 100644 (file)
@@ -3,7 +3,8 @@
 //! This library contains the tidy lints and exposes it
 //! to be used by tools.
 
-extern crate serde;
+#![deny(rust_2018_idioms)]
+
 extern crate serde_json;
 #[macro_use]
 extern crate serde_derive;