]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #57418 - lqd:collector_query, r=michaelwoerister
authorMazdak Farrokhzad <twingoow@gmail.com>
Mon, 14 Jan 2019 10:31:50 +0000 (11:31 +0100)
committerGitHub <noreply@github.com>
Mon, 14 Jan 2019 10:31:50 +0000 (11:31 +0100)
MetadataOnlyCodegenBackend: run the collector only once

Use the `collect_and_partition_mono_items` query to avoid calling the collector directly twice.

Fixes #57406.

517 files changed:
.gitignore
CODE_OF_CONDUCT.md
Cargo.lock
Cargo.toml
README.md
RELEASES.md
config.toml.example
src/bootstrap/builder.rs
src/bootstrap/compile.rs
src/bootstrap/config.rs
src/bootstrap/configure.py
src/bootstrap/dist.rs
src/bootstrap/install.rs
src/bootstrap/lib.rs
src/bootstrap/native.rs
src/bootstrap/tool.rs
src/ci/docker/dist-various-1/Dockerfile
src/doc/unstable-book/src/language-features/cfg-attr-multi.md [deleted file]
src/doc/unstable-book/src/language-features/const-fn.md
src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md [deleted file]
src/etc/htmldocck.py
src/etc/lldb_batchmode.py
src/liballoc/vec.rs
src/libcore/cmp.rs
src/libcore/fmt/mod.rs
src/libcore/future/future.rs
src/libcore/intrinsics.rs
src/libcore/iter/iterator.rs
src/libcore/iter/mod.rs
src/libcore/lib.rs
src/libcore/num/bignum.rs
src/libcore/num/f32.rs
src/libcore/num/f64.rs
src/libcore/num/mod.rs
src/libcore/option.rs
src/libcore/pin.rs
src/libcore/ptr.rs
src/libcore/result.rs
src/libcore/str/mod.rs
src/libcore/str/pattern.rs
src/libcore/time.rs
src/librustc/dep_graph/dep_node.rs
src/librustc/dep_graph/graph.rs
src/librustc/dep_graph/mod.rs
src/librustc/hir/check_attr.rs
src/librustc/hir/def.rs
src/librustc/hir/def_id.rs
src/librustc/hir/intravisit.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/blocks.rs
src/librustc/hir/map/collector.rs
src/librustc/hir/map/hir_id_validator.rs
src/librustc/hir/map/mod.rs
src/librustc/hir/mod.rs
src/librustc/infer/error_reporting/mod.rs
src/librustc/infer/lexical_region_resolve/mod.rs
src/librustc/lib.rs
src/librustc/lint/builtin.rs
src/librustc/middle/stability.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/structural_impls.rs
src/librustc/ty/context.rs
src/librustc/ty/layout.rs
src/librustc/ty/mod.rs
src/librustc/ty/query/config.rs
src/librustc/ty/query/job.rs
src/librustc/ty/query/mod.rs
src/librustc/ty/query/on_disk_cache.rs
src/librustc/ty/query/plumbing.rs
src/librustc/util/profiling.rs
src/librustc_borrowck/borrowck/check_loans.rs
src/librustc_codegen_llvm/debuginfo/metadata.rs
src/librustc_codegen_llvm/type_.rs
src/librustc_codegen_llvm/value.rs
src/librustc_codegen_ssa/back/linker.rs
src/librustc_data_structures/lib.rs
src/librustc_data_structures/sync.rs
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_errors/lib.rs
src/librustc_incremental/persist/save.rs
src/librustc_lint/builtin.rs
src/librustc_lint/nonstandard_style.rs
src/librustc_llvm/build.rs
src/librustc_mir/borrow_check/error_reporting.rs
src/librustc_mir/build/expr/as_rvalue.rs
src/librustc_mir/build/matches/mod.rs
src/librustc_mir/build/matches/test.rs
src/librustc_mir/build/mod.rs
src/librustc_mir/const_eval.rs
src/librustc_mir/diagnostics.rs
src/librustc_mir/hair/cx/expr.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/hair/pattern/mod.rs
src/librustc_mir/lib.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/qualify_min_const_fn.rs
src/librustc_mir/util/borrowck_errors.rs
src/librustc_passes/ast_validation.rs
src/librustc_passes/lib.rs
src/librustc_passes/loops.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/librustc_resolve/resolve_imports.rs
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/lib.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/demand.rs
src/librustc_typeck/check/intrinsic.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/upvar.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/coherence/orphan.rs
src/librustc_typeck/collect.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/COPYRIGHT.txt
src/librustdoc/html/static/Heuristica-Italic.woff [deleted file]
src/librustdoc/html/static/Heuristica-LICENSE.txt [deleted file]
src/librustdoc/html/static/SourceSerifPro-Bold.ttf.woff [new file with mode: 0644]
src/librustdoc/html/static/SourceSerifPro-Bold.woff [deleted file]
src/librustdoc/html/static/SourceSerifPro-It.ttf.woff [new file with mode: 0644]
src/librustdoc/html/static/SourceSerifPro-Regular.ttf.woff [new file with mode: 0644]
src/librustdoc/html/static/SourceSerifPro-Regular.woff [deleted file]
src/librustdoc/html/static/main.js
src/librustdoc/html/static/rustdoc.css
src/librustdoc/html/static_files.rs
src/librustdoc/test.rs
src/libstd/error.rs
src/libstd/io/mod.rs
src/libstd/lib.rs
src/libstd/macros.rs
src/libstd/net/ip.rs
src/libstd/path.rs
src/libstd/primitive_docs.rs
src/libstd/sys/cloudabi/time.rs
src/libstd/sys/redox/time.rs
src/libstd/sys/sgx/abi/mem.rs
src/libstd/sys/sgx/backtrace.rs
src/libstd/sys/sgx/ext/arch.rs
src/libstd/sys/unix/time.rs
src/libstd/sys/wasm/time.rs
src/libstd/sys/windows/process.rs
src/libstd/sys/windows/time.rs
src/libstd/time.rs
src/libsyntax/attr/mod.rs
src/libsyntax/config.rs
src/libsyntax/diagnostics/plugin.rs
src/libsyntax/ext/quote.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/ext/tt/transcribe.rs
src/libsyntax/feature_gate.rs
src/libsyntax/parse/lexer/tokentrees.rs
src/libsyntax/parse/parser.rs
src/libsyntax/tokenstream.rs
src/libsyntax_ext/format.rs
src/libsyntax_ext/proc_macro_server.rs
src/libsyntax_ext/test.rs
src/stdsimd
src/test/compile-fail/const-fn-error.rs
src/test/run-pass/binding/allow_irrefutable_let_patterns.rs [deleted file]
src/test/run-pass/binding/match-static-const-rename.rs [deleted file]
src/test/run-pass/const-int-conversion.rs
src/test/run-pass/const-int-overflowing.rs
src/test/run-pass/const-int-rotate.rs
src/test/run-pass/const-int-sign.rs
src/test/run-pass/const-int-wrapping.rs
src/test/run-pass/consts/const-endianess.rs
src/test/run-pass/ctfe/bswap-const.rs
src/test/run-pass/ctfe/const-block-non-item-statement-3.rs
src/test/run-pass/ctfe/const-block-non-item-statement.rs
src/test/run-pass/ctfe/issue-37550.rs
src/test/run-pass/ctfe/locals-in-const-fn.rs
src/test/run-pass/enum-variant-generic-args.rs [deleted file]
src/test/run-pass/intrinsics/intrinsics-integer.rs
src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs [deleted file]
src/test/run-pass/lint-non-camel-case-with-trailing-underscores.rs [deleted file]
src/test/run-pass/result-opt-conversions.rs
src/test/run-pass/rfcs/rfc-2175-or-if-while-let/basic.rs
src/test/run-pass/snake-case-no-lowercase-equivalent.rs [deleted file]
src/test/run-pass/test-allow-non-camel-case-variant.rs [deleted file]
src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs
src/test/run-pass/uniform-paths/basic-nested.rs
src/test/run-pass/uniform-paths/basic.rs
src/test/run-pass/uniform-paths/macros-nested.rs
src/test/run-pass/uniform-paths/macros.rs
src/test/run-pass/uniform-paths/same-crate.rs
src/test/rustdoc-ui/deny-missing-docs-crate.rs [new file with mode: 0644]
src/test/rustdoc-ui/deny-missing-docs-crate.stderr [new file with mode: 0644]
src/test/rustdoc-ui/deny-missing-docs-macro.rs [new file with mode: 0644]
src/test/rustdoc-ui/deny-missing-docs-macro.stderr [new file with mode: 0644]
src/test/rustdoc/assoc-consts-version.rs
src/test/rustdoc/auxiliary/pub-extern-crate.rs [new file with mode: 0644]
src/test/rustdoc/const.rs
src/test/rustdoc/issue-25001.rs
src/test/rustdoc/issue-32374.rs
src/test/rustdoc/issue-51236.rs
src/test/rustdoc/issue-54705.rs
src/test/rustdoc/issue-55321.rs
src/test/rustdoc/issue-56822.rs
src/test/rustdoc/pub-extern-crate.rs [new file with mode: 0644]
src/test/rustdoc/synthetic_auto/complex.rs
src/test/rustdoc/synthetic_auto/lifetimes.rs
src/test/rustdoc/synthetic_auto/manual.rs
src/test/rustdoc/synthetic_auto/negative.rs
src/test/rustdoc/synthetic_auto/nested.rs
src/test/rustdoc/synthetic_auto/no-redundancy.rs
src/test/rustdoc/synthetic_auto/project.rs
src/test/rustdoc/synthetic_auto/self-referential.rs
src/test/rustdoc/synthetic_auto/static-region.rs
src/test/ui/assoc-inherent.rs
src/test/ui/assoc-inherent.stderr
src/test/ui/associated-const/associated-const-upper-case-lint.rs [deleted file]
src/test/ui/associated-const/associated-const-upper-case-lint.stderr [deleted file]
src/test/ui/bad/bad-intrinsic-monomorphization.rs
src/test/ui/block-result/issue-13624.stderr
src/test/ui/borrowck/borrowck-borrow-from-owned-ptr.stderr
src/test/ui/borrowck/borrowck-box-insensitivity.ast.stderr
src/test/ui/borrowck/borrowck-box-insensitivity.rs
src/test/ui/borrowck/borrowck-union-borrow.ast.nll.stderr [deleted file]
src/test/ui/borrowck/borrowck-union-borrow.ast.stderr [deleted file]
src/test/ui/borrowck/borrowck-union-borrow.nll.stderr [new file with mode: 0644]
src/test/ui/borrowck/borrowck-union-borrow.rs
src/test/ui/borrowck/borrowck-union-borrow.stderr [new file with mode: 0644]
src/test/ui/check-static-values-constraints.nll.stderr
src/test/ui/check-static-values-constraints.rs
src/test/ui/check-static-values-constraints.stderr
src/test/ui/coherence/coherence-cow.re_a.stderr
src/test/ui/coherence/coherence-cow.re_b.stderr
src/test/ui/coherence/coherence-cow.re_c.stderr
src/test/ui/coherence/coherence-fundamental-trait-objects.old.stderr
src/test/ui/coherence/coherence-fundamental-trait-objects.re.stderr
src/test/ui/coherence/coherence-impls-copy.old.stderr
src/test/ui/coherence/coherence-impls-copy.re.stderr
src/test/ui/coherence/coherence-impls-send.old.stderr
src/test/ui/coherence/coherence-impls-send.re.stderr
src/test/ui/coherence/coherence-impls-sized.old.stderr
src/test/ui/coherence/coherence-impls-sized.re.stderr
src/test/ui/coherence/coherence-orphan.old.stderr
src/test/ui/coherence/coherence-orphan.re.stderr
src/test/ui/coherence/coherence-overlapping-pairs.re.stderr
src/test/ui/coherence/coherence-pair-covered-uncovered-1.re.stderr
src/test/ui/coherence/coherence-pair-covered-uncovered.re.stderr
src/test/ui/coherence/coherence-vec-local-2.re.stderr
src/test/ui/coherence/coherence-vec-local.old.stderr
src/test/ui/coherence/coherence-vec-local.re.stderr
src/test/ui/coherence/coherence_local_err_struct.old.stderr
src/test/ui/coherence/coherence_local_err_struct.re.stderr
src/test/ui/coherence/coherence_local_err_tuple.old.stderr
src/test/ui/coherence/coherence_local_err_tuple.re.stderr
src/test/ui/conditional-compilation/cfg-attr-multi-false.rs
src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs
src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr
src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs
src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr
src/test/ui/conditional-compilation/cfg-attr-multi-true.rs
src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr
src/test/ui/conditional-compilation/cfg-attr-parse.rs
src/test/ui/conditional-compilation/cfg-attr-parse.stderr
src/test/ui/consts/const-block-non-item-statement-2.rs [deleted file]
src/test/ui/consts/const-block-non-item-statement-2.stderr [deleted file]
src/test/ui/consts/const-block-non-item-statement-3.rs [deleted file]
src/test/ui/consts/const-block-non-item-statement-3.stderr [deleted file]
src/test/ui/consts/const-block-non-item-statement.rs
src/test/ui/consts/const-block-non-item-statement.stderr [deleted file]
src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs
src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr
src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs
src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr
src/test/ui/consts/const-eval/const_let.rs
src/test/ui/consts/const-eval/const_let.stderr
src/test/ui/consts/const-eval/infinite_loop.rs
src/test/ui/consts/const-eval/infinite_loop.stderr
src/test/ui/consts/const-eval/issue-52475.rs
src/test/ui/consts/const-eval/issue-52475.stderr
src/test/ui/consts/const-eval/mod-static-with-const-fn.rs
src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr
src/test/ui/consts/const-eval/ub-upvars.rs
src/test/ui/consts/const-fn-destructuring-arg.rs
src/test/ui/consts/const-fn-destructuring-arg.stderr [deleted file]
src/test/ui/consts/const-fn-not-safe-for-const.rs
src/test/ui/consts/const-fn-not-safe-for-const.stderr
src/test/ui/consts/const-int-unchecked.rs
src/test/ui/consts/const-int-unchecked.stderr
src/test/ui/consts/const_let_assign.rs
src/test/ui/consts/const_let_assign2.rs
src/test/ui/consts/const_let_assign3.rs
src/test/ui/consts/const_let_assign3.stderr
src/test/ui/consts/const_let_eq.rs
src/test/ui/consts/const_let_eq_float.rs
src/test/ui/consts/const_let_irrefutable.rs [new file with mode: 0644]
src/test/ui/consts/const_let_refutable.rs [new file with mode: 0644]
src/test/ui/consts/const_let_refutable.stderr [new file with mode: 0644]
src/test/ui/consts/const_short_circuit.rs
src/test/ui/consts/dangling-alloc-id-ice.rs
src/test/ui/consts/dangling-alloc-id-ice.stderr
src/test/ui/consts/dangling_raw_ptr.rs
src/test/ui/consts/dangling_raw_ptr.stderr
src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr
src/test/ui/consts/min_const_fn/min_const_fn.rs
src/test/ui/consts/min_const_fn/min_const_fn.stderr
src/test/ui/consts/min_const_fn/mutable_borrow.rs
src/test/ui/consts/min_const_fn/mutable_borrow.stderr
src/test/ui/consts/partial_qualif.rs
src/test/ui/consts/partial_qualif.stderr
src/test/ui/consts/projection_qualif.rs
src/test/ui/consts/projection_qualif.stderr
src/test/ui/consts/promote_const_let.nll.stderr
src/test/ui/consts/promote_const_let.rs
src/test/ui/consts/promote_const_let.stderr
src/test/ui/consts/qualif_overwrite.rs
src/test/ui/consts/qualif_overwrite.stderr
src/test/ui/consts/qualif_overwrite_2.rs
src/test/ui/consts/qualif_overwrite_2.stderr
src/test/ui/consts/static_mut_containing_mut_ref2.rs
src/test/ui/consts/static_mut_containing_mut_ref2.stderr
src/test/ui/consts/static_mut_containing_mut_ref3.rs
src/test/ui/consts/static_mut_containing_mut_ref3.stderr
src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr
src/test/ui/cycle-trait/cycle-trait-supertrait-direct.stderr
src/test/ui/dropck/drop-on-non-struct.stderr
src/test/ui/editions/edition-imports-2015.rs
src/test/ui/editions/edition-imports-2015.stderr
src/test/ui/editions/edition-imports-virtual-2015-gated.stderr
src/test/ui/enable-unstable-lib-feature.stderr
src/test/ui/error-codes/E0010-teach.rs
src/test/ui/error-codes/E0010-teach.stderr
src/test/ui/error-codes/E0010.rs
src/test/ui/error-codes/E0010.stderr
src/test/ui/error-codes/E0117.stderr
src/test/ui/error-codes/E0162.rs [deleted file]
src/test/ui/error-codes/E0162.stderr [deleted file]
src/test/ui/error-codes/E0165.rs [deleted file]
src/test/ui/error-codes/E0165.stderr [deleted file]
src/test/ui/error-codes/E0206.stderr
src/test/ui/error-codes/E0308-4.stderr
src/test/ui/error-codes/E0606.stderr
src/test/ui/error-festival.stderr
src/test/ui/existential_types/no_inferrable_concrete_type.stderr
src/test/ui/expr_attr_paren_order.stderr
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.rs [deleted file]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.stderr [deleted file]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.rs [deleted file]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.stderr [deleted file]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-1.rs [deleted file]
src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-2.rs [deleted file]
src/test/ui/feature-gates/feature-gate-const_fn.stderr
src/test/ui/feature-gates/feature-gate-const_let.rs [deleted file]
src/test/ui/feature-gates/feature-gate-const_let.stderr [deleted file]
src/test/ui/feature-gates/feature-gate-if_while_or_patterns.rs [deleted file]
src/test/ui/feature-gates/feature-gate-if_while_or_patterns.stderr [deleted file]
src/test/ui/feature-gates/feature-gate-min_const_fn.stderr
src/test/ui/feature-gates/feature-gate-underscore_const_names.rs
src/test/ui/feature-gates/feature-gate-underscore_const_names.stderr
src/test/ui/feature-gates/feature-gate-uniform-paths.rs [deleted file]
src/test/ui/feature-gates/feature-gate-uniform-paths.stderr [deleted file]
src/test/ui/feature-gates/feature-gate-without_gate_irrefutable_pattern.rs [deleted file]
src/test/ui/feature-gates/feature-gate-without_gate_irrefutable_pattern.stderr [deleted file]
src/test/ui/if-else-type-mismatch.rs [new file with mode: 0644]
src/test/ui/if-else-type-mismatch.stderr [new file with mode: 0644]
src/test/ui/if/if-branch-types.stderr
src/test/ui/if/if-let.rs
src/test/ui/if/if-let.stderr
src/test/ui/impl-trait/auto-trait-leak.stderr
src/test/ui/imports/extern-crate-used.rs [new file with mode: 0644]
src/test/ui/imports/extern-crate-used.stderr [new file with mode: 0644]
src/test/ui/imports/issue-56125.rs
src/test/ui/imports/issue-56125.stderr
src/test/ui/infinite/infinite-vec-type-recursion.stderr
src/test/ui/issues/issue-11844.stderr
src/test/ui/issues/issue-12511.stderr
src/test/ui/issues/issue-12552.stderr
src/test/ui/issues/issue-13466.stderr
src/test/ui/issues/issue-15896.stderr
src/test/ui/issues/issue-16401.stderr
src/test/ui/issues/issue-17263.ast.stderr
src/test/ui/issues/issue-17718-const-naming.rs
src/test/ui/issues/issue-17718-const-naming.stderr
src/test/ui/issues/issue-18118.nll.stderr
src/test/ui/issues/issue-18118.rs
src/test/ui/issues/issue-18118.stderr
src/test/ui/issues/issue-20772.stderr
src/test/ui/issues/issue-20825.stderr
src/test/ui/issues/issue-22673.stderr
src/test/ui/issues/issue-32829-2.rs
src/test/ui/issues/issue-32829-2.stderr
src/test/ui/issues/issue-34373.stderr
src/test/ui/issues/issue-3680.stderr
src/test/ui/issues/issue-37550.rs
src/test/ui/issues/issue-37550.stderr
src/test/ui/issues/issue-45157.rs
src/test/ui/issues/issue-45157.stderr
src/test/ui/issues/issue-5100.stderr
src/test/ui/issues/issue-51714.rs
src/test/ui/issues/issue-51714.stderr
src/test/ui/issues/issue-5358-1.stderr
src/test/ui/issues/issue-57156.rs [new file with mode: 0644]
src/test/ui/issues/issue-57472.rs [new file with mode: 0644]
src/test/ui/issues/issue-57472.stderr [new file with mode: 0644]
src/test/ui/issues/issue-7092.stderr
src/test/ui/issues/issue-7364.rs
src/test/ui/issues/issue-7364.stderr
src/test/ui/lint/command-line-lint-group-deny.stderr
src/test/ui/lint/command-line-lint-group-forbid.stderr
src/test/ui/lint/command-line-lint-group-warn.stderr
src/test/ui/lint/lint-group-nonstandard-style.stderr
src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs [new file with mode: 0644]
src/test/ui/lint/lint-lowercase-static-const-pattern.rs [new file with mode: 0644]
src/test/ui/lint/lint-lowercase-static-const-pattern.stderr [new file with mode: 0644]
src/test/ui/lint/lint-non-camel-case-types.rs
src/test/ui/lint/lint-non-camel-case-types.stderr
src/test/ui/lint/lint-non-camel-case-variant.rs [new file with mode: 0644]
src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs [new file with mode: 0644]
src/test/ui/lint/lint-non-snake-case-crate-2.rs
src/test/ui/lint/lint-non-snake-case-crate-2.stderr
src/test/ui/lint/lint-non-snake-case-crate.rs
src/test/ui/lint/lint-non-snake-case-crate.stderr
src/test/ui/lint/lint-non-snake-case-functions.rs
src/test/ui/lint/lint-non-snake-case-functions.stderr
src/test/ui/lint/lint-non-snake-case-lifetimes.rs
src/test/ui/lint/lint-non-snake-case-lifetimes.stderr
src/test/ui/lint/lint-non-snake-case-modules.rs
src/test/ui/lint/lint-non-snake-case-modules.stderr
src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs [new file with mode: 0644]
src/test/ui/lint/lint-non-uppercase-associated-const.rs [new file with mode: 0644]
src/test/ui/lint/lint-non-uppercase-associated-const.stderr [new file with mode: 0644]
src/test/ui/lint/lint-non-uppercase-statics.rs
src/test/ui/lint/lint-non-uppercase-statics.stderr
src/test/ui/lint/lint-nonstandard-style-unicode.rs [new file with mode: 0644]
src/test/ui/lint/lint-uppercase-variables.rs
src/test/ui/lint/lint-uppercase-variables.stderr
src/test/ui/lint/reasons.stderr
src/test/ui/macros/format-parse-errors.rs
src/test/ui/macros/format-parse-errors.stderr
src/test/ui/match/match-static-const-lc.rs [deleted file]
src/test/ui/match/match-static-const-lc.stderr [deleted file]
src/test/ui/match/match-struct.stderr
src/test/ui/match/match-tag-unary.stderr
src/test/ui/mismatched_types/cast-rfc0401.stderr
src/test/ui/nll/issue-57100.rs [new file with mode: 0644]
src/test/ui/nll/issue-57100.stderr [new file with mode: 0644]
src/test/ui/pattern/deny-irrefutable-let-patterns.rs [new file with mode: 0644]
src/test/ui/pattern/deny-irrefutable-let-patterns.stderr [new file with mode: 0644]
src/test/ui/pattern/enum-variant-generic-args.rs [new file with mode: 0644]
src/test/ui/pattern/irrefutable-let-patterns.rs [new file with mode: 0644]
src/test/ui/pattern/pattern-error-continue.stderr
src/test/ui/pattern/pattern-tyvar.stderr
src/test/ui/proc-macro/derive-helper-shadowing.rs
src/test/ui/proc-macro/derive-helper-shadowing.stderr
src/test/ui/regions/region-invariant-static-error-reporting.stderr
src/test/ui/regions/regions-fn-subtyping-return-static.rs
src/test/ui/regions/regions-fn-subtyping-return-static.stderr [deleted file]
src/test/ui/resolve/issue-23305.stderr
src/test/ui/resolve/issue-57523.rs [new file with mode: 0644]
src/test/ui/resolve/resolve-self-in-impl.stderr
src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs
src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr
src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.rs
src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.stderr
src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.rs
src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.stderr
src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs
src/test/ui/rust-2018/future-proofing-locals.rs
src/test/ui/rust-2018/future-proofing-locals.stderr
src/test/ui/rust-2018/local-path-suggestions-2018.rs
src/test/ui/rust-2018/local-path-suggestions-2018.stderr
src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs
src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr
src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs
src/test/ui/rust-2018/uniform-paths/issue-54390.rs [deleted file]
src/test/ui/rust-2018/uniform-paths/issue-54390.stderr [deleted file]
src/test/ui/rust-2018/uniform-paths/macro-rules.rs
src/test/ui/rust-2018/uniform-paths/macro-rules.stderr
src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs [new file with mode: 0644]
src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr [new file with mode: 0644]
src/test/ui/rust-2018/uniform-paths/prelude-fail.rs
src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr
src/test/ui/rust-2018/uniform-paths/prelude.rs
src/test/ui/should-fail-no_gate_irrefutable_if_let_pattern.rs [deleted file]
src/test/ui/should-fail-no_gate_irrefutable_if_let_pattern.stderr [deleted file]
src/test/ui/should-fail-with_gate_irrefutable_pattern_deny.rs [deleted file]
src/test/ui/should-fail-with_gate_irrefutable_pattern_deny.stderr [deleted file]
src/test/ui/simd-intrinsic/simd-intrinsic-declaration-type.stderr
src/test/ui/span/issue-24690.stderr
src/test/ui/static/static-mut-not-constant.rs
src/test/ui/static/static-mut-not-constant.stderr
src/test/ui/str/str-array-assignment.stderr
src/test/ui/structs/structure-constructor-type-mismatch.stderr
src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr
src/test/ui/underscore_const_names.rs
src/test/ui/union/union-borrow-move-parent-sibling.nll.stderr
src/test/ui/union/union-borrow-move-parent-sibling.stderr
src/test/ui/unsafe/ranged_ints2_const.rs
src/test/ui/unsafe/ranged_ints2_const.stderr
src/test/ui/unsafe/ranged_ints3_const.rs
src/test/ui/unsafe/ranged_ints4_const.rs
src/test/ui/utf8_idents.rs
src/test/ui/utf8_idents.stderr
src/test/ui/where-clauses/where-equality-constraints.stderr
src/test/ui/while-let.rs
src/test/ui/while-let.stderr
src/test/ui/write-to-static-mut-in-static.rs
src/test/ui/write-to-static-mut-in-static.stderr
src/tools/build-manifest/src/main.rs
src/tools/clippy
src/tools/miri
src/tools/rls
src/tools/rustc-workspace-hack/Cargo.toml
src/tools/tidy/src/features.rs

index e18acfd98e241b14cf69e554406705d83f7e569d..67e0dd8e795bb596d66fa4eda1899b06543270c7 100644 (file)
@@ -13,6 +13,7 @@ __pycache__/
 .settings/
 .valgrindrc
 .vscode/
+.favorites.json
 /*-*-*-*/
 /*-*-*/
 /Makefile
index d70b2b52aca1b136d70617a03d04b5c7bccd9969..ece8dedb0aed7aa74e271336d83aa2cbd35a49e9 100644 (file)
@@ -35,6 +35,6 @@ And if someone takes issue with something you said or did, resist the urge to be
 
 The enforcement policies listed above apply to all official Rust venues; including official IRC channels (#rust, #rust-internals, #rust-tools, #rust-libs, #rustc, #rust-beginners, #rust-docs, #rust-community, #rust-lang, and #cargo); GitHub repositories under rust-lang, rust-lang-nursery, and rust-lang-deprecated; and all forums under rust-lang.org (users.rust-lang.org, internals.rust-lang.org). For other projects adopting the Rust Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion.
 
-*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).*
+*Adapted from the [Node.js Policy on Trolling](https://blog.izs.me/2012/08/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).*
 
 [mod_team]: https://www.rust-lang.org/team.html#Moderation-team
index ef28723b49317f696950f4c7fa504d01914c5db8..d3c6054f4da373b12c1d54c4e590fbfacf2aacb6 100644 (file)
@@ -97,7 +97,7 @@ name = "backtrace-sys"
 version = "0.1.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
@@ -131,7 +131,7 @@ name = "bootstrap"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -264,7 +264,7 @@ version = "0.1.0"
 
 [[package]]
 name = "cc"
-version = "1.0.25"
+version = "1.0.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -322,12 +322,12 @@ dependencies = [
  "clippy-mini-macro-test 0.2.0",
  "clippy_dev 0.0.1",
  "clippy_lints 0.0.212",
- "compiletest_rs 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiletest_rs 0.3.18 (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)",
  "rustc-workspace-hack 1.0.0",
- "rustc_tools_util 0.1.0",
+ "rustc_tools_util 0.1.1",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -382,7 +382,7 @@ name = "cmake"
 version = "0.1.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -414,7 +414,7 @@ name = "compiler_builtins"
 version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
 ]
 
@@ -441,7 +441,7 @@ dependencies = [
 
 [[package]]
 name = "compiletest_rs"
-version = "0.3.17"
+version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -451,6 +451,7 @@ dependencies = [
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustfix 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
  "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)",
@@ -607,7 +608,7 @@ name = "curl-sys"
 version = "0.4.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
  "libnghttp2-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1076,7 +1077,7 @@ name = "jemalloc-sys"
 version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1160,7 +1161,7 @@ name = "libgit2-sys"
 version = "0.7.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
  "libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1174,7 +1175,7 @@ name = "libnghttp2-sys"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1183,7 +1184,7 @@ name = "libssh2-sys"
 version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1196,7 +1197,7 @@ name = "libz-sys"
 version = "1.0.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1236,7 +1237,7 @@ name = "lzma-sys"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1342,7 +1343,7 @@ name = "miniz-sys"
 version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1359,7 +1360,7 @@ name = "miniz_oxide_c_api"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
  "miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1381,7 +1382,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.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiletest_rs 0.3.18 (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)",
@@ -1473,7 +1474,7 @@ name = "openssl-src"
 version = "111.1.0+1.1.1a"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1481,7 +1482,7 @@ name = "openssl-sys"
 version = "0.9.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-src 111.1.0+1.1.1a (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1680,7 +1681,7 @@ version = "0.0.0"
 name = "profiler_builtins"
 version = "0.0.0"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
@@ -1812,7 +1813,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)",
 ]
 
@@ -1834,7 +1835,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]]
@@ -1859,7 +1860,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]]
@@ -1983,7 +1984,7 @@ dependencies = [
  "rls-vfs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-workspace-hack 1.0.0",
- "rustc_tools_util 0.1.0",
+ "rustc_tools_util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustfmt-nightly 1.0.1",
  "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2259,8 +2260,10 @@ dependencies = [
 name = "rustc-workspace-hack"
 version = "1.0.0"
 dependencies = [
+ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2320,7 +2323,7 @@ dependencies = [
 name = "rustc_codegen_llvm"
 version = "0.0.0"
 dependencies = [
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-demangle 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2332,7 +2335,7 @@ name = "rustc_codegen_ssa"
 version = "0.0.0"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2482,7 +2485,7 @@ name = "rustc_llvm"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2632,7 +2635,12 @@ dependencies = [
 
 [[package]]
 name = "rustc_tools_util"
-version = "0.1.0"
+version = "0.1.1"
+
+[[package]]
+name = "rustc_tools_util"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "rustc_traits"
@@ -2892,7 +2900,7 @@ version = "0.0.0"
 dependencies = [
  "alloc 0.0.0",
  "backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
  "dlmalloc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3403,7 +3411,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d"
 "checksum bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "716960a18f978640f25101b5cbf1c6f6b0d3192fab36a2d98ca96f0ecbe41010"
 "checksum cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d8dfe3adeb30f7938e6c1dd5327f29235d8ada3e898aeb08c343005ec2915a2"
-"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
+"checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749"
 "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
 "checksum chalk-engine 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17ec698a6f053a23bfbe646d9f2fde4b02abc19125595270a99e6f44ae0bdd1a"
 "checksum chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "295635afd6853aa9f20baeb7f0204862440c0fe994c5a253d5f479dac41d047e"
@@ -3415,7 +3423,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.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bd14d75a16b6c836c62350e2e8c85495ed8e13df30a7298c574cb1ee4cdac7bc"
-"checksum compiletest_rs 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "89747fe073b7838343bd2c2445e7a7c2e0d415598f8925f0fa9205b9cdfc48cb"
+"checksum compiletest_rs 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0d76d4322a40f6b0db7259d4f2c8a65ed8b0d84fce0bbc61b98cf47f8ec6eec3"
 "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"
 "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
@@ -3593,6 +3601,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c6d5a683c6ba4ed37959097e88d71c9e8e26659a3cb5be8b389078e7ad45306"
 "checksum rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40f06724db71e18d68b3b946fdf890ca8c921d9edccc1404fdfdb537b0d12649"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
+"checksum rustc_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"
 "checksum rustfix 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "af7c21531a91512a4a51b490be6ba1c8eff34fdda0dc5bf87dc28d86748aac56"
 "checksum rusty-fork 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9591f190d2852720b679c21f66ad929f9f1d7bb09d1193c26167586029d8489c"
index c693985a2ad83e666440526863eafdbc4d0feb3a..cb3c0ee194fe2e4f0a3cab2b46be70b7bf9ec1ef 100644 (file)
@@ -70,4 +70,3 @@ rustc-std-workspace-core = { path = 'src/tools/rustc-std-workspace-core' }
 
 [patch."https://github.com/rust-lang/rust-clippy"]
 clippy_lints = { path = "src/tools/clippy/clippy_lints" }
-rustc_tools_util = { path = "src/tools/clippy/rustc_tools_util" }
index 7eb5e8067eda2d1e30d9e6ff10e8648042bf8201..cb1f06257ed152ad958aff5aaba60b0d58f140bf 100644 (file)
--- a/README.md
+++ b/README.md
@@ -38,7 +38,6 @@ Read ["Installation"] from [The Book].
 3. Build and install:
 
     ```sh
-    $ git submodule update --init --recursive --progress
     $ ./x.py build && sudo ./x.py install
     ```
 
index 7022a86a45c5b611fa3c9f1671fca5d8084c7ee5..83c44774da283ce94eb1c0d8d289941bebf3c0a0 100644 (file)
@@ -1,3 +1,301 @@
+Version 1.32.0 (2019-01-17)
+==========================
+
+Language
+--------
+#### 2018 edition
+- [You can now use the `?` operator in macro definitions.][56245] The `?`
+  operator allows you to specify zero or one repetitions similar to the `*` and
+  `+` operators.
+- [Module paths with no leading keyword like `super`, `self`, or `crate`, will
+  now always resolve to the item (`enum`, `struct`, etc.) available in the
+  module if present, before resolving to a external crate or an item the prelude.][56759]
+  E.g.
+  ```rust
+  enum Color { Red, Green, Blue }
+
+  use Color::*;
+  ```
+
+#### All editions
+- [You can now match against `PhantomData<T>` types.][55837]
+- [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. 
+  ```rust
+  struct Point(i32, i32);
+
+  impl Point {
+      pub fn new(x: i32, y: i32) -> Self {
+          Self(x, y)
+      }
+
+      pub fn is_origin(&self) -> bool {
+          match self {
+              Self(0, 0) => true,
+              _ => false,
+          }
+      }
+  }
+  ```
+- [Self can also now be used in type definitions.][56366] E.g.
+  ```rust
+  enum List<T>
+  where
+      Self: PartialOrd<Self> // can write `Self` instead of `List<T>`
+  {
+      Nil,
+      Cons(T, Box<Self>) // likewise here
+  }
+  ```
+- [You can now mark traits with `#[must_use]`.][55663] This provides a warning if
+  a `impl Trait` or `dyn Trait` is returned and unused in the program.
+
+Compiler
+--------
+- [The default allocator has changed from jemalloc to the default allocator on
+  your system.][55238] The compiler itself on Linux & macOS will still use
+  jemalloc, but programs compiled with it will use the system allocator.
+- [Added the `aarch64-pc-windows-msvc` target.][55702]
+
+Libraries
+---------
+- [`PathBuf` now implements `FromStr`.][55148]
+- [`Box<[T]>` now implements `FromIterator<T>`.][55843]
+- [The `dbg!` macro has been stabilized.][56395] This macro enables you to
+  easily debug expressions in your rust program. E.g.
+  ```rust
+  let a = 2;
+  let b = dbg!(a * 2) + 1;
+  //      ^-- prints: [src/main.rs:4] a * 2 = 4
+  assert_eq!(b, 5);
+  ```
+
+The following APIs are now `const` functions and can be used in a
+`const` context.
+
+- [`Cell::as_ptr`]
+- [`UnsafeCell::get`]
+- [`char::is_ascii`]
+- [`iter::empty`]
+- [`ManuallyDrop::new`]
+- [`ManuallyDrop::into_inner`]
+- [`RangeInclusive::start`]
+- [`RangeInclusive::end`]
+- [`NonNull::as_ptr`]
+- [`slice::as_ptr`]
+- [`str::as_ptr`]
+- [`Duration::as_secs`]
+- [`Duration::subsec_millis`]
+- [`Duration::subsec_micros`]
+- [`Duration::subsec_nanos`]
+- [`CStr::as_ptr`]
+- [`Ipv4Addr::is_unspecified`]
+- [`Ipv6Addr::new`]
+- [`Ipv6Addr::octets`]
+
+Stabilized APIs
+---------------
+- [`i8::to_be_bytes`]
+- [`i8::to_le_bytes`]
+- [`i8::to_ne_bytes`]
+- [`i8::from_be_bytes`]
+- [`i8::from_le_bytes`]
+- [`i8::from_ne_bytes`]
+- [`i16::to_be_bytes`]
+- [`i16::to_le_bytes`]
+- [`i16::to_ne_bytes`]
+- [`i16::from_be_bytes`]
+- [`i16::from_le_bytes`]
+- [`i16::from_ne_bytes`]
+- [`i32::to_be_bytes`]
+- [`i32::to_le_bytes`]
+- [`i32::to_ne_bytes`]
+- [`i32::from_be_bytes`]
+- [`i32::from_le_bytes`]
+- [`i32::from_ne_bytes`]
+- [`i64::to_be_bytes`]
+- [`i64::to_le_bytes`]
+- [`i64::to_ne_bytes`]
+- [`i64::from_be_bytes`]
+- [`i64::from_le_bytes`]
+- [`i64::from_ne_bytes`]
+- [`i128::to_be_bytes`]
+- [`i128::to_le_bytes`]
+- [`i128::to_ne_bytes`]
+- [`i128::from_be_bytes`]
+- [`i128::from_le_bytes`]
+- [`i128::from_ne_bytes`]
+- [`isize::to_be_bytes`]
+- [`isize::to_le_bytes`]
+- [`isize::to_ne_bytes`]
+- [`isize::from_be_bytes`]
+- [`isize::from_le_bytes`]
+- [`isize::from_ne_bytes`]
+- [`u8::to_be_bytes`]
+- [`u8::to_le_bytes`]
+- [`u8::to_ne_bytes`]
+- [`u8::from_be_bytes`]
+- [`u8::from_le_bytes`]
+- [`u8::from_ne_bytes`]
+- [`u16::to_be_bytes`]
+- [`u16::to_le_bytes`]
+- [`u16::to_ne_bytes`]
+- [`u16::from_be_bytes`]
+- [`u16::from_le_bytes`]
+- [`u16::from_ne_bytes`]
+- [`u32::to_be_bytes`]
+- [`u32::to_le_bytes`]
+- [`u32::to_ne_bytes`]
+- [`u32::from_be_bytes`]
+- [`u32::from_le_bytes`]
+- [`u32::from_ne_bytes`]
+- [`u64::to_be_bytes`]
+- [`u64::to_le_bytes`]
+- [`u64::to_ne_bytes`]
+- [`u64::from_be_bytes`]
+- [`u64::from_le_bytes`]
+- [`u64::from_ne_bytes`]
+- [`u128::to_be_bytes`]
+- [`u128::to_le_bytes`]
+- [`u128::to_ne_bytes`]
+- [`u128::from_be_bytes`]
+- [`u128::from_le_bytes`]
+- [`u128::from_ne_bytes`]
+- [`usize::to_be_bytes`]
+- [`usize::to_le_bytes`]
+- [`usize::to_ne_bytes`]
+- [`usize::from_be_bytes`]
+- [`usize::from_le_bytes`]
+- [`usize::from_ne_bytes`]
+
+Cargo
+-----
+- [You can now run `cargo c` as an alias for `cargo check`.][cargo/6218]
+- [Usernames are now allowed in alt registry URLs.][cargo/6242]
+
+Misc
+----
+- [`libproc_macro` has been added to the `rust-src` distribution.][55280]
+
+Compatibility Notes
+-------------------
+- [The argument types for AVX's
+  `_mm256_stream_si256`, `_mm256_stream_pd`, `_mm256_stream_ps`][55610] have
+  been changed from `*const` to `*mut` as the previous implementation
+  was unsound.
+
+
+[55148]: https://github.com/rust-lang/rust/pull/55148/
+[55238]: https://github.com/rust-lang/rust/pull/55238/
+[55280]: https://github.com/rust-lang/rust/pull/55280/
+[55610]: https://github.com/rust-lang/rust/pull/55610/
+[55663]: https://github.com/rust-lang/rust/pull/55663/
+[55702]: https://github.com/rust-lang/rust/pull/55702/
+[55837]: https://github.com/rust-lang/rust/pull/55837/
+[55843]: https://github.com/rust-lang/rust/pull/55843/
+[56072]: https://github.com/rust-lang/rust/pull/56072/
+[56245]: https://github.com/rust-lang/rust/pull/56245/
+[56365]: https://github.com/rust-lang/rust/pull/56365/
+[56366]: https://github.com/rust-lang/rust/pull/56366/
+[56395]: https://github.com/rust-lang/rust/pull/56395/
+[56759]: https://github.com/rust-lang/rust/pull/56759/
+[cargo/6218]: https://github.com/rust-lang/cargo/pull/6218/
+[cargo/6242]: https://github.com/rust-lang/cargo/pull/6242/
+[`CStr::as_ptr`]: https://doc.rust-lang.org/std/ffi/struct.CStr.html#method.as_ptr
+[`Cell::as_ptr`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.as_ptr
+[`Duration::as_secs`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs
+[`Duration::subsec_micros`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.subsec_micros
+[`Duration::subsec_millis`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.subsec_millis
+[`Duration::subsec_nanos`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.subsec_nanos
+[`Ipv4Addr::is_unspecified`]: https://doc.rust-lang.org/std/net/struct.Ipv4Addr.html#method.is_unspecified
+[`Ipv6Addr::new`]: https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html#method.new
+[`Ipv6Addr::octets`]: https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html#method.octets
+[`ManuallyDrop::into_inner`]: https://doc.rust-lang.org/std/mem/struct.ManuallyDrop.html#method.into_inner
+[`ManuallyDrop::new`]: https://doc.rust-lang.org/std/mem/struct.ManuallyDrop.html#method.new
+[`NonNull::as_ptr`]: https://doc.rust-lang.org/std/ptr/struct.NonNull.html#method.as_ptr
+[`RangeInclusive::end`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html#method.end
+[`RangeInclusive::start`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html#method.start
+[`UnsafeCell::get`]: https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html#method.get
+[`slice::as_ptr`]: https://doc.rust-lang.org/std/primitive.slice.html#method.as_ptr
+[`char::is_ascii`]: https://doc.rust-lang.org/std/primitive.char.html#method.is_ascii
+[`i128::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.from_be_bytes
+[`i128::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.from_le_bytes
+[`i128::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.from_ne_bytes
+[`i128::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.to_be_bytes
+[`i128::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.to_le_bytes
+[`i128::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.to_ne_bytes
+[`i16::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.from_be_bytes
+[`i16::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.from_le_bytes
+[`i16::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.from_ne_bytes
+[`i16::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.to_be_bytes
+[`i16::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.to_le_bytes
+[`i16::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.to_ne_bytes
+[`i32::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.from_be_bytes
+[`i32::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.from_le_bytes
+[`i32::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.from_ne_bytes
+[`i32::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.to_be_bytes
+[`i32::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.to_le_bytes
+[`i32::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.to_ne_bytes
+[`i64::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.from_be_bytes
+[`i64::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.from_le_bytes
+[`i64::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.from_ne_bytes
+[`i64::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.to_be_bytes
+[`i64::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.to_le_bytes
+[`i64::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.to_ne_bytes
+[`i8::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.from_be_bytes
+[`i8::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.from_le_bytes
+[`i8::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.from_ne_bytes
+[`i8::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.to_be_bytes
+[`i8::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.to_le_bytes
+[`i8::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.to_ne_bytes
+[`isize::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.from_be_bytes
+[`isize::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.from_le_bytes
+[`isize::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.from_ne_bytes
+[`isize::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.to_be_bytes
+[`isize::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.to_le_bytes
+[`isize::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.to_ne_bytes
+[`iter::empty`]: https://doc.rust-lang.org/std/iter/fn.empty.html
+[`str::as_ptr`]: https://doc.rust-lang.org/std/primitive.str.html#method.as_ptr
+[`u128::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.from_be_bytes
+[`u128::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.from_le_bytes
+[`u128::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.from_ne_bytes
+[`u128::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.to_be_bytes
+[`u128::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.to_le_bytes
+[`u128::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.to_ne_bytes
+[`u16::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.from_be_bytes
+[`u16::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.from_le_bytes
+[`u16::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.from_ne_bytes
+[`u16::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.to_be_bytes
+[`u16::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.to_le_bytes
+[`u16::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.to_ne_bytes
+[`u32::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.from_be_bytes
+[`u32::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.from_le_bytes
+[`u32::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.from_ne_bytes
+[`u32::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.to_be_bytes
+[`u32::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.to_le_bytes
+[`u32::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.to_ne_bytes
+[`u64::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.from_be_bytes
+[`u64::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.from_le_bytes
+[`u64::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.from_ne_bytes
+[`u64::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.to_be_bytes
+[`u64::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.to_le_bytes
+[`u64::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.to_ne_bytes
+[`u8::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.from_be_bytes
+[`u8::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.from_le_bytes
+[`u8::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.from_ne_bytes
+[`u8::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_be_bytes
+[`u8::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_le_bytes
+[`u8::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_ne_bytes
+[`usize::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.from_be_bytes
+[`usize::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.from_le_bytes
+[`usize::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.from_ne_bytes
+[`usize::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.to_be_bytes
+[`usize::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.to_le_bytes
+[`usize::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.to_ne_bytes
+
+
 Version 1.31.1 (2018-12-20)
 ===========================
 
index f5a348593699fdbe3e912d3def210cdd5a668f9f..23943d34b7ca8fc596737ddfbfae45da9d0987a8 100644 (file)
 # with clang-cl, so this is special in that it only compiles LLVM with clang-cl
 #clang-cl = '/path/to/clang-cl.exe'
 
+# Use libc++ when building LLVM instead of libstdc++. This is the default on
+# platforms already use libc++ as the default C++ library, but this option
+# allows you to use libc++ even on platforms when it's not. You need to ensure
+# that your host compiler ships with libc++.
+#use-libcxx = true
+
 # =============================================================================
 # General build configuration options
 # =============================================================================
 #codegen-units-std = 1
 
 # Whether or not debug assertions are enabled for the compiler and standard
-# library. Also enables compilation of debug! and trace! logging macros.
+# library.
 #debug-assertions = false
 
 # Whether or not debuginfo is emitted
index 117ff0e721474b012bd686059fe323d7906d5cb2..9c58f5b179fd8b2afdadd48d4e4c31137b8157e1 100644 (file)
@@ -449,6 +449,7 @@ macro_rules! describe {
                 dist::Rls,
                 dist::Rustfmt,
                 dist::Clippy,
+                dist::Miri,
                 dist::LlvmTools,
                 dist::Lldb,
                 dist::Extended,
@@ -461,6 +462,7 @@ macro_rules! describe {
                 install::Rls,
                 install::Rustfmt,
                 install::Clippy,
+                install::Miri,
                 install::Analysis,
                 install::Src,
                 install::Rustc
index 0d2546a0e9ca9f6b30c6f8bc1111ad4773dc3ab9..8bc7c5838edda381d21fe5b4a40b9c7da2d9ebe6 100644 (file)
@@ -723,6 +723,9 @@ pub fn build_codegen_backend(builder: &Builder,
             {
                 cargo.env("LLVM_LINK_SHARED", "1");
             }
+            if builder.config.llvm_use_libcxx {
+                cargo.env("LLVM_USE_LIBCXX", "1");
+            }
         }
         _ => panic!("unknown backend: {}", backend),
     }
index 8655cf0eb305339b65541ac2aac91e091ce435bc..9421817ae6d8e644583263bb49bda30bb240fa15 100644 (file)
@@ -82,6 +82,8 @@ pub struct Config {
     pub lldb_enabled: bool,
     pub llvm_tools_enabled: bool,
 
+    pub llvm_use_libcxx: bool,
+
     // rust codegen options
     pub rust_optimize: bool,
     pub rust_codegen_units: Option<u32>,
@@ -252,6 +254,7 @@ struct Llvm {
     link_shared: Option<bool>,
     version_suffix: Option<String>,
     clang_cl: Option<String>,
+    use_libcxx: Option<bool>,
 }
 
 #[derive(Deserialize, Default, Clone)]
@@ -513,6 +516,7 @@ pub fn parse(args: &[String]) -> Config {
             config.llvm_link_jobs = llvm.link_jobs;
             config.llvm_version_suffix = llvm.version_suffix.clone();
             config.llvm_clang_cl = llvm.clang_cl.clone();
+            set(&mut config.llvm_use_libcxx, llvm.use_libcxx);
         }
 
         if let Some(ref rust) = toml.rust {
index d13a3dc783436440865f278a47b7b127d13f7cf2..b0c3c9702498dcbb20dee72d2fc23d6900c73197 100755 (executable)
@@ -62,6 +62,7 @@ o("full-tools", None, "enable all tools")
 o("lld", "rust.lld", "build lld")
 o("lldb", "rust.lldb", "build lldb")
 o("missing-tools", "dist.missing-tools", "allow failures when building tools")
+o("use-libcxx", "llvm.use_libcxx", "build LLVM with libc++")
 
 # Optimization and debugging options. These may be overridden by the release
 # channel, etc.
index 38869bf441a827607a63e768363bbda1f8ce7431..df34dfe4544ae4e550b5c8981a2006e1c0688944 100644 (file)
@@ -32,6 +32,8 @@ pub fn pkgname(builder: &Builder, component: &str) -> String {
         format!("{}-{}", component, builder.rls_package_vers())
     } else if component == "clippy" {
         format!("{}-{}", component, builder.clippy_package_vers())
+    } else if component == "miri" {
+        format!("{}-{}", component, builder.miri_package_vers())
     } else if component == "rustfmt" {
         format!("{}-{}", component, builder.rustfmt_package_vers())
     } else if component == "llvm-tools" {
@@ -1275,6 +1277,90 @@ fn run(self, builder: &Builder) -> Option<PathBuf> {
     }
 }
 
+#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct Miri {
+    pub stage: u32,
+    pub target: Interned<String>,
+}
+
+impl Step for Miri {
+    type Output = Option<PathBuf>;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun) -> ShouldRun {
+        run.path("miri")
+    }
+
+    fn make_run(run: RunConfig) {
+        run.builder.ensure(Miri {
+            stage: run.builder.top_stage,
+            target: run.target,
+        });
+    }
+
+    fn run(self, builder: &Builder) -> Option<PathBuf> {
+        let stage = self.stage;
+        let target = self.target;
+        assert!(builder.config.extended);
+
+        builder.info(&format!("Dist miri stage{} ({})", stage, target));
+        let src = builder.src.join("src/tools/miri");
+        let release_num = builder.release_num("miri");
+        let name = pkgname(builder, "miri");
+        let version = builder.miri_info.version(builder, &release_num);
+
+        let tmp = tmpdir(builder);
+        let image = tmp.join("miri-image");
+        drop(fs::remove_dir_all(&image));
+        builder.create_dir(&image);
+
+        // Prepare the image directory
+        // We expect miri to build, because we've exited this step above if tool
+        // state for miri isn't testing.
+        let miri = builder.ensure(tool::Miri {
+            compiler: builder.compiler(stage, builder.config.build),
+            target, extra_features: Vec::new()
+        }).or_else(|| { missing_tool("miri", builder.build.config.missing_tools); None })?;
+        let cargomiri = builder.ensure(tool::CargoMiri {
+            compiler: builder.compiler(stage, builder.config.build),
+            target, extra_features: Vec::new()
+        }).or_else(|| { missing_tool("cargo miri", builder.build.config.missing_tools); None })?;
+
+        builder.install(&miri, &image.join("bin"), 0o755);
+        builder.install(&cargomiri, &image.join("bin"), 0o755);
+        let doc = image.join("share/doc/miri");
+        builder.install(&src.join("README.md"), &doc, 0o644);
+        builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
+        builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
+
+        // Prepare the overlay
+        let overlay = tmp.join("miri-overlay");
+        drop(fs::remove_dir_all(&overlay));
+        t!(fs::create_dir_all(&overlay));
+        builder.install(&src.join("README.md"), &overlay, 0o644);
+        builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
+        builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
+        builder.create(&overlay.join("version"), &version);
+
+        // Generate the installer tarball
+        let mut cmd = rust_installer(builder);
+        cmd.arg("generate")
+           .arg("--product-name=Rust")
+           .arg("--rel-manifest-dir=rustlib")
+           .arg("--success-message=miri-ready-to-serve.")
+           .arg("--image-dir").arg(&image)
+           .arg("--work-dir").arg(&tmpdir(builder))
+           .arg("--output-dir").arg(&distdir(builder))
+           .arg("--non-installed-overlay").arg(&overlay)
+           .arg(format!("--package-name={}-{}", name, target))
+           .arg("--legacy-manifest-dirs=rustlib,cargo")
+           .arg("--component-name=miri-preview");
+
+        builder.run(&mut cmd);
+        Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
+    }
+}
+
 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct Rustfmt {
     pub stage: u32,
@@ -1396,6 +1482,7 @@ fn run(self, builder: &Builder) {
         let rls_installer = builder.ensure(Rls { stage, target });
         let llvm_tools_installer = builder.ensure(LlvmTools { stage, target });
         let clippy_installer = builder.ensure(Clippy { stage, target });
+        let miri_installer = builder.ensure(Miri { stage, target });
         let lldb_installer = builder.ensure(Lldb { target });
         let mingw_installer = builder.ensure(Mingw { host: target });
         let analysis_installer = builder.ensure(Analysis {
@@ -1434,6 +1521,7 @@ fn run(self, builder: &Builder) {
         tarballs.push(cargo_installer);
         tarballs.extend(rls_installer.clone());
         tarballs.extend(clippy_installer.clone());
+        tarballs.extend(miri_installer.clone());
         tarballs.extend(rustfmt_installer.clone());
         tarballs.extend(llvm_tools_installer);
         tarballs.extend(lldb_installer);
@@ -1506,6 +1594,9 @@ fn filter(contents: &str, marker: &str) -> String {
             if clippy_installer.is_none() {
                 contents = filter(&contents, "clippy");
             }
+            if miri_installer.is_none() {
+                contents = filter(&contents, "miri");
+            }
             if rustfmt_installer.is_none() {
                 contents = filter(&contents, "rustfmt");
             }
@@ -1546,6 +1637,9 @@ fn filter(contents: &str, marker: &str) -> String {
             if clippy_installer.is_some() {
                 prepare("clippy");
             }
+            if miri_installer.is_some() {
+                prepare("miri");
+            }
 
             // create an 'uninstall' package
             builder.install(&etc.join("pkg/postinstall"), &pkg.join("uninstall"), 0o755);
@@ -1576,6 +1670,8 @@ fn filter(contents: &str, marker: &str) -> String {
                     "rls-preview".to_string()
                 } else if name == "clippy" {
                     "clippy-preview".to_string()
+                } else if name == "miri" {
+                    "miri-preview".to_string()
                 } else {
                     name.to_string()
                 };
@@ -1595,6 +1691,9 @@ fn filter(contents: &str, marker: &str) -> String {
             if clippy_installer.is_some() {
                 prepare("clippy");
             }
+            if miri_installer.is_some() {
+                prepare("miri");
+            }
             if target.contains("windows-gnu") {
                 prepare("rust-mingw");
             }
@@ -1687,6 +1786,18 @@ fn filter(contents: &str, marker: &str) -> String {
                                 .arg("-out").arg(exe.join("ClippyGroup.wxs"))
                                 .arg("-t").arg(etc.join("msi/remove-duplicates.xsl")));
             }
+            if miri_installer.is_some() {
+                builder.run(Command::new(&heat)
+                                .current_dir(&exe)
+                                .arg("dir")
+                                .arg("miri")
+                                .args(&heat_flags)
+                                .arg("-cg").arg("MiriGroup")
+                                .arg("-dr").arg("Miri")
+                                .arg("-var").arg("var.MiriDir")
+                                .arg("-out").arg(exe.join("MiriGroup.wxs"))
+                                .arg("-t").arg(etc.join("msi/remove-duplicates.xsl")));
+            }
             builder.run(Command::new(&heat)
                             .current_dir(&exe)
                             .arg("dir")
@@ -1732,6 +1843,9 @@ fn filter(contents: &str, marker: &str) -> String {
                 if clippy_installer.is_some() {
                     cmd.arg("-dClippyDir=clippy");
                 }
+                if miri_installer.is_some() {
+                    cmd.arg("-dMiriDir=miri");
+                }
                 if target.contains("windows-gnu") {
                     cmd.arg("-dGccDir=rust-mingw");
                 }
@@ -1750,6 +1864,9 @@ fn filter(contents: &str, marker: &str) -> String {
             if clippy_installer.is_some() {
                 candle("ClippyGroup.wxs".as_ref());
             }
+            if miri_installer.is_some() {
+                candle("MiriGroup.wxs".as_ref());
+            }
             candle("AnalysisGroup.wxs".as_ref());
 
             if target.contains("windows-gnu") {
@@ -1782,6 +1899,9 @@ fn filter(contents: &str, marker: &str) -> String {
             if clippy_installer.is_some() {
                 cmd.arg("ClippyGroup.wixobj");
             }
+            if miri_installer.is_some() {
+                cmd.arg("MiriGroup.wixobj");
+            }
 
             if target.contains("windows-gnu") {
                 cmd.arg("GccGroup.wixobj");
@@ -1864,13 +1984,14 @@ fn run(self, builder: &Builder) {
         cmd.arg(distdir(builder));
         cmd.arg(today.trim());
         cmd.arg(builder.rust_package_vers());
+        cmd.arg(addr);
         cmd.arg(builder.package_vers(&builder.release_num("cargo")));
         cmd.arg(builder.package_vers(&builder.release_num("rls")));
         cmd.arg(builder.package_vers(&builder.release_num("clippy")));
+        cmd.arg(builder.package_vers(&builder.release_num("miri")));
         cmd.arg(builder.package_vers(&builder.release_num("rustfmt")));
         cmd.arg(builder.llvm_tools_package_vers());
         cmd.arg(builder.lldb_package_vers());
-        cmd.arg(addr);
 
         builder.create_dir(&distdir(builder));
 
index 669aae68c635b06a73eb4822f653bd928fb92031..1265fa9eff45bca8485b491edd564def56a28883 100644 (file)
@@ -32,6 +32,9 @@ pub fn install_rls(builder: &Builder, stage: u32, host: Interned<String>) {
 pub fn install_clippy(builder: &Builder, stage: u32, host: Interned<String>) {
     install_sh(builder, "clippy", "clippy", stage, Some(host));
 }
+pub fn install_miri(builder: &Builder, stage: u32, host: Interned<String>) {
+    install_sh(builder, "miri", "miri", stage, Some(host));
+}
 
 pub fn install_rustfmt(builder: &Builder, stage: u32, host: Interned<String>) {
     install_sh(builder, "rustfmt", "rustfmt", stage, Some(host));
@@ -217,6 +220,14 @@ fn run($sel, $builder: &Builder) {
             builder.info(&format!("skipping Install clippy stage{} ({})", self.stage, self.target));
         }
     };
+    Miri, "miri", Self::should_build(_config), only_hosts: true, {
+        if builder.ensure(dist::Miri { stage: self.stage, target: self.target }).is_some() ||
+            Self::should_install(builder) {
+            install_miri(builder, self.stage, self.target);
+        } else {
+            builder.info(&format!("skipping Install miri stage{} ({})", self.stage, self.target));
+        }
+    };
     Rustfmt, "rustfmt", Self::should_build(_config), only_hosts: true, {
         if builder.ensure(dist::Rustfmt { stage: self.stage, target: self.target }).is_some() ||
             Self::should_install(builder) {
index e460ef5a44e929a1242a1beafa459944739589c7..bddc6362389adcbecd4a1bf41b5f50b7d68862e2 100644 (file)
@@ -253,6 +253,7 @@ pub struct Build {
     cargo_info: channel::GitInfo,
     rls_info: channel::GitInfo,
     clippy_info: channel::GitInfo,
+    miri_info: channel::GitInfo,
     rustfmt_info: channel::GitInfo,
     local_rebuild: bool,
     fail_fast: bool,
@@ -374,6 +375,7 @@ pub fn new(config: Config) -> Build {
         let cargo_info = channel::GitInfo::new(&config, &src.join("src/tools/cargo"));
         let rls_info = channel::GitInfo::new(&config, &src.join("src/tools/rls"));
         let clippy_info = channel::GitInfo::new(&config, &src.join("src/tools/clippy"));
+        let miri_info = channel::GitInfo::new(&config, &src.join("src/tools/miri"));
         let rustfmt_info = channel::GitInfo::new(&config, &src.join("src/tools/rustfmt"));
 
         let mut build = Build {
@@ -396,6 +398,7 @@ pub fn new(config: Config) -> Build {
             cargo_info,
             rls_info,
             clippy_info,
+            miri_info,
             rustfmt_info,
             cc: HashMap::new(),
             cxx: HashMap::new(),
@@ -1016,6 +1019,11 @@ fn clippy_package_vers(&self) -> String {
         self.package_vers(&self.release_num("clippy"))
     }
 
+    /// Returns the value of `package_vers` above for miri
+    fn miri_package_vers(&self) -> String {
+        self.package_vers(&self.release_num("miri"))
+    }
+
     /// Returns the value of `package_vers` above for rustfmt
     fn rustfmt_package_vers(&self) -> String {
         self.package_vers(&self.release_num("rustfmt"))
index c548d7f6948dc17ab6bf53195cd643a83feced5f..cb9c86df55080d560f93814e2e777a8acec3770c 100644 (file)
@@ -235,7 +235,7 @@ fn run(self, builder: &Builder) -> PathBuf {
             cfg.define("PYTHON_EXECUTABLE", python);
         }
 
-        configure_cmake(builder, target, &mut cfg, false);
+        configure_cmake(builder, target, &mut cfg);
 
         // FIXME: we don't actually need to build all LLVM tools and all LLVM
         //        libraries here, e.g., we just want a few components and a few
@@ -277,8 +277,7 @@ fn check_llvm_version(builder: &Builder, llvm_config: &Path) {
 
 fn configure_cmake(builder: &Builder,
                    target: Interned<String>,
-                   cfg: &mut cmake::Config,
-                   building_dist_binaries: bool) {
+                   cfg: &mut cmake::Config) {
     if builder.config.ninja {
         cfg.generator("Ninja");
     }
@@ -347,15 +346,13 @@ fn configure_cmake(builder: &Builder,
        if builder.config.llvm_clang_cl.is_some() && target.contains("i686") {
            cfg.env("SCCACHE_EXTRA_ARGS", "-m32");
        }
-
-    // If ccache is configured we inform the build a little differently how
-    // to invoke ccache while also invoking our compilers.
-    } else if let Some(ref ccache) = builder.config.ccache {
-       cfg.define("CMAKE_C_COMPILER", ccache)
-          .define("CMAKE_C_COMPILER_ARG1", sanitize_cc(cc))
-          .define("CMAKE_CXX_COMPILER", ccache)
-          .define("CMAKE_CXX_COMPILER_ARG1", sanitize_cc(cxx));
     } else {
+       // If ccache is configured we inform the build a little differently how
+       // to invoke ccache while also invoking our compilers.
+       if let Some(ref ccache) = builder.config.ccache {
+         cfg.define("CMAKE_C_COMPILER_LAUNCHER", ccache)
+            .define("CMAKE_CXX_COMPILER_LAUNCHER", ccache);
+       }
        cfg.define("CMAKE_C_COMPILER", sanitize_cc(cc))
           .define("CMAKE_CXX_COMPILER", sanitize_cc(cxx));
     }
@@ -363,10 +360,11 @@ fn configure_cmake(builder: &Builder,
     cfg.build_arg("-j").build_arg(builder.jobs().to_string());
     cfg.define("CMAKE_C_FLAGS", builder.cflags(target, GitRepo::Llvm).join(" "));
     let mut cxxflags = builder.cflags(target, GitRepo::Llvm).join(" ");
-    if building_dist_binaries {
-        if builder.config.llvm_static_stdcpp && !target.contains("windows") {
-            cxxflags.push_str(" -static-libstdc++");
-        }
+    if builder.config.llvm_static_stdcpp &&
+        !target.contains("windows") &&
+        !target.contains("netbsd")
+    {
+        cxxflags.push_str(" -static-libstdc++");
     }
     cfg.define("CMAKE_CXX_FLAGS", cxxflags);
     if let Some(ar) = builder.ar(target) {
@@ -431,7 +429,7 @@ fn run(self, builder: &Builder) -> PathBuf {
         t!(fs::create_dir_all(&out_dir));
 
         let mut cfg = cmake::Config::new(builder.src.join("src/tools/lld"));
-        configure_cmake(builder, target, &mut cfg, true);
+        configure_cmake(builder, target, &mut cfg);
 
         // This is an awful, awful hack. Discovered when we migrated to using
         // clang-cl to compile LLVM/LLD it turns out that LLD, when built out of
index d31ea0f845873743cfaa82d2020aba28981c353b..9f6db73e6f71389dd2456e234964a23dde40d23f 100644 (file)
@@ -83,6 +83,7 @@ fn run(self, builder: &Builder) -> Option<PathBuf> {
                 | "rls"
                 | "cargo"
                 | "clippy-driver"
+                | "miri"
                 => {}
 
                 _ => return,
@@ -218,6 +219,7 @@ pub fn prepare_tool_cargo(
         if path.ends_with("cargo") ||
             path.ends_with("rls") ||
             path.ends_with("clippy") ||
+            path.ends_with("miri") ||
             path.ends_with("rustfmt")
         {
             cargo.env("LIBZ_SYS_STATIC", "1");
@@ -592,6 +594,14 @@ fn run(mut $sel, $builder: &Builder) -> Option<PathBuf> {
         });
     };
     Miri, miri, "src/tools/miri", "miri", {};
+    CargoMiri, miri, "src/tools/miri", "cargo-miri", {
+        // Miri depends on procedural macros (serde), which requires a full host
+        // compiler to be available, so we need to depend on that.
+        builder.ensure(compile::Rustc {
+            compiler: self.compiler,
+            target: builder.config.build,
+        });
+    };
     Rls, rls, "src/tools/rls", "rls", {
         let clippy = builder.ensure(Clippy {
             compiler: self.compiler,
index 4f8a3c0240e1a19b50938da2acf7b5f5e2740b97..76cdd367987b2c1cb1419abe4b2bb6c1ae419591 100644 (file)
@@ -21,12 +21,18 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   patch \
   libssl-dev \
   pkg-config \
-  gcc-arm-none-eabi \
   libnewlib-arm-none-eabi \
-  qemu-system-arm
+  qemu-system-arm \
+# software-properties-common for the add-apt-repository command
+  software-properties-common
 
 WORKDIR /build
 
+# Use the team-gcc-arm-embedded PPA for a newer version of Arm GCC
+RUN add-apt-repository ppa:team-gcc-arm-embedded/ppa && \
+    apt-get update && \
+    apt-get install -y --no-install-recommends gcc-arm-embedded
+
 COPY dist-various-1/build-rumprun.sh /build
 RUN ./build-rumprun.sh
 
@@ -103,6 +109,7 @@ ENV TARGETS=$TARGETS,thumbv6m-none-eabi
 ENV TARGETS=$TARGETS,thumbv7m-none-eabi
 ENV TARGETS=$TARGETS,thumbv7em-none-eabi
 ENV TARGETS=$TARGETS,thumbv7em-none-eabihf
+ENV TARGETS=$TARGETS,thumbv8m.main-none-eabi
 ENV TARGETS=$TARGETS,riscv32imc-unknown-none-elf
 ENV TARGETS=$TARGETS,riscv32imac-unknown-none-elf
 ENV TARGETS=$TARGETS,armebv7r-none-eabi
diff --git a/src/doc/unstable-book/src/language-features/cfg-attr-multi.md b/src/doc/unstable-book/src/language-features/cfg-attr-multi.md
deleted file mode 100644 (file)
index 6365d3e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# `cfg_attr_multi`
-
-The tracking issue for this feature is: [#54881]
-The RFC for this feature is: [#2539]
-
-[#54881]: https://github.com/rust-lang/rust/issues/54881
-[#2539]: https://github.com/rust-lang/rfcs/pull/2539
-
-------------------------
-
-This feature flag lets you put multiple attributes into a `cfg_attr` attribute.
-
-Example:
-
-```rust,ignore
-#[cfg_attr(all(), must_use, optimize)]
-```
-
-Because `cfg_attr` resolves before procedural macros, this does not affect
-macro resolution at all.
\ No newline at end of file
index d5a22436838623d7729d6dbf976ae28bcf2527ed..50dbbaf56743c6142a0869506faf904203603a96 100644 (file)
@@ -1,8 +1,8 @@
 # `const_fn`
 
-The tracking issue for this feature is: [#24111]
+The tracking issue for this feature is: [#57563]
 
-[#24111]: https://github.com/rust-lang/rust/issues/24111
+[#57563]: https://github.com/rust-lang/rust/issues/57563
 
 ------------------------
 
diff --git a/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md b/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md
deleted file mode 100644 (file)
index 46b8437..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# `irrefutable_let_patterns`
-
-The tracking issue for this feature is: [#44495]
-
-[#44495]: https://github.com/rust-lang/rust/issues/44495
-
-------------------------
-
-This feature changes the way that "irrefutable patterns" are handled
-in the `if let` and `while let` forms. An *irrefutable pattern* is one
-that cannot fail to match -- for example, the `_` pattern matches any
-value, and hence it is "irrefutable". Without this feature, using an
-irrefutable pattern in an `if let` gives a hard error (since often
-this indicates programmer error). But when the feature is enabled, the
-error becomes a lint (since in some cases irrefutable patterns are
-expected). This means you can use `#[allow]` to silence the lint:
-
-```rust
-#![feature(irrefutable_let_patterns)]
-
-#[allow(irrefutable_let_patterns)]
-fn main() {
-    // These two examples used to be errors, but now they
-    // trigger a lint (that is allowed):
-    if let _ = 5 {}
-    while let _ = 5 { break; }
-}
-```
index ef41e426f2893dcbbbe3b1e901146b09cc338543..e8be2b9b53710461734468252c8b1b9e4610e57c 100644 (file)
@@ -1,3 +1,6 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
 r"""
 htmldocck.py is a custom checker script for Rustdoc HTML outputs.
 
@@ -98,7 +101,10 @@ checks if the given file does not exist, for example.
 
 """
 
-from __future__ import print_function
+from __future__ import absolute_import, print_function, unicode_literals
+
+import codecs
+import io
 import sys
 import os.path
 import re
@@ -110,14 +116,10 @@ except ImportError:
     from HTMLParser import HTMLParser
 from xml.etree import cElementTree as ET
 
-# &larrb;/&rarrb; are not in HTML 4 but are in HTML 5
 try:
-    from html.entities import entitydefs
+    from html.entities import name2codepoint
 except ImportError:
-    from htmlentitydefs import entitydefs
-entitydefs['larrb'] = u'\u21e4'
-entitydefs['rarrb'] = u'\u21e5'
-entitydefs['nbsp'] = ' '
+    from htmlentitydefs import name2codepoint
 
 # "void elements" (no closing tag) from the HTML Standard section 12.1.2
 VOID_ELEMENTS = set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen',
@@ -157,11 +159,11 @@ class CustomHTMLParser(HTMLParser):
         self.__builder.data(data)
 
     def handle_entityref(self, name):
-        self.__builder.data(entitydefs[name])
+        self.__builder.data(unichr(name2codepoint[name]))
 
     def handle_charref(self, name):
         code = int(name[1:], 16) if name.startswith(('x', 'X')) else int(name, 10)
-        self.__builder.data(unichr(code).encode('utf-8'))
+        self.__builder.data(unichr(code))
 
     def close(self):
         HTMLParser.close(self)
@@ -210,11 +212,11 @@ LINE_PATTERN = re.compile(r'''
     (?<=(?<!\S)@)(?P<negated>!?)
     (?P<cmd>[A-Za-z]+(?:-[A-Za-z]+)*)
     (?P<args>.*)$
-''', re.X)
+''', re.X | re.UNICODE)
 
 
 def get_commands(template):
-    with open(template, 'rU') as f:
+    with io.open(template, encoding='utf-8') as f:
         for lineno, line in concat_multi_lines(f):
             m = LINE_PATTERN.search(line)
             if not m:
@@ -226,7 +228,10 @@ def get_commands(template):
             if args and not args[:1].isspace():
                 print_err(lineno, line, 'Invalid template syntax')
                 continue
-            args = shlex.split(args)
+            try:
+                args = shlex.split(args)
+            except UnicodeEncodeError:
+                args = [arg.decode('utf-8') for arg in shlex.split(args.encode('utf-8'))]
             yield Command(negated=negated, cmd=cmd, args=args, lineno=lineno+1, context=line)
 
 
@@ -280,7 +285,7 @@ class CachedFiles(object):
         if not(os.path.exists(abspath) and os.path.isfile(abspath)):
             raise FailedCheck('File does not exist {!r}'.format(path))
 
-        with open(abspath) as f:
+        with io.open(abspath, encoding='utf-8') as f:
             data = f.read()
             self.files[path] = data
             return data
@@ -294,9 +299,9 @@ class CachedFiles(object):
         if not(os.path.exists(abspath) and os.path.isfile(abspath)):
             raise FailedCheck('File does not exist {!r}'.format(path))
 
-        with open(abspath) as f:
+        with io.open(abspath, encoding='utf-8') as f:
             try:
-                tree = ET.parse(f, CustomHTMLParser())
+                tree = ET.fromstringlist(f.readlines(), CustomHTMLParser())
             except Exception as e:
                 raise RuntimeError('Cannot parse an HTML file {!r}: {}'.format(path, e))
             self.trees[path] = tree
@@ -313,7 +318,7 @@ def check_string(data, pat, regexp):
     if not pat:
         return True # special case a presence testing
     elif regexp:
-        return re.search(pat, data) is not None
+        return re.search(pat, data, flags=re.UNICODE) is not None
     else:
         data = ' '.join(data.split())
         pat = ' '.join(pat.split())
@@ -350,7 +355,7 @@ def check_tree_text(tree, path, pat, regexp):
                     break
     except Exception as e:
         print('Failed to get path "{}"'.format(path))
-        raise e
+        raise
     return ret
 
 
@@ -359,7 +364,12 @@ def get_tree_count(tree, path):
     return len(tree.findall(path))
 
 def stderr(*args):
-    print(*args, file=sys.stderr)
+    if sys.version_info.major < 3:
+        file = codecs.getwriter('utf-8')(sys.stderr)
+    else:
+        file = sys.stderr
+
+    print(*args, file=file)
 
 def print_err(lineno, context, err, message=None):
     global ERR_COUNT
index 6b4c44806740f36bc053c7a6917bea42473106c3..537b419b3279f5096f6473b2b0f30a907994e3d5 100644 (file)
@@ -18,10 +18,15 @@ import lldb
 import os
 import sys
 import threading
-import thread
 import re
 import time
 
+try:
+    import thread
+except ModuleNotFoundError:
+    # The `thread` module was renamed to `_thread` in Python 3.
+    import _thread as thread
+
 # Set this to True for additional output
 DEBUG_OUTPUT = False
 
index b69c114ed45948e3b556443faae062105edfc0ff..e1c5ab15bb5ce23975c33ed13096a4c6c9f2eac3 100644 (file)
@@ -738,53 +738,88 @@ pub fn as_mut_slice(&mut self) -> &mut [T] {
         self
     }
 
-    /// Sets the length of a vector.
+    /// Forces the length of the vector to `new_len`.
     ///
-    /// This will explicitly set the size of the vector, without actually
-    /// modifying its buffers, so it is up to the caller to ensure that the
-    /// vector is actually the specified size.
+    /// This is a low-level operation that maintains none of the normal
+    /// invariants of the type.  Normally changing the length of a vector
+    /// is done using one of the safe operations instead, such as
+    /// [`truncate`], [`resize`], [`extend`], or [`clear`].
     ///
-    /// # Examples
+    /// [`truncate`]: #method.truncate
+    /// [`resize`]: #method.resize
+    /// [`extend`]: #method.extend-1
+    /// [`clear`]: #method.clear
     ///
-    /// ```
-    /// use std::ptr;
+    /// # Safety
     ///
-    /// let mut vec = vec!['r', 'u', 's', 't'];
+    /// - `new_len` must be less than or equal to [`capacity()`].
+    /// - The elements at `old_len..new_len` must be initialized.
     ///
-    /// unsafe {
-    ///     ptr::drop_in_place(&mut vec[3]);
-    ///     vec.set_len(3);
+    /// [`capacity()`]: #method.capacity
+    ///
+    /// # Examples
+    ///
+    /// This method can be useful for situations in which the vector
+    /// is serving as a buffer for other code, particularly over FFI:
+    ///
+    /// ```no_run
+    /// # #![allow(dead_code)]
+    /// # // This is just a minimal skeleton for the doc example;
+    /// # // don't use this as a starting point for a real library.
+    /// # pub struct StreamWrapper { strm: *mut std::ffi::c_void }
+    /// # const Z_OK: i32 = 0;
+    /// # extern "C" {
+    /// #     fn deflateGetDictionary(
+    /// #         strm: *mut std::ffi::c_void,
+    /// #         dictionary: *mut u8,
+    /// #         dictLength: *mut usize,
+    /// #     ) -> i32;
+    /// # }
+    /// # impl StreamWrapper {
+    /// pub fn get_dictionary(&self) -> Option<Vec<u8>> {
+    ///     // Per the FFI method's docs, "32768 bytes is always enough".
+    ///     let mut dict = Vec::with_capacity(32_768);
+    ///     let mut dict_length = 0;
+    ///     // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
+    ///     // 1. `dict_length` elements were initialized.
+    ///     // 2. `dict_length` <= the capacity (32_768)
+    ///     // which makes `set_len` safe to call.
+    ///     unsafe {
+    ///         // Make the FFI call...
+    ///         let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
+    ///         if r == Z_OK {
+    ///             // ...and update the length to what was initialized.
+    ///             dict.set_len(dict_length);
+    ///             Some(dict)
+    ///         } else {
+    ///             None
+    ///         }
+    ///     }
     /// }
-    /// assert_eq!(vec, ['r', 'u', 's']);
+    /// # }
     /// ```
     ///
-    /// In this example, there is a memory leak since the memory locations
-    /// owned by the inner vectors were not freed prior to the `set_len` call:
+    /// While the following example is sound, there is a memory leak since
+    /// the inner vectors were not freed prior to the `set_len` call:
     ///
     /// ```
     /// let mut vec = vec![vec![1, 0, 0],
     ///                    vec![0, 1, 0],
     ///                    vec![0, 0, 1]];
+    /// // SAFETY:
+    /// // 1. `old_len..0` is empty so no elements need to be initialized.
+    /// // 2. `0 <= capacity` always holds whatever `capacity` is.
     /// unsafe {
     ///     vec.set_len(0);
     /// }
     /// ```
     ///
-    /// In this example, the vector gets expanded from zero to four items
-    /// without any memory allocations occurring, resulting in vector
-    /// values of unallocated memory:
-    ///
-    /// ```
-    /// let mut vec: Vec<char> = Vec::new();
-    ///
-    /// unsafe {
-    ///     vec.set_len(4);
-    /// }
-    /// ```
+    /// Normally, here, one would use [`clear`] instead to correctly drop
+    /// the contents and thus not leak memory.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub unsafe fn set_len(&mut self, len: usize) {
-        self.len = len;
+    pub unsafe fn set_len(&mut self, new_len: usize) {
+        self.len = new_len;
     }
 
     /// Removes an element from the vector and returns it.
index f420d0d00a4011b07320c7eb0f454d719ee2dba4..86f28a957cd2cf8c2d583f1e3737e8de3c0d7c5f 100644 (file)
@@ -1,27 +1,22 @@
 //! Functionality for ordering and comparison.
 //!
-//! This module defines both [`PartialOrd`] and [`PartialEq`] traits which are used
-//! by the compiler to implement comparison operators. Rust programs may
-//! implement [`PartialOrd`] to overload the `<`, `<=`, `>`, and `>=` operators,
-//! and may implement [`PartialEq`] to overload the `==` and `!=` operators.
+//! This module contains various tools for ordering and comparing values. In
+//! summary:
 //!
-//! [`PartialOrd`]: trait.PartialOrd.html
-//! [`PartialEq`]: trait.PartialEq.html
+//! * [`Eq`] and [`PartialEq`] are traits that allow you to define total and
+//!   partial equality between values, respectively. Implementing them overloads
+//!   the `==` and `!=` operators.
+//! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and
+//!   partial orderings between values, respectively. Implementing them overloads
+//!   the `<`, `<=`, `>`, and `>=` operators.
+//! * [`Ordering`][cmp::Ordering] is an enum returned by the
+//!   main functions of [`Ord`] and [`PartialOrd`], and describes an ordering.
+//! * [`Reverse`][cmp::Reverse] is a struct that allows you to easily reverse
+//!   an ordering.
+//! * [`max`][cmp::max] and [`min`][cmp::min] are functions that build off of
+//!   [`Ord`] and allow you to find the maximum or minimum of two values.
 //!
-//! # Examples
-//!
-//! ```
-//! let x: u32 = 0;
-//! let y: u32 = 1;
-//!
-//! // these two lines are equivalent
-//! assert_eq!(x < y, true);
-//! assert_eq!(x.lt(&y), true);
-//!
-//! // these two lines are also equivalent
-//! assert_eq!(x == y, false);
-//! assert_eq!(x.eq(&y), false);
-//! ```
+//! For more details, see the respective documentation of each item in the list.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
index ec1aeb8a7d1e946abbfc42507d4b841804df6af4..214b5d3a84f24c4bb3f88af4cb8063eea18545a0 100644 (file)
@@ -191,29 +191,8 @@ fn write_char(&mut self, c: char) -> Result {
     /// assert_eq!(&buf, "world");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn write_fmt(&mut self, args: Arguments) -> Result {
-        // This Adapter is needed to allow `self` (of type `&mut
-        // Self`) to be cast to a Write (below) without
-        // requiring a `Sized` bound.
-        struct Adapter<'a,T: ?Sized +'a>(&'a mut T);
-
-        impl<T: ?Sized> Write for Adapter<'_, T>
-            where T: Write
-        {
-            fn write_str(&mut self, s: &str) -> Result {
-                self.0.write_str(s)
-            }
-
-            fn write_char(&mut self, c: char) -> Result {
-                self.0.write_char(c)
-            }
-
-            fn write_fmt(&mut self, args: Arguments) -> Result {
-                self.0.write_fmt(args)
-            }
-        }
-
-        write(&mut Adapter(self), args)
+    fn write_fmt(mut self: &mut Self, args: Arguments) -> Result {
+        write(&mut self, args)
     }
 }
 
@@ -268,7 +247,7 @@ struct Void {
 /// family of functions. It contains a function to format the given value. At
 /// compile time it is ensured that the function and the value have the correct
 /// types, and then this struct is used to canonicalize arguments to one type.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 #[allow(missing_debug_implementations)]
 #[unstable(feature = "fmt_internals", reason = "internal to format_args!",
            issue = "0")]
@@ -278,14 +257,6 @@ pub struct ArgumentV1<'a> {
     formatter: fn(&Void, &mut Formatter) -> Result,
 }
 
-#[unstable(feature = "fmt_internals", reason = "internal to format_args!",
-           issue = "0")]
-impl Clone for ArgumentV1<'_> {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
 impl<'a> ArgumentV1<'a> {
     #[inline(never)]
     fn show_usize(x: &usize, f: &mut Formatter) -> Result {
@@ -1105,7 +1076,7 @@ fn getcount(&mut self, cnt: &rt::v1::Count) -> Option<usize> {
                 self.args[i].as_usize()
             }
             rt::v1::Count::NextParam => {
-                self.curarg.next().and_then(|arg| arg.as_usize())
+                self.curarg.next()?.as_usize()
             }
         }
     }
@@ -1171,15 +1142,15 @@ pub fn pad_integral(&mut self,
             sign = Some('+'); width += 1;
         }
 
-        let mut prefixed = false;
-        if self.alternate() {
-            prefixed = true; width += prefix.chars().count();
+        let prefixed = self.alternate();
+        if prefixed {
+            width += prefix.chars().count();
         }
 
         // Writes the sign if it exists, and then the prefix if it was requested
         let write_prefix = |f: &mut Formatter| {
             if let Some(c) = sign {
-                f.buf.write_str(c.encode_utf8(&mut [0; 4]))?;
+                f.buf.write_char(c)?;
             }
             if prefixed { f.buf.write_str(prefix) }
             else { Ok(()) }
@@ -1341,7 +1312,7 @@ fn pad_formatted_parts(&mut self, formatted: &flt2dec::Formatted) -> Result {
 
                 // remove the sign from the formatted parts
                 formatted.sign = b"";
-                width = if width < sign.len() { 0 } else { width - sign.len() };
+                width = width.saturating_sub(sign.len());
                 align = rt::v1::Alignment::Right;
                 self.fill = '0';
                 self.align = rt::v1::Alignment::Right;
index 0bc8a0fd26a047b0a0c8073aa8532e8357166093..539b07fc21eea4ec8031e0347d7f56cc4b8eea00 100644 (file)
@@ -23,7 +23,7 @@
 ///
 /// When using a future, you generally won't call `poll` directly, but instead
 /// `await!` the value.
-#[must_use]
+#[must_use = "futures do nothing unless polled"]
 pub trait Future {
     /// The result of the `Future`.
     type Output;
index 4f5310f5285c9956207887de18ae22a5126053bf..db19baf7a2c64124521c53b61b82b491ab584f6c 100644 (file)
@@ -1348,7 +1348,7 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
     /// use std::intrinsics::ctlz;
     ///
     /// let x = 0b0001_1100_u8;
-    /// let num_leading = unsafe { ctlz(x) };
+    /// let num_leading = ctlz(x);
     /// assert_eq!(num_leading, 3);
     /// ```
     ///
@@ -1360,7 +1360,7 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
     /// use std::intrinsics::ctlz;
     ///
     /// let x = 0u16;
-    /// let num_leading = unsafe { ctlz(x) };
+    /// let num_leading = ctlz(x);
     /// assert_eq!(num_leading, 16);
     /// ```
     pub fn ctlz<T>(x: T) -> T;
@@ -1391,7 +1391,7 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
     /// use std::intrinsics::cttz;
     ///
     /// let x = 0b0011_1000_u8;
-    /// let num_trailing = unsafe { cttz(x) };
+    /// let num_trailing = cttz(x);
     /// assert_eq!(num_trailing, 3);
     /// ```
     ///
@@ -1403,7 +1403,7 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
     /// use std::intrinsics::cttz;
     ///
     /// let x = 0u16;
-    /// let num_trailing = unsafe { cttz(x) };
+    /// let num_trailing = cttz(x);
     /// assert_eq!(num_trailing, 16);
     /// ```
     pub fn cttz<T>(x: T) -> T;
index 1ea500858ed1626b324fbac9f2199b9e5be5e485..640af748172826294af275cdf165539557b34508 100644 (file)
@@ -88,7 +88,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item=()>) {}
     message="`{Self}` is not an iterator"
 )]
 #[doc(spotlight)]
-#[must_use]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 pub trait Iterator {
     /// The type of the elements being iterated over.
     #[stable(feature = "rust1", since = "1.0.0")]
index 03369d6c8f3fd60959ca670a185e8d250a16203b..1ef5428a789cf9cbbd3df9b50e5c64927306bb07 100644 (file)
 //! using it. The compiler will warn us about this kind of behavior:
 //!
 //! ```text
-//! warning: unused result that must be used: iterator adaptors are lazy and
+//! warning: unused result that must be used: iterators are lazy and
 //! do nothing unless consumed
 //! ```
 //!
@@ -404,7 +404,7 @@ fn into_try(self) -> R {
 /// [`rev`]: trait.Iterator.html#method.rev
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Rev<T> {
     iter: T
@@ -505,7 +505,7 @@ unsafe impl<I> TrustedLen for Rev<I>
 /// [`copied`]: trait.Iterator.html#method.copied
 /// [`Iterator`]: trait.Iterator.html
 #[unstable(feature = "iter_copied", issue = "57127")]
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[derive(Clone, Debug)]
 pub struct Copied<I> {
     it: I,
@@ -605,7 +605,7 @@ unsafe impl<'a, I, T: 'a> TrustedLen for Copied<I>
 /// [`cloned`]: trait.Iterator.html#method.cloned
 /// [`Iterator`]: trait.Iterator.html
 #[stable(feature = "iter_cloned", since = "1.1.0")]
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[derive(Clone, Debug)]
 pub struct Cloned<I> {
     it: I,
@@ -717,7 +717,7 @@ unsafe impl<'a, I, T: 'a> TrustedLen for Cloned<I>
 /// [`cycle`]: trait.Iterator.html#method.cycle
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Cycle<I> {
     orig: I,
@@ -757,7 +757,7 @@ impl<I> FusedIterator for Cycle<I> where I: Clone + Iterator {}
 ///
 /// [`step_by`]: trait.Iterator.html#method.step_by
 /// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "iterator_step_by", since = "1.28.0")]
 #[derive(Clone, Debug)]
 pub struct StepBy<I> {
@@ -849,7 +849,7 @@ impl<I> ExactSizeIterator for StepBy<I> where I: ExactSizeIterator {}
 /// [`chain`]: trait.Iterator.html#method.chain
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Chain<A, B> {
     a: A,
@@ -1100,7 +1100,7 @@ unsafe impl<A, B> TrustedLen for Chain<A, B>
 /// [`zip`]: trait.Iterator.html#method.zip
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Zip<A, B> {
     a: A,
@@ -1400,7 +1400,7 @@ unsafe impl<A, B> TrustedLen for Zip<A, B>
 ///     println!("{:?}", pair);
 /// }
 /// ```
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct Map<I, F> {
@@ -1511,7 +1511,7 @@ fn may_have_side_effect() -> bool { true }
 ///
 /// [`filter`]: trait.Iterator.html#method.filter
 /// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct Filter<I, P> {
@@ -1643,7 +1643,7 @@ impl<I: FusedIterator, P> FusedIterator for Filter<I, P>
 ///
 /// [`filter_map`]: trait.Iterator.html#method.filter_map
 /// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct FilterMap<I, F> {
@@ -1754,7 +1754,7 @@ impl<B, I: FusedIterator, F> FusedIterator for FilterMap<I, F>
 /// [`enumerate`]: trait.Iterator.html#method.enumerate
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Enumerate<I> {
     iter: I,
@@ -1915,7 +1915,7 @@ unsafe impl<I> TrustedLen for Enumerate<I>
 /// [`peekable`]: trait.Iterator.html#method.peekable
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Peekable<I: Iterator> {
     iter: I,
@@ -2066,7 +2066,7 @@ pub fn peek(&mut self) -> Option<&I::Item> {
 ///
 /// [`skip_while`]: trait.Iterator.html#method.skip_while
 /// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct SkipWhile<I, P> {
@@ -2149,7 +2149,7 @@ impl<I, P> FusedIterator for SkipWhile<I, P>
 ///
 /// [`take_while`]: trait.Iterator.html#method.take_while
 /// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct TakeWhile<I, P> {
@@ -2233,7 +2233,7 @@ impl<I, P> FusedIterator for TakeWhile<I, P>
 /// [`skip`]: trait.Iterator.html#method.skip
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Skip<I> {
     iter: I,
@@ -2371,7 +2371,7 @@ impl<I> FusedIterator for Skip<I> where I: FusedIterator {}
 /// [`take`]: trait.Iterator.html#method.take
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Take<I> {
     iter: I,
@@ -2458,7 +2458,7 @@ unsafe impl<I: TrustedLen> TrustedLen for Take<I> {}
 ///
 /// [`scan`]: trait.Iterator.html#method.scan
 /// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct Scan<I, St, F> {
@@ -2518,7 +2518,7 @@ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
 ///
 /// [`flat_map`]: trait.Iterator.html#method.flat_map
 /// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct FlatMap<I, U: IntoIterator, F> {
     inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>
@@ -2603,7 +2603,7 @@ impl<I, U, F> FusedIterator for FlatMap<I, U, F>
 ///
 /// [`flatten`]: trait.Iterator.html#method.flatten
 /// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "iterator_flatten", since = "1.29.0")]
 pub struct Flatten<I: Iterator>
 where I::Item: IntoIterator {
@@ -2832,7 +2832,7 @@ fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
 /// [`fuse`]: trait.Iterator.html#method.fuse
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Fuse<I> {
     iter: I,
@@ -3056,7 +3056,7 @@ fn is_empty(&self) -> bool {
 ///
 /// [`inspect`]: trait.Iterator.html#method.inspect
 /// [`Iterator`]: trait.Iterator.html
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct Inspect<I, F> {
index 19bf4ab15bfc4e42ea76df6d40f65970b8e461da..8879112fcf0b96bff209558af0c6dcbef975b7a5 100644 (file)
@@ -71,7 +71,7 @@
 #![feature(cfg_target_has_atomic)]
 #![feature(concat_idents)]
 #![feature(const_fn)]
-#![feature(const_int_ops)]
+#![cfg_attr(stage0, feature(const_int_ops))]
 #![feature(const_fn_union)]
 #![feature(custom_attribute)]
 #![feature(doc_cfg)]
 #![feature(const_slice_len)]
 #![feature(const_str_as_bytes)]
 #![feature(const_str_len)]
-#![feature(const_int_rotate)]
-#![feature(const_int_wrapping)]
-#![feature(const_int_sign)]
+#![cfg_attr(stage0, feature(const_let))]
+#![cfg_attr(stage0, feature(const_int_rotate))]
 #![feature(const_int_conversion)]
 #![feature(const_transmute)]
 #![feature(reverse_bits)]
 #![feature(non_exhaustive)]
 #![feature(structural_match)]
+#![feature(abi_unadjusted)]
+#![cfg_attr(not(stage0), feature(adx_target_feature))]
 
 #[prelude_import]
 #[allow(unused)]
index 99a427ba15974d773594b5ea90c1cf971df9ad31..5326ef1e7c12e1efe68a462dbec62e6dfd5e7754 100644 (file)
@@ -46,25 +46,37 @@ macro_rules! impl_full_ops {
     ($($ty:ty: add($addfn:path), mul/div($bigty:ident);)*) => (
         $(
             impl FullOps for $ty {
+                #[cfg(stage0)]
                 fn full_add(self, other: $ty, carry: bool) -> (bool, $ty) {
-                    // this cannot overflow, the output is between 0 and 2*2^nbits - 1
-                    // FIXME will LLVM optimize this into ADC or similar???
+                    // This cannot overflow; the output is between `0` and `2 * 2^nbits - 1`.
+                    // FIXME: will LLVM optimize this into ADC or similar?
                     let (v, carry1) = unsafe { intrinsics::add_with_overflow(self, other) };
                     let (v, carry2) = unsafe {
                         intrinsics::add_with_overflow(v, if carry {1} else {0})
                     };
                     (carry1 || carry2, v)
                 }
+                #[cfg(not(stage0))]
+                fn full_add(self, other: $ty, carry: bool) -> (bool, $ty) {
+                    // This cannot overflow; the output is between `0` and `2 * 2^nbits - 1`.
+                    // FIXME: will LLVM optimize this into ADC or similar?
+                    let (v, carry1) = intrinsics::add_with_overflow(self, other);
+                    let (v, carry2) = intrinsics::add_with_overflow(v, if carry {1} else {0});
+                    (carry1 || carry2, v)
+                }
 
                 fn full_mul(self, other: $ty, carry: $ty) -> ($ty, $ty) {
-                    // this cannot overflow, the output is between 0 and 2^nbits * (2^nbits - 1)
+                    // This cannot overflow;
+                    // the output is between `0` and `2^nbits * (2^nbits - 1)`.
+                    // FIXME: will LLVM optimize this into ADC or similar?
                     let nbits = mem::size_of::<$ty>() * 8;
                     let v = (self as $bigty) * (other as $bigty) + (carry as $bigty);
                     ((v >> nbits) as $ty, v as $ty)
                 }
 
                 fn full_mul_add(self, other: $ty, other2: $ty, carry: $ty) -> ($ty, $ty) {
-                    // this cannot overflow, the output is between 0 and 2^(2*nbits) - 1
+                    // This cannot overflow;
+                    // the output is between `0` and `2^nbits * (2^nbits - 1)`.
                     let nbits = mem::size_of::<$ty>() * 8;
                     let v = (self as $bigty) * (other as $bigty) + (other2 as $bigty) +
                             (carry as $bigty);
@@ -73,7 +85,7 @@ fn full_mul_add(self, other: $ty, other2: $ty, carry: $ty) -> ($ty, $ty) {
 
                 fn full_div_rem(self, other: $ty, borrow: $ty) -> ($ty, $ty) {
                     debug_assert!(borrow < other);
-                    // this cannot overflow, the dividend is between 0 and other * 2^nbits - 1
+                    // This cannot overflow; the output is between `0` and `other * (2^nbits - 1)`.
                     let nbits = mem::size_of::<$ty>() * 8;
                     let lhs = ((borrow as $bigty) << nbits) | (self as $bigty);
                     let rhs = other as $bigty;
@@ -88,7 +100,8 @@ fn full_div_rem(self, other: $ty, borrow: $ty) -> ($ty, $ty) {
     u8:  add(intrinsics::u8_add_with_overflow),  mul/div(u16);
     u16: add(intrinsics::u16_add_with_overflow), mul/div(u32);
     u32: add(intrinsics::u32_add_with_overflow), mul/div(u64);
-//  u64: add(intrinsics::u64_add_with_overflow), mul/div(u128); // see RFC #521 for enabling this.
+    // See RFC #521 for enabling this.
+    // u64: add(intrinsics::u64_add_with_overflow), mul/div(u128);
 }
 
 /// Table of powers of 5 representable in digits. Specifically, the largest {u8, u16, u32} value
index d1bd97552024d504896bcbed4a4d6c758c8328c1..68da79135d3a33ee76d4b52c718e2ee0e646ee84 100644 (file)
@@ -161,6 +161,14 @@ pub fn is_nan(self) -> bool {
         self != self
     }
 
+    // FIXME(#50145): `abs` is publicly unavailable in libcore due to
+    // concerns about portability, so this implementation is for
+    // private use internally.
+    #[inline]
+    fn abs_private(self) -> f32 {
+        f32::from_bits(self.to_bits() & 0x7fff_ffff)
+    }
+
     /// Returns `true` if this value is positive infinity or negative infinity and
     /// false otherwise.
     ///
@@ -181,7 +189,7 @@ pub fn is_nan(self) -> bool {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_infinite(self) -> bool {
-        self == INFINITY || self == NEG_INFINITY
+        self.abs_private() == INFINITY
     }
 
     /// Returns `true` if this number is neither infinite nor `NaN`.
@@ -203,7 +211,9 @@ pub fn is_infinite(self) -> bool {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_finite(self) -> bool {
-        !(self.is_nan() || self.is_infinite())
+        // There's no need to handle NaN separately: if self is NaN,
+        // the comparison is not true, exactly as desired.
+        self.abs_private() < INFINITY
     }
 
     /// Returns `true` if the number is neither zero, infinite,
index 8ada5b6756c3855dda6e18b87c00734d15559d16..b677391548146ec4c69e26ef18f21ed9ecdbea79 100644 (file)
@@ -161,6 +161,14 @@ pub fn is_nan(self) -> bool {
         self != self
     }
 
+    // FIXME(#50145): `abs` is publicly unavailable in libcore due to
+    // concerns about portability, so this implementation is for
+    // private use internally.
+    #[inline]
+    fn abs_private(self) -> f64 {
+        f64::from_bits(self.to_bits() & 0x7fff_ffff_ffff_ffff)
+    }
+
     /// Returns `true` if this value is positive infinity or negative infinity and
     /// false otherwise.
     ///
@@ -181,7 +189,7 @@ pub fn is_nan(self) -> bool {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_infinite(self) -> bool {
-        self == INFINITY || self == NEG_INFINITY
+        self.abs_private() == INFINITY
     }
 
     /// Returns `true` if this number is neither infinite nor `NaN`.
@@ -203,7 +211,9 @@ pub fn is_infinite(self) -> bool {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_finite(self) -> bool {
-        !(self.is_nan() || self.is_infinite())
+        // There's no need to handle NaN separately: if self is NaN,
+        // the comparison is not true, exactly as desired.
+        self.abs_private() < INFINITY
     }
 
     /// Returns `true` if the number is neither zero, infinite,
index 97bf582df5a8c7289ce5590fd61d88ccc91fccbb..6827364c0f805d34f153596b93d8cefe9cefe5f3 100644 (file)
@@ -275,7 +275,7 @@ pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
 ```
 "),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
         }
@@ -291,7 +291,7 @@ pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
 ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 1);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn count_zeros(self) -> u32 {
                 (!self).count_ones()
@@ -312,7 +312,7 @@ pub const fn count_zeros(self) -> u32 {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn leading_zeros(self) -> u32 {
                 (self as $UnsignedT).leading_zeros()
@@ -333,7 +333,7 @@ pub const fn leading_zeros(self) -> u32 {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn trailing_zeros(self) -> u32 {
                 (self as $UnsignedT).trailing_zeros()
@@ -357,7 +357,7 @@ pub const fn trailing_zeros(self) -> u32 {
 assert_eq!(n.rotate_left(", $rot, "), m);
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_rotate")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))]
             #[inline]
             pub const fn rotate_left(self, n: u32) -> Self {
                 (self as $UnsignedT).rotate_left(n) as Self
@@ -382,7 +382,7 @@ pub const fn rotate_left(self, n: u32) -> Self {
 assert_eq!(n.rotate_right(", $rot, "), m);
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_rotate")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))]
             #[inline]
             pub const fn rotate_right(self, n: u32) -> Self {
                 (self as $UnsignedT).rotate_right(n) as Self
@@ -404,7 +404,7 @@ pub const fn rotate_right(self, n: u32) -> Self {
 assert_eq!(m, ", $swapped, ");
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn swap_bytes(self) -> Self {
                 (self as $UnsignedT).swap_bytes() as Self
@@ -454,7 +454,7 @@ pub const fn reverse_bits(self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn from_be(x: Self) -> Self {
                 #[cfg(target_endian = "big")]
@@ -488,7 +488,7 @@ pub const fn from_be(x: Self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn from_le(x: Self) -> Self {
                 #[cfg(target_endian = "little")]
@@ -522,7 +522,7 @@ pub const fn from_le(x: Self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn to_be(self) -> Self { // or not to be?
                 #[cfg(target_endian = "big")]
@@ -556,7 +556,7 @@ pub const fn to_be(self) -> Self { // or not to be?
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn to_le(self) -> Self {
                 #[cfg(target_endian = "little")]
@@ -994,12 +994,15 @@ pub fn saturating_pow(self, exp: u32) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_wrapping")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
             #[inline]
             pub const fn wrapping_add(self, rhs: Self) -> Self {
+                #[cfg(stage0)]
                 unsafe {
                     intrinsics::overflowing_add(self, rhs)
                 }
+                #[cfg(not(stage0))]
+                intrinsics::overflowing_add(self, rhs)
             }
         }
 
@@ -1018,12 +1021,15 @@ pub const fn wrapping_add(self, rhs: Self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_wrapping")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
             #[inline]
             pub const fn wrapping_sub(self, rhs: Self) -> Self {
+                #[cfg(stage0)]
                 unsafe {
                     intrinsics::overflowing_sub(self, rhs)
                 }
+                #[cfg(not(stage0))]
+                intrinsics::overflowing_sub(self, rhs)
             }
         }
 
@@ -1041,12 +1047,15 @@ pub const fn wrapping_sub(self, rhs: Self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_wrapping")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
             #[inline]
             pub const fn wrapping_mul(self, rhs: Self) -> Self {
+                #[cfg(stage0)]
                 unsafe {
                     intrinsics::overflowing_mul(self, rhs)
                 }
+                #[cfg(not(stage0))]
+                intrinsics::overflowing_mul(self, rhs)
             }
         }
 
@@ -1205,7 +1214,7 @@ pub fn wrapping_neg(self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "num_wrapping", since = "1.2.0")]
-            #[rustc_const_unstable(feature = "const_int_wrapping")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
             #[inline]
             pub const fn wrapping_shl(self, rhs: u32) -> Self {
                 unsafe {
@@ -1233,7 +1242,7 @@ pub const fn wrapping_shl(self, rhs: u32) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "num_wrapping", since = "1.2.0")]
-            #[rustc_const_unstable(feature = "const_int_wrapping")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
             #[inline]
             pub const fn wrapping_shr(self, rhs: u32) -> Self {
                 unsafe {
@@ -1331,13 +1340,15 @@ pub fn wrapping_pow(self, mut exp: u32) -> Self {
 "::MIN, true));", $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
-            #[rustc_const_unstable(feature = "const_int_overflowing")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
             #[inline]
             pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
+                #[cfg(stage0)]
                 let (a, b) = unsafe {
-                    intrinsics::add_with_overflow(self as $ActualT,
-                                                  rhs as $ActualT)
+                    intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT)
                 };
+                #[cfg(not(stage0))]
+                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
                 (a as Self, b)
             }
         }
@@ -1360,13 +1371,15 @@ pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
 "::MAX, true));", $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
-            #[rustc_const_unstable(feature = "const_int_overflowing")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
             #[inline]
             pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
+                #[cfg(stage0)]
                 let (a, b) = unsafe {
-                    intrinsics::sub_with_overflow(self as $ActualT,
-                                                  rhs as $ActualT)
+                    intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT)
                 };
+                #[cfg(not(stage0))]
+                let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
                 (a as Self, b)
             }
         }
@@ -1387,13 +1400,15 @@ pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
 $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
-            #[rustc_const_unstable(feature = "const_int_overflowing")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
             #[inline]
             pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
+                #[cfg(stage0)]
                 let (a, b) = unsafe {
-                    intrinsics::mul_with_overflow(self as $ActualT,
-                                                  rhs as $ActualT)
+                    intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT)
                 };
+                #[cfg(not(stage0))]
+                let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
                 (a as Self, b)
             }
         }
@@ -1576,7 +1591,7 @@ pub fn overflowing_neg(self) -> (Self, bool) {
 $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
-            #[rustc_const_unstable(feature = "const_int_overflowing")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
             #[inline]
             pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
                 (self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
@@ -1600,7 +1615,7 @@ pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
 $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
-            #[rustc_const_unstable(feature = "const_int_overflowing")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
             #[inline]
             pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                 (self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
@@ -1886,7 +1901,6 @@ pub fn signum(self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_sign")]
             #[inline]
             pub const fn is_positive(self) -> bool { self > 0 }
         }
@@ -1905,7 +1919,6 @@ pub const fn is_positive(self) -> bool { self > 0 }
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_sign")]
             #[inline]
             pub const fn is_negative(self) -> bool { self < 0 }
         }
@@ -2227,10 +2240,13 @@ pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
 assert_eq!(n.count_ones(), 3);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn count_ones(self) -> u32 {
+                #[cfg(stage0)]
                 unsafe { intrinsics::ctpop(self as $ActualT) as u32 }
+                #[cfg(not(stage0))]
+                { intrinsics::ctpop(self as $ActualT) as u32 }
             }
         }
 
@@ -2245,7 +2261,7 @@ pub const fn count_ones(self) -> u32 {
 ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 0);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn count_zeros(self) -> u32 {
                 (!self).count_ones()
@@ -2265,10 +2281,13 @@ pub const fn count_zeros(self) -> u32 {
 assert_eq!(n.leading_zeros(), 2);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn leading_zeros(self) -> u32 {
+                #[cfg(stage0)]
                 unsafe { intrinsics::ctlz(self as $ActualT) as u32 }
+                #[cfg(not(stage0))]
+                { intrinsics::ctlz(self as $ActualT) as u32 }
             }
         }
 
@@ -2286,10 +2305,13 @@ pub const fn leading_zeros(self) -> u32 {
 assert_eq!(n.trailing_zeros(), 3);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn trailing_zeros(self) -> u32 {
+                #[cfg(stage0)]
                 unsafe { intrinsics::cttz(self) as u32 }
+                #[cfg(not(stage0))]
+                { intrinsics::cttz(self) as u32 }
             }
         }
 
@@ -2310,10 +2332,13 @@ pub const fn trailing_zeros(self) -> u32 {
 assert_eq!(n.rotate_left(", $rot, "), m);
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_rotate")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))]
             #[inline]
             pub const fn rotate_left(self, n: u32) -> Self {
+                #[cfg(stage0)]
                 unsafe { intrinsics::rotate_left(self, n as $SelfT) }
+                #[cfg(not(stage0))]
+                intrinsics::rotate_left(self, n as $SelfT)
             }
         }
 
@@ -2335,10 +2360,13 @@ pub const fn rotate_left(self, n: u32) -> Self {
 assert_eq!(n.rotate_right(", $rot, "), m);
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_rotate")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))]
             #[inline]
             pub const fn rotate_right(self, n: u32) -> Self {
+                #[cfg(stage0)]
                 unsafe { intrinsics::rotate_right(self, n as $SelfT) }
+                #[cfg(not(stage0))]
+                intrinsics::rotate_right(self, n as $SelfT)
             }
         }
 
@@ -2357,10 +2385,13 @@ pub const fn rotate_right(self, n: u32) -> Self {
 assert_eq!(m, ", $swapped, ");
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn swap_bytes(self) -> Self {
+                #[cfg(stage0)]
                 unsafe { intrinsics::bswap(self as $ActualT) as Self }
+                #[cfg(not(stage0))]
+                { intrinsics::bswap(self as $ActualT) as Self }
             }
         }
 
@@ -2380,10 +2411,13 @@ pub const fn swap_bytes(self) -> Self {
 assert_eq!(m, ", $reversed, ");
 ```"),
             #[unstable(feature = "reverse_bits", issue = "48763")]
-            #[rustc_const_unstable(feature = "const_int_conversion")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_conversion"))]
             #[inline]
             pub const fn reverse_bits(self) -> Self {
+                #[cfg(stage0)]
                 unsafe { intrinsics::bitreverse(self as $ActualT) as Self }
+                #[cfg(not(stage0))]
+                { intrinsics::bitreverse(self as $ActualT) as Self }
             }
         }
 
@@ -2407,7 +2441,7 @@ pub const fn reverse_bits(self) -> Self {
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn from_be(x: Self) -> Self {
                 #[cfg(target_endian = "big")]
@@ -2441,7 +2475,7 @@ pub const fn from_be(x: Self) -> Self {
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn from_le(x: Self) -> Self {
                 #[cfg(target_endian = "little")]
@@ -2475,7 +2509,7 @@ pub const fn from_le(x: Self) -> Self {
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn to_be(self) -> Self { // or not to be?
                 #[cfg(target_endian = "big")]
@@ -2509,7 +2543,7 @@ pub const fn to_be(self) -> Self { // or not to be?
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))]
             #[inline]
             pub const fn to_le(self) -> Self {
                 #[cfg(target_endian = "little")]
@@ -2884,12 +2918,15 @@ pub fn saturating_pow(self, exp: u32) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_wrapping")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
             #[inline]
             pub const fn wrapping_add(self, rhs: Self) -> Self {
+                #[cfg(stage0)]
                 unsafe {
                     intrinsics::overflowing_add(self, rhs)
                 }
+                #[cfg(not(stage0))]
+                intrinsics::overflowing_add(self, rhs)
             }
         }
 
@@ -2907,12 +2944,15 @@ pub const fn wrapping_add(self, rhs: Self) -> Self {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_int_wrapping")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
             #[inline]
             pub const fn wrapping_sub(self, rhs: Self) -> Self {
+                #[cfg(stage0)]
                 unsafe {
                     intrinsics::overflowing_sub(self, rhs)
                 }
+                #[cfg(not(stage0))]
+                intrinsics::overflowing_sub(self, rhs)
             }
         }
 
@@ -2931,12 +2971,15 @@ pub const fn wrapping_sub(self, rhs: Self) -> Self {
         /// assert_eq!(25u8.wrapping_mul(12), 44);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
-        #[rustc_const_unstable(feature = "const_int_wrapping")]
+        #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
         #[inline]
         pub const fn wrapping_mul(self, rhs: Self) -> Self {
+            #[cfg(stage0)]
             unsafe {
                 intrinsics::overflowing_mul(self, rhs)
             }
+            #[cfg(not(stage0))]
+            intrinsics::overflowing_mul(self, rhs)
         }
 
         doc_comment! {
@@ -3081,7 +3124,7 @@ pub fn wrapping_neg(self) -> Self {
 assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);", $EndFeature, "
 ```"),
             #[stable(feature = "num_wrapping", since = "1.2.0")]
-            #[rustc_const_unstable(feature = "const_int_wrapping")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
             #[inline]
             pub const fn wrapping_shl(self, rhs: u32) -> Self {
                 unsafe {
@@ -3111,7 +3154,7 @@ pub const fn wrapping_shl(self, rhs: u32) -> Self {
 assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);", $EndFeature, "
 ```"),
             #[stable(feature = "num_wrapping", since = "1.2.0")]
-            #[rustc_const_unstable(feature = "const_int_wrapping")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))]
             #[inline]
             pub const fn wrapping_shr(self, rhs: u32) -> Self {
                 unsafe {
@@ -3176,13 +3219,15 @@ pub fn wrapping_pow(self, mut exp: u32) -> Self {
 assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (0, true));", $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
-            #[rustc_const_unstable(feature = "const_int_overflowing")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
             #[inline]
             pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
+                #[cfg(stage0)]
                 let (a, b) = unsafe {
-                    intrinsics::add_with_overflow(self as $ActualT,
-                                                  rhs as $ActualT)
+                    intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT)
                 };
+                #[cfg(not(stage0))]
+                let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
                 (a as Self, b)
             }
         }
@@ -3206,13 +3251,15 @@ pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
 $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
-            #[rustc_const_unstable(feature = "const_int_overflowing")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
             #[inline]
             pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
+                #[cfg(stage0)]
                 let (a, b) = unsafe {
-                    intrinsics::sub_with_overflow(self as $ActualT,
-                                                  rhs as $ActualT)
+                    intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT)
                 };
+                #[cfg(not(stage0))]
+                let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
                 (a as Self, b)
             }
         }
@@ -3235,13 +3282,15 @@ pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
         /// assert_eq!(1_000_000_000u32.overflowing_mul(10), (1410065408, true));
         /// ```
         #[stable(feature = "wrapping", since = "1.7.0")]
-        #[rustc_const_unstable(feature = "const_int_overflowing")]
+        #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
         #[inline]
         pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
+            #[cfg(stage0)]
             let (a, b) = unsafe {
-                intrinsics::mul_with_overflow(self as $ActualT,
-                                              rhs as $ActualT)
+                intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT)
             };
+            #[cfg(not(stage0))]
+            let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
             (a as Self, b)
         }
 
@@ -3399,7 +3448,7 @@ pub fn overflowing_neg(self) -> (Self, bool) {
 assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(132), (0x10, true));", $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
-            #[rustc_const_unstable(feature = "const_int_overflowing")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
             #[inline]
             pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
                 (self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
@@ -3424,7 +3473,7 @@ pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
 assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(132), (0x1, true));", $EndFeature, "
 ```"),
             #[stable(feature = "wrapping", since = "1.7.0")]
-            #[rustc_const_unstable(feature = "const_int_overflowing")]
+            #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_overflowing"))]
             #[inline]
             pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                 (self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
index 6d4f4be1a17824ead0498e328b5af34ecd500dba..0e54397db02476942bdda8998f04f4447b64a5a4 100644 (file)
@@ -1013,8 +1013,6 @@ impl<T, E> Option<Result<T, E>> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(transpose_result)]
-    ///
     /// #[derive(Debug, Eq, PartialEq)]
     /// struct SomeErr;
     ///
@@ -1023,7 +1021,7 @@ impl<T, E> Option<Result<T, E>> {
     /// assert_eq!(x, y.transpose());
     /// ```
     #[inline]
-    #[unstable(feature = "transpose_result", issue = "47338")]
+    #[stable(feature = "transpose_result", since = "1.33.0")]
     pub fn transpose(self) -> Result<Option<T>, E> {
         match self {
             Some(Ok(x)) => Ok(Some(x)),
index e31ac691e3a3c0ba8c91e5d6bd9f8067a3c2c36a..762e07549a52a40613a5e9bf47456e5b9f78e11a 100644 (file)
@@ -175,11 +175,11 @@ pub fn as_mut(self: &mut Pin<P>) -> Pin<&mut P::Target> {
     /// Assign a new value to the memory behind the pinned reference.
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub fn set(mut self: Pin<P>, value: P::Target)
+    pub fn set(self: &mut Pin<P>, value: P::Target)
     where
         P::Target: Sized,
     {
-        *self.pointer = value;
+        *(self.pointer) = value;
     }
 }
 
index 55a72d7a9a94daffebd36f40971ec297f210ec12..02eef07afd7ab6890cad3ecdd7bd717b9b11d1fa 100644 (file)
@@ -849,6 +849,7 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
 /// [valid]: ../ptr/index.html#safety
 /// [`Copy`]: ../marker/trait.Copy.html
 /// [`read`]: ./fn.read.html
+/// [read-ownership]: ./fn.read.html#ownership-of-the-returned-value
 ///
 /// Just like in C, whether an operation is volatile has no bearing whatsoever
 /// on questions involving concurrent access from multiple threads. Volatile
index b10d767efb24ee62f2fb3f09317455d20966f250..1ebf0714e23e41eaf68206d5965d6ea4804cde99 100644 (file)
@@ -972,8 +972,6 @@ impl<T, E> Result<Option<T>, E> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(transpose_result)]
-    ///
     /// #[derive(Debug, Eq, PartialEq)]
     /// struct SomeErr;
     ///
@@ -982,7 +980,7 @@ impl<T, E> Result<Option<T>, E> {
     /// assert_eq!(x.transpose(), y);
     /// ```
     #[inline]
-    #[unstable(feature = "transpose_result", issue = "47338")]
+    #[stable(feature = "transpose_result", since = "1.33.0")]
     pub fn transpose(self) -> Option<Result<T, E>> {
         match self {
             Ok(Some(x)) => Some(Ok(x)),
index 689d456d4124617921c4c21b85723d9e3317ebbb..bdde187d931cc4654264a42c21a7f2f21c4c89d5 100644 (file)
@@ -20,8 +20,7 @@
 #[allow(missing_docs)]
 pub mod lossy;
 
-/// A trait to abstract the idea of creating a new instance of a type from a
-/// string.
+/// Parse a value from a string
 ///
 /// `FromStr`'s [`from_str`] method is often used implicitly, through
 /// [`str`]'s [`parse`] method. See [`parse`]'s documentation for examples.
 /// [`str`]: ../../std/primitive.str.html
 /// [`parse`]: ../../std/primitive.str.html#method.parse
 ///
+/// `FromStr` does not have a lifetime parameter, and so you can only parse types
+/// that do not contain a lifetime parameter themselves. In other words, you can
+/// parse an `i32` with `FromStr`, but not a `&i32`. You can parse a struct that
+/// contains an `i32`, but not one that contains an `&i32`.
+///
 /// # Examples
 ///
 /// Basic implementation of `FromStr` on an example `Point` type:
index b4eae4d1bb742bc9a2df473f652810176b8c8f31..55a7ba181e5271d5a4e7f8188ba3714934e765d1 100644 (file)
@@ -425,8 +425,7 @@ impl<'a> Pattern<'a> for char {
     #[inline]
     fn into_searcher(self, haystack: &'a str) -> Self::Searcher {
         let mut utf8_encoded = [0; 4];
-        self.encode_utf8(&mut utf8_encoded);
-        let utf8_size = self.len_utf8();
+        let utf8_size = self.encode_utf8(&mut utf8_encoded).len();
         CharSearcher {
             haystack,
             finger: 0,
index b12ee0497d2c25fc6d4c10af69b2548826249740..a751965dffab34ac31084fa9a3cfc0cb23b87cae 100644 (file)
 const MICROS_PER_SEC: u64 = 1_000_000;
 const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64;
 
+/// The duration of one second.
+#[unstable(feature = "duration_constants", issue = "57391")]
+pub const SECOND: Duration = Duration::from_secs(1);
+
+/// The duration of one millisecond.
+#[unstable(feature = "duration_constants", issue = "57391")]
+pub const MILLISECOND: Duration = Duration::from_millis(1);
+
+/// The duration of one microsecond.
+#[unstable(feature = "duration_constants", issue = "57391")]
+pub const MICROSECOND: Duration = Duration::from_micros(1);
+
+/// The duration of one nanosecond.
+#[unstable(feature = "duration_constants", issue = "57391")]
+pub const NANOSECOND: Duration = Duration::from_nanos(1);
+
 /// A `Duration` type to represent a span of time, typically used for system
 /// timeouts.
 ///
index 3156f17e0c4c5e6b15261e353c1b8a655214c320..427fe51e6ff9cc6ccfc48586f3d026ad311b8532 100644 (file)
@@ -472,6 +472,12 @@ pub fn to_dep_node(self, tcx: TyCtxt<'_, '_, '_>, kind: DepKind) -> DepNode {
     [] UnsafetyCheckResult(DefId),
     [] UnsafeDeriveOnReprPacked(DefId),
 
+    [] CheckModAttrs(DefId),
+    [] CheckModLoops(DefId),
+    [] CheckModUnstableApiUsage(DefId),
+    [] CheckModItemTypes(DefId),
+    [] CollectModItemTypes(DefId),
+
     [] Reachability,
     [] MirKeys,
     [eval_always] CrateVariances,
index 961638151a2a8758042692c8ab4e7bb3a8fe5047..501ef01d74c6e783cd5dc8e6e3ff55b72803dfdc 100644 (file)
@@ -122,12 +122,7 @@ pub fn assert_ignored(&self)
         if let Some(..) = self.data {
             ty::tls::with_context_opt(|icx| {
                 let icx = if let Some(icx) = icx { icx } else { return };
-                match *icx.task {
-                    OpenTask::Ignore => {
-                        // ignored
-                    }
-                    _ => panic!("expected an ignore context")
-                }
+                assert!(icx.task_deps.is_none(), "expected no task dependency tracking");
             })
         }
     }
@@ -137,7 +132,7 @@ pub fn with_ignore<OP,R>(&self, op: OP) -> R
     {
         ty::tls::with_context(|icx| {
             let icx = ty::tls::ImplicitCtxt {
-                task: &OpenTask::Ignore,
+                task_deps: None,
                 ..icx.clone()
             };
 
@@ -184,12 +179,15 @@ pub fn with_task<'gcx, C, A, R>(&self,
               R: HashStable<StableHashingContext<'gcx>>,
     {
         self.with_task_impl(key, cx, arg, false, task,
-            |key| OpenTask::Regular(Lock::new(RegularOpenTask {
-                node: key,
+            |_key| Some(TaskDeps {
+                #[cfg(debug_assertions)]
+                node: Some(_key),
                 reads: SmallVec::new(),
                 read_set: Default::default(),
-            })),
-            |data, key, fingerprint, task| data.borrow_mut().complete_task(key, task, fingerprint))
+            }),
+            |data, key, fingerprint, task| {
+                data.borrow_mut().complete_task(key, task.unwrap(), fingerprint)
+            })
     }
 
     /// Creates a new dep-graph input with value `input`
@@ -206,7 +204,7 @@ fn identity_fn<C, A>(_: C, arg: A) -> A {
         }
 
         self.with_task_impl(key, cx, input, true, identity_fn,
-            |_| OpenTask::Ignore,
+            |_| None,
             |data, key, fingerprint, _| {
                 data.borrow_mut().alloc_node(key, SmallVec::new(), fingerprint)
             })
@@ -219,18 +217,18 @@ fn with_task_impl<'gcx, C, A, R>(
         arg: A,
         no_tcx: bool,
         task: fn(C, A) -> R,
-        create_task: fn(DepNode) -> OpenTask,
+        create_task: fn(DepNode) -> Option<TaskDeps>,
         finish_task_and_alloc_depnode: fn(&Lock<CurrentDepGraph>,
                                           DepNode,
                                           Fingerprint,
-                                          OpenTask) -> DepNodeIndex
+                                          Option<TaskDeps>) -> DepNodeIndex
     ) -> (R, DepNodeIndex)
     where
         C: DepGraphSafe + StableHashingContextProvider<'gcx>,
         R: HashStable<StableHashingContext<'gcx>>,
     {
         if let Some(ref data) = self.data {
-            let open_task = create_task(key);
+            let task_deps = create_task(key).map(|deps| Lock::new(deps));
 
             // In incremental mode, hash the result of the task. We don't
             // do anything with the hash yet, but we are computing it
@@ -248,7 +246,7 @@ fn with_task_impl<'gcx, C, A, R>(
             } else {
                 ty::tls::with_context(|icx| {
                     let icx = ty::tls::ImplicitCtxt {
-                        task: &open_task,
+                        task_deps: task_deps.as_ref(),
                         ..icx.clone()
                     };
 
@@ -271,7 +269,7 @@ fn with_task_impl<'gcx, C, A, R>(
                 &data.current,
                 key,
                 current_fingerprint,
-                open_task
+                task_deps.map(|lock| lock.into_inner()),
             );
 
             // Determine the color of the new DepNode.
@@ -304,15 +302,17 @@ pub fn with_anon_task<OP,R>(&self, dep_kind: DepKind, op: OP) -> (R, DepNodeInde
         where OP: FnOnce() -> R
     {
         if let Some(ref data) = self.data {
-            let (result, open_task) = ty::tls::with_context(|icx| {
-                let task = OpenTask::Anon(Lock::new(AnonOpenTask {
+            let (result, task_deps) = ty::tls::with_context(|icx| {
+                let task_deps = Lock::new(TaskDeps {
+                    #[cfg(debug_assertions)]
+                    node: None,
                     reads: SmallVec::new(),
                     read_set: Default::default(),
-                }));
+                });
 
                 let r = {
                     let icx = ty::tls::ImplicitCtxt {
-                        task: &task,
+                        task_deps: Some(&task_deps),
                         ..icx.clone()
                     };
 
@@ -321,11 +321,11 @@ pub fn with_anon_task<OP,R>(&self, dep_kind: DepKind, op: OP) -> (R, DepNodeInde
                     })
                 };
 
-                (r, task)
+                (r, task_deps.into_inner())
             });
             let dep_node_index = data.current
                                      .borrow_mut()
-                                     .pop_anon_task(dep_kind, open_task);
+                                     .complete_anon_task(dep_kind, task_deps);
             (result, dep_node_index)
         } else {
             (op(), DepNodeIndex::INVALID)
@@ -344,18 +344,23 @@ pub fn with_eval_always_task<'gcx, C, A, R>(&self,
               R: HashStable<StableHashingContext<'gcx>>,
     {
         self.with_task_impl(key, cx, arg, false, task,
-            |key| OpenTask::EvalAlways { node: key },
-            |data, key, fingerprint, task| {
-                data.borrow_mut().complete_eval_always_task(key, task, fingerprint)
+            |_| None,
+            |data, key, fingerprint, _| {
+                let mut current = data.borrow_mut();
+                let krate_idx = current.node_to_node_index[
+                    &DepNode::new_no_params(DepKind::Krate)
+                ];
+                current.alloc_node(key, smallvec![krate_idx], fingerprint)
             })
     }
 
     #[inline]
     pub fn read(&self, v: DepNode) {
         if let Some(ref data) = self.data {
-            let mut current = data.current.borrow_mut();
+            let current = data.current.borrow_mut();
             if let Some(&dep_node_index) = current.node_to_node_index.get(&v) {
-                current.read_index(dep_node_index);
+                std::mem::drop(current);
+                data.read_index(dep_node_index);
             } else {
                 bug!("DepKind {:?} should be pre-allocated but isn't.", v.kind)
             }
@@ -365,7 +370,7 @@ pub fn read(&self, v: DepNode) {
     #[inline]
     pub fn read_index(&self, dep_node_index: DepNodeIndex) {
         if let Some(ref data) = self.data {
-            data.current.borrow_mut().read_index(dep_node_index);
+            data.read_index(dep_node_index);
         }
     }
 
@@ -446,10 +451,15 @@ pub(super) fn dep_node_debug_str(&self, dep_node: DepNode) -> Option<String> {
             .cloned()
     }
 
-    pub fn edge_deduplication_data(&self) -> (u64, u64) {
-        let current_dep_graph = self.data.as_ref().unwrap().current.borrow();
+    pub fn edge_deduplication_data(&self) -> Option<(u64, u64)> {
+        if cfg!(debug_assertions) {
+            let current_dep_graph = self.data.as_ref().unwrap().current.borrow();
 
-        (current_dep_graph.total_read_count, current_dep_graph.total_duplicate_read_count)
+            Some((current_dep_graph.total_read_count,
+                  current_dep_graph.total_duplicate_read_count))
+        } else {
+            None
+        }
     }
 
     pub fn serialize(&self) -> SerializedDepGraph {
@@ -686,7 +696,7 @@ pub fn try_mark_green<'tcx>(&self,
 
                 // Promote the previous diagnostics to the current session.
                 tcx.queries.on_disk_cache
-                   .store_diagnostics(dep_node_index, diagnostics.clone());
+                   .store_diagnostics(dep_node_index, diagnostics.clone().into());
 
                 for diagnostic in diagnostics {
                     DiagnosticBuilder::new_diagnostic(handle, diagnostic).emit();
@@ -827,6 +837,7 @@ struct DepNodeData {
 pub(super) struct CurrentDepGraph {
     data: IndexVec<DepNodeIndex, DepNodeData>,
     node_to_node_index: FxHashMap<DepNode, DepNodeIndex>,
+    #[allow(dead_code)]
     forbidden_edge: Option<EdgeFilter>,
 
     // Anonymous DepNodes are nodes the ID of which we compute from the list of
@@ -890,134 +901,60 @@ fn new(prev_graph_node_count: usize) -> CurrentDepGraph {
 
     fn complete_task(
         &mut self,
-        key: DepNode,
-        task: OpenTask,
+        node: DepNode,
+        task_deps: TaskDeps,
         fingerprint: Fingerprint
     ) -> DepNodeIndex {
-        if let OpenTask::Regular(task) = task {
-            let RegularOpenTask {
-                node,
-                read_set: _,
-                reads
-            } = task.into_inner();
-            assert_eq!(node, key);
-
-            // If this is an input node, we expect that it either has no
-            // dependencies, or that it just depends on DepKind::CrateMetadata
-            // or DepKind::Krate. This happens for some "thin wrapper queries"
-            // like `crate_disambiguator` which sometimes have zero deps (for
-            // when called for LOCAL_CRATE) or they depend on a CrateMetadata
-            // node.
-            if cfg!(debug_assertions) {
-                if node.kind.is_input() && reads.len() > 0 &&
-                   // FIXME(mw): Special case for DefSpan until Spans are handled
-                   //            better in general.
-                   node.kind != DepKind::DefSpan &&
-                    reads.iter().any(|&i| {
-                        !(self.data[i].node.kind == DepKind::CrateMetadata ||
-                          self.data[i].node.kind == DepKind::Krate)
-                    })
-                {
-                    bug!("Input node {:?} with unexpected reads: {:?}",
-                        node,
-                        reads.iter().map(|&i| self.data[i].node).collect::<Vec<_>>())
-                }
+        // If this is an input node, we expect that it either has no
+        // dependencies, or that it just depends on DepKind::CrateMetadata
+        // or DepKind::Krate. This happens for some "thin wrapper queries"
+        // like `crate_disambiguator` which sometimes have zero deps (for
+        // when called for LOCAL_CRATE) or they depend on a CrateMetadata
+        // node.
+        if cfg!(debug_assertions) {
+            if node.kind.is_input() && task_deps.reads.len() > 0 &&
+                // FIXME(mw): Special case for DefSpan until Spans are handled
+                //            better in general.
+                node.kind != DepKind::DefSpan &&
+                task_deps.reads.iter().any(|&i| {
+                    !(self.data[i].node.kind == DepKind::CrateMetadata ||
+                        self.data[i].node.kind == DepKind::Krate)
+                })
+            {
+                bug!("Input node {:?} with unexpected reads: {:?}",
+                    node,
+                    task_deps.reads.iter().map(|&i| self.data[i].node).collect::<Vec<_>>())
             }
-
-            self.alloc_node(node, reads, fingerprint)
-        } else {
-            bug!("complete_task() - Expected regular task to be popped")
         }
-    }
-
-    fn pop_anon_task(&mut self, kind: DepKind, task: OpenTask) -> DepNodeIndex {
-        if let OpenTask::Anon(task) = task {
-            let AnonOpenTask {
-                read_set: _,
-                reads
-            } = task.into_inner();
-            debug_assert!(!kind.is_input());
-
-            let mut fingerprint = self.anon_id_seed;
-            let mut hasher = StableHasher::new();
 
-            for &read in reads.iter() {
-                let read_dep_node = self.data[read].node;
+        self.alloc_node(node, task_deps.reads, fingerprint)
+    }
 
-                ::std::mem::discriminant(&read_dep_node.kind).hash(&mut hasher);
+    fn complete_anon_task(&mut self, kind: DepKind, task_deps: TaskDeps) -> DepNodeIndex {
+        debug_assert!(!kind.is_input());
 
-                // Fingerprint::combine() is faster than sending Fingerprint
-                // through the StableHasher (at least as long as StableHasher
-                // is so slow).
-                fingerprint = fingerprint.combine(read_dep_node.hash);
-            }
+        let mut fingerprint = self.anon_id_seed;
+        let mut hasher = StableHasher::new();
 
-            fingerprint = fingerprint.combine(hasher.finish());
+        for &read in task_deps.reads.iter() {
+            let read_dep_node = self.data[read].node;
 
-            let target_dep_node = DepNode {
-                kind,
-                hash: fingerprint,
-            };
+            ::std::mem::discriminant(&read_dep_node.kind).hash(&mut hasher);
 
-            self.intern_node(target_dep_node, reads, Fingerprint::ZERO).0
-        } else {
-            bug!("pop_anon_task() - Expected anonymous task to be popped")
+            // Fingerprint::combine() is faster than sending Fingerprint
+            // through the StableHasher (at least as long as StableHasher
+            // is so slow).
+            fingerprint = fingerprint.combine(read_dep_node.hash);
         }
-    }
 
-    fn complete_eval_always_task(
-        &mut self,
-        key: DepNode,
-        task: OpenTask,
-        fingerprint: Fingerprint
-    ) -> DepNodeIndex {
-        if let OpenTask::EvalAlways {
-            node,
-        } = task {
-            debug_assert_eq!(node, key);
-            let krate_idx = self.node_to_node_index[&DepNode::new_no_params(DepKind::Krate)];
-            self.alloc_node(node, smallvec![krate_idx], fingerprint)
-        } else {
-            bug!("complete_eval_always_task() - Expected eval always task to be popped");
-        }
-    }
+        fingerprint = fingerprint.combine(hasher.finish());
 
-    fn read_index(&mut self, source: DepNodeIndex) {
-        ty::tls::with_context_opt(|icx| {
-            let icx = if let Some(icx) = icx { icx } else { return };
-            match *icx.task {
-                OpenTask::Regular(ref task) => {
-                    let mut task = task.lock();
-                    self.total_read_count += 1;
-                    if task.read_set.insert(source) {
-                        task.reads.push(source);
-
-                        if cfg!(debug_assertions) {
-                            if let Some(ref forbidden_edge) = self.forbidden_edge {
-                                let target = &task.node;
-                                let source = self.data[source].node;
-                                if forbidden_edge.test(&source, &target) {
-                                    bug!("forbidden edge {:?} -> {:?} created",
-                                        source,
-                                        target)
-                                }
-                            }
-                        }
-                    } else {
-                        self.total_duplicate_read_count += 1;
-                    }
-                }
-                OpenTask::Anon(ref task) => {
-                    let mut task = task.lock();
-                    if task.read_set.insert(source) {
-                        task.reads.push(source);
-                    }
-                }
-                OpenTask::Ignore | OpenTask::EvalAlways { .. } => {
-                    // ignore
-                }
-            }
-        })
+        let target_dep_node = DepNode {
+            kind,
+            hash: fingerprint,
+        };
+
+        self.intern_node(target_dep_node, task_deps.reads, Fingerprint::ZERO).0
     }
 
     fn alloc_node(
@@ -1054,26 +991,47 @@ fn intern_node(
     }
 }
 
-pub struct RegularOpenTask {
-    node: DepNode,
-    reads: SmallVec<[DepNodeIndex; 8]>,
-    read_set: FxHashSet<DepNodeIndex>,
+impl DepGraphData {
+    fn read_index(&self, source: DepNodeIndex) {
+        ty::tls::with_context_opt(|icx| {
+            let icx = if let Some(icx) = icx { icx } else {  return };
+            if let Some(task_deps) = icx.task_deps {
+                let mut task_deps = task_deps.lock();
+                if cfg!(debug_assertions) {
+                    self.current.lock().total_read_count += 1;
+                }
+                if task_deps.read_set.insert(source) {
+                    task_deps.reads.push(source);
+
+                    #[cfg(debug_assertions)]
+                    {
+                        if let Some(target) = task_deps.node {
+                            let graph = self.current.lock();
+                            if let Some(ref forbidden_edge) = graph.forbidden_edge {
+                                let source = graph.data[source].node;
+                                if forbidden_edge.test(&source, &target) {
+                                    bug!("forbidden edge {:?} -> {:?} created",
+                                        source,
+                                        target)
+                                }
+                            }
+                        }
+                    }
+                } else if cfg!(debug_assertions) {
+                    self.current.lock().total_duplicate_read_count += 1;
+                }
+            }
+        })
+    }
 }
 
-pub struct AnonOpenTask {
+pub struct TaskDeps {
+    #[cfg(debug_assertions)]
+    node: Option<DepNode>,
     reads: SmallVec<[DepNodeIndex; 8]>,
     read_set: FxHashSet<DepNodeIndex>,
 }
 
-pub enum OpenTask {
-    Regular(Lock<RegularOpenTask>),
-    Anon(Lock<AnonOpenTask>),
-    Ignore,
-    EvalAlways {
-        node: DepNode,
-    },
-}
-
 // A data structure that stores Option<DepNodeColor> values as a contiguous
 // array, using one u32 per entry.
 struct DepNodeColorMap {
index d153b7435c9b83863b2b7dd85a6b5fa62d212730..022caabcbf3a1eb9ba4fcb3fb980f0529afe5949 100644 (file)
@@ -10,7 +10,7 @@
 
 pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
 pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, label_strs};
-pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, OpenTask};
+pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps};
 pub use self::graph::WorkProductFileKind;
 pub use self::prev::PreviousDepGraph;
 pub use self::query::DepGraphQuery;
index 2e0e9672758fdd1316fe35ce69b592efd7931071..a214ec88c66549fb48067244d57394a7d9b80faf 100644 (file)
@@ -4,9 +4,14 @@
 //! conflicts between multiple such attributes attached to the same
 //! item.
 
+
+use ty::TyCtxt;
+use ty::query::Providers;
+use ty::query::queries;
+
 use hir;
+use hir::def_id::DefId;
 use hir::intravisit::{self, Visitor, NestedVisitorMap};
-use ty::TyCtxt;
 use std::fmt::{self, Display};
 use syntax_pos::Span;
 
@@ -364,8 +369,9 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
 }
 
 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    let mut checker = CheckAttrVisitor { tcx };
-    tcx.hir().krate().visit_all_item_likes(&mut checker.as_deep_visitor());
+    for &module in tcx.hir().krate().modules.keys() {
+        queries::check_mod_attrs::ensure(tcx, tcx.hir().local_def_id(module));
+    }
 }
 
 fn is_c_like_enum(item: &hir::Item) -> bool {
@@ -381,3 +387,17 @@ fn is_c_like_enum(item: &hir::Item) -> bool {
         false
     }
 }
+
+fn check_mod_attrs<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
+    tcx.hir().visit_item_likes_in_module(
+        module_def_id,
+        &mut CheckAttrVisitor { tcx }.as_deep_visitor()
+    );
+}
+
+pub(crate) fn provide(providers: &mut Providers<'_>) {
+    *providers = Providers {
+        check_mod_attrs,
+        ..*providers
+    };
+}
index 20ec620a281fda01be7317019f7e92dee6a6ff8b..2382a2ea50bbad9ff2edbb4ee9c7b3a3115d6736 100644 (file)
@@ -240,7 +240,7 @@ pub fn from_hir(vdata: &hir::VariantData) -> CtorKind {
 }
 
 impl NonMacroAttrKind {
-    fn descr(self) -> &'static str {
+    pub fn descr(self) -> &'static str {
         match self {
             NonMacroAttrKind::Builtin => "built-in attribute",
             NonMacroAttrKind::Tool => "tool attribute",
index fb2c873d740ca9b43b1bf56b1bde5aa4e136d3d4..9181076740ba077011b01562a1b6078e31d25cd2 100644 (file)
@@ -1,4 +1,5 @@
 use ty;
+use ty::TyCtxt;
 use hir::map::definitions::FIRST_FREE_HIGH_DEF_INDEX;
 use rustc_data_structures::indexed_vec::Idx;
 use serialize;
@@ -17,8 +18,6 @@ pub enum CrateNum {
     // FIXME(jseyfried): this is also used for custom derives until proc-macro crates get
     // `CrateNum`s.
     BuiltinMacros,
-    /// A CrateNum value that indicates that something is wrong.
-    Invalid,
     /// A special CrateNum that we use for the tcx.rcache when decoding from
     /// the incr. comp. cache.
     ReservedForIncrCompCache,
@@ -29,7 +28,6 @@ impl ::std::fmt::Debug for CrateNum {
     fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
         match self {
             CrateNum::Index(id) => write!(fmt, "crate{}", id.private),
-            CrateNum::Invalid => write!(fmt, "invalid crate"),
             CrateNum::BuiltinMacros => write!(fmt, "builtin macros crate"),
             CrateNum::ReservedForIncrCompCache => write!(fmt, "crate for decoding incr comp cache"),
         }
@@ -90,7 +88,6 @@ impl fmt::Display for CrateNum {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
             CrateNum::Index(id) => fmt::Display::fmt(&id.private, f),
-            CrateNum::Invalid => write!(f, "invalid crate"),
             CrateNum::BuiltinMacros => write!(f, "builtin macros crate"),
             CrateNum::ReservedForIncrCompCache => write!(f, "crate for decoding incr comp cache"),
         }
@@ -247,6 +244,14 @@ pub fn is_local(self) -> bool {
     pub fn to_local(self) -> LocalDefId {
         LocalDefId::from_def_id(self)
     }
+
+    pub fn describe_as_module(&self, tcx: TyCtxt<'_, '_, '_>) -> String {
+        if self.is_local() && self.index == CRATE_DEF_INDEX {
+            format!("top-level module")
+        } else {
+            format!("module `{}`", tcx.item_path_str(*self))
+        }
+    }
 }
 
 impl serialize::UseSpecializedEncodable for DefId {}
index d4f891c874a40cc4eb31f235e76a56e016134f85..f633703be56d409106b73e1c8b9913acdd64935b 100644 (file)
 
 #[derive(Copy, Clone)]
 pub enum FnKind<'a> {
-    /// #[xxx] pub async/const/extern "Abi" fn foo()
-    ItemFn(Name, &'a Generics, FnHeader, &'a Visibility, &'a [Attribute]),
+    /// `#[xxx] pub async/const/extern "Abi" fn foo()`
+    ItemFn(Ident, &'a Generics, FnHeader, &'a Visibility, &'a [Attribute]),
 
-    /// fn foo(&self)
+    /// `fn foo(&self)`
     Method(Ident, &'a MethodSig, Option<&'a Visibility>, &'a [Attribute]),
 
-    /// |x, y| {}
+    /// `|x, y| {}`
     Closure(&'a [Attribute]),
 }
 
@@ -472,7 +472,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
             visitor.visit_nested_body(body);
         }
         ItemKind::Fn(ref declaration, header, ref generics, body_id) => {
-            visitor.visit_fn(FnKind::ItemFn(item.ident.name,
+            visitor.visit_fn(FnKind::ItemFn(item.ident,
                                             generics,
                                             header,
                                             &item.vis,
index 359bd37488241667e19920175a4812a06023bba1..8badcbfc1b3017b4cd4d77797570239f2617346f 100644 (file)
@@ -48,7 +48,7 @@
 use util::common::FN_OUTPUT_NAME;
 use util::nodemap::{DefIdMap, NodeMap};
 
-use std::collections::BTreeMap;
+use std::collections::{BTreeSet, BTreeMap};
 use std::fmt::Debug;
 use std::mem;
 use smallvec::SmallVec;
@@ -90,6 +90,8 @@ pub struct LoweringContext<'a> {
     trait_impls: BTreeMap<DefId, Vec<NodeId>>,
     trait_auto_impl: BTreeMap<DefId, NodeId>,
 
+    modules: BTreeMap<NodeId, hir::ModuleItems>,
+
     is_generator: bool,
 
     catch_scopes: Vec<NodeId>,
@@ -124,6 +126,8 @@ pub struct LoweringContext<'a> {
     // needs to be created for it.
     in_scope_lifetimes: Vec<Ident>,
 
+    current_module: NodeId,
+
     type_def_lifetime_params: DefIdMap<usize>,
 
     current_hir_id_owner: Vec<(DefIndex, u32)>,
@@ -228,12 +232,14 @@ pub fn lower_crate(
         bodies: BTreeMap::new(),
         trait_impls: BTreeMap::new(),
         trait_auto_impl: BTreeMap::new(),
+        modules: BTreeMap::new(),
         exported_macros: Vec::new(),
         catch_scopes: Vec::new(),
         loop_scopes: Vec::new(),
         is_in_loop_condition: false,
         anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
         type_def_lifetime_params: Default::default(),
+        current_module: CRATE_NODE_ID,
         current_hir_id_owner: vec![(CRATE_DEF_INDEX, 0)],
         item_local_id_counters: Default::default(),
         node_id_to_hir_id: IndexVec::new(),
@@ -414,11 +420,24 @@ fn with_trait_impl_ref<F>(&mut self, trait_impl_ref: &Option<TraitRef>, f: F)
         }
 
         impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> {
+            fn visit_mod(&mut self, m: &'lcx Mod, _s: Span, _attrs: &[Attribute], n: NodeId) {
+                self.lctx.modules.insert(n, hir::ModuleItems {
+                    items: BTreeSet::new(),
+                    trait_items: BTreeSet::new(),
+                    impl_items: BTreeSet::new(),
+                });
+
+                let old = self.lctx.current_module;
+                self.lctx.current_module = n;
+                visit::walk_mod(self, m);
+                self.lctx.current_module = old;
+            }
+
             fn visit_item(&mut self, item: &'lcx Item) {
                 let mut item_lowered = true;
                 self.lctx.with_hir_id_owner(item.id, |lctx| {
                     if let Some(hir_item) = lctx.lower_item(item) {
-                        lctx.items.insert(item.id, hir_item);
+                        lctx.insert_item(item.id, hir_item);
                     } else {
                         item_lowered = false;
                     }
@@ -451,6 +470,7 @@ fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
                     let id = hir::TraitItemId { node_id: item.id };
                     let hir_item = lctx.lower_trait_item(item);
                     lctx.trait_items.insert(id, hir_item);
+                    lctx.modules.get_mut(&lctx.current_module).unwrap().trait_items.insert(id);
                 });
 
                 visit::walk_trait_item(self, item);
@@ -461,6 +481,7 @@ fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
                     let id = hir::ImplItemId { node_id: item.id };
                     let hir_item = lctx.lower_impl_item(item);
                     lctx.impl_items.insert(id, hir_item);
+                    lctx.modules.get_mut(&lctx.current_module).unwrap().impl_items.insert(id);
                 });
                 visit::walk_impl_item(self, item);
             }
@@ -492,9 +513,15 @@ fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
             body_ids,
             trait_impls: self.trait_impls,
             trait_auto_impl: self.trait_auto_impl,
+            modules: self.modules,
         }
     }
 
+    fn insert_item(&mut self, id: NodeId, item: hir::Item) {
+        self.items.insert(id, item);
+        self.modules.get_mut(&self.current_module).unwrap().items.insert(id);
+    }
+
     fn allocate_hir_id_counter<T: Debug>(&mut self, owner: NodeId, debug: &T) -> LoweredNodeId {
         if self.item_local_id_counters.insert(owner, 0).is_some() {
             bug!(
@@ -1370,7 +1397,7 @@ fn lower_existential_impl_trait(
             // Insert the item into the global list. This usually happens
             // automatically for all AST items. But this existential type item
             // does not actually exist in the AST.
-            lctx.items.insert(exist_ty_id.node_id, exist_ty_item);
+            lctx.insert_item(exist_ty_id.node_id, exist_ty_item);
 
             // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
             hir::TyKind::Def(hir::ItemId { id: exist_ty_id.node_id }, lifetimes)
@@ -3026,7 +3053,7 @@ fn lower_use_tree(
                         };
                         let vis = respan(vis.span, vis_kind);
 
-                        this.items.insert(
+                        this.insert_item(
                             new_id.node_id,
                             hir::Item {
                                 id: new_id.node_id,
@@ -3133,7 +3160,7 @@ fn lower_use_tree(
                         };
                         let vis = respan(vis.span, vis_kind);
 
-                        this.items.insert(
+                        this.insert_item(
                             new_id,
                             hir::Item {
                                 id: new_id,
index 837a20ac0f2f02590b8cab93b62580817d7206d7..f61b8551927bbd659b680bb6ce1deee18868b914 100644 (file)
@@ -15,7 +15,7 @@
 use hir::map;
 use hir::{Expr, FnDecl, Node};
 use hir::intravisit::FnKind;
-use syntax::ast::{Attribute, Ident, Name, NodeId};
+use syntax::ast::{Attribute, Ident, NodeId};
 use syntax_pos::Span;
 
 /// An FnLikeNode is a Node that is like a fn, in that it has a decl
@@ -98,7 +98,7 @@ pub fn from_node(map: &map::Map<'a>, id: NodeId) -> Option<Code<'a>> {
 /// These are all the components one can extract from a fn item for
 /// use when implementing FnLikeNode operations.
 struct ItemFnParts<'a> {
-    name:     Name,
+    ident:    Ident,
     decl:     &'a ast::FnDecl,
     header:   ast::FnHeader,
     vis:      &'a ast::Visibility,
@@ -200,7 +200,7 @@ pub fn unsafety(self) -> ast::Unsafety {
 
     pub fn kind(self) -> FnKind<'a> {
         let item = |p: ItemFnParts<'a>| -> FnKind<'a> {
-            FnKind::ItemFn(p.name, p.generics, p.header, p.vis, p.attrs)
+            FnKind::ItemFn(p.ident, p.generics, p.header, p.vis, p.attrs)
         };
         let closure = |c: ClosureParts<'a>| {
             FnKind::Closure(c.attrs)
@@ -228,7 +228,7 @@ fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A where
                 ast::ItemKind::Fn(ref decl, header, ref generics, block) =>
                     item_fn(ItemFnParts {
                         id: i.id,
-                        name: i.ident.name,
+                        ident: i.ident,
                         decl: &decl,
                         body: block,
                         vis: &i.vis,
index 78acea9f588144c259f1f31bc8216af8ac531685..ae9bb37842990f393562ac56686e566e7b1aa810 100644 (file)
@@ -6,6 +6,7 @@
 use ich::Fingerprint;
 use middle::cstore::CrateStore;
 use session::CrateDisambiguator;
+use session::Session;
 use std::iter::repeat;
 use syntax::ast::{NodeId, CRATE_NODE_ID};
 use syntax::source_map::SourceMap;
@@ -92,11 +93,11 @@ fn alloc_hir_dep_nodes<'a, I>(
 }
 
 impl<'a, 'hir> NodeCollector<'a, 'hir> {
-    pub(super) fn root(krate: &'hir Crate,
+    pub(super) fn root(sess: &'a Session,
+                       krate: &'hir Crate,
                        dep_graph: &'a DepGraph,
                        definitions: &'a definitions::Definitions,
-                       mut hcx: StableHashingContext<'a>,
-                       source_map: &'a SourceMap)
+                       mut hcx: StableHashingContext<'a>)
                 -> NodeCollector<'a, 'hir> {
         let root_mod_def_path_hash = definitions.def_path_hash(CRATE_DEF_INDEX);
 
@@ -119,6 +120,7 @@ pub(super) fn root(krate: &'hir Crate,
                 trait_impls: _,
                 trait_auto_impl: _,
                 body_ids: _,
+                modules: _,
             } = *krate;
 
             alloc_hir_dep_nodes(
@@ -140,8 +142,8 @@ pub(super) fn root(krate: &'hir Crate,
 
         let mut collector = NodeCollector {
             krate,
-            source_map,
-            map: vec![],
+            source_map: sess.source_map(),
+            map: repeat(None).take(sess.current_node_id_count()).collect(),
             parent_node: CRATE_NODE_ID,
             current_signature_dep_index: root_mod_sig_dep_index,
             current_full_dep_index: root_mod_full_dep_index,
@@ -218,10 +220,6 @@ pub(super) fn finalize_and_compute_crate_hash(mut self,
 
     fn insert_entry(&mut self, id: NodeId, entry: Entry<'hir>) {
         debug!("hir_map: {:?} => {:?}", id, entry);
-        let len = self.map.len();
-        if id.as_usize() >= len {
-            self.map.extend(repeat(None).take(id.as_usize() - len + 1));
-        }
         self.map[id.as_usize()] = Some(entry);
     }
 
index a8f5f93ee6cb1714d312a8045a0778fcadb800e1..91c8c29144406739d5d8456249a19f417793724e 100644 (file)
@@ -3,19 +3,24 @@
 use syntax::ast::NodeId;
 use hir::itemlikevisit::ItemLikeVisitor;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::sync::{Lock, ParallelIterator, par_iter};
 
 pub fn check_crate<'hir>(hir_map: &hir::map::Map<'hir>) {
-    let mut outer_visitor = OuterVisitor {
-        hir_map,
-        errors: vec![],
-    };
-
     hir_map.dep_graph.assert_ignored();
 
-    hir_map.krate().visit_all_item_likes(&mut outer_visitor);
-    if !outer_visitor.errors.is_empty() {
-        let message = outer_visitor
-            .errors
+    let errors = Lock::new(Vec::new());
+
+    par_iter(&hir_map.krate().modules).for_each(|(module_id, _)| {
+        hir_map.visit_item_likes_in_module(hir_map.local_def_id(*module_id), &mut OuterVisitor {
+            hir_map,
+            errors: &errors,
+        });
+    });
+
+    let errors = errors.into_inner();
+
+    if !errors.is_empty() {
+        let message = errors
             .iter()
             .fold(String::new(), |s1, s2| s1 + "\n" + s2);
         bug!("{}", message);
@@ -26,12 +31,12 @@ struct HirIdValidator<'a, 'hir: 'a> {
     hir_map: &'a hir::map::Map<'hir>,
     owner_def_index: Option<DefIndex>,
     hir_ids_seen: FxHashMap<ItemLocalId, NodeId>,
-    errors: Vec<String>,
+    errors: &'a Lock<Vec<String>>,
 }
 
 struct OuterVisitor<'a, 'hir: 'a> {
     hir_map: &'a hir::map::Map<'hir>,
-    errors: Vec<String>,
+    errors: &'a Lock<Vec<String>>,
 }
 
 impl<'a, 'hir: 'a> OuterVisitor<'a, 'hir> {
@@ -42,7 +47,7 @@ fn new_inner_visitor(&self,
             hir_map,
             owner_def_index: None,
             hir_ids_seen: Default::default(),
-            errors: Vec::new(),
+            errors: self.errors,
         }
     }
 }
@@ -51,23 +56,25 @@ impl<'a, 'hir: 'a> ItemLikeVisitor<'hir> for OuterVisitor<'a, 'hir> {
     fn visit_item(&mut self, i: &'hir hir::Item) {
         let mut inner_visitor = self.new_inner_visitor(self.hir_map);
         inner_visitor.check(i.id, |this| intravisit::walk_item(this, i));
-        self.errors.extend(inner_visitor.errors.drain(..));
     }
 
     fn visit_trait_item(&mut self, i: &'hir hir::TraitItem) {
         let mut inner_visitor = self.new_inner_visitor(self.hir_map);
         inner_visitor.check(i.id, |this| intravisit::walk_trait_item(this, i));
-        self.errors.extend(inner_visitor.errors.drain(..));
     }
 
     fn visit_impl_item(&mut self, i: &'hir hir::ImplItem) {
         let mut inner_visitor = self.new_inner_visitor(self.hir_map);
         inner_visitor.check(i.id, |this| intravisit::walk_impl_item(this, i));
-        self.errors.extend(inner_visitor.errors.drain(..));
     }
 }
 
 impl<'a, 'hir: 'a> HirIdValidator<'a, 'hir> {
+    #[cold]
+    #[inline(never)]
+    fn error(&self, f: impl FnOnce() -> String) {
+        self.errors.lock().push(f());
+    }
 
     fn check<F: FnOnce(&mut HirIdValidator<'a, 'hir>)>(&mut self,
                                                        node_id: NodeId,
@@ -119,7 +126,7 @@ fn check<F: FnOnce(&mut HirIdValidator<'a, 'hir>)>(&mut self,
                                            local_id,
                                            self.hir_map.node_to_string(node_id)));
             }
-            self.errors.push(format!(
+            self.error(|| format!(
                 "ItemLocalIds not assigned densely in {}. \
                 Max ItemLocalId = {}, missing IDs = {:?}; seens IDs = {:?}",
                 self.hir_map.def_path(DefId::local(owner_def_index)).to_string_no_crate(),
@@ -145,14 +152,14 @@ fn visit_id(&mut self, node_id: NodeId) {
         let stable_id = self.hir_map.definitions().node_to_hir_id[node_id];
 
         if stable_id == hir::DUMMY_HIR_ID {
-            self.errors.push(format!("HirIdValidator: No HirId assigned for NodeId {}: {:?}",
+            self.error(|| format!("HirIdValidator: No HirId assigned for NodeId {}: {:?}",
                                      node_id,
                                      self.hir_map.node_to_string(node_id)));
             return;
         }
 
         if owner != stable_id.owner {
-            self.errors.push(format!(
+            self.error(|| format!(
                 "HirIdValidator: The recorded owner of {} is {} instead of {}",
                 self.hir_map.node_to_string(node_id),
                 self.hir_map.def_path(DefId::local(stable_id.owner)).to_string_no_crate(),
@@ -161,7 +168,7 @@ fn visit_id(&mut self, node_id: NodeId) {
 
         if let Some(prev) = self.hir_ids_seen.insert(stable_id.local_id, node_id) {
             if prev != node_id {
-                self.errors.push(format!(
+                self.error(|| format!(
                     "HirIdValidator: Same HirId {}/{} assigned for nodes {} and {}",
                     self.hir_map.def_path(DefId::local(stable_id.owner)).to_string_no_crate(),
                     stable_id.local_id.as_usize(),
index 5bcbeeefa50309ca72be9f10cfbf2201552693ef..869baef1f5afc9ee3c2a8f9d9b4d0cb5e70d5aff 100644 (file)
@@ -7,18 +7,21 @@
 
 use hir::def_id::{CRATE_DEF_INDEX, DefId, LocalDefId, DefIndexAddressSpace};
 
-use middle::cstore::CrateStore;
+use middle::cstore::CrateStoreDyn;
 
 use rustc_target::spec::abi::Abi;
 use rustc_data_structures::svh::Svh;
+use rustc_data_structures::sync::join;
 use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID};
 use syntax::source_map::Spanned;
 use syntax::ext::base::MacroKind;
 use syntax_pos::{Span, DUMMY_SP};
 
 use hir::*;
+use hir::itemlikevisit::ItemLikeVisitor;
 use hir::print::Nested;
 use util::nodemap::FxHashMap;
+use util::common::time;
 
 use std::io;
 use std::result::Result::Err;
@@ -506,6 +509,32 @@ pub fn krate_attrs(&self) -> &'hir [ast::Attribute] {
         &self.forest.krate.attrs
     }
 
+    pub fn visit_item_likes_in_module<V>(&self, module: DefId, visitor: &mut V)
+        where V: ItemLikeVisitor<'hir>
+    {
+        let node_id = self.as_local_node_id(module).unwrap();
+
+        // Read the module so we'll be re-executed if new items
+        // appear immediately under in the module. If some new item appears
+        // in some nested item in the module, we'll be re-executed due to reads
+        // in the expect_* calls the loops below
+        self.read(node_id);
+
+        let module = &self.forest.krate.modules[&node_id];
+
+        for id in &module.items {
+            visitor.visit_item(self.expect_item(*id));
+        }
+
+        for id in &module.trait_items {
+            visitor.visit_trait_item(self.expect_trait_item(id.node_id));
+        }
+
+        for id in &module.impl_items {
+            visitor.visit_impl_item(self.expect_impl_item(id.node_id));
+        }
+    }
+
     /// Retrieve the Node corresponding to `id`, panicking if it cannot
     /// be found.
     pub fn get(&self, id: NodeId) -> Node<'hir> {
@@ -1018,26 +1047,32 @@ impl Named for TraitItem { fn name(&self) -> Name { self.ident.name } }
 impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } }
 
 pub fn map_crate<'hir>(sess: &::session::Session,
-                       cstore: &dyn CrateStore,
-                       forest: &'hir mut Forest,
+                       cstore: &CrateStoreDyn,
+                       forest: &'hir Forest,
                        definitions: &'hir Definitions)
                        -> Map<'hir> {
-    let (map, crate_hash) = {
+    let ((map, crate_hash), hir_to_node_id) = join(|| {
         let hcx = ::ich::StableHashingContext::new(sess, &forest.krate, definitions, cstore);
 
-        let mut collector = NodeCollector::root(&forest.krate,
+        let mut collector = NodeCollector::root(sess,
+                                                &forest.krate,
                                                 &forest.dep_graph,
                                                 &definitions,
-                                                hcx,
-                                                sess.source_map());
+                                                hcx);
         intravisit::walk_crate(&mut collector, &forest.krate);
 
         let crate_disambiguator = sess.local_crate_disambiguator();
         let cmdline_args = sess.opts.dep_tracking_hash();
-        collector.finalize_and_compute_crate_hash(crate_disambiguator,
-                                                  cstore,
-                                                  cmdline_args)
-    };
+        collector.finalize_and_compute_crate_hash(
+            crate_disambiguator,
+            cstore,
+            cmdline_args
+        )
+    }, || {
+        // Build the reverse mapping of `node_to_hir_id`.
+        definitions.node_to_hir_id.iter_enumerated()
+                    .map(|(node_id, &hir_id)| (hir_id, node_id)).collect()
+    });
 
     if log_enabled!(::log::Level::Debug) {
         // This only makes sense for ordered stores; note the
@@ -1051,10 +1086,6 @@ pub fn map_crate<'hir>(sess: &::session::Session,
               entries, vector_length, (entries as f64 / vector_length as f64) * 100.);
     }
 
-    // Build the reverse mapping of `node_to_hir_id`.
-    let hir_to_node_id = definitions.node_to_hir_id.iter_enumerated()
-        .map(|(node_id, &hir_id)| (hir_id, node_id)).collect();
-
     let map = Map {
         forest,
         dep_graph: forest.dep_graph.clone(),
@@ -1064,7 +1095,9 @@ pub fn map_crate<'hir>(sess: &::session::Session,
         definitions,
     };
 
-    hir_id_validator::check_crate(&map);
+    time(sess, "validate hir map", || {
+        hir_id_validator::check_crate(&map);
+    });
 
     map
 }
index 7e87171a5edf7579adb492fcd076d2b20e19a2fd..fc4bd05476f6ceb4662949ca44111a491411eb71 100644 (file)
@@ -33,7 +33,7 @@
 use rustc_data_structures::thin_vec::ThinVec;
 
 use serialize::{self, Encoder, Encodable, Decoder, Decodable};
-use std::collections::BTreeMap;
+use std::collections::{BTreeSet, BTreeMap};
 use std::fmt;
 
 /// HIR doesn't commit to a concrete storage type and has its own alias for a vector.
@@ -676,6 +676,15 @@ pub struct WhereEqPredicate {
     pub rhs_ty: P<Ty>,
 }
 
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+pub struct ModuleItems {
+    // Use BTreeSets here so items are in the same order as in the
+    // list of all items in Crate
+    pub items: BTreeSet<NodeId>,
+    pub trait_items: BTreeSet<TraitItemId>,
+    pub impl_items: BTreeSet<ImplItemId>,
+}
+
 /// The top-level data structure that stores the entire contents of
 /// the crate currently being compiled.
 ///
@@ -708,6 +717,10 @@ pub struct Crate {
     /// in the crate, you should iterate over this list rather than the keys
     /// of bodies.
     pub body_ids: Vec<BodyId>,
+
+    /// A list of modules written out in the order in which they
+    /// appear in the crate. This includes the main crate module.
+    pub modules: BTreeMap<NodeId, ModuleItems>,
 }
 
 impl Crate {
@@ -2408,6 +2421,7 @@ pub struct TraitCandidate {
 
 
 pub fn provide(providers: &mut Providers<'_>) {
+    check_attr::provide(providers);
     providers.describe_def = map::describe_def;
 }
 
index 4cce8343c02c871f83efe94c4c7f61ac84f92a5d..2995b25308d4c9f455565cf6278f92fa3e3fd988 100644 (file)
@@ -487,6 +487,11 @@ fn check_and_note_conflicting_crates(
 
     fn note_error_origin(&self, err: &mut DiagnosticBuilder<'tcx>, cause: &ObligationCause<'tcx>) {
         match cause.code {
+            ObligationCauseCode::MatchExpressionArmPattern { span, ty } => {
+                if ty.is_suggestable() {  // don't show type `_`
+                    err.span_label(span, format!("this match expression has type `{}`", ty));
+                }
+            }
             ObligationCauseCode::MatchExpressionArm { arm_span, source } => match source {
                 hir::MatchSource::IfLetDesugar { .. } => {
                     let msg = "`if let` arm with an incompatible type";
@@ -506,6 +511,18 @@ fn note_error_origin(&self, err: &mut DiagnosticBuilder<'tcx>, cause: &Obligatio
                     }
                 }
             },
+            ObligationCauseCode::IfExpression { then, outer, semicolon } => {
+                err.span_label(then, "expected because of this");
+                outer.map(|sp| err.span_label(sp, "if and else have incompatible types"));
+                if let Some(sp) = semicolon {
+                    err.span_suggestion_short_with_applicability(
+                        sp,
+                        "consider removing this semicolon",
+                        String::new(),
+                        Applicability::MachineApplicable,
+                    );
+                }
+            }
             _ => (),
         }
     }
@@ -1455,7 +1472,7 @@ fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode {
                 }
                 _ => "match arms have incompatible types",
             }),
-            IfExpression => Error0308("if and else have incompatible types"),
+            IfExpression { .. } => Error0308("if and else have incompatible types"),
             IfExpressionWithNoElse => Error0317("if may be missing an else clause"),
             MainFunctionType => Error0580("main function has wrong type"),
             StartFunctionType => Error0308("start function has wrong type"),
@@ -1483,7 +1500,7 @@ fn as_requirement_str(&self) -> &'static str {
                 hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types",
                 _ => "match arms have compatible types",
             },
-            IfExpression => "if and else have compatible types",
+            IfExpression { .. } => "if and else have compatible types",
             IfExpressionWithNoElse => "if missing an else returns ()",
             MainFunctionType => "`main` function has the correct type",
             StartFunctionType => "`start` function has the correct type",
index dbf8f270ab0c988fb88e6ebb7c4ffddbbd90ad3b..39ce8cc621b49d9215de6dfe3998085a937eead7 100644 (file)
@@ -13,6 +13,7 @@
     Direction, Graph, NodeIndex, INCOMING, OUTGOING,
 };
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
+use smallvec::SmallVec;
 use std::fmt;
 use std::u32;
 use ty::fold::TypeFoldable;
@@ -190,19 +191,24 @@ fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
             match *constraint {
                 Constraint::RegSubVar(a_region, b_vid) => {
                     let b_data = var_values.value_mut(b_vid);
-                    self.expand_node(a_region, b_vid, b_data)
+                    (self.expand_node(a_region, b_vid, b_data), false)
                 }
                 Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) {
-                    VarValue::ErrorValue => false,
+                    VarValue::ErrorValue => (false, false),
                     VarValue::Value(a_region) => {
                         let b_node = var_values.value_mut(b_vid);
-                        self.expand_node(a_region, b_vid, b_node)
+                        let changed = self.expand_node(a_region, b_vid, b_node);
+                        let retain = match *b_node {
+                            VarValue::Value(ReStatic) | VarValue::ErrorValue => false,
+                            _ => true
+                        };
+                        (changed, retain)
                     }
                 },
                 Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => {
                     // These constraints are checked after expansion
                     // is done, in `collect_errors`.
-                    false
+                    (false, false)
                 }
             }
         })
@@ -268,6 +274,13 @@ fn expand_node(
 
     fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
         let tcx = self.tcx();
+
+        // Equal scopes can show up quite often, if the fixed point
+        // iteration converges slowly, skip them
+        if a == b {
+            return a;
+        }
+
         match (a, b) {
             (&ty::ReClosureBound(..), _)
             | (_, &ty::ReClosureBound(..))
@@ -710,21 +723,23 @@ fn process_edges<'tcx>(
 
     fn iterate_until_fixed_point<F>(&self, tag: &str, mut body: F)
     where
-        F: FnMut(&Constraint<'tcx>, &SubregionOrigin<'tcx>) -> bool,
+        F: FnMut(&Constraint<'tcx>, &SubregionOrigin<'tcx>) -> (bool, bool),
     {
+        let mut constraints: SmallVec<[_; 16]> = self.data.constraints.iter().collect();
         let mut iteration = 0;
         let mut changed = true;
         while changed {
             changed = false;
             iteration += 1;
             debug!("---- {} Iteration {}{}", "#", tag, iteration);
-            for (constraint, origin) in &self.data.constraints {
-                let edge_changed = body(constraint, origin);
+            constraints.retain(|(constraint, origin)| {
+                let (edge_changed, retain) = body(constraint, origin);
                 if edge_changed {
                     debug!("Updated due to constraint {:?}", constraint);
                     changed = true;
                 }
-            }
+                retain
+            });
         }
         debug!("---- {} Complete after {} iteration(s)", tag, iteration);
     }
index b2a924ac1989562c31b77463d467d33a43137164..fba9b8527677ca1538d0250708d5fddb671eff29 100644 (file)
@@ -60,7 +60,6 @@
 #![feature(test)]
 #![feature(in_band_lifetimes)]
 #![feature(crate_visibility_modifier)]
-#![feature(transpose_result)]
 
 #![recursion_limit="512"]
 
index 22854382df15c07c624b2741c678d99542cee877..c428ff1bd1b37bc9b1ea4f68534377babdbce1b3 100644 (file)
 
 declare_lint! {
     pub IRREFUTABLE_LET_PATTERNS,
-    Deny,
+    Warn,
     "detects irrefutable patterns in if-let and while-let statements"
 }
 
index 43cb89ccf6c0fce11b2677f2a9a0c9a5ef97f16a..918e286c435bc2ba183f36c1d3024208cdf1c880 100644 (file)
@@ -8,6 +8,8 @@
 use hir::def::Def;
 use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
 use hir::intravisit::{self, Visitor, NestedVisitorMap};
+use ty::query::Providers;
+use ty::query::queries;
 use middle::privacy::AccessLevels;
 use session::{DiagnosticMessageId, Session};
 use syntax::symbol::Symbol;
@@ -454,11 +456,23 @@ pub fn local_deprecation_entry(&self, id: HirId) -> Option<DeprecationEntry> {
     }
 }
 
+pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+    for &module in tcx.hir().krate().modules.keys() {
+        queries::check_mod_unstable_api_usage::ensure(tcx, tcx.hir().local_def_id(module));
+    }
+}
+
 /// Cross-references the feature names of unstable APIs with enabled
 /// features and possibly prints errors.
-pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    let mut checker = Checker { tcx };
-    tcx.hir().krate().visit_all_item_likes(&mut checker.as_deep_visitor());
+fn check_mod_unstable_api_usage<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
+    tcx.hir().visit_item_likes_in_module(module_def_id, &mut Checker { tcx }.as_deep_visitor());
+}
+
+pub fn provide(providers: &mut Providers<'_>) {
+    *providers = Providers {
+        check_mod_unstable_api_usage,
+        ..*providers
+    };
 }
 
 /// Check whether an item marked with `deprecated(since="X")` is currently
index c6e68ba379ec378aa0b1cfa85616ddd78181e6f4..19f1c7a18fad14ebf0c4f2f2c2269cbff1de984c 100644 (file)
@@ -114,13 +114,6 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
     sysroot.join(&relative_target_lib_path(sysroot, target_triple))
 }
 
-pub fn target_lib_path(target_triple: &str) -> PathBuf {
-    let mut p = PathBuf::from(RUST_LIB_DIR);
-    p.push(target_triple);
-    p.push("lib");
-    p
-}
-
 pub fn get_or_default_sysroot() -> PathBuf {
     // Follow symlinks.  If the resolved path is relative, make it absolute.
     fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> {
index 5c977d5969e16e38a9a3e9df0de3d3aef60fa65e..fa0dfc4b38c8c4837d425321cf12377a97ac541c 100644 (file)
 use util::common::ProfileQueriesMsg;
 
 use rustc_data_structures::base_n;
-use rustc_data_structures::sync::{self, Lrc, Lock, LockCell, OneThread, Once, RwLock};
+use rustc_data_structures::sync::{
+    self, Lrc, Lock, OneThread, Once, RwLock, AtomicU64, AtomicUsize, Ordering,
+    Ordering::SeqCst,
+};
 
 use errors::{self, DiagnosticBuilder, DiagnosticId, Applicability};
 use errors::emitter::{Emitter, EmitterWriter};
 use std::path::PathBuf;
 use std::time::Duration;
 use std::sync::mpsc;
-use std::sync::atomic::{AtomicUsize, Ordering};
 
 mod code_stats;
 pub mod config;
 pub mod filesearch;
 pub mod search_paths;
 
+pub struct OptimizationFuel {
+    /// If -zfuel=crate=n is specified, initially set to n. Otherwise 0.
+    remaining: u64,
+    /// We're rejecting all further optimizations.
+    out_of_fuel: bool,
+}
+
 /// Represents the data associated with a compilation
 /// session for a single crate.
 pub struct Session {
@@ -137,16 +146,15 @@ pub struct Session {
 
     /// If -zfuel=crate=n is specified, Some(crate).
     optimization_fuel_crate: Option<String>,
-    /// If -zfuel=crate=n is specified, initially set to n. Otherwise 0.
-    optimization_fuel_limit: LockCell<u64>,
-    /// We're rejecting all further optimizations.
-    out_of_fuel: LockCell<bool>,
+
+    /// Tracks fuel info if If -zfuel=crate=n is specified
+    optimization_fuel: Lock<OptimizationFuel>,
 
     // The next two are public because the driver needs to read them.
     /// If -zprint-fuel=crate, Some(crate).
     pub print_fuel_crate: Option<String>,
     /// Always set to zero and incremented so that we can print fuel expended by a crate.
-    pub print_fuel: LockCell<u64>,
+    pub print_fuel: AtomicU64,
 
     /// Loaded up early on in the initialization of this `Session` to avoid
     /// false positives about a job server in our environment.
@@ -399,6 +407,9 @@ pub fn reserve_node_ids(&self, count: usize) -> ast::NodeId {
     pub fn next_node_id(&self) -> NodeId {
         self.reserve_node_ids(1)
     }
+    pub(crate) fn current_node_id_count(&self) -> usize {
+        self.next_node_id.get().as_u32() as usize
+    }
     pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler {
         &self.parse_sess.span_diagnostic
     }
@@ -871,20 +882,20 @@ pub fn consider_optimizing<T: Fn() -> String>(&self, crate_name: &str, msg: T) -
         if let Some(ref c) = self.optimization_fuel_crate {
             if c == crate_name {
                 assert_eq!(self.query_threads(), 1);
-                let fuel = self.optimization_fuel_limit.get();
-                ret = fuel != 0;
-                if fuel == 0 && !self.out_of_fuel.get() {
+                let mut fuel = self.optimization_fuel.lock();
+                ret = fuel.remaining != 0;
+                if fuel.remaining == 0 && !fuel.out_of_fuel {
                     eprintln!("optimization-fuel-exhausted: {}", msg());
-                    self.out_of_fuel.set(true);
-                } else if fuel > 0 {
-                    self.optimization_fuel_limit.set(fuel - 1);
+                    fuel.out_of_fuel = true;
+                } else if fuel.remaining > 0 {
+                    fuel.remaining -= 1;
                 }
             }
         }
         if let Some(ref c) = self.print_fuel_crate {
             if c == crate_name {
                 assert_eq!(self.query_threads(), 1);
-                self.print_fuel.set(self.print_fuel.get() + 1);
+                self.print_fuel.fetch_add(1, SeqCst);
             }
         }
         ret
@@ -1134,10 +1145,12 @@ pub fn build_session_(
         local_crate_source_file.map(|path| file_path_mapping.map_prefix(path).0);
 
     let optimization_fuel_crate = sopts.debugging_opts.fuel.as_ref().map(|i| i.0.clone());
-    let optimization_fuel_limit =
-        LockCell::new(sopts.debugging_opts.fuel.as_ref().map(|i| i.1).unwrap_or(0));
+    let optimization_fuel = Lock::new(OptimizationFuel {
+        remaining: sopts.debugging_opts.fuel.as_ref().map(|i| i.1).unwrap_or(0),
+        out_of_fuel: false,
+    });
     let print_fuel_crate = sopts.debugging_opts.print_fuel.clone();
-    let print_fuel = LockCell::new(0);
+    let print_fuel = AtomicU64::new(0);
 
     let working_dir = env::current_dir().unwrap_or_else(|e|
         p_s.span_diagnostic
@@ -1199,10 +1212,9 @@ pub fn build_session_(
         },
         code_stats: Default::default(),
         optimization_fuel_crate,
-        optimization_fuel_limit,
+        optimization_fuel,
         print_fuel_crate,
         print_fuel,
-        out_of_fuel: LockCell::new(false),
         // 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
index 7ce5960b9b3d6b38e9d2149b4d5c48b6de5d51cc..367a7eacdfcaf50dd4e61a592f163f65a79e82ad 100644 (file)
@@ -1444,15 +1444,15 @@ fn note_obligation_cause_code<T>(&self,
         match *cause_code {
             ObligationCauseCode::ExprAssignable |
             ObligationCauseCode::MatchExpressionArm { .. } |
-            ObligationCauseCode::IfExpression |
+            ObligationCauseCode::MatchExpressionArmPattern { .. } |
+            ObligationCauseCode::IfExpression { .. } |
             ObligationCauseCode::IfExpressionWithNoElse |
             ObligationCauseCode::MainFunctionType |
             ObligationCauseCode::StartFunctionType |
             ObligationCauseCode::IntrinsicType |
             ObligationCauseCode::MethodReceiver |
             ObligationCauseCode::ReturnNoExpression |
-            ObligationCauseCode::MiscObligation => {
-            }
+            ObligationCauseCode::MiscObligation => {}
             ObligationCauseCode::SliceOrArrayElem => {
                 err.note("slice and array elements must have `Sized` type");
             }
index b42d742b7f84139baa982af89134866fbefd245f..68383bef37a6a90d4f40cc93c43182ea7b40df94 100644 (file)
@@ -220,11 +220,20 @@ pub enum ObligationCauseCode<'tcx> {
     ExprAssignable,
 
     /// Computing common supertype in the arms of a match expression
-    MatchExpressionArm { arm_span: Span,
-                         source: hir::MatchSource },
+    MatchExpressionArm {
+        arm_span: Span,
+        source: hir::MatchSource,
+    },
+
+    /// Computing common supertype in the pattern guard for the arms of a match expression
+    MatchExpressionArmPattern { span: Span, ty: Ty<'tcx> },
 
     /// Computing common supertype in an if expression
-    IfExpression,
+    IfExpression {
+        then: Span,
+        outer: Option<Span>,
+        semicolon: Option<Span>,
+    },
 
     /// Computing common supertype of an if expression with no else counter-part
     IfExpressionWithNoElse,
index 00967242bed0e93dbd80b0e628b47b8d5e50b662..c37dc2a855ed0ff0d4b7a0e64a2e49cd9367641b 100644 (file)
@@ -252,6 +252,7 @@ fn object_safety_violation_for_method(self,
                                           method: &ty::AssociatedItem)
                                           -> Option<MethodViolationCode>
     {
+        debug!("object_safety_violation_for_method({:?}, {:?})", trait_def_id, method);
         // Any method that has a `Self : Sized` requisite is otherwise
         // exempt from the regulations.
         if self.generics_require_sized_self(method.def_id) {
@@ -270,6 +271,7 @@ pub fn is_vtable_safe_method(self,
                                  method: &ty::AssociatedItem)
                                  -> bool
     {
+        debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method);
         // Any method that has a `Self : Sized` requisite can't be called.
         if self.generics_require_sized_self(method.def_id) {
             return false;
@@ -402,6 +404,7 @@ fn virtual_call_violation_for_method(self,
     fn receiver_for_self_ty(
         self, receiver_ty: Ty<'tcx>, self_ty: Ty<'tcx>, method_def_id: DefId
     ) -> Ty<'tcx> {
+        debug!("receiver_for_self_ty({:?}, {:?}, {:?})", receiver_ty, self_ty, method_def_id);
         let substs = Substs::for_item(self, method_def_id, |param, _| {
             if param.index == 0 {
                 self_ty.into()
@@ -410,7 +413,10 @@ fn receiver_for_self_ty(
             }
         });
 
-        receiver_ty.subst(self, substs)
+        let result = receiver_ty.subst(self, substs);
+        debug!("receiver_for_self_ty({:?}, {:?}, {:?}) = {:?}",
+               receiver_ty, self_ty, method_def_id, result);
+        result
     }
 
     /// creates the object type for the current trait. For example,
@@ -426,18 +432,26 @@ fn object_ty_for_trait(self, trait_def_id: DefId, lifetime: ty::Region<'tcx>) ->
         );
 
         let mut associated_types = traits::supertraits(self, ty::Binder::dummy(trait_ref))
-            .flat_map(|trait_ref| self.associated_items(trait_ref.def_id()))
-            .filter(|item| item.kind == ty::AssociatedKind::Type)
+            .flat_map(|super_trait_ref| {
+                self.associated_items(super_trait_ref.def_id())
+                    .map(move |item| (super_trait_ref, item))
+            })
+            .filter(|(_, item)| item.kind == ty::AssociatedKind::Type)
             .collect::<Vec<_>>();
 
         // existential predicates need to be in a specific order
-        associated_types.sort_by_cached_key(|item| self.def_path_hash(item.def_id));
-
-        let projection_predicates = associated_types.into_iter().map(|item| {
+        associated_types.sort_by_cached_key(|(_, item)| self.def_path_hash(item.def_id));
+
+        let projection_predicates = associated_types.into_iter().map(|(super_trait_ref, item)| {
+            // We *can* get bound lifetimes here in cases like
+            // `trait MyTrait: for<'s> OtherTrait<&'s T, Output=bool>`.
+            //
+            // binder moved to (*)...
+            let super_trait_ref = super_trait_ref.skip_binder();
             ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
-                ty: self.mk_projection(item.def_id, trait_ref.substs),
+                ty: self.mk_projection(item.def_id, super_trait_ref.substs),
                 item_def_id: item.def_id,
-                substs: trait_ref.substs,
+                substs: super_trait_ref.substs,
             })
         });
 
@@ -446,7 +460,8 @@ fn object_ty_for_trait(self, trait_def_id: DefId, lifetime: ty::Region<'tcx>) ->
         );
 
         let object_ty = self.mk_dynamic(
-            ty::Binder::dummy(existential_predicates),
+            // (*) ... binder re-introduced here
+            ty::Binder::bind(existential_predicates),
             lifetime,
         );
 
index ae2b83e105773ac3c31b8df5cc83c3e842edf339..2f5df022218fe3fd4e71c6d0ec0f230f2785b5d5 100644 (file)
@@ -517,7 +517,14 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
                 arm_span,
                 source: source,
             }),
-            super::IfExpression => Some(super::IfExpression),
+            super::MatchExpressionArmPattern { span, ty } => {
+                tcx.lift(&ty).map(|ty| super::MatchExpressionArmPattern { span, ty })
+            }
+            super::IfExpression { then, outer, semicolon } => Some(super::IfExpression {
+                then,
+                outer,
+                semicolon,
+            }),
             super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
             super::MainFunctionType => Some(super::MainFunctionType),
             super::StartFunctionType => Some(super::StartFunctionType),
index 6c377941dad1966526bbeb794e22aa189ecf363a..d69219efbd8847a2d519f1a3777ae15a46d242d5 100644 (file)
@@ -59,6 +59,7 @@
 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;
@@ -168,7 +169,7 @@ fn intern_ty(
 
                 // Make sure we don't end up with inference
                 // types/regions in the global interner
-                if local as *const _ as usize == global as *const _ as usize {
+                if ptr::eq(local, global) {
                     bug!("Attempted to intern `{:?}` which contains \
                         inference types/regions in the global type context",
                         &ty_struct);
@@ -417,6 +418,12 @@ pub struct TypeckTables<'tcx> {
     /// All the existential types that are restricted to concrete types
     /// by this function
     pub concrete_existential_types: FxHashMap<DefId, Ty<'tcx>>,
+
+    /// Given the closure ID this map provides the list of UpvarIDs used by it.
+    /// The upvarID contains the HIR node ID and it also contains the full path
+    /// leading to the member of the struct or tuple that is used instead of the
+    /// entire variable.
+    pub upvar_list: ty::UpvarListMap,
 }
 
 impl<'tcx> TypeckTables<'tcx> {
@@ -441,6 +448,7 @@ pub fn empty(local_id_root: Option<DefId>) -> TypeckTables<'tcx> {
             tainted_by_errors: false,
             free_region_map: Default::default(),
             concrete_existential_types: Default::default(),
+            upvar_list: Default::default(),
         }
     }
 
@@ -741,6 +749,8 @@ fn hash_stable<W: StableHasherResult>(&self,
             tainted_by_errors,
             ref free_region_map,
             ref concrete_existential_types,
+            ref upvar_list,
+
         } = *self;
 
         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
@@ -783,6 +793,7 @@ fn hash_stable<W: StableHasherResult>(&self,
             tainted_by_errors.hash_stable(hcx, hasher);
             free_region_map.hash_stable(hcx, hasher);
             concrete_existential_types.hash_stable(hcx, hasher);
+            upvar_list.hash_stable(hcx, hasher);
         })
     }
 }
@@ -1125,9 +1136,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 {
-        let local = self.interners as *const _;
-        let global = &self.global_interners as *const _;
-        local as usize == global as usize
+        ptr::eq(self.interners, &self.global_interners)
     }
 
     /// Create a type context and call the closure with a `TyCtxt` reference
@@ -1248,7 +1257,11 @@ pub fn create_and_enter<F, R>(s: &'tcx Session,
 
         sync::assert_send_val(&gcx);
 
-        tls::enter_global(gcx, f)
+        let r = tls::enter_global(gcx, f);
+
+        gcx.queries.record_computed_queries(s);
+
+        r
     }
 
     pub fn consider_optimizing<T: Fn() -> String>(&self, msg: T) -> bool {
@@ -1669,8 +1682,9 @@ pub fn enter_local<'tcx, F, R>(
             let new_icx = ty::tls::ImplicitCtxt {
                 tcx,
                 query: icx.query.clone(),
+                diagnostics: icx.diagnostics,
                 layout_depth: icx.layout_depth,
-                task: icx.task,
+                task_deps: icx.task_deps,
             };
             ty::tls::enter_context(&new_icx, |_| {
                 f(tcx)
@@ -1773,12 +1787,14 @@ pub mod tls {
     use std::fmt;
     use std::mem;
     use std::marker::PhantomData;
+    use std::ptr;
     use syntax_pos;
     use ty::query;
     use errors::{Diagnostic, TRACK_DIAGNOSTICS};
     use rustc_data_structures::OnDrop;
     use rustc_data_structures::sync::{self, Lrc, Lock};
-    use dep_graph::OpenTask;
+    use rustc_data_structures::thin_vec::ThinVec;
+    use dep_graph::TaskDeps;
 
     #[cfg(not(parallel_queries))]
     use std::cell::Cell;
@@ -1797,16 +1813,20 @@ pub struct ImplicitCtxt<'a, 'gcx: 'tcx, 'tcx> {
         /// by `enter_local` with a new local interner
         pub tcx: TyCtxt<'tcx, 'gcx, 'tcx>,
 
-        /// The current query job, if any. This is updated by start_job in
+        /// The current query job, if any. This is updated by JobOwner::start in
         /// ty::query::plumbing when executing a query
         pub query: Option<Lrc<query::QueryJob<'gcx>>>,
 
+        /// Where to store diagnostics for the current query job, if any.
+        /// This is updated by JobOwner::start in ty::query::plumbing when executing a query
+        pub diagnostics: Option<&'a Lock<ThinVec<Diagnostic>>>,
+
         /// Used to prevent layout from recursing too deeply.
         pub layout_depth: usize,
 
         /// The current dep graph task. This is used to add dependencies to queries
         /// when executing them
-        pub task: &'a OpenTask,
+        pub task_deps: Option<&'a Lock<TaskDeps>>,
     }
 
     /// Sets Rayon's thread local variable which is preserved for Rayon jobs
@@ -1866,8 +1886,9 @@ fn span_debug(span: syntax_pos::Span, f: &mut fmt::Formatter<'_>) -> fmt::Result
     fn track_diagnostic(diagnostic: &Diagnostic) {
         with_context_opt(|icx| {
             if let Some(icx) = icx {
-                if let Some(ref query) = icx.query {
-                    query.diagnostics.lock().push(diagnostic.clone());
+                if let Some(ref diagnostics) = icx.diagnostics {
+                    let mut diagnostics = diagnostics.lock();
+                    diagnostics.extend(Some(diagnostic.clone()));
                 }
             }
         })
@@ -1934,8 +1955,9 @@ pub fn enter_global<'gcx, F, R>(gcx: &'gcx GlobalCtxt<'gcx>, f: F) -> R
             let icx = ImplicitCtxt {
                 tcx,
                 query: None,
+                diagnostics: None,
                 layout_depth: 0,
-                task: &OpenTask::Ignore,
+                task_deps: None,
             };
             enter_context(&icx, |_| {
                 f(tcx)
@@ -1963,9 +1985,10 @@ pub unsafe fn with_global<F, R>(f: F) -> R
         };
         let icx = ImplicitCtxt {
             query: None,
+            diagnostics: None,
             tcx,
             layout_depth: 0,
-            task: &OpenTask::Ignore,
+            task_deps: None,
         };
         enter_context(&icx, |_| f(tcx))
     }
@@ -2007,8 +2030,7 @@ pub fn with_related_context<'a, 'gcx, 'tcx1, F, R>(tcx: TyCtxt<'a, 'gcx, 'tcx1>,
     {
         with_context(|context| {
             unsafe {
-                let gcx = tcx.gcx as *const _ as usize;
-                assert!(context.tcx.gcx as *const _ as usize == gcx);
+                assert!(ptr::eq(context.tcx.gcx, tcx.gcx));
                 let context: &ImplicitCtxt<'_, '_, '_> = mem::transmute(context);
                 f(context)
             }
@@ -2026,10 +2048,8 @@ pub fn with_fully_related_context<'a, 'gcx, 'tcx, F, R>(tcx: TyCtxt<'a, 'gcx, 't
     {
         with_context(|context| {
             unsafe {
-                let gcx = tcx.gcx as *const _ as usize;
-                let interners = tcx.interners as *const _ as usize;
-                assert!(context.tcx.gcx as *const _ as usize == gcx);
-                assert!(context.tcx.interners as *const _ as usize == 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)
             }
@@ -2930,9 +2950,6 @@ fn intern_with<I: Iterator<Item=Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> S
 }
 
 pub fn provide(providers: &mut ty::query::Providers<'_>) {
-    // FIXME(#44234): almost all of these queries have no sub-queries and
-    // therefore no actual inputs, they're just reading tables calculated in
-    // resolve! Does this work? Unsure! That's what the issue is about.
     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();
     providers.crate_name = |tcx, id| {
index 171c53b7b20ba7e56082b85c2257a200327e325b..1162bff852cbba232b33eb90b188b5c45bfd3e17 100644 (file)
@@ -1842,7 +1842,11 @@ fn find_niche(&self, layout: TyLayout<'tcx>) -> Result<Option<Niche>, LayoutErro
                 return Ok(None);
             }
         }
-        if let FieldPlacement::Array { .. } = layout.fields {
+        if let FieldPlacement::Array { count: original_64_bit_count, .. } = layout.fields {
+            // rust-lang/rust#57038: avoid ICE within FieldPlacement::count when count too big
+            if original_64_bit_count > usize::max_value() as u64 {
+                return Err(LayoutError::SizeOverflow(layout.ty));
+            }
             if layout.fields.count() > 0 {
                 return self.find_niche(layout.field(self, 0)?);
             } else {
index a2c96e7cf9f662d1897c7010002a878023c5cdca..cfd99948e4370424f991da6d61dc16a159006182 100644 (file)
@@ -808,6 +808,7 @@ pub struct UpvarBorrow<'tcx> {
     pub region: ty::Region<'tcx>,
 }
 
+pub type UpvarListMap = FxHashMap<DefId, Vec<UpvarId>>;
 pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;
 
 #[derive(Copy, Clone)]
index 3464464aa229c9cc77dd5f0b47c26318dffd763b..ca5d1f6bd32036525e1d8fce04381f751a366bfe 100644 (file)
@@ -68,11 +68,56 @@ impl<'tcx, M: QueryAccessors<'tcx, Key=DefId>> QueryDescription<'tcx> for M {
             format!("processing `{}`", tcx.item_path_str(def_id)).into()
         } else {
             let name = unsafe { ::std::intrinsics::type_name::<M>() };
-            format!("processing `{}` applied to `{:?}`", name, def_id).into()
+            format!("processing {:?} with query `{}`", def_id, name).into()
         }
     }
 }
 
+impl<'tcx> QueryDescription<'tcx> for queries::check_mod_attrs<'tcx> {
+    fn describe(
+        tcx: TyCtxt<'_, '_, '_>,
+        key: DefId,
+    ) -> Cow<'static, str> {
+        format!("checking attributes in {}", key.describe_as_module(tcx)).into()
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::check_mod_unstable_api_usage<'tcx> {
+    fn describe(
+        tcx: TyCtxt<'_, '_, '_>,
+        key: DefId,
+    ) -> Cow<'static, str> {
+        format!("checking for unstable API usage in {}", key.describe_as_module(tcx)).into()
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::check_mod_loops<'tcx> {
+    fn describe(
+        tcx: TyCtxt<'_, '_, '_>,
+        key: DefId,
+    ) -> Cow<'static, str> {
+        format!("checking loops in {}", key.describe_as_module(tcx)).into()
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::check_mod_item_types<'tcx> {
+    fn describe(
+        tcx: TyCtxt<'_, '_, '_>,
+        key: DefId,
+    ) -> Cow<'static, str> {
+        format!("checking item types in {}", key.describe_as_module(tcx)).into()
+    }
+}
+
+impl<'tcx> QueryDescription<'tcx> for queries::collect_mod_item_types<'tcx> {
+    fn describe(
+        tcx: TyCtxt<'_, '_, '_>,
+        key: DefId,
+    ) -> Cow<'static, str> {
+        format!("collecting item types in {}", key.describe_as_module(tcx)).into()
+    }
+}
+
 impl<'tcx> QueryDescription<'tcx> for queries::normalize_projection_ty<'tcx> {
     fn describe(
         _tcx: TyCtxt<'_, '_, '_>,
index 0063794727fd2c31e9acbc35cf6f3f045e07a997..d794429a8a7064cb12e1a3f4ac8b3f487359663e 100644 (file)
@@ -14,7 +14,6 @@
     config::QueryDescription,
 };
 use ty::context::TyCtxt;
-use errors::Diagnostic;
 use std::process;
 use std::{fmt, ptr};
 
@@ -54,9 +53,6 @@ pub struct QueryJob<'tcx> {
     /// The parent query job which created this job and is implicitly waiting on it.
     pub parent: Option<Lrc<QueryJob<'tcx>>>,
 
-    /// Diagnostic messages which are emitted while the query executes
-    pub diagnostics: Lock<Vec<Diagnostic>>,
-
     /// The latch which is used to wait on this job
     #[cfg(parallel_queries)]
     latch: QueryLatch<'tcx>,
@@ -66,7 +62,6 @@ impl<'tcx> QueryJob<'tcx> {
     /// Creates a new query job
     pub fn new(info: QueryInfo<'tcx>, parent: Option<Lrc<QueryJob<'tcx>>>) -> Self {
         QueryJob {
-            diagnostics: Lock::new(Vec::new()),
             info,
             parent,
             #[cfg(parallel_queries)]
index 99dd3569491bc2772f8a469cd91f8b7c3bb6bda8..39d76ceed9507fc7930e038193562438b40197a0 100644 (file)
@@ -42,6 +42,7 @@
 use util::nodemap::{DefIdSet, DefIdMap, ItemLocalSet};
 use util::common::{ErrorReported};
 use util::profiling::ProfileCategory::*;
+use session::Session;
 
 use rustc_data_structures::bit_set::BitSet;
 use rustc_data_structures::indexed_vec::IndexVec;
     },
 
     Other {
+        /// Checks the attributes in the module
+        [] fn check_mod_attrs: CheckModAttrs(DefId) -> (),
+
+        [] fn check_mod_unstable_api_usage: CheckModUnstableApiUsage(DefId) -> (),
+
+        /// Checks the loops in the module
+        [] fn check_mod_loops: CheckModLoops(DefId) -> (),
+
+        [] fn check_mod_item_types: CheckModItemTypes(DefId) -> (),
+
+        [] fn collect_mod_item_types: CollectModItemTypes(DefId) -> (),
+
         /// Caches CoerceUnsized kinds for impls on custom types.
         [] fn coerce_unsized_info: CoerceUnsizedInfo(DefId)
             -> ty::adjustment::CoerceUnsizedInfo,
index 3432aba7ee0d0304c1b3f205805f1e1af1ac0fd8..a674e942b3893c97049123eb9d632903770d374d 100644 (file)
@@ -7,6 +7,7 @@
 use mir::{self, interpret};
 use mir::interpret::{AllocDecodingSession, AllocDecodingState};
 use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::thin_vec::ThinVec;
 use rustc_data_structures::sync::{Lrc, Lock, HashMapExt, Once};
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
@@ -341,11 +342,13 @@ pub fn load_diagnostics<'a, 'tcx>(&self,
     /// Store a diagnostic emitted during the current compilation session.
     /// Anything stored like this will be available via `load_diagnostics` in
     /// the next compilation session.
+    #[inline(never)]
+    #[cold]
     pub fn store_diagnostics(&self,
                              dep_node_index: DepNodeIndex,
-                             diagnostics: Vec<Diagnostic>) {
+                             diagnostics: ThinVec<Diagnostic>) {
         let mut current_diagnostics = self.current_diagnostics.borrow_mut();
-        let prev = current_diagnostics.insert(dep_node_index, diagnostics);
+        let prev = current_diagnostics.insert(dep_node_index, diagnostics.into());
         debug_assert!(prev.is_none());
     }
 
@@ -367,16 +370,16 @@ pub fn try_load_query_result<'tcx, T>(&self,
     /// Since many anonymous queries can share the same `DepNode`, we aggregate
     /// them -- as opposed to regular queries where we assume that there is a
     /// 1:1 relationship between query-key and `DepNode`.
+    #[inline(never)]
+    #[cold]
     pub fn store_diagnostics_for_anon_node(&self,
                                            dep_node_index: DepNodeIndex,
-                                           mut diagnostics: Vec<Diagnostic>) {
+                                           diagnostics: ThinVec<Diagnostic>) {
         let mut current_diagnostics = self.current_diagnostics.borrow_mut();
 
-        let x = current_diagnostics.entry(dep_node_index).or_insert_with(|| {
-            mem::replace(&mut diagnostics, Vec::new())
-        });
+        let x = current_diagnostics.entry(dep_node_index).or_insert(Vec::new());
 
-        x.extend(diagnostics.into_iter());
+        x.extend(Into::<Vec<_>>::into(diagnostics));
     }
 
     fn load_indexed<'tcx, T>(&self,
index fd51f4f86a0af8a990472214f2582a5f47ea0bc7..32d4070dfed2af5deaae70cfbb9ea628a866c0c5 100644 (file)
@@ -18,6 +18,7 @@
 
 use rustc_data_structures::fx::{FxHashMap};
 use rustc_data_structures::sync::{Lrc, Lock};
+use rustc_data_structures::thin_vec::ThinVec;
 use std::mem;
 use std::ptr;
 use std::collections::hash_map::Entry;
@@ -112,11 +113,7 @@ pub(super) fn try_get(
             let mut lock = cache.borrow_mut();
             if let Some(value) = lock.results.get(key) {
                 profq_msg!(tcx, ProfileQueriesMsg::CacheHit);
-                tcx.sess.profiler(|p| {
-                    p.record_query(Q::CATEGORY);
-                    p.record_query_hit(Q::CATEGORY);
-                });
-
+                tcx.sess.profiler(|p| p.record_query_hit(Q::CATEGORY));
                 let result = Ok((value.value.clone(), value.index));
                 #[cfg(debug_assertions)]
                 {
@@ -195,37 +192,46 @@ pub(super) fn complete(self, result: &Q::Value, dep_node_index: DepNodeIndex) {
     /// Executes a job by changing the ImplicitCtxt to point to the
     /// new query job while it executes. It returns the diagnostics
     /// captured during execution and the actual result.
+    #[inline(always)]
     pub(super) fn start<'lcx, F, R>(
         &self,
         tcx: TyCtxt<'_, 'tcx, 'lcx>,
+        diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
         compute: F)
-    -> (R, Vec<Diagnostic>)
+    -> R
     where
         F: for<'b> FnOnce(TyCtxt<'b, 'tcx, 'lcx>) -> R
     {
         // The TyCtxt stored in TLS has the same global interner lifetime
         // as `tcx`, so we use `with_related_context` to relate the 'gcx lifetimes
         // when accessing the ImplicitCtxt
-        let r = tls::with_related_context(tcx, move |current_icx| {
+        tls::with_related_context(tcx, move |current_icx| {
             // Update the ImplicitCtxt to point to our new query job
             let new_icx = tls::ImplicitCtxt {
                 tcx: tcx.global_tcx(),
                 query: Some(self.job.clone()),
+                diagnostics,
                 layout_depth: current_icx.layout_depth,
-                task: current_icx.task,
+                task_deps: current_icx.task_deps,
             };
 
             // Use the ImplicitCtxt while we execute the query
             tls::enter_context(&new_icx, |_| {
                 compute(tcx)
             })
-        });
+        })
+    }
 
-        // Extract the diagnostic from the job
-        let diagnostics = mem::replace(&mut *self.job.diagnostics.lock(), Vec::new());
+}
 
-        (r, diagnostics)
-    }
+#[inline(always)]
+fn with_diagnostics<F, R>(f: F) -> (R, ThinVec<Diagnostic>)
+where
+    F: FnOnce(Option<&Lock<ThinVec<Diagnostic>>>) -> R
+{
+    let diagnostics = Lock::new(ThinVec::new());
+    let result = f(Some(&diagnostics));
+    (result, diagnostics.into_inner())
 }
 
 impl<'a, 'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'a, 'tcx, Q> {
@@ -382,13 +388,10 @@ fn try_get_with<Q: QueryDescription<'gcx>>(
             )
         );
 
-        self.sess.profiler(|p| p.record_query(Q::CATEGORY));
-
         let job = match JobOwner::try_get(self, span, &key) {
             TryGetJob::NotYetStarted(job) => job,
             TryGetJob::JobCompleted(result) => {
                 return result.map(|(v, index)| {
-                    self.sess.profiler(|p| p.record_query_hit(Q::CATEGORY));
                     self.dep_graph.read_index(index);
                     v
                 })
@@ -408,20 +411,23 @@ fn try_get_with<Q: QueryDescription<'gcx>>(
             profq_msg!(self, ProfileQueriesMsg::ProviderBegin);
             self.sess.profiler(|p| p.start_activity(Q::CATEGORY));
 
-            let res = job.start(self, |tcx| {
-                tcx.dep_graph.with_anon_task(dep_node.kind, || {
-                    Q::compute(tcx.global_tcx(), key)
+            let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
+                job.start(self, diagnostics, |tcx| {
+                    tcx.dep_graph.with_anon_task(dep_node.kind, || {
+                        Q::compute(tcx.global_tcx(), key)
+                    })
                 })
             });
 
             self.sess.profiler(|p| p.end_activity(Q::CATEGORY));
             profq_msg!(self, ProfileQueriesMsg::ProviderEnd);
-            let ((result, dep_node_index), diagnostics) = res;
 
             self.dep_graph.read_index(dep_node_index);
 
-            self.queries.on_disk_cache
-                .store_diagnostics_for_anon_node(dep_node_index, diagnostics);
+            if unlikely!(!diagnostics.is_empty()) {
+                self.queries.on_disk_cache
+                    .store_diagnostics_for_anon_node(dep_node_index, diagnostics);
+            }
 
             job.complete(&result, dep_node_index);
 
@@ -430,9 +436,6 @@ fn try_get_with<Q: QueryDescription<'gcx>>(
 
         if !dep_node.kind.is_input() {
             if let Some(dep_node_index) = self.try_mark_green_and_read(&dep_node) {
-                profq_msg!(self, ProfileQueriesMsg::CacheHit);
-                self.sess.profiler(|p| p.record_query_hit(Q::CATEGORY));
-
                 return self.load_from_disk_and_cache_in_memory::<Q>(key,
                                                                     job,
                                                                     dep_node_index,
@@ -483,21 +486,28 @@ fn load_from_disk_and_cache_in_memory<Q: QueryDescription<'gcx>>(
         };
 
         let result = if let Some(result) = result {
+            profq_msg!(self, ProfileQueriesMsg::CacheHit);
+            self.sess.profiler(|p| p.record_query_hit(Q::CATEGORY));
+
             result
         } else {
             // We could not load a result from the on-disk cache, so
             // recompute.
 
+            self.sess.profiler(|p| p.start_activity(Q::CATEGORY));
+
             // The diagnostics for this query have already been
             // promoted to the current session during
             // try_mark_green(), so we can ignore them here.
-            let (result, _) = job.start(self, |tcx| {
+            let result = job.start(self, None, |tcx| {
                 // The dep-graph for this computation is already in
                 // place
                 tcx.dep_graph.with_ignore(|| {
                     Q::compute(tcx, key)
                 })
             });
+
+            self.sess.profiler(|p| p.end_activity(Q::CATEGORY));
             result
         };
 
@@ -547,6 +557,7 @@ fn incremental_verify_ich<Q: QueryDescription<'gcx>>(
             for {:?}", dep_node);
     }
 
+    #[inline(always)]
     fn force_query_with_job<Q: QueryDescription<'gcx>>(
         self,
         key: Q::Key,
@@ -565,37 +576,36 @@ fn force_query_with_job<Q: QueryDescription<'gcx>>(
                 key, dep_node);
 
         profq_msg!(self, ProfileQueriesMsg::ProviderBegin);
-        self.sess.profiler(|p| {
-            p.start_activity(Q::CATEGORY);
-            p.record_query(Q::CATEGORY);
-        });
-
-        let res = job.start(self, |tcx| {
-            if dep_node.kind.is_eval_always() {
-                tcx.dep_graph.with_eval_always_task(dep_node,
-                                                    tcx,
-                                                    key,
-                                                    Q::compute)
-            } else {
-                tcx.dep_graph.with_task(dep_node,
-                                        tcx,
-                                        key,
-                                        Q::compute)
-            }
+        self.sess.profiler(|p| p.start_activity(Q::CATEGORY));
+
+        let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
+            job.start(self, diagnostics, |tcx| {
+                if dep_node.kind.is_eval_always() {
+                    tcx.dep_graph.with_eval_always_task(dep_node,
+                                                        tcx,
+                                                        key,
+                                                        Q::compute)
+                } else {
+                    tcx.dep_graph.with_task(dep_node,
+                                            tcx,
+                                            key,
+                                            Q::compute)
+                }
+            })
         });
 
         self.sess.profiler(|p| p.end_activity(Q::CATEGORY));
         profq_msg!(self, ProfileQueriesMsg::ProviderEnd);
 
-        let ((result, dep_node_index), diagnostics) = res;
-
         if unlikely!(self.sess.opts.debugging_opts.query_dep_graph) {
             self.dep_graph.mark_loaded_from_cache(dep_node_index, false);
         }
 
         if dep_node.kind != ::dep_graph::DepKind::Null {
-            self.queries.on_disk_cache
-                .store_diagnostics(dep_node_index, diagnostics);
+            if unlikely!(!diagnostics.is_empty()) {
+                self.queries.on_disk_cache
+                    .store_diagnostics(dep_node_index, diagnostics);
+            }
         }
 
         job.complete(&result, dep_node_index);
@@ -624,14 +634,10 @@ pub(super) fn ensure_query<Q: QueryDescription<'gcx>>(self, key: Q::Key) -> () {
             // this introduces should be negligible as we'll immediately hit the
             // in-memory cache, or another query down the line will.
 
-            self.sess.profiler(|p| {
-                p.start_activity(Q::CATEGORY);
-                p.record_query(Q::CATEGORY);
-            });
-
             let _ = self.get_query::<Q>(DUMMY_SP, key);
-
-            self.sess.profiler(|p| p.end_activity(Q::CATEGORY));
+        } else {
+            profq_msg!(self, ProfileQueriesMsg::CacheHit);
+            self.sess.profiler(|p| p.record_query_hit(Q::CATEGORY));
         }
     }
 
@@ -751,6 +757,17 @@ pub fn new(
                 }
             }
 
+            pub fn record_computed_queries(&self, sess: &Session) {
+                sess.profiler(|p| {
+                    $(
+                        p.record_computed_queries(
+                            <queries::$name<'_> as QueryConfig<'_>>::CATEGORY,
+                            self.$name.lock().results.len()
+                        );
+                    )*
+                });
+            }
+
             #[cfg(parallel_queries)]
             pub fn collect_active_jobs(&self) -> Vec<Lrc<QueryJob<$tcx>>> {
                 let mut jobs = Vec::new();
@@ -1259,6 +1276,11 @@ macro_rules! force {
         DepKind::MirBorrowCheck => { force!(mir_borrowck, def_id!()); }
         DepKind::UnsafetyCheckResult => { force!(unsafety_check_result, def_id!()); }
         DepKind::UnsafeDeriveOnReprPacked => { force!(unsafe_derive_on_repr_packed, def_id!()); }
+        DepKind::CheckModAttrs => { force!(check_mod_attrs, def_id!()); }
+        DepKind::CheckModLoops => { force!(check_mod_loops, def_id!()); }
+        DepKind::CheckModUnstableApiUsage => { force!(check_mod_unstable_api_usage, def_id!()); }
+        DepKind::CheckModItemTypes => { force!(check_mod_item_types, def_id!()); }
+        DepKind::CollectModItemTypes => { force!(collect_mod_item_types, def_id!()); }
         DepKind::Reachability => { force!(reachable_set, LOCAL_CRATE); }
         DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); }
         DepKind::CrateVariances => { force!(crate_variances, LOCAL_CRATE); }
index d598709ae3aac0d122b0917120058ecbf8bd1484..d31a06d6cb82d93da6f85ae126f88c422e65d9dd 100644 (file)
@@ -2,7 +2,7 @@
 
 use std::fs;
 use std::io::{self, StderrLock, Write};
-use std::time::{Duration, Instant};
+use std::time::Instant;
 
 macro_rules! define_categories {
     ($($name:ident,)*) => {
@@ -62,7 +62,8 @@ fn print(&self, lock: &mut StderrLock<'_>) {
                 let total_time = ($(self.times.$name + )* 0) as f32;
 
                 $(
-                    let (hits, total) = self.query_counts.$name;
+                    let (hits, computed) = self.query_counts.$name;
+                    let total = hits + computed;
                     let (hits, total) = if total > 0 {
                         (format!("{:.2}",
                         (((hits as f32) / (total as f32)) * 100.0)), total.to_string())
@@ -86,7 +87,8 @@ fn json(&self) -> String {
                 let mut json = String::from("[");
 
                 $(
-                    let (hits, total) = self.query_counts.$name;
+                    let (hits, computed) = self.query_counts.$name;
+                    let total = hits + computed;
 
                     //normalize hits to 0%
                     let hit_percent =
@@ -168,14 +170,14 @@ pub fn start_activity(&mut self, category: ProfileCategory) {
         self.timer_stack.push(category);
     }
 
-    pub fn record_query(&mut self, category: ProfileCategory) {
-        let (hits, total) = *self.data.query_counts.get(category);
-        self.data.query_counts.set(category, (hits, total + 1));
+    pub fn record_computed_queries(&mut self, category: ProfileCategory, count: usize) {
+        let (hits, computed) = *self.data.query_counts.get(category);
+        self.data.query_counts.set(category, (hits, computed + count as u64));
     }
 
     pub fn record_query_hit(&mut self, category: ProfileCategory) {
-        let (hits, total) = *self.data.query_counts.get(category);
-        self.data.query_counts.set(category, (hits + 1, total));
+        let (hits, computed) = *self.data.query_counts.get(category);
+        self.data.query_counts.set(category, (hits + 1, computed));
     }
 
     pub fn end_activity(&mut self, category: ProfileCategory) {
@@ -203,20 +205,7 @@ pub fn end_activity(&mut self, category: ProfileCategory) {
     }
 
     fn stop_timer(&mut self) -> u64 {
-        let elapsed = if cfg!(windows) {
-            // On Windows, timers don't always appear to be monotonic (see #51648)
-            // which can lead to panics when calculating elapsed time.
-            // Work around this by testing to see if the current time is less than
-            // our recorded time, and if it is, just returning 0.
-            let now = Instant::now();
-            if self.current_timer >= now {
-                Duration::new(0, 0)
-            } else {
-                self.current_timer.elapsed()
-            }
-        } else {
-            self.current_timer.elapsed()
-        };
+        let elapsed = self.current_timer.elapsed();
 
         self.current_timer = Instant::now();
 
index 04085387c37f08c7dd3510332342040c168f3088..cafb29ed99a416b886d7289db2f70200b3c636cc 100644 (file)
@@ -557,12 +557,8 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                 if new_loan.loan_path.has_fork(&old_loan.loan_path) && common.is_some() {
                     let nl = self.bccx.loan_path_to_string(&common.unwrap());
                     let ol = nl.clone();
-                    let new_loan_msg = format!(" (via `{}`)",
-                                               self.bccx.loan_path_to_string(
-                                                   &new_loan.loan_path));
-                    let old_loan_msg = format!(" (via `{}`)",
-                                               self.bccx.loan_path_to_string(
-                                                   &old_loan.loan_path));
+                    let new_loan_msg = self.bccx.loan_path_to_string(&new_loan.loan_path);
+                    let old_loan_msg = self.bccx.loan_path_to_string(&old_loan.loan_path);
                     (nl, ol, new_loan_msg, old_loan_msg)
                 } else {
                     (self.bccx.loan_path_to_string(&new_loan.loan_path),
index 72ed55df946588440b4567ea82f6baf172e9c8e6..6deedd0b5ea33c38e28b1fd582b4393bce3a78b5 100644 (file)
@@ -47,7 +47,7 @@
 
 impl PartialEq for llvm::Metadata {
     fn eq(&self, other: &Self) -> bool {
-        self as *const _ == other as *const _
+        ptr::eq(self, other)
     }
 }
 
index 1462423d0da2abcd35f35aa623fa9fe1c615ee99..958e00506d62a266f192d23eed05cc83328062fb 100644 (file)
 
 use std::fmt;
 use std::cell::RefCell;
+use std::ptr;
 
 use libc::c_uint;
 
 impl PartialEq for Type {
     fn eq(&self, other: &Self) -> bool {
-        self as *const _ == other as *const _
+        ptr::eq(self, other)
     }
 }
 
index 0ec964d4c422f451d4c8f7d263eb45c60e91bfb6..3ad1521be9393bb487ed6c476f43f621418b2a24 100644 (file)
@@ -4,10 +4,11 @@
 
 use std::fmt;
 use std::hash::{Hash, Hasher};
+use std::ptr;
 
 impl PartialEq for Value {
     fn eq(&self, other: &Self) -> bool {
-        self as *const _ == other as *const _
+        ptr::eq(self, other)
     }
 }
 
index 270387572f1379cb3061abd5a1d5961b283efd7c..06d4f940436da82fd0e545cc950815461782dc12 100644 (file)
@@ -81,11 +81,7 @@ pub fn to_linker<'a>(
             }
 
             LinkerFlavor::Lld(LldFlavor::Wasm) => {
-                Box::new(WasmLd {
-                    cmd,
-                    sess,
-                    info: self
-                }) as Box<dyn Linker>
+                Box::new(WasmLd::new(cmd, sess, self)) as Box<dyn Linker>
             }
         }
     }
@@ -876,6 +872,67 @@ pub struct WasmLd<'a> {
     info: &'a LinkerInfo,
 }
 
+impl<'a> WasmLd<'a> {
+    fn new(mut cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> {
+        // There have been reports in the wild (rustwasm/wasm-bindgen#119) of
+        // using threads causing weird hangs and bugs. Disable it entirely as
+        // this isn't yet the bottleneck of compilation at all anyway.
+        cmd.arg("--no-threads");
+
+        // By default LLD only gives us one page of stack (64k) which is a
+        // little small. Default to a larger stack closer to other PC platforms
+        // (1MB) and users can always inject their own link-args to override this.
+        cmd.arg("-z").arg("stack-size=1048576");
+
+        // By default LLD's memory layout is:
+        //
+        // 1. First, a blank page
+        // 2. Next, all static data
+        // 3. Finally, the main stack (which grows down)
+        //
+        // This has the unfortunate consequence that on stack overflows you
+        // corrupt static data and can cause some exceedingly weird bugs. To
+        // help detect this a little sooner we instead request that the stack is
+        // placed before static data.
+        //
+        // This means that we'll generate slightly larger binaries as references
+        // to static data will take more bytes in the ULEB128 encoding, but
+        // stack overflow will be guaranteed to trap as it underflows instead of
+        // corrupting static data.
+        cmd.arg("--stack-first");
+
+        // FIXME we probably shouldn't pass this but instead pass an explicit
+        // whitelist of symbols we'll allow to be undefined. Unfortunately
+        // though we can't handle symbols like `log10` that LLVM injects at a
+        // super late date without actually parsing object files. For now let's
+        // stick to this and hopefully fix it before stabilization happens.
+        cmd.arg("--allow-undefined");
+
+        // For now we just never have an entry symbol
+        cmd.arg("--no-entry");
+
+        // Make the default table accessible
+        cmd.arg("--export-table");
+
+        // Rust code should never have warnings, and warnings are often
+        // indicative of bugs, let's prevent them.
+        cmd.arg("--fatal-warnings");
+
+        // The symbol visibility story is a bit in flux right now with LLD.
+        // It's... not entirely clear to me what's going on, but this looks to
+        // make everything work when `export_symbols` isn't otherwise called for
+        // things like executables.
+        cmd.arg("--export-dynamic");
+
+        // LLD only implements C++-like demangling, which doesn't match our own
+        // mangling scheme. Tell LLD to not demangle anything and leave it up to
+        // us to demangle these symbols later.
+        cmd.arg("--no-demangle");
+
+        WasmLd { cmd, sess, info }
+    }
+}
+
 impl<'a> Linker for WasmLd<'a> {
     fn link_dylib(&mut self, lib: &str) {
         self.cmd.arg("-l").arg(lib);
@@ -982,61 +1039,6 @@ fn no_position_independent_executable(&mut self) {
     }
 
     fn finalize(&mut self) -> Command {
-        // There have been reports in the wild (rustwasm/wasm-bindgen#119) of
-        // using threads causing weird hangs and bugs. Disable it entirely as
-        // this isn't yet the bottleneck of compilation at all anyway.
-        self.cmd.arg("--no-threads");
-
-        // By default LLD only gives us one page of stack (64k) which is a
-        // little small. Default to a larger stack closer to other PC platforms
-        // (1MB) and users can always inject their own link-args to override this.
-        self.cmd.arg("-z").arg("stack-size=1048576");
-
-        // By default LLD's memory layout is:
-        //
-        // 1. First, a blank page
-        // 2. Next, all static data
-        // 3. Finally, the main stack (which grows down)
-        //
-        // This has the unfortunate consequence that on stack overflows you
-        // corrupt static data and can cause some exceedingly weird bugs. To
-        // help detect this a little sooner we instead request that the stack is
-        // placed before static data.
-        //
-        // This means that we'll generate slightly larger binaries as references
-        // to static data will take more bytes in the ULEB128 encoding, but
-        // stack overflow will be guaranteed to trap as it underflows instead of
-        // corrupting static data.
-        self.cmd.arg("--stack-first");
-
-        // FIXME we probably shouldn't pass this but instead pass an explicit
-        // whitelist of symbols we'll allow to be undefined. Unfortunately
-        // though we can't handle symbols like `log10` that LLVM injects at a
-        // super late date without actually parsing object files. For now let's
-        // stick to this and hopefully fix it before stabilization happens.
-        self.cmd.arg("--allow-undefined");
-
-        // For now we just never have an entry symbol
-        self.cmd.arg("--no-entry");
-
-        // Make the default table accessible
-        self.cmd.arg("--export-table");
-
-        // Rust code should never have warnings, and warnings are often
-        // indicative of bugs, let's prevent them.
-        self.cmd.arg("--fatal-warnings");
-
-        // The symbol visibility story is a bit in flux right now with LLD.
-        // It's... not entirely clear to me what's going on, but this looks to
-        // make everything work when `export_symbols` isn't otherwise called for
-        // things like executables.
-        self.cmd.arg("--export-dynamic");
-
-        // LLD only implements C++-like demangling, which doesn't match our own
-        // mangling scheme. Tell LLD to not demangle anything and leave it up to
-        // us to demangle these symbols later.
-        self.cmd.arg("--no-demangle");
-
         ::std::mem::replace(&mut self.cmd, Command::new(""))
     }
 
index c086eb3aa804fd29fca056e3178ee299cb738d9a..ec71f5158948ced3e91dc5f973e318543d1ffd3d 100644 (file)
@@ -21,6 +21,7 @@
 #![feature(hash_raw_entry)]
 #![feature(stmt_expr_attributes)]
 #![feature(core_intrinsics)]
+#![feature(integer_atomics)]
 
 #![cfg_attr(unix, feature(libc))]
 #![cfg_attr(test, feature(test))]
index d935eb7bdab74c3820d54dcc2094b24c41c2f139..f9f94f0be7b9a175648d335091df2eba014286eb 100644 (file)
 //! It internally uses `parking_lot::RwLock` if cfg!(parallel_queries) is true,
 //! `RefCell` otherwise.
 //!
-//! `LockCell` is a thread safe version of `Cell`, with `set` and `get` operations.
-//! It can never deadlock. It uses `Cell` when
-//! cfg!(parallel_queries) is false, otherwise it is a `Lock`.
-//!
 //! `MTLock` is a mutex which disappears if cfg!(parallel_queries) is false.
 //!
 //! `MTRef` is a immutable reference if cfg!(parallel_queries), and an mutable reference otherwise.
 
 use std::collections::HashMap;
 use std::hash::{Hash, BuildHasher};
-use std::cmp::Ordering;
 use std::marker::PhantomData;
-use std::fmt::Debug;
-use std::fmt::Formatter;
-use std::fmt;
 use std::ops::{Deref, DerefMut};
 use owning_ref::{Erased, OwningRef};
 
@@ -54,6 +46,9 @@ pub fn serial_scope<F, R>(f: F) -> R
     f(&SerialScope)
 }
 
+pub use std::sync::atomic::Ordering::SeqCst;
+pub use std::sync::atomic::Ordering;
+
 cfg_if! {
     if #[cfg(not(parallel_queries))] {
         pub auto trait Send {}
@@ -69,6 +64,62 @@ macro_rules! rustc_erase_owner {
             }
         }
 
+        use std::ops::Add;
+
+        #[derive(Debug)]
+        pub struct Atomic<T: Copy>(Cell<T>);
+
+        impl<T: Copy> Atomic<T> {
+            pub fn new(v: T) -> Self {
+                Atomic(Cell::new(v))
+            }
+        }
+
+        impl<T: Copy + PartialEq> Atomic<T> {
+            pub fn into_inner(self) -> T {
+                self.0.into_inner()
+            }
+
+            pub fn load(&self, _: Ordering) -> T {
+                self.0.get()
+            }
+
+            pub fn store(&self, val: T, _: Ordering) {
+                self.0.set(val)
+            }
+
+            pub fn swap(&self, val: T, _: Ordering) -> T {
+                self.0.replace(val)
+            }
+
+            pub fn compare_exchange(&self,
+                                    current: T,
+                                    new: T,
+                                    _: Ordering,
+                                    _: Ordering)
+                                    -> Result<T, T> {
+                let read = self.0.get();
+                if read == current {
+                    self.0.set(new);
+                    Ok(read)
+                } else {
+                    Err(read)
+                }
+            }
+        }
+
+        impl<T: Add<Output=T> + Copy> Atomic<T> {
+            pub fn fetch_add(&self, val: T, _: Ordering) -> T {
+                let old = self.0.get();
+                self.0.set(old + val);
+                old
+            }
+        }
+
+        pub type AtomicUsize = Atomic<usize>;
+        pub type AtomicBool = Atomic<bool>;
+        pub type AtomicU64 = Atomic<u64>;
+
         pub use self::serial_join as join;
         pub use self::serial_scope as scope;
 
@@ -160,47 +211,6 @@ fn clone(&self) -> Self {
                 MTLock(self.0.clone())
             }
         }
-
-        pub struct LockCell<T>(Cell<T>);
-
-        impl<T> LockCell<T> {
-            #[inline(always)]
-            pub fn new(inner: T) -> Self {
-                LockCell(Cell::new(inner))
-            }
-
-            #[inline(always)]
-            pub fn into_inner(self) -> T {
-                self.0.into_inner()
-            }
-
-            #[inline(always)]
-            pub fn set(&self, new_inner: T) {
-                self.0.set(new_inner);
-            }
-
-            #[inline(always)]
-            pub fn get(&self) -> T where T: Copy {
-                self.0.get()
-            }
-
-            #[inline(always)]
-            pub fn set_mut(&mut self, new_inner: T) {
-                self.0.set(new_inner);
-            }
-
-            #[inline(always)]
-            pub fn get_mut(&mut self) -> T where T: Copy {
-                self.0.get()
-            }
-        }
-
-        impl<T> LockCell<Option<T>> {
-            #[inline(always)]
-            pub fn take(&self) -> Option<T> {
-                unsafe { (*self.0.as_ptr()).take() }
-            }
-        }
     } else {
         pub use std::marker::Send as Send;
         pub use std::marker::Sync as Sync;
@@ -213,6 +223,8 @@ pub fn take(&self) -> Option<T> {
         pub use parking_lot::MutexGuard as LockGuard;
         pub use parking_lot::MappedMutexGuard as MappedLockGuard;
 
+        pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU64};
+
         pub use std::sync::Arc as Lrc;
         pub use std::sync::Weak as Weak;
 
@@ -278,51 +290,11 @@ macro_rules! rustc_erase_owner {
                 v.erase_send_sync_owner()
             }}
         }
-
-        pub struct LockCell<T>(Lock<T>);
-
-        impl<T> LockCell<T> {
-            #[inline(always)]
-            pub fn new(inner: T) -> Self {
-                LockCell(Lock::new(inner))
-            }
-
-            #[inline(always)]
-            pub fn into_inner(self) -> T {
-                self.0.into_inner()
-            }
-
-            #[inline(always)]
-            pub fn set(&self, new_inner: T) {
-                *self.0.lock() = new_inner;
-            }
-
-            #[inline(always)]
-            pub fn get(&self) -> T where T: Copy {
-                *self.0.lock()
-            }
-
-            #[inline(always)]
-            pub fn set_mut(&mut self, new_inner: T) {
-                *self.0.get_mut() = new_inner;
-            }
-
-            #[inline(always)]
-            pub fn get_mut(&mut self) -> T where T: Copy {
-                *self.0.get_mut()
-            }
-        }
-
-        impl<T> LockCell<Option<T>> {
-            #[inline(always)]
-            pub fn take(&self) -> Option<T> {
-                self.0.lock().take()
-            }
-        }
     }
 }
 
 pub fn assert_sync<T: ?Sized + Sync>() {}
+pub fn assert_send<T: ?Sized + Send>() {}
 pub fn assert_send_val<T: ?Sized + Send>(_t: &T) {}
 pub fn assert_send_sync_val<T: ?Sized + Sync + Send>(_t: &T) {}
 
@@ -466,65 +438,6 @@ pub fn borrow(&self) -> &T {
     }
 }
 
-impl<T: Copy + Debug> Debug for LockCell<T> {
-    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
-        f.debug_struct("LockCell")
-            .field("value", &self.get())
-            .finish()
-    }
-}
-
-impl<T:Default> Default for LockCell<T> {
-    /// Creates a `LockCell<T>`, with the `Default` value for T.
-    #[inline]
-    fn default() -> LockCell<T> {
-        LockCell::new(Default::default())
-    }
-}
-
-impl<T:PartialEq + Copy> PartialEq for LockCell<T> {
-    #[inline]
-    fn eq(&self, other: &LockCell<T>) -> bool {
-        self.get() == other.get()
-    }
-}
-
-impl<T:Eq + Copy> Eq for LockCell<T> {}
-
-impl<T:PartialOrd + Copy> PartialOrd for LockCell<T> {
-    #[inline]
-    fn partial_cmp(&self, other: &LockCell<T>) -> Option<Ordering> {
-        self.get().partial_cmp(&other.get())
-    }
-
-    #[inline]
-    fn lt(&self, other: &LockCell<T>) -> bool {
-        self.get() < other.get()
-    }
-
-    #[inline]
-    fn le(&self, other: &LockCell<T>) -> bool {
-        self.get() <= other.get()
-    }
-
-    #[inline]
-    fn gt(&self, other: &LockCell<T>) -> bool {
-        self.get() > other.get()
-    }
-
-    #[inline]
-    fn ge(&self, other: &LockCell<T>) -> bool {
-        self.get() >= other.get()
-    }
-}
-
-impl<T:Ord + Copy> Ord for LockCell<T> {
-    #[inline]
-    fn cmp(&self, other: &LockCell<T>) -> Ordering {
-        self.get().cmp(&other.get())
-    }
-}
-
 #[derive(Debug)]
 pub struct Lock<T>(InnerLock<T>);
 
index 0204d041a242044c14bbdb506a12ed102cce985d..380f9afd68de6d2c2ff7c12cc7a95047aa2a719f 100644 (file)
@@ -402,14 +402,15 @@ pub struct CompileController<'a> {
 
     /// Allows overriding default rustc query providers,
     /// after `default_provide` has installed them.
-    pub provide: Box<dyn Fn(&mut ty::query::Providers) + 'a>,
+    pub provide: Box<dyn Fn(&mut ty::query::Providers) + 'a + sync::Send>,
     /// Same as `provide`, but only for non-local crates,
     /// applied after `default_provide_extern`.
-    pub provide_extern: Box<dyn Fn(&mut ty::query::Providers) + 'a>,
+    pub provide_extern: Box<dyn Fn(&mut ty::query::Providers) + 'a + sync::Send>,
 }
 
 impl<'a> CompileController<'a> {
     pub fn basic() -> CompileController<'a> {
+        sync::assert_send::<Self>();
         CompileController {
             after_parse: PhaseController::basic(),
             after_expand: PhaseController::basic(),
@@ -499,7 +500,7 @@ pub struct PhaseController<'a> {
     // If true then the compiler will try to run the callback even if the phase
     // ends with an error. Note that this is not always possible.
     pub run_callback_on_error: bool,
-    pub callback: Box<dyn Fn(&mut CompileState) + 'a>,
+    pub callback: Box<dyn Fn(&mut CompileState) + 'a + sync::Send>,
 }
 
 impl<'a> PhaseController<'a> {
@@ -1166,6 +1167,7 @@ pub fn default_provide(providers: &mut ty::query::Providers) {
     typeck::provide(providers);
     ty::provide(providers);
     traits::provide(providers);
+    stability::provide(providers);
     reachable::provide(providers);
     rustc_passes::provide(providers);
     rustc_traits::provide(providers);
@@ -1217,8 +1219,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(
     sess.proc_macro_decls_static
         .set(proc_macro_decls::find(&hir_map));
 
-    time(sess, "loop checking", || loops::check_crate(sess, &hir_map));
-
     let mut local_providers = ty::query::Providers::default();
     default_provide(&mut local_providers);
     codegen_backend.provide(&mut local_providers);
@@ -1246,7 +1246,9 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(
         |tcx| {
             // Do some initialization of the DepGraph that can only be done with the
             // tcx available.
-            rustc_incremental::dep_graph_tcx_init(tcx);
+            time(sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx));
+
+            time(sess, "loop checking", || loops::check_crate(tcx));
 
             time(sess, "attribute checking", || {
                 hir::check_attr::check_crate(tcx)
index 20a3009378d37ec7ea5377e4a379eff43e0f70e3..889e1ec3b98c63e98c56d094bd3fea18c3d3e730 100644 (file)
@@ -16,6 +16,7 @@
 #![feature(slice_sort_by_cached_key)]
 #![feature(set_stdio)]
 #![feature(no_debug)]
+#![feature(integer_atomics)]
 
 #![recursion_limit="256"]
 
@@ -59,7 +60,7 @@
 use rustc_resolve as resolve;
 use rustc_save_analysis as save;
 use rustc_save_analysis::DumpHandler;
-use rustc_data_structures::sync::{self, Lrc};
+use rustc_data_structures::sync::{self, Lrc, Ordering::SeqCst};
 use rustc_data_structures::OnDrop;
 use rustc::session::{self, config, Session, build_session, CompileResult};
 use rustc::session::CompileIncomplete;
@@ -269,35 +270,37 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
     }
 
     let target = session::config::host_triple();
-    // get target libdir path based on executable binary path
-    let sysroot = filesearch::get_or_default_sysroot();
-    let mut libdir_candidates = vec![filesearch::make_target_lib_path(&sysroot, &target)];
+    let mut sysroot_candidates = vec![filesearch::get_or_default_sysroot()];
     let path = current_dll_path()
         .and_then(|s| s.canonicalize().ok());
     if let Some(dll) = path {
-        // use `parent` once to chop off the file name
-        if let Some(path) = dll.parent() {
+        // use `parent` twice to chop off the file name and then also the
+        // directory containing the dll which should be either `lib` or `bin`.
+        if let Some(path) = dll.parent().and_then(|p| p.parent()) {
             // The original `path` pointed at the `rustc_driver` crate's dll.
             // Now that dll should only be in one of two locations. The first is
-            // in the compiler's libdir, for example `$sysroot/$libdir/*.dll`. The
+            // in the compiler's libdir, for example `$sysroot/lib/*.dll`. The
             // other is the target's libdir, for example
-            // `$sysroot/$libdir/rustlib/$target/lib/*.dll`.
+            // `$sysroot/lib/rustlib/$target/lib/*.dll`.
             //
             // We don't know which, so let's assume that if our `path` above
-            // doesn't end in `$target` we *could* be in the main libdir, and always
-            // assume that we may be in the target libdir.
-            libdir_candidates.push(path.to_owned());
-
-            if !path.parent().map_or(false, |p| p.ends_with(target)) {
-                libdir_candidates.push(path.join(filesearch::target_lib_path(target)));
+            // ends in `$target` we *could* be in the target libdir, and always
+            // assume that we may be in the main libdir.
+            sysroot_candidates.push(path.to_owned());
+
+            if path.ends_with(target) {
+                sysroot_candidates.extend(path.parent() // chop off `$target`
+                    .and_then(|p| p.parent())           // chop off `rustlib`
+                    .and_then(|p| p.parent())           // chop off `lib`
+                    .map(|s| s.to_owned()));
             }
         }
     }
 
-    let sysroot = libdir_candidates.iter()
-        .map(|libdir| {
-            debug!("Trying target libdir: {}", libdir.display());
-            libdir.with_file_name(
+    let sysroot = sysroot_candidates.iter()
+        .map(|sysroot| {
+            let libdir = filesearch::relative_target_lib_path(&sysroot, &target);
+            sysroot.join(libdir).with_file_name(
                 option_env!("CFG_CODEGEN_BACKENDS_DIR").unwrap_or("codegen-backends"))
         })
         .filter(|f| {
@@ -306,12 +309,12 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
         })
         .next();
     let sysroot = sysroot.unwrap_or_else(|| {
-        let candidates = libdir_candidates.iter()
+        let candidates = sysroot_candidates.iter()
             .map(|p| p.display().to_string())
             .collect::<Vec<_>>()
             .join("\n* ");
         let err = format!("failed to find a `codegen-backends` folder \
-                           in the libdir candidates:\n* {}", candidates);
+                           in the sysroot candidates:\n* {}", candidates);
         early_error(ErrorOutputType::default(), &err);
     });
     info!("probing {} for a codegen backend", sysroot.display());
@@ -925,7 +928,7 @@ fn build_controller(self: Box<Self>,
                 let sess = state.session;
                 eprintln!("Fuel used by {}: {}",
                     sess.print_fuel_crate.as_ref().unwrap(),
-                    sess.print_fuel.get());
+                    sess.print_fuel.load(SeqCst));
             }
         }
         control
index f0fde6bbd8ecc40f97abade167898917a9455e56..a074441f8a179b0624064c76e1dcb23b896cd884 100644 (file)
 
 use emitter::{Emitter, EmitterWriter};
 
-use rustc_data_structures::sync::{self, Lrc, Lock, LockCell};
+use rustc_data_structures::sync::{self, Lrc, Lock, AtomicUsize, AtomicBool, SeqCst};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::stable_hasher::StableHasher;
 
 use std::borrow::Cow;
 use std::cell::Cell;
 use std::{error, fmt};
-use std::sync::atomic::AtomicUsize;
-use std::sync::atomic::Ordering::SeqCst;
 use std::panic;
 
 use termcolor::{ColorSpec, Color};
@@ -271,7 +269,7 @@ pub struct Handler {
 
     err_count: AtomicUsize,
     emitter: Lock<Box<dyn Emitter + sync::Send>>,
-    continue_after_error: LockCell<bool>,
+    continue_after_error: AtomicBool,
     delayed_span_bugs: Lock<Vec<Diagnostic>>,
 
     // This set contains the `DiagnosticId` of all emitted diagnostics to avoid
@@ -370,7 +368,7 @@ pub fn with_emitter_and_flags(e: Box<dyn Emitter + sync::Send>, flags: HandlerFl
             flags,
             err_count: AtomicUsize::new(0),
             emitter: Lock::new(e),
-            continue_after_error: LockCell::new(true),
+            continue_after_error: AtomicBool::new(true),
             delayed_span_bugs: Lock::new(Vec::new()),
             taught_diagnostics: Default::default(),
             emitted_diagnostic_codes: Default::default(),
@@ -379,7 +377,7 @@ pub fn with_emitter_and_flags(e: Box<dyn Emitter + sync::Send>, flags: HandlerFl
     }
 
     pub fn set_continue_after_error(&self, continue_after_error: bool) {
-        self.continue_after_error.set(continue_after_error);
+        self.continue_after_error.store(continue_after_error, SeqCst);
     }
 
     /// Resets the diagnostic error count as well as the cached emitted diagnostics.
@@ -658,7 +656,7 @@ pub fn emit(&self, msp: &MultiSpan, msg: &str, lvl: Level) {
         let mut db = DiagnosticBuilder::new(self, lvl, msg);
         db.set_span(msp.clone());
         db.emit();
-        if !self.continue_after_error.get() {
+        if !self.continue_after_error.load(SeqCst) {
             self.abort_if_errors();
         }
     }
@@ -669,7 +667,7 @@ pub fn emit_with_code(&self, msp: &MultiSpan, msg: &str, code: DiagnosticId, lvl
         let mut db = DiagnosticBuilder::new_with_code(self, lvl, Some(code), msg);
         db.set_span(msp.clone());
         db.emit();
-        if !self.continue_after_error.get() {
+        if !self.continue_after_error.load(SeqCst) {
             self.abort_if_errors();
         }
     }
index 5131b63115ae5139409117f07bd7c41ef87d83a6..6a7553b3882975e28d68b589254ae54ea6534bca 100644 (file)
@@ -149,8 +149,6 @@ struct Stat {
 
         let total_node_count = serialized_graph.nodes.len();
         let total_edge_count = serialized_graph.edge_list_data.len();
-        let (total_edge_reads, total_duplicate_edge_reads) =
-            tcx.dep_graph.edge_deduplication_data();
 
         let mut counts: FxHashMap<_, Stat> = FxHashMap::default();
 
@@ -188,8 +186,11 @@ struct Stat {
         println!("[incremental]");
         println!("[incremental] Total Node Count: {}", total_node_count);
         println!("[incremental] Total Edge Count: {}", total_edge_count);
-        println!("[incremental] Total Edge Reads: {}", total_edge_reads);
-        println!("[incremental] Total Duplicate Edge Reads: {}", total_duplicate_edge_reads);
+        if let Some((total_edge_reads,
+                     total_duplicate_edge_reads)) = tcx.dep_graph.edge_deduplication_data() {
+            println!("[incremental] Total Edge Reads: {}", total_edge_reads);
+            println!("[incremental] Total Duplicate Edge Reads: {}", total_duplicate_edge_reads);
+        }
         println!("[incremental]");
         println!("[incremental]  {:<36}| {:<17}| {:<12}| {:<17}|",
                  "Node Kind",
index a555b7790971f5426fd89147268cd8b0a6d1295b..5678f30dabccd5b98112ece998330c1132daac80 100644 (file)
@@ -297,6 +297,26 @@ pub struct MissingDoc {
     private_traits: FxHashSet<ast::NodeId>,
 }
 
+fn has_doc(attr: &ast::Attribute) -> bool {
+    if !attr.check_name("doc") {
+        return false;
+    }
+
+    if attr.is_value_str() {
+        return true;
+    }
+
+    if let Some(list) = attr.meta_item_list() {
+        for meta in list {
+            if meta.check_name("include") || meta.check_name("hidden") {
+                return true;
+            }
+        }
+    }
+
+    false
+}
+
 impl MissingDoc {
     pub fn new() -> MissingDoc {
         MissingDoc {
@@ -335,26 +355,6 @@ fn check_missing_docs_attrs(&self,
             }
         }
 
-        fn has_doc(attr: &ast::Attribute) -> bool {
-            if !attr.check_name("doc") {
-                return false;
-            }
-
-            if attr.is_value_str() {
-                return true;
-            }
-
-            if let Some(list) = attr.meta_item_list() {
-                for meta in list {
-                    if meta.check_name("include") {
-                        return true;
-                    }
-                }
-            }
-
-            false
-        }
-
         let has_doc = attrs.iter().any(|a| has_doc(a));
         if !has_doc {
             cx.span_lint(MISSING_DOCS,
@@ -389,6 +389,15 @@ fn exit_lint_attrs(&mut self, _: &LateContext, _attrs: &[ast::Attribute]) {
 
     fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) {
         self.check_missing_docs_attrs(cx, None, &krate.attrs, krate.span, "crate");
+
+        for macro_def in &krate.exported_macros {
+            let has_doc = macro_def.attrs.iter().any(|a| has_doc(a));
+            if !has_doc {
+                cx.span_lint(MISSING_DOCS,
+                             cx.tcx.sess.source_map().def_span(macro_def.span),
+                             "missing documentation for macro");
+            }
+        }
     }
 
     fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
index 2694a04b94ce4c3106bdd2f81486325e6b0026da..a4a3fa552e9881627a9342126b7eb57452784379 100644 (file)
@@ -7,7 +7,8 @@
 use lint::{EarlyLintPass, LintPass, LateLintPass};
 use syntax::ast;
 use syntax::attr;
-use syntax_pos::Span;
+use syntax::errors::Applicability;
+use syntax_pos::{BytePos, symbol::Ident, Span};
 
 #[derive(PartialEq)]
 pub enum MethodLateContext {
@@ -40,13 +41,12 @@ pub fn method_context(cx: &LateContext, id: ast::NodeId) -> MethodLateContext {
 pub struct NonCamelCaseTypes;
 
 impl NonCamelCaseTypes {
-    fn check_case(&self, cx: &EarlyContext, sort: &str, name: ast::Name, span: Span) {
+    fn check_case(&self, cx: &EarlyContext, sort: &str, ident: &Ident) {
         fn char_has_case(c: char) -> bool {
             c.is_lowercase() || c.is_uppercase()
         }
 
-        fn is_camel_case(name: ast::Name) -> bool {
-            let name = name.as_str();
+        fn is_camel_case(name: &str) -> bool {
             let name = name.trim_matches('_');
             if name.is_empty() {
                 return true;
@@ -86,14 +86,20 @@ fn to_camel_case(s: &str) -> String {
                 }).0
         }
 
+        let name = &ident.name.as_str();
+
         if !is_camel_case(name) {
-            let c = to_camel_case(&name.as_str());
-            let m = if c.is_empty() {
-                format!("{} `{}` should have a camel case name such as `CamelCase`", sort, name)
-            } else {
-                format!("{} `{}` should have a camel case name such as `{}`", sort, name, c)
-            };
-            cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m);
+            let c = to_camel_case(name);
+
+            let msg = format!("{} `{}` should have a camel case name", sort, name);
+            cx.struct_span_lint(NON_CAMEL_CASE_TYPES, ident.span, &msg)
+                .span_suggestion_with_applicability(
+                    ident.span,
+                    "convert the identifier to camel case",
+                    c,
+                    Applicability::MaybeIncorrect,
+                )
+                .emit();
         }
     }
 }
@@ -122,19 +128,19 @@ fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
             ast::ItemKind::Ty(..) |
             ast::ItemKind::Enum(..) |
             ast::ItemKind::Struct(..) |
-            ast::ItemKind::Union(..) => self.check_case(cx, "type", it.ident.name, it.span),
-            ast::ItemKind::Trait(..) => self.check_case(cx, "trait", it.ident.name, it.span),
+            ast::ItemKind::Union(..) => self.check_case(cx, "type", &it.ident),
+            ast::ItemKind::Trait(..) => self.check_case(cx, "trait", &it.ident),
             _ => (),
         }
     }
 
     fn check_variant(&mut self, cx: &EarlyContext, v: &ast::Variant, _: &ast::Generics) {
-        self.check_case(cx, "variant", v.node.ident.name, v.span);
+        self.check_case(cx, "variant", &v.node.ident);
     }
 
     fn check_generic_param(&mut self, cx: &EarlyContext, param: &ast::GenericParam) {
         if let ast::GenericParamKind::Type { .. } = param.kind {
-            self.check_case(cx, "type parameter", param.ident.name, param.ident.span);
+            self.check_case(cx, "type parameter", &param.ident);
         }
     }
 }
@@ -179,7 +185,8 @@ fn to_snake_case(mut str: &str) -> String {
         words.join("_")
     }
 
-    fn check_snake_case(&self, cx: &LateContext, sort: &str, name: &str, span: Option<Span>) {
+    /// Checks if a given identifier is snake case, and reports a diagnostic if not.
+    fn check_snake_case(&self, cx: &LateContext, sort: &str, ident: &Ident) {
         fn is_snake_case(ident: &str) -> bool {
             if ident.is_empty() {
                 return true;
@@ -201,20 +208,28 @@ fn is_snake_case(ident: &str) -> bool {
             })
         }
 
+        let name = &ident.name.as_str();
+
         if !is_snake_case(name) {
             let sc = NonSnakeCase::to_snake_case(name);
-            let msg = if sc != name {
-                format!("{} `{}` should have a snake case name such as `{}`",
-                        sort,
-                        name,
-                        sc)
+
+            let msg = format!("{} `{}` should have a snake case name", sort, name);
+            let mut err = cx.struct_span_lint(NON_SNAKE_CASE, ident.span, &msg);
+
+            // We have a valid span in almost all cases, but we don't have one when linting a crate
+            // name provided via the command line.
+            if !ident.span.is_dummy() {
+                err.span_suggestion_with_applicability(
+                    ident.span,
+                    "convert the identifier to snake case",
+                    sc,
+                    Applicability::MaybeIncorrect,
+                );
             } else {
-                format!("{} `{}` should have a snake case name", sort, name)
-            };
-            match span {
-                Some(span) => cx.span_lint(NON_SNAKE_CASE, span, &msg),
-                None => cx.lint(NON_SNAKE_CASE, &msg),
+                err.help(&format!("convert the identifier to snake case: `{}`", sc));
             }
+
+            err.emit();
         }
     }
 }
@@ -227,50 +242,75 @@ fn get_lints(&self) -> LintArray {
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
     fn check_crate(&mut self, cx: &LateContext, cr: &hir::Crate) {
-        let attr_crate_name = attr::find_by_name(&cr.attrs, "crate_name")
-            .and_then(|at| at.value_str().map(|s| (at, s)));
-        if let Some(ref name) = cx.tcx.sess.opts.crate_name {
-            self.check_snake_case(cx, "crate", name, None);
-        } else if let Some((attr, name)) = attr_crate_name {
-            self.check_snake_case(cx, "crate", &name.as_str(), Some(attr.span));
+        let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name {
+            Some(Ident::from_str(name))
+        } else {
+            attr::find_by_name(&cr.attrs, "crate_name")
+                .and_then(|attr| attr.meta())
+                .and_then(|meta| {
+                    meta.name_value_literal().and_then(|lit| {
+                        if let ast::LitKind::Str(name, ..) = lit.node {
+                            // Discard the double quotes surrounding the literal.
+                            let sp = cx.sess().source_map().span_to_snippet(lit.span)
+                                .ok()
+                                .and_then(|snippet| {
+                                    let left = snippet.find('"')?;
+                                    let right = snippet.rfind('"').map(|pos| snippet.len() - pos)?;
+
+                                    Some(
+                                        lit.span
+                                            .with_lo(lit.span.lo() + BytePos(left as u32 + 1))
+                                            .with_hi(lit.span.hi() - BytePos(right as u32)),
+                                    )
+                                })
+                                .unwrap_or_else(|| lit.span);
+
+                            Some(Ident::new(name, sp))
+                        } else {
+                            None
+                        }
+                    })
+                })
+        };
+
+        if let Some(ident) = &crate_ident {
+            self.check_snake_case(cx, "crate", ident);
         }
     }
 
     fn check_generic_param(&mut self, cx: &LateContext, param: &hir::GenericParam) {
-        match param.kind {
-            GenericParamKind::Lifetime { .. } => {
-                let name = param.name.ident().as_str();
-                self.check_snake_case(cx, "lifetime", &name, Some(param.span));
-            }
-            GenericParamKind::Type { .. } => {}
+        if let GenericParamKind::Lifetime { .. } = param.kind {
+            self.check_snake_case(cx, "lifetime", &param.name.ident());
         }
     }
 
-    fn check_fn(&mut self,
-                cx: &LateContext,
-                fk: FnKind,
-                _: &hir::FnDecl,
-                _: &hir::Body,
-                span: Span,
-                id: ast::NodeId) {
-        match fk {
-            FnKind::Method(name, ..) => {
+    fn check_fn(
+        &mut self,
+        cx: &LateContext,
+        fk: FnKind,
+        _: &hir::FnDecl,
+        _: &hir::Body,
+        _: Span,
+        id: ast::NodeId,
+    ) {
+        match &fk {
+            FnKind::Method(ident, ..) => {
                 match method_context(cx, id) {
                     MethodLateContext::PlainImpl => {
-                        self.check_snake_case(cx, "method", &name.as_str(), Some(span))
+                        self.check_snake_case(cx, "method", ident);
                     }
                     MethodLateContext::TraitAutoImpl => {
-                        self.check_snake_case(cx, "trait method", &name.as_str(), Some(span))
+                        self.check_snake_case(cx, "trait method", ident);
                     }
                     _ => (),
                 }
             }
-            FnKind::ItemFn(name, _, header, _, attrs) => {
+            FnKind::ItemFn(ident, _, header, _, attrs) => {
                 // Skip foreign-ABI #[no_mangle] functions (Issue #31924)
-                if header.abi != Abi::Rust && attr::find_by_name(attrs, "no_mangle").is_some() {
+                if header.abi != Abi::Rust && attr::contains_name(attrs, "no_mangle") {
                     return;
                 }
-                self.check_snake_case(cx, "function", &name.as_str(), Some(span))
+                self.check_snake_case(cx, "function", ident);
             }
             FnKind::Closure(_) => (),
         }
@@ -278,36 +318,35 @@ fn check_fn(&mut self,
 
     fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
         if let hir::ItemKind::Mod(_) = it.node {
-            self.check_snake_case(cx, "module", &it.ident.as_str(), Some(it.span));
+            self.check_snake_case(cx, "module", &it.ident);
         }
     }
 
     fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) {
-        if let hir::TraitItemKind::Method(_, hir::TraitMethod::Required(ref pnames)) = item.node {
-            self.check_snake_case(cx,
-                                  "trait method",
-                                  &item.ident.as_str(),
-                                  Some(item.span));
+        if let hir::TraitItemKind::Method(_, hir::TraitMethod::Required(pnames)) = &item.node {
+            self.check_snake_case(cx, "trait method", &item.ident);
             for param_name in pnames {
-                self.check_snake_case(cx, "variable", &param_name.as_str(), Some(param_name.span));
+                self.check_snake_case(cx, "variable", param_name);
             }
         }
     }
 
     fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
-        if let &PatKind::Binding(_, _, ref ident, _) = &p.node {
-            self.check_snake_case(cx, "variable", &ident.as_str(), Some(p.span));
+        if let &PatKind::Binding(_, _, ident, _) = &p.node {
+            self.check_snake_case(cx, "variable", &ident);
         }
     }
 
-    fn check_struct_def(&mut self,
-                        cx: &LateContext,
-                        s: &hir::VariantData,
-                        _: ast::Name,
-                        _: &hir::Generics,
-                        _: ast::NodeId) {
+    fn check_struct_def(
+        &mut self,
+        cx: &LateContext,
+        s: &hir::VariantData,
+        _: ast::Name,
+        _: &hir::Generics,
+        _: ast::NodeId,
+    ) {
         for sf in s.fields() {
-            self.check_snake_case(cx, "structure field", &sf.ident.as_str(), Some(sf.span));
+            self.check_snake_case(cx, "structure field", &sf.ident);
         }
     }
 }
@@ -322,21 +361,21 @@ fn check_struct_def(&mut self,
 pub struct NonUpperCaseGlobals;
 
 impl NonUpperCaseGlobals {
-    fn check_upper_case(cx: &LateContext, sort: &str, name: ast::Name, span: Span) {
-        if name.as_str().chars().any(|c| c.is_lowercase()) {
-            let uc = NonSnakeCase::to_snake_case(&name.as_str()).to_uppercase();
-            if name != &*uc {
-                cx.span_lint(NON_UPPER_CASE_GLOBALS,
-                             span,
-                             &format!("{} `{}` should have an upper case name such as `{}`",
-                                      sort,
-                                      name,
-                                      uc));
-            } else {
-                cx.span_lint(NON_UPPER_CASE_GLOBALS,
-                             span,
-                             &format!("{} `{}` should have an upper case name", sort, name));
-            }
+    fn check_upper_case(cx: &LateContext, sort: &str, ident: &Ident) {
+        let name = &ident.name.as_str();
+
+        if name.chars().any(|c| c.is_lowercase()) {
+            let uc = NonSnakeCase::to_snake_case(&name).to_uppercase();
+
+            let msg = format!("{} `{}` should have an upper case name", sort, name);
+            cx.struct_span_lint(NON_UPPER_CASE_GLOBALS, ident.span, &msg)
+                .span_suggestion_with_applicability(
+                    ident.span,
+                    "convert the identifier to upper case",
+                    uc,
+                    Applicability::MaybeIncorrect,
+                )
+                .emit();
         }
     }
 }
@@ -350,38 +389,25 @@ fn get_lints(&self) -> LintArray {
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals {
     fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
         match it.node {
-            hir::ItemKind::Static(..) => {
-                if attr::find_by_name(&it.attrs, "no_mangle").is_some() {
-                    return;
-                }
-                NonUpperCaseGlobals::check_upper_case(cx, "static variable", it.ident.name,
-                                                      it.span);
+            hir::ItemKind::Static(..) if !attr::contains_name(&it.attrs, "no_mangle") => {
+                NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident);
             }
             hir::ItemKind::Const(..) => {
-                NonUpperCaseGlobals::check_upper_case(cx, "constant", it.ident.name,
-                                                      it.span);
+                NonUpperCaseGlobals::check_upper_case(cx, "constant", &it.ident);
             }
             _ => {}
         }
     }
 
     fn check_trait_item(&mut self, cx: &LateContext, ti: &hir::TraitItem) {
-        match ti.node {
-            hir::TraitItemKind::Const(..) => {
-                NonUpperCaseGlobals::check_upper_case(cx, "associated constant",
-                                                      ti.ident.name, ti.span);
-            }
-            _ => {}
+        if let hir::TraitItemKind::Const(..) = ti.node {
+            NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ti.ident);
         }
     }
 
     fn check_impl_item(&mut self, cx: &LateContext, ii: &hir::ImplItem) {
-        match ii.node {
-            hir::ImplItemKind::Const(..) => {
-                NonUpperCaseGlobals::check_upper_case(cx, "associated constant",
-                                                      ii.ident.name, ii.span);
-            }
-            _ => {}
+        if let hir::ImplItemKind::Const(..) = ii.node {
+            NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ii.ident);
         }
     }
 
@@ -390,10 +416,11 @@ fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
         if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.node {
             if let Def::Const(..) = path.def {
                 if path.segments.len() == 1 {
-                    NonUpperCaseGlobals::check_upper_case(cx,
-                                                          "constant in pattern",
-                                                          path.segments[0].ident.name,
-                                                          path.span);
+                    NonUpperCaseGlobals::check_upper_case(
+                        cx,
+                        "constant in pattern",
+                        &path.segments[0].ident
+                    );
                 }
             }
         }
index 98cf20a7ba7f40901a7bc2e902969c9c2fe04f8e..d4a3ae273fcd40935aae7a13ed48a61a2918c972 100644 (file)
@@ -236,6 +236,7 @@ fn main() {
     }
 
     let llvm_static_stdcpp = env::var_os("LLVM_STATIC_STDCPP");
+    let llvm_use_libcxx = env::var_os("LLVM_USE_LIBCXX");
 
     let stdcppname = if target.contains("openbsd") {
         // llvm-config on OpenBSD doesn't mention stdlib=libc++
@@ -245,6 +246,8 @@ fn main() {
     } else if target.contains("netbsd") && llvm_static_stdcpp.is_some() {
         // NetBSD uses a separate library when relocation is required
         "stdc++_pic"
+    } else if llvm_use_libcxx.is_some() {
+        "c++"
     } else {
         "stdc++"
     };
index 7f7d168ac0321265bca12cbb2d27fb1e3800ba00..233db12b03001967b728223f2759258cf51d80c9 100644 (file)
@@ -327,10 +327,8 @@ pub(super) fn report_conflicting_borrow(
             "closure"
         };
 
-        let desc_place = self.describe_place(place).unwrap_or_else(|| "_".to_owned());
-        let tcx = self.infcx.tcx;
-
-        let first_borrow_desc;
+        let (desc_place, msg_place, msg_borrow, union_type_name) =
+            self.describe_place_for_conflicting_borrow(place, &issued_borrow.borrowed_place);
 
         let explanation = self.explain_why_borrow_contains_point(context, issued_borrow, None);
         let second_borrow_desc = if explanation.is_explained() {
@@ -340,6 +338,8 @@ pub(super) fn report_conflicting_borrow(
         };
 
         // FIXME: supply non-"" `opt_via` when appropriate
+        let tcx = self.infcx.tcx;
+        let first_borrow_desc;
         let mut err = match (
             gen_borrow_kind,
             "immutable",
@@ -353,12 +353,12 @@ pub(super) fn report_conflicting_borrow(
                 tcx.cannot_reborrow_already_borrowed(
                     span,
                     &desc_place,
-                    "",
+                    &msg_place,
                     lft,
                     issued_span,
                     "it",
                     rgt,
-                    "",
+                    &msg_borrow,
                     None,
                     Origin::Mir,
                 )
@@ -368,12 +368,12 @@ pub(super) fn report_conflicting_borrow(
                 tcx.cannot_reborrow_already_borrowed(
                     span,
                     &desc_place,
-                    "",
+                    &msg_place,
                     lft,
                     issued_span,
                     "it",
                     rgt,
-                    "",
+                    &msg_borrow,
                     None,
                     Origin::Mir,
                 )
@@ -384,9 +384,9 @@ pub(super) fn report_conflicting_borrow(
                 tcx.cannot_mutably_borrow_multiply(
                     span,
                     &desc_place,
-                    "",
+                    &msg_place,
                     issued_span,
-                    "",
+                    &msg_borrow,
                     None,
                     Origin::Mir,
                 )
@@ -510,12 +510,118 @@ pub(super) fn report_conflicting_borrow(
             );
         }
 
+        if union_type_name != "" {
+            err.note(&format!(
+                "`{}` is a field of the union `{}`, so it overlaps the field `{}`",
+                msg_place, union_type_name, msg_borrow,
+            ));
+        }
+
         explanation
             .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, first_borrow_desc);
 
         err.buffer(&mut self.errors_buffer);
     }
 
+    /// Returns the description of the root place for a conflicting borrow and the full
+    /// descriptions of the places that caused the conflict.
+    ///
+    /// In the simplest case, where there are no unions involved, if a mutable borrow of `x` is
+    /// attempted while a shared borrow is live, then this function will return:
+    ///
+    ///     ("x", "", "")
+    ///
+    /// In the simple union case, if a mutable borrow of a union field `x.z` is attempted while
+    /// a shared borrow of another field `x.y`, then this function will return:
+    ///
+    ///     ("x", "x.z", "x.y")
+    ///
+    /// In the more complex union case, where the union is a field of a struct, then if a mutable
+    /// borrow of a union field in a struct `x.u.z` is attempted while a shared borrow of
+    /// another field `x.u.y`, then this function will return:
+    ///
+    ///     ("x.u", "x.u.z", "x.u.y")
+    ///
+    /// This is used when creating error messages like below:
+    ///
+    /// >  cannot borrow `a.u` (via `a.u.z.c`) as immutable because it is also borrowed as
+    /// >  mutable (via `a.u.s.b`) [E0502]
+    pub(super) fn describe_place_for_conflicting_borrow(
+        &self,
+        first_borrowed_place: &Place<'tcx>,
+        second_borrowed_place: &Place<'tcx>,
+    ) -> (String, String, String, String) {
+        // Define a small closure that we can use to check if the type of a place
+        // is a union.
+        let is_union = |place: &Place<'tcx>| -> bool {
+            place.ty(self.mir, self.infcx.tcx)
+                .to_ty(self.infcx.tcx)
+                .ty_adt_def()
+                .map(|adt| adt.is_union())
+                .unwrap_or(false)
+        };
+
+        // Start with an empty tuple, so we can use the functions on `Option` to reduce some
+        // code duplication (particularly around returning an empty description in the failure
+        // case).
+        Some(())
+            .filter(|_| {
+                // If we have a conflicting borrow of the same place, then we don't want to add
+                // an extraneous "via x.y" to our diagnostics, so filter out this case.
+                first_borrowed_place != second_borrowed_place
+            })
+            .and_then(|_| {
+                // We're going to want to traverse the first borrowed place to see if we can find
+                // field access to a union. If we find that, then we will keep the place of the
+                // union being accessed and the field that was being accessed so we can check the
+                // second borrowed place for the same union and a access to a different field.
+                let mut current = first_borrowed_place;
+                while let Place::Projection(box PlaceProjection { base, elem }) = current {
+                    match elem {
+                        ProjectionElem::Field(field, _) if is_union(base) => {
+                            return Some((base, field));
+                        },
+                        _ => current = base,
+                    }
+                }
+                None
+            })
+            .and_then(|(target_base, target_field)| {
+                // With the place of a union and a field access into it, we traverse the second
+                // borrowed place and look for a access to a different field of the same union.
+                let mut current = second_borrowed_place;
+                while let Place::Projection(box PlaceProjection { base, elem }) = current {
+                    match elem {
+                        ProjectionElem::Field(field, _) if {
+                            is_union(base) && field != target_field && base == target_base
+                        } => {
+                            let desc_base = self.describe_place(base)
+                                .unwrap_or_else(|| "_".to_owned());
+                            let desc_first = self.describe_place(first_borrowed_place)
+                                .unwrap_or_else(|| "_".to_owned());
+                            let desc_second = self.describe_place(second_borrowed_place)
+                                .unwrap_or_else(|| "_".to_owned());
+
+                            // Also compute the name of the union type, eg. `Foo` so we
+                            // can add a helpful note with it.
+                            let ty = base.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx);
+
+                            return Some((desc_base, desc_first, desc_second, ty.to_string()));
+                        },
+                        _ => current = base,
+                    }
+                }
+                None
+            })
+            .unwrap_or_else(|| {
+                // If we didn't find a field access into a union, or both places match, then
+                // only return the description of the first place.
+                let desc_place = self.describe_place(first_borrowed_place)
+                    .unwrap_or_else(|| "_".to_owned());
+                (desc_place, "".to_string(), "".to_string(), "".to_string())
+            })
+    }
+
     /// Reports StorageDeadOrDrop of `place` conflicts with `borrow`.
     ///
     /// This means that some data referenced by `borrow` needs to live
index a66da50c484379cb0be70f52c1b946b23ffa6f77..e0fc90931696e57851889e5f8286f9d083d711a6 100644 (file)
@@ -67,7 +67,6 @@ fn expr_as_rvalue(
                 block.and(Rvalue::Repeat(value_operand, count))
             }
             ExprKind::Borrow {
-                region,
                 borrow_kind,
                 arg,
             } => {
@@ -75,7 +74,7 @@ fn expr_as_rvalue(
                     BorrowKind::Shared => unpack!(block = this.as_read_only_place(block, arg)),
                     _ => unpack!(block = this.as_place(block, arg)),
                 };
-                block.and(Rvalue::Ref(region, borrow_kind, arg_place))
+                block.and(Rvalue::Ref(this.hir.tcx().types.re_erased, borrow_kind, arg_place))
             }
             ExprKind::Binary { op, lhs, rhs } => {
                 let lhs = unpack!(block = this.as_operand(block, scope, lhs));
@@ -249,11 +248,10 @@ fn expr_as_rvalue(
                                             BorrowKind::Mut {
                                                 allow_two_phase_borrow: false,
                                             },
-                                        region,
                                         arg,
                                     } => unpack!(
                                         block = this.limit_capture_mutability(
-                                            upvar.span, upvar.ty, scope, block, arg, region,
+                                            upvar.span, upvar.ty, scope, block, arg,
                                         )
                                     ),
                                     _ => unpack!(block = this.as_operand(block, scope, upvar)),
@@ -500,7 +498,6 @@ fn limit_capture_mutability(
         temp_lifetime: Option<region::Scope>,
         mut block: BasicBlock,
         arg: ExprRef<'tcx>,
-        region: &'tcx ty::RegionKind,
     ) -> BlockAnd<Operand<'tcx>> {
         let this = self;
 
@@ -582,7 +579,7 @@ fn limit_capture_mutability(
             block,
             source_info,
             &Place::Local(temp),
-            Rvalue::Ref(region, borrow_kind, arg_place),
+            Rvalue::Ref(this.hir.tcx().types.re_erased, borrow_kind, arg_place),
         );
 
         // In constants, temp_lifetime is None. We should not need to drop
index bc7bb485563ad99b52fd07dbbe56bd8aa2fc4bfa..d52ce9a67d29a87dd4a35dfb68c7260dfb716e41 100644 (file)
@@ -640,7 +640,7 @@ struct Binding<'tcx> {
     var_id: NodeId,
     var_ty: Ty<'tcx>,
     mutability: Mutability,
-    binding_mode: BindingMode<'tcx>,
+    binding_mode: BindingMode,
 }
 
 /// Indicates that the type of `source` must be a subtype of the
@@ -1369,7 +1369,7 @@ fn bind_matched_candidate_for_guard(
         // Assign each of the bindings. Since we are binding for a
         // guard expression, this will never trigger moves out of the
         // candidate.
-        let re_empty = self.hir.tcx().types.re_empty;
+        let re_erased = self.hir.tcx().types.re_erased;
         for binding in bindings {
             let source_info = self.source_info(binding.span);
 
@@ -1385,11 +1385,11 @@ fn bind_matched_candidate_for_guard(
             self.schedule_drop_for_binding(binding.var_id, binding.span, RefWithinGuard);
             match binding.binding_mode {
                 BindingMode::ByValue => {
-                    let rvalue = Rvalue::Ref(re_empty, BorrowKind::Shared, binding.source.clone());
+                    let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, binding.source.clone());
                     self.cfg
                         .push_assign(block, source_info, &ref_for_guard, rvalue);
                 }
-                BindingMode::ByRef(region, borrow_kind) => {
+                BindingMode::ByRef(borrow_kind) => {
                     // Tricky business: For `ref id` and `ref mut id`
                     // patterns, we want `id` within the guard to
                     // correspond to a temp of type `& &T` or `& &mut
@@ -1429,10 +1429,10 @@ fn bind_matched_candidate_for_guard(
                             allow_two_phase_borrow: true,
                         },
                     };
-                    let rvalue = Rvalue::Ref(region, borrow_kind, binding.source.clone());
+                    let rvalue = Rvalue::Ref(re_erased, borrow_kind, binding.source.clone());
                     self.cfg
                         .push_assign(block, source_info, &val_for_guard, rvalue);
-                    let rvalue = Rvalue::Ref(region, BorrowKind::Shared, val_for_guard);
+                    let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, val_for_guard);
                     self.cfg
                         .push_assign(block, source_info, &ref_for_guard, rvalue);
                 }
@@ -1450,6 +1450,8 @@ fn bind_matched_candidate_for_arm_body(
             block, bindings
         );
 
+
+        let re_erased = self.hir.tcx().types.re_erased;
         // Assign each of the bindings. This may trigger moves out of the candidate.
         for binding in bindings {
             let source_info = self.source_info(binding.span);
@@ -1460,8 +1462,8 @@ fn bind_matched_candidate_for_arm_body(
                 BindingMode::ByValue => {
                     Rvalue::Use(self.consume_by_copy_or_move(binding.source.clone()))
                 }
-                BindingMode::ByRef(region, borrow_kind) => {
-                    Rvalue::Ref(region, borrow_kind, binding.source.clone())
+                BindingMode::ByRef(borrow_kind) => {
+                    Rvalue::Ref(re_erased, borrow_kind, binding.source.clone())
                 }
             };
             self.cfg.push_assign(block, source_info, &local, rvalue);
@@ -1507,7 +1509,7 @@ fn declare_binding(
         let tcx = self.hir.tcx();
         let binding_mode = match mode {
             BindingMode::ByValue => ty::BindingMode::BindByValue(mutability.into()),
-            BindingMode::ByRef { .. } => ty::BindingMode::BindByReference(mutability.into()),
+            BindingMode::ByRef(_) => ty::BindingMode::BindByReference(mutability.into()),
         };
         debug!("declare_binding: user_ty={:?}", user_ty);
         let local = LocalDecl::<'tcx> {
@@ -1545,7 +1547,7 @@ fn declare_binding(
             let ref_for_guard = self.local_decls.push(LocalDecl::<'tcx> {
                 // See previous comment.
                 mutability: Mutability::Not,
-                ty: tcx.mk_imm_ref(tcx.types.re_empty, var_ty),
+                ty: tcx.mk_imm_ref(tcx.types.re_erased, var_ty),
                 user_ty: UserTypeProjections::none(),
                 name: Some(name),
                 source_info,
@@ -1614,7 +1616,7 @@ fn add_fake_borrows<'pat>(
 
         for (matched_place, borrow_kind) in all_fake_borrows {
             let borrowed_input =
-                Rvalue::Ref(tcx.types.re_empty, borrow_kind, matched_place.clone());
+                Rvalue::Ref(tcx.types.re_erased, borrow_kind, matched_place.clone());
             let borrowed_input_ty = borrowed_input.ty(&self.local_decls, tcx);
             let borrowed_input_temp = self.temp(borrowed_input_ty, source_info.span);
             self.cfg.push_assign(
index aae3de68aaae08996e1c853bd2532b5291374d66..696c173b048ad282227269634a70847bd5a5ac19 100644 (file)
@@ -304,17 +304,16 @@ pub fn perform_test(&mut self,
                     let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, &[ty.into()]);
                     let method = self.hir.tcx().intern_lazy_const(ty::LazyConst::Evaluated(method));
 
+                    let re_erased = self.hir.tcx().types.re_erased;
                     // take the argument by reference
-                    let region_scope = self.topmost_scope();
-                    let region = self.hir.tcx().mk_region(ty::ReScope(region_scope));
                     let tam = ty::TypeAndMut {
                         ty,
                         mutbl: Mutability::MutImmutable,
                     };
-                    let ref_ty = self.hir.tcx().mk_ref(region, tam);
+                    let ref_ty = self.hir.tcx().mk_ref(re_erased, tam);
 
                     // let lhs_ref_place = &lhs;
-                    let ref_rvalue = Rvalue::Ref(region, BorrowKind::Shared, place);
+                    let ref_rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, place);
                     let lhs_ref_place = self.temp(ref_ty, test.span);
                     self.cfg.push_assign(block, source_info, &lhs_ref_place, ref_rvalue);
                     let val = Operand::Move(lhs_ref_place);
@@ -324,7 +323,7 @@ pub fn perform_test(&mut self,
                     self.cfg.push_assign(block, source_info, &rhs_place, Rvalue::Use(expect));
 
                     // let rhs_ref_place = &rhs_place;
-                    let ref_rvalue = Rvalue::Ref(region, BorrowKind::Shared, rhs_place);
+                    let ref_rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, rhs_place);
                     let rhs_ref_place = self.temp(ref_ty, test.span);
                     self.cfg.push_assign(block, source_info, &rhs_ref_place, ref_rvalue);
                     let expect = Operand::Move(rhs_ref_place);
index 727b769cf4d4443931087f8ea7ef25e716fc81d7..65ae111fbc0fcba1bf6b93c25aa565d671ea53b4 100644 (file)
@@ -4,7 +4,7 @@
 use hair::{LintLevel, BindingMode, PatternKind};
 use rustc::hir;
 use rustc::hir::Node;
-use rustc::hir::def_id::{DefId, LocalDefId};
+use rustc::hir::def_id::DefId;
 use rustc::middle::region;
 use rustc::mir::*;
 use rustc::mir::visit::{MutVisitor, TyContext};
@@ -640,21 +640,29 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
     let arguments: Vec<_> = arguments.collect();
 
     let tcx = hir.tcx();
-    let span = tcx.hir().span(fn_id);
+    let tcx_hir = tcx.hir();
+    let span = tcx_hir.span(fn_id);
+
+    let hir_tables = hir.tables();
+    let fn_def_id = tcx_hir.local_def_id(fn_id);
 
     // Gather the upvars of a closure, if any.
-    let upvar_decls: Vec<_> = tcx.with_freevars(fn_id, |freevars| {
-        freevars.iter().map(|fv| {
-            let var_id = fv.var_id();
-            let var_hir_id = tcx.hir().node_to_hir_id(var_id);
-            let closure_expr_id = tcx.hir().local_def_id(fn_id);
-            let capture = hir.tables().upvar_capture(ty::UpvarId {
-                var_path: ty::UpvarPath {hir_id: var_hir_id},
-                closure_expr_id: LocalDefId::from_def_id(closure_expr_id),
-            });
+    // In analyze_closure() in upvar.rs we gathered a list of upvars used by a
+    // closure and we stored in a map called upvar_list in TypeckTables indexed
+    // with the closure's DefId. Here, we run through that vec of UpvarIds for
+    // the given closure and use the necessary information to create UpvarDecl.
+    let upvar_decls: Vec<_> = hir_tables
+        .upvar_list
+        .get(&fn_def_id)
+        .into_iter()
+        .flatten()
+        .map(|upvar_id| {
+            let var_hir_id = upvar_id.var_path.hir_id;
+            let var_node_id = tcx_hir.hir_to_node_id(var_hir_id);
+            let capture = hir_tables.upvar_capture(*upvar_id);
             let by_ref = match capture {
                 ty::UpvarCapture::ByValue => false,
-                ty::UpvarCapture::ByRef(..) => true
+                ty::UpvarCapture::ByRef(..) => true,
             };
             let mut decl = UpvarDecl {
                 debug_name: keywords::Invalid.name(),
@@ -662,10 +670,9 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
                 by_ref,
                 mutability: Mutability::Not,
             };
-            if let Some(Node::Binding(pat)) = tcx.hir().find(var_id) {
+            if let Some(Node::Binding(pat)) = tcx_hir.find(var_node_id) {
                 if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
                     decl.debug_name = ident.name;
-
                     if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
                         if bm == ty::BindByValue(hir::MutMutable) {
                             decl.mutability = Mutability::Mut;
@@ -678,8 +685,8 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
                 }
             }
             decl
-        }).collect()
-    });
+        })
+        .collect();
 
     let mut builder = Builder::new(hir,
         span,
@@ -689,7 +696,6 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
         return_ty_span,
         upvar_decls);
 
-    let fn_def_id = tcx.hir().local_def_id(fn_id);
     let call_site_scope = region::Scope {
         id: body.value.hir_id.local_id,
         data: region::ScopeData::CallSite
@@ -732,7 +738,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
         // RustCall pseudo-ABI untuples the last argument.
         spread_arg = Some(Local::new(arguments.len()));
     }
-    let closure_expr_id = tcx.hir().local_def_id(fn_id);
+    let closure_expr_id = tcx_hir.local_def_id(fn_id);
     info!("fn_id {:?} has attrs {:?}", closure_expr_id,
           tcx.get_attrs(closure_expr_id));
 
index 01177e5e49a0ef1042e70f421ee6f1e4471b2c57..f5f40481679385eae8372f11e161f48ae8132ccb 100644 (file)
 /// Should be a power of two for performance reasons.
 const DETECTOR_SNAPSHOT_PERIOD: isize = 256;
 
+/// Warning: do not use this function if you expect to start interpreting the given `Mir`.
+/// The `EvalContext` is only meant to be used to query values from constants and statics.
+///
+/// This function is used during const propagation. We cannot use `mk_eval_cx`, because copy
+/// propagation happens *during* the computation of the MIR of the current function. So if we
+/// tried to call the `optimized_mir` query, we'd get a cycle error because we are (transitively)
+/// inside the `optimized_mir` query of the `Instance` given.
+///
+/// Since we are looking at the MIR of the function in an abstract manner, we don't have a
+/// `ParamEnv` available to us. This function creates a `ParamEnv` for the given instance.
 pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     instance: Instance<'tcx>,
@@ -43,9 +53,22 @@ pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
 ) -> EvalResult<'tcx, CompileTimeEvalContext<'a, 'mir, 'tcx>> {
     debug!("mk_borrowck_eval_cx: {:?}", instance);
     let param_env = tcx.param_env(instance.def_id());
+    mk_eval_cx_inner(tcx, instance, mir, span, param_env)
+}
+
+/// This is just a helper function to reduce code duplication between `mk_borrowck_eval_cx` and
+/// `mk_eval_cx`. Do not call this function directly.
+fn mk_eval_cx_inner<'a, 'mir, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    instance: Instance<'tcx>,
+    mir: &'mir mir::Mir<'tcx>,
+    span: Span,
+    param_env: ty::ParamEnv<'tcx>,
+) -> EvalResult<'tcx, CompileTimeEvalContext<'a, 'mir, 'tcx>> {
     let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeInterpreter::new());
-    // insert a stack frame so any queries have the correct substs
-    // cannot use `push_stack_frame`; if we do `const_prop` explodes
+    // Insert a stack frame so any queries have the correct substs.
+    // We also avoid all the extra work performed by push_stack_frame,
+    // like initializing local variables
     ecx.stack.push(interpret::Frame {
         block: mir::START_BLOCK,
         locals: IndexVec::new(),
@@ -60,24 +83,23 @@ pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
     Ok(ecx)
 }
 
-pub fn mk_eval_cx<'a, 'tcx>(
+/// Warning: do not use this function if you expect to start interpreting the given `Mir`.
+/// The `EvalContext` is only meant to be used to do field and index projections into constants for
+/// `simd_shuffle` and const patterns in match arms.
+///
+/// The function containing the `match` that is currently being analyzed may have generic bounds
+/// that inform us about the generic bounds of the constant. E.g. using an associated constant
+/// of a function's generic parameter will require knowledge about the bounds on the generic
+/// parameter. These bounds are passed to `mk_eval_cx` via the `ParamEnv` argument.
+fn mk_eval_cx<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     instance: Instance<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
 ) -> EvalResult<'tcx, CompileTimeEvalContext<'a, 'tcx, 'tcx>> {
     debug!("mk_eval_cx: {:?}, {:?}", instance, param_env);
     let span = tcx.def_span(instance.def_id());
-    let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeInterpreter::new());
-    let mir = ecx.load_mir(instance.def)?;
-    // insert a stack frame so any queries have the correct substs
-    ecx.push_stack_frame(
-        instance,
-        mir.span,
-        mir,
-        None,
-        StackPopCleanup::Goto(None), // never pop
-    )?;
-    Ok(ecx)
+    let mir = tcx.optimized_mir(instance.def.def_id());
+    mk_eval_cx_inner(tcx, instance, mir, span, param_env)
 }
 
 pub(crate) fn eval_promoted<'a, 'mir, 'tcx>(
index 7e8ac3fb72006a4f695058f266a98a3f6620d941..ea9e19c75c215473058f94a889116a58cd4c4253 100644 (file)
@@ -325,11 +325,13 @@ struct X { x: (), }
 "##,
 
 E0162: r##"
+#### Note: this error code is no longer emitted by the compiler.
+
 An if-let pattern attempts to match the pattern, and enters the body if the
 match was successful. If the match is irrefutable (when it cannot fail to
 match), use a regular `let`-binding instead. For instance:
 
-```compile_fail,E0162
+```compile_pass
 struct Irrefutable(i32);
 let irr = Irrefutable(0);
 
@@ -352,11 +354,13 @@ struct X { x: (), }
 "##,
 
 E0165: r##"
+#### Note: this error code is no longer emitted by the compiler.
+
 A while-let pattern attempts to match the pattern, and enters the body if the
 match was successful. If the match is irrefutable (when it cannot fail to
 match), use a regular `let`-binding inside a `loop` instead. For instance:
 
-```compile_fail,E0165
+```compile_pass,no_run
 struct Irrefutable(i32);
 let irr = Irrefutable(0);
 
@@ -569,7 +573,7 @@ pub enum Method { GET, POST }
 ```
 "##,
 
-// FIXME(#24111) Change the language here when const fn stabilizes
+// FIXME(#57563) Change the language here when const fn stabilizes
 E0015: r##"
 The only functions that can be called in static or constant expressions are
 `const` functions, and struct/enum constructors. `const` functions are only
@@ -2334,7 +2338,7 @@ fn bar(x: &i32) -> &i32 { x }
 Temporaries are not always dropped at the end of the enclosing
 statement. In simple cases where the `&` expression is immediately
 stored into a variable, the compiler will automatically extend
-the lifetime of the temporary until the end of the enclosinb
+the lifetime of the temporary until the end of the enclosing
 block. Therefore, an alternative way to fix the original
 program is to write `let tmp = &foo()` and not `let tmp = foo()`:
 
index 532e6783f2f2bc38dd49aa1f5b7b202732ee9994..eb536fbcf69bb9683484cc2c2a862a22c5109415 100644 (file)
@@ -124,7 +124,6 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                                   }),
                 span,
                 kind: ExprKind::Borrow {
-                    region: deref.region,
                     borrow_kind: deref.mutbl.to_borrow_kind(),
                     arg: expr.to_ref(),
                 },
@@ -132,32 +131,24 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
 
             overloaded_place(cx, hir_expr, adjustment.target, Some(call), vec![expr.to_ref()])
         }
-        Adjust::Borrow(AutoBorrow::Ref(r, m)) => {
+        Adjust::Borrow(AutoBorrow::Ref(_, m)) => {
             ExprKind::Borrow {
-                region: r,
                 borrow_kind: m.to_borrow_kind(),
                 arg: expr.to_ref(),
             }
         }
         Adjust::Borrow(AutoBorrow::RawPtr(m)) => {
             // Convert this to a suitable `&foo` and
-            // then an unsafe coercion. Limit the region to be just this
-            // expression.
-            let region = ty::ReScope(region::Scope {
-                id: hir_expr.hir_id.local_id,
-                data: region::ScopeData::Node
-            });
-            let region = cx.tcx.mk_region(region);
+            // then an unsafe coercion.
             expr = Expr {
                 temp_lifetime,
-                ty: cx.tcx.mk_ref(region,
+                ty: cx.tcx.mk_ref(cx.tcx.types.re_erased,
                                   ty::TypeAndMut {
                                     ty: expr.ty,
                                     mutbl: m,
                                   }),
                 span,
                 kind: ExprKind::Borrow {
-                    region,
                     borrow_kind: m.to_borrow_kind(),
                     arg: expr.to_ref(),
                 },
@@ -323,12 +314,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
         }
 
         hir::ExprKind::AddrOf(mutbl, ref expr) => {
-            let region = match expr_ty.sty {
-                ty::Ref(r, _, _) => r,
-                _ => span_bug!(expr.span, "type of & not region"),
-            };
             ExprKind::Borrow {
-                region,
                 borrow_kind: mutbl.to_borrow_kind(),
                 arg: expr.to_ref(),
             }
@@ -1222,7 +1208,6 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                 ty: freevar_ty,
                 span: closure_expr.span,
                 kind: ExprKind::Borrow {
-                    region: upvar_borrow.region,
                     borrow_kind,
                     arg: captured_var.to_ref(),
                 },
index 676b98457489f81d76bf62982e99cf35b926e7f2..e902423cd30fc5170192e92a80cbc5ebb40a31a0 100644 (file)
@@ -9,7 +9,7 @@
 use rustc::infer::canonical::Canonical;
 use rustc::middle::region;
 use rustc::ty::subst::Substs;
-use rustc::ty::{AdtDef, UpvarSubsts, Region, Ty, Const, LazyConst, UserTypeAnnotation};
+use rustc::ty::{AdtDef, UpvarSubsts, Ty, Const, LazyConst, UserTypeAnnotation};
 use rustc::ty::layout::VariantIdx;
 use rustc::hir;
 use syntax::ast;
@@ -235,7 +235,6 @@ pub enum ExprKind<'tcx> {
         id: DefId,
     },
     Borrow {
-        region: Region<'tcx>,
         borrow_kind: BorrowKind,
         arg: ExprRef<'tcx>,
     },
index b25d47b390175ba7790049a1cef72ecf1803234a..188a1120442983dfba44c786cb5a4b6047a04590 100644 (file)
@@ -1372,7 +1372,14 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>,
                     let is_visible = adt.is_enum()
                         || field.vis.is_accessible_from(cx.module, cx.tcx);
                     if is_visible {
-                        field.ty(cx.tcx, substs)
+                        let ty = field.ty(cx.tcx, substs);
+                        match ty.sty {
+                            // If the field type returned is an array of an unknown
+                            // size return an TyErr.
+                            ty::Array(_, len) if len.assert_usize(cx.tcx).is_none() =>
+                                cx.tcx.types.err,
+                            _ => ty,
+                        }
                     } else {
                         // Treat all non-visible fields as TyErr. They
                         // can't appear in any other pattern from
index c104af7a7d81bd6dd177caf68fea14faaa59872d..10213beba2a6df74d420ecc50afdc864a32654d5 100644 (file)
@@ -350,7 +350,6 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
 {
     let mut seen = Matrix::empty();
     let mut catchall = None;
-    let mut printed_if_let_err = false;
     for (arm_index, &(ref pats, guard)) in arms.iter().enumerate() {
         for &(pat, hir_pat) in pats {
             let v = smallvec![pat];
@@ -359,27 +358,12 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                 NotUseful => {
                     match source {
                         hir::MatchSource::IfLetDesugar { .. } => {
-                            if cx.tcx.features().irrefutable_let_patterns {
-                                cx.tcx.lint_node(
-                                    lint::builtin::IRREFUTABLE_LET_PATTERNS,
-                                    hir_pat.id, pat.span,
-                                    "irrefutable if-let pattern");
-                            } else {
-                                if printed_if_let_err {
-                                    // we already printed an irrefutable if-let pattern error.
-                                    // We don't want two, that's just confusing.
-                                } else {
-                                    // find the first arm pattern so we can use its span
-                                    let &(ref first_arm_pats, _) = &arms[0];
-                                    let first_pat = &first_arm_pats[0];
-                                    let span = first_pat.0.span;
-                                    struct_span_err!(cx.tcx.sess, span, E0162,
-                                                    "irrefutable if-let pattern")
-                                        .span_label(span, "irrefutable pattern")
-                                        .emit();
-                                    printed_if_let_err = true;
-                                }
-                            }
+                            cx.tcx.lint_node(
+                                lint::builtin::IRREFUTABLE_LET_PATTERNS,
+                                hir_pat.id,
+                                pat.span,
+                                "irrefutable if-let pattern",
+                            );
                         }
 
                         hir::MatchSource::WhileLetDesugar => {
@@ -394,21 +378,12 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                                 },
                                 // The arm with the wildcard pattern.
                                 1 => {
-                                    if cx.tcx.features().irrefutable_let_patterns {
-                                        cx.tcx.lint_node(
-                                            lint::builtin::IRREFUTABLE_LET_PATTERNS,
-                                            hir_pat.id, pat.span,
-                                            "irrefutable while-let pattern");
-                                    } else {
-                                        // find the first arm pattern so we can use its span
-                                        let &(ref first_arm_pats, _) = &arms[0];
-                                        let first_pat = &first_arm_pats[0];
-                                        let span = first_pat.0.span;
-                                        struct_span_err!(cx.tcx.sess, span, E0165,
-                                                         "irrefutable while-let pattern")
-                                            .span_label(span, "irrefutable pattern")
-                                            .emit();
-                                    }
+                                    cx.tcx.lint_node(
+                                        lint::builtin::IRREFUTABLE_LET_PATTERNS,
+                                        hir_pat.id,
+                                        pat.span,
+                                        "irrefutable while-let pattern",
+                                    );
                                 },
                                 _ => bug!(),
                             }
index 761bca21fec03e551e95dad283b117c7c694fafe..8991a90737c7ed775a1a66a7081a966f88bc408b 100644 (file)
@@ -39,9 +39,9 @@ pub enum PatternError {
 }
 
 #[derive(Copy, Clone, Debug)]
-pub enum BindingMode<'tcx> {
+pub enum BindingMode {
     ByValue,
-    ByRef(Region<'tcx>, BorrowKind),
+    ByRef(BorrowKind),
 }
 
 #[derive(Clone, Debug)]
@@ -117,7 +117,7 @@ pub enum PatternKind<'tcx> {
     Binding {
         mutability: Mutability,
         name: ast::Name,
-        mode: BindingMode<'tcx>,
+        mode: BindingMode,
         var: ast::NodeId,
         ty: Ty<'tcx>,
         subpattern: Option<Pattern<'tcx>>,
@@ -181,7 +181,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             PatternKind::Binding { mutability, name, mode, ref subpattern, .. } => {
                 let is_mut = match mode {
                     BindingMode::ByValue => mutability == Mutability::Mut,
-                    BindingMode::ByRef(_, bk) => {
+                    BindingMode::ByRef(bk) => {
                         write!(f, "ref ")?;
                         match bk { BorrowKind::Mut { .. } => true, _ => false }
                     }
@@ -512,12 +512,9 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
 
             PatKind::Binding(_, id, ident, ref sub) => {
                 let var_ty = self.tables.node_id_to_type(pat.hir_id);
-                let region = match var_ty.sty {
-                    ty::Ref(r, _, _) => Some(r),
-                    ty::Error => { // Avoid ICE
-                        return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
-                    }
-                    _ => None,
+                if let ty::Error = var_ty.sty {
+                    // Avoid ICE
+                    return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
                 };
                 let bm = *self.tables.pat_binding_modes().get(pat.hir_id)
                                                          .expect("missing binding mode");
@@ -528,10 +525,10 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
                         (Mutability::Not, BindingMode::ByValue),
                     ty::BindByReference(hir::MutMutable) =>
                         (Mutability::Not, BindingMode::ByRef(
-                            region.unwrap(), BorrowKind::Mut { allow_two_phase_borrow: false })),
+                            BorrowKind::Mut { allow_two_phase_borrow: false })),
                     ty::BindByReference(hir::MutImmutable) =>
                         (Mutability::Not, BindingMode::ByRef(
-                            region.unwrap(), BorrowKind::Shared)),
+                            BorrowKind::Shared)),
                 };
 
                 // A ref x pattern is the same node used for x, and as such it has
@@ -1042,7 +1039,7 @@ fn super_fold_with<F: PatternFolder<$lt_tcx>>(&self, _: &mut F) -> Self {
 
 CloneImpls!{ <'tcx>
     Span, Field, Mutability, ast::Name, ast::NodeId, usize, ty::Const<'tcx>,
-    Region<'tcx>, Ty<'tcx>, BindingMode<'tcx>, &'tcx AdtDef,
+    Region<'tcx>, Ty<'tcx>, BindingMode, &'tcx AdtDef,
     &'tcx Substs<'tcx>, &'tcx Kind<'tcx>, UserTypeAnnotation<'tcx>,
     UserTypeProjection<'tcx>, PatternTypeProjection<'tcx>
 }
index 4735ebae9d42e8ef61b33bf7a7d477ee10c56729..9395da60b3886f0d1debb676f1dfcf445e25f2bf 100644 (file)
@@ -24,7 +24,7 @@
 #![feature(unicode_internals)]
 #![feature(step_trait)]
 #![feature(slice_concat_ext)]
-#![feature(if_while_or_patterns)]
+#![cfg_attr(stage0, feature(if_while_or_patterns))]
 #![feature(try_from)]
 #![feature(reverse_bits)]
 #![cfg_attr(stage0, feature(underscore_imports))]
index a04dd5bb5970f4045f29bc3ffcd1944778f9f1ba..78cf7153500c9d19251e74e34fd964bcd1413f5e 100644 (file)
@@ -21,7 +21,7 @@
 use rustc::middle::lang_items;
 use rustc::session::config::nightly_options;
 use syntax::ast::LitKind;
-use syntax::feature_gate::{UnstableFeatures, feature_err, emit_feature_err, GateIssue};
+use syntax::feature_gate::{UnstableFeatures, emit_feature_err, GateIssue};
 use syntax_pos::{Span, DUMMY_SP};
 
 use std::fmt;
@@ -104,7 +104,6 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     param_env: ty::ParamEnv<'tcx>,
     local_qualif: IndexVec<Local, Option<Qualif>>,
     qualif: Qualif,
-    const_fn_arg_vars: BitSet<Local>,
     temp_promotion_state: IndexVec<Local, TempState>,
     promotion_candidates: Vec<Candidate>
 }
@@ -139,7 +138,6 @@ fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             param_env,
             local_qualif,
             qualif: Qualif::empty(),
-            const_fn_arg_vars: BitSet::new_empty(mir.local_decls.len()),
             temp_promotion_state: temps,
             promotion_candidates: vec![]
         }
@@ -168,26 +166,6 @@ fn not_const(&mut self) {
         }
     }
 
-    /// Error about extra statements in a constant.
-    fn statement_like(&mut self) {
-        self.add(Qualif::NOT_CONST);
-        if self.mode != Mode::Fn {
-            let mut err = feature_err(
-                &self.tcx.sess.parse_sess,
-                "const_let",
-                self.span,
-                GateIssue::Language,
-                &format!("statements in {}s are unstable", self.mode),
-            );
-            if self.tcx.sess.teach(&err.get_code().unwrap()) {
-                err.note("Blocks in constants may only contain items (such as constant, function \
-                          definition, etc...) and a tail expression.");
-                err.help("To avoid it, you have to replace the non-item object.");
-            }
-            err.emit();
-        }
-    }
-
     /// Add the given qualification to self.qualif.
     fn add(&mut self, qualif: Qualif) {
         self.qualif = self.qualif | qualif;
@@ -233,80 +211,46 @@ fn assign(&mut self, dest: &Place<'tcx>, location: Location) {
             return;
         }
 
-        if self.tcx.features().const_let {
-            let mut dest = dest;
-            let index = loop {
-                match dest {
-                    // with `const_let` active, we treat all locals equal
-                    Place::Local(index) => break *index,
-                    // projections are transparent for assignments
-                    // we qualify the entire destination at once, even if just a field would have
-                    // stricter qualification
-                    Place::Projection(proj) => {
-                        // Catch more errors in the destination. `visit_place` also checks various
-                        // projection rules like union field access and raw pointer deref
-                        self.visit_place(
-                            dest,
-                            PlaceContext::MutatingUse(MutatingUseContext::Store),
-                            location
-                        );
-                        dest = &proj.base;
-                    },
-                    Place::Promoted(..) => bug!("promoteds don't exist yet during promotion"),
-                    Place::Static(..) => {
-                        // Catch more errors in the destination. `visit_place` also checks that we
-                        // do not try to access statics from constants or try to mutate statics
-                        self.visit_place(
-                            dest,
-                            PlaceContext::MutatingUse(MutatingUseContext::Store),
-                            location
-                        );
-                        return;
-                    }
+        let mut dest = dest;
+        let index = loop {
+            match dest {
+                // We treat all locals equal in constants
+                Place::Local(index) => break *index,
+                // projections are transparent for assignments
+                // we qualify the entire destination at once, even if just a field would have
+                // stricter qualification
+                Place::Projection(proj) => {
+                    // Catch more errors in the destination. `visit_place` also checks various
+                    // projection rules like union field access and raw pointer deref
+                    self.visit_place(
+                        dest,
+                        PlaceContext::MutatingUse(MutatingUseContext::Store),
+                        location
+                    );
+                    dest = &proj.base;
+                },
+                Place::Promoted(..) => bug!("promoteds don't exist yet during promotion"),
+                Place::Static(..) => {
+                    // Catch more errors in the destination. `visit_place` also checks that we
+                    // do not try to access statics from constants or try to mutate statics
+                    self.visit_place(
+                        dest,
+                        PlaceContext::MutatingUse(MutatingUseContext::Store),
+                        location
+                    );
+                    return;
                 }
-            };
-            debug!("store to var {:?}", index);
-            match &mut self.local_qualif[index] {
-                // this is overly restrictive, because even full assignments do not clear the qualif
-                // While we could special case full assignments, this would be inconsistent with
-                // aggregates where we overwrite all fields via assignments, which would not get
-                // that feature.
-                Some(ref mut qualif) => *qualif = *qualif | self.qualif,
-                // insert new qualification
-                qualif @ None => *qualif = Some(self.qualif),
-            }
-            return;
-        }
-
-        match *dest {
-            Place::Local(index) if self.mir.local_kind(index) == LocalKind::Temp ||
-                                   self.mir.local_kind(index) == LocalKind::ReturnPointer => {
-                debug!("store to {:?} (temp or return pointer)", index);
-                store(&mut self.local_qualif[index])
-            }
-
-            Place::Projection(box Projection {
-                base: Place::Local(index),
-                elem: ProjectionElem::Deref
-            }) if self.mir.local_kind(index) == LocalKind::Temp
-               && self.mir.local_decls[index].ty.is_box()
-               && self.local_qualif[index].map_or(false, |qualif| {
-                    qualif.contains(Qualif::NOT_CONST)
-               }) => {
-                // Part of `box expr`, we should've errored
-                // already for the Box allocation Rvalue.
-            }
-
-            // This must be an explicit assignment.
-            _ => {
-                // Catch more errors in the destination.
-                self.visit_place(
-                    dest,
-                    PlaceContext::MutatingUse(MutatingUseContext::Store),
-                    location
-                );
-                self.statement_like();
             }
+        };
+        debug!("store to var {:?}", index);
+        match &mut self.local_qualif[index] {
+            // this is overly restrictive, because even full assignments do not clear the qualif
+            // While we could special case full assignments, this would be inconsistent with
+            // aggregates where we overwrite all fields via assignments, which would not get
+            // that feature.
+            Some(ref mut qualif) => *qualif = *qualif | self.qualif,
+            // insert new qualification
+            qualif @ None => *qualif = Some(self.qualif),
         }
     }
 
@@ -347,45 +291,6 @@ fn qualify_const(&mut self) -> (Qualif, Lrc<BitSet<Local>>) {
                 TerminatorKind::FalseUnwind { .. } => None,
 
                 TerminatorKind::Return => {
-                    if !self.tcx.features().const_let {
-                        // Check for unused values. This usually means
-                        // there are extra statements in the AST.
-                        for temp in mir.temps_iter() {
-                            if self.local_qualif[temp].is_none() {
-                                continue;
-                            }
-
-                            let state = self.temp_promotion_state[temp];
-                            if let TempState::Defined { location, uses: 0 } = state {
-                                let data = &mir[location.block];
-                                let stmt_idx = location.statement_index;
-
-                                // Get the span for the initialization.
-                                let source_info = if stmt_idx < data.statements.len() {
-                                    data.statements[stmt_idx].source_info
-                                } else {
-                                    data.terminator().source_info
-                                };
-                                self.span = source_info.span;
-
-                                // Treat this as a statement in the AST.
-                                self.statement_like();
-                            }
-                        }
-
-                        // Make sure there are no extra unassigned variables.
-                        self.qualif = Qualif::NOT_CONST;
-                        for index in mir.vars_iter() {
-                            if !self.const_fn_arg_vars.contains(index) {
-                                debug!("unassigned variable {:?}", index);
-                                self.assign(&Place::Local(index), Location {
-                                    block: bb,
-                                    statement_index: usize::MAX,
-                                });
-                            }
-                        }
-                    }
-
                     break;
                 }
             };
@@ -454,12 +359,7 @@ fn visit_local(&mut self,
             LocalKind::ReturnPointer => {
                 self.not_const();
             }
-            LocalKind::Var if !self.tcx.features().const_let => {
-                if self.mode != Mode::Fn {
-                    emit_feature_err(&self.tcx.sess.parse_sess, "const_let",
-                                    self.span, GateIssue::Language,
-                                    &format!("let bindings in {}s are unstable",self.mode));
-                }
+            LocalKind::Var if self.mode == Mode::Fn => {
                 self.add(Qualif::NOT_CONST);
             }
             LocalKind::Var |
@@ -569,6 +469,8 @@ fn visit_place(&mut self,
                             }
                         }
 
+                        ProjectionElem::ConstantIndex {..} |
+                        ProjectionElem::Subslice {..} |
                         ProjectionElem::Field(..) |
                         ProjectionElem::Index(_) => {
                             let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx);
@@ -598,8 +500,6 @@ fn visit_place(&mut self,
                             this.qualif.restrict(ty, this.tcx, this.param_env);
                         }
 
-                        ProjectionElem::ConstantIndex {..} |
-                        ProjectionElem::Subslice {..} |
                         ProjectionElem::Downcast(..) => {
                             this.not_const()
                         }
@@ -1001,7 +901,7 @@ fn visit_terminator_kind(&mut self,
                                         err.emit();
                                     }
                                 } else {
-                                    // FIXME(#24111): remove this check when const fn stabilizes.
+                                    // FIXME(#57563): remove this check when const fn stabilizes.
                                     let (msg, note) = if let UnstableFeatures::Disallow =
                                             self.tcx.sess.opts.unstable_features {
                                         (format!("calls in {}s are limited to \
@@ -1168,46 +1068,6 @@ fn visit_assign(&mut self,
         debug!("visit_assign: dest={:?} rvalue={:?} location={:?}", dest, rvalue, location);
         self.visit_rvalue(rvalue, location);
 
-        // Check the allowed const fn argument forms.
-        if let (Mode::ConstFn, &Place::Local(index)) = (self.mode, dest) {
-            if self.mir.local_kind(index) == LocalKind::Var &&
-               self.const_fn_arg_vars.insert(index) &&
-               !self.tcx.features().const_let {
-                // Direct use of an argument is permitted.
-                match *rvalue {
-                    Rvalue::Use(Operand::Copy(Place::Local(local))) |
-                    Rvalue::Use(Operand::Move(Place::Local(local))) => {
-                        if self.mir.local_kind(local) == LocalKind::Arg {
-                            return;
-                        }
-                    }
-                    _ => {}
-                }
-                // Avoid a generic error for other uses of arguments.
-                if self.qualif.contains(Qualif::FN_ARGUMENT) {
-                    let decl = &self.mir.local_decls[index];
-                    let mut err = feature_err(
-                        &self.tcx.sess.parse_sess,
-                        "const_let",
-                        decl.source_info.span,
-                        GateIssue::Language,
-                        "arguments of constant functions can only be immutable by-value bindings"
-                    );
-                    if self.tcx.sess.teach(&err.get_code().unwrap()) {
-                        err.note("Constant functions are not allowed to mutate anything. Thus, \
-                                  binding to an argument with a mutable pattern is not allowed.");
-                        err.note("Remove any mutable bindings from the argument list to fix this \
-                                  error. In case you need to mutate the argument, try lazily \
-                                  initializing a global variable instead of using a const fn, or \
-                                  refactoring the code to a functional style to avoid mutation if \
-                                  possible.");
-                    }
-                    err.emit();
-                    return;
-                }
-            }
-        }
-
         self.assign(dest, location);
     }
 
index c1c5b18915aede665e4734aef2dd786c436a57f2..059b88a4d702ae923cff4541b5ba0aa5c5b4a703 100644 (file)
@@ -65,12 +65,6 @@ pub fn is_min_const_fn(
         }
     }
 
-    for local in mir.vars_iter() {
-        return Err((
-            mir.local_decls[local].source_info.span,
-            "local variables in const fn are unstable".into(),
-        ));
-    }
     for local in &mir.local_decls {
         check_ty(tcx, local.ty, local.source_info.span)?;
     }
@@ -147,7 +141,7 @@ fn check_rvalue(
             check_operand(tcx, mir, operand, span)
         }
         Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) => {
-            check_place(tcx, mir, place, span, PlaceMode::Read)
+            check_place(tcx, mir, place, span)
         }
         Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
             use rustc::ty::cast::CastTy;
@@ -213,11 +207,6 @@ fn check_rvalue(
     }
 }
 
-enum PlaceMode {
-    Assign,
-    Read,
-}
-
 fn check_statement(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     mir: &'a Mir<'tcx>,
@@ -226,11 +215,11 @@ fn check_statement(
     let span = statement.source_info.span;
     match &statement.kind {
         StatementKind::Assign(place, rval) => {
-            check_place(tcx, mir, place, span, PlaceMode::Assign)?;
+            check_place(tcx, mir, place, span)?;
             check_rvalue(tcx, mir, rval, span)
         }
 
-        StatementKind::FakeRead(_, place) => check_place(tcx, mir, place, span, PlaceMode::Read),
+        StatementKind::FakeRead(_, place) => check_place(tcx, mir, place, span),
 
         // just an assignment
         StatementKind::SetDiscriminant { .. } => Ok(()),
@@ -256,7 +245,7 @@ fn check_operand(
 ) -> McfResult {
     match operand {
         Operand::Move(place) | Operand::Copy(place) => {
-            check_place(tcx, mir, place, span, PlaceMode::Read)
+            check_place(tcx, mir, place, span)
         }
         Operand::Constant(_) => Ok(()),
     }
@@ -267,29 +256,17 @@ fn check_place(
     mir: &'a Mir<'tcx>,
     place: &Place<'tcx>,
     span: Span,
-    mode: PlaceMode,
 ) -> McfResult {
     match place {
-        Place::Local(l) => match mode {
-            PlaceMode::Assign => match mir.local_kind(*l) {
-                LocalKind::Temp | LocalKind::ReturnPointer => Ok(()),
-                LocalKind::Arg | LocalKind::Var => {
-                    Err((span, "assignments in const fn are unstable".into()))
-                }
-            },
-            PlaceMode::Read => Ok(()),
-        },
+        Place::Local(_) => Ok(()),
         // promoteds are always fine, they are essentially constants
         Place::Promoted(_) => Ok(()),
         Place::Static(_) => Err((span, "cannot access `static` items in const fn".into())),
         Place::Projection(proj) => {
             match proj.elem {
+                | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. }
                 | ProjectionElem::Deref | ProjectionElem::Field(..) | ProjectionElem::Index(_) => {
-                    check_place(tcx, mir, &proj.base, span, mode)
-                }
-                // slice patterns are unstable
-                | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
-                    return Err((span, "slice patterns in const fn are unstable".into()))
+                    check_place(tcx, mir, &proj.base, span)
                 }
                 | ProjectionElem::Downcast(..) => {
                     Err((span, "`match` or `if let` in `const fn` is unstable".into()))
@@ -311,10 +288,10 @@ fn check_terminator(
         | TerminatorKind::Resume => Ok(()),
 
         TerminatorKind::Drop { location, .. } => {
-            check_place(tcx, mir, location, span, PlaceMode::Read)
+            check_place(tcx, mir, location, span)
         }
         TerminatorKind::DropAndReplace { location, value, .. } => {
-            check_place(tcx, mir, location, span, PlaceMode::Read)?;
+            check_place(tcx, mir, location, span)?;
             check_operand(tcx, mir, value, span)
         },
 
@@ -342,15 +319,11 @@ fn check_terminator(
                 // some intrinsics are waved through if called inside the
                 // standard library. Users never need to call them directly
                 match tcx.fn_sig(def_id).abi() {
-                    abi::Abi::RustIntrinsic => match &tcx.item_name(def_id).as_str()[..] {
-                        | "size_of"
-                        | "min_align_of"
-                        | "needs_drop"
-                        => {},
-                        _ => return Err((
+                    abi::Abi::RustIntrinsic => if !is_intrinsic_whitelisted(tcx, def_id) {
+                        return Err((
                             span,
                             "can only call a curated list of intrinsics in `min_const_fn`".into(),
-                        )),
+                        ))
                     },
                     abi::Abi::Rust if tcx.is_min_const_fn(def_id) => {},
                     abi::Abi::Rust => return Err((
@@ -390,3 +363,33 @@ fn check_terminator(
         },
     }
 }
+
+/// Returns true if the `def_id` refers to an intrisic which we've whitelisted
+/// for being called from stable `const fn`s (`min_const_fn`).
+///
+/// Adding more intrinsics requires sign-off from @rust-lang/lang.
+fn is_intrinsic_whitelisted(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
+    match &tcx.item_name(def_id).as_str()[..] {
+        | "size_of"
+        | "min_align_of"
+        | "needs_drop"
+        // Arithmetic:
+        | "add_with_overflow" // ~> .overflowing_add
+        | "sub_with_overflow" // ~> .overflowing_sub
+        | "mul_with_overflow" // ~> .overflowing_mul
+        | "overflowing_add" // ~> .wrapping_add
+        | "overflowing_sub" // ~> .wrapping_sub
+        | "overflowing_mul" // ~> .wrapping_mul
+        | "unchecked_shl" // ~> .wrapping_shl
+        | "unchecked_shr" // ~> .wrapping_shr
+        | "rotate_left" // ~> .rotate_left
+        | "rotate_right" // ~> .rotate_right
+        | "ctpop" // ~> .count_ones
+        | "ctlz" // ~> .leading_zeros
+        | "cttz" // ~> .trailing_zeros
+        | "bswap" // ~> .swap_bytes
+        | "bitreverse" // ~> .reverse_bits
+        => true,
+        _ => false,
+    }
+}
index 5e55bb4a9b6cfec113dca20bd3a77990ed33e5c8..7ad73aaa3f9a958a7ff81a51d86d1d4ca5cf0d01 100644 (file)
@@ -138,13 +138,15 @@ fn cannot_mutably_borrow_multiply(
         old_load_end_span: Option<Span>,
         o: Origin,
     ) -> DiagnosticBuilder<'cx> {
+        let via = |msg: &str|
+            if msg.is_empty() { msg.to_string() } else { format!(" (via `{}`)", msg) };
         let mut err = struct_span_err!(
             self,
             new_loan_span,
             E0499,
             "cannot borrow `{}`{} as mutable more than once at a time{OGN}",
             desc,
-            opt_via,
+            via(opt_via),
             OGN = o
         );
         if old_loan_span == new_loan_span {
@@ -164,11 +166,11 @@ fn cannot_mutably_borrow_multiply(
         } else {
             err.span_label(
                 old_loan_span,
-                format!("first mutable borrow occurs here{}", old_opt_via),
+                format!("first mutable borrow occurs here{}", via(old_opt_via)),
             );
             err.span_label(
                 new_loan_span,
-                format!("second mutable borrow occurs here{}", opt_via),
+                format!("second mutable borrow occurs here{}", via(opt_via)),
             );
             if let Some(old_load_end_span) = old_load_end_span {
                 err.span_label(old_load_end_span, "first borrow ends here");
@@ -292,27 +294,46 @@ fn cannot_reborrow_already_borrowed(
         old_load_end_span: Option<Span>,
         o: Origin,
     ) -> DiagnosticBuilder<'cx> {
+        let via = |msg: &str|
+            if msg.is_empty() { msg.to_string() } else { format!(" (via `{}`)", msg) };
         let mut err = struct_span_err!(
             self,
             span,
             E0502,
-            "cannot borrow `{}`{} as {} because {} is also borrowed as {}{}{OGN}",
+            "cannot borrow `{}`{} as {} because {} is also borrowed \
+             as {}{}{OGN}",
             desc_new,
-            msg_new,
+            via(msg_new),
             kind_new,
             noun_old,
             kind_old,
-            msg_old,
+            via(msg_old),
             OGN = o
         );
-        err.span_label(span, format!("{} borrow occurs here{}", kind_new, msg_new));
-        err.span_label(
-            old_span,
-            format!("{} borrow occurs here{}", kind_old, msg_old),
-        );
+
+        if msg_new == "" {
+            // If `msg_new` is empty, then this isn't a borrow of a union field.
+            err.span_label(span, format!("{} borrow occurs here", kind_new));
+            err.span_label(old_span, format!("{} borrow occurs here", kind_old));
+        } else {
+            // If `msg_new` isn't empty, then this a borrow of a union field.
+            err.span_label(
+                span,
+                format!(
+                    "{} borrow of `{}` -- which overlaps with `{}` -- occurs here",
+                    kind_new, msg_new, msg_old,
+                )
+            );
+            err.span_label(
+                old_span,
+                format!("{} borrow occurs here{}", kind_old, via(msg_old)),
+            );
+        }
+
         if let Some(old_load_end_span) = old_load_end_span {
             err.span_label(old_load_end_span, format!("{} borrow ends here", kind_old));
         }
+
         self.cancel_if_wrong_origin(err, o)
     }
 
index 584f0ba0449e1213f007ad7658aaf27bcfbe75f7..3d0e46d998622e2791e6f8ba093b2843b3bc91de 100644 (file)
@@ -438,8 +438,9 @@ fn visit_generics(&mut self, generics: &'a Generics) {
         }
         for predicate in &generics.where_clause.predicates {
             if let WherePredicate::EqPredicate(ref predicate) = *predicate {
-                self.err_handler().span_err(predicate.span, "equality constraints are not yet \
-                                                             supported in where clauses (#20041)");
+                self.err_handler()
+                    .span_err(predicate.span, "equality constraints are not yet \
+                                               supported in where clauses (see #20041)");
             }
         }
         visit::walk_generics(self, generics)
index 0b394d800ea89a3ba6f793f0b03b23933be9f3e3..829d4b34cf77922cf55acb7127ea71f55905ab7d 100644 (file)
@@ -38,4 +38,5 @@
 
 pub fn provide(providers: &mut Providers) {
     rvalue_promotion::provide(providers);
+    loops::provide(providers);
 }
index 7a37a35abbce7cef715f1e0bfd9a7ef3ff7e738c..7d9165a82bc8fb52869a0a048ee00f0994ea48c4 100644 (file)
@@ -2,6 +2,10 @@
 
 use rustc::session::Session;
 
+use rustc::ty::query::Providers;
+use rustc::ty::query::queries;
+use rustc::ty::TyCtxt;
+use rustc::hir::def_id::DefId;
 use rustc::hir::map::Map;
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::hir::{self, Node, Destination};
@@ -42,28 +46,32 @@ struct CheckLoopVisitor<'a, 'hir: 'a> {
     cx: Context,
 }
 
-pub fn check_crate(sess: &Session, map: &Map) {
-    let krate = map.krate();
-    krate.visit_all_item_likes(&mut CheckLoopVisitor {
-        sess,
-        hir_map: map,
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+    for &module in tcx.hir().krate().modules.keys() {
+        queries::check_mod_loops::ensure(tcx, tcx.hir().local_def_id(module));
+    }
+}
+
+fn check_mod_loops<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
+    tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckLoopVisitor {
+        sess: &tcx.sess,
+        hir_map: &tcx.hir(),
         cx: Normal,
     }.as_deep_visitor());
 }
 
+pub(crate) fn provide(providers: &mut Providers) {
+    *providers = Providers {
+        check_mod_loops,
+        ..*providers
+    };
+}
+
 impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> {
         NestedVisitorMap::OnlyBodies(&self.hir_map)
     }
 
-    fn visit_item(&mut self, i: &'hir hir::Item) {
-        self.with_context(Normal, |v| intravisit::walk_item(v, i));
-    }
-
-    fn visit_impl_item(&mut self, i: &'hir hir::ImplItem) {
-        self.with_context(Normal, |v| intravisit::walk_impl_item(v, i));
-    }
-
     fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) {
         self.with_context(AnonConst, |v| intravisit::walk_anon_const(v, c));
     }
index cf949b62a634e3fb684e56052ef1f9b6c1644425..39be3cb7440801ce873411a3d37c2e9495d8912f 100644 (file)
@@ -67,7 +67,7 @@
 use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
 
 use std::cell::{Cell, RefCell};
-use std::{cmp, fmt, iter, ptr};
+use std::{cmp, fmt, iter, mem, ptr};
 use std::collections::BTreeSet;
 use std::mem::replace;
 use rustc_data_structures::ptr_key::PtrKey;
@@ -2017,16 +2017,14 @@ fn resolve_ident_in_lexical_scope(&mut self,
         if ident.name == keywords::Invalid.name() {
             return Some(LexicalScopeBinding::Def(Def::Err));
         }
-        if ns == TypeNS {
-            ident.span = if ident.name == keywords::SelfUpper.name() {
-                // FIXME(jseyfried) improve `Self` hygiene
-                ident.span.with_ctxt(SyntaxContext::empty())
-            } else {
-                ident.span.modern()
-            }
+        ident.span = if ident.name == keywords::SelfUpper.name() {
+            // FIXME(jseyfried) improve `Self` hygiene
+            ident.span.with_ctxt(SyntaxContext::empty())
+        } else if ns == TypeNS {
+            ident.span.modern()
         } else {
-            ident = ident.modern_and_legacy();
-        }
+            ident.span.modern_and_legacy()
+        };
 
         // Walk backwards up the ribs in scope.
         let record_used = record_used_id.is_some();
@@ -2375,11 +2373,27 @@ fn future_proof_import(&mut self, use_tree: &ast::UseTree) {
                 ast::UseTreeKind::Simple(..) if segments.len() == 1 => &[TypeNS, ValueNS][..],
                 _ => &[TypeNS],
             };
+            let report_error = |this: &Self, ns| {
+                let what = if ns == TypeNS { "type parameters" } else { "local variables" };
+                this.session.span_err(ident.span, &format!("imports cannot refer to {}", what));
+            };
+
             for &ns in nss {
-                if let Some(LexicalScopeBinding::Def(..)) =
-                        self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) {
-                    let what = if ns == TypeNS { "type parameters" } else { "local variables" };
-                    self.session.span_err(ident.span, &format!("imports cannot refer to {}", what));
+                match self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) {
+                    Some(LexicalScopeBinding::Def(..)) => {
+                        report_error(self, ns);
+                    }
+                    Some(LexicalScopeBinding::Item(binding)) => {
+                        let orig_blacklisted_binding =
+                            mem::replace(&mut self.blacklisted_binding, Some(binding));
+                        if let Some(LexicalScopeBinding::Def(..)) =
+                                self.resolve_ident_in_lexical_scope(ident, ns, None,
+                                                                    use_tree.prefix.span) {
+                            report_error(self, ns);
+                        }
+                        self.blacklisted_binding = orig_blacklisted_binding;
+                    }
+                    None => {}
                 }
             }
         } else if let ast::UseTreeKind::Nested(use_trees) = &use_tree.kind {
@@ -3874,6 +3888,13 @@ fn resolve_path(
                         module = Some(ModuleOrUniformRoot::Module(next_module));
                         record_segment_def(self, def);
                     } else if def == Def::ToolMod && i + 1 != path.len() {
+                        if binding.is_import() {
+                            self.session.struct_span_err(
+                                ident.span, "cannot use a tool module through an import"
+                            ).span_note(
+                                binding.span, "the tool module imported here"
+                            ).emit();
+                        }
                         let def = Def::NonMacroAttr(NonMacroAttrKind::Tool);
                         return PathResult::NonModule(PathResolution::new(def));
                     } else if def == Def::Err {
@@ -5089,6 +5110,9 @@ fn extern_prelude_get(&mut self, ident: Ident, speculative: bool)
         }
         self.extern_prelude.get(&ident.modern()).cloned().and_then(|entry| {
             if let Some(binding) = entry.extern_crate_item {
+                if !speculative && entry.introduced_by_item {
+                    self.record_use(ident, TypeNS, binding, false);
+                }
                 Some(binding)
             } else {
                 let crate_id = if !speculative {
index e5e6c7a994b7a02ad6dddaae4b2af30ab9ede69a..bb679d340eae7dd65f198e384e7bd6334cacfc8b 100644 (file)
@@ -376,6 +376,7 @@ pub fn resolve_macro_to_def_inner(
                     .push((path, path_span, kind, parent_scope.clone(), def.ok()));
             }
 
+            self.prohibit_imported_non_macro_attrs(None, def.ok(), path_span);
             def
         } else {
             let binding = self.early_resolve_ident_in_lexical_scope(
@@ -390,7 +391,9 @@ pub fn resolve_macro_to_def_inner(
                     .push((path[0].ident, kind, parent_scope.clone(), binding.ok()));
             }
 
-            binding.map(|binding| binding.def())
+            let def = binding.map(|binding| binding.def());
+            self.prohibit_imported_non_macro_attrs(binding.ok(), def.ok(), path_span);
+            def
         }
     }
 
@@ -828,27 +831,23 @@ struct Flags: u8 {
             // but its `Def` should coincide with a crate passed with `--extern`
             // (otherwise there would be ambiguity) and we can skip feature error in this case.
             'ok: {
-                if !is_import || self.session.features_untracked().uniform_paths {
+                if !is_import || !rust_2015 {
                     break 'ok;
                 }
                 if ns == TypeNS && use_prelude && self.extern_prelude_get(ident, true).is_some() {
                     break 'ok;
                 }
-                if rust_2015 {
-                    let root_ident = Ident::new(keywords::PathRoot.name(), orig_ident.span);
-                    let root_module = self.resolve_crate_root(root_ident);
-                    if self.resolve_ident_in_module_ext(ModuleOrUniformRoot::Module(root_module),
-                                                        orig_ident, ns, None, false, path_span)
-                                                        .is_ok() {
-                        break 'ok;
-                    }
+                let root_ident = Ident::new(keywords::PathRoot.name(), orig_ident.span);
+                let root_module = self.resolve_crate_root(root_ident);
+                if self.resolve_ident_in_module_ext(ModuleOrUniformRoot::Module(root_module),
+                                                    orig_ident, ns, None, false, path_span)
+                                                    .is_ok() {
+                    break 'ok;
                 }
 
-                let msg = "imports can only refer to extern crate names \
-                           passed with `--extern` on stable channel";
-                let mut err = feature_err(&self.session.parse_sess, "uniform_paths",
-                                          ident.span, GateIssue::Language, msg);
-
+                let msg = "imports can only refer to extern crate names passed with \
+                           `--extern` in macros originating from 2015 edition";
+                let mut err = self.session.struct_span_err(ident.span, msg);
                 let what = self.binding_description(binding, ident,
                                                     flags.contains(Flags::MISC_FROM_PRELUDE));
                 let note_msg = format!("this import refers to {what}", what = what);
@@ -977,6 +976,20 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
         }
     }
 
+    fn prohibit_imported_non_macro_attrs(&self, binding: Option<&'a NameBinding<'a>>,
+                                         def: Option<Def>, span: Span) {
+        if let Some(Def::NonMacroAttr(kind)) = def {
+            if kind != NonMacroAttrKind::Tool && binding.map_or(true, |b| b.is_import()) {
+                let msg = format!("cannot use a {} through an import", kind.descr());
+                let mut err = self.session.struct_span_err(span, &msg);
+                if let Some(binding) = binding {
+                    err.span_note(binding.span, &format!("the {} imported here", kind.descr()));
+                }
+                err.emit();
+            }
+        }
+    }
+
     fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
                           err: &mut DiagnosticBuilder<'a>, span: Span) {
         // First check if this is a locally-defined bang macro.
@@ -1073,7 +1086,12 @@ pub fn define_macro(&mut self,
             let ident = ident.modern();
             self.macro_names.insert(ident);
             let def = Def::Macro(def_id, MacroKind::Bang);
-            let vis = ty::Visibility::Invisible; // Doesn't matter for legacy bindings
+            let is_macro_export = attr::contains_name(&item.attrs, "macro_export");
+            let vis = if is_macro_export {
+                ty::Visibility::Public
+            } else {
+                ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))
+            };
             let binding = (def, vis, item.span, expansion).to_name_binding(self.arenas);
             self.set_binding_parent_module(binding, self.current_module);
             let legacy_binding = self.arenas.alloc_legacy_binding(LegacyBinding {
@@ -1081,9 +1099,8 @@ pub fn define_macro(&mut self,
             });
             *current_legacy_scope = LegacyScope::Binding(legacy_binding);
             self.all_macros.insert(ident.name, def);
-            if attr::contains_name(&item.attrs, "macro_export") {
+            if is_macro_export {
                 let module = self.graph_root;
-                let vis = ty::Visibility::Public;
                 self.define(module, ident, MacroNS,
                             (def, vis, item.span, expansion, IsMacroExport));
             } else {
index c84dbd2974624976ac95ecab8bfab19a750cf3ea..fd55897522bf7f2c1595bfe8377186e9fc102161 100644 (file)
@@ -223,6 +223,11 @@ fn resolution(&self, module: Module<'a>, ident: Ident, ns: Namespace)
         }
 
         let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| {
+            if let Some(blacklisted_binding) = this.blacklisted_binding {
+                if ptr::eq(binding, blacklisted_binding) {
+                    return Err((Determined, Weak::No));
+                }
+            }
             // `extern crate` are always usable for backwards compatibility, see issue #37020,
             // remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`.
             let usable = this.is_accessible(binding.vis) || binding.is_extern_crate();
index 891537309177e5d611d9d77ce0b3113f8c04d1dc..0c9e443efe0dbca27081c15d8b38167771dcdcda 100644 (file)
@@ -14,7 +14,7 @@
 //! recording the output.
 
 use rustc::hir::def::Def as HirDef;
-use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::hir::def_id::DefId;
 use rustc::session::config::Input;
 use rustc::ty::{self, TyCtxt};
 use rustc_data_structures::fx::FxHashSet;
@@ -56,14 +56,14 @@ macro_rules! access_from {
     ($save_ctxt:expr, $vis:expr, $id:expr) => {
         Access {
             public: $vis.node.is_pub(),
-            reachable: $save_ctxt.tcx.privacy_access_levels(LOCAL_CRATE).is_reachable($id),
+            reachable: $save_ctxt.access_levels.is_reachable($id),
         }
     };
 
     ($save_ctxt:expr, $item:expr) => {
         Access {
             public: $item.vis.node.is_pub(),
-            reachable: $save_ctxt.tcx.privacy_access_levels(LOCAL_CRATE).is_reachable($item.id),
+            reachable: $save_ctxt.access_levels.is_reachable($item.id),
         }
     };
 }
index d5b3070372ba5fdb1f2c6612bfdbc058d6c5752c..132bd4f1430a061803e8c0133963af39fe79747a 100644 (file)
 use rustc::hir::def::Def as HirDef;
 use rustc::hir::Node;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::middle::privacy::AccessLevels;
 use rustc::middle::cstore::ExternCrate;
 use rustc::session::config::{CrateType, Input, OutputType};
 use rustc::ty::{self, TyCtxt};
 use rustc_typeck::hir_ty_to_ty;
 use rustc_codegen_utils::link::{filename_for_metadata, out_filename};
+use rustc_data_structures::sync::Lrc;
 
 use std::cell::Cell;
 use std::default::Default;
@@ -68,6 +70,7 @@
 pub struct SaveContext<'l, 'tcx: 'l> {
     tcx: TyCtxt<'l, 'tcx, 'tcx>,
     tables: &'l ty::TypeckTables<'tcx>,
+    access_levels: &'l AccessLevels,
     analysis: &'l ty::CrateAnalysis,
     span_utils: SpanUtils<'tcx>,
     config: Config,
@@ -622,9 +625,11 @@ pub fn get_path_def(&self, id: NodeId) -> HirDef {
             Node::Visibility(&Spanned {
                 node: hir::VisibilityKind::Restricted { ref path, .. }, .. }) => path.def,
 
-            Node::PathSegment(seg) => match seg.def {
-                Some(def) => def,
-                None => HirDef::Err,
+            Node::PathSegment(seg) => {
+                match seg.def {
+                    Some(def) if def != HirDef::Err => def,
+                    _ => self.get_path_def(self.tcx.hir().get_parent_node(id)),
+                }
             },
             Node::Expr(&hir::Expr {
                 node: hir::ExprKind::Struct(ref qpath, ..),
@@ -1126,10 +1131,18 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>(
 
         info!("Dumping crate {}", cratename);
 
+        // Privacy checking requires and is done after type checking; use a
+        // fallback in case the access levels couldn't have been correctly computed.
+        let access_levels = match tcx.sess.compile_status() {
+            Ok(..) => tcx.privacy_access_levels(LOCAL_CRATE),
+            Err(..) => Lrc::new(AccessLevels::default()),
+        };
+
         let save_ctxt = SaveContext {
             tcx,
             tables: &ty::TypeckTables::empty(None),
             analysis,
+            access_levels: &access_levels,
             span_utils: SpanUtils::new(&tcx.sess),
             config: find_config(config),
             impl_counter: Cell::new(0),
index b66c383edb51e85d2deee7586469c723c1612b45..1767af4870d3b27eca2564d33b461a746e2f54d4 100644 (file)
 use super::report_unexpected_variant_def;
 
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
-    /// The `is_arg` argument indicates whether this pattern is the
-    /// *outermost* pattern in an argument (e.g., in `fn foo(&x:
-    /// &u32)`, it is true for the `&x` pattern but not `x`). This is
-    /// used to tailor error reporting.
+    /// `match_discrim_span` argument having a `Span` indicates that this pattern is part of
+    /// a match expression arm guard, and it points to the match discriminant to add context
+    /// in type errors. In the folloowing example, `match_discrim_span` corresponds to the
+    /// `a + b` expression:
+    ///
+    /// ```text
+    /// error[E0308]: mismatched types
+    ///  --> src/main.rs:5:9
+    ///   |
+    /// 4 |    let temp: usize = match a + b {
+    ///   |                            ----- this expression has type `usize`
+    /// 5 |         Ok(num) => num,
+    ///   |         ^^^^^^^ expected usize, found enum `std::result::Result`
+    ///   |
+    ///   = note: expected type `usize`
+    ///              found type `std::result::Result<_, _>`
+    /// ```
     pub fn check_pat_walk(
         &self,
         pat: &'gcx hir::Pat,
         mut expected: Ty<'tcx>,
         mut def_bm: ty::BindingMode,
-        is_arg: bool)
-    {
+        match_discrim_span: Option<Span>,
+    {
         let tcx = self.tcx;
 
-        debug!("check_pat_walk(pat={:?},expected={:?},def_bm={:?},is_arg={})",
-            pat, expected, def_bm, is_arg);
+        debug!("check_pat_walk(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm);
 
         let is_non_ref_pat = match pat.node {
             PatKind::Struct(..) |
@@ -210,8 +222,8 @@ pub fn check_pat_walk(
                 let common_type = self.resolve_type_vars_if_possible(&lhs_ty);
 
                 // subtyping doesn't matter here, as the value is some kind of scalar
-                self.demand_eqtype(pat.span, expected, lhs_ty);
-                self.demand_eqtype(pat.span, expected, rhs_ty);
+                self.demand_eqtype_pat(pat.span, expected, lhs_ty, match_discrim_span);
+                self.demand_eqtype_pat(pat.span, expected, rhs_ty, match_discrim_span);
                 common_type
             }
             PatKind::Binding(ba, var_id, _, ref sub) => {
@@ -240,13 +252,13 @@ pub fn check_pat_walk(
                         // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is
                         // required. However, we use equality, which is stronger. See (*) for
                         // an explanation.
-                        self.demand_eqtype(pat.span, region_ty, local_ty);
+                        self.demand_eqtype_pat(pat.span, region_ty, local_ty, match_discrim_span);
                     }
                     // otherwise the type of x is the expected type T
                     ty::BindByValue(_) => {
                         // As above, `T <: typeof(x)` is required but we
                         // use equality, see (*) below.
-                        self.demand_eqtype(pat.span, expected, local_ty);
+                        self.demand_eqtype_pat(pat.span, expected, local_ty, match_discrim_span);
                     }
                 }
 
@@ -254,23 +266,31 @@ pub fn check_pat_walk(
                 // what the type of the binding `x` ought to be
                 if var_id != pat.id {
                     let vt = self.local_ty(pat.span, var_id).decl_ty;
-                    self.demand_eqtype(pat.span, vt, local_ty);
+                    self.demand_eqtype_pat(pat.span, vt, local_ty, match_discrim_span);
                 }
 
                 if let Some(ref p) = *sub {
-                    self.check_pat_walk(&p, expected, def_bm, true);
+                    self.check_pat_walk(&p, expected, def_bm, match_discrim_span);
                 }
 
                 local_ty
             }
             PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
-                self.check_pat_tuple_struct(pat, qpath, &subpats, ddpos, expected, def_bm)
+                self.check_pat_tuple_struct(
+                    pat,
+                    qpath,
+                    &subpats,
+                    ddpos,
+                    expected,
+                    def_bm,
+                    match_discrim_span,
+                )
             }
             PatKind::Path(ref qpath) => {
                 self.check_pat_path(pat, qpath, expected)
             }
             PatKind::Struct(ref qpath, ref fields, etc) => {
-                self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm)
+                self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, match_discrim_span)
             }
             PatKind::Tuple(ref elements, ddpos) => {
                 let mut expected_len = elements.len();
@@ -295,12 +315,12 @@ pub fn check_pat_walk(
                     // further errors being emitted when using the bindings. #50333
                     let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
                     for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
-                        self.check_pat_walk(elem, &tcx.types.err, def_bm, true);
+                        self.check_pat_walk(elem, &tcx.types.err, def_bm, match_discrim_span);
                     }
                     tcx.mk_tup(element_tys_iter)
                 } else {
                     for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
-                        self.check_pat_walk(elem, &element_tys[i], def_bm, true);
+                        self.check_pat_walk(elem, &element_tys[i], def_bm, match_discrim_span);
                     }
                     pat_ty
                 }
@@ -313,11 +333,11 @@ pub fn check_pat_walk(
                     // Here, `demand::subtype` is good enough, but I don't
                     // think any errors can be introduced by using
                     // `demand::eqtype`.
-                    self.demand_eqtype(pat.span, expected, uniq_ty);
-                    self.check_pat_walk(&inner, inner_ty, def_bm, true);
+                    self.demand_eqtype_pat(pat.span, expected, uniq_ty, match_discrim_span);
+                    self.check_pat_walk(&inner, inner_ty, def_bm, match_discrim_span);
                     uniq_ty
                 } else {
-                    self.check_pat_walk(&inner, tcx.types.err, def_bm, true);
+                    self.check_pat_walk(&inner, tcx.types.err, def_bm, match_discrim_span);
                     tcx.types.err
                 }
             }
@@ -349,15 +369,13 @@ pub fn check_pat_walk(
                             // Look for a case like `fn foo(&foo: u32)` and suggest
                             // `fn foo(foo: &u32)`
                             if let Some(mut err) = err {
-                                if is_arg {
-                                    if let PatKind::Binding(..) = inner.node {
-                                        if let Ok(snippet) = tcx.sess.source_map()
-                                                                     .span_to_snippet(pat.span)
-                                        {
-                                            err.help(&format!("did you mean `{}: &{}`?",
-                                                              &snippet[1..],
-                                                              expected));
-                                        }
+                                if let PatKind::Binding(..) = inner.node {
+                                    if let Ok(snippet) = tcx.sess.source_map()
+                                                                    .span_to_snippet(pat.span)
+                                    {
+                                        err.help(&format!("did you mean `{}: &{}`?",
+                                                            &snippet[1..],
+                                                            expected));
                                     }
                                 }
                                 err.emit();
@@ -366,10 +384,10 @@ pub fn check_pat_walk(
                         }
                     };
 
-                    self.check_pat_walk(&inner, inner_ty, def_bm, true);
+                    self.check_pat_walk(&inner, inner_ty, def_bm, match_discrim_span);
                     rptr_ty
                 } else {
-                    self.check_pat_walk(&inner, tcx.types.err, def_bm, true);
+                    self.check_pat_walk(&inner, tcx.types.err, def_bm, match_discrim_span);
                     tcx.types.err
                 }
             }
@@ -427,13 +445,13 @@ pub fn check_pat_walk(
                 };
 
                 for elt in before {
-                    self.check_pat_walk(&elt, inner_ty, def_bm, true);
+                    self.check_pat_walk(&elt, inner_ty, def_bm, match_discrim_span);
                 }
                 if let Some(ref slice) = *slice {
-                    self.check_pat_walk(&slice, slice_ty, def_bm, true);
+                    self.check_pat_walk(&slice, slice_ty, def_bm, match_discrim_span);
                 }
                 for elt in after {
-                    self.check_pat_walk(&elt, inner_ty, def_bm, true);
+                    self.check_pat_walk(&elt, inner_ty, def_bm, match_discrim_span);
                 }
                 expected_ty
             }
@@ -524,12 +542,14 @@ pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &hir::
         true
     }
 
-    pub fn check_match(&self,
-                       expr: &'gcx hir::Expr,
-                       discrim: &'gcx hir::Expr,
-                       arms: &'gcx [hir::Arm],
-                       expected: Expectation<'tcx>,
-                       match_src: hir::MatchSource) -> Ty<'tcx> {
+    pub fn check_match(
+        &self,
+        expr: &'gcx hir::Expr,
+        discrim: &'gcx hir::Expr,
+        arms: &'gcx [hir::Arm],
+        expected: Expectation<'tcx>,
+        match_src: hir::MatchSource,
+    ) -> Ty<'tcx> {
         let tcx = self.tcx;
 
         // Not entirely obvious: if matches may create ref bindings, we want to
@@ -624,8 +644,12 @@ pub fn check_match(&self,
             let mut all_pats_diverge = Diverges::WarnedAlways;
             for p in &arm.pats {
                 self.diverges.set(Diverges::Maybe);
-                self.check_pat_walk(&p, discrim_ty,
-                    ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), true);
+                self.check_pat_walk(
+                    &p,
+                    discrim_ty,
+                    ty::BindingMode::BindByValue(hir::Mutability::MutImmutable),
+                    Some(discrim.span),
+                );
                 all_pats_diverge &= self.diverges.get();
             }
 
@@ -703,26 +727,34 @@ pub fn check_match(&self,
         coercion.complete(self)
     }
 
-    fn check_pat_struct(&self,
-                        pat: &'gcx hir::Pat,
-                        qpath: &hir::QPath,
-                        fields: &'gcx [Spanned<hir::FieldPat>],
-                        etc: bool,
-                        expected: Ty<'tcx>,
-                        def_bm: ty::BindingMode) -> Ty<'tcx>
+    fn check_pat_struct(
+        &self,
+        pat: &'gcx hir::Pat,
+        qpath: &hir::QPath,
+        fields: &'gcx [Spanned<hir::FieldPat>],
+        etc: bool,
+        expected: Ty<'tcx>,
+        def_bm: ty::BindingMode,
+        match_discrim_span: Option<Span>,
+    ) -> Ty<'tcx>
     {
         // Resolve the path and check the definition for errors.
         let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, pat.id) {
             variant_ty
         } else {
             for field in fields {
-                self.check_pat_walk(&field.node.pat, self.tcx.types.err, def_bm, true);
+                self.check_pat_walk(
+                    &field.node.pat,
+                    self.tcx.types.err,
+                    def_bm,
+                    match_discrim_span,
+                );
             }
             return self.tcx.types.err;
         };
 
         // Type-check the path.
-        self.demand_eqtype(pat.span, expected, pat_ty);
+        self.demand_eqtype_pat(pat.span, expected, pat_ty, match_discrim_span);
 
         // Type-check subpatterns.
         if self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc, def_bm) {
@@ -732,11 +764,12 @@ fn check_pat_struct(&self,
         }
     }
 
-    fn check_pat_path(&self,
-                      pat: &hir::Pat,
-                      qpath: &hir::QPath,
-                      expected: Ty<'tcx>) -> Ty<'tcx>
-    {
+    fn check_pat_path(
+        &self,
+        pat: &hir::Pat,
+        qpath: &hir::QPath,
+        expected: Ty<'tcx>,
+    ) -> Ty<'tcx> {
         let tcx = self.tcx;
 
         // Resolve the path and check the definition for errors.
@@ -767,18 +800,20 @@ fn check_pat_path(&self,
         pat_ty
     }
 
-    fn check_pat_tuple_struct(&self,
-                              pat: &hir::Pat,
-                              qpath: &hir::QPath,
-                              subpats: &'gcx [P<hir::Pat>],
-                              ddpos: Option<usize>,
-                              expected: Ty<'tcx>,
-                              def_bm: ty::BindingMode) -> Ty<'tcx>
-    {
+    fn check_pat_tuple_struct(
+        &self,
+        pat: &hir::Pat,
+        qpath: &hir::QPath,
+        subpats: &'gcx [P<hir::Pat>],
+        ddpos: Option<usize>,
+        expected: Ty<'tcx>,
+        def_bm: ty::BindingMode,
+        match_arm_pat_span: Option<Span>,
+    ) -> Ty<'tcx> {
         let tcx = self.tcx;
         let on_error = || {
             for pat in subpats {
-                self.check_pat_walk(&pat, tcx.types.err, def_bm, true);
+                self.check_pat_walk(&pat, tcx.types.err, def_bm, match_arm_pat_span);
             }
         };
         let report_unexpected_def = |def: Def| {
@@ -826,7 +861,7 @@ fn check_pat_tuple_struct(&self,
         let pat_ty = pat_ty.fn_sig(tcx).output();
         let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
 
-        self.demand_eqtype(pat.span, expected, pat_ty);
+        self.demand_eqtype_pat(pat.span, expected, pat_ty, match_arm_pat_span);
 
         // Type-check subpatterns.
         if subpats.len() == variant.fields.len() ||
@@ -837,7 +872,7 @@ fn check_pat_tuple_struct(&self,
             };
             for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
                 let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
-                self.check_pat_walk(&subpat, field_ty, def_bm, true);
+                self.check_pat_walk(&subpat, field_ty, def_bm, match_arm_pat_span);
 
                 self.tcx.check_stability(variant.fields[i].did, Some(pat.id), subpat.span);
             }
@@ -917,7 +952,7 @@ fn check_struct_pat_fields(&self,
                 }
             };
 
-            self.check_pat_walk(&field.pat, field_ty, def_bm, true);
+            self.check_pat_walk(&field.pat, field_ty, def_bm, None);
         }
         let mut unmentioned_fields = variant.fields
                 .iter()
index 38f9adee0a48fc1401a7ce4de3bd61caf46bf2ef..fbba89164e6db89a52ff18b1b8eb7b8946f7157d 100644 (file)
@@ -213,8 +213,14 @@ fn report_cast_error(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, e: CastError) {
                                        fcx.ty_to_string(self.expr_ty),
                                        cast_ty));
                 if let Ok(snippet) = fcx.sess().source_map().span_to_snippet(self.expr.span) {
-                    err.span_help(self.expr.span,
-                        &format!("did you mean `*{}`?", snippet));
+                    err.span_suggestion_with_applicability(
+                        self.expr.span,
+                        "dereference the expression",
+                        format!("*{}", snippet),
+                        Applicability::MaybeIncorrect,
+                    );
+                } else {
+                    err.span_help(self.expr.span, "dereference the expression with `*`");
                 }
                 err.emit();
             }
index 41f2b0ec7d24e829a67dd3e7f6c087a8f17fa7bc..c0cedd77440d9898e47352a5fb717cc918a51512 100644 (file)
@@ -1,6 +1,6 @@
 use check::FnCtxt;
 use rustc::infer::InferOk;
-use rustc::traits::ObligationCause;
+use rustc::traits::{ObligationCause, ObligationCauseCode};
 
 use syntax::ast;
 use syntax::util::parser::PREC_POSTFIX;
@@ -66,6 +66,25 @@ pub fn demand_eqtype_with_origin(&self,
         }
     }
 
+    pub fn demand_eqtype_pat(
+        &self,
+        cause_span: Span,
+        expected: Ty<'tcx>,
+        actual: Ty<'tcx>,
+        match_expr_span: Option<Span>,
+    ) {
+        let cause = if let Some(span) = match_expr_span {
+            self.cause(
+                cause_span,
+                ObligationCauseCode::MatchExpressionArmPattern { span, ty: expected },
+            )
+        } else {
+            self.misc(cause_span)
+        };
+        self.demand_eqtype_with_origin(&cause, expected, actual).map(|mut err| err.emit());
+    }
+
+
     pub fn demand_coerce(&self,
                          expr: &hir::Expr,
                          checked_ty: Ty<'tcx>,
index 821c30b4fa7090b9596fb376d29b7c664dd9fa66..9f323b9116d6fd7cc3723a6828fe62f556e98b2b 100644 (file)
@@ -66,6 +66,19 @@ fn equate_intrinsic_type<'a, 'tcx>(
     require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(def_id)), fty);
 }
 
+/// Returns whether the given intrinsic is unsafe to call or not.
+pub fn intrisic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
+    match intrinsic {
+        "size_of" | "min_align_of" | "needs_drop" |
+        "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" |
+        "overflowing_add" | "overflowing_sub" | "overflowing_mul" |
+        "rotate_left" | "rotate_right" |
+        "ctpop" | "ctlz" | "cttz" | "bswap" | "bitreverse"
+        => hir::Unsafety::Normal,
+        _ => hir::Unsafety::Unsafe,
+    }
+}
+
 /// Remember to add all intrinsics here, in librustc_codegen_llvm/intrinsic.rs,
 /// and in libcore/intrinsics.rs
 pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -117,10 +130,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     } else if &name[..] == "abort" || &name[..] == "unreachable" {
         (0, Vec::new(), tcx.types.never, hir::Unsafety::Unsafe)
     } else {
-        let unsafety = match &name[..] {
-            "size_of" | "min_align_of" | "needs_drop" => hir::Unsafety::Normal,
-            _ => hir::Unsafety::Unsafe,
-        };
+        let unsafety = intrisic_operation_unsafety(&name[..]);
         let (n_tps, inputs, output) = match &name[..] {
             "breakpoint" => (0, Vec::new(), tcx.mk_unit()),
             "size_of" |
index 1a5d164873d32f94a060e4029f9cd5a929a3dd52..1b07385d4d1f4e95da1d63627bddfddcda2e6f56 100644 (file)
@@ -80,7 +80,7 @@
 mod callee;
 mod compare_method;
 mod generator_interior;
-mod intrinsic;
+pub mod intrinsic;
 mod op;
 
 use astconv::{AstConv, PathSeg};
 use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::query::Providers;
+use rustc::ty::query::queries;
 use rustc::ty::subst::{UnpackedKind, Subst, Substs, UserSelfTy, UserSubsts};
 use rustc::ty::util::{Representability, IntTypeExt, Discr};
 use rustc::ty::layout::VariantIdx;
@@ -700,10 +701,16 @@ pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorRe
 
 pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
     tcx.sess.track_errors(|| {
-        tcx.hir().krate().visit_all_item_likes(&mut CheckItemTypesVisitor { tcx });
+        for &module in tcx.hir().krate().modules.keys() {
+            queries::check_mod_item_types::ensure(tcx, tcx.hir().local_def_id(module));
+        }
     })
 }
 
+fn check_mod_item_types<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
+    tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
+}
+
 pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), CompileIncomplete> {
     tcx.typeck_item_bodies(LOCAL_CRATE)
 }
@@ -742,6 +749,7 @@ pub fn provide(providers: &mut Providers) {
         check_item_well_formed,
         check_trait_item_well_formed,
         check_impl_item_well_formed,
+        check_mod_item_types,
         ..*providers
     };
 }
@@ -1084,8 +1092,12 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
     // Add formal parameters.
     for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
         // Check the pattern.
-        fcx.check_pat_walk(&arg.pat, arg_ty,
-            ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), true);
+        fcx.check_pat_walk(
+            &arg.pat,
+            arg_ty,
+            ty::BindingMode::BindByValue(hir::Mutability::MutImmutable),
+            None,
+        );
 
         // Check that argument is Sized.
         // The check for a non-trivial pattern is a hack to avoid duplicate warnings
@@ -3354,13 +3366,103 @@ fn check_then_else(&self,
         let coerce_to_ty = expected.coercion_target_type(self, sp);
         let mut coerce: DynamicCoerceMany = CoerceMany::new(coerce_to_ty);
 
-        let if_cause = self.cause(sp, ObligationCauseCode::IfExpression);
-        coerce.coerce(self, &if_cause, then_expr, then_ty);
+        coerce.coerce(self, &self.misc(sp), then_expr, then_ty);
 
         if let Some(else_expr) = opt_else_expr {
             let else_ty = self.check_expr_with_expectation(else_expr, expected);
             let else_diverges = self.diverges.get();
 
+            let mut outer_sp = if self.tcx.sess.source_map().is_multiline(sp) {
+                // The `if`/`else` isn't in one line in the output, include some context to make it
+                // clear it is an if/else expression:
+                // ```
+                // LL |      let x = if true {
+                //    | _____________-
+                // LL ||         10i32
+                //    ||         ----- expected because of this
+                // LL ||     } else {
+                // LL ||         10u32
+                //    ||         ^^^^^ expected i32, found u32
+                // LL ||     };
+                //    ||_____- if and else have incompatible types
+                // ```
+                Some(sp)
+            } else {
+                // The entire expression is in one line, only point at the arms
+                // ```
+                // LL |     let x = if true { 10i32 } else { 10u32 };
+                //    |                       -----          ^^^^^ expected i32, found u32
+                //    |                       |
+                //    |                       expected because of this
+                // ```
+                None
+            };
+            let mut remove_semicolon = None;
+            let error_sp = if let ExprKind::Block(block, _) = &else_expr.node {
+                if let Some(expr) = &block.expr {
+                    expr.span
+                } else if let Some(stmt) = block.stmts.last() {
+                    // possibly incorrect trailing `;` in the else arm
+                    remove_semicolon = self.could_remove_semicolon(block, then_ty);
+                    stmt.span
+                } else {  // empty block, point at its entirety
+                    // Avoid overlapping spans that aren't as readable:
+                    // ```
+                    // 2 |        let x = if true {
+                    //   |   _____________-
+                    // 3 |  |         3
+                    //   |  |         - expected because of this
+                    // 4 |  |     } else {
+                    //   |  |____________^
+                    // 5 | ||
+                    // 6 | ||     };
+                    //   | ||     ^
+                    //   | ||_____|
+                    //   | |______if and else have incompatible types
+                    //   |        expected integer, found ()
+                    // ```
+                    // by not pointing at the entire expression:
+                    // ```
+                    // 2 |       let x = if true {
+                    //   |               ------- if and else have incompatible types
+                    // 3 |           3
+                    //   |           - expected because of this
+                    // 4 |       } else {
+                    //   |  ____________^
+                    // 5 | |
+                    // 6 | |     };
+                    //   | |_____^ expected integer, found ()
+                    // ```
+                    if outer_sp.is_some() {
+                        outer_sp = Some(self.tcx.sess.source_map().def_span(sp));
+                    }
+                    else_expr.span
+                }
+            } else { // shouldn't happen unless the parser has done something weird
+                else_expr.span
+            };
+            let then_sp = if let ExprKind::Block(block, _) = &then_expr.node {
+                if let Some(expr) = &block.expr {
+                    expr.span
+                } else if let Some(stmt) = block.stmts.last() {
+                    // possibly incorrect trailing `;` in the else arm
+                    remove_semicolon = remove_semicolon.or(
+                        self.could_remove_semicolon(block, else_ty));
+                    stmt.span
+                } else {  // empty block, point at its entirety
+                    outer_sp = None;  // same as in `error_sp`, cleanup output
+                    then_expr.span
+                }
+            } else {  // shouldn't happen unless the parser has done something weird
+                then_expr.span
+            };
+
+            let if_cause = self.cause(error_sp, ObligationCauseCode::IfExpression {
+                then: then_sp,
+                outer: outer_sp,
+                semicolon: remove_semicolon,
+            });
+
             coerce.coerce(self, &if_cause, else_expr, else_ty);
 
             // We won't diverge unless both branches do (or the condition does).
@@ -4723,9 +4825,12 @@ pub fn check_decl_local(&self, local: &'gcx hir::Local) {
             }
         }
 
-        self.check_pat_walk(&local.pat, t,
-                            ty::BindingMode::BindByValue(hir::Mutability::MutImmutable),
-                            true);
+        self.check_pat_walk(
+            &local.pat,
+            t,
+            ty::BindingMode::BindByValue(hir::Mutability::MutImmutable),
+            None,
+        );
         let pat_ty = self.node_ty(local.pat.hir_id);
         if pat_ty.references_error() {
             self.write_ty(local.hir_id, pat_ty);
@@ -5129,7 +5234,6 @@ fn suggest_missing_return_type(&self,
         }
     }
 
-
     /// A common error is to add an extra semicolon:
     ///
     /// ```
@@ -5141,31 +5245,43 @@ fn suggest_missing_return_type(&self,
     /// This routine checks if the final statement in a block is an
     /// expression with an explicit semicolon whose type is compatible
     /// with `expected_ty`. If so, it suggests removing the semicolon.
-    fn consider_hint_about_removing_semicolon(&self,
-                                              blk: &'gcx hir::Block,
-                                              expected_ty: Ty<'tcx>,
-                                              err: &mut DiagnosticBuilder) {
+    fn consider_hint_about_removing_semicolon(
+        &self,
+        blk: &'gcx hir::Block,
+        expected_ty: Ty<'tcx>,
+        err: &mut DiagnosticBuilder,
+    ) {
+        if let Some(span_semi) = self.could_remove_semicolon(blk, expected_ty) {
+            err.span_suggestion_with_applicability(
+                span_semi,
+                "consider removing this semicolon",
+                String::new(),
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+
+    fn could_remove_semicolon(
+        &self,
+        blk: &'gcx hir::Block,
+        expected_ty: Ty<'tcx>,
+    ) -> Option<Span> {
         // Be helpful when the user wrote `{... expr;}` and
         // taking the `;` off is enough to fix the error.
         let last_stmt = match blk.stmts.last() {
             Some(s) => s,
-            None => return,
+            None => return None,
         };
         let last_expr = match last_stmt.node {
             hir::StmtKind::Semi(ref e, _) => e,
-            _ => return,
+            _ => return None,
         };
         let last_expr_ty = self.node_ty(last_expr.hir_id);
         if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
-            return;
+            return None;
         }
         let original_span = original_sp(last_stmt.span, blk.span);
-        let span_semi = original_span.with_lo(original_span.hi() - BytePos(1));
-        err.span_suggestion_with_applicability(
-            span_semi,
-            "consider removing this semicolon",
-            String::new(),
-            Applicability::MachineApplicable);
+        Some(original_span.with_lo(original_span.hi() - BytePos(1)))
     }
 
     // Instantiates the given path, which must refer to an item with the given
index 86165d50b27e4366887070a27efd31ee3c35755a..ffd7c2114e5ab34294c4f03584d02d669ce4cf42 100644 (file)
@@ -122,14 +122,18 @@ fn analyze_closure(
         };
 
         self.tcx.with_freevars(closure_node_id, |freevars| {
+            let mut freevar_list: Vec<ty::UpvarId> = Vec::with_capacity(freevars.len());
             for freevar in freevars {
                 let upvar_id = ty::UpvarId {
                     var_path: ty::UpvarPath {
-                        hir_id : self.tcx.hir().node_to_hir_id(freevar.var_id()),
+                        hir_id: self.tcx.hir().node_to_hir_id(freevar.var_id()),
                     },
                     closure_expr_id: LocalDefId::from_def_id(closure_def_id),
                 };
                 debug!("seed upvar_id {:?}", upvar_id);
+                // Adding the upvar Id to the list of Upvars, which will be added
+                // to the map for the closure at the end of the for loop.
+                freevar_list.push(upvar_id);
 
                 let capture_kind = match capture_clause {
                     hir::CaptureByValue => ty::UpvarCapture::ByValue,
@@ -149,6 +153,15 @@ fn analyze_closure(
                     .upvar_capture_map
                     .insert(upvar_id, capture_kind);
             }
+            // Add the vector of freevars to the map keyed with the closure id.
+            // This gives us an easier access to them without having to call
+            // with_freevars again..
+            if !freevar_list.is_empty() {
+                self.tables
+                    .borrow_mut()
+                    .upvar_list
+                    .insert(closure_def_id, freevar_list);
+            }
         });
 
         let body_owner_def_id = self.tcx.hir().body_owner_def_id(body.id());
@@ -166,7 +179,8 @@ fn analyze_closure(
             self.param_env,
             region_scope_tree,
             &self.tables.borrow(),
-        ).consume_body(body);
+        )
+        .consume_body(body);
 
         if let Some(closure_substs) = infer_kind {
             // Unify the (as yet unbound) type variable in the closure
@@ -240,9 +254,7 @@ fn final_upvar_tys(&self, closure_id: ast::NodeId) -> Vec<Ty<'tcx>> {
                     let var_hir_id = tcx.hir().node_to_hir_id(var_node_id);
                     let freevar_ty = self.node_ty(var_hir_id);
                     let upvar_id = ty::UpvarId {
-                        var_path: ty::UpvarPath {
-                            hir_id: var_hir_id,
-                        },
+                        var_path: ty::UpvarPath { hir_id: var_hir_id },
                         closure_expr_id: LocalDefId::from_def_id(closure_def_index),
                     };
                     let capture = self.tables.borrow().upvar_capture(upvar_id);
@@ -262,7 +274,8 @@ fn final_upvar_tys(&self, closure_id: ast::NodeId) -> Vec<Ty<'tcx>> {
                             },
                         ),
                     }
-                }).collect()
+                })
+                .collect()
         })
     }
 }
index 38de936a027ff6e2dd4e28ddb2d70812ea138744..c61159eb4948121bb64bcfb2bfd46122a3bf3071 100644 (file)
 ///////////////////////////////////////////////////////////////////////////
 // Entry point
 
+// During type inference, partially inferred types are
+// represented using Type variables (ty::Infer). These don't appear in
+// the final TypeckTables since all of the types should have been
+// inferred once typeck_tables_of is done.
+// When type inference is running however, having to update the typeck
+// tables every time a new type is inferred would be unreasonably slow,
+// so instead all of the replacement happens at the end in
+// resolve_type_vars_in_body, which creates a new TypeTables which
+// doesn't contain any inference types.
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body) -> &'gcx ty::TypeckTables<'gcx> {
         let item_id = self.tcx.hir().body_owner(body.id());
@@ -35,7 +44,8 @@ pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body) -> &'gcx ty::Type
             wbcx.visit_node_id(arg.pat.span, arg.hir_id);
         }
         wbcx.visit_body(body);
-        wbcx.visit_upvar_borrow_map();
+        wbcx.visit_upvar_capture_map();
+        wbcx.visit_upvar_list_map();
         wbcx.visit_closures();
         wbcx.visit_liberated_fn_sigs();
         wbcx.visit_fru_field_types();
@@ -291,7 +301,7 @@ fn visit_ty(&mut self, hir_ty: &'gcx hir::Ty) {
 }
 
 impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
-    fn visit_upvar_borrow_map(&mut self) {
+    fn visit_upvar_capture_map(&mut self) {
         for (upvar_id, upvar_capture) in self.fcx.tables.borrow().upvar_capture_map.iter() {
             let new_upvar_capture = match *upvar_capture {
                 ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue,
@@ -314,6 +324,21 @@ fn visit_upvar_borrow_map(&mut self) {
         }
     }
 
+    /// Runs through the function context's upvar list map and adds the same to
+    /// the TypeckTables. upvarlist is a hashmap of the list of upvars referred
+    /// to in a closure..
+    fn visit_upvar_list_map(&mut self) {
+        for (closure_def_id, upvar_list) in self.fcx.tables.borrow().upvar_list.iter() {
+            debug!(
+                "UpvarIDs captured by closure {:?} are: {:?}",
+                closure_def_id, upvar_list
+            );
+            self.tables
+                .upvar_list
+                .insert(*closure_def_id, upvar_list.to_vec());
+        }
+    }
+
     fn visit_closures(&mut self) {
         let fcx_tables = self.fcx.tables.borrow();
         debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root);
index 54e4a86cc4ec5eea6cbbe1c6a309c5277777895e..2df137c3f5094db5ca60181e61c7dc0bea910b31 100644 (file)
@@ -40,7 +40,7 @@ fn visit_item(&mut self, item: &hir::Item) {
                                      "only traits defined in the current crate can be \
                                       implemented for arbitrary types")
                         .span_label(sp, "impl doesn't use types inside crate")
-                        .note("the impl does not reference any types defined in this crate")
+                        .note("the impl does not reference only types defined in this crate")
                         .note("define and implement a trait or new type instead")
                         .emit();
                     return;
index e0e173901ef38bfb1af2612757bf96975d35f608..67e3d1278022009402908f513da4fa928ab3035d 100644 (file)
 
 use astconv::{AstConv, Bounds};
 use constrained_type_params as ctp;
+use check::intrinsic::intrisic_operation_unsafety;
 use lint;
 use middle::lang_items::SizedTraitLangItem;
 use middle::resolve_lifetime as rl;
 use middle::weak_lang_items;
 use rustc::mir::mono::Linkage;
 use rustc::ty::query::Providers;
+use rustc::ty::query::queries;
 use rustc::ty::subst::Substs;
 use rustc::ty::util::Discr;
 use rustc::ty::util::IntTypeExt;
 // Main entry point
 
 pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    let mut visitor = CollectItemTypesVisitor { tcx };
-    tcx.hir()
-       .krate()
-       .visit_all_item_likes(&mut visitor.as_deep_visitor());
+    for &module in tcx.hir().krate().modules.keys() {
+        queries::collect_mod_item_types::ensure(tcx, tcx.hir().local_def_id(module));
+    }
+}
+
+fn collect_mod_item_types<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
+    tcx.hir().visit_item_likes_in_module(
+        module_def_id,
+        &mut CollectItemTypesVisitor { tcx }.as_deep_visitor()
+    );
 }
 
 pub fn provide(providers: &mut Providers) {
@@ -77,6 +85,7 @@ pub fn provide(providers: &mut Providers) {
         impl_polarity,
         is_foreign_item,
         codegen_fn_attrs,
+        collect_mod_item_types,
         ..*providers
     };
 }
@@ -1107,7 +1116,7 @@ fn report_assoc_ty_on_inherent_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span:
         tcx.sess,
         span,
         E0202,
-        "associated types are not allowed in inherent impls"
+        "associated types are not yet supported in inherent impls (see #8995)"
     );
 }
 
@@ -2080,10 +2089,7 @@ fn compute_sig_of_foreign_fn_decl<'a, 'tcx>(
     abi: abi::Abi,
 ) -> ty::PolyFnSig<'tcx> {
     let unsafety = if abi == abi::Abi::RustIntrinsic {
-        match &*tcx.item_name(def_id).as_str() {
-            "size_of" | "min_align_of" | "needs_drop" => hir::Unsafety::Normal,
-            _ => hir::Unsafety::Unsafe,
-        }
+        intrisic_operation_unsafety(&*tcx.item_name(def_id).as_str())
     } else {
         hir::Unsafety::Unsafe
     };
index 37c6407fbd1c0eedbfdc57c3c10d4d42ce274e59..6eea95b61c99051e5652a028c4639bebcc283c37 100644 (file)
@@ -587,7 +587,7 @@ fn clean(&self, cx: &DocContext) -> Item {
         let attrs = self.attrs.clean(cx);
 
         let mut items: Vec<Item> = vec![];
-        items.extend(self.extern_crates.iter().map(|x| x.clean(cx)));
+        items.extend(self.extern_crates.iter().flat_map(|x| x.clean(cx)));
         items.extend(self.imports.iter().flat_map(|x| x.clean(cx)));
         items.extend(self.structs.iter().map(|x| x.clean(cx)));
         items.extend(self.unions.iter().map(|x| x.clean(cx)));
@@ -3503,9 +3503,30 @@ fn build_deref_target_impls(cx: &DocContext,
     }
 }
 
-impl Clean<Item> for doctree::ExternCrate {
-    fn clean(&self, cx: &DocContext) -> Item {
-        Item {
+impl Clean<Vec<Item>> for doctree::ExternCrate {
+    fn clean(&self, cx: &DocContext) -> Vec<Item> {
+
+        let please_inline = self.vis.node.is_pub() && self.attrs.iter().any(|a| {
+            a.name() == "doc" && match a.meta_item_list() {
+                Some(l) => attr::list_contains_name(&l, "inline"),
+                None => false,
+            }
+        });
+
+        if please_inline {
+            let mut visited = FxHashSet::default();
+
+            let def = Def::Mod(DefId {
+                krate: self.cnum,
+                index: CRATE_DEF_INDEX,
+            });
+
+            if let Some(items) = inline::try_inline(cx, def, self.name, &mut visited) {
+                return items;
+            }
+        }
+
+        vec![Item {
             name: None,
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
@@ -3514,7 +3535,7 @@ fn clean(&self, cx: &DocContext) -> Item {
             stability: None,
             deprecation: None,
             inner: ExternCrateItem(self.name.clean(cx), self.path.clone())
-        }
+        }]
     }
 }
 
index 184d5b24d6e12cadd2c933d342cf0a33cf5b9957..31e06cb1a045fb6164ab683e27ce3a92a25ee696 100644 (file)
@@ -893,14 +893,12 @@ fn write_shared(
           static_files::fira_sans::MEDIUM)?;
     write(cx.dst.join("FiraSans-LICENSE.txt"),
           static_files::fira_sans::LICENSE)?;
-    write(cx.dst.join("Heuristica-Italic.woff"),
-          static_files::heuristica::ITALIC)?;
-    write(cx.dst.join("Heuristica-LICENSE.txt"),
-          static_files::heuristica::LICENSE)?;
-    write(cx.dst.join("SourceSerifPro-Regular.woff"),
+    write(cx.dst.join("SourceSerifPro-Regular.ttf.woff"),
           static_files::source_serif_pro::REGULAR)?;
-    write(cx.dst.join("SourceSerifPro-Bold.woff"),
+    write(cx.dst.join("SourceSerifPro-Bold.ttf.woff"),
           static_files::source_serif_pro::BOLD)?;
+    write(cx.dst.join("SourceSerifPro-It.ttf.woff"),
+          static_files::source_serif_pro::ITALIC)?;
     write(cx.dst.join("SourceSerifPro-LICENSE.txt"),
           static_files::source_serif_pro::LICENSE)?;
     write(cx.dst.join("SourceCodePro-Regular.woff"),
@@ -3061,7 +3059,7 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::
         let item_type = m.type_();
         let id = cx.derive_id(format!("{}.{}", item_type, name));
         let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
-        write!(w, "{extra}<h3 id='{id}' class='method'><code id='{ns_id}'>",
+        write!(w, "<h3 id='{id}' class='method'>{extra}<code id='{ns_id}'>",
                extra = render_spotlight_traits(m)?,
                id = id,
                ns_id = ns_id)?;
@@ -3446,7 +3444,7 @@ fn item_union(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
             let id = format!("{}.{}", ItemType::StructField, name);
             write!(w, "<span id=\"{id}\" class=\"{shortty} small-section-header\">\
                            <a href=\"#{id}\" class=\"anchor field\"></a>\
-                           <span class='invisible'><code>{name}: {ty}</code></span>\
+                           <code>{name}: {ty}</code>\
                        </span>",
                    id = id,
                    name = name,
@@ -4001,8 +3999,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
             None => "impl".to_string(),
         });
         if let Some(use_absolute) = use_absolute {
-            write!(w, "<h3 id='{}' class='impl'><span class='in-band'><table class='table-display'>\
-                       <tbody><tr><td><code>", id)?;
+            write!(w, "<h3 id='{}' class='impl'><code class='in-band'>", id)?;
             fmt_impl_for_trait_page(&i.inner_impl(), w, use_absolute)?;
             if show_def_docs {
                 for it in &i.inner_impl().items {
@@ -4016,22 +4013,18 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
             }
             write!(w, "</code>")?;
         } else {
-            write!(w, "<h3 id='{}' class='impl'><span class='in-band'><table class='table-display'>\
-                       <tbody><tr><td><code>{}</code>",
-                   id, i.inner_impl())?;
+            write!(w, "<h3 id='{}' class='impl'><code class='in-band'>{}</code>",
+                id, i.inner_impl()
+            )?;
         }
         write!(w, "<a href='#{}' class='anchor'></a>", id)?;
-        write!(w, "</td><td><span class='out-of-band'>")?;
         let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]);
+        render_stability_since_raw(w, since, outer_version)?;
         if let Some(l) = (Item { item: &i.impl_item, cx: cx }).src_href() {
-            write!(w, "<div class='ghost'></div>")?;
-            render_stability_since_raw(w, since, outer_version)?;
             write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
                    l, "goto source code")?;
-        } else {
-            render_stability_since_raw(w, since, outer_version)?;
         }
-        write!(w, "</span></td></tr></tbody></table></span></h3>")?;
+        write!(w, "</h3>")?;
         if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) {
             let mut ids = cx.id_map.borrow_mut();
             write!(w, "<div class='docblock'>{}</div>",
@@ -4067,20 +4060,15 @@ fn doc_impl_item(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
                     let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
                     write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class)?;
                     write!(w, "{}", spotlight_decl(decl)?)?;
-                    write!(w, "<table id='{}' class='table-display'><tbody><tr><td><code>", ns_id)?;
+                    write!(w, "<code id='{}'>", ns_id)?;
                     render_assoc_item(w, item, link.anchor(&id), ItemType::Impl)?;
                     write!(w, "</code>")?;
+                    render_stability_since_raw(w, item.stable_since(), outer_version)?;
                     if let Some(l) = (Item { cx, item }).src_href() {
-                        write!(w, "</td><td><span class='out-of-band'>")?;
-                        write!(w, "<div class='ghost'></div>")?;
-                        render_stability_since_raw(w, item.stable_since(), outer_version)?;
-                        write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a></span>",
+                        write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
                                l, "goto source code")?;
-                    } else {
-                        write!(w, "</td><td>")?;
-                        render_stability_since_raw(w, item.stable_since(), outer_version)?;
                     }
-                    write!(w, "</td></tr></tbody></table></h4>")?;
+                    write!(w, "</h4>")?;
                 }
             }
             clean::TypedefItem(ref tydef, _) => {
@@ -4092,40 +4080,18 @@ fn doc_impl_item(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
                 write!(w, "</code></h4>")?;
             }
             clean::AssociatedConstItem(ref ty, ref default) => {
-                let mut version = String::new();
-
-                render_stability_since_raw(&mut version, item.stable_since(), outer_version)?;
-
                 let id = cx.derive_id(format!("{}.{}", item_type, name));
                 let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
                 write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class)?;
-                if !version.is_empty() {
-                    write!(w, "<table id='{}' class='table-display'><tbody><tr><td><code>", ns_id)?;
-                } else {
-                    write!(w, "<code id='{}'>", ns_id)?;
-                }
+                write!(w, "<code id='{}'>", ns_id)?;
                 assoc_const(w, item, ty, default.as_ref(), link.anchor(&id))?;
-                if !version.is_empty() {
-                    write!(w, "</code>")?;
-                }
-                let src = if let Some(l) = (Item { cx, item }).src_href() {
-                    if !version.is_empty() {
-                        write!(w, "</td><td><span class='out-of-band'>")?;
-                        write!(w, "<div class='ghost'></div>{}", version)?;
-                    }
-                    format!("<a class='srclink' href='{}' title='{}'>[src]</a>",
-                            l, "goto source code")
-                } else {
-                    if !version.is_empty() {
-                        write!(w, "</td><td>{}", version)?;
-                    }
-                    String::new()
-                };
-                if version.is_empty() {
-                    write!(w, "</code>{}</h4>", src)?;
-                } else {
-                    write!(w, "{}</span></td></tr></tbody></table></h4>", src)?;
+                write!(w, "</code>")?;
+                render_stability_since_raw(w, item.stable_since(), outer_version)?;
+                if let Some(l) = (Item { cx, item }).src_href() {
+                    write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
+                            l, "goto source code")?;
                 }
+                write!(w, "</h4>")?;
             }
             clean::AssociatedTypeItem(ref bounds, ref default) => {
                 let id = cx.derive_id(format!("{}.{}", item_type, name));
index c69861aa70a237dd77f6ff611a215080b596e2f5..af77776cca431b6d88da119f16e64f66f0834f37 100644 (file)
@@ -12,21 +12,6 @@ included, and carry their own copyright notices and license terms:
     Licensed under the SIL Open Font License, Version 1.1.
     See FiraSans-LICENSE.txt.
 
-* Heuristica (Heuristica-Italic.woff):
-
-    Copyright 1989, 1991 Adobe Systems Incorporated. All rights reserved.
-    Utopia is either a registered trademark or trademark of Adobe Systems
-    Incorporated in the United States and/or other countries. Used under
-    license.
-
-    Copyright 2006 Han The Thanh, Vntopia font family, http://vntex.sf.net
-
-    Copyright (c) 2008-2012, Andrey V. Panov (panov@canopus.iacp.dvo.ru),
-    with Reserved Font Name Heuristica.
-
-    Licensed under the SIL Open Font License, Version 1.1.
-    See Heuristica-LICENSE.txt.
-
 * rustdoc.css, main.js, and playpen.js:
 
     Copyright 2015 The Rust Developers.
@@ -47,7 +32,8 @@ included, and carry their own copyright notices and license terms:
     Licensed under the SIL Open Font License, Version 1.1.
     See SourceCodePro-LICENSE.txt.
 
-* Source Serif Pro (SourceSerifPro-Regular.woff, SourceSerifPro-Bold.woff):
+* Source Serif Pro (SourceSerifPro-Regular.ttf.woff,
+    SourceSerifPro-Bold.ttf.woff, SourceSerifPro-It.ttf.woff):
 
     Copyright 2014 Adobe Systems Incorporated (http://www.adobe.com/), with
     Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of
diff --git a/src/librustdoc/html/static/Heuristica-Italic.woff b/src/librustdoc/html/static/Heuristica-Italic.woff
deleted file mode 100644 (file)
index b0cebf0..0000000
Binary files a/src/librustdoc/html/static/Heuristica-Italic.woff and /dev/null differ
diff --git a/src/librustdoc/html/static/Heuristica-LICENSE.txt b/src/librustdoc/html/static/Heuristica-LICENSE.txt
deleted file mode 100644 (file)
index dd85e40..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-Copyright 1989, 1991 Adobe Systems Incorporated. All rights reserved.
-Utopia is either a registered trademark or trademark of Adobe Systems
-Incorporated in the United States and/or other countries. Used under
-license.
-
-Copyright 2006 Han The Thanh, Vntopia font family, http://vntex.sf.net
-
-Copyright (c) 2008-2012, Andrey V. Panov (panov@canopus.iacp.dvo.ru),
-with Reserved Font Name Heuristica.
-
-This Font Software is licensed under the SIL Open Font License, Version 1.1.
-This license is copied below, and is also available with a FAQ at:
-http://scripts.sil.org/OFL
-
-
------------------------------------------------------------
-SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
------------------------------------------------------------
-
-PREAMBLE
-The goals of the Open Font License (OFL) are to stimulate worldwide
-development of collaborative font projects, to support the font creation
-efforts of academic and linguistic communities, and to provide a free and
-open framework in which fonts may be shared and improved in partnership
-with others.
-
-The OFL allows the licensed fonts to be used, studied, modified and
-redistributed freely as long as they are not sold by themselves. The
-fonts, including any derivative works, can be bundled, embedded,
-redistributed and/or sold with any software provided that any reserved
-names are not used by derivative works. The fonts and derivatives,
-however, cannot be released under any other type of license. The
-requirement for fonts to remain under this license does not apply
-to any document created using the fonts or their derivatives.
-
-DEFINITIONS
-"Font Software" refers to the set of files released by the Copyright
-Holder(s) under this license and clearly marked as such. This may
-include source files, build scripts and documentation.
-
-"Reserved Font Name" refers to any names specified as such after the
-copyright statement(s).
-
-"Original Version" refers to the collection of Font Software components as
-distributed by the Copyright Holder(s).
-
-"Modified Version" refers to any derivative made by adding to, deleting,
-or substituting -- in part or in whole -- any of the components of the
-Original Version, by changing formats or by porting the Font Software to a
-new environment.
-
-"Author" refers to any designer, engineer, programmer, technical
-writer or other person who contributed to the Font Software.
-
-PERMISSION & CONDITIONS
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of the Font Software, to use, study, copy, merge, embed, modify,
-redistribute, and sell modified and unmodified copies of the Font
-Software, subject to the following conditions:
-
-1) Neither the Font Software nor any of its individual components,
-in Original or Modified Versions, may be sold by itself.
-
-2) Original or Modified Versions of the Font Software may be bundled,
-redistributed and/or sold with any software, provided that each copy
-contains the above copyright notice and this license. These can be
-included either as stand-alone text files, human-readable headers or
-in the appropriate machine-readable metadata fields within text or
-binary files as long as those fields can be easily viewed by the user.
-
-3) No Modified Version of the Font Software may use the Reserved Font
-Name(s) unless explicit written permission is granted by the corresponding
-Copyright Holder. This restriction only applies to the primary font name as
-presented to the users.
-
-4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
-Software shall not be used to promote, endorse or advertise any
-Modified Version, except to acknowledge the contribution(s) of the
-Copyright Holder(s) and the Author(s) or with their explicit written
-permission.
-
-5) The Font Software, modified or unmodified, in part or in whole,
-must be distributed entirely under this license, and must not be
-distributed under any other license. The requirement for fonts to
-remain under this license does not apply to any document created
-using the Font Software.
-
-TERMINATION
-This license becomes null and void if any of the above conditions are
-not met.
-
-DISCLAIMER
-THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
-COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
-DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
-OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/src/librustdoc/html/static/SourceSerifPro-Bold.ttf.woff b/src/librustdoc/html/static/SourceSerifPro-Bold.ttf.woff
new file mode 100644 (file)
index 0000000..e283dae
Binary files /dev/null and b/src/librustdoc/html/static/SourceSerifPro-Bold.ttf.woff differ
diff --git a/src/librustdoc/html/static/SourceSerifPro-Bold.woff b/src/librustdoc/html/static/SourceSerifPro-Bold.woff
deleted file mode 100644 (file)
index ac1b1b3..0000000
Binary files a/src/librustdoc/html/static/SourceSerifPro-Bold.woff and /dev/null differ
diff --git a/src/librustdoc/html/static/SourceSerifPro-It.ttf.woff b/src/librustdoc/html/static/SourceSerifPro-It.ttf.woff
new file mode 100644 (file)
index 0000000..4bd621c
Binary files /dev/null and b/src/librustdoc/html/static/SourceSerifPro-It.ttf.woff differ
diff --git a/src/librustdoc/html/static/SourceSerifPro-Regular.ttf.woff b/src/librustdoc/html/static/SourceSerifPro-Regular.ttf.woff
new file mode 100644 (file)
index 0000000..96b36a0
Binary files /dev/null and b/src/librustdoc/html/static/SourceSerifPro-Regular.ttf.woff differ
diff --git a/src/librustdoc/html/static/SourceSerifPro-Regular.woff b/src/librustdoc/html/static/SourceSerifPro-Regular.woff
deleted file mode 100644 (file)
index e8c43b8..0000000
Binary files a/src/librustdoc/html/static/SourceSerifPro-Regular.woff and /dev/null differ
index 75b0f5df0d8b3667b04791dd0791afc5a2f8f70f..9db1c686090399570951f5cf8caa2c9ea0ef54e2 100644 (file)
@@ -2409,8 +2409,17 @@ if (!DOMTokenList.prototype.remove) {
             e.remove();
         });
         onEachLazy(main.childNodes, function(e) {
+            // Unhide the actual content once loading is complete. Headers get
+            // flex treatment for their horizontal layout, divs get block treatment
+            // for vertical layout (column-oriented flex layout for divs caused
+            // errors in mobile browsers).
             if (e.tagName === "H2" || e.tagName === "H3") {
-                e.nextElementSibling.style.display = "block";
+                let nextTagName = e.nextElementSibling.tagName;
+                if (nextTagName == "H2" || nextTagName == "H3") {
+                    e.nextElementSibling.style.display = "flex";
+                } else {
+                    e.nextElementSibling.style.display = "block";
+                }
             }
         });
     }
index 2cc0b5e30b89321b14868df96891a61ef73daf10..8a8b7adcf7d4a0384735615565119368d0dca2d8 100644 (file)
        src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff');
 }
 
-/* See SourceSerifPro-LICENSE.txt for the Source Serif Pro license and
- * Heuristica-LICENSE.txt for the Heuristica license. */
+/* See SourceSerifPro-LICENSE.txt for the Source Serif Pro license. */
 @font-face {
        font-family: 'Source Serif Pro';
        font-style: normal;
        font-weight: 400;
-       src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff');
+       src: local('Source Serif Pro'), url("SourceSerifPro-Regular.ttf.woff") format('woff');
 }
 @font-face {
        font-family: 'Source Serif Pro';
        font-style: italic;
        font-weight: 400;
-       src: url("Heuristica-Italic.woff") format('woff');
+       src: local('Source Serif Pro Italic'), url("SourceSerifPro-It.ttf.woff") format('woff');
 }
 @font-face {
        font-family: 'Source Serif Pro';
        font-style: normal;
        font-weight: 700;
-       src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff');
+       src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.ttf.woff") format('woff');
 }
 
 /* See SourceCodePro-LICENSE.txt for the Source Code Pro license. */
@@ -90,8 +89,9 @@ h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.t
        border-bottom: 1px solid;
 }
 h3.impl, h3.method, h4.method, h3.type, h4.type, h4.associatedconstant {
+       flex-basis: 100%;
        font-weight: 600;
-       margin-top: 10px;
+       margin-top: 16px;
        margin-bottom: 10px;
        position: relative;
 }
@@ -357,7 +357,8 @@ nav.sub {
 #main > .docblock h3, #main > .docblock h4, #main > .docblock h5 { font-size: 1em; }
 
 #main > h2 + div, #main > h2 + h3, #main > h3 + div {
-       display: none;
+       display: none; /* Changed to flex or block via js once the page is loaded */
+       flex-wrap: wrap;
 }
 
 .docblock h1 { font-size: 1em; }
@@ -391,7 +392,7 @@ h4 > code, h3 > code, .invisible > code {
 }
 
 .in-band, code {
-       z-index: 5;
+       z-index: -5;
 }
 
 .invisible {
@@ -535,6 +536,10 @@ h4 > code, h3 > code, .invisible > code {
        margin-top: -8px;
 }
 
+.impl-items {
+       flex-basis: 100%;
+}
+
 #main > .stability {
        margin-top: 0;
 }
@@ -785,6 +790,33 @@ body.blur > :not(#help) {
        top: 0;
 }
 
+.impl-items .since, .impl .since {
+       flex-grow: 0;
+       padding-left: 12px;
+       padding-right: 2px;
+       position: initial;
+}
+
+.impl-items .srclink, .impl .srclink {
+       flex-grow: 0;
+       /* Override header settings otherwise it's too bold */
+       font-size: 17px;
+       font-weight: normal;
+}
+
+.impl-items code, .impl code {
+       flex-grow: 1;
+}
+
+.impl-items h4, h4.impl, h3.impl {
+       display: flex;
+       flex-basis: 100%;
+       font-size: 16px;
+       margin-bottom: 12px;
+       /* Push the src link out to the right edge consistently */
+       justify-content: space-between;
+}
+
 .variants_table {
        width: 100%;
 }
@@ -872,15 +904,6 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
        margin-left: 20px;
 }
 
-.ghost {
-       display: none;
-}
-
-.ghost + .since {
-       position: initial;
-       display: table-cell;
-}
-
 .since + .srclink {
        display: table-cell;
        padding-left: 10px;
@@ -1120,7 +1143,7 @@ span.since {
        margin-left: 5px;
        top: -5px;
        left: 105%;
-       z-index: 1;
+       z-index: 10;
 }
 
 .tooltip:hover .tooltiptext {
@@ -1362,8 +1385,9 @@ h3.important {
        margin-top: 16px;
 }
 
-.content > .methods > div.important-traits {
+.content > .methods > .method > div.important-traits {
        position: absolute;
+       font-weight: 400;
        left: -42px;
        margin-top: 2px;
 }
index 47629d058e31a1b19a5f8e6d0f8ebc9f286a3024..f340590e5fe33b4dc4bd149f14a44e1c6c24a04b 100644 (file)
@@ -73,22 +73,17 @@ pub mod fira_sans {
     pub static LICENSE: &'static [u8] = include_bytes!("static/FiraSans-LICENSE.txt");
 }
 
-/// Files related to the Heuristica font.
-pub mod heuristica {
-    /// The file `Heuristica-Italic.woff`, the Italic variant of the Heuristica font.
-    pub static ITALIC: &'static [u8] = include_bytes!("static/Heuristica-Italic.woff");
-
-    /// The file `Heuristica-LICENSE.txt`, the license text for the Heuristica font.
-    pub static LICENSE: &'static [u8] = include_bytes!("static/Heuristica-LICENSE.txt");
-}
-
 /// Files related to the Source Serif Pro font.
 pub mod source_serif_pro {
-    /// The file `SourceSerifPro-Regular.woff`, the Regular variant of the Source Serif Pro font.
-    pub static REGULAR: &'static [u8] = include_bytes!("static/SourceSerifPro-Regular.woff");
+    /// The file `SourceSerifPro-Regular.ttf.woff`, the Regular variant of the Source Serif Pro
+    /// font.
+    pub static REGULAR: &'static [u8] = include_bytes!("static/SourceSerifPro-Regular.ttf.woff");
+
+    /// The file `SourceSerifPro-Bold.ttf.woff`, the Bold variant of the Source Serif Pro font.
+    pub static BOLD: &'static [u8] = include_bytes!("static/SourceSerifPro-Bold.ttf.woff");
 
-    /// The file `SourceSerifPro-Bold.woff`, the Bold variant of the Source Serif Pro font.
-    pub static BOLD: &'static [u8] = include_bytes!("static/SourceSerifPro-Bold.woff");
+    /// The file `SourceSerifPro-It.ttf.woff`, the Italic variant of the Source Serif Pro font.
+    pub static ITALIC: &'static [u8] = include_bytes!("static/SourceSerifPro-It.ttf.woff");
 
     /// The file `SourceSerifPro-LICENSE.txt`, the license text for the Source Serif Pro font.
     pub static LICENSE: &'static [u8] = include_bytes!("static/SourceSerifPro-LICENSE.txt");
index 2170054b532b96eb1d23dc7d4c29088c2bb367d6..1f19fa2e7f598fbd8315fd62a6baba1170400264 100644 (file)
@@ -394,7 +394,7 @@ pub fn make_test(s: &str,
 
     // Uses libsyntax to parse the doctest and find if there's a main fn and the extern
     // crate already is included.
-    let (already_has_main, already_has_extern_crate) = crate::syntax::with_globals(|| {
+    let (already_has_main, already_has_extern_crate, found_macro) = crate::syntax::with_globals(|| {
         use crate::syntax::{ast, parse::{self, ParseSess}, source_map::FilePathMapping};
         use crate::syntax_pos::FileName;
         use errors::emitter::EmitterWriter;
@@ -412,6 +412,7 @@ pub fn make_test(s: &str,
 
         let mut found_main = false;
         let mut found_extern_crate = cratename.is_none();
+        let mut found_macro = false;
 
         let mut parser = match parse::maybe_new_parser_from_source_str(&sess, filename, source) {
             Ok(p) => p,
@@ -420,7 +421,7 @@ pub fn make_test(s: &str,
                     err.cancel();
                 }
 
-                return (found_main, found_extern_crate);
+                return (found_main, found_extern_crate, found_macro);
             }
         };
 
@@ -448,6 +449,12 @@ pub fn make_test(s: &str,
                         }
                     }
 
+                    if !found_macro {
+                        if let ast::ItemKind::Mac(..) = item.node {
+                            found_macro = true;
+                        }
+                    }
+
                     if found_main && found_extern_crate {
                         break;
                     }
@@ -460,9 +467,28 @@ pub fn make_test(s: &str,
             }
         }
 
-        (found_main, found_extern_crate)
+        (found_main, found_extern_crate, found_macro)
     });
 
+    // If a doctest's `fn main` is being masked by a wrapper macro, the parsing loop above won't
+    // see it. In that case, run the old text-based scan to see if they at least have a main
+    // function written inside a macro invocation. See
+    // https://github.com/rust-lang/rust/issues/56898
+    let already_has_main = if found_macro && !already_has_main {
+        s.lines()
+            .map(|line| {
+                let comment = line.find("//");
+                if let Some(comment_begins) = comment {
+                    &line[0..comment_begins]
+                } else {
+                    line
+                }
+            })
+            .any(|code| code.contains("fn main"))
+    } else {
+        already_has_main
+    };
+
     // Don't inject `extern crate std` because it's already injected by the
     // compiler.
     if !already_has_extern_crate && !opts.no_crate_inject && cratename != Some("std") {
@@ -1143,4 +1169,23 @@ fn main() {
         let output = make_test(input, Some("asdf"), false, &opts);
         assert_eq!(output, (expected, 3));
     }
+
+    #[test]
+    fn make_test_main_in_macro() {
+        let opts = TestOptions::default();
+        let input =
+"#[macro_use] extern crate my_crate;
+test_wrapper! {
+    fn main() {}
+}";
+        let expected =
+"#![allow(unused)]
+#[macro_use] extern crate my_crate;
+test_wrapper! {
+    fn main() {}
+}".to_string();
+
+        let output = make_test(input, Some("my_crate"), false, &opts);
+        assert_eq!(output, (expected, 1));
+    }
 }
index f026cadd639c318c837ce4dacb3a7e173401af59..2f9efb3f0fb579cfa4677add42daa9f9ce0e60e0 100644 (file)
 /// themselves through the [`Display`] and [`Debug`] traits, and may provide
 /// cause chain information:
 ///
-/// The [`cause`] method is generally used when errors cross "abstraction
-/// boundaries", i.e.,  when a one module must report an error that is "caused"
-/// by an error from a lower-level module. This setup makes it possible for the
-/// high-level module to provide its own errors that do not commit to any
-/// particular implementation, but also reveal some of its implementation for
-/// debugging via [`cause`] chains.
+/// The [`source`] method is generally used when errors cross "abstraction
+/// boundaries". If one module must report an error that is caused by an error
+/// from a lower-level module, it can allow access to that error via the
+/// [`source`] method. This makes it possible for the high-level module to
+/// provide its own errors while also revealing some of the implementation for
+/// debugging via [`source`] chains.
 ///
 /// [`Result<T, E>`]: ../result/enum.Result.html
 /// [`Display`]: ../fmt/trait.Display.html
 /// [`Debug`]: ../fmt/trait.Debug.html
-/// [`cause`]: trait.Error.html#method.cause
+/// [`source`]: trait.Error.html#method.source
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Error: Debug + Display {
     /// **This method is soft-deprecated.**
index 0991957fa7fd58cc725104b5af070fe0bb724be0..28a6fbd48cf0917851e3ffce1a20be479b50f296 100644 (file)
 //! [`println!`]: ../macro.println.html
 //! [`Lines`]: struct.Lines.html
 //! [`io::Result`]: type.Result.html
-//! [`?` operator]: ../../book/first-edition/syntax-index.html
+//! [`?` operator]: ../../book/appendix-02-operators.html
 //! [`Read::read`]: trait.Read.html#tymethod.read
 //! [`Result`]: ../result/enum.Result.html
 //! [`.unwrap()`]: ../result/enum.Result.html#method.unwrap
index d42e39f16e66303be72922a9ee4ee2ad3a9447ea..e22008084494690373829e636fbc04bbbd69acac 100644 (file)
 #![feature(char_error_internals)]
 #![feature(compiler_builtins_lib)]
 #![feature(concat_idents)]
-#![feature(const_int_ops)]
-#![feature(const_ip)]
+#![cfg_attr(stage0, feature(const_int_ops))]
+#![cfg_attr(stage0, feature(const_ip))]
 #![feature(const_raw_ptr_deref)]
 #![feature(const_cstr_unchecked)]
 #![feature(core_intrinsics)]
 #![feature(dropck_eyepatch)]
+#![feature(duration_constants)]
 #![feature(exact_size_is_empty)]
 #![feature(external_doc)]
 #![feature(fixed_size_array)]
 #![feature(maybe_uninit)]
 #![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"),
             feature(global_asm, range_contains, slice_index_methods,
-                    decl_macro, coerce_unsized, sgx_platform))]
+                    decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))]
 
 #![default_lib_allocator]
 
index c92365df03a8ede1f66c39a95352b882c0dfa47d..b87257188df10c50a1e34cccff76191c838f2769 100644 (file)
@@ -322,6 +322,7 @@ macro_rules! dbg {
     }
 }
 
+/// A macro to await on an async call.
 #[macro_export]
 #[unstable(feature = "await_macro", issue = "50547")]
 #[allow_internal_unstable]
index 52a29f4885f5646f1dc6beffbc50bd0c48aac3fd..f98113e0896f7908eb634e0952acb0b5dbe9e732 100644 (file)
@@ -328,7 +328,7 @@ impl Ipv4Addr {
     /// let addr = Ipv4Addr::new(127, 0, 0, 1);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_ip")]
+    #[cfg_attr(stage0, rustc_const_unstable(feature = "const_ip"))]
     pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
         Ipv4Addr {
             inner: c::in_addr {
index 317a7d817db43e50eb52f1a7d4748685f1e5e549..5c7bff70a0dcdf4a132447ec0ae59bffad4bad3c 100644 (file)
@@ -2203,6 +2203,8 @@ fn _with_extension(&self, extension: &OsStr) -> PathBuf {
     ///   `a/b` all have `a` and `b` as components, but `./a/b` starts with
     ///   an additional [`CurDir`] component.
     ///
+    /// * A trailing slash is normalized away, `/a/b` and `/a/b/` are equivalent.
+    ///
     /// Note that no other normalization takes place; in particular, `a/c`
     /// and `a/b/../c` are distinct, to account for the possibility that `b`
     /// is a symbolic link (so its parent isn't `a`).
index 475c9b4aeaa4efaf29482afc4f4e2b1ac6e55441..c2751508ce094dd84e25b808d38b06d1ff0d0549 100644 (file)
@@ -550,7 +550,6 @@ mod prim_array { }
 #[doc(alias = "[")]
 #[doc(alias = "]")]
 #[doc(alias = "[]")]
-//
 /// A dynamically-sized view into a contiguous sequence, `[T]`.
 ///
 /// *[See also the `std::slice` module](slice/index.html).*
@@ -572,11 +571,11 @@ mod prim_array { }
 /// points to:
 ///
 /// ```
-/// let x = &mut [1, 2, 3];
+/// let mut x = [1, 2, 3];
+/// let x = &mut x[..]; // Take a full slice of `x`.
 /// x[1] = 7;
 /// assert_eq!(x, &[1, 7, 3]);
 /// ```
-///
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_slice { }
 
index 906beba4ae12257f76c9683e9028ef89631b202c..545e3c0ce845510a99c2e57ada037f88ba64a7a8 100644 (file)
@@ -25,6 +25,14 @@ pub fn now() -> Instant {
         }
     }
 
+    pub fn actually_monotonic() -> bool {
+        true
+    }
+
+    pub const fn zero() -> Instant {
+        Instant { t: 0 }
+    }
+
     pub fn sub_instant(&self, other: &Instant) -> Duration {
         let diff = self.t
             .checked_sub(other.t)
index b32723506574631327399bbba8afaa417e0a1625..401b7012aa7e9af932d1926453fcc41eb4bcabf2 100644 (file)
@@ -128,6 +128,14 @@ pub fn now() -> Instant {
         Instant { t: now(syscall::CLOCK_MONOTONIC) }
     }
 
+    pub const fn zero() -> Instant {
+        Instant { t: Timespec { t: syscall::TimeSpec { tv_sec: 0, tv_nsec: 0 } } }
+    }
+
+    pub fn actually_monotonic() -> bool {
+        false
+    }
+
     pub fn sub_instant(&self, other: &Instant) -> Duration {
         self.t.sub_timespec(&other.t).unwrap_or_else(|_| {
             panic!("specified instant was later than self")
index 09552d5b4af295b1d6c29ca2570980f4c8d3ee27..808f1ce3ff2c73a4265f9d60319357505de2a425 100644 (file)
@@ -17,8 +17,10 @@ pub(crate) unsafe fn rel_ptr_mut<T>(offset: u64) -> *mut T {
 // Do not remove inline: will result in relocation failure
 // For the same reason we use inline ASM here instead of an extern static to
 // locate the base
+/// Returns address at which current enclave is loaded.
 #[inline(always)]
-fn image_base() -> u64 {
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub fn image_base() -> u64 {
     let base;
     unsafe { asm!("lea IMAGE_BASE(%rip),$0":"=r"(base)) };
     base
index 52d4a63bb6384aa428d93564b7b7895c05386119..2b8e1da05791dee62231a0c0c1aeeb02ee26cadf 100644 (file)
@@ -1,21 +1,90 @@
 use io;
-use sys::unsupported;
+use error::Error;
+use libc;
 use sys_common::backtrace::Frame;
+use unwind as uw;
+use sys::sgx::abi::mem::image_base;
 
 pub struct BacktraceContext;
 
-pub fn unwind_backtrace(_frames: &mut [Frame])
-    -> io::Result<(usize, BacktraceContext)>
-{
-    unsupported()
+struct Context<'a> {
+    idx: usize,
+    frames: &'a mut [Frame],
+}
+
+#[derive(Debug)]
+struct UnwindError(uw::_Unwind_Reason_Code);
+
+impl Error for UnwindError {
+    fn description(&self) -> &'static str {
+        "unexpected return value while unwinding"
+    }
+}
+
+impl ::fmt::Display for UnwindError {
+    fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+        write!(f, "{}: {:?}", self.description(), self.0)
+    }
+}
+
+#[inline(never)] // this function call can be skipped it when tracing.
+pub fn unwind_backtrace(frames: &mut [Frame]) -> io::Result<(usize, BacktraceContext)> {
+    let mut cx = Context { idx: 0, frames };
+    let result_unwind =
+        unsafe { uw::_Unwind_Backtrace(trace_fn, &mut cx as *mut Context as *mut libc::c_void) };
+    // See libunwind:src/unwind/Backtrace.c for the return values.
+    // No, there is no doc.
+    let res = match result_unwind {
+        // These return codes seem to be benign and need to be ignored for backtraces
+        // to show up properly on all tested platforms.
+        uw::_URC_END_OF_STACK | uw::_URC_FATAL_PHASE1_ERROR | uw::_URC_FAILURE => {
+            Ok((cx.idx, BacktraceContext))
+        }
+        _ => Err(io::Error::new(
+            io::ErrorKind::Other,
+            UnwindError(result_unwind),
+        )),
+    };
+    res
+}
+
+extern "C" fn trace_fn(
+    ctx: *mut uw::_Unwind_Context,
+    arg: *mut libc::c_void,
+) -> uw::_Unwind_Reason_Code {
+    let cx = unsafe { &mut *(arg as *mut Context) };
+    if cx.idx >= cx.frames.len() {
+        return uw::_URC_NORMAL_STOP;
+    }
+
+    let mut ip_before_insn = 0;
+    let mut ip = unsafe { uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void };
+    if !ip.is_null() && ip_before_insn == 0 {
+        // this is a non-signaling frame, so `ip` refers to the address
+        // after the calling instruction. account for that.
+        ip = (ip as usize - 1) as *mut _;
+    }
+
+    let symaddr = unsafe { uw::_Unwind_FindEnclosingFunction(ip) };
+    cx.frames[cx.idx] = Frame {
+        symbol_addr: symaddr as *mut u8,
+        exact_position: ip as *mut u8,
+        inline_context: 0,
+    };
+    cx.idx += 1;
+
+    uw::_URC_NO_REASON
 }
 
-pub fn resolve_symname<F>(_frame: Frame,
-                          _callback: F,
+// To reduce TCB size in Sgx enclave, we do not want to implement resolve_symname functionality.
+// Rather, we print the offset of the address here, which could be later mapped to correct function.
+pub fn resolve_symname<F>(frame: Frame,
+                          callback: F,
                           _: &BacktraceContext) -> io::Result<()>
     where F: FnOnce(Option<&str>) -> io::Result<()>
 {
-    unsupported()
+    callback(Some(&format!("0x{:x}",
+            (frame.symbol_addr.wrapping_offset_from(image_base() as _)))))
 }
 
 pub fn foreach_symbol_fileline<F>(_: Frame,
@@ -23,5 +92,5 @@ pub fn foreach_symbol_fileline<F>(_: Frame,
                                   _: &BacktraceContext) -> io::Result<bool>
     where F: FnMut(&[u8], u32) -> io::Result<()>
 {
-    unsupported()
+    Ok(false)
 }
index ba6f9e622ad3532e61254232ab194fca38157458..3bd87b5d2657403910e3b3d3c2efb344b95b8cb9 100644 (file)
@@ -36,7 +36,7 @@
             : "={eax}"(error)
             : "{eax}"(ENCLU_EGETKEY),
               "{rbx}"(request),
-              "{rcx}"(out.get_mut())
+              "{rcx}"(out.as_mut_ptr())
             : "flags"
         );
 
@@ -66,7 +66,7 @@ pub fn ereport(
             : "{eax}"(ENCLU_EREPORT),
               "{rbx}"(targetinfo),
               "{rcx}"(reportdata),
-              "{rdx}"(report.get_mut())
+              "{rdx}"(report.as_mut_ptr())
         );
 
         report.into_inner()
index 073c0d0686df9fd2fda0e2a4f3326f877642b8e6..4a655714f991cba30c12b9b6a18705c89d2f74b9 100644 (file)
@@ -14,6 +14,12 @@ struct Timespec {
 }
 
 impl Timespec {
+    const fn zero() -> Timespec {
+        Timespec {
+            t: libc::timespec { tv_sec: 0, tv_nsec: 0 },
+        }
+    }
+
     fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
         if self >= other {
             Ok(if self.t.tv_nsec >= other.t.tv_nsec {
@@ -128,12 +134,7 @@ pub struct SystemTime {
     }
 
     pub const UNIX_EPOCH: SystemTime = SystemTime {
-        t: Timespec {
-            t: libc::timespec {
-                tv_sec: 0,
-                tv_nsec: 0,
-            },
-        },
+        t: Timespec::zero(),
     };
 
     impl Instant {
@@ -141,6 +142,14 @@ pub fn now() -> Instant {
             Instant { t: unsafe { libc::mach_absolute_time() } }
         }
 
+        pub const fn zero() -> Instant {
+            Instant { t: 0 }
+        }
+
+        pub fn actually_monotonic() -> bool {
+            true
+        }
+
         pub fn sub_instant(&self, other: &Instant) -> Duration {
             let info = info();
             let diff = self.t.checked_sub(other.t)
@@ -258,12 +267,7 @@ pub struct SystemTime {
     }
 
     pub const UNIX_EPOCH: SystemTime = SystemTime {
-        t: Timespec {
-            t: libc::timespec {
-                tv_sec: 0,
-                tv_nsec: 0,
-            },
-        },
+        t: Timespec::zero(),
     };
 
     impl Instant {
@@ -271,6 +275,18 @@ pub fn now() -> Instant {
             Instant { t: now(libc::CLOCK_MONOTONIC) }
         }
 
+        pub const fn zero() -> Instant {
+            Instant {
+                t: Timespec::zero(),
+            }
+        }
+
+        pub fn actually_monotonic() -> bool {
+            (cfg!(target_os = "linux") && cfg!(target_arch = "x86_64")) ||
+            (cfg!(target_os = "linux") && cfg!(target_arch = "x86")) ||
+            false // last clause, used so `||` is always trailing above
+        }
+
         pub fn sub_instant(&self, other: &Instant) -> Duration {
             self.t.sub_timespec(&other.t).unwrap_or_else(|_| {
                 panic!("specified instant was later than self")
index a5c41d4a96eff93eb0871918daf61698cedf0982..31798466fed2ae493f1346fd5ecc789e5f35d9ef 100644 (file)
@@ -14,6 +14,14 @@ pub fn now() -> Instant {
         Instant(TimeSysCall::perform(TimeClock::Monotonic))
     }
 
+    pub const fn zero() -> Instant {
+        Instant(Duration::from_secs(0))
+    }
+
+    pub fn actually_monotonic() -> bool {
+        false
+    }
+
     pub fn sub_instant(&self, other: &Instant) -> Duration {
         self.0 - other.0
     }
index 06c58659c08ae6cb5676359a59cce48b45c8190a..08a166bd8c50425f3c86f0963e78ec9c70514e5b 100644 (file)
@@ -393,7 +393,16 @@ fn from(u: c::DWORD) -> ExitStatus {
 
 impl fmt::Display for ExitStatus {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "exit code: {}", self.0)
+        // Windows exit codes with the high bit set typically mean some form of
+        // unhandled exception or warning. In this scenario printing the exit
+        // code in decimal doesn't always make sense because it's a very large
+        // and somewhat gibberish number. The hex code is a bit more
+        // recognizable and easier to search for, so print that.
+        if self.0 & 0x80000000 != 0 {
+            write!(f, "exit code: {:#x}", self.0)
+        } else {
+            write!(f, "exit code: {}", self.0)
+        }
     }
 }
 
index 60c96959186fbb348bdbf13d58cbd0fa34c4f756..8e8e9195cf471913fe742bf173b6c21a52536b5f 100644 (file)
@@ -40,6 +40,14 @@ pub fn now() -> Instant {
         t
     }
 
+    pub fn actually_monotonic() -> bool {
+        false
+    }
+
+    pub const fn zero() -> Instant {
+        Instant { t: 0 }
+    }
+
     pub fn sub_instant(&self, other: &Instant) -> Duration {
         // Values which are +- 1 need to be considered as basically the same
         // units in time due to various measurement oddities, according to
index eb67b718dbd3d4fcf71f3221883c89d68b387898..507ea395c6c6c409d15b0be4ec40bb370f9d115b 100644 (file)
 
 #![stable(feature = "time", since = "1.3.0")]
 
+use cmp;
 use error::Error;
 use fmt;
 use ops::{Add, Sub, AddAssign, SubAssign};
 use sys::time;
 use sys_common::FromInner;
+use sys_common::mutex::Mutex;
 
 #[stable(feature = "time", since = "1.3.0")]
 pub use core::time::Duration;
 
+#[unstable(feature = "duration_constants", issue = "57391")]
+pub use core::time::{SECOND, MILLISECOND, MICROSECOND, NANOSECOND};
+
 /// A measurement of a monotonically nondecreasing clock.
 /// Opaque and useful only with `Duration`.
 ///
@@ -150,7 +155,45 @@ impl Instant {
     /// ```
     #[stable(feature = "time2", since = "1.8.0")]
     pub fn now() -> Instant {
-        Instant(time::Instant::now())
+        let os_now = time::Instant::now();
+
+        // And here we come upon a sad state of affairs. The whole point of
+        // `Instant` is that it's monotonically increasing. We've found in the
+        // wild, however, that it's not actually monotonically increasing for
+        // one reason or another. These appear to be OS and hardware level bugs,
+        // and there's not really a whole lot we can do about them. Here's a
+        // taste of what we've found:
+        //
+        // * #48514 - OpenBSD, x86_64
+        // * #49281 - linux arm64 and s390x
+        // * #51648 - windows, x86
+        // * #56560 - windows, x86_64, AWS
+        // * #56612 - windows, x86, vm (?)
+        // * #56940 - linux, arm64
+        // * https://bugzilla.mozilla.org/show_bug.cgi?id=1487778 - a similar
+        //   Firefox bug
+        //
+        // It simply seems that this it just happens so that a lot in the wild
+        // we're seeing panics across various platforms where consecutive calls
+        // to `Instant::now`, such as via the `elapsed` function, are panicking
+        // as they're going backwards. Placed here is a last-ditch effort to try
+        // to fix things up. We keep a global "latest now" instance which is
+        // returned instead of what the OS says if the OS goes backwards.
+        //
+        // To hopefully mitigate the impact of this though a few platforms are
+        // whitelisted as "these at least haven't gone backwards yet".
+        if time::Instant::actually_monotonic() {
+            return Instant(os_now)
+        }
+
+        static LOCK: Mutex = Mutex::new();
+        static mut LAST_NOW: time::Instant = time::Instant::zero();
+        unsafe {
+            let _lock = LOCK.lock();
+            let now = cmp::max(LAST_NOW, os_now);
+            LAST_NOW = now;
+            Instant(now)
+        }
     }
 
     /// Returns the amount of time elapsed from another instant to this one.
index a309775a1a40b1da9765d57b7c3989f1abb77e8a..d03563f8891aa56982862e1dda9ce45344a9f96d 100644 (file)
@@ -472,7 +472,7 @@ fn tokens(&self) -> TokenStream {
                                          Token::from_ast_ident(segment.ident)).into());
             last_pos = segment.ident.span.hi();
         }
-        idents.push(self.node.tokens(self.span));
+        self.node.tokens(self.span).append_to_tree_and_joint_vec(&mut idents);
         TokenStream::new(idents)
     }
 
@@ -529,7 +529,9 @@ pub fn tokens(&self, span: Span) -> TokenStream {
         match *self {
             MetaItemKind::Word => TokenStream::empty(),
             MetaItemKind::NameValue(ref lit) => {
-                TokenStream::new(vec![TokenTree::Token(span, Token::Eq).into(), lit.tokens()])
+                let mut vec = vec![TokenTree::Token(span, Token::Eq).into()];
+                lit.tokens().append_to_tree_and_joint_vec(&mut vec);
+                TokenStream::new(vec)
             }
             MetaItemKind::List(ref list) => {
                 let mut tokens = Vec::new();
@@ -537,7 +539,7 @@ pub fn tokens(&self, span: Span) -> TokenStream {
                     if i > 0 {
                         tokens.push(TokenTree::Token(span, Token::Comma).into());
                     }
-                    tokens.push(item.node.tokens());
+                    item.node.tokens().append_to_tree_and_joint_vec(&mut tokens);
                 }
                 TokenTree::Delimited(
                     DelimSpan::from_single(span),
index 9eebbedc0bc8cfc570287d422ddbaf5f4ca1001e..a987f534a272531c84f642a0a587ddf029d110a5 100644 (file)
@@ -5,7 +5,6 @@
     Features,
     get_features,
     GateIssue,
-    emit_feature_err,
 };
 use {fold, attr};
 use ast;
@@ -94,13 +93,6 @@ fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
             return vec![attr];
         }
 
-        let gate_cfg_attr_multi = if let Some(ref features) = self.features {
-            !features.cfg_attr_multi
-        } else {
-            false
-        };
-        let cfg_attr_span = attr.span;
-
         let (cfg_predicate, expanded_attrs) = match attr.parse(self.sess, |parser| {
             parser.expect(&token::OpenDelim(token::Paren))?;
 
@@ -130,21 +122,8 @@ fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
         // Check feature gate and lint on zero attributes in source. Even if the feature is gated,
         // we still compute as if it wasn't, since the emitted error will stop compilation further
         // along the compilation.
-        match (expanded_attrs.len(), gate_cfg_attr_multi) {
-            (0, false) => {
-                // FIXME: Emit unused attribute lint here.
-            },
-            (1, _) => {},
-            (_, true) => {
-                emit_feature_err(
-                    self.sess,
-                    "cfg_attr_multi",
-                    cfg_attr_span,
-                    GateIssue::Language,
-                    "cfg_attr with zero or more than one attributes is experimental",
-                );
-            },
-            (_, false) => {}
+        if expanded_attrs.len() == 0 {
+            // FIXME: Emit unused attribute lint here.
         }
 
         if attr::cfg_matches(&cfg_predicate, self.sess, self.features) {
index 71028ef9fc66a7ca488f49b80147982260c8fb77..fa6b825f2a2c21e8e4daa54aac69f5c3b7ae8167 100644 (file)
@@ -117,16 +117,18 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
             ));
         }
     });
-    let sym = Ident::with_empty_ctxt(Symbol::gensym(&format!(
-        "__register_diagnostic_{}", code
-    )));
+
+    let span = span.apply_mark(ecx.current_expansion.mark);
+
+    let sym = Ident::new(Symbol::gensym(&format!("__register_diagnostic_{}", code)), span);
+
     MacEager::items(smallvec![
         ecx.item_mod(
             span,
             span,
             sym,
-            Vec::new(),
-            Vec::new()
+            vec![],
+            vec![],
         )
     ])
 }
index ad8668aca70f9442a7dadb13d68057b163beccef..c3124144009ab61bfc2b7f589d8df50e59d3586c 100644 (file)
@@ -233,7 +233,7 @@ fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
                     self.span, token::Token::from_ast_ident(segment.ident)
                 ).into());
             }
-            inner.push(self.tokens.clone());
+            self.tokens.clone().append_to_tree_and_joint_vec(&mut inner);
 
             let delim_span = DelimSpan::from_single(self.span);
             r.push(TokenTree::Delimited(
index d55f785bd9b4b5f695d33994c99a06cd087ac868..b4003ac729addf611bc7130f38be8804568ea61d 100644 (file)
@@ -271,7 +271,7 @@ pub enum ParseResult<T> {
     Success(T),
     /// Arm failed to match. If the second parameter is `token::Eof`, it indicates an unexpected
     /// end of macro invocation. Otherwise, it indicates that no rules expected the given token.
-    Failure(syntax_pos::Span, Token, String),
+    Failure(syntax_pos::Span, Token, &'static str),
     /// Fatal error (malformed macro?). Abort compilation.
     Error(syntax_pos::Span, String),
 }
@@ -721,7 +721,7 @@ pub fn parse(
                         sess.source_map().next_point(parser.span)
                     },
                     token::Eof,
-                    "missing tokens in macro arguments".to_string(),
+                    "missing tokens in macro arguments",
                 );
             }
         }
@@ -760,7 +760,7 @@ pub fn parse(
             return Failure(
                 parser.span,
                 parser.token,
-                "no rules expected this token in macro call".to_string(),
+                "no rules expected this token in macro call",
             );
         }
         // Dump all possible `next_items` into `cur_items` for the next iteration.
index cb8fbce66978bb6dd9d1ffaee31d55b4bb107090..24202ca8fbdc08774ccf38079239d2bf4fe24a57 100644 (file)
@@ -202,7 +202,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt,
     let best_fail_msg = parse_failure_msg(best_fail_tok.expect("ran no matchers"));
     let span = best_fail_spot.substitute_dummy(sp);
     let mut err = cx.struct_span_err(span, &best_fail_msg);
-    err.span_label(span, best_fail_text.unwrap_or(best_fail_msg));
+    err.span_label(span, best_fail_text.unwrap_or(&best_fail_msg));
     if let Some(sp) = def_span {
         if cx.source_map().span_to_filename(sp).is_real() && !sp.is_dummy() {
             err.span_label(cx.source_map().def_span(sp), "when calling this macro");
index 31d87508c6bca13998f7024853967f7d06ce2460..0ef2d3b749d810f962e5b226fba17f94a58e0eac 100644 (file)
@@ -7,7 +7,7 @@
 use parse::token::{self, Token, NtTT};
 use smallvec::SmallVec;
 use syntax_pos::DUMMY_SP;
-use tokenstream::{TokenStream, TokenTree, DelimSpan};
+use tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
@@ -63,7 +63,7 @@ pub fn transcribe(cx: &ExtCtxt,
     let mut stack: SmallVec<[Frame; 1]> = smallvec![Frame::new(src)];
     let interpolations = interp.unwrap_or_else(FxHashMap::default); /* just a convenience */
     let mut repeats = Vec::new();
-    let mut result: Vec<TokenStream> = Vec::new();
+    let mut result: Vec<TreeAndJoint> = Vec::new();
     let mut result_stack = Vec::new();
 
     loop {
@@ -78,7 +78,7 @@ pub fn transcribe(cx: &ExtCtxt,
                     if let Some(sep) = sep.clone() {
                         // repeat same span, I guess
                         let prev_span = match result.last() {
-                            Some(stream) => stream.trees().next().unwrap().span(),
+                            Some((tt, _)) => tt.span(),
                             None => DUMMY_SP,
                         };
                         result.push(TokenTree::Token(prev_span, sep).into());
index cca2702f1a784f63477ae3fb3a32046f582325b0..9b4231d8803a33a6e5d3fd3e39c5c2e224e22adb 100644 (file)
@@ -191,10 +191,7 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     (active, slice_patterns, "1.0.0", Some(23121), None),
 
     // Allows the definition of `const` functions with some advanced features.
-    (active, const_fn, "1.2.0", Some(24111), None),
-
-    // Allows let bindings and destructuring in `const` functions and constants.
-    (active, const_let, "1.22.1", Some(48821), None),
+    (active, const_fn, "1.2.0", Some(57563), None),
 
     // Allows accessing fields of unions inside `const` functions.
     (active, const_fn_union, "1.27.0", Some(51909), None),
@@ -384,9 +381,6 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // Infer static outlives requirements (RFC 2093).
     (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
 
-    // Multiple patterns with `|` in `if let` and `while let`.
-    (active, if_while_or_patterns, "1.26.0", Some(48215), None),
-
     // Allows macro invocations in `extern {}` blocks.
     (active, macros_in_extern, "1.27.0", Some(49476), None),
 
@@ -414,9 +408,6 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // `#[doc(alias = "...")]`
     (active, doc_alias, "1.27.0", Some(50146), None),
 
-    // Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
-    (active, irrefutable_let_patterns, "1.27.0", Some(44495), None),
-
     // inconsistent bounds in where clauses
     (active, trivial_bounds, "1.28.0", Some(48214), None),
 
@@ -443,9 +434,6 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // support for arbitrary delimited token streams in non-macro attributes
     (active, unrestricted_attribute_tokens, "1.30.0", Some(55208), None),
 
-    // Allows `use x::y;` to resolve through `self::x`, not just `::x`.
-    (active, uniform_paths, "1.30.0", Some(53130), None),
-
     // Allows unsized rvalues at arguments and parameters.
     (active, unsized_locals, "1.30.0", Some(48055), None),
 
@@ -465,9 +453,6 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // Allows `impl Trait` in bindings (`let`, `const`, `static`).
     (active, impl_trait_in_bindings, "1.30.0", Some(34511), None),
 
-    // `#[cfg_attr(predicate, multiple, attributes, here)]`
-    (active, cfg_attr_multi, "1.31.0", Some(54881), None),
-
     // Allows `const _: TYPE = VALUE`.
     (active, underscore_const_names, "1.31.0", Some(54912), None),
 
@@ -687,8 +672,20 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     (accepted, underscore_imports, "1.33.0", Some(48216), None),
     // Allows `#[repr(packed(N))]` attribute on structs.
     (accepted, repr_packed, "1.33.0", Some(33158), None),
+    // Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
+    (accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None),
     // Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
     (accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None),
+    // Allows let bindings, assignments and destructuring in `const` functions and constants.
+    // As long as control flow is not implemented in const eval, `&&` and `||` may not be used
+    // at the same time as let bindings.
+    (accepted, const_let, "1.33.0", Some(48821), None),
+    // `#[cfg_attr(predicate, multiple, attributes, here)]`
+    (accepted, cfg_attr_multi, "1.33.0", Some(54881), None),
+    // Top level or-patterns (`p | q`) in `if let` and `while let`.
+    (accepted, if_while_or_patterns, "1.33.0", Some(48215), None),
+    // Allows `use x::y;` to search `x` in the current scope.
+    (accepted, uniform_paths, "1.32.0", Some(53130), None),
 );
 
 // If you change this, please modify `src/doc/unstable-book` as well. You must
@@ -1702,12 +1699,6 @@ fn visit_expr(&mut self, e: &'a ast::Expr) {
             ast::ExprKind::TryBlock(_) => {
                 gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
             }
-            ast::ExprKind::IfLet(ref pats, ..) | ast::ExprKind::WhileLet(ref pats, ..) => {
-                if pats.len() > 1 {
-                    gate_feature_post!(&self, if_while_or_patterns, e.span,
-                                    "multiple patterns in `if let` and `while let` are unstable");
-                }
-            }
             ast::ExprKind::Block(_, opt_label) => {
                 if let Some(label) = opt_label {
                     gate_feature_post!(&self, label_break_value, label.ident.span,
index 6c4e9e1c940c557fe8c93d4dc3e66bf760707491..d219f29f06c204ba2145ec8a9a3da8195e29a23f 100644 (file)
@@ -1,7 +1,7 @@
 use print::pprust::token_to_string;
 use parse::lexer::StringReader;
 use parse::{token, PResult};
-use tokenstream::{DelimSpan, IsJoint::*, TokenStream, TokenTree};
+use tokenstream::{DelimSpan, IsJoint::*, TokenStream, TokenTree, TreeAndJoint};
 
 impl<'a> StringReader<'a> {
     // Parse a stream of tokens into a list of `TokenTree`s, up to an `Eof`.
@@ -33,7 +33,7 @@ fn parse_token_trees_until_close_delim(&mut self) -> TokenStream {
         }
     }
 
-    fn parse_token_tree(&mut self) -> PResult<'a, TokenStream> {
+    fn parse_token_tree(&mut self) -> PResult<'a, TreeAndJoint> {
         let sm = self.sess.source_map();
         match self.token {
             token::Eof => {
@@ -156,7 +156,7 @@ fn parse_token_tree(&mut self) -> PResult<'a, TokenStream> {
                 Ok(TokenTree::Delimited(
                     delim_span,
                     delim,
-                    tts.into(),
+                    tts.into()
                 ).into())
             },
             token::CloseDelim(_) => {
@@ -176,7 +176,7 @@ fn parse_token_tree(&mut self) -> PResult<'a, TokenStream> {
                 let raw = self.span_src_raw;
                 self.real_token();
                 let is_joint = raw.hi() == self.span_src_raw.lo() && token::is_op(&self.token);
-                Ok(TokenStream::Tree(tt, if is_joint { Joint } else { NonJoint }))
+                Ok((tt, if is_joint { Joint } else { NonJoint }))
             }
         }
     }
index 1e4a26b353759ab244289f2b1845e400627618f4..5c8ed94731afbb16785163a68e350cfe0714bfc1 100644 (file)
@@ -2914,7 +2914,7 @@ fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>, lo: Span) -> PResult<'a,
                 TokenTree::Delimited(
                     frame.span,
                     frame.delim,
-                    frame.tree_cursor.original_stream().into(),
+                    frame.tree_cursor.stream.into(),
                 )
             },
             token::CloseDelim(_) | token::Eof => unreachable!(),
@@ -3660,8 +3660,6 @@ fn parse_match_expr(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<E
         maybe_whole!(self, NtArm, |x| x);
 
         let attrs = self.parse_outer_attributes()?;
-        // Allow a '|' before the pats (RFC 1925)
-        self.eat(&token::BinOp(token::Or));
         let pats = self.parse_pats()?;
         let guard = if self.eat_keyword(keywords::If) {
             Some(Guard::If(self.parse_expr()?))
@@ -3768,6 +3766,9 @@ fn parse_initializer(&mut self, skip_eq: bool) -> PResult<'a, Option<P<Expr>>> {
 
     /// Parse patterns, separated by '|' s
     fn parse_pats(&mut self) -> PResult<'a, Vec<P<Pat>>> {
+        // Allow a '|' before the pats (RFC 1925 + RFC 2530)
+        self.eat(&token::BinOp(token::Or));
+
         let mut pats = Vec::new();
         loop {
             pats.push(self.parse_top_level_pat()?);
index 4b33a715c5c89c3168946bb6a0a61d2f16ccded0..fb72ef9c956ce5057041339d2645dbb56b31c1d8 100644 (file)
@@ -147,9 +147,11 @@ pub fn close_tt(span: Span, delim: DelimToken) -> TokenTree {
 pub enum TokenStream {
     Empty,
     Tree(TokenTree, IsJoint),
-    Stream(Lrc<Vec<TokenStream>>),
+    Stream(Lrc<Vec<TreeAndJoint>>),
 }
 
+pub type TreeAndJoint = (TokenTree, IsJoint);
+
 // `TokenStream` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
 static_assert!(MEM_SIZE_OF_TOKEN_STREAM: mem::size_of::<TokenStream>() == 32);
@@ -173,16 +175,14 @@ pub(crate) fn add_comma(&self) -> Option<(TokenStream, Span)> {
             while let Some((pos, ts)) = iter.next() {
                 if let Some((_, next)) = iter.peek() {
                     let sp = match (&ts, &next) {
-                        (TokenStream::Tree(TokenTree::Token(_, token::Token::Comma), NonJoint), _) |
-                        (_, TokenStream::Tree(TokenTree::Token(_, token::Token::Comma), NonJoint))
-                          => continue,
-                        (TokenStream::Tree(TokenTree::Token(sp, _), NonJoint), _) => *sp,
-                        (TokenStream::Tree(TokenTree::Delimited(sp, ..), NonJoint), _) =>
-                            sp.entire(),
+                        ((TokenTree::Token(_, token::Token::Comma), NonJoint), _) |
+                        (_, (TokenTree::Token(_, token::Token::Comma), NonJoint)) => continue,
+                        ((TokenTree::Token(sp, _), NonJoint), _) => *sp,
+                        ((TokenTree::Delimited(sp, ..), NonJoint), _) => sp.entire(),
                         _ => continue,
                     };
                     let sp = sp.shrink_to_hi();
-                    let comma = TokenStream::Tree(TokenTree::Token(sp, token::Comma), NonJoint);
+                    let comma = (TokenTree::Token(sp, token::Comma), NonJoint);
                     suggestion = Some((pos, comma, sp));
                 }
             }
@@ -200,8 +200,14 @@ pub(crate) fn add_comma(&self) -> Option<(TokenStream, Span)> {
 }
 
 impl From<TokenTree> for TokenStream {
-    fn from(tt: TokenTree) -> TokenStream {
-        TokenStream::Tree(tt, NonJoint)
+    fn from(tree: TokenTree) -> TokenStream {
+        TokenStream::Tree(tree, NonJoint)
+    }
+}
+
+impl From<TokenTree> for TreeAndJoint {
+    fn from(tree: TokenTree) -> TreeAndJoint {
+        (tree, NonJoint)
     }
 }
 
@@ -213,56 +219,7 @@ fn from(token: Token) -> TokenStream {
 
 impl<T: Into<TokenStream>> iter::FromIterator<T> for TokenStream {
     fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
-        TokenStream::new(iter.into_iter().map(Into::into).collect::<Vec<_>>())
-    }
-}
-
-impl Extend<TokenStream> for TokenStream {
-    fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, iter: I) {
-        let iter = iter.into_iter();
-        let this = mem::replace(self, TokenStream::Empty);
-
-        // Vector of token streams originally in self.
-        let tts: Vec<TokenStream> = match this {
-            TokenStream::Empty => {
-                let mut vec = Vec::new();
-                vec.reserve(iter.size_hint().0);
-                vec
-            }
-            TokenStream::Tree(..) => {
-                let mut vec = Vec::new();
-                vec.reserve(1 + iter.size_hint().0);
-                vec.push(this);
-                vec
-            }
-            TokenStream::Stream(rc_vec) => match Lrc::try_unwrap(rc_vec) {
-                Ok(mut vec) => {
-                    // Extend in place using the existing capacity if possible.
-                    // This is the fast path for libraries like `quote` that
-                    // build a token stream.
-                    vec.reserve(iter.size_hint().0);
-                    vec
-                }
-                Err(rc_vec) => {
-                    // Self is shared so we need to copy and extend that.
-                    let mut vec = Vec::new();
-                    vec.reserve(rc_vec.len() + iter.size_hint().0);
-                    vec.extend_from_slice(&rc_vec);
-                    vec
-                }
-            }
-        };
-
-        // Perform the extend, joining tokens as needed along the way.
-        let mut builder = TokenStreamBuilder(tts);
-        for stream in iter {
-            builder.push(stream);
-        }
-
-        // Build the resulting token stream. If it contains more than one token,
-        // preserve capacity in the vector in anticipation of the caller
-        // performing additional calls to extend.
-        *self = TokenStream::new(builder.0);
+        TokenStream::from_streams(iter.into_iter().map(Into::into).collect::<Vec<_>>())
     }
 }
 
@@ -294,14 +251,43 @@ pub fn is_empty(&self) -> bool {
         }
     }
 
-    pub fn new(mut streams: Vec<TokenStream>) -> TokenStream {
+    fn from_streams(mut streams: Vec<TokenStream>) -> TokenStream {
         match streams.len() {
             0 => TokenStream::empty(),
             1 => streams.pop().unwrap(),
+            _ => {
+                let mut vec = vec![];
+                for stream in streams {
+                    match stream {
+                        TokenStream::Empty => {},
+                        TokenStream::Tree(tree, is_joint) => vec.push((tree, is_joint)),
+                        TokenStream::Stream(stream2) => vec.extend(stream2.iter().cloned()),
+                    }
+                }
+                TokenStream::new(vec)
+            }
+        }
+    }
+
+    pub fn new(mut streams: Vec<TreeAndJoint>) -> TokenStream {
+        match streams.len() {
+            0 => TokenStream::empty(),
+            1 => {
+                let (tree, is_joint) = streams.pop().unwrap();
+                TokenStream::Tree(tree, is_joint)
+            }
             _ => TokenStream::Stream(Lrc::new(streams)),
         }
     }
 
+    pub fn append_to_tree_and_joint_vec(self, vec: &mut Vec<TreeAndJoint>) {
+        match self {
+            TokenStream::Empty => {}
+            TokenStream::Tree(tree, is_joint) => vec.push((tree, is_joint)),
+            TokenStream::Stream(stream) => vec.extend(stream.iter().cloned()),
+        }
+    }
+
     pub fn trees(&self) -> Cursor {
         self.clone().into_trees()
     }
@@ -362,54 +348,58 @@ fn semantic_tree(tree: &TokenTree) -> bool {
         t1.next().is_none() && t2.next().is_none()
     }
 
-    /// Precondition: `self` consists of a single token tree.
-    /// Returns true if the token tree is a joint operation w.r.t. `proc_macro::TokenNode`.
-    pub fn as_tree(self) -> (TokenTree, bool /* joint? */) {
-        match self {
-            TokenStream::Tree(tree, is_joint) => (tree, is_joint == Joint),
-            _ => unreachable!(),
-        }
-    }
-
     pub fn map_enumerated<F: FnMut(usize, TokenTree) -> TokenTree>(self, mut f: F) -> TokenStream {
-        let mut trees = self.into_trees();
-        let mut result = Vec::new();
-        let mut i = 0;
-        while let Some(stream) = trees.next_as_stream() {
-            result.push(match stream {
-                TokenStream::Tree(tree, is_joint) => TokenStream::Tree(f(i, tree), is_joint),
-                _ => unreachable!()
-            });
-            i += 1;
+        match self {
+            TokenStream::Empty => TokenStream::Empty,
+            TokenStream::Tree(tree, is_joint) => TokenStream::Tree(f(0, tree), is_joint),
+            TokenStream::Stream(stream) => TokenStream::Stream(Lrc::new(
+                stream
+                    .iter()
+                    .enumerate()
+                    .map(|(i, (tree, is_joint))| (f(i, tree.clone()), *is_joint))
+                    .collect()
+            )),
         }
-        TokenStream::new(result)
     }
 
     pub fn map<F: FnMut(TokenTree) -> TokenTree>(self, mut f: F) -> TokenStream {
-        let mut trees = self.into_trees();
-        let mut result = Vec::new();
-        while let Some(stream) = trees.next_as_stream() {
-            result.push(match stream {
-                TokenStream::Tree(tree, is_joint) => TokenStream::Tree(f(tree), is_joint),
-                _ => unreachable!()
-            });
+        match self {
+            TokenStream::Empty => TokenStream::Empty,
+            TokenStream::Tree(tree, is_joint) => TokenStream::Tree(f(tree), is_joint),
+            TokenStream::Stream(stream) => TokenStream::Stream(Lrc::new(
+                stream
+                    .iter()
+                    .map(|(tree, is_joint)| (f(tree.clone()), *is_joint))
+                    .collect()
+            )),
         }
-        TokenStream::new(result)
     }
 
     fn first_tree_and_joint(&self) -> Option<(TokenTree, IsJoint)> {
         match self {
             TokenStream::Empty => None,
             TokenStream::Tree(ref tree, is_joint) => Some((tree.clone(), *is_joint)),
-            TokenStream::Stream(ref stream) => stream.first().unwrap().first_tree_and_joint(),
+            TokenStream::Stream(ref stream) => Some(stream.first().unwrap().clone())
         }
     }
 
     fn last_tree_if_joint(&self) -> Option<TokenTree> {
         match self {
-            TokenStream::Empty | TokenStream::Tree(_, NonJoint) => None,
-            TokenStream::Tree(ref tree, Joint) => Some(tree.clone()),
-            TokenStream::Stream(ref stream) => stream.last().unwrap().last_tree_if_joint(),
+            TokenStream::Empty => None,
+            TokenStream::Tree(ref tree, is_joint) => {
+                if *is_joint == Joint {
+                    Some(tree.clone())
+                } else {
+                    None
+                }
+            }
+            TokenStream::Stream(ref stream) => {
+                if let (tree, Joint) = stream.last().unwrap() {
+                    Some(tree.clone())
+                } else {
+                    None
+                }
+            }
         }
     }
 }
@@ -442,13 +432,8 @@ pub fn push<T: Into<TokenStream>>(&mut self, stream: T) {
         self.0.push(stream);
     }
 
-    pub fn add<T: Into<TokenStream>>(mut self, stream: T) -> Self {
-        self.push(stream);
-        self
-    }
-
     pub fn build(self) -> TokenStream {
-        TokenStream::new(self.0)
+        TokenStream::from_streams(self.0)
     }
 
     fn push_all_but_last_tree(&mut self, stream: &TokenStream) {
@@ -456,10 +441,9 @@ fn push_all_but_last_tree(&mut self, stream: &TokenStream) {
             let len = streams.len();
             match len {
                 1 => {}
-                2 => self.0.push(streams[0].clone().into()),
-                _ => self.0.push(TokenStream::new(streams[0 .. len - 1].to_vec())),
+                2 => self.0.push(TokenStream::Tree(streams[0].0.clone(), streams[0].1)),
+                _ => self.0.push(TokenStream::Stream(Lrc::new(streams[0 .. len - 1].to_vec()))),
             }
-            self.push_all_but_last_tree(&streams[len - 1])
         }
     }
 
@@ -468,154 +452,77 @@ fn push_all_but_first_tree(&mut self, stream: &TokenStream) {
             let len = streams.len();
             match len {
                 1 => {}
-                2 => self.0.push(streams[1].clone().into()),
-                _ => self.0.push(TokenStream::new(streams[1 .. len].to_vec())),
+                2 => self.0.push(TokenStream::Tree(streams[1].0.clone(), streams[1].1)),
+                _ => self.0.push(TokenStream::Stream(Lrc::new(streams[1 .. len].to_vec()))),
             }
-            self.push_all_but_first_tree(&streams[0])
         }
     }
 }
 
 #[derive(Clone)]
-pub struct Cursor(CursorKind);
-
-#[derive(Clone)]
-enum CursorKind {
-    Empty,
-    Tree(TokenTree, IsJoint, bool /* consumed? */),
-    Stream(StreamCursor),
-}
-
-#[derive(Clone)]
-struct StreamCursor {
-    stream: Lrc<Vec<TokenStream>>,
+pub struct Cursor {
+    pub stream: TokenStream,
     index: usize,
-    stack: Vec<(Lrc<Vec<TokenStream>>, usize)>,
-}
-
-impl StreamCursor {
-    fn new(stream: Lrc<Vec<TokenStream>>) -> Self {
-        StreamCursor { stream: stream, index: 0, stack: Vec::new() }
-    }
-
-    fn next_as_stream(&mut self) -> Option<TokenStream> {
-        loop {
-            if self.index < self.stream.len() {
-                self.index += 1;
-                let next = self.stream[self.index - 1].clone();
-                match next {
-                    TokenStream::Empty => {}
-                    TokenStream::Tree(..) => return Some(next),
-                    TokenStream::Stream(stream) => self.insert(stream),
-                }
-            } else if let Some((stream, index)) = self.stack.pop() {
-                self.stream = stream;
-                self.index = index;
-            } else {
-                return None;
-            }
-        }
-    }
-
-    fn insert(&mut self, stream: Lrc<Vec<TokenStream>>) {
-        self.stack.push((mem::replace(&mut self.stream, stream),
-                         mem::replace(&mut self.index, 0)));
-    }
 }
 
 impl Iterator for Cursor {
     type Item = TokenTree;
 
     fn next(&mut self) -> Option<TokenTree> {
-        self.next_as_stream().map(|stream| match stream {
-            TokenStream::Tree(tree, _) => tree,
-            _ => unreachable!()
-        })
+        self.next_with_joint().map(|(tree, _)| tree)
     }
 }
 
 impl Cursor {
     fn new(stream: TokenStream) -> Self {
-        Cursor(match stream {
-            TokenStream::Empty => CursorKind::Empty,
-            TokenStream::Tree(tree, is_joint) => CursorKind::Tree(tree, is_joint, false),
-            TokenStream::Stream(stream) => CursorKind::Stream(StreamCursor::new(stream)),
-        })
-    }
-
-    pub fn next_as_stream(&mut self) -> Option<TokenStream> {
-        let (stream, consumed) = match self.0 {
-            CursorKind::Tree(ref tree, ref is_joint, ref mut consumed @ false) =>
-                (TokenStream::Tree(tree.clone(), *is_joint), consumed),
-            CursorKind::Stream(ref mut cursor) => return cursor.next_as_stream(),
-            _ => return None,
-        };
-
-        *consumed = true;
-        Some(stream)
+        Cursor { stream, index: 0 }
     }
 
-    pub fn insert(&mut self, stream: TokenStream) {
-        match self.0 {
-            _ if stream.is_empty() => return,
-            CursorKind::Empty => *self = stream.trees(),
-            CursorKind::Tree(_, _, consumed) => {
-                *self = TokenStream::new(vec![self.original_stream(), stream]).trees();
-                if consumed {
-                    self.next();
+    pub fn next_with_joint(&mut self) -> Option<TreeAndJoint> {
+        match self.stream {
+            TokenStream::Empty => None,
+            TokenStream::Tree(ref tree, ref is_joint) => {
+                if self.index == 0 {
+                    self.index = 1;
+                    Some((tree.clone(), *is_joint))
+                } else {
+                    None
                 }
             }
-            CursorKind::Stream(ref mut cursor) => {
-                cursor.insert(ThinTokenStream::from(stream).0.unwrap());
+            TokenStream::Stream(ref stream) => {
+                if self.index < stream.len() {
+                    self.index += 1;
+                    Some(stream[self.index - 1].clone())
+                } else {
+                    None
+                }
             }
         }
     }
 
-    pub fn original_stream(&self) -> TokenStream {
-        match self.0 {
-            CursorKind::Empty => TokenStream::empty(),
-            CursorKind::Tree(ref tree, ref is_joint, _) =>
-                TokenStream::Tree(tree.clone(), *is_joint),
-            CursorKind::Stream(ref cursor) => TokenStream::Stream(
-                cursor.stack.get(0).cloned().map(|(stream, _)| stream)
-                    .unwrap_or_else(|| cursor.stream.clone())
-            ),
+    pub fn append(&mut self, new_stream: TokenStream) {
+        if new_stream.is_empty() {
+            return;
         }
+        let index = self.index;
+        let stream = mem::replace(&mut self.stream, TokenStream::Empty);
+        *self = TokenStream::from_streams(vec![stream, new_stream]).into_trees();
+        self.index = index;
     }
 
     pub fn look_ahead(&self, n: usize) -> Option<TokenTree> {
-        fn look_ahead(streams: &[TokenStream], mut n: usize) -> Result<TokenTree, usize> {
-            for stream in streams {
-                n = match stream {
-                    TokenStream::Tree(ref tree, _) if n == 0 => return Ok(tree.clone()),
-                    TokenStream::Tree(..) => n - 1,
-                    TokenStream::Stream(ref stream) => match look_ahead(stream, n) {
-                        Ok(tree) => return Ok(tree),
-                        Err(n) => n,
-                    },
-                    _ => n,
-                };
+        match self.stream {
+            TokenStream::Empty => None,
+            TokenStream::Tree(ref tree, _) => {
+                if n == 0 && self.index == 0 {
+                    Some(tree.clone())
+                } else {
+                    None
+                }
             }
-            Err(n)
+            TokenStream::Stream(ref stream) =>
+                stream[self.index ..].get(n).map(|(tree, _)| tree.clone()),
         }
-
-        match self.0 {
-            CursorKind::Empty |
-            CursorKind::Tree(_, _, true) => Err(n),
-            CursorKind::Tree(ref tree, _, false) => look_ahead(&[tree.clone().into()], n),
-            CursorKind::Stream(ref cursor) => {
-                look_ahead(&cursor.stream[cursor.index ..], n).or_else(|mut n| {
-                    for &(ref stream, index) in cursor.stack.iter().rev() {
-                        n = match look_ahead(&stream[index..], n) {
-                            Ok(tree) => return Ok(tree),
-                            Err(n) => n,
-                        }
-                    }
-
-                    Err(n)
-                })
-            }
-        }.ok()
     }
 }
 
@@ -623,7 +530,7 @@ fn look_ahead(streams: &[TokenStream], mut n: usize) -> Result<TokenTree, usize>
 /// `ThinTokenStream` is smaller, but needs to allocate to represent a single `TokenTree`.
 /// We must use `ThinTokenStream` in `TokenTree::Delimited` to avoid infinite size due to recursion.
 #[derive(Debug, Clone)]
-pub struct ThinTokenStream(Option<Lrc<Vec<TokenStream>>>);
+pub struct ThinTokenStream(Option<Lrc<Vec<TreeAndJoint>>>);
 
 impl ThinTokenStream {
     pub fn stream(&self) -> TokenStream {
@@ -635,7 +542,7 @@ impl From<TokenStream> for ThinTokenStream {
     fn from(stream: TokenStream) -> ThinTokenStream {
         ThinTokenStream(match stream {
             TokenStream::Empty => None,
-            TokenStream::Tree(..) => Some(Lrc::new(vec![stream])),
+            TokenStream::Tree(tree, is_joint) => Some(Lrc::new(vec![(tree, is_joint)])),
             TokenStream::Stream(stream) => Some(stream),
         })
     }
@@ -742,7 +649,7 @@ fn test_concat() {
             let test_res = string_to_ts("foo::bar::baz");
             let test_fst = string_to_ts("foo::bar");
             let test_snd = string_to_ts("::baz");
-            let eq_res = TokenStream::new(vec![test_fst, test_snd]);
+            let eq_res = TokenStream::from_streams(vec![test_fst, test_snd]);
             assert_eq!(test_res.trees().count(), 5);
             assert_eq!(eq_res.trees().count(), 5);
             assert_eq!(test_res.eq_unspanned(&eq_res), true);
@@ -827,107 +734,4 @@ fn test_dotdotdot() {
         assert!(stream.eq_unspanned(&string_to_ts("...")));
         assert_eq!(stream.trees().count(), 1);
     }
-
-    #[test]
-    fn test_extend_empty() {
-        with_globals(|| {
-            // Append a token onto an empty token stream.
-            let mut stream = TokenStream::empty();
-            stream.extend(vec![string_to_ts("t")]);
-
-            let expected = string_to_ts("t");
-            assert!(stream.eq_unspanned(&expected));
-        });
-    }
-
-    #[test]
-    fn test_extend_nothing() {
-        with_globals(|| {
-            // Append nothing onto a token stream containing one token.
-            let mut stream = string_to_ts("t");
-            stream.extend(vec![]);
-
-            let expected = string_to_ts("t");
-            assert!(stream.eq_unspanned(&expected));
-        });
-    }
-
-    #[test]
-    fn test_extend_single() {
-        with_globals(|| {
-            // Append a token onto token stream containing a single token.
-            let mut stream = string_to_ts("t1");
-            stream.extend(vec![string_to_ts("t2")]);
-
-            let expected = string_to_ts("t1 t2");
-            assert!(stream.eq_unspanned(&expected));
-        });
-    }
-
-    #[test]
-    fn test_extend_in_place() {
-        with_globals(|| {
-            // Append a token onto token stream containing a reference counted
-            // vec of tokens. The token stream has a reference count of 1 so
-            // this can happen in place.
-            let mut stream = string_to_ts("t1 t2");
-            stream.extend(vec![string_to_ts("t3")]);
-
-            let expected = string_to_ts("t1 t2 t3");
-            assert!(stream.eq_unspanned(&expected));
-        });
-    }
-
-    #[test]
-    fn test_extend_copy() {
-        with_globals(|| {
-            // Append a token onto token stream containing a reference counted
-            // vec of tokens. The token stream is shared so the extend takes
-            // place on a copy.
-            let mut stream = string_to_ts("t1 t2");
-            let _incref = stream.clone();
-            stream.extend(vec![string_to_ts("t3")]);
-
-            let expected = string_to_ts("t1 t2 t3");
-            assert!(stream.eq_unspanned(&expected));
-        });
-    }
-
-    #[test]
-    fn test_extend_no_join() {
-        with_globals(|| {
-            let first = TokenTree::Token(DUMMY_SP, Token::Dot);
-            let second = TokenTree::Token(DUMMY_SP, Token::Dot);
-
-            // Append a dot onto a token stream containing a dot, but do not
-            // join them.
-            let mut stream = TokenStream::from(first);
-            stream.extend(vec![TokenStream::from(second)]);
-
-            let expected = string_to_ts(". .");
-            assert!(stream.eq_unspanned(&expected));
-
-            let unexpected = string_to_ts("..");
-            assert!(!stream.eq_unspanned(&unexpected));
-        });
-    }
-
-    #[test]
-    fn test_extend_join() {
-        with_globals(|| {
-            let first = TokenTree::Token(DUMMY_SP, Token::Dot).joint();
-            let second = TokenTree::Token(DUMMY_SP, Token::Dot);
-
-            // Append a dot onto a token stream containing a dot, forming a
-            // dotdot.
-            let mut stream = first;
-            stream.extend(vec![TokenStream::from(second)]);
-
-            let expected = string_to_ts("..");
-            assert!(stream.eq_unspanned(&expected));
-
-            let unexpected = string_to_ts(". .");
-            assert!(!stream.eq_unspanned(&unexpected));
-        });
-    }
 }
index 61722ba5516535a9ec5e3f3eea5bd2b3b4d8f7ef..3e3bca7080fb6d4b9f77ce95272ffc6a68b5ee8b 100644 (file)
@@ -159,7 +159,7 @@ fn parse_args<'a>(
             };
             let name: &str = &ident.as_str();
 
-            p.expect(&token::Eq).unwrap();
+            p.expect(&token::Eq)?;
             let e = p.parse_expr()?;
             if let Some(prev) = names.get(name) {
                 ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", name))
index afd86a4f7465cd0b72455beed5afbbc1bfed8a1f..158cbc791ef504f30cf0d5ff6802f84769480874 100644 (file)
@@ -11,7 +11,7 @@
 use syntax::ext::base::ExtCtxt;
 use syntax::parse::lexer::comments;
 use syntax::parse::{self, token, ParseSess};
-use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream};
+use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
 use syntax_pos::hygiene::{SyntaxContext, Transparency};
 use syntax_pos::symbol::{keywords, Symbol};
 use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
@@ -46,13 +46,14 @@ fn to_internal(self) -> token::DelimToken {
     }
 }
 
-impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec<Self>)>
+impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
     for TokenTree<Group, Punct, Ident, Literal>
 {
-    fn from_internal((stream, sess, stack): (TokenStream, &ParseSess, &mut Vec<Self>)) -> Self {
+    fn from_internal(((tree, is_joint), sess, stack): (TreeAndJoint, &ParseSess, &mut Vec<Self>))
+                    -> Self {
         use syntax::parse::token::*;
 
-        let (tree, joint) = stream.as_tree();
+        let joint = is_joint == Joint;
         let (span, token) = match tree {
             tokenstream::TokenTree::Delimited(span, delim, tts) => {
                 let delimiter = Delimiter::from_internal(delim);
@@ -450,7 +451,7 @@ fn next(
     ) -> Option<TokenTree<Self::Group, Self::Punct, Self::Ident, Self::Literal>> {
         loop {
             let tree = iter.stack.pop().or_else(|| {
-                let next = iter.cursor.next_as_stream()?;
+                let next = iter.cursor.next_with_joint()?;
                 Some(TokenTree::from_internal((next, self.sess, &mut iter.stack)))
             })?;
             // HACK: The condition "dummy span + group with empty delimiter" represents an AST
@@ -461,7 +462,7 @@ fn next(
             // and not doing the roundtrip through AST.
             if let TokenTree::Group(ref group) = tree {
                 if group.delimiter == Delimiter::None && group.span.entire().is_dummy() {
-                    iter.cursor.insert(group.stream.clone());
+                    iter.cursor.append(group.stream.clone());
                     continue;
                 }
             }
index cf842dddeb3d6cce4aeaeefbef83c00ce3386abf..a19d0458edd80309bc56365309c728046e4c4082 100644 (file)
@@ -124,14 +124,14 @@ pub fn expand_test_or_bench(
         ])
     };
 
-    let mut test_const = cx.item(sp, item.ident.gensym(),
+    let mut test_const = cx.item(sp, ast::Ident::new(item.ident.name.gensymed(), sp),
         vec![
             // #[cfg(test)]
             cx.attribute(attr_sp, cx.meta_list(attr_sp, Symbol::intern("cfg"), vec![
                 cx.meta_list_item_word(attr_sp, Symbol::intern("test"))
             ])),
             // #[rustc_test_marker]
-            cx.attribute(attr_sp, cx.meta_word(attr_sp, Symbol::intern("rustc_test_marker")))
+            cx.attribute(attr_sp, cx.meta_word(attr_sp, Symbol::intern("rustc_test_marker"))),
         ],
         // const $ident: test::TestDescAndFn =
         ast::ItemKind::Const(cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
index ddb30221d7985e813b4214d14c2a560ed6ee0991..269d0ba959f70e9b692e528311c78b8f9601d4af 160000 (submodule)
@@ -1 +1 @@
-Subproject commit ddb30221d7985e813b4214d14c2a560ed6ee0991
+Subproject commit 269d0ba959f70e9b692e528311c78b8f9601d4af
index 9913138693c9490d5cbbadbd020ec61dca454dd7..da6036a04a549e7aa4dbcc1179bd3841a2729283 100644 (file)
@@ -1,4 +1,4 @@
-#![feature(const_fn, const_let)]
+#![feature(const_fn)]
 
 const X : usize = 2;
 
diff --git a/src/test/run-pass/binding/allow_irrefutable_let_patterns.rs b/src/test/run-pass/binding/allow_irrefutable_let_patterns.rs
deleted file mode 100644 (file)
index d9a42a2..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// run-pass
-#![feature(irrefutable_let_patterns)]
-
-// must-compile-successfully-irrefutable_let_patterns_with_gate
-#[allow(irrefutable_let_patterns)]
-fn main() {
-    if let _ = 5 {}
-
-    while let _ = 5 {
-        break;
-    }
-}
diff --git a/src/test/run-pass/binding/match-static-const-rename.rs b/src/test/run-pass/binding/match-static-const-rename.rs
deleted file mode 100644 (file)
index e78ae40..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-// run-pass
-// Issue #7526: lowercase static constants in patterns look like bindings
-
-// This is similar to compile-fail/match-static-const-lc, except it
-// shows the expected usual workaround (choosing a different name for
-// the static definition) and also demonstrates that one can work
-// around this problem locally by renaming the constant in the `use`
-// form to an uppercase identifier that placates the lint.
-
-
-#![deny(non_upper_case_globals)]
-
-pub const A : isize = 97;
-
-fn f() {
-    let r = match (0,0) {
-        (0, A) => 0,
-        (x, y) => 1 + x + y,
-    };
-    assert_eq!(r, 1);
-    let r = match (0,97) {
-        (0, A) => 0,
-        (x, y) => 1 + x + y,
-    };
-    assert_eq!(r, 0);
-}
-
-mod m {
-    #[allow(non_upper_case_globals)]
-    pub const aha : isize = 7;
-}
-
-fn g() {
-    use self::m::aha as AHA;
-    let r = match (0,0) {
-        (0, AHA) => 0,
-        (x, y)   => 1 + x + y,
-    };
-    assert_eq!(r, 1);
-    let r = match (0,7) {
-        (0, AHA) => 0,
-        (x, y)   => 1 + x + y,
-    };
-    assert_eq!(r, 0);
-}
-
-fn h() {
-    let r = match (0,0) {
-        (0, self::m::aha) => 0,
-        (x, y)      => 1 + x + y,
-    };
-    assert_eq!(r, 1);
-    let r = match (0,7) {
-        (0, self::m::aha) => 0,
-        (x, y)      => 1 + x + y,
-    };
-    assert_eq!(r, 0);
-}
-
-pub fn main () {
-    f();
-    g();
-    h();
-}
index 2b4904cc6c39ae95b5e1e3acfbad9457cfadcaff..19d65860179b2628a598479fe69bf664bdbeabd5 100644 (file)
@@ -1,4 +1,4 @@
-#![feature(const_int_conversion, const_int_ops, reverse_bits)]
+#![feature(const_int_conversion, reverse_bits)]
 
 const REVERSE: u32 = 0x12345678_u32.reverse_bits();
 const FROM_BE_BYTES: i32 = i32::from_be_bytes([0x12, 0x34, 0x56, 0x78]);
@@ -21,4 +21,3 @@ fn main() {
     assert_eq!(TO_LE_BYTES, ident([0x78, 0x56, 0x34, 0x12]));
     assert_eq!(TO_NE_BYTES, ident([0x80, 0, 0, 0]));
 }
-
index ae7ee5aa96e3e945c9a8d702906e4d3798f48a86..289b1236cf1e214149afed505a62170ab7aea49a 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_int_overflowing)]
-
 const ADD_A: (u32, bool) = 5u32.overflowing_add(2);
 const ADD_B: (u32, bool) = u32::max_value().overflowing_add(1);
 
index 68c77f27a3193457c53d95ca152c6fba12deb1a9..c014e97ef19b806efa9dd5d1ce015aa5a1d4863f 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_int_rotate)]
-
 const LEFT: u32 = 0x10000b3u32.rotate_left(8);
 const RIGHT: u32 = 0xb301u32.rotate_right(8);
 
index ae55c1a9b0e39542fba300ddd70f4e872a67df4b..9d656a020306921d4cc851fa592a32cd39b051fd 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_int_sign)]
-
 const NEGATIVE_A: bool = (-10i32).is_negative();
 const NEGATIVE_B: bool = 10i32.is_negative();
 const POSITIVE_A: bool= (-10i32).is_positive();
index 504a654c0db659b526de42b74eee4e05f42ca8bd..5ab712015dfc37e42d002d35c46af02212a2c175 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_int_wrapping)]
-
 const ADD_A: u32 = 200u32.wrapping_add(55);
 const ADD_B: u32 = 200u32.wrapping_add(u32::max_value());
 
index dfc6678ba289dd7d7d5d18bfed1b29cbd6dbb6b9..cbe6d864c9c3a7eb35be33cb0679a3a2759e9546 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(const_int_ops)]
 #![feature(test)]
 
 extern crate test;
@@ -8,7 +7,6 @@
 const BE_U32: u32 = 55u32.to_be();
 const LE_U32: u32 = 55u32.to_le();
 
-
 fn main() {
     assert_eq!(BE_U32, b(55u32).to_be());
     assert_eq!(LE_U32, b(55u32).to_le());
index 90e97c8edbdd5f75f34b9e96e14833c95faf3b17..3145c21acc9889b5e7c0a221b1166b288b292e3a 100644 (file)
@@ -4,9 +4,9 @@
 
 use std::intrinsics;
 
-const SWAPPED_U8: u8 = unsafe { intrinsics::bswap(0x12_u8) };
-const SWAPPED_U16: u16 = unsafe { intrinsics::bswap(0x12_34_u16) };
-const SWAPPED_I32: i32 = unsafe { intrinsics::bswap(0x12_34_56_78_i32) };
+const SWAPPED_U8: u8 = intrinsics::bswap(0x12_u8);
+const SWAPPED_U16: u16 = intrinsics::bswap(0x12_34_u16);
+const SWAPPED_I32: i32 = intrinsics::bswap(0x12_34_56_78_i32);
 
 fn main() {
     assert_eq!(SWAPPED_U8, 0x12);
index 90295414d3efc73c1781d00b14eb1b4576e011cf..10a4c31f24ed4eb25c6c41d101842463c10185ee 100644 (file)
@@ -1,8 +1,8 @@
 // run-pass
 #![allow(dead_code)]
 
-#![feature(const_let)]
-
 type Array = [u32; {  let x = 2; 5 }];
 
-pub fn main() {}
+pub fn main() {
+    let _: Array = [0; 5];
+}
index 21ce08ab69c73cb5bf5244bffa361d39ca5e04f2..a1b9b586ad0384e70e2fffc0c66a141c51972dd9 100644 (file)
@@ -1,10 +1,11 @@
 // run-pass
 #![allow(dead_code)]
 
-#![feature(const_let)]
-
+#[repr(u8)]
 enum Foo {
     Bar = { let x = 1; 3 }
 }
 
-pub fn main() {}
+pub fn main() {
+    assert_eq!(3, Foo::Bar as u8);
+}
index 732c34dff5a801057f32a8988b4c6e6d7f5bf825..04865830df2ebec06bb9e8550be08dd39c9579e6 100644 (file)
@@ -2,7 +2,7 @@
 #![allow(dead_code)]
 #![allow(unused_variables)]
 
-#![feature(const_fn, const_let)]
+#![feature(const_fn)]
 
 const fn x() {
     let t = true;
index e527e1e88c8da6d8759c6efe7221696a31c78f25..95d50171a847bca7d0db0f0a2705106d669ffc58 100644 (file)
@@ -2,8 +2,6 @@
 
 // https://github.com/rust-lang/rust/issues/48821
 
-#![feature(const_fn, const_let)]
-
 const fn foo(i: usize) -> usize {
     let x = i;
     x
diff --git a/src/test/run-pass/enum-variant-generic-args.rs b/src/test/run-pass/enum-variant-generic-args.rs
deleted file mode 100644 (file)
index 0743f99..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#![feature(irrefutable_let_patterns)]
-#![feature(type_alias_enum_variants)]
-
-#![allow(irrefutable_let_patterns)]
-
-#[allow(dead_code)]
-enum Enum<T> { TSVariant(T), SVariant { v: T } }
-type Alias<T> = Enum<T>;
-type AliasFixed = Enum<()>;
-
-macro_rules! is_variant {
-    (TSVariant, $expr:expr) => (is_variant!(@check TSVariant, (_), $expr));
-    (SVariant, $expr:expr) => (is_variant!(@check SVariant, { v: _ }, $expr));
-    (@check $variant:ident, $matcher:tt, $expr:expr) => (
-        assert!(if let Enum::$variant::<()> $matcher = $expr { true } else { false },
-                "expr does not have correct type");
-    );
-}
-
-fn main() {
-    // Tuple struct variant
-
-    is_variant!(TSVariant, Enum::TSVariant(()));
-    is_variant!(TSVariant, Enum::TSVariant::<()>(()));
-    is_variant!(TSVariant, Enum::<()>::TSVariant(()));
-
-    is_variant!(TSVariant, Alias::TSVariant(()));
-    is_variant!(TSVariant, Alias::<()>::TSVariant(()));
-
-    is_variant!(TSVariant, AliasFixed::TSVariant(()));
-
-    // Struct variant
-
-    is_variant!(SVariant, Enum::SVariant { v: () });
-    is_variant!(SVariant, Enum::SVariant::<()> { v: () });
-    is_variant!(SVariant, Enum::<()>::SVariant { v: () });
-
-    is_variant!(SVariant, Alias::SVariant { v: () });
-    is_variant!(SVariant, Alias::<()>::SVariant { v: () });
-
-    is_variant!(SVariant, AliasFixed::SVariant { v: () });
-}
index 66e07f8683a8730e7c3c942e857fdbcb89f7f4fd..0154f0499502959fe95372e12aa730acd6f61217 100644 (file)
@@ -16,63 +16,63 @@ mod rusti {
 }
 
 pub fn main() {
-    unsafe {
-        use rusti::*;
-
-        assert_eq!(ctpop(0u8), 0); assert_eq!(ctpop(0i8), 0);
-        assert_eq!(ctpop(0u16), 0); assert_eq!(ctpop(0i16), 0);
-        assert_eq!(ctpop(0u32), 0); assert_eq!(ctpop(0i32), 0);
-        assert_eq!(ctpop(0u64), 0); assert_eq!(ctpop(0i64), 0);
-        assert_eq!(ctpop(0u128), 0); assert_eq!(ctpop(0i128), 0);
-
-        assert_eq!(ctpop(1u8), 1); assert_eq!(ctpop(1i8), 1);
-        assert_eq!(ctpop(1u16), 1); assert_eq!(ctpop(1i16), 1);
-        assert_eq!(ctpop(1u32), 1); assert_eq!(ctpop(1i32), 1);
-        assert_eq!(ctpop(1u64), 1); assert_eq!(ctpop(1i64), 1);
-        assert_eq!(ctpop(1u128), 1); assert_eq!(ctpop(1i128), 1);
-
-        assert_eq!(ctpop(10u8), 2); assert_eq!(ctpop(10i8), 2);
-        assert_eq!(ctpop(10u16), 2); assert_eq!(ctpop(10i16), 2);
-        assert_eq!(ctpop(10u32), 2); assert_eq!(ctpop(10i32), 2);
-        assert_eq!(ctpop(10u64), 2); assert_eq!(ctpop(10i64), 2);
-        assert_eq!(ctpop(10u128), 2); assert_eq!(ctpop(10i128), 2);
-
-        assert_eq!(ctpop(100u8), 3); assert_eq!(ctpop(100i8), 3);
-        assert_eq!(ctpop(100u16), 3); assert_eq!(ctpop(100i16), 3);
-        assert_eq!(ctpop(100u32), 3); assert_eq!(ctpop(100i32), 3);
-        assert_eq!(ctpop(100u64), 3); assert_eq!(ctpop(100i64), 3);
-        assert_eq!(ctpop(100u128), 3); assert_eq!(ctpop(100i128), 3);
-
-        assert_eq!(ctpop(-1i8 as u8), 8); assert_eq!(ctpop(-1i8), 8);
-        assert_eq!(ctpop(-1i16 as u16), 16); assert_eq!(ctpop(-1i16), 16);
-        assert_eq!(ctpop(-1i32 as u32), 32); assert_eq!(ctpop(-1i32), 32);
-        assert_eq!(ctpop(-1i64 as u64), 64); assert_eq!(ctpop(-1i64), 64);
-        assert_eq!(ctpop(-1i128 as u128), 128); assert_eq!(ctpop(-1i128), 128);
-
-        assert_eq!(ctlz(0u8), 8); assert_eq!(ctlz(0i8), 8);
-        assert_eq!(ctlz(0u16), 16); assert_eq!(ctlz(0i16), 16);
-        assert_eq!(ctlz(0u32), 32); assert_eq!(ctlz(0i32), 32);
-        assert_eq!(ctlz(0u64), 64); assert_eq!(ctlz(0i64), 64);
-        assert_eq!(ctlz(0u128), 128); assert_eq!(ctlz(0i128), 128);
-
-        assert_eq!(ctlz(1u8), 7); assert_eq!(ctlz(1i8), 7);
-        assert_eq!(ctlz(1u16), 15); assert_eq!(ctlz(1i16), 15);
-        assert_eq!(ctlz(1u32), 31); assert_eq!(ctlz(1i32), 31);
-        assert_eq!(ctlz(1u64), 63); assert_eq!(ctlz(1i64), 63);
-        assert_eq!(ctlz(1u128), 127); assert_eq!(ctlz(1i128), 127);
-
-        assert_eq!(ctlz(10u8), 4); assert_eq!(ctlz(10i8), 4);
-        assert_eq!(ctlz(10u16), 12); assert_eq!(ctlz(10i16), 12);
-        assert_eq!(ctlz(10u32), 28); assert_eq!(ctlz(10i32), 28);
-        assert_eq!(ctlz(10u64), 60); assert_eq!(ctlz(10i64), 60);
-        assert_eq!(ctlz(10u128), 124); assert_eq!(ctlz(10i128), 124);
-
-        assert_eq!(ctlz(100u8), 1); assert_eq!(ctlz(100i8), 1);
-        assert_eq!(ctlz(100u16), 9); assert_eq!(ctlz(100i16), 9);
-        assert_eq!(ctlz(100u32), 25); assert_eq!(ctlz(100i32), 25);
-        assert_eq!(ctlz(100u64), 57); assert_eq!(ctlz(100i64), 57);
-        assert_eq!(ctlz(100u128), 121); assert_eq!(ctlz(100i128), 121);
+    use rusti::*;
+
+    assert_eq!(ctpop(0u8), 0); assert_eq!(ctpop(0i8), 0);
+    assert_eq!(ctpop(0u16), 0); assert_eq!(ctpop(0i16), 0);
+    assert_eq!(ctpop(0u32), 0); assert_eq!(ctpop(0i32), 0);
+    assert_eq!(ctpop(0u64), 0); assert_eq!(ctpop(0i64), 0);
+    assert_eq!(ctpop(0u128), 0); assert_eq!(ctpop(0i128), 0);
+
+    assert_eq!(ctpop(1u8), 1); assert_eq!(ctpop(1i8), 1);
+    assert_eq!(ctpop(1u16), 1); assert_eq!(ctpop(1i16), 1);
+    assert_eq!(ctpop(1u32), 1); assert_eq!(ctpop(1i32), 1);
+    assert_eq!(ctpop(1u64), 1); assert_eq!(ctpop(1i64), 1);
+    assert_eq!(ctpop(1u128), 1); assert_eq!(ctpop(1i128), 1);
+
+    assert_eq!(ctpop(10u8), 2); assert_eq!(ctpop(10i8), 2);
+    assert_eq!(ctpop(10u16), 2); assert_eq!(ctpop(10i16), 2);
+    assert_eq!(ctpop(10u32), 2); assert_eq!(ctpop(10i32), 2);
+    assert_eq!(ctpop(10u64), 2); assert_eq!(ctpop(10i64), 2);
+    assert_eq!(ctpop(10u128), 2); assert_eq!(ctpop(10i128), 2);
+
+    assert_eq!(ctpop(100u8), 3); assert_eq!(ctpop(100i8), 3);
+    assert_eq!(ctpop(100u16), 3); assert_eq!(ctpop(100i16), 3);
+    assert_eq!(ctpop(100u32), 3); assert_eq!(ctpop(100i32), 3);
+    assert_eq!(ctpop(100u64), 3); assert_eq!(ctpop(100i64), 3);
+    assert_eq!(ctpop(100u128), 3); assert_eq!(ctpop(100i128), 3);
+
+    assert_eq!(ctpop(-1i8 as u8), 8); assert_eq!(ctpop(-1i8), 8);
+    assert_eq!(ctpop(-1i16 as u16), 16); assert_eq!(ctpop(-1i16), 16);
+    assert_eq!(ctpop(-1i32 as u32), 32); assert_eq!(ctpop(-1i32), 32);
+    assert_eq!(ctpop(-1i64 as u64), 64); assert_eq!(ctpop(-1i64), 64);
+    assert_eq!(ctpop(-1i128 as u128), 128); assert_eq!(ctpop(-1i128), 128);
+
+    assert_eq!(ctlz(0u8), 8); assert_eq!(ctlz(0i8), 8);
+    assert_eq!(ctlz(0u16), 16); assert_eq!(ctlz(0i16), 16);
+    assert_eq!(ctlz(0u32), 32); assert_eq!(ctlz(0i32), 32);
+    assert_eq!(ctlz(0u64), 64); assert_eq!(ctlz(0i64), 64);
+    assert_eq!(ctlz(0u128), 128); assert_eq!(ctlz(0i128), 128);
+
+    assert_eq!(ctlz(1u8), 7); assert_eq!(ctlz(1i8), 7);
+    assert_eq!(ctlz(1u16), 15); assert_eq!(ctlz(1i16), 15);
+    assert_eq!(ctlz(1u32), 31); assert_eq!(ctlz(1i32), 31);
+    assert_eq!(ctlz(1u64), 63); assert_eq!(ctlz(1i64), 63);
+    assert_eq!(ctlz(1u128), 127); assert_eq!(ctlz(1i128), 127);
+
+    assert_eq!(ctlz(10u8), 4); assert_eq!(ctlz(10i8), 4);
+    assert_eq!(ctlz(10u16), 12); assert_eq!(ctlz(10i16), 12);
+    assert_eq!(ctlz(10u32), 28); assert_eq!(ctlz(10i32), 28);
+    assert_eq!(ctlz(10u64), 60); assert_eq!(ctlz(10i64), 60);
+    assert_eq!(ctlz(10u128), 124); assert_eq!(ctlz(10i128), 124);
+
+    assert_eq!(ctlz(100u8), 1); assert_eq!(ctlz(100i8), 1);
+    assert_eq!(ctlz(100u16), 9); assert_eq!(ctlz(100i16), 9);
+    assert_eq!(ctlz(100u32), 25); assert_eq!(ctlz(100i32), 25);
+    assert_eq!(ctlz(100u64), 57); assert_eq!(ctlz(100i64), 57);
+    assert_eq!(ctlz(100u128), 121); assert_eq!(ctlz(100i128), 121);
 
+    unsafe {
         assert_eq!(ctlz_nonzero(1u8), 7); assert_eq!(ctlz_nonzero(1i8), 7);
         assert_eq!(ctlz_nonzero(1u16), 15); assert_eq!(ctlz_nonzero(1i16), 15);
         assert_eq!(ctlz_nonzero(1u32), 31); assert_eq!(ctlz_nonzero(1i32), 31);
@@ -90,37 +90,39 @@ pub fn main() {
         assert_eq!(ctlz_nonzero(100u32), 25); assert_eq!(ctlz_nonzero(100i32), 25);
         assert_eq!(ctlz_nonzero(100u64), 57); assert_eq!(ctlz_nonzero(100i64), 57);
         assert_eq!(ctlz_nonzero(100u128), 121); assert_eq!(ctlz_nonzero(100i128), 121);
+    }
 
-        assert_eq!(cttz(-1i8 as u8), 0); assert_eq!(cttz(-1i8), 0);
-        assert_eq!(cttz(-1i16 as u16), 0); assert_eq!(cttz(-1i16), 0);
-        assert_eq!(cttz(-1i32 as u32), 0); assert_eq!(cttz(-1i32), 0);
-        assert_eq!(cttz(-1i64 as u64), 0); assert_eq!(cttz(-1i64), 0);
-        assert_eq!(cttz(-1i128 as u128), 0); assert_eq!(cttz(-1i128), 0);
-
-        assert_eq!(cttz(0u8), 8); assert_eq!(cttz(0i8), 8);
-        assert_eq!(cttz(0u16), 16); assert_eq!(cttz(0i16), 16);
-        assert_eq!(cttz(0u32), 32); assert_eq!(cttz(0i32), 32);
-        assert_eq!(cttz(0u64), 64); assert_eq!(cttz(0i64), 64);
-        assert_eq!(cttz(0u128), 128); assert_eq!(cttz(0i128), 128);
-
-        assert_eq!(cttz(1u8), 0); assert_eq!(cttz(1i8), 0);
-        assert_eq!(cttz(1u16), 0); assert_eq!(cttz(1i16), 0);
-        assert_eq!(cttz(1u32), 0); assert_eq!(cttz(1i32), 0);
-        assert_eq!(cttz(1u64), 0); assert_eq!(cttz(1i64), 0);
-        assert_eq!(cttz(1u128), 0); assert_eq!(cttz(1i128), 0);
-
-        assert_eq!(cttz(10u8), 1); assert_eq!(cttz(10i8), 1);
-        assert_eq!(cttz(10u16), 1); assert_eq!(cttz(10i16), 1);
-        assert_eq!(cttz(10u32), 1); assert_eq!(cttz(10i32), 1);
-        assert_eq!(cttz(10u64), 1); assert_eq!(cttz(10i64), 1);
-        assert_eq!(cttz(10u128), 1); assert_eq!(cttz(10i128), 1);
-
-        assert_eq!(cttz(100u8), 2); assert_eq!(cttz(100i8), 2);
-        assert_eq!(cttz(100u16), 2); assert_eq!(cttz(100i16), 2);
-        assert_eq!(cttz(100u32), 2); assert_eq!(cttz(100i32), 2);
-        assert_eq!(cttz(100u64), 2); assert_eq!(cttz(100i64), 2);
-        assert_eq!(cttz(100u128), 2); assert_eq!(cttz(100i128), 2);
+    assert_eq!(cttz(-1i8 as u8), 0); assert_eq!(cttz(-1i8), 0);
+    assert_eq!(cttz(-1i16 as u16), 0); assert_eq!(cttz(-1i16), 0);
+    assert_eq!(cttz(-1i32 as u32), 0); assert_eq!(cttz(-1i32), 0);
+    assert_eq!(cttz(-1i64 as u64), 0); assert_eq!(cttz(-1i64), 0);
+    assert_eq!(cttz(-1i128 as u128), 0); assert_eq!(cttz(-1i128), 0);
+
+    assert_eq!(cttz(0u8), 8); assert_eq!(cttz(0i8), 8);
+    assert_eq!(cttz(0u16), 16); assert_eq!(cttz(0i16), 16);
+    assert_eq!(cttz(0u32), 32); assert_eq!(cttz(0i32), 32);
+    assert_eq!(cttz(0u64), 64); assert_eq!(cttz(0i64), 64);
+    assert_eq!(cttz(0u128), 128); assert_eq!(cttz(0i128), 128);
+
+    assert_eq!(cttz(1u8), 0); assert_eq!(cttz(1i8), 0);
+    assert_eq!(cttz(1u16), 0); assert_eq!(cttz(1i16), 0);
+    assert_eq!(cttz(1u32), 0); assert_eq!(cttz(1i32), 0);
+    assert_eq!(cttz(1u64), 0); assert_eq!(cttz(1i64), 0);
+    assert_eq!(cttz(1u128), 0); assert_eq!(cttz(1i128), 0);
+
+    assert_eq!(cttz(10u8), 1); assert_eq!(cttz(10i8), 1);
+    assert_eq!(cttz(10u16), 1); assert_eq!(cttz(10i16), 1);
+    assert_eq!(cttz(10u32), 1); assert_eq!(cttz(10i32), 1);
+    assert_eq!(cttz(10u64), 1); assert_eq!(cttz(10i64), 1);
+    assert_eq!(cttz(10u128), 1); assert_eq!(cttz(10i128), 1);
+
+    assert_eq!(cttz(100u8), 2); assert_eq!(cttz(100i8), 2);
+    assert_eq!(cttz(100u16), 2); assert_eq!(cttz(100i16), 2);
+    assert_eq!(cttz(100u32), 2); assert_eq!(cttz(100i32), 2);
+    assert_eq!(cttz(100u64), 2); assert_eq!(cttz(100i64), 2);
+    assert_eq!(cttz(100u128), 2); assert_eq!(cttz(100i128), 2);
 
+    unsafe {
         assert_eq!(cttz_nonzero(-1i8 as u8), 0); assert_eq!(cttz_nonzero(-1i8), 0);
         assert_eq!(cttz_nonzero(-1i16 as u16), 0); assert_eq!(cttz_nonzero(-1i16), 0);
         assert_eq!(cttz_nonzero(-1i32 as u32), 0); assert_eq!(cttz_nonzero(-1i32), 0);
@@ -144,27 +146,27 @@ pub fn main() {
         assert_eq!(cttz_nonzero(100u32), 2); assert_eq!(cttz_nonzero(100i32), 2);
         assert_eq!(cttz_nonzero(100u64), 2); assert_eq!(cttz_nonzero(100i64), 2);
         assert_eq!(cttz_nonzero(100u128), 2); assert_eq!(cttz_nonzero(100i128), 2);
-
-        assert_eq!(bswap(0x0Au8), 0x0A); // no-op
-        assert_eq!(bswap(0x0Ai8), 0x0A); // no-op
-        assert_eq!(bswap(0x0A0Bu16), 0x0B0A);
-        assert_eq!(bswap(0x0A0Bi16), 0x0B0A);
-        assert_eq!(bswap(0x0ABBCC0Du32), 0x0DCCBB0A);
-        assert_eq!(bswap(0x0ABBCC0Di32), 0x0DCCBB0A);
-        assert_eq!(bswap(0x0122334455667708u64), 0x0877665544332201);
-        assert_eq!(bswap(0x0122334455667708i64), 0x0877665544332201);
-        assert_eq!(bswap(0x0122334455667708u128), 0x08776655443322010000000000000000);
-        assert_eq!(bswap(0x0122334455667708i128), 0x08776655443322010000000000000000);
-
-        assert_eq!(bitreverse(0x0Au8), 0x50);
-        assert_eq!(bitreverse(0x0Ai8), 0x50);
-        assert_eq!(bitreverse(0x0A0Cu16), 0x3050);
-        assert_eq!(bitreverse(0x0A0Ci16), 0x3050);
-        assert_eq!(bitreverse(0x0ABBCC0Eu32), 0x7033DD50);
-        assert_eq!(bitreverse(0x0ABBCC0Ei32), 0x7033DD50);
-        assert_eq!(bitreverse(0x0122334455667708u64), 0x10EE66AA22CC4480);
-        assert_eq!(bitreverse(0x0122334455667708i64), 0x10EE66AA22CC4480);
-        assert_eq!(bitreverse(0x0122334455667708u128), 0x10EE66AA22CC44800000000000000000);
-        assert_eq!(bitreverse(0x0122334455667708i128), 0x10EE66AA22CC44800000000000000000);
     }
+
+    assert_eq!(bswap(0x0Au8), 0x0A); // no-op
+    assert_eq!(bswap(0x0Ai8), 0x0A); // no-op
+    assert_eq!(bswap(0x0A0Bu16), 0x0B0A);
+    assert_eq!(bswap(0x0A0Bi16), 0x0B0A);
+    assert_eq!(bswap(0x0ABBCC0Du32), 0x0DCCBB0A);
+    assert_eq!(bswap(0x0ABBCC0Di32), 0x0DCCBB0A);
+    assert_eq!(bswap(0x0122334455667708u64), 0x0877665544332201);
+    assert_eq!(bswap(0x0122334455667708i64), 0x0877665544332201);
+    assert_eq!(bswap(0x0122334455667708u128), 0x08776655443322010000000000000000);
+    assert_eq!(bswap(0x0122334455667708i128), 0x08776655443322010000000000000000);
+
+    assert_eq!(bitreverse(0x0Au8), 0x50);
+    assert_eq!(bitreverse(0x0Ai8), 0x50);
+    assert_eq!(bitreverse(0x0A0Cu16), 0x3050);
+    assert_eq!(bitreverse(0x0A0Ci16), 0x3050);
+    assert_eq!(bitreverse(0x0ABBCC0Eu32), 0x7033DD50);
+    assert_eq!(bitreverse(0x0ABBCC0Ei32), 0x7033DD50);
+    assert_eq!(bitreverse(0x0122334455667708u64), 0x10EE66AA22CC4480);
+    assert_eq!(bitreverse(0x0122334455667708i64), 0x10EE66AA22CC4480);
+    assert_eq!(bitreverse(0x0122334455667708u128), 0x10EE66AA22CC44800000000000000000);
+    assert_eq!(bitreverse(0x0122334455667708i128), 0x10EE66AA22CC44800000000000000000);
 }
diff --git a/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs b/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs
deleted file mode 100644 (file)
index a123abd..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-//
-#![allow(dead_code)]
-
-
-#![forbid(non_camel_case_types)]
-#![forbid(non_upper_case_globals)]
-#![feature(non_ascii_idents)]
-
-// Some scripts (e.g., hiragana) don't have a concept of
-// upper/lowercase
-
-struct ãƒ’;
-
-static ãƒ©: usize = 0;
-
-pub fn main() {}
diff --git a/src/test/run-pass/lint-non-camel-case-with-trailing-underscores.rs b/src/test/run-pass/lint-non-camel-case-with-trailing-underscores.rs
deleted file mode 100644 (file)
index 6c0ea83..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#![allow(dead_code)]
-// This is ok because we often use the trailing underscore to mean 'prime'
-
-// pretty-expanded FIXME #23616
-
-#[forbid(non_camel_case_types)]
-type Foo_ = isize;
-
-pub fn main() { }
index a817ac736632e6c41366d4708ff6107a6c7c5b86..14b562160dfed5691eee478f3e2f1d632983a2da 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(transpose_result)]
-
 #[derive(Copy, Clone, Debug, PartialEq)]
 struct BadNumErr;
 
index f9bd2f471ae9dac755f84c9430d475e63f4391c4..22f04c58f3b3c3c35865633f3420fe405efd7deb 100644 (file)
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(dead_code)]
-#![feature(if_while_or_patterns)]
 
 enum E {
     V(u8),
@@ -19,4 +18,16 @@ fn main() {
         assert_eq!(x, 10);
         e = W;
     }
+
+    // Accept leading `|`:
+
+    let mut e = V(10);
+
+    if let | V(x) | U(x) = e {
+        assert_eq!(x, 10);
+    }
+    while let | V(x) | U(x) = e {
+        assert_eq!(x, 10);
+        e = W;
+    }
 }
diff --git a/src/test/run-pass/snake-case-no-lowercase-equivalent.rs b/src/test/run-pass/snake-case-no-lowercase-equivalent.rs
deleted file mode 100644 (file)
index cf7a163..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#![allow(dead_code)]
-// pretty-expanded FIXME #23616
-
-#![feature(non_ascii_idents)]
-#![deny(non_snake_case)]
-
-// This name is neither upper nor lower case
-fn ä½ å¥½() {}
-
-fn main() {}
diff --git a/src/test/run-pass/test-allow-non-camel-case-variant.rs b/src/test/run-pass/test-allow-non-camel-case-variant.rs
deleted file mode 100644 (file)
index da3ef7e..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#![deny(non_camel_case_types)]
-
-pub enum Foo {
-    #[allow(non_camel_case_types)]
-    bar
-}
-
-fn main() {}
index e8e25d877477aaceca8c1794e64d210b82bf526b..a46533178609bb7b6677944d34e61e6ef2bc24e5 100644 (file)
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(uniform_paths)]
-
 mod m { pub fn f() {} }
 mod n { pub fn g() {} }
 
index 0b95618ded5d388f552811102e585323d4dcd95f..e4e8b32c70ee9a1d6907d9d45adfb223861375a4 100644 (file)
@@ -1,12 +1,12 @@
-// run-pass
-#![allow(unused_imports)]
-#![allow(non_camel_case_types)]
+// This test is similar to `basic.rs`, but nested in modules.
 
+// run-pass
 // edition:2018
 
-#![feature(decl_macro, uniform_paths)]
+#![feature(decl_macro)]
 
-// This test is similar to `basic.rs`, but nested in modules.
+#![allow(unused_imports)]
+#![allow(non_camel_case_types)]
 
 mod foo {
     // Test that ambiguity errors are not emitted between `self::test` and
index 347e0bc00f118d82eabda13e3be2ae17a6aaa336..4e2e2dedef67924c9bb265bbba87d59500b691f1 100644 (file)
@@ -1,10 +1,8 @@
 // run-pass
-#![allow(unused_imports)]
-#![allow(non_camel_case_types)]
-
 // edition:2018
 
-#![feature(uniform_paths)]
+#![allow(unused_imports)]
+#![allow(non_camel_case_types)]
 
 // Test that ambiguity errors are not emitted between `self::test` and
 // `::test`, assuming the latter (crate) is not in `extern_prelude`.
index cf33c4860a1b42876b275637d7f77e2a84e5a94d..a62a28bb94d12681bf90d7ff97bfd750b914cfa4 100644 (file)
@@ -1,11 +1,9 @@
-// run-pass
-#![allow(non_camel_case_types)]
+// This test is similar to `macros.rs`, but nested in modules.
 
+// run-pass
 // edition:2018
 
-#![feature(uniform_paths)]
-
-// This test is similar to `macros.rs`, but nested in modules.
+#![allow(non_camel_case_types)]
 
 mod foo {
     // Test that ambiguity errors are not emitted between `self::test` and
index 332c2266e322bf20d93d8f20086501e801cde7ee..31b809f0cfdc5f2a5ad39ad08a64ca302017e2b9 100644 (file)
@@ -1,11 +1,9 @@
-// run-pass
-#![allow(non_camel_case_types)]
+// This test is similar to `basic.rs`, but with macros defining local items.
 
+// run-pass
 // edition:2018
 
-#![feature(uniform_paths)]
-
-// This test is similar to `basic.rs`, but with macros defining local items.
+#![allow(non_camel_case_types)]
 
 // Test that ambiguity errors are not emitted between `self::test` and
 // `::test`, assuming the latter (crate) is not in `extern_prelude`.
index 18a7d089a9b0c12089bade019c9d25eb227803d9..ce4cc13d9ecd7876007f5ed679a90deca6fe0aae 100644 (file)
@@ -1,9 +1,6 @@
 // run-pass
-
 // edition:2018
 
-#![feature(uniform_paths)]
-
 pub const A: usize = 0;
 
 pub mod foo {
diff --git a/src/test/rustdoc-ui/deny-missing-docs-crate.rs b/src/test/rustdoc-ui/deny-missing-docs-crate.rs
new file mode 100644 (file)
index 0000000..910c993
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![deny(missing_docs)] //~ ERROR
+
+pub struct Foo; //~ ERROR
diff --git a/src/test/rustdoc-ui/deny-missing-docs-crate.stderr b/src/test/rustdoc-ui/deny-missing-docs-crate.stderr
new file mode 100644 (file)
index 0000000..7f0590e
--- /dev/null
@@ -0,0 +1,22 @@
+error: missing documentation for crate
+  --> $DIR/deny-missing-docs-crate.rs:11:1
+   |
+LL | / #![deny(missing_docs)] //~ ERROR
+LL | |
+LL | | pub struct Foo; //~ ERROR
+   | |_______________^
+   |
+note: lint level defined here
+  --> $DIR/deny-missing-docs-crate.rs:11:9
+   |
+LL | #![deny(missing_docs)] //~ ERROR
+   |         ^^^^^^^^^^^^
+
+error: missing documentation for a struct
+  --> $DIR/deny-missing-docs-crate.rs:13:1
+   |
+LL | pub struct Foo; //~ ERROR
+   | ^^^^^^^^^^^^^^^
+
+error: Compilation failed, aborting rustdoc
+
diff --git a/src/test/rustdoc-ui/deny-missing-docs-macro.rs b/src/test/rustdoc-ui/deny-missing-docs-macro.rs
new file mode 100644 (file)
index 0000000..a12fe17
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! foo
+
+#![deny(missing_docs)]
+
+#[macro_export]
+macro_rules! foo { //~ ERROR
+    () => {}
+}
diff --git a/src/test/rustdoc-ui/deny-missing-docs-macro.stderr b/src/test/rustdoc-ui/deny-missing-docs-macro.stderr
new file mode 100644 (file)
index 0000000..686a450
--- /dev/null
@@ -0,0 +1,14 @@
+error: missing documentation for macro
+  --> $DIR/deny-missing-docs-macro.rs:16:1
+   |
+LL | macro_rules! foo { //~ ERROR
+   | ^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/deny-missing-docs-macro.rs:13:9
+   |
+LL | #![deny(missing_docs)]
+   |         ^^^^^^^^^^^^
+
+error: Compilation failed, aborting rustdoc
+
index 3f3c25162994e3f67bdad2523d841dcee2722f9b..c561269cf9a856fab03feacda61a7ccb061fabb7 100644 (file)
@@ -10,7 +10,7 @@
 pub struct SomeStruct;
 
 impl SomeStruct {
-    // @has 'foo/struct.SomeStruct.html' '//*[@id="SOME_CONST.v"]//div[@class="since"]' '1.1.2'
+    // @has 'foo/struct.SomeStruct.html' '//*[@id="associatedconstant.SOME_CONST"]//div[@class="since"]' '1.1.2'
     #[stable(since="1.1.2", feature="rust2")]
     pub const SOME_CONST: usize = 0;
 }
diff --git a/src/test/rustdoc/auxiliary/pub-extern-crate.rs b/src/test/rustdoc/auxiliary/pub-extern-crate.rs
new file mode 100644 (file)
index 0000000..8c89c8d
--- /dev/null
@@ -0,0 +1,2 @@
+#![crate_name = "inner"]
+pub struct SomeStruct;
index f3118bb606630851ac304f606f68a78fc9757982..c33db5809cc7c5d685e47d439e66523f7d65a527 100644 (file)
@@ -3,7 +3,7 @@
 pub struct Foo;
 
 impl Foo {
-    // @has const/struct.Foo.html '//*[@id="new.v"]//code' 'const unsafe fn new'
+    // @has const/struct.Foo.html '//code[@id="new.v"]' 'const unsafe fn new'
     pub const unsafe fn new() -> Foo {
         Foo
     }
index 3c1580f3786bb6cd0fb298ef6684ed782490e39d..55d8ee394385b50b4bc4c49c59784e0ef39bb6de 100644 (file)
@@ -9,17 +9,17 @@ pub trait Bar {
 
 impl Foo<u8> {
     // @has - '//*[@id="method.pass"]//code' 'fn pass()'
-    // @has - '//*[@id="pass.v"]//code' 'fn pass()'
+    // @has - '//code[@id="pass.v"]' 'fn pass()'
     pub fn pass() {}
 }
 impl Foo<u16> {
     // @has - '//*[@id="method.pass-1"]//code' 'fn pass() -> usize'
-    // @has - '//*[@id="pass.v-1"]//code' 'fn pass() -> usize'
+    // @has - '//code[@id="pass.v-1"]' 'fn pass() -> usize'
     pub fn pass() -> usize { 42 }
 }
 impl Foo<u32> {
     // @has - '//*[@id="method.pass-2"]//code' 'fn pass() -> isize'
-    // @has - '//*[@id="pass.v-2"]//code' 'fn pass() -> isize'
+    // @has - '//code[@id="pass.v-2"]' 'fn pass() -> isize'
     pub fn pass() -> isize { 42 }
 }
 
index 709cf5be7812d46fc18279209a3d03ed656b6ee8..58876a1aa116277401614b8e40c831c3609210d9 100644 (file)
@@ -10,7 +10,7 @@
 //      'Deprecated since 1.0.0: text'
 // @has - '<code>test</code>&nbsp;<a href="http://issue_url/32374">#32374</a>'
 // @matches issue_32374/struct.T.html '//*[@class="stab unstable"]' \
-//      '🔬 This is a nightly-only experimental API. \(test #32374\)$'
+//      '🔬 This is a nightly-only experimental API. \(test\s#32374\)$'
 /// Docs
 #[rustc_deprecated(since = "1.0.0", reason = "text")]
 #[unstable(feature = "test", issue = "32374")]
index b57a067f3d9b85ad719cbcd13ec9bd4ca6ea366e..d9accf9c5998b355c6f139af54aa738fb8e44557 100644 (file)
@@ -7,7 +7,7 @@ pub trait Owned<'a> {
 }
 
 // @has issue_51236/struct.Owned.html
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<T> Send for \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> Send for \
 // Owned<T> where <T as Owned<'static>>::Reader: Send"
 pub struct Owned<T> where T: for<'a> ::traits::Owned<'a> {
     marker: PhantomData<<T as ::traits::Owned<'static>>::Reader>,
index 34f71fab0cc6373ef89256eb13fbed2bd901ea14..263b1eb0bd65aad1cbcbcf0130804d482c187088 100644 (file)
@@ -3,10 +3,10 @@ pub trait ScopeHandle<'scope> {}
 
 
 // @has issue_54705/struct.ScopeFutureContents.html
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'scope, S> \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'scope, S> \
 // Send for ScopeFutureContents<'scope, S> where S: Sync"
 //
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'scope, S> \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'scope, S> \
 // Sync for ScopeFutureContents<'scope, S> where S: Sync"
 pub struct ScopeFutureContents<'scope, S>
     where S: ScopeHandle<'scope>,
index 5c34a4d34ab872feee76c86c1dfa13d0d9238827..257cb32c65c259261b177e7791dacadf6594ccbb 100644 (file)
@@ -1,16 +1,16 @@
 #![feature(optin_builtin_traits)]
 
 // @has issue_55321/struct.A.html
-// @has - '//*[@id="implementations-list"]/*[@class="impl"]//*/code' "impl !Send for A"
-// @has - '//*[@id="implementations-list"]/*[@class="impl"]//*/code' "impl !Sync for A"
+// @has - '//*[@id="implementations-list"]/*[@class="impl"]//code' "impl !Send for A"
+// @has - '//*[@id="implementations-list"]/*[@class="impl"]//code' "impl !Sync for A"
 pub struct A();
 
 impl !Send for A {}
 impl !Sync for A {}
 
 // @has issue_55321/struct.B.html
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<T> !Send for \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> !Send for \
 // B<T>"
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<T> !Sync for \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> !Sync for \
 // B<T>"
 pub struct B<T: ?Sized>(A, Box<T>);
index 2d6cb1368d120ffa791212c56bdbad723281680c..5b67817fa4caaf6d4dfac69a4521f10d38429aa4 100644 (file)
@@ -17,7 +17,7 @@ impl<'a, T> MyTrait for Inner<'a, T> {
 }
 
 // @has issue_56822/struct.Parser.html
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'a> Send for \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'a> Send for \
 // Parser<'a>"
 pub struct Parser<'a> {
     field: <Wrapper<Inner<'a, u8>> as MyTrait>::Output
diff --git a/src/test/rustdoc/pub-extern-crate.rs b/src/test/rustdoc/pub-extern-crate.rs
new file mode 100644 (file)
index 0000000..26747a4
--- /dev/null
@@ -0,0 +1,9 @@
+// aux-build:pub-extern-crate.rs
+
+// @has pub_extern_crate/index.html
+// @!has - '//code' 'pub extern crate inner'
+// @has - '//a/@href' 'inner/index.html'
+// @has pub_extern_crate/inner/index.html
+// @has pub_extern_crate/inner/struct.SomeStruct.html
+#[doc(inline)]
+pub extern crate inner;
index d2533a2dd390e0335416117383bd2dcc55839ab0..609cefc7115e2d19b8f8443d759d53f69d324b6c 100644 (file)
@@ -20,7 +20,7 @@ pub struct Foo<T> {
 }
 
 // @has complex/struct.NotOuter.html
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'a, T, K: \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'a, T, K: \
 // ?Sized> Send for NotOuter<'a, T, K> where K: for<'b> Fn((&'b bool, &'a u8)) \
 // -> &'b i8, T: MyTrait<'a>, <T as MyTrait<'a>>::MyItem: Copy, 'a: 'static"
 
index 03b84c7838edc2b6e6793a0d687f1d67c4e4c774..6d0a68f9b0734eeaaf7c0f465e012d1593df9a5c 100644 (file)
@@ -9,10 +9,10 @@ unsafe impl<'a, T> Send for Inner<'a, T>
 {}
 
 // @has lifetimes/struct.Foo.html
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'c, K> Send \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'c, K> Send \
 // for Foo<'c, K> where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static"
 //
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'c, K> Sync \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'c, K> Sync \
 // for Foo<'c, K> where K: Sync"
 pub struct Foo<'c, K: 'c> {
     inner_field: Inner<'c, K>,
index c7cfa0c0fa1b81e2827ccf07aeae8f44ce8f250c..413ba187f4556410a3267dd1b3b3bc168783d408 100644 (file)
@@ -1,8 +1,8 @@
 // @has manual/struct.Foo.html
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' 'impl<T> Sync for \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' 'impl<T> Sync for \
 // Foo<T> where T: Sync'
 //
-// @has - '//*[@id="implementations-list"]/*[@class="impl"]//*/code' \
+// @has - '//*[@id="implementations-list"]/*[@class="impl"]//code' \
 // 'impl<T> Send for Foo<T>'
 //
 // @count - '//*[@id="implementations-list"]/*[@class="impl"]' 1
index 5b6304ed4e4712863f7aee58157429354191b18b..30713849da221fd6bcf278778cbff88aa19d2658 100644 (file)
@@ -3,10 +3,10 @@ pub struct Inner<T: Copy> {
 }
 
 // @has negative/struct.Outer.html
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<T> !Send for \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> !Send for \
 // Outer<T>"
 //
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<T> \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> \
 // !Sync for Outer<T>"
 pub struct Outer<T: Copy> {
     inner_field: Inner<T>,
index 75d2ff2af13e1c39b60ae38731eadee1be45d857..e710ce1c2ed95eb1c49a21da5a81d28ecabc9998 100644 (file)
@@ -9,10 +9,10 @@ unsafe impl<T> Send for Inner<T>
 }
 
 // @has nested/struct.Foo.html
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' 'impl<T> Send for \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' 'impl<T> Send for \
 // Foo<T> where T: Copy'
 //
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' \
 // 'impl<T> Sync for Foo<T> where T: Sync'
 pub struct Foo<T> {
     inner_field: Inner<T>,
index 92402714b9d51d6159a4db8129f7bf261e1a6e7a..cf173111ec1e27ebdab26114d4315721d1ccff01 100644 (file)
@@ -9,7 +9,7 @@ unsafe impl<T> Send for Inner<T>
 }
 
 // @has no_redundancy/struct.Outer.html
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<T> Send for \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> Send for \
 // Outer<T> where T: Copy + Send"
 pub struct Outer<T> {
     inner_field: Inner<T>,
index 6be6b44a4400af417f62294c88c8b67bccd805ee..5346521f8d2e365cbffabda500186b9e781605fc 100644 (file)
@@ -23,10 +23,10 @@ unsafe impl<'a, T> Sync for Inner<'a, T>
 }
 
 // @has project/struct.Foo.html
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'c, K> Send \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'c, K> Send \
 // for Foo<'c, K> where K: MyTrait<MyItem = bool>, 'c: 'static"
 //
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'c, K> Sync \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'c, K> Sync \
 // for Foo<'c, K> where K: MyTrait, <K as MyTrait>::MyItem: OtherTrait, 'c: 'static,"
 pub struct Foo<'c, K: 'c> {
     inner_field: Inner<'c, K>,
index 0dca8fe297820d58284bc6772485025fa001a75e..7d15434afe6dbb9cfd12fb50b768be211b1bcc83 100644 (file)
@@ -23,7 +23,7 @@ impl<T> Pattern for Wrapper<T> {
 
 
 // @has self_referential/struct.WriteAndThen.html
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<P1> Send for \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<P1> Send for \
 // WriteAndThen<P1>  where  <P1 as Pattern>::Value: Send"
 pub struct WriteAndThen<P1>(pub P1::Value,pub <Constrain<P1, Wrapper<P1::Value>> as Pattern>::Value)
     where P1: Pattern;
index d1d50fbc6ba15f35818c69977c52282f1d871cce..59493744b623d7155f82ad268e1939cb9eda97af 100644 (file)
@@ -3,7 +3,7 @@ pub trait OwnedTrait<'a> {
 }
 
 // @has static_region/struct.Owned.html
-// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<T> Send for \
+// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> Send for \
 // Owned<T> where <T as OwnedTrait<'static>>::Reader: Send"
 pub struct Owned<T> where T: OwnedTrait<'static> {
     marker: <T as OwnedTrait<'static>>::Reader,
index fe34be3731736d5c3d27753df16d2103f0393fff..05329a2714257bed0eaa05d6c11f7c38a09ab84d 100644 (file)
@@ -1,9 +1,9 @@
-// Test associated types are forbidden in inherent impls.
+// Test associated types are, until #8995 is implemented, forbidden in inherent impls.
 
 struct Foo;
 
 impl Foo {
-    type Bar = isize; //~ERROR associated types are not allowed in inherent impls
+    type Bar = isize; //~ERROR associated types are not yet supported in inherent impls (see #8995)
 }
 
 fn main() {}
index 1a555bd53ac8307f9aabf91819f6deeffc0deb32..f438ac8df4a090a0d639684ca3089c603895c415 100644 (file)
@@ -1,7 +1,7 @@
-error[E0202]: associated types are not allowed in inherent impls
+error[E0202]: associated types are not yet supported in inherent impls (see #8995)
   --> $DIR/assoc-inherent.rs:6:5
    |
-LL |     type Bar = isize; //~ERROR associated types are not allowed in inherent impls
+LL |     type Bar = isize; //~ERROR associated types are not yet supported in inherent impls (see #8995)
    |     ^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
diff --git a/src/test/ui/associated-const/associated-const-upper-case-lint.rs b/src/test/ui/associated-const/associated-const-upper-case-lint.rs
deleted file mode 100644 (file)
index c851b27..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#![deny(non_upper_case_globals)]
-#![allow(dead_code)]
-
-struct Foo;
-
-impl Foo {
-    const not_upper: bool = true;
-}
-//~^^ ERROR associated constant `not_upper` should have an upper case name such as `NOT_UPPER`
-
-fn main() {}
diff --git a/src/test/ui/associated-const/associated-const-upper-case-lint.stderr b/src/test/ui/associated-const/associated-const-upper-case-lint.stderr
deleted file mode 100644 (file)
index 43feb03..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error: associated constant `not_upper` should have an upper case name such as `NOT_UPPER`
-  --> $DIR/associated-const-upper-case-lint.rs:7:5
-   |
-LL |     const not_upper: bool = true;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: lint level defined here
-  --> $DIR/associated-const-upper-case-lint.rs:1:9
-   |
-LL | #![deny(non_upper_case_globals)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
index b56e1ea039cf1f83b5d956ad99c7cd93f72b40b6..a29723f34b4326239c944eed987d1ae385de3020 100644 (file)
@@ -14,7 +14,7 @@
 #[derive(Copy, Clone)]
 pub struct Foo(i64);
 
-pub unsafe fn test_cttz(v: Foo) -> Foo {
+pub fn test_cttz(v: Foo) -> Foo {
     intrinsics::cttz(v)
     //~^ ERROR `cttz` intrinsic: expected basic integer type, found `Foo`
 }
index b38633b0ffeea09a64b56ce67e95910052e2a630..417667a5354fd723d445c5e9271bb60ccf7d59e1 100644 (file)
@@ -12,6 +12,8 @@ LL |     Enum::EnumStructVariant { x: 1, y: 2, z: 3 }
 error[E0308]: mismatched types
   --> $DIR/issue-13624.rs:22:9
    |
+LL |       match enum_struct_variant {
+   |             ------------------- this match expression has type `()`
 LL |         a::Enum::EnumStructVariant { x, y, z } => {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum `a::Enum`
    |
index 79dc55bbbaeda148e282afac8f279652de4ee6eb..e116cb70c1c311499e9a4699a2facf3fb967e9dd 100644 (file)
@@ -138,7 +138,7 @@ error[E0502]: cannot borrow `foo` (via `foo.bar2`) as immutable because `foo` is
 LL |     let bar1 = &mut foo.bar1;
    |                     -------- mutable borrow occurs here (via `foo.bar1`)
 LL |     let _foo1 = &foo.bar2; //~ ERROR cannot borrow
-   |                  ^^^^^^^^ immutable borrow occurs here (via `foo.bar2`)
+   |                  ^^^^^^^^ immutable borrow of `foo.bar2` -- which overlaps with `foo.bar1` -- occurs here
 LL |     *bar1;
 LL | }
    | - mutable borrow ends here
index 95b26a5724a412da7024ec1f88ecd1a4f59ce61f..236064da3e8b6ed409eb3dd2543acf4919c19e2b 100644 (file)
@@ -61,7 +61,7 @@ error[E0502]: cannot borrow `a` (via `a.y`) as immutable because `a` is also bor
 LL |     let _x = &mut a.x;
    |                   --- mutable borrow occurs here (via `a.x`)
 LL |     let _y = &a.y; //[ast]~ ERROR cannot borrow
-   |               ^^^ immutable borrow occurs here (via `a.y`)
+   |               ^^^ immutable borrow of `a.y` -- which overlaps with `a.x` -- occurs here
 ...
 LL | }
    | - mutable borrow ends here
@@ -72,7 +72,7 @@ error[E0502]: cannot borrow `a` (via `a.y`) as mutable because `a` is also borro
 LL |     let _x = &a.x;
    |               --- immutable borrow occurs here (via `a.x`)
 LL |     let _y = &mut a.y; //[ast]~ ERROR cannot borrow
-   |                   ^^^ mutable borrow occurs here (via `a.y`)
+   |                   ^^^ mutable borrow of `a.y` -- which overlaps with `a.x` -- occurs here
 ...
 LL | }
    | - immutable borrow ends here
index 2af97a9fc1d58718ed3e92eefa80f0549adbe68e..e72048d0ea4bc66ed949be508f99c1d31640ce6e 100644 (file)
@@ -83,14 +83,14 @@ fn borrow_after_mut_borrow() {
     let mut a: Box<_> = box A { x: box 0, y: 1 };
     let _x = &mut a.x;
     let _y = &a.y; //[ast]~ ERROR cannot borrow
-    //[ast]~^ immutable borrow occurs here (via `a.y`)
+    //[ast]~^ immutable borrow of `a.y` -- which overlaps with `a.x` -- occurs here
     use_mut(_x);
 }
 fn mut_borrow_after_borrow() {
     let mut a: Box<_> = box A { x: box 0, y: 1 };
     let _x = &a.x;
     let _y = &mut a.y; //[ast]~ ERROR cannot borrow
-    //[ast]~^ mutable borrow occurs here (via `a.y`)
+    //[ast]~^ mutable borrow of `a.y` -- which overlaps with `a.x` -- occurs here
     use_imm(_x);
 }
 fn copy_after_move_nested() {
diff --git a/src/test/ui/borrowck/borrowck-union-borrow.ast.nll.stderr b/src/test/ui/borrowck/borrowck-union-borrow.ast.nll.stderr
deleted file mode 100644 (file)
index 1a2433c..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-error[E0502]: cannot borrow `u.a` as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-union-borrow.rs:27:23
-   |
-LL |             let ra = &u.a;
-   |                      ---- immutable borrow occurs here
-LL |             let rma = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
-   |                       ^^^^^^^^ mutable borrow occurs here
-LL |                                 //[mir]~^ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
-LL |             drop(ra);
-   |                  -- immutable borrow later used here
-
-error[E0506]: cannot assign to `u.a` because it is borrowed
-  --> $DIR/borrowck-union-borrow.rs:33:13
-   |
-LL |             let ra = &u.a;
-   |                      ---- borrow of `u.a` occurs here
-LL |             u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed
-   |             ^^^^^^^ assignment to borrowed `u.a` occurs here
-LL |                      //[mir]~^ ERROR cannot assign to `u.a` because it is borrowed
-LL |             drop(ra);
-   |                  -- borrow later used here
-
-error[E0502]: cannot borrow `u.b` as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-union-borrow.rs:50:23
-   |
-LL |             let ra = &u.a;
-   |                      ---- immutable borrow occurs here
-LL |             let rmb = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
-   |                       ^^^^^^^^ mutable borrow occurs here
-LL |                                 //[mir]~^ ERROR cannot borrow `u.b` as mutable because it is also borrowed as immutable
-LL |             drop(ra);
-   |                  -- immutable borrow later used here
-
-error[E0506]: cannot assign to `u.b` because it is borrowed
-  --> $DIR/borrowck-union-borrow.rs:56:13
-   |
-LL |             let ra = &u.a;
-   |                      ---- borrow of `u.b` occurs here
-LL |             u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed
-   |             ^^^^^^^ assignment to borrowed `u.b` occurs here
-LL |                      //[mir]~^ ERROR cannot assign to `u.b` because it is borrowed
-LL |             drop(ra);
-   |                  -- borrow later used here
-
-error[E0502]: cannot borrow `u.a` as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-union-borrow.rs:63:22
-   |
-LL |             let rma = &mut u.a;
-   |                       -------- mutable borrow occurs here
-LL |             let ra = &u.a; //[ast]~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
-   |                      ^^^^ immutable borrow occurs here
-LL |                          //[mir]~^ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
-LL |             drop(rma);
-   |                  --- mutable borrow later used here
-
-error[E0503]: cannot use `u.a` because it was mutably borrowed
-  --> $DIR/borrowck-union-borrow.rs:69:21
-   |
-LL |             let ra = &mut u.a;
-   |                      -------- borrow of `u.a` occurs here
-LL |             let a = u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
-   |                     ^^^ use of borrowed `u.a`
-LL |                          //[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed
-LL |             drop(ra);
-   |                  -- borrow later used here
-
-error[E0499]: cannot borrow `u.a` as mutable more than once at a time
-  --> $DIR/borrowck-union-borrow.rs:75:24
-   |
-LL |             let rma = &mut u.a;
-   |                       -------- first mutable borrow occurs here
-LL |             let rma2 = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable more than once at a time
-   |                        ^^^^^^^^ second mutable borrow occurs here
-LL |                                  //[mir]~^ ERROR cannot borrow `u.a` as mutable more than once at a time
-LL |             drop(rma);
-   |                  --- first borrow later used here
-
-error[E0506]: cannot assign to `u.a` because it is borrowed
-  --> $DIR/borrowck-union-borrow.rs:81:13
-   |
-LL |             let rma = &mut u.a;
-   |                       -------- borrow of `u.a` occurs here
-LL |             u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed
-   |             ^^^^^^^ assignment to borrowed `u.a` occurs here
-LL |                      //[mir]~^ ERROR cannot assign to `u.a` because it is borrowed
-LL |             drop(rma);
-   |                  --- borrow later used here
-
-error[E0502]: cannot borrow `u.b` as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-union-borrow.rs:88:22
-   |
-LL |             let rma = &mut u.a;
-   |                       -------- mutable borrow occurs here
-LL |             let rb = &u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
-   |                      ^^^^ immutable borrow occurs here
-LL |                            //[mir]~^ ERROR cannot borrow `u.b` as immutable because it is also borrowed as mutable
-LL |             drop(rma);
-   |                  --- mutable borrow later used here
-
-error[E0503]: cannot use `u.b` because it was mutably borrowed
-  --> $DIR/borrowck-union-borrow.rs:94:21
-   |
-LL |             let ra = &mut u.a;
-   |                      -------- borrow of `u.a` occurs here
-LL |             let b = u.b; //[ast]~ ERROR cannot use `u.b` because it was mutably borrowed
-   |                     ^^^ use of borrowed `u.a`
-...
-LL |             drop(ra);
-   |                  -- borrow later used here
-
-error[E0499]: cannot borrow `u.b` as mutable more than once at a time
-  --> $DIR/borrowck-union-borrow.rs:101:24
-   |
-LL |             let rma = &mut u.a;
-   |                       -------- first mutable borrow occurs here
-LL |             let rmb2 = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
-   |                        ^^^^^^^^ second mutable borrow occurs here
-LL |                                  //[mir]~^ ERROR cannot borrow `u.b` as mutable more than once at a time
-LL |             drop(rma);
-   |                  --- first borrow later used here
-
-error[E0506]: cannot assign to `u.b` because it is borrowed
-  --> $DIR/borrowck-union-borrow.rs:107:13
-   |
-LL |             let rma = &mut u.a;
-   |                       -------- borrow of `u.b` occurs here
-LL |             u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed
-   |             ^^^^^^^ assignment to borrowed `u.b` occurs here
-LL |                      //[mir]~^ ERROR cannot assign to `u.b` because it is borrowed
-LL |             drop(rma);
-   |                  --- borrow later used here
-
-error: aborting due to 12 previous errors
-
-Some errors occurred: E0499, E0502, E0503, E0506.
-For more information about an error, try `rustc --explain E0499`.
diff --git a/src/test/ui/borrowck/borrowck-union-borrow.ast.stderr b/src/test/ui/borrowck/borrowck-union-borrow.ast.stderr
deleted file mode 100644 (file)
index 0f786b8..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-error[E0502]: cannot borrow `u.a` as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-union-borrow.rs:27:28
-   |
-LL |             let ra = &u.a;
-   |                       --- immutable borrow occurs here
-LL |             let rma = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
-   |                            ^^^ mutable borrow occurs here
-...
-LL |         }
-   |         - immutable borrow ends here
-
-error[E0506]: cannot assign to `u.a` because it is borrowed
-  --> $DIR/borrowck-union-borrow.rs:33:13
-   |
-LL |             let ra = &u.a;
-   |                       --- borrow of `u.a` occurs here
-LL |             u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed
-   |             ^^^^^^^ assignment to borrowed `u.a` occurs here
-
-error[E0502]: cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
-  --> $DIR/borrowck-union-borrow.rs:50:28
-   |
-LL |             let ra = &u.a;
-   |                       --- immutable borrow occurs here (via `u.a`)
-LL |             let rmb = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
-   |                            ^^^ mutable borrow occurs here (via `u.b`)
-...
-LL |         }
-   |         - immutable borrow ends here
-
-error[E0506]: cannot assign to `u.b` because it is borrowed
-  --> $DIR/borrowck-union-borrow.rs:56:13
-   |
-LL |             let ra = &u.a;
-   |                       --- borrow of `u.b` occurs here
-LL |             u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed
-   |             ^^^^^^^ assignment to borrowed `u.b` occurs here
-
-error[E0502]: cannot borrow `u.a` as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-union-borrow.rs:63:23
-   |
-LL |             let rma = &mut u.a;
-   |                            --- mutable borrow occurs here
-LL |             let ra = &u.a; //[ast]~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
-   |                       ^^^ immutable borrow occurs here
-...
-LL |         }
-   |         - mutable borrow ends here
-
-error[E0503]: cannot use `u.a` because it was mutably borrowed
-  --> $DIR/borrowck-union-borrow.rs:69:17
-   |
-LL |             let ra = &mut u.a;
-   |                           --- borrow of `u.a` occurs here
-LL |             let a = u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
-   |                 ^ use of borrowed `u.a`
-
-error[E0499]: cannot borrow `u.a` as mutable more than once at a time
-  --> $DIR/borrowck-union-borrow.rs:75:29
-   |
-LL |             let rma = &mut u.a;
-   |                            --- first mutable borrow occurs here
-LL |             let rma2 = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable more than once at a time
-   |                             ^^^ second mutable borrow occurs here
-...
-LL |         }
-   |         - first borrow ends here
-
-error[E0506]: cannot assign to `u.a` because it is borrowed
-  --> $DIR/borrowck-union-borrow.rs:81:13
-   |
-LL |             let rma = &mut u.a;
-   |                            --- borrow of `u.a` occurs here
-LL |             u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed
-   |             ^^^^^^^ assignment to borrowed `u.a` occurs here
-
-error[E0502]: cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
-  --> $DIR/borrowck-union-borrow.rs:88:23
-   |
-LL |             let rma = &mut u.a;
-   |                            --- mutable borrow occurs here (via `u.a`)
-LL |             let rb = &u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
-   |                       ^^^ immutable borrow occurs here (via `u.b`)
-...
-LL |         }
-   |         - mutable borrow ends here
-
-error[E0503]: cannot use `u.b` because it was mutably borrowed
-  --> $DIR/borrowck-union-borrow.rs:94:17
-   |
-LL |             let ra = &mut u.a;
-   |                           --- borrow of `u.a` occurs here
-LL |             let b = u.b; //[ast]~ ERROR cannot use `u.b` because it was mutably borrowed
-   |                 ^ use of borrowed `u.a`
-
-error[E0499]: cannot borrow `u` (via `u.b`) as mutable more than once at a time
-  --> $DIR/borrowck-union-borrow.rs:101:29
-   |
-LL |             let rma = &mut u.a;
-   |                            --- first mutable borrow occurs here (via `u.a`)
-LL |             let rmb2 = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
-   |                             ^^^ second mutable borrow occurs here (via `u.b`)
-...
-LL |         }
-   |         - first borrow ends here
-
-error[E0506]: cannot assign to `u.b` because it is borrowed
-  --> $DIR/borrowck-union-borrow.rs:107:13
-   |
-LL |             let rma = &mut u.a;
-   |                            --- borrow of `u.b` occurs here
-LL |             u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed
-   |             ^^^^^^^ assignment to borrowed `u.b` occurs here
-
-error: aborting due to 12 previous errors
-
-Some errors occurred: E0499, E0502, E0503, E0506.
-For more information about an error, try `rustc --explain E0499`.
diff --git a/src/test/ui/borrowck/borrowck-union-borrow.nll.stderr b/src/test/ui/borrowck/borrowck-union-borrow.nll.stderr
new file mode 100644 (file)
index 0000000..5cba30b
--- /dev/null
@@ -0,0 +1,131 @@
+error[E0502]: cannot borrow `u.a` as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-union-borrow.rs:25:23
+   |
+LL |             let ra = &u.a;
+   |                      ---- immutable borrow occurs here
+LL |             let rma = &mut u.a; //~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
+   |                       ^^^^^^^^ mutable borrow occurs here
+LL |             drop(ra);
+   |                  -- immutable borrow later used here
+
+error[E0506]: cannot assign to `u.a` because it is borrowed
+  --> $DIR/borrowck-union-borrow.rs:30:13
+   |
+LL |             let ra = &u.a;
+   |                      ---- borrow of `u.a` occurs here
+LL |             u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
+   |             ^^^^^^^ assignment to borrowed `u.a` occurs here
+LL |             drop(ra);
+   |                  -- borrow later used here
+
+error[E0502]: cannot borrow `u` (via `u.b`) as mutable because it is also borrowed as immutable (via `u.a`)
+  --> $DIR/borrowck-union-borrow.rs:46:23
+   |
+LL |             let ra = &u.a;
+   |                      ---- immutable borrow occurs here (via `u.a`)
+LL |             let rmb = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
+   |                       ^^^^^^^^ mutable borrow of `u.b` -- which overlaps with `u.a` -- occurs here
+LL |             drop(ra);
+   |                  -- immutable borrow later used here
+   |
+   = note: `u.b` is a field of the union `U`, so it overlaps the field `u.a`
+
+error[E0506]: cannot assign to `u.b` because it is borrowed
+  --> $DIR/borrowck-union-borrow.rs:51:13
+   |
+LL |             let ra = &u.a;
+   |                      ---- borrow of `u.b` occurs here
+LL |             u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
+   |             ^^^^^^^ assignment to borrowed `u.b` occurs here
+LL |             drop(ra);
+   |                  -- borrow later used here
+
+error[E0502]: cannot borrow `u.a` as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-union-borrow.rs:57:22
+   |
+LL |             let rma = &mut u.a;
+   |                       -------- mutable borrow occurs here
+LL |             let ra = &u.a; //~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
+   |                      ^^^^ immutable borrow occurs here
+LL |             drop(rma);
+   |                  --- mutable borrow later used here
+
+error[E0503]: cannot use `u.a` because it was mutably borrowed
+  --> $DIR/borrowck-union-borrow.rs:62:21
+   |
+LL |             let ra = &mut u.a;
+   |                      -------- borrow of `u.a` occurs here
+LL |             let a = u.a; //~ ERROR cannot use `u.a` because it was mutably borrowed
+   |                     ^^^ use of borrowed `u.a`
+LL |             drop(ra);
+   |                  -- borrow later used here
+
+error[E0499]: cannot borrow `u.a` as mutable more than once at a time
+  --> $DIR/borrowck-union-borrow.rs:67:24
+   |
+LL |             let rma = &mut u.a;
+   |                       -------- first mutable borrow occurs here
+LL |             let rma2 = &mut u.a; //~ ERROR cannot borrow `u.a` as mutable more than once at a time
+   |                        ^^^^^^^^ second mutable borrow occurs here
+LL |             drop(rma);
+   |                  --- first borrow later used here
+
+error[E0506]: cannot assign to `u.a` because it is borrowed
+  --> $DIR/borrowck-union-borrow.rs:72:13
+   |
+LL |             let rma = &mut u.a;
+   |                       -------- borrow of `u.a` occurs here
+LL |             u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
+   |             ^^^^^^^ assignment to borrowed `u.a` occurs here
+LL |             drop(rma);
+   |                  --- borrow later used here
+
+error[E0502]: cannot borrow `u` (via `u.b`) as immutable because it is also borrowed as mutable (via `u.a`)
+  --> $DIR/borrowck-union-borrow.rs:78:22
+   |
+LL |             let rma = &mut u.a;
+   |                       -------- mutable borrow occurs here (via `u.a`)
+LL |             let rb = &u.b; //~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
+   |                      ^^^^ immutable borrow of `u.b` -- which overlaps with `u.a` -- occurs here
+LL |             drop(rma);
+   |                  --- mutable borrow later used here
+   |
+   = note: `u.b` is a field of the union `U`, so it overlaps the field `u.a`
+
+error[E0503]: cannot use `u.b` because it was mutably borrowed
+  --> $DIR/borrowck-union-borrow.rs:83:21
+   |
+LL |             let ra = &mut u.a;
+   |                      -------- borrow of `u.a` occurs here
+LL |             let b = u.b; //~ ERROR cannot use `u.b` because it was mutably borrowed
+   |                     ^^^ use of borrowed `u.a`
+LL | 
+LL |             drop(ra);
+   |                  -- borrow later used here
+
+error[E0499]: cannot borrow `u` (via `u.b`) as mutable more than once at a time
+  --> $DIR/borrowck-union-borrow.rs:89:24
+   |
+LL |             let rma = &mut u.a;
+   |                       -------- first mutable borrow occurs here (via `u.a`)
+LL |             let rmb2 = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
+   |                        ^^^^^^^^ second mutable borrow occurs here (via `u.b`)
+LL |             drop(rma);
+   |                  --- first borrow later used here
+   |
+   = note: `u.b` is a field of the union `U`, so it overlaps the field `u.a`
+
+error[E0506]: cannot assign to `u.b` because it is borrowed
+  --> $DIR/borrowck-union-borrow.rs:94:13
+   |
+LL |             let rma = &mut u.a;
+   |                       -------- borrow of `u.b` occurs here
+LL |             u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
+   |             ^^^^^^^ assignment to borrowed `u.b` occurs here
+LL |             drop(rma);
+   |                  --- borrow later used here
+
+error: aborting due to 12 previous errors
+
+Some errors occurred: E0499, E0502, E0503, E0506.
+For more information about an error, try `rustc --explain E0499`.
index 62647a2f5e85e93071218081a1c0d3fa1e8c8f71..8afc0be8b55c523800d0fc0cd3000a1f6cb71a74 100644 (file)
@@ -1,6 +1,4 @@
 // ignore-tidy-linelength
-// revisions: ast mir
-//[mir]compile-flags: -Z borrowck=mir
 
 #[derive(Clone, Copy)]
 union U {
@@ -24,14 +22,12 @@ fn main() {
         }
         {
             let ra = &u.a;
-            let rma = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
-                                //[mir]~^ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
+            let rma = &mut u.a; //~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
             drop(ra);
         }
         {
             let ra = &u.a;
-            u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed
-                     //[mir]~^ ERROR cannot assign to `u.a` because it is borrowed
+            u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
             drop(ra);
         }
         // Imm borrow, other field
@@ -47,65 +43,55 @@ fn main() {
         }
         {
             let ra = &u.a;
-            let rmb = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
-                                //[mir]~^ ERROR cannot borrow `u.b` as mutable because it is also borrowed as immutable
+            let rmb = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
             drop(ra);
         }
         {
             let ra = &u.a;
-            u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed
-                     //[mir]~^ ERROR cannot assign to `u.b` because it is borrowed
+            u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
             drop(ra);
         }
         // Mut borrow, same field
         {
             let rma = &mut u.a;
-            let ra = &u.a; //[ast]~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
-                         //[mir]~^ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
+            let ra = &u.a; //~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
             drop(rma);
         }
         {
             let ra = &mut u.a;
-            let a = u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
-                         //[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed
+            let a = u.a; //~ ERROR cannot use `u.a` because it was mutably borrowed
             drop(ra);
         }
         {
             let rma = &mut u.a;
-            let rma2 = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable more than once at a time
-                                 //[mir]~^ ERROR cannot borrow `u.a` as mutable more than once at a time
+            let rma2 = &mut u.a; //~ ERROR cannot borrow `u.a` as mutable more than once at a time
             drop(rma);
         }
         {
             let rma = &mut u.a;
-            u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed
-                     //[mir]~^ ERROR cannot assign to `u.a` because it is borrowed
+            u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
             drop(rma);
         }
         // Mut borrow, other field
         {
             let rma = &mut u.a;
-            let rb = &u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
-                           //[mir]~^ ERROR cannot borrow `u.b` as immutable because it is also borrowed as mutable
+            let rb = &u.b; //~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
             drop(rma);
         }
         {
             let ra = &mut u.a;
-            let b = u.b; //[ast]~ ERROR cannot use `u.b` because it was mutably borrowed
-                         //[mir]~^ ERROR cannot use `u.b` because it was mutably borrowed
+            let b = u.b; //~ ERROR cannot use `u.b` because it was mutably borrowed
 
             drop(ra);
         }
         {
             let rma = &mut u.a;
-            let rmb2 = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
-                                 //[mir]~^ ERROR cannot borrow `u.b` as mutable more than once at a time
+            let rmb2 = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
             drop(rma);
         }
         {
             let rma = &mut u.a;
-            u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed
-                     //[mir]~^ ERROR cannot assign to `u.b` because it is borrowed
+            u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
             drop(rma);
         }
     }
diff --git a/src/test/ui/borrowck/borrowck-union-borrow.stderr b/src/test/ui/borrowck/borrowck-union-borrow.stderr
new file mode 100644 (file)
index 0000000..ef6a331
--- /dev/null
@@ -0,0 +1,118 @@
+error[E0502]: cannot borrow `u.a` as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-union-borrow.rs:25:28
+   |
+LL |             let ra = &u.a;
+   |                       --- immutable borrow occurs here
+LL |             let rma = &mut u.a; //~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
+   |                            ^^^ mutable borrow occurs here
+LL |             drop(ra);
+LL |         }
+   |         - immutable borrow ends here
+
+error[E0506]: cannot assign to `u.a` because it is borrowed
+  --> $DIR/borrowck-union-borrow.rs:30:13
+   |
+LL |             let ra = &u.a;
+   |                       --- borrow of `u.a` occurs here
+LL |             u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
+   |             ^^^^^^^ assignment to borrowed `u.a` occurs here
+
+error[E0502]: cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
+  --> $DIR/borrowck-union-borrow.rs:46:28
+   |
+LL |             let ra = &u.a;
+   |                       --- immutable borrow occurs here (via `u.a`)
+LL |             let rmb = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
+   |                            ^^^ mutable borrow of `u.b` -- which overlaps with `u.a` -- occurs here
+LL |             drop(ra);
+LL |         }
+   |         - immutable borrow ends here
+
+error[E0506]: cannot assign to `u.b` because it is borrowed
+  --> $DIR/borrowck-union-borrow.rs:51:13
+   |
+LL |             let ra = &u.a;
+   |                       --- borrow of `u.b` occurs here
+LL |             u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
+   |             ^^^^^^^ assignment to borrowed `u.b` occurs here
+
+error[E0502]: cannot borrow `u.a` as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-union-borrow.rs:57:23
+   |
+LL |             let rma = &mut u.a;
+   |                            --- mutable borrow occurs here
+LL |             let ra = &u.a; //~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
+   |                       ^^^ immutable borrow occurs here
+LL |             drop(rma);
+LL |         }
+   |         - mutable borrow ends here
+
+error[E0503]: cannot use `u.a` because it was mutably borrowed
+  --> $DIR/borrowck-union-borrow.rs:62:17
+   |
+LL |             let ra = &mut u.a;
+   |                           --- borrow of `u.a` occurs here
+LL |             let a = u.a; //~ ERROR cannot use `u.a` because it was mutably borrowed
+   |                 ^ use of borrowed `u.a`
+
+error[E0499]: cannot borrow `u.a` as mutable more than once at a time
+  --> $DIR/borrowck-union-borrow.rs:67:29
+   |
+LL |             let rma = &mut u.a;
+   |                            --- first mutable borrow occurs here
+LL |             let rma2 = &mut u.a; //~ ERROR cannot borrow `u.a` as mutable more than once at a time
+   |                             ^^^ second mutable borrow occurs here
+LL |             drop(rma);
+LL |         }
+   |         - first borrow ends here
+
+error[E0506]: cannot assign to `u.a` because it is borrowed
+  --> $DIR/borrowck-union-borrow.rs:72:13
+   |
+LL |             let rma = &mut u.a;
+   |                            --- borrow of `u.a` occurs here
+LL |             u.a = 1; //~ ERROR cannot assign to `u.a` because it is borrowed
+   |             ^^^^^^^ assignment to borrowed `u.a` occurs here
+
+error[E0502]: cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
+  --> $DIR/borrowck-union-borrow.rs:78:23
+   |
+LL |             let rma = &mut u.a;
+   |                            --- mutable borrow occurs here (via `u.a`)
+LL |             let rb = &u.b; //~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
+   |                       ^^^ immutable borrow of `u.b` -- which overlaps with `u.a` -- occurs here
+LL |             drop(rma);
+LL |         }
+   |         - mutable borrow ends here
+
+error[E0503]: cannot use `u.b` because it was mutably borrowed
+  --> $DIR/borrowck-union-borrow.rs:83:17
+   |
+LL |             let ra = &mut u.a;
+   |                           --- borrow of `u.a` occurs here
+LL |             let b = u.b; //~ ERROR cannot use `u.b` because it was mutably borrowed
+   |                 ^ use of borrowed `u.a`
+
+error[E0499]: cannot borrow `u` (via `u.b`) as mutable more than once at a time
+  --> $DIR/borrowck-union-borrow.rs:89:29
+   |
+LL |             let rma = &mut u.a;
+   |                            --- first mutable borrow occurs here (via `u.a`)
+LL |             let rmb2 = &mut u.b; //~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
+   |                             ^^^ second mutable borrow occurs here (via `u.b`)
+LL |             drop(rma);
+LL |         }
+   |         - first borrow ends here
+
+error[E0506]: cannot assign to `u.b` because it is borrowed
+  --> $DIR/borrowck-union-borrow.rs:94:13
+   |
+LL |             let rma = &mut u.a;
+   |                            --- borrow of `u.b` occurs here
+LL |             u.b = 1; //~ ERROR cannot assign to `u.b` because it is borrowed
+   |             ^^^^^^^ assignment to borrowed `u.b` occurs here
+
+error: aborting due to 12 previous errors
+
+Some errors occurred: E0499, E0502, E0503, E0506.
+For more information about an error, try `rustc --explain E0499`.
index d2f6c7510a91d415a8283d7531e9afff98182244..f1a2312490813a6672d005a94bafb9298dcda6ed 100644 (file)
@@ -13,44 +13,80 @@ error[E0010]: allocations are not allowed in statics
 LL | static STATIC11: Box<MyOwned> = box MyOwned;
    |                                 ^^^^^^^^^^^ allocation not allowed in statics
 
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/check-static-values-constraints.rs:79:37
+   |
+LL | static STATIC11: Box<MyOwned> = box MyOwned;
+   |                                     ^^^^^^^
+
 error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
-  --> $DIR/check-static-values-constraints.rs:89:32
+  --> $DIR/check-static-values-constraints.rs:90:32
    |
 LL |     field2: SafeEnum::Variant4("str".to_string())
    |                                ^^^^^^^^^^^^^^^^^
 
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:94:5
+  --> $DIR/check-static-values-constraints.rs:95:5
    |
 LL |     box MyOwned, //~ ERROR allocations are not allowed in statics
    |     ^^^^^^^^^^^ allocation not allowed in statics
 
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/check-static-values-constraints.rs:95:9
+   |
+LL |     box MyOwned, //~ ERROR allocations are not allowed in statics
+   |         ^^^^^^^
+
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:95:5
+  --> $DIR/check-static-values-constraints.rs:97:5
    |
 LL |     box MyOwned, //~ ERROR allocations are not allowed in statics
    |     ^^^^^^^^^^^ allocation not allowed in statics
 
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/check-static-values-constraints.rs:97:9
+   |
+LL |     box MyOwned, //~ ERROR allocations are not allowed in statics
+   |         ^^^^^^^
+
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:99:6
+  --> $DIR/check-static-values-constraints.rs:102:6
    |
 LL |     &box MyOwned, //~ ERROR allocations are not allowed in statics
    |      ^^^^^^^^^^^ allocation not allowed in statics
 
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/check-static-values-constraints.rs:102:10
+   |
+LL |     &box MyOwned, //~ ERROR allocations are not allowed in statics
+   |          ^^^^^^^
+
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:100:6
+  --> $DIR/check-static-values-constraints.rs:104:6
    |
 LL |     &box MyOwned, //~ ERROR allocations are not allowed in statics
    |      ^^^^^^^^^^^ allocation not allowed in statics
 
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/check-static-values-constraints.rs:104:10
+   |
+LL |     &box MyOwned, //~ ERROR allocations are not allowed in statics
+   |          ^^^^^^^
+
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:106:5
+  --> $DIR/check-static-values-constraints.rs:111:5
    |
 LL |     box 3;
    |     ^^^^^ allocation not allowed in statics
 
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/check-static-values-constraints.rs:111:9
+   |
+LL |     box 3;
+   |         ^
+
 error[E0507]: cannot move out of static item
-  --> $DIR/check-static-values-constraints.rs:110:45
+  --> $DIR/check-static-values-constraints.rs:116:45
    |
 LL |     let y = { static x: Box<isize> = box 3; x };
    |                                             ^
@@ -59,12 +95,18 @@ LL |     let y = { static x: Box<isize> = box 3; x };
    |                                             help: consider borrowing here: `&x`
 
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:110:38
+  --> $DIR/check-static-values-constraints.rs:116:38
    |
 LL |     let y = { static x: Box<isize> = box 3; x };
    |                                      ^^^^^ allocation not allowed in statics
 
-error: aborting due to 10 previous errors
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/check-static-values-constraints.rs:116:42
+   |
+LL |     let y = { static x: Box<isize> = box 3; x };
+   |                                          ^
+
+error: aborting due to 17 previous errors
 
-Some errors occurred: E0010, E0015, E0493, E0507.
+Some errors occurred: E0010, E0015, E0019, E0493, E0507.
 For more information about an error, try `rustc --explain E0010`.
index eb0fc39e1bf15f49e2df910b66a78d172272cb1a..acfb3b5e44bab041a8ded3504faab37c026ccb85 100644 (file)
@@ -78,6 +78,7 @@ fn drop(&mut self) {}
 
 static STATIC11: Box<MyOwned> = box MyOwned;
 //~^ ERROR allocations are not allowed in statics
+//~| ERROR static contains unimplemented expression type
 
 static mut STATIC12: UnsafeStruct = UnsafeStruct;
 
@@ -92,12 +93,16 @@ fn drop(&mut self) {}
 
 static STATIC15: &'static [Box<MyOwned>] = &[
     box MyOwned, //~ ERROR allocations are not allowed in statics
+    //~| ERROR contains unimplemented expression
     box MyOwned, //~ ERROR allocations are not allowed in statics
+    //~| ERROR contains unimplemented expression
 ];
 
 static STATIC16: (&'static Box<MyOwned>, &'static Box<MyOwned>) = (
     &box MyOwned, //~ ERROR allocations are not allowed in statics
+    //~| ERROR contains unimplemented expression
     &box MyOwned, //~ ERROR allocations are not allowed in statics
+    //~| ERROR contains unimplemented expression
 );
 
 static mut STATIC17: SafeEnum = SafeEnum::Variant1;
@@ -105,9 +110,11 @@ fn drop(&mut self) {}
 static STATIC19: Box<isize> =
     box 3;
 //~^ ERROR allocations are not allowed in statics
+    //~| ERROR contains unimplemented expression
 
 pub fn main() {
     let y = { static x: Box<isize> = box 3; x };
     //~^ ERROR allocations are not allowed in statics
-    //~^^ ERROR cannot move out of static item
+    //~| ERROR cannot move out of static item
+    //~| ERROR contains unimplemented expression
 }
index 450a9ba0c0d1135bb13f5053268bff2a05112e86..5b1f265c34aef5c94ff8f1d53394555c4db83e44 100644 (file)
@@ -13,55 +13,97 @@ error[E0010]: allocations are not allowed in statics
 LL | static STATIC11: Box<MyOwned> = box MyOwned;
    |                                 ^^^^^^^^^^^ allocation not allowed in statics
 
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/check-static-values-constraints.rs:79:37
+   |
+LL | static STATIC11: Box<MyOwned> = box MyOwned;
+   |                                     ^^^^^^^
+
 error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
-  --> $DIR/check-static-values-constraints.rs:89:32
+  --> $DIR/check-static-values-constraints.rs:90:32
    |
 LL |     field2: SafeEnum::Variant4("str".to_string())
    |                                ^^^^^^^^^^^^^^^^^
 
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:94:5
+  --> $DIR/check-static-values-constraints.rs:95:5
    |
 LL |     box MyOwned, //~ ERROR allocations are not allowed in statics
    |     ^^^^^^^^^^^ allocation not allowed in statics
 
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/check-static-values-constraints.rs:95:9
+   |
+LL |     box MyOwned, //~ ERROR allocations are not allowed in statics
+   |         ^^^^^^^
+
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:95:5
+  --> $DIR/check-static-values-constraints.rs:97:5
    |
 LL |     box MyOwned, //~ ERROR allocations are not allowed in statics
    |     ^^^^^^^^^^^ allocation not allowed in statics
 
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/check-static-values-constraints.rs:97:9
+   |
+LL |     box MyOwned, //~ ERROR allocations are not allowed in statics
+   |         ^^^^^^^
+
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:99:6
+  --> $DIR/check-static-values-constraints.rs:102:6
    |
 LL |     &box MyOwned, //~ ERROR allocations are not allowed in statics
    |      ^^^^^^^^^^^ allocation not allowed in statics
 
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/check-static-values-constraints.rs:102:10
+   |
+LL |     &box MyOwned, //~ ERROR allocations are not allowed in statics
+   |          ^^^^^^^
+
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:100:6
+  --> $DIR/check-static-values-constraints.rs:104:6
    |
 LL |     &box MyOwned, //~ ERROR allocations are not allowed in statics
    |      ^^^^^^^^^^^ allocation not allowed in statics
 
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/check-static-values-constraints.rs:104:10
+   |
+LL |     &box MyOwned, //~ ERROR allocations are not allowed in statics
+   |          ^^^^^^^
+
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:106:5
+  --> $DIR/check-static-values-constraints.rs:111:5
    |
 LL |     box 3;
    |     ^^^^^ allocation not allowed in statics
 
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/check-static-values-constraints.rs:111:9
+   |
+LL |     box 3;
+   |         ^
+
 error[E0507]: cannot move out of static item
-  --> $DIR/check-static-values-constraints.rs:110:45
+  --> $DIR/check-static-values-constraints.rs:116:45
    |
 LL |     let y = { static x: Box<isize> = box 3; x };
    |                                             ^ cannot move out of static item
 
 error[E0010]: allocations are not allowed in statics
-  --> $DIR/check-static-values-constraints.rs:110:38
+  --> $DIR/check-static-values-constraints.rs:116:38
    |
 LL |     let y = { static x: Box<isize> = box 3; x };
    |                                      ^^^^^ allocation not allowed in statics
 
-error: aborting due to 10 previous errors
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/check-static-values-constraints.rs:116:42
+   |
+LL |     let y = { static x: Box<isize> = box 3; x };
+   |                                          ^
+
+error: aborting due to 17 previous errors
 
-Some errors occurred: E0010, E0015, E0493, E0507.
+Some errors occurred: E0010, E0015, E0019, E0493, E0507.
 For more information about an error, try `rustc --explain E0010`.
index ed627600b0f5d39bdc2794d8a50d9ce10e5e2b84..b0ec55a9bc578cda297d39aaee4ef08388d18d85 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl<T> Remote for Pair<T,Cover<T>> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index 1a85887ae7bc47ece6da6c5e3a97a64a529a3813..ce2611270938d8c08b1c09bf799bf7221f2030e9 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl<T> Remote for Pair<Cover<T>,T> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index 8043b6702b07efb983cd4aa758be1b8a8b76591e..1c2030d8dfea8fdb4b661097bfb196a75e4c84cf 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl<T,U> Remote for Pair<Cover<T>,U> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index 756ab2b102b56d819d514fb90a2ead200bb3ff8b..2d1247e831ec4a943c55e34447a3cad3e6be918e 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Misc for dyn Fundamental<Local> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index 756ab2b102b56d819d514fb90a2ead200bb3ff8b..2d1247e831ec4a943c55e34447a3cad3e6be918e 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Misc for dyn Fundamental<Local> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index defbbbadd5598461f3be680663469a6edc8322a7..e870c267ce141e120d82b6e571e44ae43912ba87 100644 (file)
@@ -51,7 +51,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Copy for i32 {}
    | ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -60,7 +60,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Copy for (MyType, MyType) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -69,7 +69,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Copy for [MyType] {}
    | ^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -78,7 +78,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Copy for &'static [NotSync] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to 10 previous errors
index defbbbadd5598461f3be680663469a6edc8322a7..e870c267ce141e120d82b6e571e44ae43912ba87 100644 (file)
@@ -51,7 +51,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Copy for i32 {}
    | ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -60,7 +60,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Copy for (MyType, MyType) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -69,7 +69,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Copy for [MyType] {}
    | ^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -78,7 +78,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Copy for &'static [NotSync] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to 10 previous errors
index ca45c28ec2d7484393b95d6efedaa96474007c57..3ede8363d119e4a7cf11d72df92d016350881d0e 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | unsafe impl Send for (MyType, MyType) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `&'static NotSync`
@@ -19,7 +19,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | unsafe impl Send for [MyType] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -28,7 +28,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | unsafe impl Send for &'static [NotSync] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to 4 previous errors
index ca45c28ec2d7484393b95d6efedaa96474007c57..3ede8363d119e4a7cf11d72df92d016350881d0e 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | unsafe impl Send for (MyType, MyType) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `&'static NotSync`
@@ -19,7 +19,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | unsafe impl Send for [MyType] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -28,7 +28,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | unsafe impl Send for &'static [NotSync] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to 4 previous errors
index c9c7dd0ed66887edfcb537efc4c818e4705f5cf0..86a0996554d419e8d5be7f59925ad338f7d2b68c 100644 (file)
@@ -40,7 +40,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Sized for (MyType, MyType) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -49,7 +49,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Sized for [MyType] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -58,7 +58,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Sized for &'static [NotSync] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to 9 previous errors
index c9c7dd0ed66887edfcb537efc4c818e4705f5cf0..86a0996554d419e8d5be7f59925ad338f7d2b68c 100644 (file)
@@ -40,7 +40,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Sized for (MyType, MyType) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -49,7 +49,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Sized for [MyType] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -58,7 +58,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Sized for &'static [NotSync] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to 9 previous errors
index da5de461bf41b62df8ad37ac8035c2e47c69a0ca..e6dc17d95a24118e2c230e4763b4288604efbcf7 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl TheTrait<usize> for isize { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -13,7 +13,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl !Send for Vec<isize> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to 2 previous errors
index da5de461bf41b62df8ad37ac8035c2e47c69a0ca..e6dc17d95a24118e2c230e4763b4288604efbcf7 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl TheTrait<usize> for isize { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -13,7 +13,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl !Send for Vec<isize> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to 2 previous errors
index 0f2ec6f4ce0699d079c518744333b87abc9c2eca..a6fa609deb21449209d5f008a5af098c7b093680 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl<T> Remote for lib::Pair<T,Foo> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index 0c654ca41835d5f1c81a55eea2b38605d1395b00..e45cd78363ca72c11dbd28ad6ac61a3766870735 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl<T, U> Remote1<Pair<T, Local<U>>> for i32 { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index 9bddc15390212cb4b2674c9d049daae3aeca4d30..54d5f3058a85cba7b38a765f3b35108a041fc9f5 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl<T,U> Remote for Pair<T,Local<U>> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index 37859f7cfa285f4f413fc76295f0d65970344a47..6992aa7a0bdc641f7fc99a20cb227dbf9cff82c7 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl<T> Remote for Vec<Local<T>> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index 304aaaf36875ccd67327bbff67c991b571bd2e13..b35e7a8ba8bed60207a65f3c0c8d08e2438f8d3c 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Remote for Vec<Local> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index 304aaaf36875ccd67327bbff67c991b571bd2e13..b35e7a8ba8bed60207a65f3c0c8d08e2438f8d3c 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Remote for Vec<Local> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index 61c94c1c7cad78e0af42701e84080719377d7a62..e1f651493f67c1a6b03fbd085b09fcf4b66ec32c 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl lib::MyCopy for lib::MyStruct<MyType> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index 61c94c1c7cad78e0af42701e84080719377d7a62..e1f651493f67c1a6b03fbd085b09fcf4b66ec32c 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl lib::MyCopy for lib::MyStruct<MyType> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index 934e2fcb890e35b99f0b184210cf913c877f4ca4..171daa54861fed56635848940afccba179305802 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl lib::MyCopy for (MyType,) { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index 934e2fcb890e35b99f0b184210cf913c877f4ca4..171daa54861fed56635848940afccba179305802 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl lib::MyCopy for (MyType,) { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to previous error
index ec4ee80b498a57c6d8a31ff9bff4833a1106eec0..f1ab2f0f9461f696ff2b8803fa319e8febeba71e 100644 (file)
@@ -4,7 +4,6 @@
 // compile-pass
 
 #![warn(unused_must_use)]
-#![feature(cfg_attr_multi)]
 
 #[cfg_attr(any(), deprecated, must_use)]
 struct Struct {}
index 16813a7623c77f4273ca7ce0e31b83f80724b7f3..be762c56048d407713abe98cd54e6be2b040725a 100644 (file)
@@ -1,6 +1,5 @@
 // compile-flags: --cfg broken
 
-#![feature(cfg_attr_multi)]
 #![crate_type = "lib"]
 #![cfg_attr(broken, no_core, no_std)] //~ ERROR no_core is experimental
 
index f63e4f93dfcbd67b5bb2f588f334c28fc7943be8..8cdf4ec31e7fc033d4b68529cfc30d54c4eb4133 100644 (file)
@@ -1,5 +1,5 @@
 error[E0658]: no_core is experimental (see issue #29639)
-  --> $DIR/cfg-attr-multi-invalid-1.rs:5:21
+  --> $DIR/cfg-attr-multi-invalid-1.rs:4:21
    |
 LL | #![cfg_attr(broken, no_core, no_std)] //~ ERROR no_core is experimental
    |                     ^^^^^^^
index 39f8fc4b8b9f1f26143e8f62ef13daa0b08cc2b7..8a9e99d703c7027169cea885fdffd9e1de4803e7 100644 (file)
@@ -1,6 +1,5 @@
 // compile-flags: --cfg broken
 
-#![feature(cfg_attr_multi)]
 #![crate_type = "lib"]
 #![cfg_attr(broken, no_std, no_core)] //~ ERROR no_core is experimental
 
index 590720002237e13683b2f91d4f14562f7ae130c6..b3a3b0c0f97bdbf528c606bec8ba9623f22e923f 100644 (file)
@@ -1,5 +1,5 @@
 error[E0658]: no_core is experimental (see issue #29639)
-  --> $DIR/cfg-attr-multi-invalid-2.rs:5:29
+  --> $DIR/cfg-attr-multi-invalid-2.rs:4:29
    |
 LL | #![cfg_attr(broken, no_std, no_core)] //~ ERROR no_core is experimental
    |                             ^^^^^^^
index 68307a9c456b7b3eadf449e6492a53e5ab8eb1e0..86524e8bd28ffe32f2c33a601bbaa715abadaef8 100644 (file)
@@ -5,7 +5,6 @@
 // compile-pass
 
 #![warn(unused_must_use)]
-#![feature(cfg_attr_multi)]
 
 #[cfg_attr(all(), deprecated, must_use)]
 struct MustUseDeprecated {}
index 8b62587c6f8932c80f810f3894a04efdc336800a..3d14c1973979858856439d154409bffb3416c83e 100644 (file)
@@ -1,5 +1,5 @@
 warning: use of deprecated item 'MustUseDeprecated'
-  --> $DIR/cfg-attr-multi-true.rs:13:6
+  --> $DIR/cfg-attr-multi-true.rs:12:6
    |
 LL | impl MustUseDeprecated { //~ warning: use of deprecated item
    |      ^^^^^^^^^^^^^^^^^
@@ -7,25 +7,25 @@ LL | impl MustUseDeprecated { //~ warning: use of deprecated item
    = note: #[warn(deprecated)] on by default
 
 warning: use of deprecated item 'MustUseDeprecated'
-  --> $DIR/cfg-attr-multi-true.rs:20:5
+  --> $DIR/cfg-attr-multi-true.rs:19:5
    |
 LL |     MustUseDeprecated::new(); //~ warning: use of deprecated item
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated item 'MustUseDeprecated'
-  --> $DIR/cfg-attr-multi-true.rs:14:17
+  --> $DIR/cfg-attr-multi-true.rs:13:17
    |
 LL |     fn new() -> MustUseDeprecated { //~ warning: use of deprecated item
    |                 ^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated item 'MustUseDeprecated'
-  --> $DIR/cfg-attr-multi-true.rs:15:9
+  --> $DIR/cfg-attr-multi-true.rs:14:9
    |
 LL |         MustUseDeprecated {} //~ warning: use of deprecated item
    |         ^^^^^^^^^^^^^^^^^
 
 warning: unused `MustUseDeprecated` that must be used
-  --> $DIR/cfg-attr-multi-true.rs:20:5
+  --> $DIR/cfg-attr-multi-true.rs:19:5
    |
 LL |     MustUseDeprecated::new(); //~ warning: use of deprecated item
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
index eec0e8faca877b7f71a2537232861fa2a66fb628..93aef72220cc413d41c3d4cae363b83745535221 100644 (file)
@@ -1,7 +1,5 @@
 // Parse `cfg_attr` with varying numbers of attributes and trailing commas
 
-#![feature(cfg_attr_multi)]
-
 // Completely empty `cfg_attr` input
 #[cfg_attr()] //~ error: expected identifier, found `)`
 struct NoConfigurationPredicate;
index 553406b6dd83d25f11775a734c48838f1d580735..36c7c817cb33d067e2294b90b5f8402c4a63800c 100644 (file)
@@ -1,29 +1,29 @@
 error: expected identifier, found `)`
-  --> $DIR/cfg-attr-parse.rs:6:12
+  --> $DIR/cfg-attr-parse.rs:4:12
    |
 LL | #[cfg_attr()] //~ error: expected identifier, found `)`
    |            ^ expected identifier
 
 error: expected `,`, found `)`
-  --> $DIR/cfg-attr-parse.rs:10:17
+  --> $DIR/cfg-attr-parse.rs:8:17
    |
 LL | #[cfg_attr(all())] //~ error: expected `,`, found `)`
    |                 ^ expected `,`
 
 error: expected identifier, found `,`
-  --> $DIR/cfg-attr-parse.rs:18:18
+  --> $DIR/cfg-attr-parse.rs:16:18
    |
 LL | #[cfg_attr(all(),,)] //~ ERROR expected identifier
    |                  ^ expected identifier
 
 error: expected identifier, found `,`
-  --> $DIR/cfg-attr-parse.rs:30:28
+  --> $DIR/cfg-attr-parse.rs:28:28
    |
 LL | #[cfg_attr(all(), must_use,,)] //~ ERROR expected identifier
    |                            ^ expected identifier
 
 error: expected identifier, found `,`
-  --> $DIR/cfg-attr-parse.rs:42:40
+  --> $DIR/cfg-attr-parse.rs:40:40
    |
 LL | #[cfg_attr(all(), must_use, deprecated,,)] //~ ERROR expected identifier
    |                                        ^ expected identifier
diff --git a/src/test/ui/consts/const-block-non-item-statement-2.rs b/src/test/ui/consts/const-block-non-item-statement-2.rs
deleted file mode 100644 (file)
index 58a6cf6..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-const A: usize = { 1; 2 };
-//~^ ERROR statements in constants are unstable
-
-const B: usize = { { } 2 };
-//~^ ERROR statements in constants are unstable
-
-macro_rules! foo {
-    () => (()) //~ ERROR statements in constants are unstable
-}
-const C: usize = { foo!(); 2 };
-
-const D: usize = { let x = 4; 2 };
-//~^ ERROR let bindings in constants are unstable
-//~| ERROR statements in constants are unstable
-//~| ERROR let bindings in constants are unstable
-//~| ERROR statements in constants are unstable
-
-pub fn main() {}
diff --git a/src/test/ui/consts/const-block-non-item-statement-2.stderr b/src/test/ui/consts/const-block-non-item-statement-2.stderr
deleted file mode 100644 (file)
index e0c61a9..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement-2.rs:1:20
-   |
-LL | const A: usize = { 1; 2 };
-   |                    ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement-2.rs:4:20
-   |
-LL | const B: usize = { { } 2 };
-   |                    ^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement-2.rs:8:12
-   |
-LL |     () => (()) //~ ERROR statements in constants are unstable
-   |            ^^
-LL | }
-LL | const C: usize = { foo!(); 2 };
-   |                    ------- in this macro invocation
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement-2.rs:12:28
-   |
-LL | const D: usize = { let x = 4; 2 };
-   |                            ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement-2.rs:12:28
-   |
-LL | const D: usize = { let x = 4; 2 };
-   |                            ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement-2.rs:12:1
-   |
-LL | const D: usize = { let x = 4; 2 };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement-2.rs:12:1
-   |
-LL | const D: usize = { let x = 4; 2 };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error: aborting due to 7 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/consts/const-block-non-item-statement-3.rs b/src/test/ui/consts/const-block-non-item-statement-3.rs
deleted file mode 100644 (file)
index 8678409..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-type Array = [u32; {  let x = 2; 5 }];
-//~^ ERROR let bindings in constants are unstable
-//~| ERROR statements in constants are unstable
-//~| ERROR let bindings in constants are unstable
-//~| ERROR statements in constants are unstable
-
-pub fn main() {}
diff --git a/src/test/ui/consts/const-block-non-item-statement-3.stderr b/src/test/ui/consts/const-block-non-item-statement-3.stderr
deleted file mode 100644 (file)
index 0a549bc..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-error[E0658]: let bindings in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement-3.rs:1:31
-   |
-LL | type Array = [u32; {  let x = 2; 5 }];
-   |                               ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement-3.rs:1:31
-   |
-LL | type Array = [u32; {  let x = 2; 5 }];
-   |                               ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement-3.rs:1:20
-   |
-LL | type Array = [u32; {  let x = 2; 5 }];
-   |                    ^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement-3.rs:1:20
-   |
-LL | type Array = [u32; {  let x = 2; 5 }];
-   |                    ^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
index 2db9e2413e5b5f880d374e6e5748197ff1c4a555..5ecf9a049842d4a1631dff192f522b0b7e60277c 100644 (file)
@@ -1,9 +1,23 @@
+// compile-pass
+
 enum Foo {
     Bar = { let x = 1; 3 }
-    //~^ ERROR let bindings in constants are unstable
-    //~| ERROR statements in constants are unstable
-    //~| ERROR let bindings in constants are unstable
-    //~| ERROR statements in constants are unstable
 }
 
+
+const A: usize = { 1; 2 };
+
+const B: usize = { { } 2 };
+
+macro_rules! foo {
+    () => (())
+}
+
+const C: usize = { foo!(); 2 };
+
+const D: usize = { let x = 4; 2 };
+
+type Array = [u32; {  let x = 2; 5 }];
+type Array2 = [u32; { let mut x = 2; x = 3; x}];
+
 pub fn main() {}
diff --git a/src/test/ui/consts/const-block-non-item-statement.stderr b/src/test/ui/consts/const-block-non-item-statement.stderr
deleted file mode 100644 (file)
index f0d751e..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-error[E0658]: let bindings in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement.rs:2:21
-   |
-LL |     Bar = { let x = 1; 3 }
-   |                     ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement.rs:2:21
-   |
-LL |     Bar = { let x = 1; 3 }
-   |                     ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement.rs:2:11
-   |
-LL |     Bar = { let x = 1; 3 }
-   |           ^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/const-block-non-item-statement.rs:2:11
-   |
-LL |     Bar = { let x = 1; 3 }
-   |           ^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
index ba8d032367ef8841ef8a8fa8320a83506eb52cf2..4d3c714481a290984b67a31d8d688af363c08d07 100644 (file)
@@ -2,7 +2,6 @@
 // The test should never compile successfully
 
 #![feature(const_raw_ptr_deref)]
-#![feature(const_let)]
 
 use std::cell::UnsafeCell;
 
index 6ca9d688bd062e453882f3275925b79cdf4682a0..be1be6c060071cb8b240bbc6ac2fffd3e2a55a37 100644 (file)
@@ -1,5 +1,5 @@
 error[E0019]: static contains unimplemented expression type
-  --> $DIR/assign-to-static-within-other-static-2.rs:17:5
+  --> $DIR/assign-to-static-within-other-static-2.rs:16:5
    |
 LL |     *FOO.0.get() = 5; //~ ERROR contains unimplemented expression type
    |     ^^^^^^^^^^^^^^^^
index 9fe17bfc6a06e207694372f5fec99e45bcefb254..b4c416b1c55f040e3c921e5540e7c6ccf66abd41 100644 (file)
@@ -2,7 +2,6 @@
 // The test should never compile successfully
 
 #![feature(const_raw_ptr_deref)]
-#![feature(const_let)]
 
 use std::cell::UnsafeCell;
 
index 2ab9765305f47e4dff66380c508e55fd77cebbe9..31e49dc10ca60e845264f5dc23eca45bfd2bbbea 100644 (file)
@@ -1,5 +1,5 @@
 error: cannot mutate statics in the initializer of another static
-  --> $DIR/assign-to-static-within-other-static.rs:11:5
+  --> $DIR/assign-to-static-within-other-static.rs:10:5
    |
 LL |     FOO = 5; //~ ERROR cannot mutate statics in the initializer of another static
    |     ^^^^^^^
index 9e6952733bb0b0e624597e9fdd43da80f44f43d6..63321b9120076aedd3ef431a56f31da3135f2027 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_let)]
-
 fn main() {}
 
 struct FakeNeedsDrop;
index e128ca07d8659e552aceae29e0f05197a561b167..00de97e6fb3a027a3a119dc0ace1d746171a82d3 100644 (file)
@@ -1,11 +1,11 @@
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/const_let.rs:15:55
+  --> $DIR/const_let.rs:13:55
    |
 LL | const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x };
    |                                                       ^
 
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/const_let.rs:19:35
+  --> $DIR/const_let.rs:17:35
    |
 LL | const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); };
    |                                   ^
index 0d5530acc95827ad0bc70291eb4406da202a3dd2..a2a45af7cb086e1361c92fd1687f2835464e205e 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_let)]
-
 fn main() {
     // Tests the Collatz conjecture with an incorrect base case (0 instead of 1).
     // The value of `n` will loop indefinitely (4 - 2 - 1 - 4).
index 90d2159d7b5512da8b9a638f4f3960923fa61734..422c2bab6ea906567f4f805199568d45ce28ec9a 100644 (file)
@@ -1,5 +1,5 @@
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/infinite_loop.rs:9:9
+  --> $DIR/infinite_loop.rs:7:9
    |
 LL | /         while n != 0 { //~ ERROR constant contains unimplemented expression type
 LL | |             n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
@@ -8,7 +8,7 @@ LL | |         }
    | |_________^
 
 warning: Constant evaluating a complex constant, this might take some time
-  --> $DIR/infinite_loop.rs:6:18
+  --> $DIR/infinite_loop.rs:4:18
    |
 LL |       let _ = [(); {
    |  __________________^
@@ -21,7 +21,7 @@ LL | |     }];
    | |_____^
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/infinite_loop.rs:10:20
+  --> $DIR/infinite_loop.rs:8:20
    |
 LL |             n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
    |                    ^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate
index 2e3d6fb9e84befe4fece3c50e528039ae63d45eb..aafdd5fe61782fe8ed935182d35d72860e222988 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_let)]
-
 fn main() {
     let _ = [(); {
         //~^ WARNING Constant evaluating a complex constant, this might take some time
index 329ea8a21f989961593b0cf71552d0c6403bc309..4f1b2ab4c8f4625b3ae3808f2c4d8eec7ed5ba7e 100644 (file)
@@ -1,5 +1,5 @@
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/issue-52475.rs:8:9
+  --> $DIR/issue-52475.rs:6:9
    |
 LL | /         while n < 5 { //~ ERROR constant contains unimplemented expression type
 LL | |             n = (n + 1) % 5; //~ ERROR evaluation of constant value failed
@@ -8,7 +8,7 @@ LL | |         }
    | |_________^
 
 warning: Constant evaluating a complex constant, this might take some time
-  --> $DIR/issue-52475.rs:4:18
+  --> $DIR/issue-52475.rs:2:18
    |
 LL |       let _ = [(); {
    |  __________________^
@@ -21,7 +21,7 @@ LL | |     }];
    | |_____^
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/issue-52475.rs:9:17
+  --> $DIR/issue-52475.rs:7:17
    |
 LL |             n = (n + 1) % 5; //~ ERROR evaluation of constant value failed
    |                 ^^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate
index 62090f4180d36a38f7fc776932df0030279b240d..32f0062168b3d6648a5133e25588b5b8639260f1 100644 (file)
@@ -2,7 +2,6 @@
 // The test should never compile successfully
 
 #![feature(const_raw_ptr_deref)]
-#![feature(const_let)]
 
 use std::cell::UnsafeCell;
 
index 12d6e3be40a9945f3c6b3b3e54c2192510f03b74..9fad6868d2038e60cea295c8d52fb5a95df1f0d8 100644 (file)
@@ -1,11 +1,11 @@
 error[E0019]: static contains unimplemented expression type
-  --> $DIR/mod-static-with-const-fn.rs:19:5
+  --> $DIR/mod-static-with-const-fn.rs:18:5
    |
 LL |     *FOO.0.get() = 5;
    |     ^^^^^^^^^^^^^^^^
 
 error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
-  --> $DIR/mod-static-with-const-fn.rs:22:5
+  --> $DIR/mod-static-with-const-fn.rs:21:5
    |
 LL |     foo();
    |     ^^^^^
index 16df0c1b0cc0eb26ff0a57371dd0ffed576cbfc3..9b7bca6b72d61eeb6a9273312a649527c0aa3c41 100644 (file)
@@ -1,4 +1,4 @@
-#![feature(const_transmute,const_let)]
+#![feature(const_transmute)]
 #![allow(const_err)] // make sure we cannot allow away the errors tested here
 
 use std::mem;
index 7f818079a19d11a4f8e42ba5fc68e3f00a5d3565..dcf89f90e31da3e70aa1625c6921cc41424b5256 100644 (file)
@@ -1,17 +1,7 @@
-// test that certain things are disallowed in constant functions
+// compile-pass
 
-#![feature(const_fn)]
-
-// no destructuring
-const fn i((
-            a,
-            //~^ ERROR arguments of constant functions can only be immutable by-value bindings
-            b
-            //~^ ERROR arguments of constant functions can only be immutable by-value bindings
-           ): (u32, u32)) -> u32 {
+const fn i((a, b): (u32, u32)) -> u32 {
     a + b
-    //~^ ERROR let bindings in constant functions are unstable
-    //~| ERROR let bindings in constant functions are unstable
 }
 
 fn main() {}
diff --git a/src/test/ui/consts/const-fn-destructuring-arg.stderr b/src/test/ui/consts/const-fn-destructuring-arg.stderr
deleted file mode 100644 (file)
index db63e83..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-error[E0658]: arguments of constant functions can only be immutable by-value bindings (see issue #48821)
-  --> $DIR/const-fn-destructuring-arg.rs:7:13
-   |
-LL |             a,
-   |             ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: arguments of constant functions can only be immutable by-value bindings (see issue #48821)
-  --> $DIR/const-fn-destructuring-arg.rs:9:13
-   |
-LL |             b
-   |             ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in constant functions are unstable (see issue #48821)
-  --> $DIR/const-fn-destructuring-arg.rs:12:5
-   |
-LL |     a + b
-   |     ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in constant functions are unstable (see issue #48821)
-  --> $DIR/const-fn-destructuring-arg.rs:12:9
-   |
-LL |     a + b
-   |         ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
index fe672e7b3e6da5691c8556cba51e1d230a336b6a..085ff5c58e60c6c68f693ad5eec77ce2fdd75fae 100644 (file)
@@ -27,13 +27,9 @@ const fn get_Y_addr() -> &'static u32 {
 }
 
 const fn get() -> u32 {
-    let x = 22; //~ ERROR let bindings in constant functions are unstable
-//~^ ERROR statements in constant functions
-    let y = 44; //~ ERROR let bindings in constant functions are unstable
-//~^ ERROR statements in constant functions
+    let x = 22;
+    let y = 44;
     x + y
-//~^ ERROR let bindings in constant functions are unstable
-//~| ERROR let bindings in constant functions are unstable
 }
 
 fn main() {}
index 8cc4c38526238db76ffe555063cb7e17ca4e7989..2003b137c272b8b0ef3b084ccfc32c625235a731 100644 (file)
@@ -16,55 +16,7 @@ error[E0013]: constant functions cannot refer to statics, use a constant instead
 LL |     &Y
    |     ^^
 
-error[E0658]: let bindings in constant functions are unstable (see issue #48821)
-  --> $DIR/const-fn-not-safe-for-const.rs:30:13
-   |
-LL |     let x = 22; //~ ERROR let bindings in constant functions are unstable
-   |             ^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constant functions are unstable (see issue #48821)
-  --> $DIR/const-fn-not-safe-for-const.rs:30:13
-   |
-LL |     let x = 22; //~ ERROR let bindings in constant functions are unstable
-   |             ^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in constant functions are unstable (see issue #48821)
-  --> $DIR/const-fn-not-safe-for-const.rs:32:13
-   |
-LL |     let y = 44; //~ ERROR let bindings in constant functions are unstable
-   |             ^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constant functions are unstable (see issue #48821)
-  --> $DIR/const-fn-not-safe-for-const.rs:32:13
-   |
-LL |     let y = 44; //~ ERROR let bindings in constant functions are unstable
-   |             ^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in constant functions are unstable (see issue #48821)
-  --> $DIR/const-fn-not-safe-for-const.rs:34:5
-   |
-LL |     x + y
-   |     ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in constant functions are unstable (see issue #48821)
-  --> $DIR/const-fn-not-safe-for-const.rs:34:9
-   |
-LL |     x + y
-   |         ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error: aborting due to 9 previous errors
+error: aborting due to 3 previous errors
 
-Some errors occurred: E0013, E0015, E0658.
+Some errors occurred: E0013, E0015.
 For more information about an error, try `rustc --explain E0013`.
index aeac6c37dcbabbfade7932b28dfedd9fd87892ca..8ee029b6cc390295b00c512108a5fa1a4b8da7b1 100644 (file)
 
 use std::intrinsics;
 
-const SHR: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) };
+// The documentation of `unchecked_shl` states that it:
+//
+// Performs an unchecked left shift, resulting in undefined behavior when
+// y < 0 or y >= N, where N is the width of T in bits.
+//
+// So we check this for a few `y`.
+
+// unsigned types:
+
+const SHL_U8: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) };
+//~^ ERROR any use of this value will cause an error
+const SHL_U16: u16 = unsafe { intrinsics::unchecked_shl(5_u16, 16) };
+//~^ ERROR any use of this value will cause an error
+const SHL_U32: u32 = unsafe { intrinsics::unchecked_shl(5_u32, 32) };
+//~^ ERROR any use of this value will cause an error
+const SHL_U64: u64 = unsafe { intrinsics::unchecked_shl(5_u64, 64) };
+//~^ ERROR any use of this value will cause an error
+const SHL_U128: u128 = unsafe { intrinsics::unchecked_shl(5_u128, 128) };
+//~^ ERROR any use of this value will cause an error
+
+// signed types:
+
+const SHL_I8: i8 = unsafe { intrinsics::unchecked_shl(5_i8, 8) };
+//~^ ERROR any use of this value will cause an error
+const SHL_I16: i16 = unsafe { intrinsics::unchecked_shl(5_16, 16) };
+//~^ ERROR any use of this value will cause an error
+const SHL_I32: i32 = unsafe { intrinsics::unchecked_shl(5_i32, 32) };
+//~^ ERROR any use of this value will cause an error
+const SHL_I64: i64 = unsafe { intrinsics::unchecked_shl(5_i64, 64) };
+//~^ ERROR any use of this value will cause an error
+const SHL_I128: i128 = unsafe { intrinsics::unchecked_shl(5_i128, 128) };
+//~^ ERROR any use of this value will cause an error
+
+// and make sure we capture y < 0:
+
+const SHL_I8_NEG: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -1) };
+//~^ ERROR any use of this value will cause an error
+const SHL_I16_NEG: i16 = unsafe { intrinsics::unchecked_shl(5_16, -1) };
+//~^ ERROR any use of this value will cause an error
+const SHL_I32_NEG: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -1) };
+//~^ ERROR any use of this value will cause an error
+const SHL_I64_NEG: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -1) };
+//~^ ERROR any use of this value will cause an error
+const SHL_I128_NEG: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -1) };
+//~^ ERROR any use of this value will cause an error
+
+// and that there's no special relation to the value -1 by picking some
+// negative values at random:
+
+const SHL_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -6) };
+//~^ ERROR any use of this value will cause an error
+const SHL_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shl(5_16, -13) };
+//~^ ERROR any use of this value will cause an error
+const SHL_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -25) };
+//~^ ERROR any use of this value will cause an error
+const SHL_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -30) };
+//~^ ERROR any use of this value will cause an error
+const SHL_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -93) };
+//~^ ERROR any use of this value will cause an error
+
+// Repeat it all over for `unchecked_shr`
+
+// unsigned types:
+
+const SHR_U8: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) };
+//~^ ERROR any use of this value will cause an error
+const SHR_U16: u16 = unsafe { intrinsics::unchecked_shr(5_u16, 16) };
+//~^ ERROR any use of this value will cause an error
+const SHR_U32: u32 = unsafe { intrinsics::unchecked_shr(5_u32, 32) };
+//~^ ERROR any use of this value will cause an error
+const SHR_U64: u64 = unsafe { intrinsics::unchecked_shr(5_u64, 64) };
+//~^ ERROR any use of this value will cause an error
+const SHR_U128: u128 = unsafe { intrinsics::unchecked_shr(5_u128, 128) };
+//~^ ERROR any use of this value will cause an error
+
+// signed types:
+
+const SHR_I8: i8 = unsafe { intrinsics::unchecked_shr(5_i8, 8) };
+//~^ ERROR any use of this value will cause an error
+const SHR_I16: i16 = unsafe { intrinsics::unchecked_shr(5_16, 16) };
+//~^ ERROR any use of this value will cause an error
+const SHR_I32: i32 = unsafe { intrinsics::unchecked_shr(5_i32, 32) };
+//~^ ERROR any use of this value will cause an error
+const SHR_I64: i64 = unsafe { intrinsics::unchecked_shr(5_i64, 64) };
+//~^ ERROR any use of this value will cause an error
+const SHR_I128: i128 = unsafe { intrinsics::unchecked_shr(5_i128, 128) };
+//~^ ERROR any use of this value will cause an error
+
+// and make sure we capture y < 0:
+
+const SHR_I8_NEG: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -1) };
+//~^ ERROR any use of this value will cause an error
+const SHR_I16_NEG: i16 = unsafe { intrinsics::unchecked_shr(5_16, -1) };
+//~^ ERROR any use of this value will cause an error
+const SHR_I32_NEG: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -1) };
+//~^ ERROR any use of this value will cause an error
+const SHR_I64_NEG: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -1) };
+//~^ ERROR any use of this value will cause an error
+const SHR_I128_NEG: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -1) };
+//~^ ERROR any use of this value will cause an error
+
+// and that there's no special relation to the value -1 by picking some
+// negative values at random:
+
+const SHR_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -6) };
+//~^ ERROR any use of this value will cause an error
+const SHR_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shr(5_16, -13) };
+//~^ ERROR any use of this value will cause an error
+const SHR_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -25) };
+//~^ ERROR any use of this value will cause an error
+const SHR_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -30) };
 //~^ ERROR any use of this value will cause an error
-const SHL: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) };
+const SHR_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -93) };
 //~^ ERROR any use of this value will cause an error
 
-fn main() {
-}
+fn main() {}
index dd28cc4d533e9ee26d76096239657e676c7868f6..4382d9174b757bbf7bc3e883f3b453ae00168c9a 100644 (file)
 error: any use of this value will cause an error
-  --> $DIR/const-int-unchecked.rs:5:1
+  --> $DIR/const-int-unchecked.rs:14:1
    |
-LL | const SHR: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^
-   |                          |
-   |                          Overflowing shift by 8 in unchecked_shr
+LL | const SHL_U8: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^
+   |                             |
+   |                             Overflowing shift by 8 in unchecked_shl
    |
    = note: #[deny(const_err)] on by default
 
 error: any use of this value will cause an error
-  --> $DIR/const-int-unchecked.rs:7:1
+  --> $DIR/const-int-unchecked.rs:16:1
    |
-LL | const SHL: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^
-   |                          |
-   |                          Overflowing shift by 8 in unchecked_shl
+LL | const SHL_U16: u16 = unsafe { intrinsics::unchecked_shl(5_u16, 16) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                               |
+   |                               Overflowing shift by 16 in unchecked_shl
 
-error: aborting due to 2 previous errors
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:18:1
+   |
+LL | const SHL_U32: u32 = unsafe { intrinsics::unchecked_shl(5_u32, 32) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                               |
+   |                               Overflowing shift by 32 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:20:1
+   |
+LL | const SHL_U64: u64 = unsafe { intrinsics::unchecked_shl(5_u64, 64) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                               |
+   |                               Overflowing shift by 64 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:22:1
+   |
+LL | const SHL_U128: u128 = unsafe { intrinsics::unchecked_shl(5_u128, 128) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------------------^^^
+   |                                 |
+   |                                 Overflowing shift by 128 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:27:1
+   |
+LL | const SHL_I8: i8 = unsafe { intrinsics::unchecked_shl(5_i8, 8) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^
+   |                             |
+   |                             Overflowing shift by 8 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:29:1
+   |
+LL | const SHL_I16: i16 = unsafe { intrinsics::unchecked_shl(5_16, 16) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^
+   |                               |
+   |                               Overflowing shift by 16 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:31:1
+   |
+LL | const SHL_I32: i32 = unsafe { intrinsics::unchecked_shl(5_i32, 32) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                               |
+   |                               Overflowing shift by 32 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:33:1
+   |
+LL | const SHL_I64: i64 = unsafe { intrinsics::unchecked_shl(5_i64, 64) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                               |
+   |                               Overflowing shift by 64 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:35:1
+   |
+LL | const SHL_I128: i128 = unsafe { intrinsics::unchecked_shl(5_i128, 128) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------------------^^^
+   |                                 |
+   |                                 Overflowing shift by 128 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:40:1
+   |
+LL | const SHL_I8_NEG: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -1) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^
+   |                                 |
+   |                                 Overflowing shift by 255 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:42:1
+   |
+LL | const SHL_I16_NEG: i16 = unsafe { intrinsics::unchecked_shl(5_16, -1) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^
+   |                                   |
+   |                                   Overflowing shift by 65535 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:44:1
+   |
+LL | const SHL_I32_NEG: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -1) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                                   |
+   |                                   Overflowing shift by 4294967295 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:46:1
+   |
+LL | const SHL_I64_NEG: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -1) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                                   |
+   |                                   Overflowing shift by 18446744073709551615 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:48:1
+   |
+LL | const SHL_I128_NEG: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -1) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------------------------------^^^
+   |                                     |
+   |                                     Overflowing shift by 340282366920938463463374607431768211455 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:54:1
+   |
+LL | const SHL_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -6) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^
+   |                                        |
+   |                                        Overflowing shift by 250 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:56:1
+   |
+LL | const SHL_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shl(5_16, -13) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                                          |
+   |                                          Overflowing shift by 65523 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:58:1
+   |
+LL | const SHL_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -25) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------------------------------^^^
+   |                                          |
+   |                                          Overflowing shift by 4294967271 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:60:1
+   |
+LL | const SHL_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -30) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------------------------------^^^
+   |                                          |
+   |                                          Overflowing shift by 18446744073709551586 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:62:1
+   |
+LL | const SHL_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -93) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------------------^^^
+   |                                            |
+   |                                            Overflowing shift by 340282366920938463463374607431768211363 in unchecked_shl
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:69:1
+   |
+LL | const SHR_U8: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^
+   |                             |
+   |                             Overflowing shift by 8 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:71:1
+   |
+LL | const SHR_U16: u16 = unsafe { intrinsics::unchecked_shr(5_u16, 16) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                               |
+   |                               Overflowing shift by 16 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:73:1
+   |
+LL | const SHR_U32: u32 = unsafe { intrinsics::unchecked_shr(5_u32, 32) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                               |
+   |                               Overflowing shift by 32 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:75:1
+   |
+LL | const SHR_U64: u64 = unsafe { intrinsics::unchecked_shr(5_u64, 64) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                               |
+   |                               Overflowing shift by 64 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:77:1
+   |
+LL | const SHR_U128: u128 = unsafe { intrinsics::unchecked_shr(5_u128, 128) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------------------^^^
+   |                                 |
+   |                                 Overflowing shift by 128 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:82:1
+   |
+LL | const SHR_I8: i8 = unsafe { intrinsics::unchecked_shr(5_i8, 8) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^
+   |                             |
+   |                             Overflowing shift by 8 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:84:1
+   |
+LL | const SHR_I16: i16 = unsafe { intrinsics::unchecked_shr(5_16, 16) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^
+   |                               |
+   |                               Overflowing shift by 16 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:86:1
+   |
+LL | const SHR_I32: i32 = unsafe { intrinsics::unchecked_shr(5_i32, 32) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                               |
+   |                               Overflowing shift by 32 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:88:1
+   |
+LL | const SHR_I64: i64 = unsafe { intrinsics::unchecked_shr(5_i64, 64) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                               |
+   |                               Overflowing shift by 64 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:90:1
+   |
+LL | const SHR_I128: i128 = unsafe { intrinsics::unchecked_shr(5_i128, 128) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------------------^^^
+   |                                 |
+   |                                 Overflowing shift by 128 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:95:1
+   |
+LL | const SHR_I8_NEG: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -1) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^
+   |                                 |
+   |                                 Overflowing shift by 255 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:97:1
+   |
+LL | const SHR_I16_NEG: i16 = unsafe { intrinsics::unchecked_shr(5_16, -1) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^
+   |                                   |
+   |                                   Overflowing shift by 65535 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:99:1
+   |
+LL | const SHR_I32_NEG: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -1) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                                   |
+   |                                   Overflowing shift by 4294967295 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:101:1
+   |
+LL | const SHR_I64_NEG: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -1) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                                   |
+   |                                   Overflowing shift by 18446744073709551615 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:103:1
+   |
+LL | const SHR_I128_NEG: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -1) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------------------------------^^^
+   |                                     |
+   |                                     Overflowing shift by 340282366920938463463374607431768211455 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:109:1
+   |
+LL | const SHR_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -6) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^
+   |                                        |
+   |                                        Overflowing shift by 250 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:111:1
+   |
+LL | const SHR_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shr(5_16, -13) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^
+   |                                          |
+   |                                          Overflowing shift by 65523 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:113:1
+   |
+LL | const SHR_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -25) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------------------------------^^^
+   |                                          |
+   |                                          Overflowing shift by 4294967271 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:115:1
+   |
+LL | const SHR_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -30) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------------------------------^^^
+   |                                          |
+   |                                          Overflowing shift by 18446744073709551586 in unchecked_shr
+
+error: any use of this value will cause an error
+  --> $DIR/const-int-unchecked.rs:117:1
+   |
+LL | const SHR_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -93) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------------------^^^
+   |                                            |
+   |                                            Overflowing shift by 340282366920938463463374607431768211363 in unchecked_shr
+
+error: aborting due to 40 previous errors
 
index a3c53a451e106732063ff34e2a8f89fc11fba354..0b09b8469fd752f206b6dffa945d78dfffeef1fd 100644 (file)
@@ -1,7 +1,5 @@
 // compile-pass
 
-#![feature(const_let)]
-
 struct S(i32);
 
 const A: () = {
index 0de7396501adc053762a4e2a6b15b06cccd1bdd9..1c44237e49b7a2f20c0e3506df439630c4f4fa86 100644 (file)
@@ -1,8 +1,5 @@
 // compile-pass
 
-#![feature(const_let)]
-#![feature(const_fn)]
-
 pub struct AA {
     pub data: [u8; 10],
 }
index c2ed6cd85ab5c176b795a4ad4d8eba8453cbd8da..cbe73923e9c424b961abec029bb092733899827f 100644 (file)
@@ -1,4 +1,3 @@
-#![feature(const_let)]
 #![feature(const_fn)]
 
 struct S {
@@ -18,6 +17,15 @@ const fn foo(&mut self, x: u32) {
     s
 };
 
+type Array = [u32; {
+    let mut x = 2;
+    let y = &mut x;
+//~^ ERROR references in constants may only refer to immutable values
+    *y = 42;
+//~^ ERROR constant contains unimplemented expression type
+    *y
+}];
+
 fn main() {
     assert_eq!(FOO.state, 3);
 }
index 0f294616d255c3f73c7eba1f3b2687a53702427e..6649fb997cce471ef79b22c267ebfd51abba6a90 100644 (file)
@@ -1,16 +1,28 @@
 error[E0019]: constant function contains unimplemented expression type
-  --> $DIR/const_let_assign3.rs:10:9
+  --> $DIR/const_let_assign3.rs:9:9
    |
 LL |         self.state = x;
    |         ^^^^^^^^^^^^^^
 
 error[E0017]: references in constants may only refer to immutable values
-  --> $DIR/const_let_assign3.rs:17:5
+  --> $DIR/const_let_assign3.rs:16:5
    |
 LL |     s.foo(3); //~ ERROR references in constants may only refer to immutable values
    |     ^ constants require immutable values
 
-error: aborting due to 2 previous errors
+error[E0017]: references in constants may only refer to immutable values
+  --> $DIR/const_let_assign3.rs:22:13
+   |
+LL |     let y = &mut x;
+   |             ^^^^^^ constants require immutable values
+
+error[E0019]: constant contains unimplemented expression type
+  --> $DIR/const_let_assign3.rs:24:5
+   |
+LL |     *y = 42;
+   |     ^^^^^^^
+
+error: aborting due to 4 previous errors
 
 Some errors occurred: E0017, E0019.
 For more information about an error, try `rustc --explain E0017`.
index 8739cb80e9403cf6d780d51f9d01931f8b9ca511..a2364c392f26bd945bf232a315f343d498197bdf 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_let, const_fn)]
-
 // run-pass
 
 struct Foo<T>(T);
index 2c7262df367a399d9a10d1ccfc592519c41a7f22..c48f54e567b2cb4f651a601f0badcc7776d291c0 100644 (file)
@@ -1,6 +1,6 @@
 // compile-pass
 
-#![feature(const_let, const_fn)]
+#![feature(const_fn)]
 
 struct Foo<T>(T);
 struct Bar<T> { x: T }
diff --git a/src/test/ui/consts/const_let_irrefutable.rs b/src/test/ui/consts/const_let_irrefutable.rs
new file mode 100644 (file)
index 0000000..424a16f
--- /dev/null
@@ -0,0 +1,11 @@
+// compile-pass
+
+fn main() {}
+
+const fn tup((a, b): (i32, i32)) -> i32 {
+    a + b
+}
+
+const fn array([a, b]: [i32; 2]) -> i32 {
+    a + b
+}
diff --git a/src/test/ui/consts/const_let_refutable.rs b/src/test/ui/consts/const_let_refutable.rs
new file mode 100644 (file)
index 0000000..345f682
--- /dev/null
@@ -0,0 +1,5 @@
+fn main() {}
+
+const fn slice([a, b]: &[i32]) -> i32 { //~ ERROR refutable pattern in function argument
+    a + b
+}
diff --git a/src/test/ui/consts/const_let_refutable.stderr b/src/test/ui/consts/const_let_refutable.stderr
new file mode 100644 (file)
index 0000000..c5d2ba0
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0005]: refutable pattern in function argument: `&[]` not covered
+  --> $DIR/const_let_refutable.rs:3:16
+   |
+LL | const fn slice([a, b]: &[i32]) -> i32 { //~ ERROR refutable pattern in function argument
+   |                ^^^^^^ pattern `&[]` not covered
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0005`.
index cc49e4696e58fd9d803cabfede462415844ca35a..1e7b7ed3193557a52dbacef980517bf52c90e839 100644 (file)
@@ -1,4 +1,4 @@
-#![feature(underscore_const_names, const_let)]
+#![feature(underscore_const_names)]
 
 const _: bool = false && false;
 const _: bool = true && false;
index 695d33b6908984b4c7e6874c1b1965c51aaa2447..dbc50f1fbd4b4c75efcaf784d0b1165685e9662a 100644 (file)
@@ -1,7 +1,5 @@
 // https://github.com/rust-lang/rust/issues/55223
 
-#![feature(const_let)]
-
 union Foo<'a> {
     y: &'a (),
     long_live_the_unit: &'static (),
index a5fa88e5e683242f6089a4f91fc7eddc6c924e31..2cd8711f03d3168ed8e696c4c8b40b6a49a1f3d8 100644 (file)
@@ -1,5 +1,5 @@
 error: any use of this value will cause an error
-  --> $DIR/dangling-alloc-id-ice.rs:10:1
+  --> $DIR/dangling-alloc-id-ice.rs:8:1
    |
 LL | / const FOO: &() = { //~ ERROR any use of this value will cause an error
 LL | |     let y = ();
index 7fc773412f2f8e55f87de5331c9090c3cc852514..c2d8e6d421a2876346286962f7b620bc946114ed 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_let)]
-
 const FOO: *const u32 = { //~ ERROR any use of this value will cause an error
     let x = 42;
     &x
index 3b20936f8ae971a293050214cbd1141e0b660696..091f1f785cb02a2824d36e8917f4267d000bf360 100644 (file)
@@ -1,5 +1,5 @@
 error: any use of this value will cause an error
-  --> $DIR/dangling_raw_ptr.rs:3:1
+  --> $DIR/dangling_raw_ptr.rs:1:1
    |
 LL | / const FOO: *const u32 = { //~ ERROR any use of this value will cause an error
 LL | |     let x = 42;
index 551bc57e5ae7dfedf7c3598f11b9ac01dfeffc03..91b076097b0183ec730ad482f02e0ab0993e1455 100644 (file)
@@ -112,12 +112,6 @@ error: `if`, `match`, `&&` and `||` are not stable in const fn
 LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
    |                             ^^^^^^^^^^^
 
-error: local variables in const fn are unstable
-  --> $DIR/min_const_fn.rs:99:34
-   |
-LL | const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn
-   |                                  ^
-
 error: `if`, `match`, `&&` and `||` are not stable in const fn
   --> $DIR/min_const_fn.rs:100:44
    |
@@ -220,7 +214,7 @@ error: function pointers in const fn are unstable
 LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
    |                           ^^^^
 
-error: aborting due to 35 previous errors
+error: aborting due to 34 previous errors
 
 Some errors occurred: E0493, E0515.
 For more information about an error, try `rustc --explain E0493`.
index 238b5f7e310036f76cfcc4405bdabbd153336c88..05cf3d5f1f1731aa69eb49a91bc2514d24b9c246 100644 (file)
@@ -96,7 +96,7 @@ const fn foo30_2(x: *mut u32) -> usize { x as usize }
 const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
 //~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn
 const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
-const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn
+const fn foo30_6() -> bool { let x = true; x }
 const fn foo36(a: bool, b: bool) -> bool { a && b }
 //~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn
 const fn foo37(a: bool, b: bool) -> bool { a || b }
index 1c68df513b69750925746f9d4064fa9f41668ab3..2cae714fbf727cbb25dc889b73bbe208d75a2196 100644 (file)
@@ -112,12 +112,6 @@ error: `if`, `match`, `&&` and `||` are not stable in const fn
 LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
    |                             ^^^^^^^^^^^
 
-error: local variables in const fn are unstable
-  --> $DIR/min_const_fn.rs:99:34
-   |
-LL | const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn
-   |                                  ^
-
 error: `if`, `match`, `&&` and `||` are not stable in const fn
   --> $DIR/min_const_fn.rs:100:44
    |
@@ -208,6 +202,6 @@ error: function pointers in const fn are unstable
 LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
    |                           ^^^^
 
-error: aborting due to 35 previous errors
+error: aborting due to 34 previous errors
 
 For more information about this error, try `rustc --explain E0493`.
index 3dd76b630a883401acf05ed0179268d498c7fb3a..89acfea6ed8ff8d60ae13bdc63c8602ef235fdf3 100644 (file)
@@ -1,6 +1,6 @@
 const fn mutable_ref_in_const() -> u8 {
-    let mut a = 0; //~ ERROR local variables in const fn
-    let b = &mut a;
+    let mut a = 0;
+    let b = &mut a; //~ ERROR mutable references in const fn
     *b
 }
 
@@ -8,8 +8,8 @@ const fn mutable_ref_in_const() -> u8 {
 
 impl X {
     const fn inherent_mutable_ref_in_const() -> u8 {
-        let mut a = 0; //~ ERROR local variables in const fn
-        let b = &mut a;
+        let mut a = 0;
+        let b = &mut a; //~ ERROR mutable references in const fn
         *b
     }
 }
index fa46f5c804fe0eaed14f4360e024bfa122ed4a6a..5ce0f30dc6e1f27bfc7e5578a016a80cc8f26343 100644 (file)
@@ -1,14 +1,14 @@
-error: local variables in const fn are unstable
-  --> $DIR/mutable_borrow.rs:2:9
+error: mutable references in const fn are unstable
+  --> $DIR/mutable_borrow.rs:3:9
    |
-LL |     let mut a = 0; //~ ERROR local variables in const fn
-   |         ^^^^^
+LL |     let b = &mut a; //~ ERROR mutable references in const fn
+   |         ^
 
-error: local variables in const fn are unstable
-  --> $DIR/mutable_borrow.rs:11:13
+error: mutable references in const fn are unstable
+  --> $DIR/mutable_borrow.rs:12:13
    |
-LL |         let mut a = 0; //~ ERROR local variables in const fn
-   |             ^^^^^
+LL |         let b = &mut a; //~ ERROR mutable references in const fn
+   |             ^
 
 error: aborting due to 2 previous errors
 
index 4ce41f80f82c8dff332491835619331abdf21e40..32c68e69f4beda7d4d4ba48908ce00ae90aaf899 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_let)]
-
 use std::cell::Cell;
 
 const FOO: &(Cell<usize>, bool) = {
index d695f64e2c3b55a6a1d9fddf1372cfc6f9ba6856..967fb83b78b087d64d18cc5770af96a3c0f04de5 100644 (file)
@@ -1,5 +1,5 @@
 error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
-  --> $DIR/partial_qualif.rs:8:5
+  --> $DIR/partial_qualif.rs:6:5
    |
 LL |     &{a} //~ ERROR cannot borrow a constant which may contain interior mutability
    |     ^^^^
index 5863429a2f2c5ddd19ad6e7efc57eb130582155f..dedb7db5920891315da02e88b4ef7988207dae46 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_let)]
-
 use std::cell::Cell;
 
 const FOO: &u32 = {
index cc3635a979b370f792afd0c1e34da3b5a3141daa..410c51c4b54e1bb666d4bc7a87a760756fa99e16 100644 (file)
@@ -1,17 +1,17 @@
 error[E0017]: references in constants may only refer to immutable values
-  --> $DIR/projection_qualif.rs:8:27
+  --> $DIR/projection_qualif.rs:6:27
    |
 LL |         let b: *mut u32 = &mut a; //~ ERROR may only refer to immutable values
    |                           ^^^^^^ constants require immutable values
 
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/projection_qualif.rs:9:18
+  --> $DIR/projection_qualif.rs:7:18
    |
 LL |         unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants
    |                  ^^^^^^
 
 error[E0658]: dereferencing raw pointers in constants is unstable (see issue #51911)
-  --> $DIR/projection_qualif.rs:9:18
+  --> $DIR/projection_qualif.rs:7:18
    |
 LL |         unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants
    |                  ^^^^^^
index d8749bb5fd90bff0251e2c94a71fe0ffd246fa9d..e6ee1523a3b285e4ecd0bd4805bb6c1570c3bf64 100644 (file)
@@ -1,5 +1,5 @@
 error[E0597]: `y` does not live long enough
-  --> $DIR/promote_const_let.rs:6:9
+  --> $DIR/promote_const_let.rs:4:9
    |
 LL |     let x: &'static u32 = {
    |            ------------ type annotation requires that `y` is borrowed for `'static`
@@ -9,6 +9,21 @@ LL |         &y //~ ERROR does not live long enough
 LL |     };
    |     - `y` dropped here while still borrowed
 
-error: aborting due to previous error
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/promote_const_let.rs:6:28
+   |
+LL |       let x: &'static u32 = &{ //~ ERROR does not live long enough
+   |  ____________------------____^
+   | |            |
+   | |            type annotation requires that borrow lasts for `'static`
+LL | |         let y = 42;
+LL | |         y
+LL | |     };
+   | |_____^ creates a temporary which is freed while still in use
+LL |   }
+   |   - temporary value is freed at the end of this statement
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0597`.
+Some errors occurred: E0597, E0716.
+For more information about an error, try `rustc --explain E0597`.
index 8de9b00eb111d3bb0baca2e63cd9278d0ba68ced..a8a6d4d99c6ffb959c5156f1cb30c418564415af 100644 (file)
@@ -1,8 +1,10 @@
-#![feature(const_let)]
-
 fn main() {
     let x: &'static u32 = {
         let y = 42;
         &y //~ ERROR does not live long enough
     };
+    let x: &'static u32 = &{ //~ ERROR does not live long enough
+        let y = 42;
+        y
+    };
 }
index 6bbb7495fb0dca1035a811a19ddc173f98730315..d37bd49186032d141e56aee31f8ad56cfa790d91 100644 (file)
@@ -1,5 +1,5 @@
 error[E0597]: `y` does not live long enough
-  --> $DIR/promote_const_let.rs:6:10
+  --> $DIR/promote_const_let.rs:4:10
    |
 LL |         &y //~ ERROR does not live long enough
    |          ^ borrowed value does not live long enough
@@ -8,6 +8,20 @@ LL |     };
    |
    = note: borrowed value must be valid for the static lifetime...
 
-error: aborting due to previous error
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote_const_let.rs:6:28
+   |
+LL |       let x: &'static u32 = &{ //~ ERROR does not live long enough
+   |  ____________________________^
+LL | |         let y = 42;
+LL | |         y
+LL | |     };
+   | |_____^ temporary value does not live long enough
+LL |   }
+   |   - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0597`.
index 806a74ee4530b0f798783a60930668b78d6c0ccc..430eea37de73c60cb76e51b054d1e346e136393a 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_let)]
-
 use std::cell::Cell;
 
 // this is overly conservative. The reset to `None` should clear `a` of all qualifications
index 4fac64bf8063f19dbec23b44a35eb5278989fee8..30479139e314c82c0d51341b79b678dafd8d9960 100644 (file)
@@ -1,5 +1,5 @@
 error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
-  --> $DIR/qualif_overwrite.rs:12:5
+  --> $DIR/qualif_overwrite.rs:10:5
    |
 LL |     &{a} //~ ERROR cannot borrow a constant which may contain interior mutability
    |     ^^^^
index 29557a3da47811d491291021e7fc49bc339d5872..fa79b5c14a73629e80853143aaff2217c7f83d2f 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_let)]
-
 use std::cell::Cell;
 
 // const qualification is not smart enough to know about fields and always assumes that there might
index 181b728c7b76f2746f63f1e59a150238eccc4359..8276db99a12c0b264b227387cbb90b70b1a3e03a 100644 (file)
@@ -1,5 +1,5 @@
 error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
-  --> $DIR/qualif_overwrite_2.rs:10:5
+  --> $DIR/qualif_overwrite_2.rs:8:5
    |
 LL |     &{a.0} //~ ERROR cannot borrow a constant which may contain interior mutability
    |     ^^^^^^
index 4180b1e295ab049d4eaceb20aca335d07d5e479c..ef378fa84518e5cc1e208e87d5e6c192d486042f 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_let)]
-
 static mut STDERR_BUFFER_SPACE: u8 = 0;
 
 pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
index f0ae1545056b7ad3ac98d209eb0d3fa7d5e81db5..72186571d697e15f25a57659797eaf712ab7aedf 100644 (file)
@@ -1,11 +1,11 @@
 error[E0017]: references in statics may only refer to immutable values
-  --> $DIR/static_mut_containing_mut_ref2.rs:5:46
+  --> $DIR/static_mut_containing_mut_ref2.rs:3:46
    |
 LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
    |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^ statics require immutable values
 
 error[E0019]: static contains unimplemented expression type
-  --> $DIR/static_mut_containing_mut_ref2.rs:5:45
+  --> $DIR/static_mut_containing_mut_ref2.rs:3:45
    |
 LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; };
    |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 0bc7faa9afdec7b2d170a33883be90041fcfe459..c24c7e27920795a6d8fe14c3f67a5c3a4bd40c90 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_let)]
-
 static mut FOO: (u8, u8) = (42, 43);
 
 static mut BAR: () = unsafe { FOO.0 = 99; };
index cae53c6fee9dd9d6297adb4c4a1276e550777a57..e88e49b097af26b7d0cbe13936c58de0a7153b5e 100644 (file)
@@ -1,5 +1,5 @@
 error[E0080]: could not evaluate static initializer
-  --> $DIR/static_mut_containing_mut_ref3.rs:5:31
+  --> $DIR/static_mut_containing_mut_ref3.rs:3:31
    |
 LL | static mut BAR: () = unsafe { FOO.0 = 99; };
    |                               ^^^^^^^^^^ tried to modify a static's initial value from another static's initializer
index 1a75eb5e3145025d53c17849e1611ec07605bf4f..aa45462a52e41e702cd06b07e042e81355297a46 100644 (file)
@@ -5,6 +5,11 @@ LL | trait Foo<X = Box<Foo>> {
    |                   ^^^
    |
    = note: ...which again requires processing `Foo::X`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/cycle-trait-default-type-trait.rs:4:1
+   |
+LL | trait Foo<X = Box<Foo>> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 22efa8ee0a58d3cc9ae6137b7f11af0941e8fdef..8aa3ac8abf52c5eaa658bc0955a17c059e57f77a 100644 (file)
@@ -5,6 +5,11 @@ LL | trait Chromosome: Chromosome {
    |                   ^^^^^^^^^^
    |
    = note: ...which again requires computing the supertraits of `Chromosome`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/cycle-trait-supertrait-direct.rs:3:1
+   |
+LL | trait Chromosome: Chromosome {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index c458635040a21c7542d5eca648abe6d774f5ab37..6b670d5d434e4782693758be99e7da73ee29a05c 100644 (file)
@@ -10,7 +10,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl<'a> Drop for &'a mut isize {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to 2 previous errors
index b89ca28e279db223c19a7b6a516c4e13f7aa4d8c..5ba45b19dded0f22bef9377a9facd12e813221e3 100644 (file)
@@ -3,8 +3,6 @@
 // aux-build:edition-imports-2018.rs
 // aux-build:absolute.rs
 
-#![feature(uniform_paths)]
-
 #[macro_use]
 extern crate edition_imports_2018;
 
index fb6b2e64ef5b8ddc27e50a1d561453eba564bea9..816ab21d81426677658c193b21826d4945373de5 100644 (file)
@@ -1,5 +1,5 @@
 error: cannot glob-import all possible crates
-  --> $DIR/edition-imports-2015.rs:25:5
+  --> $DIR/edition-imports-2015.rs:23:5
    |
 LL |     gen_glob!(); //~ ERROR cannot glob-import all possible crates
    |     ^^^^^^^^^^^^
index 7c1837e3f56e3e90275e6b6084e5481b63fb68fb..7c78fbb26a1b876060066374b0cab7a58e641504 100644 (file)
@@ -1,4 +1,4 @@
-error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
+error: imports can only refer to extern crate names passed with `--extern` in macros originating from 2015 edition
   --> <::edition_imports_2015::gen_gated macros>:1:50
    |
 LL | (  ) => { fn check_gated (  ) { enum E { A } use E :: * ; } }
@@ -9,7 +9,6 @@ LL | (  ) => { fn check_gated (  ) { enum E { A } use E :: * ; } }
 LL |     gen_gated!();
    |     ------------- not an extern crate passed with `--extern`
    |
-   = help: add #![feature(uniform_paths)] to the crate attributes to enable
 note: this import refers to the enum defined here
   --> $DIR/edition-imports-virtual-2015-gated.rs:9:5
    |
@@ -19,4 +18,3 @@ LL |     gen_gated!();
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0658`.
index d905ccc8ac070bccfc6a66d2e6d16f8ba7c12d78..51cfe7beade2dc467ffb4845a8e1f1f81585b68e 100644 (file)
@@ -1,8 +1,8 @@
-error: function `BOGUS` should have a snake case name such as `bogus`
-  --> $DIR/enable-unstable-lib-feature.rs:12:1
+error: function `BOGUS` should have a snake case name
+  --> $DIR/enable-unstable-lib-feature.rs:12:8
    |
 LL | pub fn BOGUS() { } //~ ERROR
-   | ^^^^^^^^^^^^^^^^^^
+   |        ^^^^^ help: convert the identifier to snake case: `bogus`
    |
 note: lint level defined here
   --> $DIR/enable-unstable-lib-feature.rs:6:9
index fc5dffb37cfe743dac9c2c65c3301dc94f1ae91d..da51035ab555062b2e03c26a658f14690a0d301c 100644 (file)
@@ -4,5 +4,6 @@
 #![allow(warnings)]
 
 const CON : Box<i32> = box 0; //~ ERROR E0010
+//~^ ERROR constant contains unimplemented expression type
 
 fn main() {}
index da0aadfded5f864cd331bf3058035a1e911dda32..77e7b5ec0e860cf50e2102db6e5d0b4a30bfee7c 100644 (file)
@@ -6,6 +6,16 @@ LL | const CON : Box<i32> = box 0; //~ ERROR E0010
    |
    = note: The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time.
 
-error: aborting due to previous error
+error[E0019]: constant contains unimplemented expression type
+  --> $DIR/E0010-teach.rs:6:28
+   |
+LL | const CON : Box<i32> = box 0; //~ ERROR E0010
+   |                            ^
+   |
+   = note: A function call isn't allowed in the const's initialization expression because the expression's value must be known at compile-time.
+   = note: Remember: you can't use a function call inside a const's initialization expression! However, you can use it anywhere else.
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0010`.
+Some errors occurred: E0010, E0019.
+For more information about an error, try `rustc --explain E0010`.
index e62997640f473e1ee2af953cdfc5a3542d7389be..3398e2c28ba6b5cdcf7acb9a81cf5178b78be955 100644 (file)
@@ -2,5 +2,6 @@
 #![allow(warnings)]
 
 const CON : Box<i32> = box 0; //~ ERROR E0010
+//~^ ERROR constant contains unimplemented expression type
 
 fn main() {}
index b4b490922c45f09734b60a8a81b706ad85a90123..1364693109e086bc64d6ccb8510b2e3d28f67ee5 100644 (file)
@@ -4,6 +4,13 @@ error[E0010]: allocations are not allowed in constants
 LL | const CON : Box<i32> = box 0; //~ ERROR E0010
    |                        ^^^^^ allocation not allowed in constants
 
-error: aborting due to previous error
+error[E0019]: constant contains unimplemented expression type
+  --> $DIR/E0010.rs:4:28
+   |
+LL | const CON : Box<i32> = box 0; //~ ERROR E0010
+   |                            ^
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0010`.
+Some errors occurred: E0010, E0019.
+For more information about an error, try `rustc --explain E0010`.
index 8e32db49cedeef9a2661df84d63a5502a416c246..b007ca05ab2cf9f3b0118b9064b0bc941821f7e2 100644 (file)
@@ -10,7 +10,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Drop for u32 {} //~ ERROR E0117
    | ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/error-codes/E0162.rs b/src/test/ui/error-codes/E0162.rs
deleted file mode 100644 (file)
index d3221f8..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-struct Irrefutable(i32);
-
-fn main() {
-    let irr = Irrefutable(0);
-    if let Irrefutable(x) = irr { //~ ERROR E0162
-        println!("{}", x);
-    }
-}
diff --git a/src/test/ui/error-codes/E0162.stderr b/src/test/ui/error-codes/E0162.stderr
deleted file mode 100644 (file)
index ca5c56c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0162]: irrefutable if-let pattern
-  --> $DIR/E0162.rs:5:12
-   |
-LL |     if let Irrefutable(x) = irr { //~ ERROR E0162
-   |            ^^^^^^^^^^^^^^ irrefutable pattern
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0162`.
diff --git a/src/test/ui/error-codes/E0165.rs b/src/test/ui/error-codes/E0165.rs
deleted file mode 100644 (file)
index 952071c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-struct Irrefutable(i32);
-
-fn main() {
-    let irr = Irrefutable(0);
-    while let Irrefutable(x) = irr { //~ ERROR E0165
-                                     //~| irrefutable pattern
-        // ...
-    }
-}
diff --git a/src/test/ui/error-codes/E0165.stderr b/src/test/ui/error-codes/E0165.stderr
deleted file mode 100644 (file)
index e0d192e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0165]: irrefutable while-let pattern
-  --> $DIR/E0165.rs:5:15
-   |
-LL |     while let Irrefutable(x) = irr { //~ ERROR E0165
-   |               ^^^^^^^^^^^^^^ irrefutable pattern
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0165`.
index 499c6ae3f8852d869a64cba75ffced039a3611fe..a0c4b0149a09994b05f18dbf2d3f39f8e8e017df 100644 (file)
@@ -16,7 +16,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl Copy for Foo { }
    | ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to 3 previous errors
index 8117bc754b6b91dfde2818f39efbd9d7997b89f2..f69a389336590817614194480b0a7f037ada8ca2 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/E0308-4.rs:4:9
    |
+LL |     match x {
+   |           - this match expression has type `u8`
 LL |         0u8..=3i8 => (), //~ ERROR E0308
    |         ^^^^^^^^^ expected u8, found i8
 
index bc872b3b79cceb22297928c387eb61defe59d8b9..89ec4896a2b4329b459efcc30c9fe5a41b9f60d9 100644 (file)
@@ -2,13 +2,10 @@ error[E0606]: casting `&u8` as `u8` is invalid
   --> $DIR/E0606.rs:2:5
    |
 LL |     &0u8 as u8; //~ ERROR E0606
-   |     ^^^^^^^^^^ cannot cast `&u8` as `u8`
-   |
-help: did you mean `*&0u8`?
-  --> $DIR/E0606.rs:2:5
-   |
-LL |     &0u8 as u8; //~ ERROR E0606
-   |     ^^^^
+   |     ----^^^^^^
+   |     |
+   |     cannot cast `&u8` as `u8`
+   |     help: dereference the expression: `*&0u8`
 
 error: aborting due to previous error
 
index 2a482722169198eed5bbda4d93a98c3fa490b33b..ef7b49399bf3ab58e0250fcce40b1ff3e9a2c039 100644 (file)
@@ -60,13 +60,10 @@ error[E0606]: casting `&u8` as `u32` is invalid
   --> $DIR/error-festival.rs:37:18
    |
 LL |     let y: u32 = x as u32;
-   |                  ^^^^^^^^ cannot cast `&u8` as `u32`
-   |
-help: did you mean `*x`?
-  --> $DIR/error-festival.rs:37:18
-   |
-LL |     let y: u32 = x as u32;
-   |                  ^
+   |                  -^^^^^^^
+   |                  |
+   |                  cannot cast `&u8` as `u32`
+   |                  help: dereference the expression: `*x`
 
 error[E0607]: cannot cast thin pointer `*const u8` to fat pointer `*const [u8]`
   --> $DIR/error-festival.rs:41:5
index 9d2609e546db56849b80e418585b02053d18b09c..fab61bd9ed06504261475531ae84bba7e47cf759 100644 (file)
@@ -10,6 +10,17 @@ note: ...which requires processing `bar`...
 LL | fn bar(x: Foo) -> Foo { x }
    |                       ^^^^^
    = note: ...which again requires processing `Foo`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/no_inferrable_concrete_type.rs:4:1
+   |
+LL | / #![feature(existential_type)]
+LL | |
+LL | | existential type Foo: Copy; //~ cycle detected
+LL | |
+...  |
+LL | |     let _: Foo = std::mem::transmute(0u8);
+LL | | }
+   | |_^
 
 error: aborting due to previous error
 
index f3aa39f89cc3d1f5d698d9a8a4647e49ef42853c..8155514191ce35511f81bdae0a6f9a0f5602226f 100644 (file)
@@ -1,8 +1,8 @@
-error: variable `X` should have a snake case name such as `x`
+error: variable `X` should have a snake case name
   --> $DIR/expr_attr_paren_order.rs:19:17
    |
 LL |             let X = 0; //~ ERROR snake case name
-   |                 ^
+   |                 ^ help: convert the identifier to snake case: `x`
    |
 note: lint level defined here
   --> $DIR/expr_attr_paren_order.rs:17:17
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.rs b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.rs
deleted file mode 100644 (file)
index 9515380..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-// gate-test-cfg_attr_multi
-
-#![cfg_attr(all(), warn(nonstandard_style), allow(unused_attributes))]
-//~^ ERROR cfg_attr with zero or more than one attributes is experimental
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.stderr b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-1.stderr
deleted file mode 100644 (file)
index 088e6df..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: cfg_attr with zero or more than one attributes is experimental (see issue #54881)
-  --> $DIR/feature-gate-cfg-attr-multi-1.rs:3:1
-   |
-LL | #![cfg_attr(all(), warn(nonstandard_style), allow(unused_attributes))]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(cfg_attr_multi)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.rs b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.rs
deleted file mode 100644 (file)
index cf02432..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#![cfg_attr(all(),)]
-//~^ ERROR cfg_attr with zero or more than one attributes is experimental
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.stderr b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-2.stderr
deleted file mode 100644 (file)
index a018761..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: cfg_attr with zero or more than one attributes is experimental (see issue #54881)
-  --> $DIR/feature-gate-cfg-attr-multi-2.rs:1:1
-   |
-LL | #![cfg_attr(all(),)]
-   | ^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(cfg_attr_multi)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-1.rs b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-1.rs
deleted file mode 100644 (file)
index e473792..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// Test that settingt the featute gate while using its functionality doesn't error.
-
-// compile-pass
-
-#![cfg_attr(all(), feature(cfg_attr_multi), crate_type="bin")]
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-2.rs b/src/test/ui/feature-gates/feature-gate-cfg-attr-multi-bootstrap-2.rs
deleted file mode 100644 (file)
index df74054..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// Test that settingt the featute gate while using its functionality doesn't error.
-// Specifically, if there's a cfg-attr *before* the feature gate.
-
-// compile-pass
-
-#![cfg_attr(all(),)]
-#![cfg_attr(all(), feature(cfg_attr_multi), crate_type="bin")]
-
-fn main() {}
index b3fc587b1cf773fc33722a66f925aba7b3fcb020..be5237fbfcf3b1d798501902783e117ffd1746ef 100644 (file)
@@ -16,7 +16,7 @@ error[E0379]: trait fns cannot be declared const
 LL |     const fn foo() -> u32 { 0 } //~ ERROR trait fns cannot be declared const
    |     ^^^^^ trait fns cannot be const
 
-error[E0658]: const fn is unstable (see issue #24111)
+error[E0658]: const fn is unstable (see issue #57563)
   --> $DIR/feature-gate-const_fn.rs:6:5
    |
 LL |     const fn foo() -> u32; //~ ERROR const fn is unstable
@@ -24,7 +24,7 @@ LL |     const fn foo() -> u32; //~ ERROR const fn is unstable
    |
    = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error[E0658]: const fn is unstable (see issue #24111)
+error[E0658]: const fn is unstable (see issue #57563)
   --> $DIR/feature-gate-const_fn.rs:8:5
    |
 LL |     const fn bar() -> u32 { 0 } //~ ERROR const fn is unstable
diff --git a/src/test/ui/feature-gates/feature-gate-const_let.rs b/src/test/ui/feature-gates/feature-gate-const_let.rs
deleted file mode 100644 (file)
index 74cefd7..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Test use of const let without feature gate.
-
-const FOO: usize = {
-    //~^ ERROR statements in constants are unstable
-    //~| ERROR: let bindings in constants are unstable
-    let x = 42;
-    //~^ ERROR statements in constants are unstable
-    //~| ERROR: let bindings in constants are unstable
-    42
-};
-
-static BAR: usize = {
-    //~^ ERROR statements in statics are unstable
-    //~| ERROR: let bindings in statics are unstable
-    let x = 42;
-    //~^ ERROR statements in statics are unstable
-    //~| ERROR: let bindings in statics are unstable
-    42
-};
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-const_let.stderr b/src/test/ui/feature-gates/feature-gate-const_let.stderr
deleted file mode 100644 (file)
index 5631299..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-error[E0658]: let bindings in constants are unstable (see issue #48821)
-  --> $DIR/feature-gate-const_let.rs:6:13
-   |
-LL |     let x = 42;
-   |             ^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/feature-gate-const_let.rs:6:13
-   |
-LL |     let x = 42;
-   |             ^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in constants are unstable (see issue #48821)
-  --> $DIR/feature-gate-const_let.rs:3:1
-   |
-LL | / const FOO: usize = {
-LL | |     //~^ ERROR statements in constants are unstable
-LL | |     //~| ERROR: let bindings in constants are unstable
-LL | |     let x = 42;
-...  |
-LL | |     42
-LL | | };
-   | |__^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/feature-gate-const_let.rs:3:1
-   |
-LL | / const FOO: usize = {
-LL | |     //~^ ERROR statements in constants are unstable
-LL | |     //~| ERROR: let bindings in constants are unstable
-LL | |     let x = 42;
-...  |
-LL | |     42
-LL | | };
-   | |__^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in statics are unstable (see issue #48821)
-  --> $DIR/feature-gate-const_let.rs:15:13
-   |
-LL |     let x = 42;
-   |             ^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in statics are unstable (see issue #48821)
-  --> $DIR/feature-gate-const_let.rs:15:13
-   |
-LL |     let x = 42;
-   |             ^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in statics are unstable (see issue #48821)
-  --> $DIR/feature-gate-const_let.rs:12:1
-   |
-LL | / static BAR: usize = {
-LL | |     //~^ ERROR statements in statics are unstable
-LL | |     //~| ERROR: let bindings in statics are unstable
-LL | |     let x = 42;
-...  |
-LL | |     42
-LL | | };
-   | |__^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in statics are unstable (see issue #48821)
-  --> $DIR/feature-gate-const_let.rs:12:1
-   |
-LL | / static BAR: usize = {
-LL | |     //~^ ERROR statements in statics are unstable
-LL | |     //~| ERROR: let bindings in statics are unstable
-LL | |     let x = 42;
-...  |
-LL | |     42
-LL | | };
-   | |__^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error: aborting due to 8 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-if_while_or_patterns.rs b/src/test/ui/feature-gates/feature-gate-if_while_or_patterns.rs
deleted file mode 100644 (file)
index 233185f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-fn main() {
-    if let 0 | 1 = 0 { //~ ERROR multiple patterns in `if let` and `while let` are unstable
-        ;
-    }
-    while let 0 | 1 = 1 { //~ ERROR multiple patterns in `if let` and `while let` are unstable
-        break;
-    }
-}
diff --git a/src/test/ui/feature-gates/feature-gate-if_while_or_patterns.stderr b/src/test/ui/feature-gates/feature-gate-if_while_or_patterns.stderr
deleted file mode 100644 (file)
index ff99181..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0658]: multiple patterns in `if let` and `while let` are unstable (see issue #48215)
-  --> $DIR/feature-gate-if_while_or_patterns.rs:2:5
-   |
-LL | /     if let 0 | 1 = 0 { //~ ERROR multiple patterns in `if let` and `while let` are unstable
-LL | |         ;
-LL | |     }
-   | |_____^
-   |
-   = help: add #![feature(if_while_or_patterns)] to the crate attributes to enable
-
-error[E0658]: multiple patterns in `if let` and `while let` are unstable (see issue #48215)
-  --> $DIR/feature-gate-if_while_or_patterns.rs:5:5
-   |
-LL | /     while let 0 | 1 = 1 { //~ ERROR multiple patterns in `if let` and `while let` are unstable
-LL | |         break;
-LL | |     }
-   | |_____^
-   |
-   = help: add #![feature(if_while_or_patterns)] to the crate attributes to enable
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
index bcc5b0198c319de4f704ae574372e86759b86321..056e33111f0dfcfcb5bfe56d559a3968684c6572 100644 (file)
@@ -16,7 +16,7 @@ error[E0379]: trait fns cannot be declared const
 LL |     const fn foo() -> u32 { 0 } //~ ERROR trait fns cannot be declared const
    |     ^^^^^ trait fns cannot be const
 
-error[E0658]: const fn is unstable (see issue #24111)
+error[E0658]: const fn is unstable (see issue #57563)
   --> $DIR/feature-gate-min_const_fn.rs:6:5
    |
 LL |     const fn foo() -> u32; //~ ERROR const fn is unstable
@@ -24,7 +24,7 @@ LL |     const fn foo() -> u32; //~ ERROR const fn is unstable
    |
    = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error[E0658]: const fn is unstable (see issue #24111)
+error[E0658]: const fn is unstable (see issue #57563)
   --> $DIR/feature-gate-min_const_fn.rs:8:5
    |
 LL |     const fn bar() -> u32 { 0 } //~ ERROR const fn is unstable
index a82b356c75216e7d013e7a04fad57e0055833583..6b97c24a47ed24ce983d85a6b729a6de1cf5f34f 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_let)]
-
 trait Trt {}
 struct Str {}
 
index b3658208828e96f237872bc1cbb6805fb2d18c10..d608f3d37cf2ae7000118abe596f611aa49e8f45 100644 (file)
@@ -1,5 +1,5 @@
 error[E0658]: naming constants with `_` is unstable (see issue #54912)
-  --> $DIR/feature-gate-underscore_const_names.rs:8:1
+  --> $DIR/feature-gate-underscore_const_names.rs:6:1
    |
 LL | / const _ : () = {
 LL | | //~^ ERROR is unstable
diff --git a/src/test/ui/feature-gates/feature-gate-uniform-paths.rs b/src/test/ui/feature-gates/feature-gate-uniform-paths.rs
deleted file mode 100644 (file)
index 71f880a..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// edition:2018
-
-pub mod foo {
-    pub use bar::Bar; //~ ERROR imports can only refer to extern crate names
-
-    pub mod bar {
-        pub struct Bar;
-    }
-}
-
-use inline; //~ ERROR imports can only refer to extern crate names
-
-use Vec; //~ ERROR imports can only refer to extern crate names
-
-use vec; //~ ERROR imports can only refer to extern crate names
-
-fn main() {
-    let _ = foo::Bar;
-}
diff --git a/src/test/ui/feature-gates/feature-gate-uniform-paths.stderr b/src/test/ui/feature-gates/feature-gate-uniform-paths.stderr
deleted file mode 100644 (file)
index 8b79e59..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
-  --> $DIR/feature-gate-uniform-paths.rs:4:13
-   |
-LL |       pub use bar::Bar; //~ ERROR imports can only refer to extern crate names
-   |               ^^^
-LL | 
-LL | /     pub mod bar {
-LL | |         pub struct Bar;
-LL | |     }
-   | |_____- not an extern crate passed with `--extern`
-   |
-   = help: add #![feature(uniform_paths)] to the crate attributes to enable
-note: this import refers to the module defined here
-  --> $DIR/feature-gate-uniform-paths.rs:6:5
-   |
-LL | /     pub mod bar {
-LL | |         pub struct Bar;
-LL | |     }
-   | |_____^
-
-error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
-  --> $DIR/feature-gate-uniform-paths.rs:11:5
-   |
-LL | use inline; //~ ERROR imports can only refer to extern crate names
-   |     ^^^^^^ not an extern crate passed with `--extern`
-   |
-   = help: add #![feature(uniform_paths)] to the crate attributes to enable
-   = note: this import refers to a built-in attribute
-
-error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
-  --> $DIR/feature-gate-uniform-paths.rs:13:5
-   |
-LL | use Vec; //~ ERROR imports can only refer to extern crate names
-   |     ^^^ not an extern crate passed with `--extern`
-   |
-   = help: add #![feature(uniform_paths)] to the crate attributes to enable
-   = note: this import refers to a struct from prelude
-
-error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
-  --> $DIR/feature-gate-uniform-paths.rs:15:5
-   |
-LL | use vec; //~ ERROR imports can only refer to extern crate names
-   |     ^^^ not an extern crate passed with `--extern`
-   |
-   = help: add #![feature(uniform_paths)] to the crate attributes to enable
-   = note: this import refers to a macro from prelude
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-without_gate_irrefutable_pattern.rs b/src/test/ui/feature-gates/feature-gate-without_gate_irrefutable_pattern.rs
deleted file mode 100644 (file)
index cae2f1d..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// gate-test-irrefutable_let_patterns
-
-
-#[allow(irrefutable_let_patterns)]
-fn main() {
-    if let _ = 5 {}
-    //~^ ERROR irrefutable if-let pattern [E0162]
-}
diff --git a/src/test/ui/feature-gates/feature-gate-without_gate_irrefutable_pattern.stderr b/src/test/ui/feature-gates/feature-gate-without_gate_irrefutable_pattern.stderr
deleted file mode 100644 (file)
index fa8b74f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0162]: irrefutable if-let pattern
-  --> $DIR/feature-gate-without_gate_irrefutable_pattern.rs:6:12
-   |
-LL |     if let _ = 5 {}
-   |            ^ irrefutable pattern
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0162`.
diff --git a/src/test/ui/if-else-type-mismatch.rs b/src/test/ui/if-else-type-mismatch.rs
new file mode 100644 (file)
index 0000000..583c3d0
--- /dev/null
@@ -0,0 +1,46 @@
+fn main() {
+    let _ = if true {
+        1i32
+    } else {
+        2u32
+    };
+    //~^^ ERROR if and else have incompatible types
+    let _ = if true { 42i32 } else { 42u32 };
+    //~^ ERROR if and else have incompatible types
+    let _ = if true {
+        3u32;
+    } else {
+        4u32
+    };
+    //~^^ ERROR if and else have incompatible types
+    let _ = if true {
+        5u32
+    } else {
+        6u32;
+    };
+    //~^^ ERROR if and else have incompatible types
+    let _ = if true {
+        7i32;
+    } else {
+        8u32
+    };
+    //~^^ ERROR if and else have incompatible types
+    let _ = if true {
+        9i32
+    } else {
+        10u32;
+    };
+    //~^^ ERROR if and else have incompatible types
+    let _ = if true {
+
+    } else {
+        11u32
+    };
+    //~^^ ERROR if and else have incompatible types
+    let _ = if true {
+        12i32
+    } else {
+
+    };
+    //~^^^ ERROR if and else have incompatible types
+}
diff --git a/src/test/ui/if-else-type-mismatch.stderr b/src/test/ui/if-else-type-mismatch.stderr
new file mode 100644 (file)
index 0000000..b418c96
--- /dev/null
@@ -0,0 +1,130 @@
+error[E0308]: if and else have incompatible types
+  --> $DIR/if-else-type-mismatch.rs:5:9
+   |
+LL |       let _ = if true {
+   |  _____________-
+LL | |         1i32
+   | |         ---- expected because of this
+LL | |     } else {
+LL | |         2u32
+   | |         ^^^^ expected i32, found u32
+LL | |     };
+   | |_____- if and else have incompatible types
+   |
+   = note: expected type `i32`
+              found type `u32`
+
+error[E0308]: if and else have incompatible types
+  --> $DIR/if-else-type-mismatch.rs:8:38
+   |
+LL |     let _ = if true { 42i32 } else { 42u32 };
+   |                       -----          ^^^^^ expected i32, found u32
+   |                       |
+   |                       expected because of this
+   |
+   = note: expected type `i32`
+              found type `u32`
+
+error[E0308]: if and else have incompatible types
+  --> $DIR/if-else-type-mismatch.rs:13:9
+   |
+LL |       let _ = if true {
+   |  _____________-
+LL | |         3u32;
+   | |         -----
+   | |         |   |
+   | |         |   help: consider removing this semicolon
+   | |         expected because of this
+LL | |     } else {
+LL | |         4u32
+   | |         ^^^^ expected (), found u32
+LL | |     };
+   | |_____- if and else have incompatible types
+   |
+   = note: expected type `()`
+              found type `u32`
+
+error[E0308]: if and else have incompatible types
+  --> $DIR/if-else-type-mismatch.rs:19:9
+   |
+LL |       let _ = if true {
+   |  _____________-
+LL | |         5u32
+   | |         ---- expected because of this
+LL | |     } else {
+LL | |         6u32;
+   | |         ^^^^-
+   | |         |   |
+   | |         |   help: consider removing this semicolon
+   | |         expected u32, found ()
+LL | |     };
+   | |_____- if and else have incompatible types
+   |
+   = note: expected type `u32`
+              found type `()`
+
+error[E0308]: if and else have incompatible types
+  --> $DIR/if-else-type-mismatch.rs:25:9
+   |
+LL |       let _ = if true {
+   |  _____________-
+LL | |         7i32;
+   | |         ----- expected because of this
+LL | |     } else {
+LL | |         8u32
+   | |         ^^^^ expected (), found u32
+LL | |     };
+   | |_____- if and else have incompatible types
+   |
+   = note: expected type `()`
+              found type `u32`
+
+error[E0308]: if and else have incompatible types
+  --> $DIR/if-else-type-mismatch.rs:31:9
+   |
+LL |       let _ = if true {
+   |  _____________-
+LL | |         9i32
+   | |         ---- expected because of this
+LL | |     } else {
+LL | |         10u32;
+   | |         ^^^^^^ expected i32, found ()
+LL | |     };
+   | |_____- if and else have incompatible types
+   |
+   = note: expected type `i32`
+              found type `()`
+
+error[E0308]: if and else have incompatible types
+  --> $DIR/if-else-type-mismatch.rs:37:9
+   |
+LL |       let _ = if true {
+   |  _____________________-
+LL | |
+LL | |     } else {
+   | |_____- expected because of this
+LL |           11u32
+   |           ^^^^^ expected (), found u32
+   |
+   = note: expected type `()`
+              found type `u32`
+
+error[E0308]: if and else have incompatible types
+  --> $DIR/if-else-type-mismatch.rs:42:12
+   |
+LL |       let _ = if true {
+   |               ------- if and else have incompatible types
+LL |           12i32
+   |           ----- expected because of this
+LL |       } else {
+   |  ____________^
+LL | |
+LL | |     };
+   | |_____^ expected i32, found ()
+   |
+   = note: expected type `i32`
+              found type `()`
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
index 44e172da783949d8c651691091a7bb9298895caa..74b925f72fff02248f7542a72a2beabce559e4cb 100644 (file)
@@ -1,8 +1,10 @@
 error[E0308]: if and else have incompatible types
-  --> $DIR/if-branch-types.rs:2:13
+  --> $DIR/if-branch-types.rs:2:38
    |
 LL |     let x = if true { 10i32 } else { 10u32 };
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found u32
+   |                       -----          ^^^^^ expected i32, found u32
+   |                       |
+   |                       expected because of this
    |
    = note: expected type `i32`
               found type `u32`
index 304de457059f373cc7957261f33ccfb0f543954e..741685fe9b64995a85b95356e9434532110c5f70 100644 (file)
@@ -1,3 +1,5 @@
+// compile-pass
+
 fn macros() {
     macro_rules! foo{
         ($p:pat, $e:expr, $b:block) => {{
@@ -10,20 +12,20 @@ macro_rules! bar{
         }}
     }
 
-    foo!(a, 1, { //~ ERROR irrefutable if-let
+    foo!(a, 1, { //~ WARN irrefutable if-let
         println!("irrefutable pattern");
     });
-    bar!(a, 1, { //~ ERROR irrefutable if-let
+    bar!(a, 1, { //~ WARN irrefutable if-let
         println!("irrefutable pattern");
     });
 }
 
 pub fn main() {
-    if let a = 1 { //~ ERROR irrefutable if-let
+    if let a = 1 { //~ WARN irrefutable if-let
         println!("irrefutable pattern");
     }
 
-    if let a = 1 { //~ ERROR irrefutable if-let
+    if let a = 1 { //~ WARN irrefutable if-let
         println!("irrefutable pattern");
     } else if true {
         println!("else-if in irrefutable if-let");
@@ -33,13 +35,13 @@ pub fn main() {
 
     if let 1 = 2 {
         println!("refutable pattern");
-    } else if let a = 1 { //~ ERROR irrefutable if-let
+    } else if let a = 1 { //~ WARN irrefutable if-let
         println!("irrefutable pattern");
     }
 
     if true {
         println!("if");
-    } else if let a = 1 { //~ ERROR irrefutable if-let
+    } else if let a = 1 { //~ WARN irrefutable if-let
         println!("irrefutable pattern");
     }
 }
index 3802d7828ae7d7b216129b62aef7ad93dd9687ab..b2a104bfacffc7d99713db786f4c391b040d4f19 100644 (file)
@@ -1,39 +1,62 @@
-error[E0162]: irrefutable if-let pattern
-  --> $DIR/if-let.rs:13:10
+warning: irrefutable if-let pattern
+  --> $DIR/if-let.rs:6:13
    |
-LL |     foo!(a, 1, { //~ ERROR irrefutable if-let
-   |          ^ irrefutable pattern
-
-error[E0162]: irrefutable if-let pattern
-  --> $DIR/if-let.rs:16:10
+LL |               if let $p = $e $b
+   |               ^^
+...
+LL | /     foo!(a, 1, { //~ WARN irrefutable if-let
+LL | |         println!("irrefutable pattern");
+LL | |     });
+   | |_______- in this macro invocation
    |
-LL |     bar!(a, 1, { //~ ERROR irrefutable if-let
-   |          ^ irrefutable pattern
+   = note: #[warn(irrefutable_let_patterns)] on by default
 
-error[E0162]: irrefutable if-let pattern
-  --> $DIR/if-let.rs:22:12
+warning: irrefutable if-let pattern
+  --> $DIR/if-let.rs:6:13
    |
-LL |     if let a = 1 { //~ ERROR irrefutable if-let
-   |            ^ irrefutable pattern
+LL |               if let $p = $e $b
+   |               ^^
+...
+LL | /     bar!(a, 1, { //~ WARN irrefutable if-let
+LL | |         println!("irrefutable pattern");
+LL | |     });
+   | |_______- in this macro invocation
 
-error[E0162]: irrefutable if-let pattern
-  --> $DIR/if-let.rs:26:12
+warning: irrefutable if-let pattern
+  --> $DIR/if-let.rs:24:5
    |
-LL |     if let a = 1 { //~ ERROR irrefutable if-let
-   |            ^ irrefutable pattern
+LL | /     if let a = 1 { //~ WARN irrefutable if-let
+LL | |         println!("irrefutable pattern");
+LL | |     }
+   | |_____^
 
-error[E0162]: irrefutable if-let pattern
-  --> $DIR/if-let.rs:36:19
+warning: irrefutable if-let pattern
+  --> $DIR/if-let.rs:28:5
    |
-LL |     } else if let a = 1 { //~ ERROR irrefutable if-let
-   |                   ^ irrefutable pattern
+LL | /     if let a = 1 { //~ WARN irrefutable if-let
+LL | |         println!("irrefutable pattern");
+LL | |     } else if true {
+LL | |         println!("else-if in irrefutable if-let");
+LL | |     } else {
+LL | |         println!("else in irrefutable if-let");
+LL | |     }
+   | |_____^
 
-error[E0162]: irrefutable if-let pattern
-  --> $DIR/if-let.rs:42:19
+warning: irrefutable if-let pattern
+  --> $DIR/if-let.rs:38:12
    |
-LL |     } else if let a = 1 { //~ ERROR irrefutable if-let
-   |                   ^ irrefutable pattern
+LL |       } else if let a = 1 { //~ WARN irrefutable if-let
+   |  ____________^
+LL | |         println!("irrefutable pattern");
+LL | |     }
+   | |_____^
 
-error: aborting due to 6 previous errors
+warning: irrefutable if-let pattern
+  --> $DIR/if-let.rs:44:12
+   |
+LL |       } else if let a = 1 { //~ WARN irrefutable if-let
+   |  ____________^
+LL | |         println!("irrefutable pattern");
+LL | |     }
+   | |_____^
 
-For more information about this error, try `rustc --explain E0162`.
index d6928584b9e430875a65f25f5575cba13afb1817..4acc400f8e79982f9d710d1457f842fcc7a33ea2 100644 (file)
@@ -22,6 +22,17 @@ LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
    = note: ...which again requires processing `cycle1::{{impl-Trait}}`, completing the cycle
+note: cycle used when checking item types in top-level module
+  --> $DIR/auto-trait-leak.rs:3:1
+   |
+LL | / use std::cell::Cell;
+LL | | use std::rc::Rc;
+LL | |
+LL | | fn send<T: Send>(_: T) {}
+...  |
+LL | |     Rc::new(String::from("foo"))
+LL | | }
+   | |_^
 
 error[E0391]: cycle detected when processing `cycle1::{{impl-Trait}}`
   --> $DIR/auto-trait-leak.rs:14:16
@@ -46,6 +57,17 @@ note: ...which requires processing `cycle2`...
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which again requires processing `cycle1::{{impl-Trait}}`, completing the cycle
+note: cycle used when checking item types in top-level module
+  --> $DIR/auto-trait-leak.rs:3:1
+   |
+LL | / use std::cell::Cell;
+LL | | use std::rc::Rc;
+LL | |
+LL | | fn send<T: Send>(_: T) {}
+...  |
+LL | |     Rc::new(String::from("foo"))
+LL | | }
+   | |_^
 
 error[E0277]: `std::rc::Rc<std::string::String>` cannot be sent between threads safely
   --> $DIR/auto-trait-leak.rs:17:5
diff --git a/src/test/ui/imports/extern-crate-used.rs b/src/test/ui/imports/extern-crate-used.rs
new file mode 100644 (file)
index 0000000..2d91cbc
--- /dev/null
@@ -0,0 +1,28 @@
+// Extern crate items are marked as used if they are used
+// through extern prelude entries introduced by them.
+
+// edition:2018
+
+#![deny(unused_extern_crates)]
+
+extern crate core as iso1; //~ ERROR `extern crate` is not idiomatic in the new edition
+extern crate core as iso2; //~ ERROR `extern crate` is not idiomatic in the new edition
+extern crate core as iso3; //~ ERROR `extern crate` is not idiomatic in the new edition
+extern crate core as iso4; //~ ERROR `extern crate` is not idiomatic in the new edition
+
+// Doesn't introduce its extern prelude entry, so it's still considered unused.
+extern crate core; //~ ERROR unused extern crate
+
+mod m {
+    use iso1::any as are_you_okay1;
+    use ::iso2::any as are_you_okay2;
+    type AreYouOkay1 = iso3::any::Any;
+    type AreYouOkay2 = ::iso4::any::Any;
+
+    use core::any as are_you_okay3;
+    use ::core::any as are_you_okay4;
+    type AreYouOkay3 = core::any::Any;
+    type AreYouOkay4 = ::core::any::Any;
+}
+
+fn main() {}
diff --git a/src/test/ui/imports/extern-crate-used.stderr b/src/test/ui/imports/extern-crate-used.stderr
new file mode 100644 (file)
index 0000000..3f9aab9
--- /dev/null
@@ -0,0 +1,38 @@
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/extern-crate-used.rs:8:1
+   |
+LL | extern crate core as iso1; //~ ERROR `extern crate` is not idiomatic in the new edition
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
+   |
+note: lint level defined here
+  --> $DIR/extern-crate-used.rs:6:9
+   |
+LL | #![deny(unused_extern_crates)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/extern-crate-used.rs:9:1
+   |
+LL | extern crate core as iso2; //~ ERROR `extern crate` is not idiomatic in the new edition
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
+
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/extern-crate-used.rs:10:1
+   |
+LL | extern crate core as iso3; //~ ERROR `extern crate` is not idiomatic in the new edition
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
+
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/extern-crate-used.rs:11:1
+   |
+LL | extern crate core as iso4; //~ ERROR `extern crate` is not idiomatic in the new edition
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
+
+error: unused extern crate
+  --> $DIR/extern-crate-used.rs:14:1
+   |
+LL | extern crate core; //~ ERROR unused extern crate
+   | ^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: aborting due to 5 previous errors
+
index 0327522e4b8d60760f6c3259ca885cf2a0972b79..ec5747b4bca8c8b0c75aaa9fd62c93c6dffefb2d 100644 (file)
@@ -2,8 +2,6 @@
 // compile-flags:--extern issue_56125
 // aux-build:issue-56125.rs
 
-#![feature(uniform_paths)]
-
 mod m1 {
     use issue_56125::last_segment::*;
     //~^ ERROR `issue_56125` is ambiguous
index 210f6a43996355c53a00a6d1a18213d257fc03fa..844962b910a6917ad08f36ca4a97f826f828e7fa 100644 (file)
@@ -1,11 +1,11 @@
 error[E0432]: unresolved import `empty::issue_56125`
-  --> $DIR/issue-56125.rs:19:9
+  --> $DIR/issue-56125.rs:17:9
    |
 LL |     use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125`
    |         ^^^^^^^^^^^^^^^^^^ no `issue_56125` in `m3::empty`
 
 error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution)
-  --> $DIR/issue-56125.rs:8:9
+  --> $DIR/issue-56125.rs:6:9
    |
 LL |     use issue_56125::last_segment::*;
    |         ^^^^^^^^^^^ ambiguous name
@@ -13,14 +13,14 @@ LL |     use issue_56125::last_segment::*;
    = note: `issue_56125` could refer to an extern crate passed with `--extern`
    = help: use `::issue_56125` to refer to this extern crate unambiguously
 note: `issue_56125` could also refer to the module imported here
-  --> $DIR/issue-56125.rs:8:9
+  --> $DIR/issue-56125.rs:6:9
    |
 LL |     use issue_56125::last_segment::*;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: use `self::issue_56125` to refer to this module unambiguously
 
 error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution)
-  --> $DIR/issue-56125.rs:13:9
+  --> $DIR/issue-56125.rs:11:9
    |
 LL |     use issue_56125::non_last_segment::non_last_segment::*;
    |         ^^^^^^^^^^^ ambiguous name
@@ -28,14 +28,14 @@ LL |     use issue_56125::non_last_segment::non_last_segment::*;
    = note: `issue_56125` could refer to an extern crate passed with `--extern`
    = help: use `::issue_56125` to refer to this extern crate unambiguously
 note: `issue_56125` could also refer to the module imported here
-  --> $DIR/issue-56125.rs:13:9
+  --> $DIR/issue-56125.rs:11:9
    |
 LL |     use issue_56125::non_last_segment::non_last_segment::*;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: use `self::issue_56125` to refer to this module unambiguously
 
 error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution)
-  --> $DIR/issue-56125.rs:20:9
+  --> $DIR/issue-56125.rs:18:9
    |
 LL |     use issue_56125::*; //~ ERROR `issue_56125` is ambiguous
    |         ^^^^^^^^^^^ ambiguous name
@@ -43,7 +43,7 @@ LL |     use issue_56125::*; //~ ERROR `issue_56125` is ambiguous
    = note: `issue_56125` could refer to an extern crate passed with `--extern`
    = help: use `::issue_56125` to refer to this extern crate unambiguously
 note: `issue_56125` could also refer to the module imported here
-  --> $DIR/issue-56125.rs:20:9
+  --> $DIR/issue-56125.rs:18:9
    |
 LL |     use issue_56125::*; //~ ERROR `issue_56125` is ambiguous
    |         ^^^^^^^^^^^^^^
index eb1461a7b29e1675271238326ac7fb1f87c9faee..daa18a7e9b1ce1928a3b3ace0808756a8247acba 100644 (file)
@@ -5,6 +5,14 @@ LL | type X = Vec<X>;
    |              ^
    |
    = note: ...which again requires processing `X`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/infinite-vec-type-recursion.rs:1:1
+   |
+LL | / type X = Vec<X>;
+LL | | //~^ ERROR cycle detected
+LL | |
+LL | | fn main() { let b: X = Vec::new(); }
+   | |____________________________________^
 
 error: aborting due to previous error
 
index 05d2685958eb87dbb2f8b0d4726795b0501c4984..683ad48ff52c0b4249eefe376f2474f353961678 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/issue-11844.rs:6:9
    |
+LL |     match a {
+   |           - this match expression has type `std::option::Option<std::boxed::Box<{integer}>>`
 LL |         Ok(a) => //~ ERROR: mismatched types
    |         ^^^^^ expected enum `std::option::Option`, found enum `std::result::Result`
    |
index 945cdc745efb0ab12127f23b0f121d3403927110..37e38ff60ae4bd55bf2eea482ed5babc3fcb3b45 100644 (file)
@@ -10,6 +10,11 @@ note: ...which requires computing the supertraits of `T2`...
 LL | trait T2 : T1 {
    |            ^^
    = note: ...which again requires computing the supertraits of `T1`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/issue-12511.rs:1:1
+   |
+LL | trait T1 : T2 {
+   | ^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index ca5efcdc4726abd66855b38686998cc2059625d0..768d11bf899a1f333f33f22c15aeb0c8769305aa 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/issue-12552.rs:6:5
    |
+LL |   match t {
+   |         - this match expression has type `std::result::Result<_, {integer}>`
 LL |     Some(k) => match k { //~ ERROR mismatched types
    |     ^^^^^^^ expected enum `std::result::Result`, found enum `std::option::Option`
    |
index 2f60070337b77aea27d022e3bf96ec36dc619879..66255891f469a01534d355464546a796ca3c14f1 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/issue-13466.rs:8:9
    |
+LL |     let _x: usize = match Some(1) {
+   |                           ------- this match expression has type `std::option::Option<{integer}>`
 LL |         Ok(u) => u,
    |         ^^^^^ expected enum `std::option::Option`, found enum `std::result::Result`
    |
@@ -10,6 +12,9 @@ LL |         Ok(u) => u,
 error[E0308]: mismatched types
   --> $DIR/issue-13466.rs:14:9
    |
+LL |     let _x: usize = match Some(1) {
+   |                           ------- this match expression has type `std::option::Option<{integer}>`
+...
 LL |         Err(e) => panic!(e)
    |         ^^^^^^ expected enum `std::option::Option`, found enum `std::result::Result`
    |
index cd629841fee839c45c52315305a4de6487870942..de9757d5d32ed912e4cc322177d84d0b9b74e658 100644 (file)
@@ -1,6 +1,9 @@
 error[E0308]: mismatched types
   --> $DIR/issue-15896.rs:11:11
    |
+LL |     let u = match e {
+   |                   - this match expression has type `main::R`
+LL |         E::B(
 LL |           Tau{t: x},
    |           ^^^^^^^^^ expected enum `main::R`, found struct `main::Tau`
    |
index a1cf6c98705aa5a9c0a9a455478c45246f36a30b..1779d0befd871faab0eb4d6751dcb64ce5fa8d9f 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/issue-16401.rs:8:9
    |
+LL |     match () {
+   |           -- this match expression has type `()`
 LL |         Slice { data: data, len: len } => (),
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found struct `Slice`
    |
index 3d42dcb52f5db1966810ef67f5269a04c6b22b21..823f2c747d686b3a8c819d2b348e0e86a8cc13a0 100644 (file)
@@ -13,7 +13,7 @@ error[E0502]: cannot borrow `foo` (via `foo.b`) as immutable because `foo` is al
   --> $DIR/issue-17263.rs:21:32
    |
 LL |     let (c, d) = (&mut foo.a, &foo.b);
-   |                        -----   ^^^^^ immutable borrow occurs here (via `foo.b`)
+   |                        -----   ^^^^^ immutable borrow of `foo.b` -- which overlaps with `foo.a` -- occurs here
    |                        |
    |                        mutable borrow occurs here (via `foo.a`)
 ...
index 9b3d84b3dd51c50cd35831179e73d619aabbce08..d30b95843f300a5c7b559f2158eb1795a53880d4 100644 (file)
@@ -1,8 +1,8 @@
 #![warn(unused)]
-#[deny(warnings)]
+#![deny(warnings)]
 
 const foo: isize = 3;
-//~^ ERROR: should have an upper case name such as
+//~^ ERROR: should have an upper case name
 //~^^ ERROR: constant item is never used
 
 fn main() {}
index 641e50a5fc9b7d68e944521cc80e0e40a63ba2e6..b92acecb83eca0ecb589d70ac252c73093509ed9 100644 (file)
@@ -5,23 +5,23 @@ LL | const foo: isize = 3;
    | ^^^^^^^^^^^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/issue-17718-const-naming.rs:2:8
+  --> $DIR/issue-17718-const-naming.rs:2:9
    |
-LL | #[deny(warnings)]
-   |        ^^^^^^^^
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
    = note: #[deny(dead_code)] implied by #[deny(warnings)]
 
-error: constant `foo` should have an upper case name such as `FOO`
-  --> $DIR/issue-17718-const-naming.rs:4:1
+error: constant `foo` should have an upper case name
+  --> $DIR/issue-17718-const-naming.rs:4:7
    |
 LL | const foo: isize = 3;
-   | ^^^^^^^^^^^^^^^^^^^^^
+   |       ^^^ help: convert the identifier to upper case: `FOO`
    |
 note: lint level defined here
-  --> $DIR/issue-17718-const-naming.rs:2:8
+  --> $DIR/issue-17718-const-naming.rs:2:9
    |
-LL | #[deny(warnings)]
-   |        ^^^^^^^^
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
    = note: #[deny(non_upper_case_globals)] implied by #[deny(warnings)]
 
 error: aborting due to 2 previous errors
index d3084b0616776b3060f9fe3a9fd7abf830c4ade7..1920e1637d1494905bf9ebcefa5c8b3a07c2b9b8 100644 (file)
@@ -1,68 +1,14 @@
-error[E0658]: let bindings in constants are unstable (see issue #48821)
-  --> $DIR/issue-18118.rs:5:17
-   |
-LL |         let p = 3;
-   |                 ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/issue-18118.rs:5:17
-   |
-LL |         let p = 3;
-   |                 ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in constants are unstable (see issue #48821)
-  --> $DIR/issue-18118.rs:8:9
-   |
-LL |         &p //~ ERROR `p` does not live long enough
-   |         ^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in constants are unstable (see issue #48821)
-  --> $DIR/issue-18118.rs:2:5
-   |
-LL | /     const z: &'static isize = {
-LL | |         //~^ ERROR let bindings in constants are unstable
-LL | |         //~| ERROR statements in constants are unstable
-LL | |         let p = 3;
-...  |
-LL | |         //~^ ERROR let bindings in constants are unstable
-LL | |     };
-   | |______^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/issue-18118.rs:2:5
-   |
-LL | /     const z: &'static isize = {
-LL | |         //~^ ERROR let bindings in constants are unstable
-LL | |         //~| ERROR statements in constants are unstable
-LL | |         let p = 3;
-...  |
-LL | |         //~^ ERROR let bindings in constants are unstable
-LL | |     };
-   | |______^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
 error[E0597]: `p` does not live long enough
-  --> $DIR/issue-18118.rs:8:9
+  --> $DIR/issue-18118.rs:4:9
    |
 LL |         &p //~ ERROR `p` does not live long enough
    |         ^^
    |         |
    |         borrowed value does not live long enough
    |         using this value as a constant requires that `p` is borrowed for `'static`
-LL |         //~^ ERROR let bindings in constants are unstable
 LL |     };
    |     - `p` dropped here while still borrowed
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error
 
-Some errors occurred: E0597, E0658.
-For more information about an error, try `rustc --explain E0597`.
+For more information about this error, try `rustc --explain E0597`.
index 7bbea191cd16723c904b142a6b67baee768a0489..f58a3de281f1ae1123e7ec98c7057e050f72c947 100644 (file)
@@ -1,11 +1,6 @@
 pub fn main() {
     const z: &'static isize = {
-        //~^ ERROR let bindings in constants are unstable
-        //~| ERROR statements in constants are unstable
         let p = 3;
-        //~^ ERROR let bindings in constants are unstable
-        //~| ERROR statements in constants are unstable
         &p //~ ERROR `p` does not live long enough
-        //~^ ERROR let bindings in constants are unstable
     };
 }
index 1383cdb4438c931755b2acc6489f00da5565989b..9b21ece341a9f2fa87b66cb7b8d39220237591ea 100644 (file)
@@ -1,67 +1,13 @@
-error[E0658]: let bindings in constants are unstable (see issue #48821)
-  --> $DIR/issue-18118.rs:5:17
-   |
-LL |         let p = 3;
-   |                 ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/issue-18118.rs:5:17
-   |
-LL |         let p = 3;
-   |                 ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in constants are unstable (see issue #48821)
-  --> $DIR/issue-18118.rs:8:9
-   |
-LL |         &p //~ ERROR `p` does not live long enough
-   |         ^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: let bindings in constants are unstable (see issue #48821)
-  --> $DIR/issue-18118.rs:2:5
-   |
-LL | /     const z: &'static isize = {
-LL | |         //~^ ERROR let bindings in constants are unstable
-LL | |         //~| ERROR statements in constants are unstable
-LL | |         let p = 3;
-...  |
-LL | |         //~^ ERROR let bindings in constants are unstable
-LL | |     };
-   | |______^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/issue-18118.rs:2:5
-   |
-LL | /     const z: &'static isize = {
-LL | |         //~^ ERROR let bindings in constants are unstable
-LL | |         //~| ERROR statements in constants are unstable
-LL | |         let p = 3;
-...  |
-LL | |         //~^ ERROR let bindings in constants are unstable
-LL | |     };
-   | |______^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
 error[E0597]: `p` does not live long enough
-  --> $DIR/issue-18118.rs:8:10
+  --> $DIR/issue-18118.rs:4:10
    |
 LL |         &p //~ ERROR `p` does not live long enough
    |          ^ borrowed value does not live long enough
-LL |         //~^ ERROR let bindings in constants are unstable
 LL |     };
    |     - borrowed value only lives until here
    |
    = note: borrowed value must be valid for the static lifetime...
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error
 
-Some errors occurred: E0597, E0658.
-For more information about an error, try `rustc --explain E0597`.
+For more information about this error, try `rustc --explain E0597`.
index 15a5fc40926fef439681fe8b5766ce75dea5d343..7dc4e43fd573db65af75d8a03a307babd9ee46f3 100644 (file)
@@ -8,6 +8,14 @@ LL | | {}
    | |__^
    |
    = note: ...which again requires computing the supertraits of `T`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/issue-20772.rs:1:1
+   |
+LL | / trait T : Iterator<Item=Self::Item>
+LL | | //~^ ERROR cycle detected
+LL | | //~| ERROR associated type `Item` not found for `Self`
+LL | | {}
+   | |__^
 
 error[E0220]: associated type `Item` not found for `Self`
   --> $DIR/issue-20772.rs:1:25
index 1df51dc2d41ac92cf37c76bcd0288628bc795880..5f9709d1c649badb26b724e024d9ecda38bf9e78 100644 (file)
@@ -5,6 +5,11 @@ LL | pub trait Processor: Subscriber<Input = Self::Input> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: ...which again requires computing the supertraits of `Processor`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/issue-20825.rs:5:1
+   |
+LL | pub trait Processor: Subscriber<Input = Self::Input> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 4b5730c91eb55ab1241216cb0bb09f8d55470ee3..9e7e4b218b1c668cdba6e31068cc2af5c05316b2 100644 (file)
@@ -5,6 +5,11 @@ LL | trait Expr : PartialEq<Self::Item> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: ...which again requires computing the supertraits of `Expr`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/issue-22673.rs:1:1
+   |
+LL | trait Expr : PartialEq<Self::Item> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 9db9d30411d6f16cafac1b0689cbffa8f8170d5f..c93c84b5fb7732d342cb1b68597cdb0091aa845e 100644 (file)
@@ -1,11 +1,8 @@
 // ignore-tidy-linelength
 
-#![feature(const_fn)]
-
 const bad : u32 = {
     {
         5;
-        //~^ ERROR statements in constants are unstable
         0
     }
 };
@@ -13,8 +10,7 @@
 const bad_two : u32 = {
     {
         invalid();
-        //~^ ERROR statements in constants are unstable
-        //~^^ ERROR: calls in constants are limited to constant functions, tuple structs and tuple variants
+        //~^ ERROR: calls in constants are limited to constant functions, tuple structs and tuple variants
         0
     }
 };
@@ -22,7 +18,6 @@
 const bad_three : u32 = {
     {
         valid();
-        //~^ ERROR statements in constants are unstable
         0
     }
 };
@@ -30,7 +25,6 @@
 static bad_four : u32 = {
     {
         5;
-        //~^ ERROR statements in statics are unstable
         0
     }
 };
@@ -39,7 +33,6 @@
     {
         invalid();
         //~^ ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants
-        //~| ERROR statements in statics are unstable
         0
     }
 };
@@ -47,7 +40,6 @@
 static bad_six : u32 = {
     {
         valid();
-        //~^ ERROR statements in statics are unstable
         0
     }
 };
@@ -55,7 +47,6 @@
 static mut bad_seven : u32 = {
     {
         5;
-        //~^ ERROR statements in statics are unstable
         0
     }
 };
@@ -63,8 +54,7 @@
 static mut bad_eight : u32 = {
     {
         invalid();
-        //~^ ERROR statements in statics are unstable
-        //~| ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants
+        //~^ ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants
         0
     }
 };
@@ -72,7 +62,6 @@
 static mut bad_nine : u32 = {
     {
         valid();
-        //~^ ERROR statements in statics are unstable
         0
     }
 };
index 7fe0261281830fe30fe24f1fceabffa3f7be38a6..8d7423f29ae97acc537b695bd25c0096994067b6 100644 (file)
@@ -1,94 +1,21 @@
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/issue-32829-2.rs:7:9
-   |
-LL |         5;
-   |         ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
 error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
-  --> $DIR/issue-32829-2.rs:15:9
+  --> $DIR/issue-32829-2.rs:12:9
    |
 LL |         invalid();
    |         ^^^^^^^^^
 
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/issue-32829-2.rs:15:9
-   |
-LL |         invalid();
-   |         ^^^^^^^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in constants are unstable (see issue #48821)
-  --> $DIR/issue-32829-2.rs:24:9
-   |
-LL |         valid();
-   |         ^^^^^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in statics are unstable (see issue #48821)
-  --> $DIR/issue-32829-2.rs:32:9
-   |
-LL |         5;
-   |         ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
 error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
-  --> $DIR/issue-32829-2.rs:40:9
+  --> $DIR/issue-32829-2.rs:34:9
    |
 LL |         invalid();
    |         ^^^^^^^^^
 
-error[E0658]: statements in statics are unstable (see issue #48821)
-  --> $DIR/issue-32829-2.rs:40:9
-   |
-LL |         invalid();
-   |         ^^^^^^^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in statics are unstable (see issue #48821)
-  --> $DIR/issue-32829-2.rs:49:9
-   |
-LL |         valid();
-   |         ^^^^^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in statics are unstable (see issue #48821)
-  --> $DIR/issue-32829-2.rs:57:9
-   |
-LL |         5;
-   |         ^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
 error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
-  --> $DIR/issue-32829-2.rs:65:9
+  --> $DIR/issue-32829-2.rs:56:9
    |
 LL |         invalid();
    |         ^^^^^^^^^
 
-error[E0658]: statements in statics are unstable (see issue #48821)
-  --> $DIR/issue-32829-2.rs:65:9
-   |
-LL |         invalid();
-   |         ^^^^^^^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error[E0658]: statements in statics are unstable (see issue #48821)
-  --> $DIR/issue-32829-2.rs:74:9
-   |
-LL |         valid();
-   |         ^^^^^^^
-   |
-   = help: add #![feature(const_let)] to the crate attributes to enable
-
-error: aborting due to 12 previous errors
+error: aborting due to 3 previous errors
 
-Some errors occurred: E0015, E0658.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0015`.
index 45e8d1bf3e3996a8d7aeb41b50feefa22bfdceff..07ac421455cf6e02cae79ac7d9d2dfa15a78e943 100644 (file)
@@ -10,6 +10,17 @@ note: ...which requires processing `DefaultFoo`...
 LL | type DefaultFoo = Foo;
    |                   ^^^
    = note: ...which again requires processing `Foo::T`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/issue-34373.rs:1:1
+   |
+LL | / #![allow(warnings)]
+LL | |
+LL | | trait Trait<T> {
+LL | |     fn foo(_: T) {}
+...  |
+LL | | fn main() {
+LL | | }
+   | |_^
 
 error: aborting due to previous error
 
index 78c3f92fb53b5172de6e036e4c43e0c158004217..51903cfadab15e4ee9096679d32a83cb3a1a4634 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/issue-3680.rs:3:9
    |
+LL |     match None {
+   |           ---- this match expression has type `std::option::Option<_>`
 LL |         Err(_) => ()
    |         ^^^^^^ expected enum `std::option::Option`, found enum `std::result::Result`
    |
index 12282f3e548870e60e89c1f65283b515329d5874..505c030b967122758a770ba84f1d7081bc9ee04d 100644 (file)
@@ -1,6 +1,6 @@
 const fn x() {
-    let t = true; //~ ERROR local variables in const fn
-    let x = || t;
+    let t = true;
+    let x = || t; //~ ERROR function pointers in const fn are unstable
 }
 
 fn main() {}
index d42f72ad3fac837fb3982fce16a73a2fec17c3e5..d2b03416cb73cb923de830cf930bcd8dfd6a2362 100644 (file)
@@ -1,7 +1,7 @@
-error: local variables in const fn are unstable
-  --> $DIR/issue-37550.rs:2:9
+error: function pointers in const fn are unstable
+  --> $DIR/issue-37550.rs:3:9
    |
-LL |     let t = true; //~ ERROR local variables in const fn
+LL |     let x = || t; //~ ERROR function pointers in const fn are unstable
    |         ^
 
 error: aborting due to previous error
index c2c9ed62d4edc1d9992d8f27f189d3e7893cace9..22ea254a769e842d64dc1a690031127a43267dbe 100644 (file)
@@ -1,6 +1,8 @@
 #![allow(unused)]
 #![feature(nll)]
 
+// ignore-tidy-linelength
+
 #[derive(Clone, Copy, Default)]
 struct S {
     a: u8,
@@ -25,8 +27,7 @@ fn main() {
         *mref = 22;
 
         let nref = &u.z.c;
-        //~^ ERROR cannot borrow `u.z.c` as immutable because it is also borrowed as mutable [E0502]
+        //~^ ERROR cannot borrow `u` (via `u.z.c`) as immutable because it is also borrowed as mutable (via `u.s.a`) [E0502]
         println!("{} {}", mref, nref)
     }
 }
-
index 038d6ecf48d29415ed3043d5d2daa221df15a9cb..3b15a8dbd9ef86f92635d4240dfd556a232ece48 100644 (file)
@@ -1,14 +1,16 @@
-error[E0502]: cannot borrow `u.z.c` as immutable because it is also borrowed as mutable
-  --> $DIR/issue-45157.rs:27:20
+error[E0502]: cannot borrow `u` (via `u.z.c`) as immutable because it is also borrowed as mutable (via `u.s.a`)
+  --> $DIR/issue-45157.rs:29:20
    |
 LL |         let mref = &mut u.s.a;
-   |                    ---------- mutable borrow occurs here
+   |                    ---------- mutable borrow occurs here (via `u.s.a`)
 ...
 LL |         let nref = &u.z.c;
-   |                    ^^^^^^ immutable borrow occurs here
-LL |         //~^ ERROR cannot borrow `u.z.c` as immutable because it is also borrowed as mutable [E0502]
+   |                    ^^^^^^ immutable borrow of `u.z.c` -- which overlaps with `u.s.a` -- occurs here
+LL |         //~^ ERROR cannot borrow `u` (via `u.z.c`) as immutable because it is also borrowed as mutable (via `u.s.a`) [E0502]
 LL |         println!("{} {}", mref, nref)
    |                           ---- mutable borrow later used here
+   |
+   = note: `u.z.c` is a field of the union `U`, so it overlaps the field `u.s.a`
 
 error: aborting due to previous error
 
index a6f6229fe78d2dd0e1d4626d8c5b3bb42659eead..0a918a789703e5f0e66725373b2e78026dfe3575 100644 (file)
@@ -28,6 +28,8 @@ LL |         (true, false, false) => ()
 error[E0308]: mismatched types
   --> $DIR/issue-5100.rs:33:9
    |
+LL |     match (true, false) {
+   |           ------------- this match expression has type `(bool, bool)`
 LL |         box (true, false) => ()
    |         ^^^^^^^^^^^^^^^^^ expected tuple, found struct `std::boxed::Box`
    |
index b52e3ac6abd846c8abbf196e1490bf767b169024..4885e4a2db7d5e5a0fa6b7dd894dd993716c078f 100644 (file)
@@ -10,5 +10,5 @@ fn main() {
 
     [(); return while let Some(n) = Some(0) {}];
     //~^ ERROR return statement outside of function body
-    //~^^ ERROR irrefutable while-let pattern
+    //~^^ WARN irrefutable while-let pattern
 }
index 47a8b415b0cf04ef3978570f3f70ac2692f4c813..df11f6b7f5a535c3a06f0ba10bc02f99b373fb7b 100644 (file)
@@ -22,13 +22,14 @@ error[E0572]: return statement outside of function body
 LL |     [(); return while let Some(n) = Some(0) {}];
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0165]: irrefutable while-let pattern
-  --> $DIR/issue-51714.rs:11:27
+warning: irrefutable while-let pattern
+  --> $DIR/issue-51714.rs:11:17
    |
 LL |     [(); return while let Some(n) = Some(0) {}];
-   |                           ^^^^^^^ irrefutable pattern
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: #[warn(irrefutable_let_patterns)] on by default
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
-Some errors occurred: E0165, E0572.
-For more information about an error, try `rustc --explain E0165`.
+For more information about this error, try `rustc --explain E0572`.
index dbbafb38e6580a02b23e19717aeb74948b389639..649a0c1581a687e0069b1e2504d13e5d7722d46c 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/issue-5358-1.rs:6:9
    |
+LL |     match S(Either::Left(5)) {
+   |           ------------------ this match expression has type `S`
 LL |         Either::Right(_) => {}
    |         ^^^^^^^^^^^^^^^^ expected struct `S`, found enum `Either`
    |
diff --git a/src/test/ui/issues/issue-57156.rs b/src/test/ui/issues/issue-57156.rs
new file mode 100644 (file)
index 0000000..f20b0f4
--- /dev/null
@@ -0,0 +1,23 @@
+// compile-pass
+
+trait Foo<Args> {
+    type Output;
+}
+
+trait Bar<'a, T>: for<'s> Foo<&'s T, Output=bool> {
+    fn cb(&self) -> Box<dyn Bar<'a, T, Output=bool>>;
+}
+
+impl<'s> Foo<&'s ()> for () {
+    type Output = bool;
+}
+
+impl<'a> Bar<'a, ()> for () {
+    fn cb(&self) -> Box<dyn Bar<'a, (), Output=bool>> {
+        Box::new(*self)
+    }
+}
+
+fn main() {
+    let _t = ().cb();
+}
diff --git a/src/test/ui/issues/issue-57472.rs b/src/test/ui/issues/issue-57472.rs
new file mode 100644 (file)
index 0000000..1131006
--- /dev/null
@@ -0,0 +1,35 @@
+#![crate_type="lib"]
+#![deny(unreachable_patterns)]
+
+mod test_struct {
+    // Test the exact copy of the minimal example
+    // posted in the issue.
+    pub struct Punned {
+        foo: [u8; 1],
+        bar: [u8; 1],
+    }
+
+    pub fn test(punned: Punned) {
+        match punned {
+            Punned { foo: [_], .. } => println!("foo"),
+            Punned { bar: [_], .. } => println!("bar"),
+            //~^ ERROR unreachable pattern [unreachable_patterns]
+        }
+    }
+}
+
+mod test_union {
+    // Test the same thing using a union.
+    pub union Punned {
+        foo: [u8; 1],
+        bar: [u8; 1],
+    }
+
+    pub fn test(punned: Punned) {
+        match punned {
+            Punned { foo: [_] } => println!("foo"),
+            Punned { bar: [_] } => println!("bar"),
+            //~^ ERROR unreachable pattern [unreachable_patterns]
+        }
+    }
+}
diff --git a/src/test/ui/issues/issue-57472.stderr b/src/test/ui/issues/issue-57472.stderr
new file mode 100644 (file)
index 0000000..b6dd7e2
--- /dev/null
@@ -0,0 +1,20 @@
+error: unreachable pattern
+  --> $DIR/issue-57472.rs:15:13
+   |
+LL |             Punned { bar: [_], .. } => println!("bar"),
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/issue-57472.rs:2:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/issue-57472.rs:31:13
+   |
+LL |             Punned { bar: [_] } => println!("bar"),
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
index aa24182e3a39dbf29d74bfbf1a259c6a34a7761a..7bb682028748706ea5aa1c406e11c5de8035d7b6 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/issue-7092.rs:6:9
    |
+LL |     match x {
+   |           - this match expression has type `Whatever`
 LL |         Some(field) =>
    |         ^^^^^^^^^^^ expected enum `Whatever`, found enum `std::option::Option`
    |
index 3f9c2ef48a7af73baa9f3cadddebe229750b2c68..52ec9e42be78282a46f370d2bc2dca078ab536b0 100644 (file)
@@ -6,5 +6,6 @@
 static boxed: Box<RefCell<isize>> = box RefCell::new(0);
 //~^ ERROR allocations are not allowed in statics
 //~| ERROR `std::cell::RefCell<isize>` cannot be shared between threads safely [E0277]
+//~| ERROR static contains unimplemented expression type
 
 fn main() { }
index 0e4d6ff1d71fa26187ac7bccb027ebc3a9028d36..52a99ce36b8704ced0caa0280cadd1941dafa2df 100644 (file)
@@ -4,6 +4,12 @@ error[E0010]: allocations are not allowed in statics
 LL | static boxed: Box<RefCell<isize>> = box RefCell::new(0);
    |                                     ^^^^^^^^^^^^^^^^^^^ allocation not allowed in statics
 
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/issue-7364.rs:6:41
+   |
+LL | static boxed: Box<RefCell<isize>> = box RefCell::new(0);
+   |                                         ^^^^^^^^^^^^^^^
+
 error[E0277]: `std::cell::RefCell<isize>` cannot be shared between threads safely
   --> $DIR/issue-7364.rs:6:1
    |
@@ -15,7 +21,7 @@ LL | static boxed: Box<RefCell<isize>> = box RefCell::new(0);
    = note: required because it appears within the type `std::boxed::Box<std::cell::RefCell<isize>>`
    = note: shared static variables must have a type that implements `Sync`
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
-Some errors occurred: E0010, E0277.
+Some errors occurred: E0010, E0019, E0277.
 For more information about an error, try `rustc --explain E0010`.
index c6a8f33829863953f943c216cf461c795c4a04cb..3250a41ee0ecdc940c459130a633181b6d3ab0f9 100644 (file)
@@ -1,8 +1,8 @@
-error: variable `_InappropriateCamelCasing` should have a snake case name such as `_inappropriate_camel_casing`
+error: variable `_InappropriateCamelCasing` should have a snake case name
   --> $DIR/command-line-lint-group-deny.rs:4:9
    |
 LL |     let _InappropriateCamelCasing = true; //~ ERROR should have a snake
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `_inappropriate_camel_casing`
    |
    = note: `-D non-snake-case` implied by `-D bad-style`
 
index 2c11cca96398b45784a184b680791f0f7e37ae3f..39f6da400c4935b1e7da45567182519327951486 100644 (file)
@@ -1,8 +1,8 @@
-error: variable `_InappropriateCamelCasing` should have a snake case name such as `_inappropriate_camel_casing`
+error: variable `_InappropriateCamelCasing` should have a snake case name
   --> $DIR/command-line-lint-group-forbid.rs:4:9
    |
 LL |     let _InappropriateCamelCasing = true; //~ ERROR should have a snake
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `_inappropriate_camel_casing`
    |
    = note: `-F non-snake-case` implied by `-F bad-style`
 
index 3939461ef57427d986aa907b2ff0d7daf9298824..42a198fe7e3e2bcfd41eb0383506f3a99235db83 100644 (file)
@@ -1,8 +1,8 @@
-warning: variable `_InappropriateCamelCasing` should have a snake case name such as `_inappropriate_camel_casing`
+warning: variable `_InappropriateCamelCasing` should have a snake case name
   --> $DIR/command-line-lint-group-warn.rs:5:9
    |
 LL |     let _InappropriateCamelCasing = true;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `_inappropriate_camel_casing`
    |
    = note: `-W non-snake-case` implied by `-W bad-style`
 
index d85ca7811d01e97e066f6cf228bb7126e8ed3150..f3c7d70054b777a4da352a603adc8cff81f95bda 100644 (file)
@@ -1,8 +1,8 @@
-warning: type `snake_case` should have a camel case name such as `SnakeCase`
-  --> $DIR/lint-group-nonstandard-style.rs:22:9
+warning: type `snake_case` should have a camel case name
+  --> $DIR/lint-group-nonstandard-style.rs:22:16
    |
 LL |         struct snake_case; //~ WARN should have a camel
-   |         ^^^^^^^^^^^^^^^^^^
+   |                ^^^^^^^^^^ help: convert the identifier to camel case: `SnakeCase`
    |
 note: lint level defined here
   --> $DIR/lint-group-nonstandard-style.rs:18:17
@@ -11,11 +11,11 @@ LL |         #![warn(nonstandard_style)]
    |                 ^^^^^^^^^^^^^^^^^
    = note: #[warn(non_camel_case_types)] implied by #[warn(nonstandard_style)]
 
-error: function `CamelCase` should have a snake case name such as `camel_case`
-  --> $DIR/lint-group-nonstandard-style.rs:4:1
+error: function `CamelCase` should have a snake case name
+  --> $DIR/lint-group-nonstandard-style.rs:4:4
    |
 LL | fn CamelCase() {} //~ ERROR should have a snake
-   | ^^^^^^^^^^^^^^^^^
+   |    ^^^^^^^^^ help: convert the identifier to snake case: `camel_case`
    |
 note: lint level defined here
   --> $DIR/lint-group-nonstandard-style.rs:1:9
@@ -24,11 +24,11 @@ LL | #![deny(nonstandard_style)]
    |         ^^^^^^^^^^^^^^^^^
    = note: #[deny(non_snake_case)] implied by #[deny(nonstandard_style)]
 
-error: function `CamelCase` should have a snake case name such as `camel_case`
-  --> $DIR/lint-group-nonstandard-style.rs:12:9
+error: function `CamelCase` should have a snake case name
+  --> $DIR/lint-group-nonstandard-style.rs:12:12
    |
 LL |         fn CamelCase() {} //~ ERROR should have a snake
-   |         ^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^ help: convert the identifier to snake case: `camel_case`
    |
 note: lint level defined here
   --> $DIR/lint-group-nonstandard-style.rs:10:14
@@ -37,11 +37,11 @@ LL |     #[forbid(nonstandard_style)]
    |              ^^^^^^^^^^^^^^^^^
    = note: #[forbid(non_snake_case)] implied by #[forbid(nonstandard_style)]
 
-error: static variable `bad` should have an upper case name such as `BAD`
-  --> $DIR/lint-group-nonstandard-style.rs:14:9
+error: static variable `bad` should have an upper case name
+  --> $DIR/lint-group-nonstandard-style.rs:14:16
    |
 LL |         static bad: isize = 1; //~ ERROR should have an upper
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |                ^^^ help: convert the identifier to upper case: `BAD`
    |
 note: lint level defined here
   --> $DIR/lint-group-nonstandard-style.rs:10:14
@@ -50,11 +50,11 @@ LL |     #[forbid(nonstandard_style)]
    |              ^^^^^^^^^^^^^^^^^
    = note: #[forbid(non_upper_case_globals)] implied by #[forbid(nonstandard_style)]
 
-warning: function `CamelCase` should have a snake case name such as `camel_case`
-  --> $DIR/lint-group-nonstandard-style.rs:20:9
+warning: function `CamelCase` should have a snake case name
+  --> $DIR/lint-group-nonstandard-style.rs:20:12
    |
 LL |         fn CamelCase() {} //~ WARN should have a snake
-   |         ^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^ help: convert the identifier to snake case: `camel_case`
    |
 note: lint level defined here
   --> $DIR/lint-group-nonstandard-style.rs:18:17
diff --git a/src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs b/src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs
new file mode 100644 (file)
index 0000000..8ca5af2
--- /dev/null
@@ -0,0 +1,63 @@
+// compile-pass
+// Issue #7526: lowercase static constants in patterns look like bindings
+
+// This is similar to lint-lowercase-static-const-pattern.rs, except it
+// shows the expected usual workaround (choosing a different name for
+// the static definition) and also demonstrates that one can work
+// around this problem locally by renaming the constant in the `use`
+// form to an uppercase identifier that placates the lint.
+
+#![deny(non_upper_case_globals)]
+
+pub const A : isize = 97;
+
+fn f() {
+    let r = match (0,0) {
+        (0, A) => 0,
+        (x, y) => 1 + x + y,
+    };
+    assert_eq!(r, 1);
+    let r = match (0,97) {
+        (0, A) => 0,
+        (x, y) => 1 + x + y,
+    };
+    assert_eq!(r, 0);
+}
+
+mod m {
+    #[allow(non_upper_case_globals)]
+    pub const aha : isize = 7;
+}
+
+fn g() {
+    use self::m::aha as AHA;
+    let r = match (0,0) {
+        (0, AHA) => 0,
+        (x, y)   => 1 + x + y,
+    };
+    assert_eq!(r, 1);
+    let r = match (0,7) {
+        (0, AHA) => 0,
+        (x, y)   => 1 + x + y,
+    };
+    assert_eq!(r, 0);
+}
+
+fn h() {
+    let r = match (0,0) {
+        (0, self::m::aha) => 0,
+        (x, y)      => 1 + x + y,
+    };
+    assert_eq!(r, 1);
+    let r = match (0,7) {
+        (0, self::m::aha) => 0,
+        (x, y)      => 1 + x + y,
+    };
+    assert_eq!(r, 0);
+}
+
+pub fn main () {
+    f();
+    g();
+    h();
+}
diff --git a/src/test/ui/lint/lint-lowercase-static-const-pattern.rs b/src/test/ui/lint/lint-lowercase-static-const-pattern.rs
new file mode 100644 (file)
index 0000000..c2e159e
--- /dev/null
@@ -0,0 +1,51 @@
+// Issue #7526: lowercase static constants in patterns look like bindings
+
+#![allow(dead_code)]
+#![deny(non_upper_case_globals)]
+
+#[allow(non_upper_case_globals)]
+pub const a : isize = 97;
+
+fn f() {
+    let r = match (0,0) {
+        (0, a) => 0,
+        //~^ ERROR constant in pattern `a` should have an upper case name
+        (x, y) => 1 + x + y,
+    };
+    assert_eq!(r, 1);
+}
+
+mod m {
+    #[allow(non_upper_case_globals)]
+    pub const aha : isize = 7;
+}
+
+fn g() {
+    use self::m::aha;
+    let r = match (0,0) {
+        (0, aha) => 0,
+        //~^ ERROR constant in pattern `aha` should have an upper case name
+        (x, y)   => 1 + x + y,
+    };
+    assert_eq!(r, 1);
+}
+
+mod n {
+    pub const OKAY : isize = 8;
+}
+
+fn h() {
+    use self::n::OKAY as not_okay;
+    let r = match (0,0) {
+        (0, not_okay) => 0,
+//~^ ERROR constant in pattern `not_okay` should have an upper case name
+        (x, y)   => 1 + x + y,
+    };
+    assert_eq!(r, 1);
+}
+
+fn main () {
+    f();
+    g();
+    h();
+}
diff --git a/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr b/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr
new file mode 100644 (file)
index 0000000..d95510c
--- /dev/null
@@ -0,0 +1,26 @@
+error: constant in pattern `a` should have an upper case name
+  --> $DIR/lint-lowercase-static-const-pattern.rs:11:13
+   |
+LL |         (0, a) => 0,
+   |             ^ help: convert the identifier to upper case: `A`
+   |
+note: lint level defined here
+  --> $DIR/lint-lowercase-static-const-pattern.rs:4:9
+   |
+LL | #![deny(non_upper_case_globals)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: constant in pattern `aha` should have an upper case name
+  --> $DIR/lint-lowercase-static-const-pattern.rs:26:13
+   |
+LL |         (0, aha) => 0,
+   |             ^^^ help: convert the identifier to upper case: `AHA`
+
+error: constant in pattern `not_okay` should have an upper case name
+  --> $DIR/lint-lowercase-static-const-pattern.rs:40:13
+   |
+LL |         (0, not_okay) => 0,
+   |             ^^^^^^^^ help: convert the identifier to upper case: `NOT_OKAY`
+
+error: aborting due to 3 previous errors
+
index 436763b831687aff9998bb17c13d1d9f07d18fa4..bca1992605b77f655f62068e4504c1cf78bdc881 100644 (file)
@@ -2,31 +2,31 @@
 #![allow(dead_code)]
 
 struct ONE_TWO_THREE;
-//~^ ERROR type `ONE_TWO_THREE` should have a camel case name such as `OneTwoThree`
+//~^ ERROR type `ONE_TWO_THREE` should have a camel case name
 
-struct foo { //~ ERROR type `foo` should have a camel case name such as `Foo`
+struct foo { //~ ERROR type `foo` should have a camel case name
     bar: isize,
 }
 
-enum foo2 { //~ ERROR type `foo2` should have a camel case name such as `Foo2`
+enum foo2 { //~ ERROR type `foo2` should have a camel case name
     Bar
 }
 
-struct foo3 { //~ ERROR type `foo3` should have a camel case name such as `Foo3`
+struct foo3 { //~ ERROR type `foo3` should have a camel case name
     bar: isize
 }
 
-type foo4 = isize; //~ ERROR type `foo4` should have a camel case name such as `Foo4`
+type foo4 = isize; //~ ERROR type `foo4` should have a camel case name
 
 enum Foo5 {
-    bar //~ ERROR variant `bar` should have a camel case name such as `Bar`
+    bar //~ ERROR variant `bar` should have a camel case name
 }
 
-trait foo6 { //~ ERROR trait `foo6` should have a camel case name such as `Foo6`
+trait foo6 { //~ ERROR trait `foo6` should have a camel case name
     fn dummy(&self) { }
 }
 
-fn f<ty>(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name such as `Ty`
+fn f<ty>(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name
 
 #[repr(C)]
 struct foo7 {
@@ -35,10 +35,10 @@ struct foo7 {
 
 struct X86_64;
 
-struct X86__64; //~ ERROR type `X86__64` should have a camel case name such as `X86_64`
+struct X86__64; //~ ERROR type `X86__64` should have a camel case name
 
-struct Abc_123; //~ ERROR type `Abc_123` should have a camel case name such as `Abc123`
+struct Abc_123; //~ ERROR type `Abc_123` should have a camel case name
 
-struct A1_b2_c3; //~ ERROR type `A1_b2_c3` should have a camel case name such as `A1B2C3`
+struct A1_b2_c3; //~ ERROR type `A1_b2_c3` should have a camel case name
 
 fn main() { }
index 31a8555977116fffe7fa4a01d5d8eb5055066281..74f9a5993b8599a6280cf6a4309c573388596777 100644 (file)
@@ -1,8 +1,8 @@
-error: type `ONE_TWO_THREE` should have a camel case name such as `OneTwoThree`
-  --> $DIR/lint-non-camel-case-types.rs:4:1
+error: type `ONE_TWO_THREE` should have a camel case name
+  --> $DIR/lint-non-camel-case-types.rs:4:8
    |
 LL | struct ONE_TWO_THREE;
-   | ^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^ help: convert the identifier to camel case: `OneTwoThree`
    |
 note: lint level defined here
   --> $DIR/lint-non-camel-case-types.rs:1:11
@@ -10,73 +10,65 @@ note: lint level defined here
 LL | #![forbid(non_camel_case_types)]
    |           ^^^^^^^^^^^^^^^^^^^^
 
-error: type `foo` should have a camel case name such as `Foo`
-  --> $DIR/lint-non-camel-case-types.rs:7:1
+error: type `foo` should have a camel case name
+  --> $DIR/lint-non-camel-case-types.rs:7:8
    |
-LL | / struct foo { //~ ERROR type `foo` should have a camel case name such as `Foo`
-LL | |     bar: isize,
-LL | | }
-   | |_^
+LL | struct foo { //~ ERROR type `foo` should have a camel case name
+   |        ^^^ help: convert the identifier to camel case: `Foo`
 
-error: type `foo2` should have a camel case name such as `Foo2`
-  --> $DIR/lint-non-camel-case-types.rs:11:1
+error: type `foo2` should have a camel case name
+  --> $DIR/lint-non-camel-case-types.rs:11:6
    |
-LL | / enum foo2 { //~ ERROR type `foo2` should have a camel case name such as `Foo2`
-LL | |     Bar
-LL | | }
-   | |_^
+LL | enum foo2 { //~ ERROR type `foo2` should have a camel case name
+   |      ^^^^ help: convert the identifier to camel case: `Foo2`
 
-error: type `foo3` should have a camel case name such as `Foo3`
-  --> $DIR/lint-non-camel-case-types.rs:15:1
+error: type `foo3` should have a camel case name
+  --> $DIR/lint-non-camel-case-types.rs:15:8
    |
-LL | / struct foo3 { //~ ERROR type `foo3` should have a camel case name such as `Foo3`
-LL | |     bar: isize
-LL | | }
-   | |_^
+LL | struct foo3 { //~ ERROR type `foo3` should have a camel case name
+   |        ^^^^ help: convert the identifier to camel case: `Foo3`
 
-error: type `foo4` should have a camel case name such as `Foo4`
-  --> $DIR/lint-non-camel-case-types.rs:19:1
+error: type `foo4` should have a camel case name
+  --> $DIR/lint-non-camel-case-types.rs:19:6
    |
-LL | type foo4 = isize; //~ ERROR type `foo4` should have a camel case name such as `Foo4`
-   | ^^^^^^^^^^^^^^^^^^
+LL | type foo4 = isize; //~ ERROR type `foo4` should have a camel case name
+   |      ^^^^ help: convert the identifier to camel case: `Foo4`
 
-error: variant `bar` should have a camel case name such as `Bar`
+error: variant `bar` should have a camel case name
   --> $DIR/lint-non-camel-case-types.rs:22:5
    |
-LL |     bar //~ ERROR variant `bar` should have a camel case name such as `Bar`
-   |     ^^^
+LL |     bar //~ ERROR variant `bar` should have a camel case name
+   |     ^^^ help: convert the identifier to camel case: `Bar`
 
-error: trait `foo6` should have a camel case name such as `Foo6`
-  --> $DIR/lint-non-camel-case-types.rs:25:1
+error: trait `foo6` should have a camel case name
+  --> $DIR/lint-non-camel-case-types.rs:25:7
    |
-LL | / trait foo6 { //~ ERROR trait `foo6` should have a camel case name such as `Foo6`
-LL | |     fn dummy(&self) { }
-LL | | }
-   | |_^
+LL | trait foo6 { //~ ERROR trait `foo6` should have a camel case name
+   |       ^^^^ help: convert the identifier to camel case: `Foo6`
 
-error: type parameter `ty` should have a camel case name such as `Ty`
+error: type parameter `ty` should have a camel case name
   --> $DIR/lint-non-camel-case-types.rs:29:6
    |
-LL | fn f<ty>(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name such as `Ty`
-   |      ^^
+LL | fn f<ty>(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name
+   |      ^^ help: convert the identifier to camel case: `Ty`
 
-error: type `X86__64` should have a camel case name such as `X86_64`
-  --> $DIR/lint-non-camel-case-types.rs:38:1
+error: type `X86__64` should have a camel case name
+  --> $DIR/lint-non-camel-case-types.rs:38:8
    |
-LL | struct X86__64; //~ ERROR type `X86__64` should have a camel case name such as `X86_64`
-   | ^^^^^^^^^^^^^^^
+LL | struct X86__64; //~ ERROR type `X86__64` should have a camel case name
+   |        ^^^^^^^ help: convert the identifier to camel case: `X86_64`
 
-error: type `Abc_123` should have a camel case name such as `Abc123`
-  --> $DIR/lint-non-camel-case-types.rs:40:1
+error: type `Abc_123` should have a camel case name
+  --> $DIR/lint-non-camel-case-types.rs:40:8
    |
-LL | struct Abc_123; //~ ERROR type `Abc_123` should have a camel case name such as `Abc123`
-   | ^^^^^^^^^^^^^^^
+LL | struct Abc_123; //~ ERROR type `Abc_123` should have a camel case name
+   |        ^^^^^^^ help: convert the identifier to camel case: `Abc123`
 
-error: type `A1_b2_c3` should have a camel case name such as `A1B2C3`
-  --> $DIR/lint-non-camel-case-types.rs:42:1
+error: type `A1_b2_c3` should have a camel case name
+  --> $DIR/lint-non-camel-case-types.rs:42:8
    |
-LL | struct A1_b2_c3; //~ ERROR type `A1_b2_c3` should have a camel case name such as `A1B2C3`
-   | ^^^^^^^^^^^^^^^^
+LL | struct A1_b2_c3; //~ ERROR type `A1_b2_c3` should have a camel case name
+   |        ^^^^^^^^ help: convert the identifier to camel case: `A1B2C3`
 
 error: aborting due to 11 previous errors
 
diff --git a/src/test/ui/lint/lint-non-camel-case-variant.rs b/src/test/ui/lint/lint-non-camel-case-variant.rs
new file mode 100644 (file)
index 0000000..1f06b28
--- /dev/null
@@ -0,0 +1,10 @@
+// compile-pass
+
+#![deny(non_camel_case_types)]
+
+pub enum Foo {
+    #[allow(non_camel_case_types)]
+    bar
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs b/src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs
new file mode 100644 (file)
index 0000000..c2fdfb4
--- /dev/null
@@ -0,0 +1,11 @@
+// compile-pass
+
+#![allow(dead_code)]
+// This is ok because we often use the trailing underscore to mean 'prime'
+
+// pretty-expanded FIXME #23616
+
+#[forbid(non_camel_case_types)]
+type Foo_ = isize;
+
+pub fn main() { }
index 56c35c256f2a2a6cc3b031c7cdaad7ec0ba8efe0..1b763a9d868d91f1d590c58ce89c7803b55e56cd 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: --crate-name NonSnakeCase
-// error-pattern: crate `NonSnakeCase` should have a snake case name such as `non_snake_case`
+// error-pattern: crate `NonSnakeCase` should have a snake case name
 
 #![deny(non_snake_case)]
 
index eef7f1c79ee5f7b33d0948e67cc9b709221ae58f..f3303191a06fe2ea85e22ae20bc33700dbfdc33c 100644 (file)
@@ -1,10 +1,11 @@
-error: crate `NonSnakeCase` should have a snake case name such as `non_snake_case`
+error: crate `NonSnakeCase` should have a snake case name
    |
 note: lint level defined here
   --> $DIR/lint-non-snake-case-crate-2.rs:4:9
    |
 LL | #![deny(non_snake_case)]
    |         ^^^^^^^^^^^^^^
+   = help: convert the identifier to snake case: `non_snake_case`
 
 error: aborting due to previous error
 
index 221ce611db5d24aa3063e3ed84b7abfb12ec0c84..e4e84261a4ee9d062e01a148eb750a11a791459d 100644 (file)
@@ -1,5 +1,5 @@
 #![crate_name = "NonSnakeCase"]
-//~^ ERROR crate `NonSnakeCase` should have a snake case name such as `non_snake_case`
+//~^ ERROR crate `NonSnakeCase` should have a snake case name
 #![deny(non_snake_case)]
 
 fn main() {}
index 6d8112091ece6eb88d05037df0a4887bb8a41d3a..5cfd60a76e437e09cba67449580cb5a0b28cd84e 100644 (file)
@@ -1,8 +1,8 @@
-error: crate `NonSnakeCase` should have a snake case name such as `non_snake_case`
-  --> $DIR/lint-non-snake-case-crate.rs:1:1
+error: crate `NonSnakeCase` should have a snake case name
+  --> $DIR/lint-non-snake-case-crate.rs:1:18
    |
 LL | #![crate_name = "NonSnakeCase"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
    |
 note: lint level defined here
   --> $DIR/lint-non-snake-case-crate.rs:3:9
index 5ad454a7a52d59ab6d5238bc92f4d57bdeb8f1bc..fa64a9f980e75b51a070e2ac11b41aac5edc96cb 100644 (file)
@@ -5,28 +5,28 @@
 
 impl Foo {
     fn Foo_Method() {}
-    //~^ ERROR method `Foo_Method` should have a snake case name such as `foo_method`
+    //~^ ERROR method `Foo_Method` should have a snake case name
 
     // Don't allow two underscores in a row
     fn foo__method(&self) {}
-    //~^ ERROR method `foo__method` should have a snake case name such as `foo_method`
+    //~^ ERROR method `foo__method` should have a snake case name
 
     pub fn xyZ(&mut self) {}
-    //~^ ERROR method `xyZ` should have a snake case name such as `xy_z`
+    //~^ ERROR method `xyZ` should have a snake case name
 
     fn render_HTML() {}
-    //~^ ERROR method `render_HTML` should have a snake case name such as `render_html`
+    //~^ ERROR method `render_HTML` should have a snake case name
 }
 
 trait X {
     fn ABC();
-    //~^ ERROR trait method `ABC` should have a snake case name such as `abc`
+    //~^ ERROR trait method `ABC` should have a snake case name
 
     fn a_b_C(&self) {}
-    //~^ ERROR trait method `a_b_C` should have a snake case name such as `a_b_c`
+    //~^ ERROR trait method `a_b_C` should have a snake case name
 
     fn something__else(&mut self);
-    //~^ ERROR trait method `something__else` should have a snake case name such as `something_else`
+    //~^ ERROR trait method `something__else` should have a snake case name
 }
 
 impl X for Foo {
@@ -36,9 +36,9 @@ fn something__else(&mut self) {}
 }
 
 fn Cookie() {}
-//~^ ERROR function `Cookie` should have a snake case name such as `cookie`
+//~^ ERROR function `Cookie` should have a snake case name
 
 pub fn bi_S_Cuit() {}
-//~^ ERROR function `bi_S_Cuit` should have a snake case name such as `bi_s_cuit`
+//~^ ERROR function `bi_S_Cuit` should have a snake case name
 
 fn main() { }
index 508fb225437e4adda5b8cff7e58001a9a4bdab5a..49cbfa941261055d30a2509083bdd64801d606f1 100644 (file)
@@ -1,8 +1,8 @@
-error: method `Foo_Method` should have a snake case name such as `foo_method`
-  --> $DIR/lint-non-snake-case-functions.rs:7:5
+error: method `Foo_Method` should have a snake case name
+  --> $DIR/lint-non-snake-case-functions.rs:7:8
    |
 LL |     fn Foo_Method() {}
-   |     ^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^ help: convert the identifier to snake case: `foo_method`
    |
 note: lint level defined here
   --> $DIR/lint-non-snake-case-functions.rs:1:9
@@ -10,53 +10,53 @@ note: lint level defined here
 LL | #![deny(non_snake_case)]
    |         ^^^^^^^^^^^^^^
 
-error: method `foo__method` should have a snake case name such as `foo_method`
-  --> $DIR/lint-non-snake-case-functions.rs:11:5
+error: method `foo__method` should have a snake case name
+  --> $DIR/lint-non-snake-case-functions.rs:11:8
    |
 LL |     fn foo__method(&self) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^ help: convert the identifier to snake case: `foo_method`
 
-error: method `xyZ` should have a snake case name such as `xy_z`
-  --> $DIR/lint-non-snake-case-functions.rs:14:5
+error: method `xyZ` should have a snake case name
+  --> $DIR/lint-non-snake-case-functions.rs:14:12
    |
 LL |     pub fn xyZ(&mut self) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^ help: convert the identifier to snake case: `xy_z`
 
-error: method `render_HTML` should have a snake case name such as `render_html`
-  --> $DIR/lint-non-snake-case-functions.rs:17:5
+error: method `render_HTML` should have a snake case name
+  --> $DIR/lint-non-snake-case-functions.rs:17:8
    |
 LL |     fn render_HTML() {}
-   |     ^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^ help: convert the identifier to snake case: `render_html`
 
-error: trait method `ABC` should have a snake case name such as `abc`
-  --> $DIR/lint-non-snake-case-functions.rs:22:5
+error: trait method `ABC` should have a snake case name
+  --> $DIR/lint-non-snake-case-functions.rs:22:8
    |
 LL |     fn ABC();
-   |     ^^^^^^^^^
+   |        ^^^ help: convert the identifier to snake case: `abc`
 
-error: trait method `a_b_C` should have a snake case name such as `a_b_c`
-  --> $DIR/lint-non-snake-case-functions.rs:25:5
+error: trait method `a_b_C` should have a snake case name
+  --> $DIR/lint-non-snake-case-functions.rs:25:8
    |
 LL |     fn a_b_C(&self) {}
-   |     ^^^^^^^^^^^^^^^^^^
+   |        ^^^^^ help: convert the identifier to snake case: `a_b_c`
 
-error: trait method `something__else` should have a snake case name such as `something_else`
-  --> $DIR/lint-non-snake-case-functions.rs:28:5
+error: trait method `something__else` should have a snake case name
+  --> $DIR/lint-non-snake-case-functions.rs:28:8
    |
 LL |     fn something__else(&mut self);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `something_else`
 
-error: function `Cookie` should have a snake case name such as `cookie`
-  --> $DIR/lint-non-snake-case-functions.rs:38:1
+error: function `Cookie` should have a snake case name
+  --> $DIR/lint-non-snake-case-functions.rs:38:4
    |
 LL | fn Cookie() {}
-   | ^^^^^^^^^^^^^^
+   |    ^^^^^^ help: convert the identifier to snake case: `cookie`
 
-error: function `bi_S_Cuit` should have a snake case name such as `bi_s_cuit`
-  --> $DIR/lint-non-snake-case-functions.rs:41:1
+error: function `bi_S_Cuit` should have a snake case name
+  --> $DIR/lint-non-snake-case-functions.rs:41:8
    |
 LL | pub fn bi_S_Cuit() {}
-   | ^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^ help: convert the identifier to snake case: `bi_s_cuit`
 
 error: aborting due to 9 previous errors
 
index c7af431bafc3af0aa2d43ff0427247f24a96c1f9..de76d2dbef26adabe93cd941ac8719a79b49d3dc 100644 (file)
@@ -1,7 +1,7 @@
 #![deny(non_snake_case)]
 #![allow(dead_code)]
 
-fn f<'FooBar>( //~ ERROR lifetime `'FooBar` should have a snake case name such as `'foo_bar`
+fn f<'FooBar>( //~ ERROR lifetime `'FooBar` should have a snake case name
     _: &'FooBar ()
 ) {}
 
index 694a5a2252565e318e93604af94f382ca81658ae..970666ebcfdc3cd9ce3f7744b5c638de2d47086d 100644 (file)
@@ -1,8 +1,8 @@
-error: lifetime `'FooBar` should have a snake case name such as `'foo_bar`
+error: lifetime `'FooBar` should have a snake case name
   --> $DIR/lint-non-snake-case-lifetimes.rs:4:6
    |
-LL | fn f<'FooBar>( //~ ERROR lifetime `'FooBar` should have a snake case name such as `'foo_bar`
-   |      ^^^^^^^
+LL | fn f<'FooBar>( //~ ERROR lifetime `'FooBar` should have a snake case name
+   |      ^^^^^^^ help: convert the identifier to snake case: `'foo_bar`
    |
 note: lint level defined here
   --> $DIR/lint-non-snake-case-lifetimes.rs:1:9
index 90f45a4f413155ab3c66a9febcded32e0b4f58e2..73f1233217225980422207fe92cbb19fd3a9f556 100644 (file)
@@ -1,7 +1,7 @@
 #![deny(non_snake_case)]
 #![allow(dead_code)]
 
-mod FooBar { //~ ERROR module `FooBar` should have a snake case name such as `foo_bar`
+mod FooBar { //~ ERROR module `FooBar` should have a snake case name
     pub struct S;
 }
 
index ec3accf2ae882fc3a8602a6e6b7c74d546c87fc6..651132e49d914c5dd0f55b996912729da1e8a7e8 100644 (file)
@@ -1,10 +1,8 @@
-error: module `FooBar` should have a snake case name such as `foo_bar`
-  --> $DIR/lint-non-snake-case-modules.rs:4:1
+error: module `FooBar` should have a snake case name
+  --> $DIR/lint-non-snake-case-modules.rs:4:5
    |
-LL | / mod FooBar { //~ ERROR module `FooBar` should have a snake case name such as `foo_bar`
-LL | |     pub struct S;
-LL | | }
-   | |_^
+LL | mod FooBar { //~ ERROR module `FooBar` should have a snake case name
+   |     ^^^^^^ help: convert the identifier to snake case: `foo_bar`
    |
 note: lint level defined here
   --> $DIR/lint-non-snake-case-modules.rs:1:9
diff --git a/src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs b/src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs
new file mode 100644 (file)
index 0000000..9a6487d
--- /dev/null
@@ -0,0 +1,12 @@
+// compile-pass
+
+#![allow(dead_code)]
+// pretty-expanded FIXME #23616
+
+#![feature(non_ascii_idents)]
+#![deny(non_snake_case)]
+
+// This name is neither upper nor lower case
+fn ä½ å¥½() {}
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-non-uppercase-associated-const.rs b/src/test/ui/lint/lint-non-uppercase-associated-const.rs
new file mode 100644 (file)
index 0000000..7b0d939
--- /dev/null
@@ -0,0 +1,11 @@
+#![deny(non_upper_case_globals)]
+#![allow(dead_code)]
+
+struct Foo;
+
+impl Foo {
+    const not_upper: bool = true;
+}
+//~^^ ERROR associated constant `not_upper` should have an upper case name
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-non-uppercase-associated-const.stderr b/src/test/ui/lint/lint-non-uppercase-associated-const.stderr
new file mode 100644 (file)
index 0000000..2185d5a
--- /dev/null
@@ -0,0 +1,14 @@
+error: associated constant `not_upper` should have an upper case name
+  --> $DIR/lint-non-uppercase-associated-const.rs:7:11
+   |
+LL |     const not_upper: bool = true;
+   |           ^^^^^^^^^ help: convert the identifier to upper case: `NOT_UPPER`
+   |
+note: lint level defined here
+  --> $DIR/lint-non-uppercase-associated-const.rs:1:9
+   |
+LL | #![deny(non_upper_case_globals)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
index 9424bef3dfbf2808e617f3d2e93ec02584bd4ece..5bd1430328b48e6c35e1640f8c5f22a87bddb564 100644 (file)
@@ -1,10 +1,9 @@
 #![forbid(non_upper_case_globals)]
 #![allow(dead_code)]
 
-static foo: isize = 1; //~ ERROR static variable `foo` should have an upper case name such as `FOO`
+static foo: isize = 1; //~ ERROR static variable `foo` should have an upper case name
 
-static mut bar: isize = 1;
-        //~^ ERROR static variable `bar` should have an upper case name such as `BAR`
+static mut bar: isize = 1; //~ ERROR static variable `bar` should have an upper case name
 
 #[no_mangle]
 pub static extern_foo: isize = 1; // OK, because #[no_mangle] supersedes the warning
index 9c3dbb2fdeae5c1669859f990bca8b9fdfacce53..f5bba5f145de4877fc5d00602bdbf2e59f9f65cc 100644 (file)
@@ -1,8 +1,8 @@
-error: static variable `foo` should have an upper case name such as `FOO`
-  --> $DIR/lint-non-uppercase-statics.rs:4:1
+error: static variable `foo` should have an upper case name
+  --> $DIR/lint-non-uppercase-statics.rs:4:8
    |
-LL | static foo: isize = 1; //~ ERROR static variable `foo` should have an upper case name such as `FOO`
-   | ^^^^^^^^^^^^^^^^^^^^^^
+LL | static foo: isize = 1; //~ ERROR static variable `foo` should have an upper case name
+   |        ^^^ help: convert the identifier to upper case: `FOO`
    |
 note: lint level defined here
   --> $DIR/lint-non-uppercase-statics.rs:1:11
@@ -10,11 +10,11 @@ note: lint level defined here
 LL | #![forbid(non_upper_case_globals)]
    |           ^^^^^^^^^^^^^^^^^^^^^^
 
-error: static variable `bar` should have an upper case name such as `BAR`
-  --> $DIR/lint-non-uppercase-statics.rs:6:1
+error: static variable `bar` should have an upper case name
+  --> $DIR/lint-non-uppercase-statics.rs:6:12
    |
-LL | static mut bar: isize = 1;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | static mut bar: isize = 1; //~ ERROR static variable `bar` should have an upper case name
+   |            ^^^ help: convert the identifier to upper case: `BAR`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/lint/lint-nonstandard-style-unicode.rs b/src/test/ui/lint/lint-nonstandard-style-unicode.rs
new file mode 100644 (file)
index 0000000..a0b4130
--- /dev/null
@@ -0,0 +1,16 @@
+// compile-pass
+
+#![allow(dead_code)]
+
+#![forbid(non_camel_case_types)]
+#![forbid(non_upper_case_globals)]
+#![feature(non_ascii_idents)]
+
+// Some scripts (e.g., hiragana) don't have a concept of
+// upper/lowercase
+
+struct ãƒ’;
+
+static ãƒ©: usize = 0;
+
+pub fn main() {}
index 33c2968e610c9cc7fb4efd06de79029aa6ccd258..86a39502a81cc62c8debf8bb685cc930ba7e2156 100644 (file)
@@ -7,20 +7,20 @@ pub enum Foo { Foo }
 }
 
 struct Something {
-    X: usize //~ ERROR structure field `X` should have a snake case name such as `x`
+    X: usize //~ ERROR structure field `X` should have a snake case name
 }
 
-fn test(Xx: usize) { //~ ERROR variable `Xx` should have a snake case name such as `xx`
+fn test(Xx: usize) { //~ ERROR variable `Xx` should have a snake case name
     println!("{}", Xx);
 }
 
 fn main() {
-    let Test: usize = 0; //~ ERROR variable `Test` should have a snake case name such as `test`
+    let Test: usize = 0; //~ ERROR variable `Test` should have a snake case name
     println!("{}", Test);
 
     match foo::Foo::Foo {
         Foo => {}
-//~^ ERROR variable `Foo` should have a snake case name such as `foo`
+//~^ ERROR variable `Foo` should have a snake case name
 //~^^ WARN `Foo` is named the same as one of the variants of the type `foo::Foo`
 //~^^^ WARN unused variable: `Foo`
     }
index f8564668e920fe58d19967318c4a72317cfb4138..0741179c4a4ddf6170a48a1e6b534f41cd396a8b 100644 (file)
@@ -17,11 +17,11 @@ LL | #![warn(unused)]
    |         ^^^^^^
    = note: #[warn(unused_variables)] implied by #[warn(unused)]
 
-error: structure field `X` should have a snake case name such as `x`
+error: structure field `X` should have a snake case name
   --> $DIR/lint-uppercase-variables.rs:10:5
    |
-LL |     X: usize //~ ERROR structure field `X` should have a snake case name such as `x`
-   |     ^^^^^^^^
+LL |     X: usize //~ ERROR structure field `X` should have a snake case name
+   |     ^ help: convert the identifier to snake case: `x`
    |
 note: lint level defined here
   --> $DIR/lint-uppercase-variables.rs:3:9
@@ -29,23 +29,23 @@ note: lint level defined here
 LL | #![deny(non_snake_case)]
    |         ^^^^^^^^^^^^^^
 
-error: variable `Xx` should have a snake case name such as `xx`
+error: variable `Xx` should have a snake case name
   --> $DIR/lint-uppercase-variables.rs:13:9
    |
-LL | fn test(Xx: usize) { //~ ERROR variable `Xx` should have a snake case name such as `xx`
-   |         ^^
+LL | fn test(Xx: usize) { //~ ERROR variable `Xx` should have a snake case name
+   |         ^^ help: convert the identifier to snake case: `xx`
 
-error: variable `Test` should have a snake case name such as `test`
+error: variable `Test` should have a snake case name
   --> $DIR/lint-uppercase-variables.rs:18:9
    |
-LL |     let Test: usize = 0; //~ ERROR variable `Test` should have a snake case name such as `test`
-   |         ^^^^
+LL |     let Test: usize = 0; //~ ERROR variable `Test` should have a snake case name
+   |         ^^^^ help: convert the identifier to snake case: `test`
 
-error: variable `Foo` should have a snake case name such as `foo`
+error: variable `Foo` should have a snake case name
   --> $DIR/lint-uppercase-variables.rs:22:9
    |
 LL |         Foo => {}
-   |         ^^^
+   |         ^^^ help: convert the identifier to snake case: `foo`
 
 error: aborting due to 4 previous errors
 
index df0f9cb9b61e89c7c87835cadc9a1c24cf4420fc..3bb1480a301095c12b3667c1d5e39e8ceffc0259 100644 (file)
@@ -11,11 +11,11 @@ note: lint level defined here
 LL | #![warn(elided_lifetimes_in_paths,
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: variable `Social_exchange_psychology` should have a snake case name such as `social_exchange_psychology`
+warning: variable `Social_exchange_psychology` should have a snake case name
   --> $DIR/reasons.rs:30:9
    |
 LL |     let Social_exchange_psychology = CheaterDetectionMechanism {};
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `social_exchange_psychology`
    |
    = note: people shouldn't have to change their usual style habits
            to contribute to our project
index ba1e441fe339fd0eaf87f6a8f9887797a881efb2..96aee5e6aeed5cc9c9561f90ccd1f61d2661c6f4 100644 (file)
@@ -2,6 +2,7 @@ fn main() {
     format!(); //~ ERROR requires at least a format string argument
     format!(struct); //~ ERROR expected expression
     format!("s", name =); //~ ERROR expected expression
+    format!("s", foo = foo, bar); //~ ERROR expected `=`
     format!("s", foo = struct); //~ ERROR expected expression
     format!("s", struct); //~ ERROR expected expression
 
index 0463c54890177f1a5e70300df81cce3ae536d3d9..a3d2786bce1119ef10d39e387245096d5c0e2475 100644 (file)
@@ -18,20 +18,26 @@ error: expected expression, found `<eof>`
 LL |     format!("s", name =); //~ ERROR expected expression
    |                       ^ expected expression
 
+error: expected `=`, found `<eof>`
+  --> $DIR/format-parse-errors.rs:5:29
+   |
+LL |     format!("s", foo = foo, bar); //~ ERROR expected `=`
+   |                             ^^^ expected `=`
+
 error: expected expression, found keyword `struct`
-  --> $DIR/format-parse-errors.rs:5:24
+  --> $DIR/format-parse-errors.rs:6:24
    |
 LL |     format!("s", foo = struct); //~ ERROR expected expression
    |                        ^^^^^^ expected expression
 
 error: expected expression, found keyword `struct`
-  --> $DIR/format-parse-errors.rs:6:18
+  --> $DIR/format-parse-errors.rs:7:18
    |
 LL |     format!("s", struct); //~ ERROR expected expression
    |                  ^^^^^^ expected expression
 
 error: format argument must be a string literal
-  --> $DIR/format-parse-errors.rs:9:13
+  --> $DIR/format-parse-errors.rs:10:13
    |
 LL |     format!(123); //~ ERROR format argument must be a string literal
    |             ^^^
@@ -40,5 +46,5 @@ help: you might be missing a string literal to format with
 LL |     format!("{}", 123); //~ ERROR format argument must be a string literal
    |             ^^^^^
 
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/match/match-static-const-lc.rs b/src/test/ui/match/match-static-const-lc.rs
deleted file mode 100644 (file)
index c79da6e..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-// Issue #7526: lowercase static constants in patterns look like bindings
-
-#![allow(dead_code)]
-#![deny(non_upper_case_globals)]
-
-#[allow(non_upper_case_globals)]
-pub const a : isize = 97;
-
-fn f() {
-    let r = match (0,0) {
-        (0, a) => 0,
-        //~^ ERROR constant in pattern `a` should have an upper case name such as `A`
-        (x, y) => 1 + x + y,
-    };
-    assert_eq!(r, 1);
-}
-
-mod m {
-    #[allow(non_upper_case_globals)]
-    pub const aha : isize = 7;
-}
-
-fn g() {
-    use self::m::aha;
-    let r = match (0,0) {
-        (0, aha) => 0,
-        //~^ ERROR constant in pattern `aha` should have an upper case name such as `AHA`
-        (x, y)   => 1 + x + y,
-    };
-    assert_eq!(r, 1);
-}
-
-mod n {
-    pub const OKAY : isize = 8;
-}
-
-fn h() {
-    use self::n::OKAY as not_okay;
-    let r = match (0,0) {
-        (0, not_okay) => 0,
-//~^ ERROR constant in pattern `not_okay` should have an upper case name such as `NOT_OKAY`
-        (x, y)   => 1 + x + y,
-    };
-    assert_eq!(r, 1);
-}
-
-fn main () {
-    f();
-    g();
-    h();
-}
diff --git a/src/test/ui/match/match-static-const-lc.stderr b/src/test/ui/match/match-static-const-lc.stderr
deleted file mode 100644 (file)
index 1ddb831..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-error: constant in pattern `a` should have an upper case name such as `A`
-  --> $DIR/match-static-const-lc.rs:11:13
-   |
-LL |         (0, a) => 0,
-   |             ^
-   |
-note: lint level defined here
-  --> $DIR/match-static-const-lc.rs:4:9
-   |
-LL | #![deny(non_upper_case_globals)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
-
-error: constant in pattern `aha` should have an upper case name such as `AHA`
-  --> $DIR/match-static-const-lc.rs:26:13
-   |
-LL |         (0, aha) => 0,
-   |             ^^^
-
-error: constant in pattern `not_okay` should have an upper case name such as `NOT_OKAY`
-  --> $DIR/match-static-const-lc.rs:40:13
-   |
-LL |         (0, not_okay) => 0,
-   |             ^^^^^^^^
-
-error: aborting due to 3 previous errors
-
index bad41485a53b162438fef113879a1b52063cf8a9..2a24a293e98364e68c6a3a4c47fbecac7ace3e05 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/match-struct.rs:6:9
    |
+LL |     match (S { a: 1 }) {
+   |           ------------ this match expression has type `S`
 LL |         E::C(_) => (),
    |         ^^^^^^^ expected struct `S`, found enum `E`
    |
index c90029b2fa12ee678cc747ea0ae3e6fde630bcc3..53b663513696626d0b3a3a09eafb8fa17dc5bd9f 100644 (file)
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/match-tag-unary.rs:4:43
    |
 LL | fn main() { let x: A = A::A(0); match x { B::B(y) => { } } } //~ ERROR mismatched types
-   |                                           ^^^^^^^ expected enum `A`, found enum `B`
+   |                                       -   ^^^^^^^ expected enum `A`, found enum `B`
+   |                                       |
+   |                                       this match expression has type `A`
    |
    = note: expected type `A`
               found type `B`
index 158d114616979c907a59eaed5a6b629f19ecc6ef..fbe5e6d409934fe0fc7a8251f02a3ef8de742e27 100644 (file)
@@ -240,13 +240,10 @@ error[E0606]: casting `&{float}` as `f32` is invalid
   --> $DIR/cast-rfc0401.rs:71:30
    |
 LL |     vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>(); //~ ERROR is invalid
-   |                              ^^^^^^^^ cannot cast `&{float}` as `f32`
-   |
-help: did you mean `*s`?
-  --> $DIR/cast-rfc0401.rs:71:30
-   |
-LL |     vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>(); //~ ERROR is invalid
-   |                              ^
+   |                              -^^^^^^^
+   |                              |
+   |                              cannot cast `&{float}` as `f32`
+   |                              help: dereference the expression: `*s`
 
 error: aborting due to 34 previous errors
 
diff --git a/src/test/ui/nll/issue-57100.rs b/src/test/ui/nll/issue-57100.rs
new file mode 100644 (file)
index 0000000..f669fe0
--- /dev/null
@@ -0,0 +1,69 @@
+#![allow(unused)]
+#![feature(nll)]
+
+// ignore-tidy-linelength
+
+// This tests the error messages for borrows of union fields when the unions are embedded in other
+// structs or unions.
+
+#[derive(Clone, Copy, Default)]
+struct Leaf {
+    l1_u8: u8,
+    l2_u8: u8,
+}
+
+#[derive(Clone, Copy)]
+union First {
+    f1_leaf: Leaf,
+    f2_leaf: Leaf,
+    f3_union: Second,
+}
+
+#[derive(Clone, Copy)]
+union Second {
+    s1_leaf: Leaf,
+    s2_leaf: Leaf,
+}
+
+struct Root {
+    r1_u8: u8,
+    r2_union: First,
+}
+
+// Borrow a different field of the nested union.
+fn nested_union() {
+    unsafe {
+        let mut r = Root {
+            r1_u8: 3,
+            r2_union: First { f3_union: Second { s2_leaf: Leaf { l1_u8: 8, l2_u8: 4 } } }
+        };
+
+        let mref = &mut r.r2_union.f3_union.s1_leaf.l1_u8;
+        //                                  ^^^^^^^
+        *mref = 22;
+        let nref = &r.r2_union.f3_union.s2_leaf.l1_u8;
+        //                              ^^^^^^^
+        //~^^ ERROR cannot borrow `r.r2_union.f3_union` (via `r.r2_union.f3_union.s2_leaf.l1_u8`) as immutable because it is also borrowed as mutable (via `r.r2_union.f3_union.s1_leaf.l1_u8`) [E0502]
+        println!("{} {}", mref, nref)
+    }
+}
+
+// Borrow a different field of the first union.
+fn first_union() {
+    unsafe {
+        let mut r = Root {
+            r1_u8: 3,
+            r2_union: First { f3_union: Second { s2_leaf: Leaf { l1_u8: 8, l2_u8: 4 } } }
+        };
+
+        let mref = &mut r.r2_union.f2_leaf.l1_u8;
+        //                         ^^^^^^^
+        *mref = 22;
+        let nref = &r.r2_union.f1_leaf.l1_u8;
+        //                     ^^^^^^^
+        //~^^ ERROR cannot borrow `r.r2_union` (via `r.r2_union.f1_leaf.l1_u8`) as immutable because it is also borrowed as mutable (via `r.r2_union.f2_leaf.l1_u8`) [E0502]
+        println!("{} {}", mref, nref)
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/issue-57100.stderr b/src/test/ui/nll/issue-57100.stderr
new file mode 100644 (file)
index 0000000..5d5c86c
--- /dev/null
@@ -0,0 +1,31 @@
+error[E0502]: cannot borrow `r.r2_union.f3_union` (via `r.r2_union.f3_union.s2_leaf.l1_u8`) as immutable because it is also borrowed as mutable (via `r.r2_union.f3_union.s1_leaf.l1_u8`)
+  --> $DIR/issue-57100.rs:44:20
+   |
+LL |         let mref = &mut r.r2_union.f3_union.s1_leaf.l1_u8;
+   |                    -------------------------------------- mutable borrow occurs here (via `r.r2_union.f3_union.s1_leaf.l1_u8`)
+...
+LL |         let nref = &r.r2_union.f3_union.s2_leaf.l1_u8;
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ immutable borrow of `r.r2_union.f3_union.s2_leaf.l1_u8` -- which overlaps with `r.r2_union.f3_union.s1_leaf.l1_u8` -- occurs here
+...
+LL |         println!("{} {}", mref, nref)
+   |                           ---- mutable borrow later used here
+   |
+   = note: `r.r2_union.f3_union.s2_leaf.l1_u8` is a field of the union `Second`, so it overlaps the field `r.r2_union.f3_union.s1_leaf.l1_u8`
+
+error[E0502]: cannot borrow `r.r2_union` (via `r.r2_union.f1_leaf.l1_u8`) as immutable because it is also borrowed as mutable (via `r.r2_union.f2_leaf.l1_u8`)
+  --> $DIR/issue-57100.rs:62:20
+   |
+LL |         let mref = &mut r.r2_union.f2_leaf.l1_u8;
+   |                    ----------------------------- mutable borrow occurs here (via `r.r2_union.f2_leaf.l1_u8`)
+...
+LL |         let nref = &r.r2_union.f1_leaf.l1_u8;
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^ immutable borrow of `r.r2_union.f1_leaf.l1_u8` -- which overlaps with `r.r2_union.f2_leaf.l1_u8` -- occurs here
+...
+LL |         println!("{} {}", mref, nref)
+   |                           ---- mutable borrow later used here
+   |
+   = note: `r.r2_union.f1_leaf.l1_u8` is a field of the union `First`, so it overlaps the field `r.r2_union.f2_leaf.l1_u8`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0502`.
diff --git a/src/test/ui/pattern/deny-irrefutable-let-patterns.rs b/src/test/ui/pattern/deny-irrefutable-let-patterns.rs
new file mode 100644 (file)
index 0000000..14040c8
--- /dev/null
@@ -0,0 +1,9 @@
+#![deny(irrefutable_let_patterns)]
+
+fn main() {
+    if let _ = 5 {} //~ ERROR irrefutable if-let pattern
+
+    while let _ = 5 { //~ ERROR irrefutable while-let pattern
+        break;
+    }
+}
diff --git a/src/test/ui/pattern/deny-irrefutable-let-patterns.stderr b/src/test/ui/pattern/deny-irrefutable-let-patterns.stderr
new file mode 100644 (file)
index 0000000..ad8cc2e
--- /dev/null
@@ -0,0 +1,22 @@
+error: irrefutable if-let pattern
+  --> $DIR/deny-irrefutable-let-patterns.rs:4:5
+   |
+LL |     if let _ = 5 {} //~ ERROR irrefutable if-let pattern
+   |     ^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/deny-irrefutable-let-patterns.rs:1:9
+   |
+LL | #![deny(irrefutable_let_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: irrefutable while-let pattern
+  --> $DIR/deny-irrefutable-let-patterns.rs:6:5
+   |
+LL | /     while let _ = 5 { //~ ERROR irrefutable while-let pattern
+LL | |         break;
+LL | |     }
+   | |_____^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/pattern/enum-variant-generic-args.rs b/src/test/ui/pattern/enum-variant-generic-args.rs
new file mode 100644 (file)
index 0000000..8559953
--- /dev/null
@@ -0,0 +1,43 @@
+// run-pass
+
+#![feature(type_alias_enum_variants)]
+
+#![allow(irrefutable_let_patterns)]
+
+#[allow(dead_code)]
+enum Enum<T> { TSVariant(T), SVariant { v: T } }
+type Alias<T> = Enum<T>;
+type AliasFixed = Enum<()>;
+
+macro_rules! is_variant {
+    (TSVariant, $expr:expr) => (is_variant!(@check TSVariant, (_), $expr));
+    (SVariant, $expr:expr) => (is_variant!(@check SVariant, { v: _ }, $expr));
+    (@check $variant:ident, $matcher:tt, $expr:expr) => (
+        assert!(if let Enum::$variant::<()> $matcher = $expr { true } else { false },
+                "expr does not have correct type");
+    );
+}
+
+fn main() {
+    // Tuple struct variant
+
+    is_variant!(TSVariant, Enum::TSVariant(()));
+    is_variant!(TSVariant, Enum::TSVariant::<()>(()));
+    is_variant!(TSVariant, Enum::<()>::TSVariant(()));
+
+    is_variant!(TSVariant, Alias::TSVariant(()));
+    is_variant!(TSVariant, Alias::<()>::TSVariant(()));
+
+    is_variant!(TSVariant, AliasFixed::TSVariant(()));
+
+    // Struct variant
+
+    is_variant!(SVariant, Enum::SVariant { v: () });
+    is_variant!(SVariant, Enum::SVariant::<()> { v: () });
+    is_variant!(SVariant, Enum::<()>::SVariant { v: () });
+
+    is_variant!(SVariant, Alias::SVariant { v: () });
+    is_variant!(SVariant, Alias::<()>::SVariant { v: () });
+
+    is_variant!(SVariant, AliasFixed::SVariant { v: () });
+}
diff --git a/src/test/ui/pattern/irrefutable-let-patterns.rs b/src/test/ui/pattern/irrefutable-let-patterns.rs
new file mode 100644 (file)
index 0000000..d400ef0
--- /dev/null
@@ -0,0 +1,11 @@
+// run-pass
+
+#![allow(irrefutable_let_patterns)]
+
+fn main() {
+    if let _ = 5 {}
+
+    while let _ = 5 {
+        break;
+    }
+}
index c17d4b70f0b000248f42ff60553fbec6ee1ff364..c2810d764c2ceba3d2247485e1f357aa962d755b 100644 (file)
@@ -21,6 +21,8 @@ LL |         A::B(_, _, _) => (), //~ ERROR this pattern has 3 fields, but
 error[E0308]: mismatched types
   --> $DIR/pattern-error-continue.rs:22:9
    |
+LL |     match 'c' {
+   |           --- this match expression has type `char`
 LL |         S { .. } => (),
    |         ^^^^^^^^ expected char, found struct `S`
    |
index dae17fa51661059496cbcad488a5fbd36c738450..69cd552aabd1bf56c29f311977558064e6daa56a 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/pattern-tyvar.rs:5:18
    |
+LL |     match t {
+   |           - this match expression has type `std::option::Option<std::vec::Vec<isize>>`
 LL |       Bar::T1(_, Some::<isize>(x)) => { //~ ERROR mismatched types
    |                  ^^^^^^^^^^^^^^^^ expected struct `std::vec::Vec`, found isize
    |
index aa9eae0ba317afc4159519d71ed7823cb3cf7367..f6fe9f9fd8b304d48d4b081e1070c29c11210b9d 100644 (file)
@@ -5,6 +5,26 @@
 
 #[my_attr] //~ ERROR `my_attr` is ambiguous
 #[derive(MyTrait)]
-struct S;
+struct S {
+    // FIXME No ambiguity, attributes in non-macro positions are not resolved properly
+    #[my_attr]
+    field: [u8; {
+        // FIXME No ambiguity, derive helpers are not put into scope for non-attributes
+        use my_attr;
 
-fn main() {}
+        // FIXME No ambiguity, derive helpers are not put into scope for inner items
+        #[my_attr]
+        struct U;
+
+        mod inner {
+            #[my_attr] //~ ERROR attribute `my_attr` is currently unknown
+            struct V;
+        }
+
+        0
+    }]
+}
+
+fn main() {
+    let s = S { field: [] };
+}
index cc50fefc46453d393defc7bfb7ba3dbc691deed7..8180c84d3f6eba226545dbef42d98e7b422374e9 100644 (file)
@@ -1,3 +1,11 @@
+error[E0658]: The attribute `my_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
+  --> $DIR/derive-helper-shadowing.rs:20:15
+   |
+LL |             #[my_attr] //~ ERROR attribute `my_attr` is currently unknown
+   |               ^^^^^^^
+   |
+   = help: add #![feature(custom_attribute)] to the crate attributes to enable
+
 error[E0659]: `my_attr` is ambiguous (derive helper attribute vs any other name)
   --> $DIR/derive-helper-shadowing.rs:6:3
    |
@@ -16,6 +24,7 @@ LL | use derive_helper_shadowing::*;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: use `crate::my_attr` to refer to this attribute macro unambiguously
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0659`.
+Some errors occurred: E0658, E0659.
+For more information about an error, try `rustc --explain E0658`.
index 40a3e7e96486bad644e64d0958001dfe47eaa5c4..60e70ddcd97019d20a1aa0c2cab400f6da47db52 100644 (file)
@@ -1,13 +1,15 @@
 error[E0308]: if and else have incompatible types
-  --> $DIR/region-invariant-static-error-reporting.rs:14:15
+  --> $DIR/region-invariant-static-error-reporting.rs:17:9
    |
 LL |       let bad = if x.is_some() {
-   |  _______________^
+   |  _______________-
 LL | |         x.unwrap()
+   | |         ---------- expected because of this
 LL | |     } else {
 LL | |         mk_static()
+   | |         ^^^^^^^^^^^ lifetime mismatch
 LL | |     };
-   | |_____^ lifetime mismatch
+   | |_____- if and else have incompatible types
    |
    = note: expected type `Invariant<'a>`
               found type `Invariant<'static>`
index 4d6d342f571a5c6b27fecbdd0ab0d5dc5acfa53f..9010770f1dc821dcf9877a315e3c1c2f3d8fbdd8 100644 (file)
@@ -10,6 +10,7 @@
 
 #![allow(dead_code)]
 #![allow(unused_variables)]
+#![allow(non_snake_case)]
 
 struct S;
 
diff --git a/src/test/ui/regions/regions-fn-subtyping-return-static.stderr b/src/test/ui/regions/regions-fn-subtyping-return-static.stderr
deleted file mode 100644 (file)
index 61eaf9f..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-warning: function `want_F` should have a snake case name such as `want_f`
-  --> $DIR/regions-fn-subtyping-return-static.rs:18:1
-   |
-LL | fn want_F(f: F) { }
-   | ^^^^^^^^^^^^^^^^^^^
-   |
-   = note: #[warn(non_snake_case)] on by default
-
-warning: function `want_G` should have a snake case name such as `want_g`
-  --> $DIR/regions-fn-subtyping-return-static.rs:22:1
-   |
-LL | fn want_G(f: G) { }
-   | ^^^^^^^^^^^^^^^^^^^
-
-warning: function `supply_F` should have a snake case name such as `supply_f`
-  --> $DIR/regions-fn-subtyping-return-static.rs:39:1
-   |
-LL | / fn supply_F() {
-LL | |     want_F(foo);
-LL | |
-LL | |     want_F(bar);
-LL | |
-LL | |     want_F(baz);
-LL | | }
-   | |_^
-
index 17b2f9fa4fbbc242774e7a93c274fc950e07d602..1da56ad05d28c11b3fd12e5a4cbb045a20d74904 100644 (file)
@@ -5,6 +5,11 @@ LL | impl ToNbt<Self> {}
    |            ^^^^
    |
    = note: ...which again requires processing `<impl at $DIR/issue-23305.rs:5:1: 5:20>`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/issue-23305.rs:1:1
+   |
+LL | pub trait ToNbt<T> {
+   | ^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/resolve/issue-57523.rs b/src/test/ui/resolve/issue-57523.rs
new file mode 100644 (file)
index 0000000..c2a2f28
--- /dev/null
@@ -0,0 +1,21 @@
+// compile-pass
+
+struct S(u8);
+
+impl S {
+    fn method1() -> Self {
+        Self(0)
+    }
+}
+
+macro_rules! define_method { () => {
+    impl S {
+        fn method2() -> Self {
+            Self(0) // OK
+        }
+    }
+}}
+
+define_method!();
+
+fn main() {}
index 47704f114d16c29db9a66c82221025388f0d2032..1940c0cd2a4b7e163aff228de447f1c56e5b2e7e 100644 (file)
@@ -5,6 +5,17 @@ LL | impl Tr for Self {} //~ ERROR cycle detected
    |             ^^^^
    |
    = note: ...which again requires processing `<impl at $DIR/resolve-self-in-impl.rs:14:1: 14:20>`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/resolve-self-in-impl.rs:1:1
+   |
+LL | / #![feature(associated_type_defaults)]
+LL | |
+LL | | struct S<T = u8>(T);
+LL | | trait Tr<T = u8> {
+...  |
+LL | |
+LL | | fn main() {}
+   | |____________^
 
 error[E0391]: cycle detected when processing `<impl at $DIR/resolve-self-in-impl.rs:15:1: 15:23>`
   --> $DIR/resolve-self-in-impl.rs:15:15
@@ -13,6 +24,17 @@ LL | impl Tr for S<Self> {} //~ ERROR cycle detected
    |               ^^^^
    |
    = note: ...which again requires processing `<impl at $DIR/resolve-self-in-impl.rs:15:1: 15:23>`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/resolve-self-in-impl.rs:1:1
+   |
+LL | / #![feature(associated_type_defaults)]
+LL | |
+LL | | struct S<T = u8>(T);
+LL | | trait Tr<T = u8> {
+...  |
+LL | |
+LL | | fn main() {}
+   | |____________^
 
 error[E0391]: cycle detected when processing `<impl at $DIR/resolve-self-in-impl.rs:16:1: 16:13>`
   --> $DIR/resolve-self-in-impl.rs:16:6
@@ -21,6 +43,17 @@ LL | impl Self {} //~ ERROR cycle detected
    |      ^^^^
    |
    = note: ...which again requires processing `<impl at $DIR/resolve-self-in-impl.rs:16:1: 16:13>`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/resolve-self-in-impl.rs:1:1
+   |
+LL | / #![feature(associated_type_defaults)]
+LL | |
+LL | | struct S<T = u8>(T);
+LL | | trait Tr<T = u8> {
+...  |
+LL | |
+LL | | fn main() {}
+   | |____________^
 
 error[E0391]: cycle detected when processing `<impl at $DIR/resolve-self-in-impl.rs:17:1: 17:16>`
   --> $DIR/resolve-self-in-impl.rs:17:8
@@ -29,6 +62,17 @@ LL | impl S<Self> {} //~ ERROR cycle detected
    |        ^^^^
    |
    = note: ...which again requires processing `<impl at $DIR/resolve-self-in-impl.rs:17:1: 17:16>`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/resolve-self-in-impl.rs:1:1
+   |
+LL | / #![feature(associated_type_defaults)]
+LL | |
+LL | | struct S<T = u8>(T);
+LL | | trait Tr<T = u8> {
+...  |
+LL | |
+LL | | fn main() {}
+   | |____________^
 
 error[E0391]: cycle detected when processing `<impl at $DIR/resolve-self-in-impl.rs:18:1: 18:26>`
   --> $DIR/resolve-self-in-impl.rs:18:1
@@ -37,6 +81,17 @@ LL | impl Tr<Self::A> for S {} //~ ERROR cycle detected
    | ^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: ...which again requires processing `<impl at $DIR/resolve-self-in-impl.rs:18:1: 18:26>`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/resolve-self-in-impl.rs:1:1
+   |
+LL | / #![feature(associated_type_defaults)]
+LL | |
+LL | | struct S<T = u8>(T);
+LL | | trait Tr<T = u8> {
+...  |
+LL | |
+LL | | fn main() {}
+   | |____________^
 
 error: aborting due to 5 previous errors
 
index 1dd428b7c83f643021272275c1953dadca102e59..dd21de75aaf75bb1e2847b345c39995a9b2c447e 100644 (file)
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(uniform_paths)]
-
 // Tests that arbitrary crates (other than `core`, `std` and `meta`)
 // aren't allowed without `--extern`, even if they're in the sysroot.
 use alloc; //~ ERROR unresolved import `alloc`
index e4eaa1dc3d2b3695ab14b7e321524d7b8f79119e..3bea7816b3061e6726bffb60dd0df442ba36a47f 100644 (file)
@@ -1,11 +1,11 @@
 error: cannot import a built-in macro
-  --> $DIR/not-whitelisted.rs:8:5
+  --> $DIR/not-whitelisted.rs:6:5
    |
 LL | use test; //~ ERROR cannot import a built-in macro
    |     ^^^^
 
 error[E0432]: unresolved import `alloc`
-  --> $DIR/not-whitelisted.rs:7:5
+  --> $DIR/not-whitelisted.rs:5:5
    |
 LL | use alloc; //~ ERROR unresolved import `alloc`
    |     ^^^^^ no `alloc` external crate
index 3814fc02745a7083b3c2533c74a3e5c583eb62d4..d79798d57e820622787d44647a523bf8b90e35fd 100644 (file)
@@ -2,7 +2,6 @@
 
 // Enabling `ireffutable_let_patterns` isn't necessary for what this tests, but it makes coming up
 // with examples easier.
-#![feature(irrefutable_let_patterns)]
 
 #[allow(irrefutable_let_patterns)]
 fn main() {
index 1d518215c2c36690d3bec4c02410e107c7adc03a..2cd59fe56cf2d111a346af2c792663d6bab6d3df 100644 (file)
@@ -1,5 +1,5 @@
 error: ambiguous use of `&&`
-  --> $DIR/syntax-ambiguity-2015.rs:11:47
+  --> $DIR/syntax-ambiguity-2015.rs:10:47
    |
 LL |     if let Range { start: _, end: _ } = true..true && false { }
    |                                               ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)`
@@ -8,7 +8,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false { }
    = note: see rust-lang/rust#53668 for more information
 
 error: ambiguous use of `||`
-  --> $DIR/syntax-ambiguity-2015.rs:14:47
+  --> $DIR/syntax-ambiguity-2015.rs:13:47
    |
 LL |     if let Range { start: _, end: _ } = true..true || false { }
    |                                               ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)`
@@ -17,7 +17,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false { }
    = note: see rust-lang/rust#53668 for more information
 
 error: ambiguous use of `&&`
-  --> $DIR/syntax-ambiguity-2015.rs:17:50
+  --> $DIR/syntax-ambiguity-2015.rs:16:50
    |
 LL |     while let Range { start: _, end: _ } = true..true && false { }
    |                                                  ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)`
@@ -26,7 +26,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false { }
    = note: see rust-lang/rust#53668 for more information
 
 error: ambiguous use of `||`
-  --> $DIR/syntax-ambiguity-2015.rs:20:50
+  --> $DIR/syntax-ambiguity-2015.rs:19:50
    |
 LL |     while let Range { start: _, end: _ } = true..true || false { }
    |                                                  ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)`
@@ -35,7 +35,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false { }
    = note: see rust-lang/rust#53668 for more information
 
 error: ambiguous use of `&&`
-  --> $DIR/syntax-ambiguity-2015.rs:23:19
+  --> $DIR/syntax-ambiguity-2015.rs:22:19
    |
 LL |     if let true = false && false { }
    |                   ^^^^^^^^^^^^^^ help: consider adding parentheses: `(false && false)`
@@ -44,7 +44,7 @@ LL |     if let true = false && false { }
    = note: see rust-lang/rust#53668 for more information
 
 error: ambiguous use of `&&`
-  --> $DIR/syntax-ambiguity-2015.rs:26:22
+  --> $DIR/syntax-ambiguity-2015.rs:25:22
    |
 LL |     while let true = (1 == 2) && false { }
    |                      ^^^^^^^^^^^^^^^^^ help: consider adding parentheses: `((1 == 2) && false)`
index 311953a283e376384b6ce1a44b948822102578d9..687bf659416ab27a2172be16cbc15f365d7a7d6b 100644 (file)
@@ -2,7 +2,6 @@
 
 // Enabling `ireffutable_let_patterns` isn't necessary for what this tests, but it makes coming up
 // with examples easier.
-#![feature(irrefutable_let_patterns)]
 
 #[allow(irrefutable_let_patterns)]
 fn main() {
index b3579973ca2bd5766756a9cdee7b83dce9115b8a..cbba2d7473334ef4f582901cfd21d3b28828f098 100644 (file)
@@ -1,5 +1,5 @@
 error: ambiguous use of `&&`
-  --> $DIR/syntax-ambiguity-2018.rs:11:47
+  --> $DIR/syntax-ambiguity-2018.rs:10:47
    |
 LL |     if let Range { start: _, end: _ } = true..true && false { }
    |                                               ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)`
@@ -8,7 +8,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false { }
    = note: see rust-lang/rust#53668 for more information
 
 error: ambiguous use of `||`
-  --> $DIR/syntax-ambiguity-2018.rs:14:47
+  --> $DIR/syntax-ambiguity-2018.rs:13:47
    |
 LL |     if let Range { start: _, end: _ } = true..true || false { }
    |                                               ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)`
@@ -17,7 +17,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false { }
    = note: see rust-lang/rust#53668 for more information
 
 error: ambiguous use of `&&`
-  --> $DIR/syntax-ambiguity-2018.rs:17:50
+  --> $DIR/syntax-ambiguity-2018.rs:16:50
    |
 LL |     while let Range { start: _, end: _ } = true..true && false { }
    |                                                  ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)`
@@ -26,7 +26,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false { }
    = note: see rust-lang/rust#53668 for more information
 
 error: ambiguous use of `||`
-  --> $DIR/syntax-ambiguity-2018.rs:20:50
+  --> $DIR/syntax-ambiguity-2018.rs:19:50
    |
 LL |     while let Range { start: _, end: _ } = true..true || false { }
    |                                                  ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)`
@@ -35,7 +35,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false { }
    = note: see rust-lang/rust#53668 for more information
 
 error: ambiguous use of `&&`
-  --> $DIR/syntax-ambiguity-2018.rs:23:19
+  --> $DIR/syntax-ambiguity-2018.rs:22:19
    |
 LL |     if let true = false && false { }
    |                   ^^^^^^^^^^^^^^ help: consider adding parentheses: `(false && false)`
@@ -44,7 +44,7 @@ LL |     if let true = false && false { }
    = note: see rust-lang/rust#53668 for more information
 
 error: ambiguous use of `&&`
-  --> $DIR/syntax-ambiguity-2018.rs:26:22
+  --> $DIR/syntax-ambiguity-2018.rs:25:22
    |
 LL |     while let true = (1 == 2) && false { }
    |                      ^^^^^^^^^^^^^^^^^ help: consider adding parentheses: `((1 == 2) && false)`
index 1ef154447903b2472d37e4f8fca335ed3c2e2ab3..e0184164b3ac22c68975dc89d1cc15899d7b0a49 100644 (file)
@@ -28,7 +28,7 @@ fn foo<T>(iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /*
 
 // Full example of enumerate iterator
 
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
 struct StreamEnumerate<I> {
     iter: I,
     count: usize,
index d777b1165f30b9b5161c80b7690fbb3c9a9618c6..1e53c2d1daca465044bc19a724d3badee99539de 100644 (file)
@@ -1,6 +1,5 @@
 // edition:2018
 
-#![feature(uniform_paths)]
 #![allow(non_camel_case_types)]
 
 mod T {
@@ -17,7 +16,7 @@ fn type_param<T>() {
 }
 
 fn self_import<T>() {
-    use T; // FIXME Should be an error, but future-proofing fails due to `T` being "self-shadowed"
+    use T; //~ ERROR imports cannot refer to type parameters
 }
 
 fn let_binding() {
index 594b22496e74adbe7fda873c1d2e38bf72f3a3a2..413e199cd646cdc829323cd8527d1589e86ae630 100644 (file)
@@ -1,50 +1,56 @@
 error: imports cannot refer to type parameters
-  --> $DIR/future-proofing-locals.rs:14:9
+  --> $DIR/future-proofing-locals.rs:13:9
    |
 LL |     use T as _; //~ ERROR imports cannot refer to type parameters
    |         ^
 
 error: imports cannot refer to type parameters
-  --> $DIR/future-proofing-locals.rs:15:9
+  --> $DIR/future-proofing-locals.rs:14:9
    |
 LL |     use T::U; //~ ERROR imports cannot refer to type parameters
    |         ^
 
 error: imports cannot refer to type parameters
-  --> $DIR/future-proofing-locals.rs:16:9
+  --> $DIR/future-proofing-locals.rs:15:9
    |
 LL |     use T::*; //~ ERROR imports cannot refer to type parameters
    |         ^
 
+error: imports cannot refer to type parameters
+  --> $DIR/future-proofing-locals.rs:19:9
+   |
+LL |     use T; //~ ERROR imports cannot refer to type parameters
+   |         ^
+
 error: imports cannot refer to local variables
-  --> $DIR/future-proofing-locals.rs:26:9
+  --> $DIR/future-proofing-locals.rs:25:9
    |
 LL |     use x as _; //~ ERROR imports cannot refer to local variables
    |         ^
 
 error: imports cannot refer to local variables
-  --> $DIR/future-proofing-locals.rs:32:9
+  --> $DIR/future-proofing-locals.rs:31:9
    |
 LL |     use x; //~ ERROR imports cannot refer to local variables
    |         ^
 
 error: imports cannot refer to local variables
-  --> $DIR/future-proofing-locals.rs:38:17
+  --> $DIR/future-proofing-locals.rs:37:17
    |
 LL |             use x; //~ ERROR imports cannot refer to local variables
    |                 ^
 
 error: imports cannot refer to type parameters
-  --> $DIR/future-proofing-locals.rs:46:10
+  --> $DIR/future-proofing-locals.rs:45:10
    |
 LL |     use {T as _, x}; //~ ERROR imports cannot refer to type parameters
    |          ^
 
 error: imports cannot refer to local variables
-  --> $DIR/future-proofing-locals.rs:46:18
+  --> $DIR/future-proofing-locals.rs:45:18
    |
 LL |     use {T as _, x}; //~ ERROR imports cannot refer to type parameters
    |                  ^
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 
index 824405074abe3c602e0a4e6f34a65f43ae0859b5..5eafbb2c2fc66a2ef86f1a8f1e4b159475caef14 100644 (file)
@@ -2,8 +2,6 @@
 // compile-flags:--extern baz
 // edition:2018
 
-#![feature(uniform_paths)]
-
 mod foo {
     pub type Bar = u32;
 }
index 8425ee0752e8bc20192e18ffbfb4609113261f8d..71c8289264ffe47620b21f0ec208afc263a33b05 100644 (file)
@@ -1,5 +1,5 @@
 error[E0432]: unresolved import `foo`
-  --> $DIR/local-path-suggestions-2018.rs:12:9
+  --> $DIR/local-path-suggestions-2018.rs:10:9
    |
 LL |     use foo::Bar; //~ ERROR unresolved import `foo`
    |         ^^^ did you mean `crate::foo`?
@@ -7,7 +7,7 @@ LL |     use foo::Bar; //~ ERROR unresolved import `foo`
    = note: `use` statements changed in Rust 2018; read more at <https://doc.rust-lang.org/edition-guide/rust-2018/module-system/path-clarity.html>
 
 error[E0432]: unresolved import `foobar`
-  --> $DIR/local-path-suggestions-2018.rs:21:5
+  --> $DIR/local-path-suggestions-2018.rs:19:5
    |
 LL | use foobar::Baz; //~ ERROR unresolved import `foobar`
    |     ^^^^^^ did you mean `baz::foobar`?
index 19be7dc9640409383dbfa8f560a0e16484485944..3f5897901a056b7cb1714f880ebe41222e7d31f8 100644 (file)
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(uniform_paths)]
-
 mod my {
     pub mod sub {
         pub fn bar() {}
index 0088296b1a4717217c8bfcca034ae2b978d62a30..4a01ba5088f62099cf2f200b76f4db2549a72d7a 100644 (file)
@@ -1,16 +1,16 @@
 error[E0659]: `sub` is ambiguous (name vs any other name during import resolution)
-  --> $DIR/block-scoped-shadow-nested.rs:18:13
+  --> $DIR/block-scoped-shadow-nested.rs:16:13
    |
 LL |         use sub::bar; //~ ERROR `sub` is ambiguous
    |             ^^^ ambiguous name
    |
 note: `sub` could refer to the module imported here
-  --> $DIR/block-scoped-shadow-nested.rs:16:9
+  --> $DIR/block-scoped-shadow-nested.rs:14:9
    |
 LL |     use my::sub;
    |         ^^^^^^^
 note: `sub` could also refer to the module defined here
-  --> $DIR/block-scoped-shadow-nested.rs:11:1
+  --> $DIR/block-scoped-shadow-nested.rs:9:1
    |
 LL | / mod sub {
 LL | |     pub fn bar() {}
index a7bc625bbf0a4480cb4482a9382bc3b61b5ffc94..0c2da1884b758744e4aff57539597b217d0c5a08 100644 (file)
@@ -1,8 +1,6 @@
 // compile-pass
 // edition:2018
 
-#![feature(uniform_paths)]
-
 fn main() {
     enum E { A, B, C }
 
diff --git a/src/test/ui/rust-2018/uniform-paths/issue-54390.rs b/src/test/ui/rust-2018/uniform-paths/issue-54390.rs
deleted file mode 100644 (file)
index 536cc25..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// edition:2018
-
-#![deny(unused)]
-
-use std::fmt;
-
-// No "unresolved import" + "unused import" combination here.
-use fmt::Write; //~ ERROR imports can only refer to extern crate names
-                //~| ERROR unused import: `fmt::Write`
-
-fn main() {}
diff --git a/src/test/ui/rust-2018/uniform-paths/issue-54390.stderr b/src/test/ui/rust-2018/uniform-paths/issue-54390.stderr
deleted file mode 100644 (file)
index 8f86698..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
-  --> $DIR/issue-54390.rs:8:5
-   |
-LL | use std::fmt;
-   |     -------- not an extern crate passed with `--extern`
-...
-LL | use fmt::Write; //~ ERROR imports can only refer to extern crate names
-   |     ^^^
-   |
-   = help: add #![feature(uniform_paths)] to the crate attributes to enable
-note: this import refers to the module imported here
-  --> $DIR/issue-54390.rs:5:5
-   |
-LL | use std::fmt;
-   |     ^^^^^^^^
-
-error: unused import: `fmt::Write`
-  --> $DIR/issue-54390.rs:8:5
-   |
-LL | use fmt::Write; //~ ERROR imports can only refer to extern crate names
-   |     ^^^^^^^^^^
-   |
-note: lint level defined here
-  --> $DIR/issue-54390.rs:3:9
-   |
-LL | #![deny(unused)]
-   |         ^^^^^^
-   = note: #[deny(unused_imports)] implied by #[deny(unused)]
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
index 69f6a8668add39a7231bbc29b79d3eb93f10bdaf..6c3f1892cb3697ffd27bf570d72bd64917908850 100644 (file)
@@ -1,23 +1,23 @@
 // edition:2018
 
-// For the time being `macro_rules` items are treated as *very* private...
-
-#![feature(decl_macro, uniform_paths)]
-#![allow(non_camel_case_types)]
+#![feature(decl_macro)]
 
 mod m1 {
+    // Non-exported legacy macros are treated as `pub(crate)`.
     macro_rules! legacy_macro { () => () }
 
-    // ... so they can't be imported by themselves, ...
-    use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
+    use legacy_macro as _; // OK
+    pub(crate) use legacy_macro as _; // OK
+    pub use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
 }
 
 mod m2 {
     macro_rules! legacy_macro { () => () }
 
+    #[allow(non_camel_case_types)]
     type legacy_macro = u8;
 
-    // ... but don't prevent names from other namespaces from being imported, ...
+    // Legacy macro imports don't prevent names from other namespaces from being imported.
     use legacy_macro as _; // OK
 }
 
@@ -27,19 +27,17 @@ mod m3 {
     fn f() {
         macro_rules! legacy_macro { () => () }
 
-        // ... but still create ambiguities with other names in the same namespace.
+        // Legacy macro imports create ambiguities with other names in the same namespace.
         use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous
-                               //~| ERROR `legacy_macro` is private, and cannot be re-exported
     }
 }
 
 mod exported {
-    // Exported macros are treated as private as well,
-    // some better rules need to be figured out later.
+    // Exported legacy macros are treated as `pub`.
     #[macro_export]
     macro_rules! legacy_macro { () => () }
 
-    use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
+    pub use legacy_macro as _; // OK
 }
 
 fn main() {}
index be7bbd314df316027358d84d6e44872a217ab306..684f5fceac15fc6f191d99bc6e07031553c99d3d 100644 (file)
@@ -1,39 +1,15 @@
 error[E0364]: `legacy_macro` is private, and cannot be re-exported
-  --> $DIR/macro-rules.rs:12:9
+  --> $DIR/macro-rules.rs:11:13
    |
-LL |     use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
-   |         ^^^^^^^^^^^^^^^^^
-   |
-note: consider marking `legacy_macro` as `pub` in the imported module
-  --> $DIR/macro-rules.rs:12:9
-   |
-LL |     use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
-   |         ^^^^^^^^^^^^^^^^^
-
-error[E0364]: `legacy_macro` is private, and cannot be re-exported
-  --> $DIR/macro-rules.rs:31:13
-   |
-LL |         use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous
+LL |     pub use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
    |             ^^^^^^^^^^^^^^^^^
    |
 note: consider marking `legacy_macro` as `pub` in the imported module
-  --> $DIR/macro-rules.rs:31:13
+  --> $DIR/macro-rules.rs:11:13
    |
-LL |         use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous
+LL |     pub use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
    |             ^^^^^^^^^^^^^^^^^
 
-error[E0364]: `legacy_macro` is private, and cannot be re-exported
-  --> $DIR/macro-rules.rs:42:9
-   |
-LL |     use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
-   |         ^^^^^^^^^^^^^^^^^
-   |
-note: consider marking `legacy_macro` as `pub` in the imported module
-  --> $DIR/macro-rules.rs:42:9
-   |
-LL |     use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
-   |         ^^^^^^^^^^^^^^^^^
-
 error[E0659]: `legacy_macro` is ambiguous (name vs any other name during import resolution)
   --> $DIR/macro-rules.rs:31:13
    |
@@ -52,7 +28,7 @@ LL |     macro legacy_macro() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    = help: use `self::legacy_macro` to refer to this macro unambiguously
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 Some errors occurred: E0364, E0659.
 For more information about an error, try `rustc --explain E0364`.
diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs b/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs
new file mode 100644 (file)
index 0000000..541fc1b
--- /dev/null
@@ -0,0 +1,19 @@
+// edition:2018
+
+// Built-in attribute
+use inline as imported_inline;
+mod builtin {
+    pub use inline as imported_inline;
+}
+
+// Tool module
+use rustfmt as imported_rustfmt;
+mod tool_mod {
+    pub use rustfmt as imported_rustfmt;
+}
+
+#[imported_inline] //~ ERROR cannot use a built-in attribute through an import
+#[builtin::imported_inline] //~ ERROR cannot use a built-in attribute through an import
+#[imported_rustfmt::skip] //~ ERROR cannot use a tool module through an import
+#[tool_mod::imported_rustfmt::skip] //~ ERROR cannot use a tool module through an import
+fn main() {}
diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr b/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr
new file mode 100644 (file)
index 0000000..40b8fcf
--- /dev/null
@@ -0,0 +1,44 @@
+error: cannot use a built-in attribute through an import
+  --> $DIR/prelude-fail-2.rs:15:3
+   |
+LL | #[imported_inline] //~ ERROR cannot use a built-in attribute through an import
+   |   ^^^^^^^^^^^^^^^
+   |
+note: the built-in attribute imported here
+  --> $DIR/prelude-fail-2.rs:4:5
+   |
+LL | use inline as imported_inline;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot use a built-in attribute through an import
+  --> $DIR/prelude-fail-2.rs:16:3
+   |
+LL | #[builtin::imported_inline] //~ ERROR cannot use a built-in attribute through an import
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot use a tool module through an import
+  --> $DIR/prelude-fail-2.rs:17:3
+   |
+LL | #[imported_rustfmt::skip] //~ ERROR cannot use a tool module through an import
+   |   ^^^^^^^^^^^^^^^^
+   |
+note: the tool module imported here
+  --> $DIR/prelude-fail-2.rs:10:5
+   |
+LL | use rustfmt as imported_rustfmt;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot use a tool module through an import
+  --> $DIR/prelude-fail-2.rs:18:13
+   |
+LL | #[tool_mod::imported_rustfmt::skip] //~ ERROR cannot use a tool module through an import
+   |             ^^^^^^^^^^^^^^^^
+   |
+note: the tool module imported here
+  --> $DIR/prelude-fail-2.rs:12:13
+   |
+LL |     pub use rustfmt as imported_rustfmt;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
index c5bd50f2f567f2f3675eacc0493532c45a9c8fc3..d717884c901b3e6efd658fc8035c3128b7a72331 100644 (file)
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(uniform_paths)]
-
 // Built-in macro
 use env as env_imported; //~ ERROR cannot import a built-in macro
 
index 794d986b82ef181e76baf4c8c78a4731d13664bf..fdfea416b12f1af9d7d907ae0afba6688ad5d444 100644 (file)
@@ -1,11 +1,11 @@
 error: cannot import a built-in macro
-  --> $DIR/prelude-fail.rs:6:5
+  --> $DIR/prelude-fail.rs:4:5
    |
 LL | use env as env_imported; //~ ERROR cannot import a built-in macro
    |     ^^^^^^^^^^^^^^^^^^^
 
 error[E0432]: unresolved import `rustfmt`
-  --> $DIR/prelude-fail.rs:9:5
+  --> $DIR/prelude-fail.rs:7:5
    |
 LL | use rustfmt::skip as imported_rustfmt_skip; //~ ERROR unresolved import `rustfmt`
    |     ^^^^^^^ not a module `rustfmt`
index 5aab5fc3a40187ac246368817eddd95612c20986..9a326b4c728bdd68eb791ba6166072b08629870e 100644 (file)
@@ -1,17 +1,9 @@
 // compile-pass
 // edition:2018
 
-#![feature(uniform_paths)]
-
 // Macro imported with `#[macro_use] extern crate`
 use vec as imported_vec;
 
-// Built-in attribute
-use inline as imported_inline;
-
-// Tool module
-use rustfmt as imported_rustfmt;
-
 // Standard library prelude
 use Vec as ImportedVec;
 
@@ -20,8 +12,6 @@
 
 type A = imported_u8;
 
-#[imported_inline]
-#[imported_rustfmt::skip]
 fn main() {
     imported_vec![0];
     ImportedVec::<u8>::new();
diff --git a/src/test/ui/should-fail-no_gate_irrefutable_if_let_pattern.rs b/src/test/ui/should-fail-no_gate_irrefutable_if_let_pattern.rs
deleted file mode 100644 (file)
index 2899298..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-// should-fail-irrefutable_let_patterns
-fn main() {
-    if let _ = 5 {}
-    //~^ ERROR irrefutable if-let pattern [E0162]
-}
diff --git a/src/test/ui/should-fail-no_gate_irrefutable_if_let_pattern.stderr b/src/test/ui/should-fail-no_gate_irrefutable_if_let_pattern.stderr
deleted file mode 100644 (file)
index 9c9ebc6..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0162]: irrefutable if-let pattern
-  --> $DIR/should-fail-no_gate_irrefutable_if_let_pattern.rs:3:12
-   |
-LL |     if let _ = 5 {}
-   |            ^ irrefutable pattern
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0162`.
diff --git a/src/test/ui/should-fail-with_gate_irrefutable_pattern_deny.rs b/src/test/ui/should-fail-with_gate_irrefutable_pattern_deny.rs
deleted file mode 100644 (file)
index 1b9b3dc..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#![feature(irrefutable_let_patterns)]
-
-// should-fail-irrefutable_let_patterns_with_gate
-fn main() {
-    if let _ = 5 {}
-    //~^ ERROR irrefutable if-let pattern [irrefutable_let_patterns]
-}
diff --git a/src/test/ui/should-fail-with_gate_irrefutable_pattern_deny.stderr b/src/test/ui/should-fail-with_gate_irrefutable_pattern_deny.stderr
deleted file mode 100644 (file)
index dc670f0..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-error: irrefutable if-let pattern
-  --> $DIR/should-fail-with_gate_irrefutable_pattern_deny.rs:5:5
-   |
-LL |     if let _ = 5 {}
-   |     ^^^^^^^^^^^^^^^
-   |
-   = note: #[deny(irrefutable_let_patterns)] on by default
-
-error: aborting due to previous error
-
index 4c1985b9f3af1ab8daa9c11f89f136f1aeaf79e5..22df5e42d2607d57ef4c57954938dfee2ed8811b 100644 (file)
@@ -1,39 +1,3 @@
-error[E0442]: intrinsic argument 1 has wrong type: found `u16`, expected `i16`
-  --> $DIR/simd-intrinsic-declaration-type.rs:33:9
-   |
-LL |         fn x86_mm_adds_epi16(x: u16x8, y: u16x8) -> u16x8;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0442]: intrinsic argument 2 has wrong type: found `u16`, expected `i16`
-  --> $DIR/simd-intrinsic-declaration-type.rs:33:9
-   |
-LL |         fn x86_mm_adds_epi16(x: u16x8, y: u16x8) -> u16x8;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0442]: intrinsic return value has wrong type: found `u16`, expected `i16`
-  --> $DIR/simd-intrinsic-declaration-type.rs:33:9
-   |
-LL |         fn x86_mm_adds_epi16(x: u16x8, y: u16x8) -> u16x8;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0442]: intrinsic argument 1 has wrong type: found `i16`, expected `u16`
-  --> $DIR/simd-intrinsic-declaration-type.rs:37:9
-   |
-LL |         fn x86_mm_adds_epu16(x: i16x8, y: i16x8) -> i16x8;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0442]: intrinsic argument 2 has wrong type: found `i16`, expected `u16`
-  --> $DIR/simd-intrinsic-declaration-type.rs:37:9
-   |
-LL |         fn x86_mm_adds_epu16(x: i16x8, y: i16x8) -> i16x8;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0442]: intrinsic return value has wrong type: found `i16`, expected `u16`
-  --> $DIR/simd-intrinsic-declaration-type.rs:37:9
-   |
-LL |         fn x86_mm_adds_epu16(x: i16x8, y: i16x8) -> i16x8;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0442]: intrinsic argument 1 has wrong type: found vector with length 16, expected length 8
   --> $DIR/simd-intrinsic-declaration-type.rs:45:5
    |
@@ -70,6 +34,42 @@ error[E0442]: intrinsic return value has wrong type: found `i32`, expected `f32`
 LL |     fn x86_mm_max_ps(x: i32x4, y: i32x4) -> i32x4;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error[E0442]: intrinsic argument 1 has wrong type: found `u16`, expected `i16`
+  --> $DIR/simd-intrinsic-declaration-type.rs:33:9
+   |
+LL |         fn x86_mm_adds_epi16(x: u16x8, y: u16x8) -> u16x8;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0442]: intrinsic argument 2 has wrong type: found `u16`, expected `i16`
+  --> $DIR/simd-intrinsic-declaration-type.rs:33:9
+   |
+LL |         fn x86_mm_adds_epi16(x: u16x8, y: u16x8) -> u16x8;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0442]: intrinsic return value has wrong type: found `u16`, expected `i16`
+  --> $DIR/simd-intrinsic-declaration-type.rs:33:9
+   |
+LL |         fn x86_mm_adds_epi16(x: u16x8, y: u16x8) -> u16x8;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0442]: intrinsic argument 1 has wrong type: found `i16`, expected `u16`
+  --> $DIR/simd-intrinsic-declaration-type.rs:37:9
+   |
+LL |         fn x86_mm_adds_epu16(x: i16x8, y: i16x8) -> i16x8;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0442]: intrinsic argument 2 has wrong type: found `i16`, expected `u16`
+  --> $DIR/simd-intrinsic-declaration-type.rs:37:9
+   |
+LL |         fn x86_mm_adds_epu16(x: i16x8, y: i16x8) -> i16x8;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0442]: intrinsic return value has wrong type: found `i16`, expected `u16`
+  --> $DIR/simd-intrinsic-declaration-type.rs:37:9
+   |
+LL |         fn x86_mm_adds_epu16(x: i16x8, y: i16x8) -> i16x8;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error: aborting due to 12 previous errors
 
 For more information about this error, try `rustc --explain E0442`.
index 42b93334572fc15a8af4555bc992b522129a6625..f052f866c901b863b13948e30485cc693dc3f95c 100644 (file)
@@ -11,17 +11,17 @@ LL | #![warn(unused)]
    |         ^^^^^^
    = note: #[warn(unused_variables)] implied by #[warn(unused)]
 
-warning: variable `theTwo` should have a snake case name such as `the_two`
+warning: variable `theTwo` should have a snake case name
   --> $DIR/issue-24690.rs:12:9
    |
 LL |     let theTwo = 2; //~ WARN should have a snake case name
-   |         ^^^^^^
+   |         ^^^^^^ help: convert the identifier to snake case: `the_two`
    |
    = note: #[warn(non_snake_case)] on by default
 
-warning: variable `theOtherTwo` should have a snake case name such as `the_other_two`
+warning: variable `theOtherTwo` should have a snake case name
   --> $DIR/issue-24690.rs:13:9
    |
 LL |     let theOtherTwo = 2; //~ WARN should have a snake case name
-   |         ^^^^^^^^^^^
+   |         ^^^^^^^^^^^ help: convert the identifier to snake case: `the_other_two`
 
index 2091fffd418ee68c3b315e16f01b5fbb0af6954b..84d401c9fa61df2d7b718119bc3cc11a1af5f2f6 100644 (file)
@@ -2,5 +2,6 @@
 
 static mut a: Box<isize> = box 3;
 //~^ ERROR allocations are not allowed in statics
+//~| ERROR static contains unimplemented expression type
 
 fn main() {}
index a0fa245156f877e369cdaad136af48ff131bda5e..d2c6ba6a2f85a70dc95ecfb4bd66b4c0592327c4 100644 (file)
@@ -4,6 +4,13 @@ error[E0010]: allocations are not allowed in statics
 LL | static mut a: Box<isize> = box 3;
    |                            ^^^^^ allocation not allowed in statics
 
-error: aborting due to previous error
+error[E0019]: static contains unimplemented expression type
+  --> $DIR/static-mut-not-constant.rs:3:32
+   |
+LL | static mut a: Box<isize> = box 3;
+   |                                ^
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0010`.
+Some errors occurred: E0010, E0019.
+For more information about an error, try `rustc --explain E0010`.
index 24d8db481b46833ef9e096a5c3fd5d387397199e..87809d212d79dd4e6b31b19c053b30ed43c80541 100644 (file)
@@ -1,8 +1,10 @@
 error[E0308]: if and else have incompatible types
-  --> $DIR/str-array-assignment.rs:3:11
+  --> $DIR/str-array-assignment.rs:3:37
    |
 LL |   let t = if true { s[..2] } else { s };
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected str, found &str
+   |                     ------          ^ expected str, found &str
+   |                     |
+   |                     expected because of this
    |
    = note: expected type `str`
               found type `&str`
index 3c1ed8e69a6bda290a1f34a04956ad4af3e02a52..cc62316bec1851c82be12ddd0c97d37f075e199b 100644 (file)
@@ -109,6 +109,8 @@ LL |         PointF::<u32> { .. } => {} //~ ERROR wrong number of type arguments
 error[E0308]: mismatched types
   --> $DIR/structure-constructor-type-mismatch.rs:54:9
    |
+LL |     match (Point { x: 1, y: 2 }) {
+   |           ---------------------- this match expression has type `Point<{integer}>`
 LL |         PointF::<u32> { .. } => {} //~ ERROR wrong number of type arguments
    |         ^^^^^^^^^^^^^^^^^^^^ expected integer, found f32
    |
@@ -118,6 +120,8 @@ LL |         PointF::<u32> { .. } => {} //~ ERROR wrong number of type arguments
 error[E0308]: mismatched types
   --> $DIR/structure-constructor-type-mismatch.rs:59:9
    |
+LL |     match (Point { x: 1, y: 2 }) {
+   |           ---------------------- this match expression has type `Point<{integer}>`
 LL |         PointF { .. } => {} //~ ERROR mismatched types
    |         ^^^^^^^^^^^^^ expected integer, found f32
    |
@@ -127,6 +131,8 @@ LL |         PointF { .. } => {} //~ ERROR mismatched types
 error[E0308]: mismatched types
   --> $DIR/structure-constructor-type-mismatch.rs:67:9
    |
+LL |     match (Pair { x: 1, y: 2 }) {
+   |           --------------------- this match expression has type `Pair<{integer}, {integer}>`
 LL |         PairF::<u32> { .. } => {} //~ ERROR mismatched types
    |         ^^^^^^^^^^^^^^^^^^^ expected integer, found f32
    |
index b8b743d3f40723116e525087bddc7f96f559a692..2bfb4110603f5a73411095d0caa37d71a502f0e9 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl DefaultedTrait for (A,) { } //~ ERROR E0117
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
@@ -13,7 +13,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl !DefaultedTrait for (B,) { } //~ ERROR E0117
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error[E0321]: cross-crate traits with a default impl, like `lib::DefaultedTrait`, can only be implemented for a struct/enum type defined in the current crate
@@ -28,7 +28,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl DefaultedTrait for lib::Something<C> { } //~ ERROR E0117
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
-   = note: the impl does not reference any types defined in this crate
+   = note: the impl does not reference only types defined in this crate
    = note: define and implement a trait or new type instead
 
 error: aborting due to 4 previous errors
index 811d166ed65a78c7c486a88b09e58ee103895bb5..1db022e886208f17050815bfd3f2bf65631ad186 100644 (file)
@@ -1,6 +1,5 @@
 // compile-pass
 
-#![feature(const_let)]
 #![feature(underscore_const_names)]
 
 trait Trt {}
index 953160db14e385294df4d24d2deb30ed9f837ba6..848c3d9bdb017caf607aea607654a35ab57199be 100644 (file)
@@ -1,12 +1,14 @@
-error[E0502]: cannot borrow `u.y` as immutable because it is also borrowed as mutable
+error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x.0`)
   --> $DIR/union-borrow-move-parent-sibling.rs:15:13
    |
 LL |     let a = &mut u.x.0;
-   |             ---------- mutable borrow occurs here
+   |             ---------- mutable borrow occurs here (via `u.x.0`)
 LL |     let b = &u.y; //~ ERROR cannot borrow `u.y`
-   |             ^^^^ immutable borrow occurs here
+   |             ^^^^ immutable borrow of `u.y` -- which overlaps with `u.x.0` -- occurs here
 LL |     use_borrow(a);
    |                - mutable borrow later used here
+   |
+   = note: `u.y` is a field of the union `U`, so it overlaps the field `u.x.0`
 
 error[E0382]: use of moved value: `u`
   --> $DIR/union-borrow-move-parent-sibling.rs:22:13
@@ -18,15 +20,17 @@ LL |     let b = u.y; //~ ERROR use of moved value: `u.y`
    |
    = note: move occurs because `u` has type `U`, which does not implement the `Copy` trait
 
-error[E0502]: cannot borrow `u.y` as immutable because it is also borrowed as mutable
+error[E0502]: cannot borrow `u` (via `u.y`) as immutable because it is also borrowed as mutable (via `u.x.0.0`)
   --> $DIR/union-borrow-move-parent-sibling.rs:28:13
    |
 LL |     let a = &mut (u.x.0).0;
-   |             -------------- mutable borrow occurs here
+   |             -------------- mutable borrow occurs here (via `u.x.0.0`)
 LL |     let b = &u.y; //~ ERROR cannot borrow `u.y`
-   |             ^^^^ immutable borrow occurs here
+   |             ^^^^ immutable borrow of `u.y` -- which overlaps with `u.x.0.0` -- occurs here
 LL |     use_borrow(a);
    |                - mutable borrow later used here
+   |
+   = note: `u.y` is a field of the union `U`, so it overlaps the field `u.x.0.0`
 
 error[E0382]: use of moved value: `u`
   --> $DIR/union-borrow-move-parent-sibling.rs:35:13
@@ -38,15 +42,17 @@ LL |     let b = u.y; //~ ERROR use of moved value: `u.y`
    |
    = note: move occurs because `u` has type `U`, which does not implement the `Copy` trait
 
-error[E0502]: cannot borrow `u.x` as immutable because it is also borrowed as mutable
+error[E0502]: cannot borrow `u` (via `u.x`) as immutable because it is also borrowed as mutable (via `*u.y`)
   --> $DIR/union-borrow-move-parent-sibling.rs:41:13
    |
 LL |     let a = &mut *u.y;
-   |             --------- mutable borrow occurs here
+   |             --------- mutable borrow occurs here (via `*u.y`)
 LL |     let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
-   |             ^^^^ immutable borrow occurs here
+   |             ^^^^ immutable borrow of `u.x` -- which overlaps with `*u.y` -- occurs here
 LL |     use_borrow(a);
    |                - mutable borrow later used here
+   |
+   = note: `u.x` is a field of the union `U`, so it overlaps the field `*u.y`
 
 error[E0382]: use of moved value: `u`
   --> $DIR/union-borrow-move-parent-sibling.rs:48:13
index c5baf82c74584ba8481175a000220e789277fd7c..9058707e505168bfc0f6c8db7c837c6ce694975b 100644 (file)
@@ -46,7 +46,7 @@ error[E0502]: cannot borrow `u` (via `u.x`) as immutable because `u` is also bor
 LL |     let a = &mut *u.y;
    |                  ---- mutable borrow occurs here (via `*u.y`)
 LL |     let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
-   |              ^^^ immutable borrow occurs here (via `u.x`)
+   |              ^^^ immutable borrow of `u.x` -- which overlaps with `*u.y` -- occurs here
 LL |     use_borrow(a);
 LL | }
    | - mutable borrow ends here
index a61e3329bdce8b9dd899aedca44e80e914c63959..788f49f743cda3a667987939dd2d61be5f5dd9b1 100644 (file)
@@ -1,4 +1,4 @@
-#![feature(rustc_attrs, const_let, const_fn)]
+#![feature(rustc_attrs)]
 
 #[rustc_layout_scalar_valid_range_start(1)]
 #[repr(transparent)]
@@ -8,13 +8,13 @@ fn main() {
 
 const fn foo() -> NonZero<u32> {
     let mut x = unsafe { NonZero(1) };
-    let y = &mut x.0; //~ ERROR references in constant functions may only refer to immutable
+    let y = &mut x.0; //~ ERROR references in const fn are unstable
     //~^ ERROR mutation of layout constrained field is unsafe
     unsafe { NonZero(1) }
 }
 
 const fn bar() -> NonZero<u32> {
     let mut x = unsafe { NonZero(1) };
-    let y = unsafe { &mut x.0 }; //~ ERROR references in constant functions may only refer to immut
+    let y = unsafe { &mut x.0 }; //~ ERROR mutable references in const fn are unstable
     unsafe { NonZero(1) }
 }
index f79792ffba9bec63c9a2e1960920a6ef8aa16da6..39a55190b17deed7328383bfe2bbe25c6a154aa3 100644 (file)
@@ -1,24 +1,23 @@
-error[E0017]: references in constant functions may only refer to immutable values
-  --> $DIR/ranged_ints2_const.rs:11:13
+error: mutable references in const fn are unstable
+  --> $DIR/ranged_ints2_const.rs:11:9
    |
-LL |     let y = &mut x.0; //~ ERROR references in constant functions may only refer to immutable
-   |             ^^^^^^^^ constant functions require immutable values
+LL |     let y = &mut x.0; //~ ERROR references in const fn are unstable
+   |         ^
 
-error[E0017]: references in constant functions may only refer to immutable values
-  --> $DIR/ranged_ints2_const.rs:18:22
+error: mutable references in const fn are unstable
+  --> $DIR/ranged_ints2_const.rs:18:9
    |
-LL |     let y = unsafe { &mut x.0 }; //~ ERROR references in constant functions may only refer to immut
-   |                      ^^^^^^^^ constant functions require immutable values
+LL |     let y = unsafe { &mut x.0 }; //~ ERROR mutable references in const fn are unstable
+   |         ^
 
 error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
   --> $DIR/ranged_ints2_const.rs:11:13
    |
-LL |     let y = &mut x.0; //~ ERROR references in constant functions may only refer to immutable
+LL |     let y = &mut x.0; //~ ERROR references in const fn are unstable
    |             ^^^^^^^^ mutation of layout constrained field
    |
    = note: mutating layout constrained fields cannot statically be checked for valid values
 
 error: aborting due to 3 previous errors
 
-Some errors occurred: E0017, E0133.
-For more information about an error, try `rustc --explain E0017`.
+For more information about this error, try `rustc --explain E0133`.
index 6497b611224b6a77b3d17cd7acf41427f68dce90..7b03d8eda9380ef1bf3125b7a64ac44ed5ef7035 100644 (file)
@@ -1,4 +1,4 @@
-#![feature(rustc_attrs, const_let, const_fn)]
+#![feature(rustc_attrs)]
 
 use std::cell::Cell;
 
index f589e4739baf17145f7d3e09d0e1e68e086a95fb..f09168c3d3f9ca48a8225cc0b165cb0d62d6fb1a 100644 (file)
@@ -1,4 +1,4 @@
-#![feature(rustc_attrs, const_let, const_fn)]
+#![feature(rustc_attrs)]
 
 #[rustc_layout_scalar_valid_range_start(1)]
 #[repr(transparent)]
index bed0d9bb2be5498919c79606c549bed7215e996f..e601c6e455544516948d72d06c02b909e13b9fd7 100644 (file)
@@ -3,7 +3,7 @@
 fn foo<
     'β, //~ ERROR non-ascii idents are not fully supported
     Î³  //~ ERROR non-ascii idents are not fully supported
-       //~^ WARN type parameter `γ` should have a camel case name such as `Γ`
+       //~^ WARN type parameter `γ` should have a camel case name
 >() {}
 
 struct X {
index 1ccf767491cdb3f7e72e33c12204e0694b88fca8..268dd99d06031ad10e7f74a51ec2f0ac40a33e4f 100644 (file)
@@ -30,11 +30,11 @@ LL |     let Î± = 0.00001f64; //~ ERROR non-ascii idents are not fully supported
    |
    = help: add #![feature(non_ascii_idents)] to the crate attributes to enable
 
-warning: type parameter `γ` should have a camel case name such as `Γ`
+warning: type parameter `γ` should have a camel case name
   --> $DIR/utf8_idents.rs:5:5
    |
 LL |     Î³  //~ ERROR non-ascii idents are not fully supported
-   |     ^
+   |     ^ help: convert the identifier to camel case: `Γ`
    |
    = note: #[warn(non_camel_case_types)] on by default
 
index 56caaaeee401e988491361b3a23513a6a2845610..220447079c629f88ed84f6d0d838963c312abbca 100644 (file)
@@ -1,10 +1,10 @@
-error: equality constraints are not yet supported in where clauses (#20041)
+error: equality constraints are not yet supported in where clauses (see #20041)
   --> $DIR/where-equality-constraints.rs:1:14
    |
 LL | fn f() where u8 = u16 {}
    |              ^^^^^^^^
 
-error: equality constraints are not yet supported in where clauses (#20041)
+error: equality constraints are not yet supported in where clauses (see #20041)
   --> $DIR/where-equality-constraints.rs:3:14
    |
 LL | fn g() where for<'a> &'static (u8,) == u16, {}
index 348edc15aca4c1027b97da3e0fedaa013d15c8eb..69f9de9497740018274cace4089346960bfdf2c2 100644 (file)
@@ -1,3 +1,5 @@
+// run-pass
+
 fn macros() {
     macro_rules! foo{
         ($p:pat, $e:expr, $b:block) => {{
@@ -10,16 +12,17 @@ macro_rules! bar{
         }}
     }
 
-    foo!(a, 1, { //~ ERROR irrefutable while-let
+    foo!(a, 1, { //~ WARN irrefutable while-let
         println!("irrefutable pattern");
     });
-    bar!(a, 1, { //~ ERROR irrefutable while-let
+    bar!(a, 1, { //~ WARN irrefutable while-let
         println!("irrefutable pattern");
     });
 }
 
 pub fn main() {
-    while let a = 1 { //~ ERROR irrefutable while-let
+    while let a = 1 { //~ WARN irrefutable while-let
         println!("irrefutable pattern");
+        break;
     }
 }
index 838dd8c14d7b566d10204be59ad65fa7c3ea8285..6d61143d33c844f1a89399bb0525bd147d58ec0f 100644 (file)
@@ -1,21 +1,33 @@
-error[E0165]: irrefutable while-let pattern
-  --> $DIR/while-let.rs:13:10
+warning: irrefutable while-let pattern
+  --> $DIR/while-let.rs:6:13
    |
-LL |     foo!(a, 1, { //~ ERROR irrefutable while-let
-   |          ^ irrefutable pattern
-
-error[E0165]: irrefutable while-let pattern
-  --> $DIR/while-let.rs:16:10
+LL |               while let $p = $e $b
+   |               ^^^^^
+...
+LL | /     foo!(a, 1, { //~ WARN irrefutable while-let
+LL | |         println!("irrefutable pattern");
+LL | |     });
+   | |_______- in this macro invocation
    |
-LL |     bar!(a, 1, { //~ ERROR irrefutable while-let
-   |          ^ irrefutable pattern
+   = note: #[warn(irrefutable_let_patterns)] on by default
 
-error[E0165]: irrefutable while-let pattern
-  --> $DIR/while-let.rs:22:15
+warning: irrefutable while-let pattern
+  --> $DIR/while-let.rs:6:13
    |
-LL |     while let a = 1 { //~ ERROR irrefutable while-let
-   |               ^ irrefutable pattern
+LL |               while let $p = $e $b
+   |               ^^^^^
+...
+LL | /     bar!(a, 1, { //~ WARN irrefutable while-let
+LL | |         println!("irrefutable pattern");
+LL | |     });
+   | |_______- in this macro invocation
 
-error: aborting due to 3 previous errors
+warning: irrefutable while-let pattern
+  --> $DIR/while-let.rs:24:5
+   |
+LL | /     while let a = 1 { //~ WARN irrefutable while-let
+LL | |         println!("irrefutable pattern");
+LL | |         break;
+LL | |     }
+   | |_____^
 
-For more information about this error, try `rustc --explain E0165`.
index 3c34a7704e0dfa524d573ca0d64d92bdb2709607..43c63fed8cef19efd88767d2973a012fe0215107 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(const_let)]
-
 pub static mut A: u32 = 0;
 pub static mut B: () = unsafe { A = 1; };
 //~^ ERROR could not evaluate static initializer
index 7be83b8dafcfdb4a0132861298eab079be712478..eba1c609d2f8355ad3efde3bb3c7f19cf83be76b 100644 (file)
@@ -1,23 +1,23 @@
 error[E0080]: could not evaluate static initializer
-  --> $DIR/write-to-static-mut-in-static.rs:4:33
+  --> $DIR/write-to-static-mut-in-static.rs:2:33
    |
 LL | pub static mut B: () = unsafe { A = 1; };
    |                                 ^^^^^ tried to modify a static's initial value from another static's initializer
 
 error[E0391]: cycle detected when const-evaluating `C`
-  --> $DIR/write-to-static-mut-in-static.rs:7:34
+  --> $DIR/write-to-static-mut-in-static.rs:5:34
    |
 LL | pub static mut C: u32 = unsafe { C = 1; 0 };
    |                                  ^^^^^
    |
 note: ...which requires const-evaluating `C`...
-  --> $DIR/write-to-static-mut-in-static.rs:7:1
+  --> $DIR/write-to-static-mut-in-static.rs:5:1
    |
 LL | pub static mut C: u32 = unsafe { C = 1; 0 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which again requires const-evaluating `C`, completing the cycle
 note: cycle used when const-evaluating + checking `C`
-  --> $DIR/write-to-static-mut-in-static.rs:7:1
+  --> $DIR/write-to-static-mut-in-static.rs:5:1
    |
 LL | pub static mut C: u32 = unsafe { C = 1; 0 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 574526c6a56a37df6cabf2eeb29fa33c653dea36..8c1baa55bcdcae2f6e57e480e57649791d87c151 100644 (file)
@@ -90,6 +90,7 @@
     "thumbv7em-none-eabi",
     "thumbv7em-none-eabihf",
     "thumbv7m-none-eabi",
+    "thumbv8m.main-none-eabi",
     "wasm32-unknown-emscripten",
     "wasm32-unknown-unknown",
     "x86_64-apple-darwin",
@@ -131,7 +132,8 @@ struct Manifest {
     manifest_version: String,
     date: String,
     pkg: BTreeMap<String, Package>,
-    renames: BTreeMap<String, Rename>
+    renames: BTreeMap<String, Rename>,
+    profiles: BTreeMap<String, Vec<String>>,
 }
 
 #[derive(Serialize)]
@@ -192,6 +194,7 @@ struct Builder {
     rustfmt_release: String,
     llvm_tools_release: String,
     lldb_release: String,
+    miri_release: String,
 
     input: PathBuf,
     output: PathBuf,
@@ -207,6 +210,7 @@ struct Builder {
     rustfmt_version: Option<String>,
     llvm_tools_version: Option<String>,
     lldb_version: Option<String>,
+    miri_version: Option<String>,
 
     rust_git_commit_hash: Option<String>,
     cargo_git_commit_hash: Option<String>,
@@ -215,6 +219,7 @@ struct Builder {
     rustfmt_git_commit_hash: Option<String>,
     llvm_tools_git_commit_hash: Option<String>,
     lldb_git_commit_hash: Option<String>,
+    miri_git_commit_hash: Option<String>,
 
     should_sign: bool,
 }
@@ -237,13 +242,14 @@ fn main() {
     let output = PathBuf::from(args.next().unwrap());
     let date = args.next().unwrap();
     let rust_release = args.next().unwrap();
+    let s3_address = args.next().unwrap();
     let cargo_release = args.next().unwrap();
     let rls_release = args.next().unwrap();
     let clippy_release = args.next().unwrap();
+    let miri_release = args.next().unwrap();
     let rustfmt_release = args.next().unwrap();
     let llvm_tools_release = args.next().unwrap();
     let lldb_release = args.next().unwrap();
-    let s3_address = args.next().unwrap();
 
     // Do not ask for a passphrase while manually testing
     let mut passphrase = String::new();
@@ -259,6 +265,7 @@ fn main() {
         rustfmt_release,
         llvm_tools_release,
         lldb_release,
+        miri_release,
 
         input,
         output,
@@ -274,6 +281,7 @@ fn main() {
         rustfmt_version: None,
         llvm_tools_version: None,
         lldb_version: None,
+        miri_version: None,
 
         rust_git_commit_hash: None,
         cargo_git_commit_hash: None,
@@ -282,6 +290,7 @@ fn main() {
         rustfmt_git_commit_hash: None,
         llvm_tools_git_commit_hash: None,
         lldb_git_commit_hash: None,
+        miri_git_commit_hash: None,
 
         should_sign,
     }.build();
@@ -297,6 +306,7 @@ fn build(&mut self) {
         self.llvm_tools_version = self.version("llvm-tools", "x86_64-unknown-linux-gnu");
         // lldb is only built for macOS.
         self.lldb_version = self.version("lldb", "x86_64-apple-darwin");
+        self.miri_version = self.version("miri", "x86_64-unknown-linux-gnu");
 
         self.rust_git_commit_hash = self.git_commit_hash("rust", "x86_64-unknown-linux-gnu");
         self.cargo_git_commit_hash = self.git_commit_hash("cargo", "x86_64-unknown-linux-gnu");
@@ -306,6 +316,7 @@ fn build(&mut self) {
         self.llvm_tools_git_commit_hash = self.git_commit_hash("llvm-tools",
                                                                "x86_64-unknown-linux-gnu");
         self.lldb_git_commit_hash = self.git_commit_hash("lldb", "x86_64-unknown-linux-gnu");
+        self.miri_git_commit_hash = self.git_commit_hash("miri", "x86_64-unknown-linux-gnu");
 
         self.digest_and_sign();
         let manifest = self.build_manifest();
@@ -331,6 +342,7 @@ fn build_manifest(&mut self) -> Manifest {
             date: self.date.to_string(),
             pkg: BTreeMap::new(),
             renames: BTreeMap::new(),
+            profiles: BTreeMap::new(),
         };
 
         self.package("rustc", &mut manifest.pkg, HOSTS);
@@ -346,6 +358,20 @@ fn build_manifest(&mut self) -> Manifest {
         self.package("llvm-tools-preview", &mut manifest.pkg, TARGETS);
         self.package("lldb-preview", &mut manifest.pkg, TARGETS);
 
+        self.profile("minimal",
+                     &mut manifest.profiles,
+                     &["rustc", "cargo", "rust-std", "rust-mingw"]);
+        self.profile("default",
+                     &mut manifest.profiles,
+                     &["rustc", "cargo", "rust-std", "rust-mingw",
+                       "rust-docs", "rustfmt-preview", "clippy-preview"]);
+        self.profile("complete",
+                     &mut manifest.profiles,
+                     &["rustc", "cargo", "rust-std", "rust-mingw",
+                       "rust-docs", "rustfmt-preview", "clippy-preview",
+                       "rls-preview", "rust-src", "llvm-tools-preview",
+                       "lldb-preview", "rust-analysis"]);
+
         manifest.renames.insert("rls".to_owned(), Rename { to: "rls-preview".to_owned() });
         manifest.renames.insert("rustfmt".to_owned(), Rename { to: "rustfmt-preview".to_owned() });
         manifest.renames.insert("clippy".to_owned(), Rename { to: "clippy-preview".to_owned() });
@@ -444,6 +470,13 @@ fn build_manifest(&mut self) -> Manifest {
         return manifest;
     }
 
+    fn profile(&mut self,
+               profile_name: &str,
+               dst: &mut BTreeMap<String, Vec<String>>,
+               pkgs: &[&str]) {
+        dst.insert(profile_name.to_owned(), pkgs.iter().map(|s| (*s).to_owned()).collect());
+    }
+
     fn package(&mut self,
                pkgname: &str,
                dst: &mut BTreeMap<String, Package>,
@@ -516,6 +549,8 @@ fn filename(&self, component: &str, target: &str) -> String {
             format!("llvm-tools-{}-{}.tar.gz", self.llvm_tools_release, target)
         } else if component == "lldb" || component == "lldb-preview" {
             format!("lldb-{}-{}.tar.gz", self.lldb_release, target)
+        } else if component == "miri" || component == "miri-preview" {
+            format!("miri-{}-{}.tar.gz", self.miri_release, target)
         } else {
             format!("{}-{}-{}.tar.gz", component, self.rust_release, target)
         }
@@ -534,6 +569,8 @@ fn cached_version(&self, component: &str) -> &Option<String> {
             &self.llvm_tools_version
         } else if component == "lldb" || component == "lldb-preview" {
             &self.lldb_version
+        } else if component == "miri" || component == "miri-preview" {
+            &self.miri_version
         } else {
             &self.rust_version
         }
@@ -552,6 +589,8 @@ fn cached_git_commit_hash(&self, component: &str) -> &Option<String> {
             &self.llvm_tools_git_commit_hash
         } else if component == "lldb" || component == "lldb-preview" {
             &self.lldb_git_commit_hash
+        } else if component == "miri" || component == "miri-preview" {
+            &self.miri_git_commit_hash
         } else {
             &self.rust_git_commit_hash
         }
index 39bd84494f4a9b40f2e3b38416a91d52d5c4738b..c63b6349b44019146cc2edcef8141692891b9401 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 39bd84494f4a9b40f2e3b38416a91d52d5c4738b
+Subproject commit c63b6349b44019146cc2edcef8141692891b9401
index 2e2a33aab897273a36498d526530f648d6113dc8..97f4cff8e904c268569d37922a27835209deff5d 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 2e2a33aab897273a36498d526530f648d6113dc8
+Subproject commit 97f4cff8e904c268569d37922a27835209deff5d
index 6f5e4bba7b1586fca6e0ea7724cadb5683b2f308..1a6361bd399a9466deba9b42ff2ff2ae365c5d0e 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 6f5e4bba7b1586fca6e0ea7724cadb5683b2f308
+Subproject commit 1a6361bd399a9466deba9b42ff2ff2ae365c5d0e
index ca440167f9f077e896815f1733ae40125d257d5c..c4499ef95ad8e205fead99248059ac0329bc70a3 100644 (file)
@@ -27,18 +27,21 @@ features = [
   "errhandlingapi",
   "jobapi",
   "jobapi2",
+  "knownfolders",
   "lmcons",
   "memoryapi",
   "minschannel",
   "minwinbase",
   "ntsecapi",
   "ntstatus",
+  "objbase",
   "profileapi",
   "processenv",
   "psapi",
   "schannel",
   "securitybaseapi",
   "shellapi",
+  "shlobj",
   "sspi",
   "synchapi",
   "sysinfoapi",
@@ -50,12 +53,15 @@ features = [
 ]
 
 [dependencies]
-curl-sys = { version = "0.4.13", optional = true }
+curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true }
 parking_lot = { version = "0.6", features = ['nightly'] }
 rand = { version = "0.5.5", features = ["i128_support"] }
 serde = { version = "1.0.82", features = ['derive'] }
 serde_json = { version = "1.0.31", features = ["raw_value"] }
 smallvec = { version = "0.6", features = ['union'] }
+scopeguard = { version = "0.3.3", features = ["use_std", "default"]}
+byteorder = { version = "1.2.7", features = ["i128"]}
+
 
 [target.'cfg(not(windows))'.dependencies]
 openssl = { version = "0.10.12", optional = true }
index 049a0ee49f0a41fa1aebc8ff34d9ff2f859f6837..2435a0cfd4e3892b968290c2ac647db4f9a7f908 100644 (file)
@@ -336,12 +336,11 @@ macro_rules! err {
                     level: Status::Unstable,
                     since: "None".to_owned(),
                     has_gate_test: false,
-                    // Whether there is a common tracking issue
-                    // for these feature gates remains an open question
-                    // https://github.com/rust-lang/rust/issues/24111#issuecomment-340283184
-                    // But we take 24111 otherwise they will be shown as
-                    // "internal to the compiler" which they are not.
-                    tracking_issue: Some(24111),
+                    // FIXME(#57563): #57563 is now used as a common tracking issue,
+                    // although we would like to have specific tracking
+                    // issues for each `rustc_const_unstable` in the
+                    // future.
+                    tracking_issue: Some(57563),
                 };
                 mf(Ok((feature_name, feature)), file, i + 1);
                 continue;