]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #61159 - RalfJung:ptr, r=alexcrichton
authorMazdak Farrokhzad <twingoow@gmail.com>
Tue, 28 May 2019 16:15:38 +0000 (18:15 +0200)
committerGitHub <noreply@github.com>
Tue, 28 May 2019 16:15:38 +0000 (18:15 +0200)
split core::ptr module into multiple files

Cc @Centril

562 files changed:
.azure-pipelines/auto.yml
.gitignore
.mailmap
Cargo.lock
README.md
RELEASES.md
appveyor.yml
src/bootstrap/builder.rs
src/bootstrap/channel.rs
src/bootstrap/check.rs
src/bootstrap/compile.rs
src/bootstrap/flags.rs
src/bootstrap/native.rs
src/bootstrap/test.rs
src/bootstrap/tool.rs
src/bootstrap/util.rs
src/ci/docker/dist-various-1/Dockerfile
src/ci/docker/x86_64-gnu-tools/checktools.sh
src/doc/rustc/src/lints/listing/warn-by-default.md
src/doc/rustdoc/src/the-doc-attribute.md
src/liballoc/boxed.rs
src/liballoc/raw_vec.rs
src/liballoc/tests/vec.rs
src/liballoc/vec.rs
src/libcore/cell.rs
src/libcore/future/future.rs
src/libcore/iter/mod.rs
src/libcore/iter/traits/iterator.rs
src/libcore/macros.rs
src/libcore/mem.rs
src/libcore/num/mod.rs
src/libcore/num/wrapping.rs
src/libcore/task/wake.rs
src/libprofiler_builtins/build.rs
src/librustc/error_codes.rs
src/librustc/hir/def.rs
src/librustc/hir/intravisit.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/def_collector.rs
src/librustc/hir/map/definitions.rs
src/librustc/hir/map/mod.rs
src/librustc/hir/mod.rs
src/librustc/infer/error_reporting/mod.rs
src/librustc/infer/freshen.rs
src/librustc/lint/context.rs
src/librustc/lint/internal.rs
src/librustc/lint/levels.rs
src/librustc/middle/dead.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/reachable.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc/mir/interpret/allocation.rs
src/librustc/mir/interpret/error.rs
src/librustc/mir/interpret/mod.rs
src/librustc/mir/interpret/pointer.rs
src/librustc/mir/interpret/value.rs
src/librustc/mir/mod.rs
src/librustc/query/mod.rs
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc/traits/mod.rs
src/librustc/traits/object_safety.rs
src/librustc/traits/on_unimplemented.rs
src/librustc/traits/project.rs
src/librustc/traits/query/normalize.rs
src/librustc/traits/specialize/mod.rs
src/librustc/traits/specialize/specialization_graph.rs
src/librustc/traits/util.rs
src/librustc/ty/adjustment.rs
src/librustc/ty/context.rs
src/librustc/ty/fold.rs
src/librustc/ty/instance.rs
src/librustc/ty/mod.rs
src/librustc/ty/print/mod.rs
src/librustc/ty/print/pretty.rs
src/librustc/ty/structural_impls.rs
src/librustc/ty/sty.rs
src/librustc/ty/subst.rs
src/librustc/util/profiling.rs
src/librustc_allocator/expand.rs
src/librustc_codegen_llvm/back/write.rs
src/librustc_codegen_ssa/back/write.rs
src/librustc_codegen_ssa/mir/constant.rs
src/librustc_codegen_ssa/mir/operand.rs
src/librustc_codegen_utils/symbol_names.rs
src/librustc_interface/util.rs
src/librustc_lint/builtin.rs
src/librustc_macros/src/symbols.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/schema.rs
src/librustc_mir/borrow_check/conflict_errors.rs
src/librustc_mir/borrow_check/move_errors.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/borrow_check/path_utils.rs
src/librustc_mir/borrow_check/place_ext.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/misc.rs
src/librustc_mir/const_eval.rs
src/librustc_mir/dataflow/impls/borrowed_locals.rs
src/librustc_mir/dataflow/move_paths/builder.rs
src/librustc_mir/dataflow/move_paths/mod.rs
src/librustc_mir/hair/constant.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/cx/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/interpret/eval_context.rs
src/librustc_mir/interpret/memory.rs
src/librustc_mir/interpret/operand.rs
src/librustc_mir/interpret/place.rs
src/librustc_mir/interpret/validity.rs
src/librustc_mir/lints.rs
src/librustc_mir/monomorphize/collector.rs
src/librustc_mir/monomorphize/item.rs
src/librustc_mir/monomorphize/mod.rs
src/librustc_mir/shim.rs
src/librustc_mir/transform/const_prop.rs
src/librustc_mir/transform/elaborate_drops.rs
src/librustc_mir/transform/generator.rs
src/librustc_mir/transform/inline.rs
src/librustc_mir/transform/qualify_min_const_fn.rs
src/librustc_mir/util/elaborate_drops.rs
src/librustc_mir/util/pretty.rs
src/librustc_passes/rvalue_promotion.rs
src/librustc_plugin/load.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/diagnostics.rs
src/librustc_resolve/lib.rs
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/lib.rs
src/librustc_save_analysis/sig.rs
src/librustc_target/Cargo.toml
src/librustc_target/abi/mod.rs
src/librustc_traits/lowering/mod.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/demand.rs
src/librustc_typeck/check/method/mod.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/impl_wf_check.rs
src/librustc_typeck/namespace.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/format.rs
src/librustdoc/html/item_type.rs
src/librustdoc/html/render.rs
src/librustdoc/passes/collect_intra_doc_links.rs
src/librustdoc/passes/mod.rs
src/libstd/Cargo.toml
src/libstd/env.rs
src/libstd/sys/cloudabi/backtrace.rs [deleted file]
src/libstd/sys/cloudabi/mod.rs
src/libstd/sys/redox/backtrace/mod.rs [deleted file]
src/libstd/sys/redox/backtrace/printing.rs [deleted file]
src/libstd/sys/redox/backtrace/tracing.rs [deleted file]
src/libstd/sys/redox/mod.rs
src/libstd/sys/sgx/backtrace.rs [deleted file]
src/libstd/sys/sgx/mod.rs
src/libstd/sys/unix/backtrace/mod.rs [deleted file]
src/libstd/sys/unix/backtrace/printing/dladdr.rs [deleted file]
src/libstd/sys/unix/backtrace/printing/mod.rs [deleted file]
src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs [deleted file]
src/libstd/sys/unix/backtrace/tracing/gcc_s.rs [deleted file]
src/libstd/sys/unix/backtrace/tracing/mod.rs [deleted file]
src/libstd/sys/unix/mod.rs
src/libstd/sys/wasi/backtrace.rs [deleted file]
src/libstd/sys/wasi/mod.rs
src/libstd/sys/wasm/backtrace.rs [deleted file]
src/libstd/sys/wasm/mod.rs
src/libstd/sys/windows/backtrace/backtrace_gnu.rs [deleted file]
src/libstd/sys/windows/backtrace/mod.rs [deleted file]
src/libstd/sys/windows/backtrace/printing/mod.rs [deleted file]
src/libstd/sys/windows/backtrace/printing/msvc.rs [deleted file]
src/libstd/sys/windows/c.rs
src/libstd/sys/windows/dynamic_lib.rs [deleted file]
src/libstd/sys/windows/mod.rs
src/libstd/sys_common/backtrace.rs
src/libstd/sys_common/gnu/libbacktrace.rs [deleted file]
src/libstd/sys_common/gnu/mod.rs [deleted file]
src/libstd/sys_common/mod.rs
src/libsyntax/ast.rs
src/libsyntax/attr/builtin.rs
src/libsyntax/attr/mod.rs
src/libsyntax/config.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/derive.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/feature_gate.rs
src/libsyntax/lib.rs
src/libsyntax/parse/diagnostics.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/literal.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/std_inject.rs
src/libsyntax/test.rs
src/libsyntax/tokenstream.rs
src/libsyntax_ext/asm.rs
src/libsyntax_ext/assert.rs
src/libsyntax_ext/deriving/clone.rs
src/libsyntax_ext/deriving/cmp/eq.rs
src/libsyntax_ext/deriving/cmp/ord.rs
src/libsyntax_ext/deriving/cmp/partial_eq.rs
src/libsyntax_ext/deriving/cmp/partial_ord.rs
src/libsyntax_ext/deriving/custom.rs
src/libsyntax_ext/deriving/debug.rs
src/libsyntax_ext/deriving/default.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_ext/deriving/hash.rs
src/libsyntax_ext/deriving/mod.rs
src/libsyntax_ext/env.rs
src/libsyntax_ext/format.rs
src/libsyntax_ext/lib.rs
src/libsyntax_ext/proc_macro_decls.rs
src/libsyntax_ext/proc_macro_server.rs
src/libsyntax_ext/test.rs
src/libsyntax_ext/test_case.rs
src/libsyntax_pos/symbol.rs
src/libtest/lib.rs
src/stage0.txt
src/test/mir-opt/box_expr.rs
src/test/mir-opt/byte_slice.rs [new file with mode: 0644]
src/test/mir-opt/inline-trait-method.rs
src/test/mir-opt/inline-trait-method_2.rs
src/test/mir-opt/issue-49232.rs
src/test/mir-opt/unusual-item-types.rs
src/test/pretty/issue-54752-async-block.rs [deleted file]
src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile [new file with mode: 0644]
src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/clib.c [new file with mode: 0644]
src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/cmain.c [new file with mode: 0644]
src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/main.rs [new file with mode: 0644]
src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/rustlib.rs [new file with mode: 0644]
src/test/run-pass/async-await.rs [deleted file]
src/test/run-pass/await-macro.rs [deleted file]
src/test/run-pass/generator/issue-59972.rs [deleted file]
src/test/run-pass/issue-55809.rs [deleted file]
src/test/run-pass/unsized-locals/fnbox-compat.rs
src/test/ui/E0501.rs [deleted file]
src/test/ui/E0501.stderr [deleted file]
src/test/ui/E0506.rs [deleted file]
src/test/ui/E0506.stderr [deleted file]
src/test/ui/E0508-fail.rs [deleted file]
src/test/ui/E0508-fail.stderr [deleted file]
src/test/ui/E0508.rs [deleted file]
src/test/ui/E0508.stderr [deleted file]
src/test/ui/E0583.rs [deleted file]
src/test/ui/E0583.stderr [deleted file]
src/test/ui/E0594.rs [deleted file]
src/test/ui/E0594.stderr [deleted file]
src/test/ui/E0596.rs [deleted file]
src/test/ui/E0596.stderr [deleted file]
src/test/ui/E0642.rs [deleted file]
src/test/ui/E0642.stderr [deleted file]
src/test/ui/E0660.rs [deleted file]
src/test/ui/E0660.stderr [deleted file]
src/test/ui/E0661.rs [deleted file]
src/test/ui/E0661.stderr [deleted file]
src/test/ui/E0662.rs [deleted file]
src/test/ui/E0662.stderr [deleted file]
src/test/ui/E0663.rs [deleted file]
src/test/ui/E0663.stderr [deleted file]
src/test/ui/E0664.rs [deleted file]
src/test/ui/E0664.stderr [deleted file]
src/test/ui/E0665.rs [deleted file]
src/test/ui/E0665.stderr [deleted file]
src/test/ui/E0705.rs [deleted file]
src/test/ui/E0705.stderr [deleted file]
src/test/ui/associated-types/associated-types-overridden-binding.stderr
src/test/ui/associated-types/associated-types-unconstrained.stderr
src/test/ui/async-await/async-await.rs [new file with mode: 0644]
src/test/ui/async-await/async-fn-multiple-lifetimes.rs [new file with mode: 0644]
src/test/ui/async-await/async-fn-multiple-lifetimes.stderr [new file with mode: 0644]
src/test/ui/async-await/async-fn-path-elision.rs [new file with mode: 0644]
src/test/ui/async-await/async-fn-path-elision.stderr [new file with mode: 0644]
src/test/ui/async-await/async-matches-expr.rs [new file with mode: 0644]
src/test/ui/async-await/async-with-closure.rs [new file with mode: 0644]
src/test/ui/async-await/auxiliary/issue-60674.rs [deleted file]
src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.rs [new file with mode: 0644]
src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.stderr [new file with mode: 0644]
src/test/ui/async-await/await-keyword/2015-edition-warning.fixed [new file with mode: 0644]
src/test/ui/async-await/await-keyword/2015-edition-warning.rs [new file with mode: 0644]
src/test/ui/async-await/await-keyword/2015-edition-warning.stderr [new file with mode: 0644]
src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs [new file with mode: 0644]
src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr [new file with mode: 0644]
src/test/ui/async-await/await-keyword/2018-edition-error.rs [new file with mode: 0644]
src/test/ui/async-await/await-keyword/2018-edition-error.stderr [new file with mode: 0644]
src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs [new file with mode: 0644]
src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr [new file with mode: 0644]
src/test/ui/async-await/await-keyword/post_expansion_error.rs [new file with mode: 0644]
src/test/ui/async-await/await-keyword/post_expansion_error.stderr [new file with mode: 0644]
src/test/ui/async-await/await-macro.rs [new file with mode: 0644]
src/test/ui/async-await/dont-print-desugared-async.rs [new file with mode: 0644]
src/test/ui/async-await/dont-print-desugared-async.stderr [new file with mode: 0644]
src/test/ui/async-await/drop-order-for-async-fn-parameters-by-ref-binding.rs [deleted file]
src/test/ui/async-await/drop-order-for-async-fn-parameters.rs [deleted file]
src/test/ui/async-await/drop-order-locals-are-hidden.rs [deleted file]
src/test/ui/async-await/drop-order-locals-are-hidden.stderr [deleted file]
src/test/ui/async-await/drop-order/auxiliary/arc_wake.rs [new file with mode: 0644]
src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs [new file with mode: 0644]
src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs [new file with mode: 0644]
src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.rs [new file with mode: 0644]
src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr [new file with mode: 0644]
src/test/ui/async-await/edition-deny-async-fns-2015.rs [new file with mode: 0644]
src/test/ui/async-await/edition-deny-async-fns-2015.stderr [new file with mode: 0644]
src/test/ui/async-await/issue-60518.rs [deleted file]
src/test/ui/async-await/issue-60674.rs [deleted file]
src/test/ui/async-await/issue-60674.stdout [deleted file]
src/test/ui/async-await/issues/auxiliary/issue-60674.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-51719.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-51719.stderr [new file with mode: 0644]
src/test/ui/async-await/issues/issue-51751.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-51751.stderr [new file with mode: 0644]
src/test/ui/async-await/issues/issue-53249.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-54752-async-block.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-54974.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-55324.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-55809.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-58885.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-59001.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-59972.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-60518.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-60655-latebound-regions.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-60674.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-60674.stdout [new file with mode: 0644]
src/test/ui/async-await/no-args-non-move-async-closure.rs [new file with mode: 0644]
src/test/ui/async-await/no-args-non-move-async-closure.stderr [new file with mode: 0644]
src/test/ui/async-await/recursive-async-impl-trait-type.rs [new file with mode: 0644]
src/test/ui/async-await/recursive-async-impl-trait-type.stderr [new file with mode: 0644]
src/test/ui/async-await/unresolved_type_param.rs [new file with mode: 0644]
src/test/ui/async-await/unresolved_type_param.stderr [new file with mode: 0644]
src/test/ui/async-fn-multiple-lifetimes.rs [deleted file]
src/test/ui/async-fn-multiple-lifetimes.stderr [deleted file]
src/test/ui/async-fn-path-elision.rs [deleted file]
src/test/ui/async-fn-path-elision.stderr [deleted file]
src/test/ui/async-matches-expr.rs [deleted file]
src/test/ui/async-with-closure.rs [deleted file]
src/test/ui/auxiliary/issue-59764.rs [deleted file]
src/test/ui/await-keyword/2015-edition-error-in-non-macro-position.rs [deleted file]
src/test/ui/await-keyword/2015-edition-error-in-non-macro-position.stderr [deleted file]
src/test/ui/await-keyword/2015-edition-warning.fixed [deleted file]
src/test/ui/await-keyword/2015-edition-warning.rs [deleted file]
src/test/ui/await-keyword/2015-edition-warning.stderr [deleted file]
src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.rs [deleted file]
src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.stderr [deleted file]
src/test/ui/await-keyword/2018-edition-error.rs [deleted file]
src/test/ui/await-keyword/2018-edition-error.stderr [deleted file]
src/test/ui/await-keyword/incorrect-syntax-suggestions.rs [deleted file]
src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr [deleted file]
src/test/ui/await-keyword/post_expansion_error.rs [deleted file]
src/test/ui/await-keyword/post_expansion_error.stderr [deleted file]
src/test/ui/confuse-field-and-method/issue-2392.rs
src/test/ui/confuse-field-and-method/issue-2392.stderr
src/test/ui/const-generics/cannot-infer-const-args.stderr
src/test/ui/consts/const_let_refutable.nll.stderr
src/test/ui/consts/const_let_refutable.stderr
src/test/ui/deprecation/deprecated_no_stack_check.stderr
src/test/ui/deprecation/invalid-literal.rs
src/test/ui/deprecation/invalid-literal.stderr
src/test/ui/e0119/auxiliary/complex_impl_support.rs [deleted file]
src/test/ui/e0119/auxiliary/issue-23563-a.rs [deleted file]
src/test/ui/e0119/complex-impl.rs [deleted file]
src/test/ui/e0119/complex-impl.stderr [deleted file]
src/test/ui/e0119/conflict-with-std.rs [deleted file]
src/test/ui/e0119/conflict-with-std.stderr [deleted file]
src/test/ui/e0119/issue-23563.rs [deleted file]
src/test/ui/e0119/issue-23563.stderr [deleted file]
src/test/ui/e0119/issue-27403.rs [deleted file]
src/test/ui/e0119/issue-27403.stderr [deleted file]
src/test/ui/e0119/issue-28981.rs [deleted file]
src/test/ui/e0119/issue-28981.stderr [deleted file]
src/test/ui/e0119/so-37347311.rs [deleted file]
src/test/ui/e0119/so-37347311.stderr [deleted file]
src/test/ui/editions/edition-deny-async-fns-2015.rs [deleted file]
src/test/ui/editions/edition-deny-async-fns-2015.stderr [deleted file]
src/test/ui/error-codes/E0452.stderr
src/test/ui/error-codes/E0501.rs [new file with mode: 0644]
src/test/ui/error-codes/E0501.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0506.rs [new file with mode: 0644]
src/test/ui/error-codes/E0506.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0508-fail.rs [new file with mode: 0644]
src/test/ui/error-codes/E0508-fail.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0508.rs [new file with mode: 0644]
src/test/ui/error-codes/E0508.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0583.rs [new file with mode: 0644]
src/test/ui/error-codes/E0583.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0594.rs [new file with mode: 0644]
src/test/ui/error-codes/E0594.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0596.rs [new file with mode: 0644]
src/test/ui/error-codes/E0596.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0642.rs [new file with mode: 0644]
src/test/ui/error-codes/E0642.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0660.rs [new file with mode: 0644]
src/test/ui/error-codes/E0660.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0661.rs [new file with mode: 0644]
src/test/ui/error-codes/E0661.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0662.rs [new file with mode: 0644]
src/test/ui/error-codes/E0662.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0663.rs [new file with mode: 0644]
src/test/ui/error-codes/E0663.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0664.rs [new file with mode: 0644]
src/test/ui/error-codes/E0664.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0665.rs [new file with mode: 0644]
src/test/ui/error-codes/E0665.stderr [new file with mode: 0644]
src/test/ui/error-codes/E0705.rs [new file with mode: 0644]
src/test/ui/error-codes/E0705.stderr [new file with mode: 0644]
src/test/ui/error-codes/e0119/auxiliary/complex_impl_support.rs [new file with mode: 0644]
src/test/ui/error-codes/e0119/auxiliary/issue-23563-a.rs [new file with mode: 0644]
src/test/ui/error-codes/e0119/complex-impl.rs [new file with mode: 0644]
src/test/ui/error-codes/e0119/complex-impl.stderr [new file with mode: 0644]
src/test/ui/error-codes/e0119/conflict-with-std.rs [new file with mode: 0644]
src/test/ui/error-codes/e0119/conflict-with-std.stderr [new file with mode: 0644]
src/test/ui/error-codes/e0119/issue-23563.rs [new file with mode: 0644]
src/test/ui/error-codes/e0119/issue-23563.stderr [new file with mode: 0644]
src/test/ui/error-codes/e0119/issue-27403.rs [new file with mode: 0644]
src/test/ui/error-codes/e0119/issue-27403.stderr [new file with mode: 0644]
src/test/ui/error-codes/e0119/issue-28981.rs [new file with mode: 0644]
src/test/ui/error-codes/e0119/issue-28981.stderr [new file with mode: 0644]
src/test/ui/error-codes/e0119/so-37347311.rs [new file with mode: 0644]
src/test/ui/error-codes/e0119/so-37347311.stderr [new file with mode: 0644]
src/test/ui/existential_types/issue-60655-latebound-regions.rs [deleted file]
src/test/ui/feature-gate/issue-43106-gating-of-macro_use.rs
src/test/ui/feature-gate/issue-43106-gating-of-macro_use.stderr
src/test/ui/gated-bad-feature.rs
src/test/ui/gated-bad-feature.stderr
src/test/ui/generator/unresolved_type_param.rs [deleted file]
src/test/ui/generator/unresolved_type_param.stderr [deleted file]
src/test/ui/impl-trait/recursive-async-impl-trait-type.rs [deleted file]
src/test/ui/impl-trait/recursive-async-impl-trait-type.stderr [deleted file]
src/test/ui/invalid-self-argument/bare-fn-start.rs
src/test/ui/invalid-self-argument/bare-fn-start.stderr
src/test/ui/invalid-self-argument/bare-fn.rs
src/test/ui/invalid-self-argument/bare-fn.stderr
src/test/ui/invalid-self-argument/trait-fn.rs
src/test/ui/invalid-self-argument/trait-fn.stderr
src/test/ui/invalid_crate_type_syntax.rs
src/test/ui/invalid_crate_type_syntax.stderr
src/test/ui/issue-53249.rs [deleted file]
src/test/ui/issue-59508-1.rs [deleted file]
src/test/ui/issue-59508-1.stderr [deleted file]
src/test/ui/issue-59508.fixed [deleted file]
src/test/ui/issue-59508.rs [deleted file]
src/test/ui/issue-59508.stderr [deleted file]
src/test/ui/issue-59756.fixed [deleted file]
src/test/ui/issue-59756.rs [deleted file]
src/test/ui/issue-59756.stderr [deleted file]
src/test/ui/issue-59764.rs [deleted file]
src/test/ui/issue-59764.stderr [deleted file]
src/test/ui/issue-60075.rs [deleted file]
src/test/ui/issue-60075.stderr [deleted file]
src/test/ui/issue-60622.rs [deleted file]
src/test/ui/issue-60622.stderr [deleted file]
src/test/ui/issues/auxiliary/issue-59764.rs [new file with mode: 0644]
src/test/ui/issues/issue-12028.stderr
src/test/ui/issues/issue-43988.rs
src/test/ui/issues/issue-43988.stderr
src/test/ui/issues/issue-51719.rs [deleted file]
src/test/ui/issues/issue-51719.stderr [deleted file]
src/test/ui/issues/issue-51751.rs [deleted file]
src/test/ui/issues/issue-51751.stderr [deleted file]
src/test/ui/issues/issue-54974.rs [deleted file]
src/test/ui/issues/issue-55324.rs [deleted file]
src/test/ui/issues/issue-58885.rs [deleted file]
src/test/ui/issues/issue-59001.rs [deleted file]
src/test/ui/issues/issue-59508-1.rs [new file with mode: 0644]
src/test/ui/issues/issue-59508-1.stderr [new file with mode: 0644]
src/test/ui/issues/issue-59508.fixed [new file with mode: 0644]
src/test/ui/issues/issue-59508.rs [new file with mode: 0644]
src/test/ui/issues/issue-59508.stderr [new file with mode: 0644]
src/test/ui/issues/issue-59756.fixed [new file with mode: 0644]
src/test/ui/issues/issue-59756.rs [new file with mode: 0644]
src/test/ui/issues/issue-59756.stderr [new file with mode: 0644]
src/test/ui/issues/issue-59764.rs [new file with mode: 0644]
src/test/ui/issues/issue-59764.stderr [new file with mode: 0644]
src/test/ui/issues/issue-60075.rs [new file with mode: 0644]
src/test/ui/issues/issue-60075.stderr [new file with mode: 0644]
src/test/ui/issues/issue-60622.rs [new file with mode: 0644]
src/test/ui/issues/issue-60622.stderr [new file with mode: 0644]
src/test/ui/issues/issue-60989.rs [new file with mode: 0644]
src/test/ui/issues/issue-60989.stderr [new file with mode: 0644]
src/test/ui/issues/issue-61108.rs [new file with mode: 0644]
src/test/ui/issues/issue-61108.stderr [new file with mode: 0644]
src/test/ui/lint/lint-malformed.rs
src/test/ui/lint/lint-malformed.stderr
src/test/ui/lint/reasons-erroneous.rs
src/test/ui/lint/reasons-erroneous.stderr
src/test/ui/macros/format-parse-errors.stderr
src/test/ui/malformed/malformed-derive-entry.rs
src/test/ui/malformed/malformed-derive-entry.stderr
src/test/ui/malformed/malformed-plugin-1.rs
src/test/ui/malformed/malformed-plugin-1.stderr
src/test/ui/malformed/malformed-plugin-2.rs
src/test/ui/malformed/malformed-plugin-2.stderr
src/test/ui/malformed/malformed-plugin-3.rs
src/test/ui/malformed/malformed-plugin-3.stderr
src/test/ui/malformed/malformed-special-attrs.rs
src/test/ui/malformed/malformed-special-attrs.stderr
src/test/ui/malformed/malformed-unwind-1.rs
src/test/ui/malformed/malformed-unwind-1.stderr
src/test/ui/malformed/malformed-unwind-2.rs
src/test/ui/malformed/malformed-unwind-2.stderr
src/test/ui/marker_trait_attr/marker-attribute-with-values.rs
src/test/ui/marker_trait_attr/marker-attribute-with-values.stderr
src/test/ui/nll/dont-print-desugared-async.rs [deleted file]
src/test/ui/nll/dont-print-desugared-async.stderr [deleted file]
src/test/ui/no-args-non-move-async-closure.rs [deleted file]
src/test/ui/no-args-non-move-async-closure.stderr [deleted file]
src/test/ui/no_crate_type.rs
src/test/ui/no_crate_type.stderr
src/test/ui/on-unimplemented/bad-annotation.rs
src/test/ui/on-unimplemented/bad-annotation.stderr
src/test/ui/parser/macro/bad-macro-argument.rs [new file with mode: 0644]
src/test/ui/parser/macro/bad-macro-argument.stderr [new file with mode: 0644]
src/test/ui/parser/self-in-function-arg.rs [new file with mode: 0644]
src/test/ui/parser/self-in-function-arg.stderr [new file with mode: 0644]
src/test/ui/pattern/const-pat-ice.stderr
src/test/ui/pattern/slice-pattern-const-2.rs
src/test/ui/pattern/slice-pattern-const-2.stderr
src/test/ui/proc-macro/attr-invalid-exprs.rs
src/test/ui/proc-macro/attr-invalid-exprs.stderr
src/test/ui/proc-macro/attribute.rs
src/test/ui/proc-macro/attribute.stderr
src/test/ui/proc-macro/invalid-attributes.rs
src/test/ui/proc-macro/invalid-attributes.stderr
src/test/ui/question-mark-type-infer.stderr
src/test/ui/repr.rs
src/test/ui/repr.stderr
src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.rs
src/test/ui/rfc-2008-non-exhaustive/invalid-attribute.stderr
src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.rs [new file with mode: 0644]
src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.stderr [new file with mode: 0644]
src/test/ui/stability-attribute/stability-attribute-sanity-4.rs
src/test/ui/stability-attribute/stability-attribute-sanity-4.stderr
src/test/ui/suggestions/borrow-for-loop-head.stderr
src/test/ui/suggestions/option-content-move.fixed [new file with mode: 0644]
src/test/ui/suggestions/option-content-move.rs [new file with mode: 0644]
src/test/ui/suggestions/option-content-move.stderr [new file with mode: 0644]
src/test/ui/symbol-names/impl2.rs [new file with mode: 0644]
src/test/ui/symbol-names/impl2.stderr [new file with mode: 0644]
src/test/ui/target-feature-wrong.rs
src/test/ui/target-feature-wrong.stderr
src/tools/cargo
src/tools/clippy
src/tools/rustc-workspace-hack/Cargo.toml
src/tools/tidy/src/deps.rs
src/tools/tidy/src/pal.rs

index 7bb38a4e8eb9e34f567b7ef514795c56d598f0ae..4cdf8423c0885cbfdf59a76e719e876da6064545 100644 (file)
@@ -11,6 +11,7 @@ variables:
 
 jobs:
 - job: Linux
+  timeoutInMinutes: 600
   pool:
     vmImage: ubuntu-16.04
   steps:
@@ -150,11 +151,10 @@ jobs:
         IMAGE: mingw-check
 
 - job: macOS
+  timeoutInMinutes: 600
   pool:
     vmImage: macos-10.13
   steps:
-  - checkout: self
-    fetchDepth: 2
   - template: steps/run.yml
   strategy:
     matrix:
@@ -214,6 +214,7 @@ jobs:
 
 
 - job: Windows
+  timeoutInMinutes: 600
   pool:
     vmImage: 'vs2017-win2016'
   steps:
index 67e0dd8e795bb596d66fa4eda1899b06543270c7..d34ed114972c5a794627ea18c0a36cede861562b 100644 (file)
@@ -12,7 +12,7 @@ __pycache__/
 .project
 .settings/
 .valgrindrc
-.vscode/
+.vscode
 .favorites.json
 /*-*-*-*/
 /*-*-*/
index 63a49cd413287437a4f57c13ec5479d330d6438f..2d5759b539e5dcd9317ced1226b45e5191597d45 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -6,7 +6,7 @@
 #
 
 Aaron Todd <github@opprobrio.us>
-Aaron Power <theaaronepower@gmail.com>
+Aaron Power <theaaronepower@gmail.com> Erin Power <xampprocky@gmail.com>
 Abhishek Chanda <abhishek.becs@gmail.com> Abhishek Chanda <abhishek@cloudscaling.com>
 Adolfo Ochagavía <aochagavia92@gmail.com>
 Adrien Tétar <adri-from-59@hotmail.fr>
index 392f3e8e4bdce56b25b47b89bb32dc0c857dc9c0..d5e2969e9649a59fb36efba127c8c5181d64da84 100644 (file)
@@ -105,16 +105,23 @@ dependencies = [
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "autocfg"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "backtrace"
-version = "0.3.11"
+version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
+ "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-demangle 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-std-workspace-core 1.0.0",
 ]
 
 [[package]]
@@ -253,7 +260,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "cargo"
-version = "0.37.0"
+version = "0.38.0"
 dependencies = [
  "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -261,7 +268,7 @@ dependencies = [
  "bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "crates-io 0.25.0",
+ "crates-io 0.26.0",
  "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "curl 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -278,7 +285,7 @@ dependencies = [
  "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "ignore 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "im-rc 12.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "im-rc 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "jobserver 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -300,6 +307,7 @@ dependencies = [
  "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "strip-ansi-escapes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -334,8 +342,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "cfg-if"
-version = "0.1.6"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-std-workspace-core 1.0.0",
+]
 
 [[package]]
 name = "chalk-engine"
@@ -391,7 +403,7 @@ dependencies = [
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-workspace-hack 1.0.0",
- "rustc_tools_util 0.1.1",
+ "rustc_tools_util 0.2.0",
  "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)",
 ]
@@ -405,7 +417,7 @@ name = "clippy_lints"
 version = "0.0.212"
 dependencies = [
  "cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "if_chain 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -537,7 +549,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "crates-io"
-version = "0.25.0"
+version = "0.26.0"
 dependencies = [
  "curl 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -561,7 +573,7 @@ name = "crc32fast"
 version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -597,7 +609,7 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -611,7 +623,7 @@ version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -623,7 +635,7 @@ name = "crossbeam-utils"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -631,7 +643,7 @@ name = "crossbeam-utils"
 version = "0.6.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -813,7 +825,7 @@ name = "error-chain"
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -821,7 +833,7 @@ name = "error-chain"
 version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -836,7 +848,7 @@ name = "failure"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -861,7 +873,7 @@ name = "filetime"
 version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1141,7 +1153,7 @@ dependencies = [
 
 [[package]]
 name = "if_chain"
-version = "0.1.3"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1163,10 +1175,11 @@ dependencies = [
 
 [[package]]
 name = "im-rc"
-version = "12.3.0"
+version = "13.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sized-chunks 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1354,7 +1367,7 @@ name = "log"
 version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1640,7 +1653,7 @@ name = "net2"
 version = "0.2.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1709,7 +1722,7 @@ version = "0.10.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1765,7 +1778,7 @@ name = "packed_simd"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2239,7 +2252,7 @@ dependencies = [
 name = "rls"
 version = "1.36.0"
 dependencies = [
- "cargo 0.37.0",
+ "cargo 0.38.0",
  "cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "clippy_lints 0.0.212",
  "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2349,7 +2362,7 @@ name = "rustc"
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "chalk-engine 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2407,7 +2420,7 @@ name = "rustc-ap-rustc_data_structures"
 version = "407.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "jobserver 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2479,7 +2492,7 @@ name = "rustc-ap-syntax_pos"
 version = "407.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-arena 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_data_structures 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-serialize 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2706,7 +2719,7 @@ dependencies = [
 name = "rustc_data_structures"
 version = "0.0.0"
 dependencies = [
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "ena 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
  "jobserver 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2996,16 +3009,17 @@ dependencies = [
  "rustc_cratesio_shim 0.0.0",
  "rustc_data_structures 0.0.0",
  "serialize 0.0.0",
+ "syntax_pos 0.0.0",
 ]
 
 [[package]]
 name = "rustc_tools_util"
 version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "rustc_tools_util"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "0.2.0"
 
 [[package]]
 name = "rustc_traits"
@@ -3263,6 +3277,14 @@ name = "siphasher"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "sized-chunks"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "slab"
 version = "0.4.2"
@@ -3281,7 +3303,7 @@ name = "socket2"
 version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3297,7 +3319,7 @@ name = "std"
 version = "0.0.0"
 dependencies = [
  "alloc 0.0.0",
- "backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
@@ -3309,7 +3331,6 @@ dependencies = [
  "panic_unwind 0.0.0",
  "profiler_builtins 0.0.0",
  "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-demangle 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_asan 0.0.0",
  "rustc_lsan 0.0.0",
  "rustc_msan 0.0.0",
@@ -3348,6 +3369,14 @@ name = "string_cache_shared"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "strip-ansi-escapes"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "vte 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "strsim"
 version = "0.7.0"
@@ -3444,7 +3473,7 @@ name = "syntax_pos"
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_data_structures 0.0.0",
  "rustc_macros 0.1.0",
  "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3468,7 +3497,7 @@ name = "tempfile"
 version = "3.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3924,6 +3953,11 @@ name = "utf8-ranges"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "utf8parse"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "vcpkg"
 version = "0.2.6"
@@ -3954,6 +3988,14 @@ name = "void"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "vte"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "wait-timeout"
 version = "0.1.5"
@@ -4060,7 +4102,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
 "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
 "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
-"checksum backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "18b65ea1161bfb2dd6da6fade5edd4dbd08fba85012123dd333d2fd1b90b2782"
+"checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf"
+"checksum backtrace 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "1c50b4cb6d852a8567d98bb11c03f91ccec4dfbd88778bc1b92789c624081283"
 "checksum backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)" = "6ea90dd7b012b3d1a2cb6bec16670a0db2c95d4e931e84f4047e0460c1b34c8d"
 "checksum bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1efcc46c18245a69c38fcc5cc650f16d3a59d034f3106e9ed63748f695730a"
 "checksum bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf"
@@ -4078,7 +4121,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "716960a18f978640f25101b5cbf1c6f6b0d3192fab36a2d98ca96f0ecbe41010"
 "checksum cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "585784cac9b05c93a53b17a0b24a5cdd1dfdda5256f030e089b549d2390cc720"
 "checksum cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5f3fee5eeb60324c2781f1e41286bdee933850fff9b3c672587fed5ec58c83"
-"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
+"checksum cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "89431bba4e6b7092fb5fcd00a6f6ca596c55cc26b2f1e6dcdd08a1f4933f66b2"
 "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"
 "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
@@ -4156,9 +4199,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fe67e3678f2827030e89cc4b9e7ecd16d52f132c0b940ab5005f88e821500f6a"
 "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
 "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
-"checksum if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4bac95d9aa0624e7b78187d6fb8ab012b41d9f6f54b1bcb61e61c4845f8357ec"
+"checksum if_chain 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3360c7b59e5ffa2653671fb74b4741a5d343c03f331c0a4aeda42b5c2b0ec7d"
 "checksum ignore 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8dc57fa12805f367736a38541ac1a9fc6a52812a0ca959b1d4d4b640a89eb002"
-"checksum im-rc 12.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9460397452f537fd51808056ff209f4c4c4c9d20d42ae952f517708726284972"
+"checksum im-rc 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0197597d095c0d11107975d3175173f810ee572c2501ff4de64f4f3f119806"
 "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
 "checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053"
 "checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
@@ -4309,6 +4352,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
 "checksum signal-hook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1f272d1b7586bec132ed427f532dd418d8beca1ca7f2caf7df35569b1415a4b4"
 "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
+"checksum sized-chunks 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2a2eb3fe454976eefb479f78f9b394d34d661b647c6326a3a6e66f68bb12c26"
 "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
 "checksum smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b73ea3738b47563803ef814925e69be00799a8c07420be8b996f8e98fb2336db"
 "checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7"
@@ -4316,6 +4360,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
 "checksum string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da"
 "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
+"checksum strip-ansi-escapes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d63676e2abafa709460982ddc02a3bb586b6d15a49b75c212e06edd3933acee"
 "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
 "checksum strum 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c3a2071519ab6a48f465808c4c1ffdd00dfc8e93111d02b4fc5abab177676e"
 "checksum strum_macros 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8baacebd7b7c9b864d83a6ba7a246232983e277b86fa5cdec77f565715a4b136"
@@ -4368,11 +4413,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea"
 "checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c"
 "checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
+"checksum utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d"
 "checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d"
 "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
 "checksum vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba"
 "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+"checksum vte 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f42f536e22f7fcbb407639765c8fd78707a33109301f834a594758bedd6e8cf"
 "checksum wait-timeout 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b9f3bf741a801531993db6478b95682117471f76916f5e690dd8d45395b09349"
 "checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
index 75d7823490a201564a55c708960c231c7a9b869d..b522b161ecf939d23c877e6448ddcd88cb6bef4d 100644 (file)
--- a/README.md
+++ b/README.md
@@ -134,9 +134,8 @@ MSVC builds of Rust additionally require an installation of Visual Studio 2017
 
 [Visual Studio Build Tools]: https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019
 
-At last check (cmake 3.14.3 and msvc 16.0.3) using the 2019 tools fails to
-build the in-tree LLVM build with a CMake error, so use 2017 instead by
-including the “MSVC v141 – VS 2017 C++ x64/x86 build tools (v14.16)” component.
+(If you're installing cmake yourself, be careful that “C++ CMake tools for
+Windows” doesn't get included under “Individual components”.)
 
 With these dependencies installed, you can build the compiler in a `cmd.exe`
 shell with:
@@ -151,7 +150,7 @@ then you may need to force rustbuild to use an older version. This can be done
 by manually calling the appropriate vcvars file before running the bootstrap.
 
 ```batch
-> CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"
+> CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
 > python x.py build
 ```
 
index 4185961187b395d277272a31763c25d22662df16..91e3c5f721952a65c0b4ddf2a9b269c0d293f732 100644 (file)
@@ -157,7 +157,7 @@ Libraries
   produce a warning if their returning type is unused.
 - [The methods `checked_pow`, `saturating_pow`, `wrapping_pow`, and
   `overflowing_pow` are now available for all numeric types.][57873] These are
-  equivalvent to methods such as `wrapping_add` for the `pow` operation.
+  equivalent to methods such as `wrapping_add` for the `pow` operation.
 
 
 Stabilized APIs
index c35da8927ce93520f4f94520660c5c0f9f470eee..6dc33f30c7e2b0a34ee5b15ae29934f34553ee20 100644 (file)
@@ -104,7 +104,7 @@ environment:
     DEPLOY: 1
   - CI_JOB_NAME: dist-i686-mingw
     MSYS_BITS: 32
-    RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools
+    RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools --enable-profiler
     SCRIPT: python x.py dist
     MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror
     MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z
@@ -114,7 +114,7 @@ environment:
   - CI_JOB_NAME: dist-x86_64-mingw
     MSYS_BITS: 64
     SCRIPT: python x.py dist
-    RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-full-tools
+    RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-full-tools --enable-profiler
     MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror
     MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z
     MINGW_DIR: mingw64
index e616b2647a9f4ea16806d902391b5387b984a7b6..198b7dbc3f9d42cc0fb84da8e7023eaa60973eaa 100644 (file)
@@ -318,6 +318,8 @@ fn pathset_for_path(&self, path: &Path) -> Option<&PathSet> {
 pub enum Kind {
     Build,
     Check,
+    Clippy,
+    Fix,
     Test,
     Bench,
     Dist,
@@ -359,7 +361,7 @@ macro_rules! describe {
                 tool::Miri,
                 native::Lld
             ),
-            Kind::Check => describe!(
+            Kind::Check | Kind::Clippy | Kind::Fix => describe!(
                 check::Std,
                 check::Test,
                 check::Rustc,
@@ -520,6 +522,8 @@ pub fn new(build: &Build) -> Builder<'_> {
         let (kind, paths) = match build.config.cmd {
             Subcommand::Build { ref paths } => (Kind::Build, &paths[..]),
             Subcommand::Check { ref paths } => (Kind::Check, &paths[..]),
+            Subcommand::Clippy { ref paths } => (Kind::Clippy, &paths[..]),
+            Subcommand::Fix { ref paths } => (Kind::Fix, &paths[..]),
             Subcommand::Doc { ref paths } => (Kind::Doc, &paths[..]),
             Subcommand::Test { ref paths, .. } => (Kind::Test, &paths[..]),
             Subcommand::Bench { ref paths, .. } => (Kind::Bench, &paths[..]),
@@ -757,17 +761,17 @@ pub fn cargo(
         };
 
         let libstd_stamp = match cmd {
-            "check" => check::libstd_stamp(self, cmp, target),
+            "check" | "clippy" | "fix" => check::libstd_stamp(self, cmp, target),
             _ => compile::libstd_stamp(self, cmp, target),
         };
 
         let libtest_stamp = match cmd {
-            "check" => check::libtest_stamp(self, cmp, target),
+            "check" | "clippy" | "fix" => check::libtest_stamp(self, cmp, target),
             _ => compile::libstd_stamp(self, cmp, target),
         };
 
         let librustc_stamp = match cmd {
-            "check" => check::librustc_stamp(self, cmp, target),
+            "check" | "clippy" | "fix" => check::librustc_stamp(self, cmp, target),
             _ => compile::librustc_stamp(self, cmp, target),
         };
 
@@ -831,9 +835,9 @@ pub fn cargo(
             assert_eq!(target, compiler.host);
         }
 
-        // Set a flag for `check` so that certain build scripts can do less work
-        // (e.g., not building/requiring LLVM).
-        if cmd == "check" {
+        // Set a flag for `check`/`clippy`/`fix`, so that certain build
+        // scripts can do less work (e.g. not building/requiring LLVM).
+        if cmd == "check" || cmd == "clippy" || cmd == "fix" {
             cargo.env("RUST_CHECK", "1");
         }
 
@@ -898,6 +902,11 @@ pub fn cargo(
             extra_args.push_str(&s);
         }
 
+        if cmd == "clippy" {
+            extra_args.push_str("-Zforce-unstable-if-unmarked -Zunstable-options \
+                --json-rendered=termcolor");
+        }
+
         if !extra_args.is_empty() {
             cargo.env(
                 "RUSTFLAGS",
@@ -966,7 +975,7 @@ pub fn cargo(
         if let Some(ref error_format) = self.config.rustc_error_format {
             cargo.env("RUSTC_ERROR_FORMAT", error_format);
         }
-        if cmd != "build" && cmd != "check" && cmd != "rustc" && want_rustdoc {
+        if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc {
             cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
         }
 
index a6da4f5385a5be1e3485e8112cd946befc84a40e..41235d911c03e52131bc1f6be897140c4c73f152 100644 (file)
@@ -13,7 +13,7 @@
 use crate::Build;
 
 // The version number
-pub const CFG_RELEASE_NUM: &str = "1.36.0";
+pub const CFG_RELEASE_NUM: &str = "1.37.0";
 
 pub struct GitInfo {
     inner: Option<Info>,
index a30b465698e2a263b40b10f7ef6b7a33dd3442a4..bdf5306d4b549a70660cd61347db19b90b9a9c9b 100644 (file)
@@ -1,8 +1,8 @@
-//! Implementation of compiling the compiler and standard library, in "check" mode.
+//! Implementation of compiling the compiler and standard library, in "check"-based modes.
 
 use crate::compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env,
                      add_to_sysroot};
-use crate::builder::{RunConfig, Builder, ShouldRun, Step};
+use crate::builder::{RunConfig, Builder, Kind, ShouldRun, Step};
 use crate::tool::{prepare_tool_cargo, SourceType};
 use crate::{Compiler, Mode};
 use crate::cache::{INTERNER, Interned};
@@ -13,6 +13,22 @@ pub struct Std {
     pub target: Interned<String>,
 }
 
+fn args(kind: Kind) -> Vec<String> {
+    match kind {
+        Kind::Clippy => vec!["--".to_owned(), "--cap-lints".to_owned(), "warn".to_owned()],
+        _ => Vec::new()
+    }
+}
+
+fn cargo_subcommand(kind: Kind) -> &'static str {
+    match kind {
+        Kind::Check => "check",
+        Kind::Clippy => "clippy",
+        Kind::Fix => "fix",
+        _ => unreachable!()
+    }
+}
+
 impl Step for Std {
     type Output = ();
     const DEFAULT: bool = true;
@@ -31,13 +47,14 @@ fn run(self, builder: &Builder<'_>) {
         let target = self.target;
         let compiler = builder.compiler(0, builder.config.build);
 
-        let mut cargo = builder.cargo(compiler, Mode::Std, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Std, target, cargo_subcommand(builder.kind));
         std_cargo(builder, &compiler, target, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-std", compiler.stage));
         builder.info(&format!("Checking std artifacts ({} -> {})", &compiler.host, target));
         run_cargo(builder,
                   &mut cargo,
+                  args(builder.kind),
                   &libstd_stamp(builder, compiler, target),
                   true);
 
@@ -78,13 +95,15 @@ fn run(self, builder: &Builder<'_>) {
 
         builder.ensure(Test { target });
 
-        let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Rustc, target,
+            cargo_subcommand(builder.kind));
         rustc_cargo(builder, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-rustc", compiler.stage));
         builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target));
         run_cargo(builder,
                   &mut cargo,
+                  args(builder.kind),
                   &librustc_stamp(builder, compiler, target),
                   true);
 
@@ -127,7 +146,8 @@ fn run(self, builder: &Builder<'_>) {
 
         builder.ensure(Rustc { target });
 
-        let mut cargo = builder.cargo(compiler, Mode::Codegen, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Codegen, target,
+            cargo_subcommand(builder.kind));
         cargo.arg("--manifest-path").arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml"));
         rustc_cargo_env(builder, &mut cargo);
 
@@ -136,6 +156,7 @@ fn run(self, builder: &Builder<'_>) {
         let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage));
         run_cargo(builder,
                   &mut cargo,
+                  args(builder.kind),
                   &codegen_backend_stamp(builder, compiler, target, backend),
                   true);
     }
@@ -166,13 +187,14 @@ fn run(self, builder: &Builder<'_>) {
 
         builder.ensure(Std { target });
 
-        let mut cargo = builder.cargo(compiler, Mode::Test, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Test, target, cargo_subcommand(builder.kind));
         test_cargo(builder, &compiler, target, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-test", compiler.stage));
         builder.info(&format!("Checking test artifacts ({} -> {})", &compiler.host, target));
         run_cargo(builder,
                   &mut cargo,
+                  args(builder.kind),
                   &libtest_stamp(builder, compiler, target),
                   true);
 
@@ -212,7 +234,7 @@ fn run(self, builder: &Builder<'_>) {
                                            compiler,
                                            Mode::ToolRustc,
                                            target,
-                                           "check",
+                                           cargo_subcommand(builder.kind),
                                            "src/tools/rustdoc",
                                            SourceType::InTree,
                                            &[]);
@@ -221,6 +243,7 @@ fn run(self, builder: &Builder<'_>) {
         println!("Checking rustdoc artifacts ({} -> {})", &compiler.host, target);
         run_cargo(builder,
                   &mut cargo,
+                  args(builder.kind),
                   &rustdoc_stamp(builder, compiler, target),
                   true);
 
index 6c81b6ada2b9fdc066589dde545b87c68a7b9903..50c9602de1b145ccefe013d48373289187d98550 100644 (file)
@@ -100,6 +100,7 @@ fn run(self, builder: &Builder<'_>) {
                 &compiler.host, target));
         run_cargo(builder,
                   &mut cargo,
+                  vec![],
                   &libstd_stamp(builder, compiler, target),
                   false);
 
@@ -425,6 +426,7 @@ fn run(self, builder: &Builder<'_>) {
                 &compiler.host, target));
         run_cargo(builder,
                   &mut cargo,
+                  vec![],
                   &libtest_stamp(builder, compiler, target),
                   false);
 
@@ -556,6 +558,7 @@ fn run(self, builder: &Builder<'_>) {
                  compiler.stage, &compiler.host, target));
         run_cargo(builder,
                   &mut cargo,
+                  vec![],
                   &librustc_stamp(builder, compiler, target),
                   false);
 
@@ -707,6 +710,7 @@ fn run(self, builder: &Builder<'_>) {
         let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage));
         let files = run_cargo(builder,
                               cargo.arg("--features").arg(features),
+                              vec![],
                               &tmp_stamp,
                               false);
         if builder.config.dry_run {
@@ -1077,6 +1081,7 @@ pub fn add_to_sysroot(
 
 pub fn run_cargo(builder: &Builder<'_>,
                  cargo: &mut Command,
+                 tail_args: Vec<String>,
                  stamp: &Path,
                  is_check: bool)
     -> Vec<PathBuf>
@@ -1099,7 +1104,7 @@ pub fn run_cargo(builder: &Builder<'_>,
     // files we need to probe for later.
     let mut deps = Vec::new();
     let mut toplevel = Vec::new();
-    let ok = stream_cargo(builder, cargo, &mut |msg| {
+    let ok = stream_cargo(builder, cargo, tail_args, &mut |msg| {
         let (filenames, crate_types) = match msg {
             CargoMessage::CompilerArtifact {
                 filenames,
@@ -1108,6 +1113,10 @@ pub fn run_cargo(builder: &Builder<'_>,
                 },
                 ..
             } => (filenames, crate_types),
+            CargoMessage::CompilerMessage { message } => {
+                eprintln!("{}", message.rendered);
+                return;
+            }
             _ => return,
         };
         for filename in filenames {
@@ -1235,6 +1244,7 @@ pub fn run_cargo(builder: &Builder<'_>,
 pub fn stream_cargo(
     builder: &Builder<'_>,
     cargo: &mut Command,
+    tail_args: Vec<String>,
     cb: &mut dyn FnMut(CargoMessage<'_>),
 ) -> bool {
     if builder.config.dry_run {
@@ -1245,6 +1255,10 @@ pub fn stream_cargo(
     cargo.arg("--message-format").arg("json")
          .stdout(Stdio::piped());
 
+    for arg in tail_args {
+        cargo.arg(arg);
+    }
+
     builder.verbose(&format!("running: {:?}", cargo));
     let mut child = match cargo.spawn() {
         Ok(child) => child,
@@ -1291,5 +1305,13 @@ pub enum CargoMessage<'a> {
     },
     BuildScriptExecuted {
         package_id: Cow<'a, str>,
+    },
+    CompilerMessage {
+        message: ClippyMessage<'a>
     }
 }
+
+#[derive(Deserialize)]
+pub struct ClippyMessage<'a> {
+    rendered: Cow<'a, str>,
+}
index a1f89d6c86f1d8a345b405307050cb2e2fcb5573..4774c0a51c09a15f2a664a85b3a3d3c11d9220a9 100644 (file)
@@ -44,6 +44,12 @@ pub enum Subcommand {
     Check {
         paths: Vec<PathBuf>,
     },
+    Clippy {
+        paths: Vec<PathBuf>,
+    },
+    Fix {
+        paths: Vec<PathBuf>,
+    },
     Doc {
         paths: Vec<PathBuf>,
     },
@@ -90,6 +96,8 @@ pub fn parse(args: &[String]) -> Flags {
 Subcommands:
     build       Compile either the compiler or libraries
     check       Compile either the compiler or libraries, using cargo check
+    clippy      Run clippy
+    fix         Run cargo fix
     test        Build and run some test suites
     bench       Build and run some benchmarks
     doc         Build documentation
@@ -146,6 +154,8 @@ pub fn parse(args: &[String]) -> Flags {
         let subcommand = args.iter().find(|&s| {
             (s == "build")
                 || (s == "check")
+                || (s == "clippy")
+                || (s == "fix")
                 || (s == "test")
                 || (s == "bench")
                 || (s == "doc")
@@ -281,6 +291,28 @@ pub fn parse(args: &[String]) -> Flags {
     the compiler.",
                 );
             }
+            "clippy" => {
+                subcommand_help.push_str(
+                    "\n
+Arguments:
+    This subcommand accepts a number of paths to directories to the crates
+    and/or artifacts to run clippy against. For example:
+
+        ./x.py clippy src/libcore
+        ./x.py clippy src/libcore src/libproc_macro",
+                );
+            }
+            "fix" => {
+                subcommand_help.push_str(
+                    "\n
+Arguments:
+    This subcommand accepts a number of paths to directories to the crates
+    and/or artifacts to run `cargo fix` against. For example:
+
+        ./x.py fix src/libcore
+        ./x.py fix src/libcore src/libproc_macro",
+                );
+            }
             "test" => {
                 subcommand_help.push_str(
                     "\n
@@ -363,6 +395,8 @@ pub fn parse(args: &[String]) -> Flags {
         let cmd = match subcommand.as_str() {
             "build" => Subcommand::Build { paths },
             "check" => Subcommand::Check { paths },
+            "clippy" => Subcommand::Clippy { paths },
+            "fix" => Subcommand::Fix { paths },
             "test" => Subcommand::Test {
                 paths,
                 bless: matches.opt_present("bless"),
index da2e03a1a08482e6e6f912ee249a69056c884e51..bf3601cb312fdf0519f0c1f06b7604db92afce1b 100644 (file)
@@ -203,8 +203,16 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
             cfg.define("LLVM_BUILD_32_BITS", "ON");
         }
 
+        let mut enabled_llvm_projects = Vec::new();
+
+        if util::forcing_clang_based_tests() {
+            enabled_llvm_projects.push("clang");
+            enabled_llvm_projects.push("compiler-rt");
+        }
+
         if want_lldb {
-            cfg.define("LLVM_ENABLE_PROJECTS", "clang;lldb");
+            enabled_llvm_projects.push("clang");
+            enabled_llvm_projects.push("lldb");
             // For the time being, disable code signing.
             cfg.define("LLDB_CODESIGN_IDENTITY", "");
             cfg.define("LLDB_NO_DEBUGSERVER", "ON");
@@ -214,6 +222,12 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
             cfg.define("LLVM_ENABLE_LIBXML2", "OFF");
         }
 
+        if enabled_llvm_projects.len() > 0 {
+            enabled_llvm_projects.sort();
+            enabled_llvm_projects.dedup();
+            cfg.define("LLVM_ENABLE_PROJECTS", enabled_llvm_projects.join(";"));
+        }
+
         if let Some(num_linkers) = builder.config.llvm_link_jobs {
             if num_linkers > 0 {
                 cfg.define("LLVM_PARALLEL_LINK_JOBS", num_linkers.to_string());
index 05b3ce6bc896464c0c127ca6a0a9444219ded7e1..9d0aa09f15cfb01f674bda17b39421769c4ccad6 100644 (file)
@@ -1143,24 +1143,9 @@ fn run(self, builder: &Builder<'_>) {
             }
         }
 
-        if let Some(var) = env::var_os("RUSTBUILD_FORCE_CLANG_BASED_TESTS") {
-            match &var.to_string_lossy().to_lowercase()[..] {
-                "1" | "yes" | "on" => {
-                    assert!(builder.config.lldb_enabled,
-                        "RUSTBUILD_FORCE_CLANG_BASED_TESTS needs Clang/LLDB to \
-                         be built.");
-                    let clang_exe = builder.llvm_out(target).join("bin").join("clang");
-                    cmd.arg("--run-clang-based-tests-with").arg(clang_exe);
-                }
-                "0" | "no" | "off" => {
-                    // Nothing to do.
-                }
-                other => {
-                    // Let's make sure typos don't get unnoticed
-                    panic!("Unrecognized option '{}' set in \
-                            RUSTBUILD_FORCE_CLANG_BASED_TESTS", other);
-                }
-            }
+        if util::forcing_clang_based_tests() {
+            let clang_exe = builder.llvm_out(target).join("bin").join("clang");
+            cmd.arg("--run-clang-based-tests-with").arg(clang_exe);
         }
 
         // Get paths from cmd args
index d723f286fa8890a7b5936474d2e1116333d3be50..68fe92466027a6d6e6bdb056869722c70f5a6889 100644 (file)
@@ -77,7 +77,7 @@ fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
         let _folder = builder.fold_output(|| format!("stage{}-{}", compiler.stage, tool));
         builder.info(&format!("Building stage{} tool {} ({})", compiler.stage, tool, target));
         let mut duplicates = Vec::new();
-        let is_expected = compile::stream_cargo(builder, &mut cargo, &mut |msg| {
+        let is_expected = compile::stream_cargo(builder, &mut cargo, vec![], &mut |msg| {
             // Only care about big things like the RLS/Cargo for now
             match tool {
                 | "rls"
index f22f0559265b11ef6d0f5bbb526b722e5359c91d..9f684678bb060be35fbfde61d36a04adafec9374 100644 (file)
@@ -356,3 +356,19 @@ pub fn force_coloring_in_ci(self, cmd: &mut Command) {
         }
     }
 }
+
+pub fn forcing_clang_based_tests() -> bool {
+    if let Some(var) = env::var_os("RUSTBUILD_FORCE_CLANG_BASED_TESTS") {
+        match &var.to_string_lossy().to_lowercase()[..] {
+            "1" | "yes" | "on" => true,
+            "0" | "no" | "off" => false,
+            other => {
+                // Let's make sure typos don't go unnoticed
+                panic!("Unrecognized option '{}' set in \
+                        RUSTBUILD_FORCE_CLANG_BASED_TESTS", other)
+            }
+        }
+    } else {
+        false
+    }
+}
index a722a4183912e9ec75f2caeddbdc1903173a6b25..5ab4be328a9f7c7248dae17ada753300d55d010a 100644 (file)
@@ -126,7 +126,6 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
     CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc \
     CC_sparc64_unknown_linux_gnu=sparc64-linux-gnu-gcc \
     CC_x86_64_unknown_redox=x86_64-unknown-redox-gcc \
-    CC_armebv7r_none_eabi=arm-none-eabi-gcc \
     CC_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \
     AR_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \
     CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++
index a0fe307cffcdb2187cfef2bace1998f6592b9bff..af0198705a2fefda34bf4f1ea5efc881078d2081 100755 (executable)
@@ -74,9 +74,7 @@ status_check() {
     check_dispatch $1 beta nomicon src/doc/nomicon
     check_dispatch $1 beta reference src/doc/reference
     check_dispatch $1 beta rust-by-example src/doc/rust-by-example
-    # Temporarily disabled until
-    # https://github.com/rust-lang/rust/issues/60459 is fixed.
-    # check_dispatch $1 beta edition-guide src/doc/edition-guide
+    check_dispatch $1 beta edition-guide src/doc/edition-guide
     check_dispatch $1 beta rls src/tools/rls
     check_dispatch $1 beta rustfmt src/tools/rustfmt
     check_dispatch $1 beta clippy-driver src/tools/clippy
index ba927b1ef3b5761dcc08ba64c1d8d76f65e9cf42..f090f142c0816cb17e5c363b7cc3bcd0e1f0e79c 100644 (file)
@@ -529,18 +529,21 @@ This lint detects bounds in type aliases. These are not currently enforced.
 Some example code that triggers this lint:
 
 ```rust
+#[allow(dead_code)]
 type SendVec<T: Send> = Vec<T>;
 ```
 
 This will produce:
 
 ```text
-warning: type alias is never used: `SendVec`
- --> src/main.rs:1:1
+warning: bounds on generic parameters are not enforced in type aliases
+ --> src/lib.rs:2:17
   |
-1 | type SendVec<T: Send> = Vec<T>;
-  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+2 | type SendVec<T: Send> = Vec<T>;
+  |                 ^^^^
   |
+  = note: #[warn(type_alias_bounds)] on by default
+  = help: the bound will not be checked when the type alias is used, and should be removed
 ```
 
 ## tyvar-behind-raw-pointer
index b165c5a6b3b937fa6cd3ca1c5925e15cad6b06ef..80ac405eb2f2a72d9d6bbcac0e1b15ce35e027c7 100644 (file)
@@ -202,7 +202,7 @@ mod bar {
 Now we'll have a `Re-exports` line, and `Bar` will not link to anywhere.
 
 One special case: In Rust 2018 and later, if you `pub use` one of your dependencies, `rustdoc` will
-not eagerly inline it as a module unless you add `#[doc(inline)}`.
+not eagerly inline it as a module unless you add `#[doc(inline)]`.
 
 ## `#[doc(hidden)]`
 
index 97c2d8e7a8e796010dc0f5126c599b52c386de57..76b660fba685ce6b9716e6194f248e628a509497 100644 (file)
@@ -395,11 +395,10 @@ fn clone_from(&mut self, source: &Box<T>) {
 #[stable(feature = "box_slice_clone", since = "1.3.0")]
 impl Clone for Box<str> {
     fn clone(&self) -> Self {
-        let len = self.len();
-        let buf = RawVec::with_capacity(len);
+        // this makes a copy of the data
+        let buf: Box<[u8]> = self.as_bytes().into();
         unsafe {
-            ptr::copy_nonoverlapping(self.as_ptr(), buf.ptr(), len);
-            from_boxed_utf8_unchecked(buf.into_box())
+            from_boxed_utf8_unchecked(buf)
         }
     }
 }
@@ -546,9 +545,12 @@ impl<T: Copy> From<&[T]> for Box<[T]> {
     /// println!("{:?}", boxed_slice);
     /// ```
     fn from(slice: &[T]) -> Box<[T]> {
-        let mut boxed = unsafe { RawVec::with_capacity(slice.len()).into_box() };
-        boxed.copy_from_slice(slice);
-        boxed
+        let len = slice.len();
+        let buf = RawVec::with_capacity(len);
+        unsafe {
+            ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len);
+            buf.into_box()
+        }
     }
 }
 
@@ -759,13 +761,14 @@ extern "rust-call" fn call(&self, args: A) -> Self::Output {
     }
 }
 
+/// `FnBox` is deprecated and will be removed.
+/// `Box<dyn FnOnce()>` can be called directly, since Rust 1.35.0.
+///
 /// `FnBox` is a version of the `FnOnce` intended for use with boxed
-/// closure objects. The idea is that where one would normally store a
-/// `Box<dyn FnOnce()>` in a data structure, you should use
+/// closure objects. The idea was that where one would normally store a
+/// `Box<dyn FnOnce()>` in a data structure, you whould use
 /// `Box<dyn FnBox()>`. The two traits behave essentially the same, except
-/// that a `FnBox` closure can only be called if it is boxed. (Note
-/// that `FnBox` may be deprecated in the future if `Box<dyn FnOnce()>`
-/// closures become directly usable.)
+/// that a `FnBox` closure can only be called if it is boxed.
 ///
 /// # Examples
 ///
@@ -777,6 +780,7 @@ extern "rust-call" fn call(&self, args: A) -> Self::Output {
 ///
 /// ```
 /// #![feature(fnbox)]
+/// #![allow(deprecated)]
 ///
 /// use std::boxed::FnBox;
 /// use std::collections::HashMap;
@@ -796,16 +800,38 @@ extern "rust-call" fn call(&self, args: A) -> Self::Output {
 ///     }
 /// }
 /// ```
+///
+/// In Rust 1.35.0 or later, use `FnOnce`, `FnMut`, or `Fn` instead:
+///
+/// ```
+/// use std::collections::HashMap;
+///
+/// fn make_map() -> HashMap<i32, Box<dyn FnOnce() -> i32>> {
+///     let mut map: HashMap<i32, Box<dyn FnOnce() -> i32>> = HashMap::new();
+///     map.insert(1, Box::new(|| 22));
+///     map.insert(2, Box::new(|| 44));
+///     map
+/// }
+///
+/// fn main() {
+///     let mut map = make_map();
+///     for i in &[1, 2] {
+///         let f = map.remove(&i).unwrap();
+///         assert_eq!(f(), i * 22);
+///     }
+/// }
+/// ```
 #[rustc_paren_sugar]
-#[unstable(feature = "fnbox",
-           reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
+#[unstable(feature = "fnbox", issue = "28796")]
+#[rustc_deprecated(reason = "use `FnOnce`, `FnMut`, or `Fn` instead", since = "1.37.0")]
 pub trait FnBox<A>: FnOnce<A> {
     /// Performs the call operation.
     fn call_box(self: Box<Self>, args: A) -> Self::Output;
 }
 
-#[unstable(feature = "fnbox",
-           reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
+#[unstable(feature = "fnbox", issue = "28796")]
+#[rustc_deprecated(reason = "use `FnOnce`, `FnMut`, or `Fn` instead", since = "1.37.0")]
+#[allow(deprecated, deprecated_in_future)]
 impl<A, F> FnBox<A> for F
     where F: FnOnce<A>
 {
index d1fc5ac3b30d44abe088ce33ca3487f5c3cfef21..0454a564435790e56e3eed2a621bf5499a9d0724 100644 (file)
@@ -685,12 +685,14 @@ fn reserve_internal(
 impl<T> RawVec<T, Global> {
     /// Converts the entire buffer into `Box<[T]>`.
     ///
-    /// While it is not *strictly* Undefined Behavior to call
-    /// this procedure while some of the RawVec is uninitialized,
-    /// it certainly makes it trivial to trigger it.
-    ///
     /// Note that this will correctly reconstitute any `cap` changes
     /// that may have been performed. (see description of type for details)
+    ///
+    /// # Undefined Behavior
+    ///
+    /// All elements of `RawVec<T, Global>` must be initialized. Notice that
+    /// the rules around uninitialized boxed values are not finalized yet,
+    /// but until they are, it is advisable to avoid them.
     pub unsafe fn into_box(self) -> Box<[T]> {
         // NOTE: not calling `cap()` here, actually using the real `cap` field!
         let slice = slice::from_raw_parts_mut(self.ptr(), self.cap);
index 3307bdf94f98590a04463d631cdce47c6dca2da1..5ddac673c9ff17fe9b72859dc9748abb3a57cbfa 100644 (file)
@@ -1152,3 +1152,24 @@ fn test_try_reserve_exact() {
     }
 
 }
+
+#[test]
+fn test_stable_push_pop() {
+    // Test that, if we reserved enough space, adding and removing elements does not
+    // invalidate references into the vector (such as `v0`).  This test also
+    // runs in Miri, which would detect such problems.
+    let mut v = Vec::with_capacity(10);
+    v.push(13);
+
+    // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
+    let v0 = unsafe { &*(&v[0] as *const _) };
+
+    // Now do a bunch of things and occasionally use `v0` again to assert it is still valid.
+    v.push(1);
+    v.push(2);
+    v.insert(1, 1);
+    assert_eq!(*v0, 13);
+    v.remove(1);
+    v.pop().unwrap();
+    assert_eq!(*v0, 13);
+}
index dc661a267e2a621f84682065b3276ecd45008d56..5cb91395b7bf75cd64cdb81e54392b61ec7140c1 100644 (file)
@@ -735,6 +735,75 @@ pub fn as_mut_slice(&mut self) -> &mut [T] {
         self
     }
 
+    /// Returns a raw pointer to the vector's buffer.
+    ///
+    /// The caller must ensure that the vector outlives the pointer this
+    /// function returns, or else it will end up pointing to garbage.
+    /// Modifying the vector may cause its buffer to be reallocated,
+    /// which would also make any pointers to it invalid.
+    ///
+    /// The caller must also ensure that the memory the pointer (non-transitively) points to
+    /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
+    /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let x = vec![1, 2, 4];
+    /// let x_ptr = x.as_ptr();
+    ///
+    /// unsafe {
+    ///     for i in 0..x.len() {
+    ///         assert_eq!(*x_ptr.add(i), 1 << i);
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// [`as_mut_ptr`]: #method.as_mut_ptr
+    #[stable(feature = "vec_as_ptr", since = "1.37.0")]
+    #[inline]
+    pub fn as_ptr(&self) -> *const T {
+        // We shadow the slice method of the same name to avoid going through
+        // `deref`, which creates an intermediate reference.
+        let ptr = self.buf.ptr();
+        unsafe { assume(!ptr.is_null()); }
+        ptr
+    }
+
+    /// Returns an unsafe mutable pointer to the vector's buffer.
+    ///
+    /// The caller must ensure that the vector outlives the pointer this
+    /// function returns, or else it will end up pointing to garbage.
+    /// Modifying the vector may cause its buffer to be reallocated,
+    /// which would also make any pointers to it invalid.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// // Allocate vector big enough for 4 elements.
+    /// let size = 4;
+    /// let mut x: Vec<i32> = Vec::with_capacity(size);
+    /// let x_ptr = x.as_mut_ptr();
+    ///
+    /// // Initialize elements via raw pointer writes, then set length.
+    /// unsafe {
+    ///     for i in 0..size {
+    ///         *x_ptr.add(i) = i as i32;
+    ///     }
+    ///     x.set_len(size);
+    /// }
+    /// assert_eq!(&*x, &[0,1,2,3]);
+    /// ```
+    #[stable(feature = "vec_as_ptr", since = "1.37.0")]
+    #[inline]
+    pub fn as_mut_ptr(&mut self) -> *mut T {
+        // We shadow the slice method of the same name to avoid going through
+        // `deref_mut`, which creates an intermediate reference.
+        let ptr = self.buf.ptr();
+        unsafe { assume(!ptr.is_null()); }
+        ptr
+    }
+
     /// Forces the length of the vector to `new_len`.
     ///
     /// This is a low-level operation that maintains none of the normal
@@ -1706,9 +1775,7 @@ impl<T> ops::Deref for Vec<T> {
 
     fn deref(&self) -> &[T] {
         unsafe {
-            let p = self.buf.ptr();
-            assume(!p.is_null());
-            slice::from_raw_parts(p, self.len)
+            slice::from_raw_parts(self.as_ptr(), self.len)
         }
     }
 }
@@ -1717,9 +1784,7 @@ fn deref(&self) -> &[T] {
 impl<T> ops::DerefMut for Vec<T> {
     fn deref_mut(&mut self) -> &mut [T] {
         unsafe {
-            let ptr = self.buf.ptr();
-            assume(!ptr.is_null());
-            slice::from_raw_parts_mut(ptr, self.len)
+            slice::from_raw_parts_mut(self.as_mut_ptr(), self.len)
         }
     }
 }
@@ -1754,7 +1819,6 @@ impl<T> IntoIterator for Vec<T> {
     fn into_iter(mut self) -> IntoIter<T> {
         unsafe {
             let begin = self.as_mut_ptr();
-            assume(!begin.is_null());
             let end = if mem::size_of::<T>() == 0 {
                 arith_offset(begin as *const i8, self.len() as isize) as *const T
             } else {
index 9672cf4ffed36860db66de3fac8a5c2d5768ceeb..80341409037683e6db06685ec7b9c424839fdab7 100644 (file)
@@ -11,7 +11,7 @@
 //! mutate it.
 //!
 //! Shareable mutable containers exist to permit mutability in a controlled manner, even in the
-//! presence of aliasing. Both `Cell<T>` and `RefCell<T>` allows to do this in a single threaded
+//! presence of aliasing. Both `Cell<T>` and `RefCell<T>` allow doing this in a single-threaded
 //! way. However, neither `Cell<T>` nor `RefCell<T>` are thread safe (they do not implement
 //! `Sync`). If you need to do aliasing and mutation between multiple threads it is possible to
 //! use [`Mutex`](../../std/sync/struct.Mutex.html),
index 3f76ac20192ba092734225342772b827165e627b..0492fd709b8dca8476297166b2ce48da99454fa9 100644 (file)
@@ -21,7 +21,7 @@
 /// task.
 ///
 /// When using a future, you generally won't call `poll` directly, but instead
-/// `await!` the value.
+/// `.await` the value.
 #[doc(spotlight)]
 #[must_use = "futures do nothing unless you `.await` or poll them"]
 #[stable(feature = "futures_api", since = "1.36.0")]
index 1601357d3b05400199dc9c8326a9fd4f333eaca9..6eccb9d1ea86d294c9527dff5361fd870f1d89b7 100644 (file)
 //! call `next()` on your iterator, until it reaches `None`. Let's go over that
 //! next.
 //!
+//! Also note that `Iterator` provides a default implementation of methods such as `nth` and `fold`
+//! which call `next` internally. However, it is also possible to write a custom implementation of
+//! methods like `nth` and `fold` if an iterator can compute them more efficiently without calling
+//! `next`.
+//!
 //! # for Loops and IntoIterator
 //!
 //! Rust's `for` loop syntax is actually sugar for iterators. Here's a basic
index 38c7c9bc4d086c53e9e27eed48168dff5670b4ef..d0fdd79473e6726eaf0cc48ffff0beb79e761822 100644 (file)
@@ -964,6 +964,7 @@ fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
     /// Creates an iterator that skips the first `n` elements.
     ///
     /// After they have been consumed, the rest of the elements are yielded.
+    /// Rather than overriding this method directly, instead override the `nth` method.
     ///
     /// # Examples
     ///
index d2ee9b11b3640c2ffd32c64e9e0fc26ee809a2c6..9dfa09cf8a512cd0ad84c49ab008fbc1c6492baf 100644 (file)
@@ -445,9 +445,10 @@ macro_rules! writeln {
 /// * Iterators that dynamically terminate.
 ///
 /// If the determination that the code is unreachable proves incorrect, the
-/// program immediately terminates with a [`panic!`]. The function [`unreachable_unchecked`],
-/// which belongs to the [`std::hint`] module, informs the compiler to
-/// optimize the code out of the release version entirely.
+/// program immediately terminates with a [`panic!`].
+///
+/// The unsafe counterpart of this macro is the [`unreachable_unchecked`] function, which
+/// will cause undefined behavior if the code is reached.
 ///
 /// [`panic!`]:  ../std/macro.panic.html
 /// [`unreachable_unchecked`]: ../std/hint/fn.unreachable_unchecked.html
index 56869f38a4f6bb3f09dd2988ef1ff4cc46137405..ce4aee7ebc54f8be0ceed6408e4642a18c4a5918 100644 (file)
@@ -982,7 +982,7 @@ fn deref_mut(&mut self) -> &mut T {
 ///     out.write(vec![1, 2, 3]);
 /// }
 ///
-/// let mut v: MaybeUninit<Vec<i32>> = MaybeUninit::uninit();
+/// let mut v = MaybeUninit::uninit();
 /// unsafe { make_vec(v.as_mut_ptr()); }
 /// // Now we know `v` is initialized! This also makes sure the vector gets
 /// // properly dropped.
@@ -1071,7 +1071,7 @@ fn deref_mut(&mut self) -> &mut T {
 /// optimizations, potentially resulting in a larger size:
 ///
 /// ```rust
-/// # use std::mem::{MaybeUninit, size_of, align_of};
+/// # use std::mem::{MaybeUninit, size_of};
 /// assert_eq!(size_of::<Option<bool>>(), 1);
 /// assert_eq!(size_of::<Option<MaybeUninit<bool>>>(), 2);
 /// ```
index 932c0eaa4c7b1ede320ad45c12243fb25f68f27e..7ec75ed0114889adb302a009fe71c8e6bb4628a9 100644 (file)
@@ -473,6 +473,7 @@ pub const fn swap_bytes(self) -> Self {
             #[unstable(feature = "reverse_bits", issue = "48763")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
             #[inline]
+            #[must_use]
             pub const fn reverse_bits(self) -> Self {
                 (self as $UnsignedT).reverse_bits() as Self
             }
@@ -2522,6 +2523,7 @@ pub const fn swap_bytes(self) -> Self {
 ```"),
             #[unstable(feature = "reverse_bits", issue = "48763")]
             #[inline]
+            #[must_use]
             pub const fn reverse_bits(self) -> Self {
                 intrinsics::bitreverse(self as $ActualT) as Self
             }
index a3491bc3dc66490ff555ad22794fb288eade45f7..5eb5ec558f8c132a847e0ba3680c2360d99e5e16 100644 (file)
@@ -524,6 +524,7 @@ pub const fn swap_bytes(self) -> Self {
             /// ```
             #[unstable(feature = "reverse_bits", issue = "48763")]
             #[inline]
+            #[must_use]
             pub const fn reverse_bits(self) -> Self {
                 Wrapping(self.0.reverse_bits())
             }
index a6d611d2e93c4b83847a9791a39a28bb1a270e14..f1247239f4f50e2b30349676b5962f96590cfcf0 100644 (file)
@@ -147,14 +147,13 @@ impl RawWakerVTable {
     /// [`Waker`]: struct.Waker.html
     /// [`RawWaker`]: struct.RawWaker.html
     #[rustc_promotable]
-    #[cfg_attr(stage0, unstable(feature = "futures_api_const_fn_ptr", issue = "50547"))]
-    #[cfg_attr(not(stage0), stable(feature = "futures_api", since = "1.36.0"))]
+    #[stable(feature = "futures_api", since = "1.36.0")]
     // `rustc_allow_const_fn_ptr` is a hack that should not be used anywhere else
     // without first consulting with T-Lang.
     //
     // FIXME: remove whenever we have a stable way to accept fn pointers from const fn
     // (see https://github.com/rust-rfcs/const-eval/issues/19#issuecomment-472799062)
-    #[cfg_attr(not(stage0), rustc_allow_const_fn_ptr)]
+    #[rustc_allow_const_fn_ptr]
     pub const fn new(
         clone: unsafe fn(*const ()) -> RawWaker,
         wake: unsafe fn(*const ()),
index 491986480deba1082cce16d4b955915c2bce3121..0b2bda577d75f7e56721cda21ee93e920f253980 100644 (file)
@@ -41,7 +41,11 @@ fn main() {
         cfg.flag("-fomit-frame-pointer");
         cfg.flag("-ffreestanding");
         cfg.define("VISIBILITY_HIDDEN", None);
-        cfg.define("COMPILER_RT_HAS_UNAME", Some("1"));
+        if !target.contains("windows") {
+            cfg.define("COMPILER_RT_HAS_UNAME", Some("1"));
+        } else {
+            profile_sources.push("WindowsMMap.c");
+        }
     }
 
     // Assume that the Unixes we are building this for have fnctl() available
index a1bfd417566ad7473f93f8c2696af3674503aa6f..6243e911bd5fdf92bc5b834a3ad51e7ccb0f7fd7 100644 (file)
@@ -1207,6 +1207,51 @@ fn main() {
 ```
 "##,
 
+E0284: r##"
+This error occurs when the compiler is unable to unambiguously infer the
+return type of a function or method which is generic on return type, such
+as the `collect` method for `Iterator`s.
+
+For example:
+
+```compile_fail,E0284
+fn foo() -> Result<bool, ()> {
+    let results = [Ok(true), Ok(false), Err(())].iter().cloned();
+    let v: Vec<bool> = results.collect()?;
+    // Do things with v...
+    Ok(true)
+}
+```
+
+Here we have an iterator `results` over `Result<bool, ()>`.
+Hence, `results.collect()` can return any type implementing
+`FromIterator<Result<bool, ()>>`. On the other hand, the
+`?` operator can accept any type implementing `Try`.
+
+The author of this code probably wants `collect()` to return a
+`Result<Vec<bool>, ()>`, but the compiler can't be sure
+that there isn't another type `T` implementing both `Try` and
+`FromIterator<Result<bool, ()>>` in scope such that
+`T::Ok == Vec<bool>`. Hence, this code is ambiguous and an error
+is returned.
+
+To resolve this error, use a concrete type for the intermediate expression:
+
+```
+fn foo() -> Result<bool, ()> {
+    let results = [Ok(true), Ok(false), Err(())].iter().cloned();
+    let v = {
+        let temp: Result<Vec<bool>, ()> = results.collect();
+        temp?
+    };
+    // Do things with v...
+    Ok(true)
+}
+```
+
+Note that the type of `v` can now be inferred from the type of `temp`.
+"##,
+
 E0308: r##"
 This error occurs when the compiler was unable to infer the concrete type of a
 variable. It can occur for several cases, the most common of which is a
@@ -2158,7 +2203,6 @@ trait Foo { }
     E0278, // requirement is not satisfied
     E0279, // requirement is not satisfied
     E0280, // requirement is not satisfied
-    E0284, // cannot resolve type
 //  E0285, // overflow evaluation builtin bounds
 //  E0296, // replaced with a generic attribute input check
 //  E0300, // unexpanded macro
index 91256385232a9b32da2de83e6bd50e34650e9e5a..03f24dbb29025f70ef8004cdab5c80275a6e45fc 100644 (file)
@@ -61,9 +61,9 @@ pub enum DefKind {
     TyAlias,
     ForeignTy,
     TraitAlias,
-    AssociatedTy,
+    AssocTy,
     /// `existential type Foo: Bar;`
-    AssociatedExistential,
+    AssocExistential,
     TyParam,
 
     // Value namespace
@@ -74,7 +74,7 @@ pub enum DefKind {
     /// Refers to the struct or enum variant's constructor.
     Ctor(CtorOf, CtorKind),
     Method,
-    AssociatedConst,
+    AssocConst,
 
     // Macro namespace
     Macro(MacroKind),
@@ -99,14 +99,14 @@ pub fn descr(self) -> &'static str {
             DefKind::Existential => "existential type",
             DefKind::TyAlias => "type alias",
             DefKind::TraitAlias => "trait alias",
-            DefKind::AssociatedTy => "associated type",
-            DefKind::AssociatedExistential => "associated existential type",
+            DefKind::AssocTy => "associated type",
+            DefKind::AssocExistential => "associated existential type",
             DefKind::Union => "union",
             DefKind::Trait => "trait",
             DefKind::ForeignTy => "foreign type",
             DefKind::Method => "method",
             DefKind::Const => "constant",
-            DefKind::AssociatedConst => "associated constant",
+            DefKind::AssocConst => "associated constant",
             DefKind::TyParam => "type parameter",
             DefKind::ConstParam => "const parameter",
             DefKind::Macro(macro_kind) => macro_kind.descr(),
@@ -116,9 +116,9 @@ pub fn descr(self) -> &'static str {
     /// An English article for the def.
     pub fn article(&self) -> &'static str {
         match *self {
-            DefKind::AssociatedTy
-            | DefKind::AssociatedConst
-            | DefKind::AssociatedExistential
+            DefKind::AssocTy
+            | DefKind::AssocConst
+            | DefKind::AssocExistential
             | DefKind::Enum
             | DefKind::Existential => "an",
             DefKind::Macro(macro_kind) => macro_kind.article(),
index 517c99f99efea1e257339c96ca398c644e1b68a5..8000666044a1aeddeee0dcb9135456365d19cd17 100644 (file)
@@ -370,7 +370,7 @@ fn visit_macro_def(&mut self, macro_def: &'v MacroDef) {
     fn visit_vis(&mut self, vis: &'v Visibility) {
         walk_vis(self, vis)
     }
-    fn visit_associated_item_kind(&mut self, kind: &'v AssociatedItemKind) {
+    fn visit_associated_item_kind(&mut self, kind: &'v AssocItemKind) {
         walk_associated_item_kind(self, kind);
     }
     fn visit_defaultness(&mut self, defaultness: &'v Defaultness) {
@@ -1120,7 +1120,7 @@ pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) {
     }
 }
 
-pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssociatedItemKind) {
+pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssocItemKind) {
     // No visitable content here: this fn exists so you can call it if
     // the right thing to do, should content be added in the future,
     // would be to walk it.
index 3d83918bd0a661989ef1d7a78eac2504ae75e42a..c5bcddcb26623097858a21b104707626d5f8714e 100644 (file)
@@ -1145,9 +1145,7 @@ fn make_async_expr(
         let unstable_span = self.sess.source_map().mark_span_with_reason(
             CompilerDesugaringKind::Async,
             span,
-            Some(vec![
-                Symbol::intern("gen_future"),
-            ].into()),
+            Some(vec![sym::gen_future].into()),
         );
         let gen_future = self.expr_std_path(
             unstable_span, &[sym::future, sym::from_generator], None, ThinVec::new());
@@ -1862,7 +1860,7 @@ fn lower_qpath(
                         index: this.def_key(def_id).parent.expect("missing parent"),
                     };
                     let type_def_id = match partial_res.base_res() {
-                        Res::Def(DefKind::AssociatedTy, def_id) if i + 2 == proj_start => {
+                        Res::Def(DefKind::AssocTy, def_id) if i + 2 == proj_start => {
                             Some(parent_def_id(self, def_id))
                         }
                         Res::Def(DefKind::Variant, def_id) if i + 1 == proj_start => {
@@ -1884,8 +1882,8 @@ fn lower_qpath(
                             if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
                         // `a::b::Trait(Args)::TraitItem`
                         Res::Def(DefKind::Method, _)
-                        | Res::Def(DefKind::AssociatedConst, _)
-                        | Res::Def(DefKind::AssociatedTy, _)
+                        | Res::Def(DefKind::AssocConst, _)
+                        | Res::Def(DefKind::AssocTy, _)
                             if i + 2 == proj_start =>
                         {
                             ParenthesizedGenericArgs::Ok
@@ -2958,7 +2956,7 @@ fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::Stru
             ident: match f.ident {
                 Some(ident) => ident,
                 // FIXME(jseyfried): positional field hygiene
-                None => Ident::new(Symbol::intern(&index.to_string()), f.span),
+                None => Ident::new(sym::integer(index), f.span),
             },
             vis: self.lower_visibility(&f.vis, None),
             ty: self.lower_ty(&f.ty, ImplTraitContext::disallowed()),
@@ -3591,13 +3589,13 @@ fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
     fn lower_trait_item_ref(&mut self, i: &TraitItem) -> hir::TraitItemRef {
         let (kind, has_default) = match i.node {
             TraitItemKind::Const(_, ref default) => {
-                (hir::AssociatedItemKind::Const, default.is_some())
+                (hir::AssocItemKind::Const, default.is_some())
             }
             TraitItemKind::Type(_, ref default) => {
-                (hir::AssociatedItemKind::Type, default.is_some())
+                (hir::AssocItemKind::Type, default.is_some())
             }
             TraitItemKind::Method(ref sig, ref default) => (
-                hir::AssociatedItemKind::Method {
+                hir::AssocItemKind::Method {
                     has_self: sig.decl.has_self(),
                 },
                 default.is_some(),
@@ -3697,10 +3695,10 @@ fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
             vis: self.lower_visibility(&i.vis, Some(i.id)),
             defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
             kind: match i.node {
-                ImplItemKind::Const(..) => hir::AssociatedItemKind::Const,
-                ImplItemKind::Type(..) => hir::AssociatedItemKind::Type,
-                ImplItemKind::Existential(..) => hir::AssociatedItemKind::Existential,
-                ImplItemKind::Method(ref sig, _) => hir::AssociatedItemKind::Method {
+                ImplItemKind::Const(..) => hir::AssocItemKind::Const,
+                ImplItemKind::Type(..) => hir::AssocItemKind::Type,
+                ImplItemKind::Existential(..) => hir::AssocItemKind::Existential,
+                ImplItemKind::Method(ref sig, _) => hir::AssocItemKind::Method {
                     has_self: sig.decl.has_self(),
                 },
                 ImplItemKind::Macro(..) => unimplemented!(),
@@ -4177,9 +4175,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     let unstable_span = this.sess.source_map().mark_span_with_reason(
                         CompilerDesugaringKind::TryBlock,
                         body.span,
-                        Some(vec![
-                            Symbol::intern("try_trait"),
-                        ].into()),
+                        Some(vec![sym::try_trait].into()),
                     );
                     let mut block = this.lower_block(body, true).into_inner();
                     let tail = block.expr.take().map_or_else(
index bb9e76f02624651c2eb1483f89dad597fff6a78c..bde27c71f9a6d242f68bcd5f8c4c2b08b912ac85 100644 (file)
@@ -5,8 +5,7 @@
 use syntax::ast::*;
 use syntax::ext::hygiene::Mark;
 use syntax::visit;
-use syntax::symbol::kw;
-use syntax::symbol::Symbol;
+use syntax::symbol::{kw, sym};
 use syntax::parse::token::{self, Token};
 use syntax_pos::Span;
 
@@ -221,7 +220,7 @@ fn visit_variant_data(&mut self, data: &'a VariantData, _: Ident,
                           _: &'a Generics, _: NodeId, _: Span) {
         for (index, field) in data.fields().iter().enumerate() {
             let name = field.ident.map(|ident| ident.name)
-                .unwrap_or_else(|| Symbol::intern(&index.to_string()));
+                .unwrap_or_else(|| sym::integer(index));
             let def = self.create_def(field.id,
                                       DefPathData::ValueNs(name.as_interned_str()),
                                       field.span);
index 1cc9a2c0e8a1b9d875b7f9a31520c5644f727e76..2324c3f04284ff33483b490f92280ebc07a1afc8 100644 (file)
@@ -10,7 +10,6 @@
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::{IndexVec};
 use rustc_data_structures::stable_hasher::StableHasher;
-use serialize::{Encodable, Decodable, Encoder, Decoder};
 use crate::session::CrateDisambiguator;
 use std::borrow::Borrow;
 use std::fmt::Write;
 /// Internally the DefPathTable holds a tree of DefKeys, where each DefKey
 /// stores the DefIndex of its parent.
 /// There is one DefPathTable for each crate.
-#[derive(Clone, Default)]
+#[derive(Clone, Default, RustcDecodable, RustcEncodable)]
 pub struct DefPathTable {
     index_to_key: Vec<DefKey>,
     def_path_hashes: Vec<DefPathHash>,
 }
 
 impl DefPathTable {
-
     fn allocate(&mut self,
                 key: DefKey,
                 def_path_hash: DefPathHash)
@@ -86,28 +84,6 @@ pub fn size(&self) -> usize {
     }
 }
 
-
-impl Encodable for DefPathTable {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        // Index to key
-        self.index_to_key.encode(s)?;
-
-        // DefPath hashes
-        self.def_path_hashes.encode(s)?;
-
-        Ok(())
-    }
-}
-
-impl Decodable for DefPathTable {
-    fn decode<D: Decoder>(d: &mut D) -> Result<DefPathTable, D::Error> {
-        Ok(DefPathTable {
-            index_to_key: Decodable::decode(d)?,
-            def_path_hashes : Decodable::decode(d)?,
-        })
-    }
-}
-
 /// The definition table containing node definitions.
 /// It holds the `DefPathTable` for local `DefId`s/`DefPath`s and it also stores a
 /// mapping from `NodeId`s to local `DefId`s.
index 0741d9322c65328eff9d2fb7dcb1ffdac3883481..fd42c6f469e1eec2bb91f70e64f6b8dc1d6be44e 100644 (file)
@@ -337,17 +337,17 @@ fn def_kind(&self, node_id: NodeId) -> Option<DefKind> {
             }
             Node::TraitItem(item) => {
                 match item.node {
-                    TraitItemKind::Const(..) => DefKind::AssociatedConst,
+                    TraitItemKind::Const(..) => DefKind::AssocConst,
                     TraitItemKind::Method(..) => DefKind::Method,
-                    TraitItemKind::Type(..) => DefKind::AssociatedTy,
+                    TraitItemKind::Type(..) => DefKind::AssocTy,
                 }
             }
             Node::ImplItem(item) => {
                 match item.node {
-                    ImplItemKind::Const(..) => DefKind::AssociatedConst,
+                    ImplItemKind::Const(..) => DefKind::AssocConst,
                     ImplItemKind::Method(..) => DefKind::Method,
-                    ImplItemKind::Type(..) => DefKind::AssociatedTy,
-                    ImplItemKind::Existential(..) => DefKind::AssociatedExistential,
+                    ImplItemKind::Type(..) => DefKind::AssocTy,
+                    ImplItemKind::Existential(..) => DefKind::AssocExistential,
                 }
             }
             Node::Variant(_) => DefKind::Variant,
index 2ae5f7a0b5531f4771c6c264320cb75fe3c6f71e..1a6f5d3733e7ac5fbc1664639dc078dad699f6a2 100644 (file)
@@ -2422,7 +2422,7 @@ pub struct TraitItemRef {
     pub id: TraitItemId,
     #[stable_hasher(project(name))]
     pub ident: Ident,
-    pub kind: AssociatedItemKind,
+    pub kind: AssocItemKind,
     pub span: Span,
     pub defaultness: Defaultness,
 }
@@ -2438,14 +2438,14 @@ pub struct ImplItemRef {
     pub id: ImplItemId,
     #[stable_hasher(project(name))]
     pub ident: Ident,
-    pub kind: AssociatedItemKind,
+    pub kind: AssocItemKind,
     pub span: Span,
     pub vis: Visibility,
     pub defaultness: Defaultness,
 }
 
 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub enum AssociatedItemKind {
+pub enum AssocItemKind {
     Const,
     Method { has_self: bool },
     Type,
index e4505a240379f0047bbde6f12e9f1e85c2f7612d..8ec9d42ec5f827b272ae5a78016fc45a4ee0e93b 100644 (file)
@@ -462,6 +462,7 @@ impl<'gcx, 'tcx> Printer<'gcx, 'tcx> for AbsolutePathPrinter<'_, 'gcx, 'tcx> {
             type Region = !;
             type Type = !;
             type DynExistential = !;
+            type Const = !;
 
             fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> {
                 self.tcx
@@ -488,6 +489,13 @@ fn print_dyn_existential(
                 Err(NonTrivialPath)
             }
 
+            fn print_const(
+                self,
+                _ct: &'tcx ty::Const<'tcx>,
+            ) -> Result<Self::Const, Self::Error> {
+                Err(NonTrivialPath)
+            }
+
             fn path_crate(
                 self,
                 cnum: CrateNum,
index 679635bef13e5623436aab23f846427c4ad59306..8f52ef7a3f3a4c1d0ad8b827fcda24585aa67b1e 100644 (file)
@@ -260,7 +260,7 @@ fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
 
             ConstValue::Param(_) |
             ConstValue::Scalar(_) |
-            ConstValue::Slice(..) |
+            ConstValue::Slice { .. } |
             ConstValue::ByRef(..) |
             ConstValue::Unevaluated(..) => {}
         }
index 7e1e751e856478197de92a2e69dc2e2b86ebcea3..c6583dd7a27b707cd1057dc24b9804f6a96ade1c 100644 (file)
@@ -759,27 +759,27 @@ pub fn current_lint_root(&self) -> hir::HirId {
     /// # Examples
     ///
     /// ```rust,ignore (no context or def id available)
-    /// if cx.match_def_path(def_id, &["core", "option", "Option"]) {
+    /// if cx.match_def_path(def_id, &[sym::core, sym::option, sym::Option]) {
     ///     // The given `def_id` is that of an `Option` type
     /// }
     /// ```
-    pub fn match_def_path(&self, def_id: DefId, path: &[&str]) -> bool {
+    pub fn match_def_path(&self, def_id: DefId, path: &[Symbol]) -> bool {
         let names = self.get_def_path(def_id);
 
-        names.len() == path.len() && names.into_iter().zip(path.iter()).all(|(a, &b)| *a == *b)
+        names.len() == path.len() && names.into_iter().zip(path.iter()).all(|(a, &b)| a == b)
     }
 
-    /// Gets the absolute path of `def_id` as a vector of `&str`.
+    /// Gets the absolute path of `def_id` as a vector of `Symbol`.
     ///
     /// # Examples
     ///
     /// ```rust,ignore (no context or def id available)
     /// let def_path = cx.get_def_path(def_id);
-    /// if let &["core", "option", "Option"] = &def_path[..] {
+    /// if let &[sym::core, sym::option, sym::Option] = &def_path[..] {
     ///     // The given `def_id` is that of an `Option` type
     /// }
     /// ```
-    pub fn get_def_path(&self, def_id: DefId) -> Vec<LocalInternedString> {
+    pub fn get_def_path(&self, def_id: DefId) -> Vec<Symbol> {
         pub struct AbsolutePathPrinter<'a, 'tcx> {
             pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
@@ -787,10 +787,11 @@ pub struct AbsolutePathPrinter<'a, 'tcx> {
         impl<'tcx> Printer<'tcx, 'tcx> for AbsolutePathPrinter<'_, 'tcx> {
             type Error = !;
 
-            type Path = Vec<LocalInternedString>;
+            type Path = Vec<Symbol>;
             type Region = ();
             type Type = ();
             type DynExistential = ();
+            type Const = ();
 
             fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
                 self.tcx
@@ -807,19 +808,26 @@ fn print_type(self, _ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
             fn print_dyn_existential(
                 self,
                 _predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
-                ) -> Result<Self::DynExistential, Self::Error> {
+            ) -> Result<Self::DynExistential, Self::Error> {
+                Ok(())
+            }
+
+            fn print_const(
+                self,
+                _ct: &'tcx ty::Const<'tcx>,
+            ) -> Result<Self::Const, Self::Error> {
                 Ok(())
             }
 
             fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
-                Ok(vec![self.tcx.original_crate_name(cnum).as_str()])
+                Ok(vec![self.tcx.original_crate_name(cnum)])
             }
 
             fn path_qualified(
                 self,
                 self_ty: Ty<'tcx>,
                 trait_ref: Option<ty::TraitRef<'tcx>>,
-                ) -> Result<Self::Path, Self::Error> {
+            ) -> Result<Self::Path, Self::Error> {
                 if trait_ref.is_none() {
                     if let ty::Adt(def, substs) = self_ty.sty {
                         return self.print_def_path(def.did, substs);
@@ -828,8 +836,8 @@ fn path_qualified(
 
                 // This shouldn't ever be needed, but just in case:
                 Ok(vec![match trait_ref {
-                    Some(trait_ref) => LocalInternedString::intern(&format!("{:?}", trait_ref)),
-                    None => LocalInternedString::intern(&format!("<{}>", self_ty)),
+                    Some(trait_ref) => Symbol::intern(&format!("{:?}", trait_ref)),
+                    None => Symbol::intern(&format!("<{}>", self_ty)),
                 }])
             }
 
@@ -839,16 +847,16 @@ fn path_append_impl(
                 _disambiguated_data: &DisambiguatedDefPathData,
                 self_ty: Ty<'tcx>,
                 trait_ref: Option<ty::TraitRef<'tcx>>,
-                ) -> Result<Self::Path, Self::Error> {
+            ) -> Result<Self::Path, Self::Error> {
                 let mut path = print_prefix(self)?;
 
                 // This shouldn't ever be needed, but just in case:
                 path.push(match trait_ref {
                     Some(trait_ref) => {
-                        LocalInternedString::intern(&format!("<impl {} for {}>", trait_ref,
+                        Symbol::intern(&format!("<impl {} for {}>", trait_ref,
                                                     self_ty))
                     },
-                    None => LocalInternedString::intern(&format!("<impl {}>", self_ty)),
+                    None => Symbol::intern(&format!("<impl {}>", self_ty)),
                 });
 
                 Ok(path)
@@ -858,7 +866,7 @@ fn path_append(
                 self,
                 print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
                 disambiguated_data: &DisambiguatedDefPathData,
-                ) -> Result<Self::Path, Self::Error> {
+            ) -> Result<Self::Path, Self::Error> {
                 let mut path = print_prefix(self)?;
 
                 // Skip `::{{constructor}}` on tuple/unit structs.
@@ -867,7 +875,7 @@ fn path_append(
                     _ => {}
                 }
 
-                path.push(disambiguated_data.data.as_interned_str().as_str());
+                path.push(disambiguated_data.data.as_interned_str().as_symbol());
                 Ok(path)
             }
 
@@ -875,7 +883,7 @@ fn path_generic_args(
                 self,
                 print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
                 _args: &[Kind<'tcx>],
-                ) -> Result<Self::Path, Self::Error> {
+            ) -> Result<Self::Path, Self::Error> {
                 print_prefix(self)
             }
         }
index c78026209760753b588dcc200e815f7e3ba64108..e953c084599631e28d74136bde4b31e1c0babde9 100644 (file)
@@ -8,6 +8,7 @@
 use errors::Applicability;
 use rustc_data_structures::fx::FxHashMap;
 use syntax::ast::Ident;
+use syntax::symbol::{sym, Symbol};
 
 declare_lint! {
     pub DEFAULT_HASH_TYPES,
 }
 
 pub struct DefaultHashTypes {
-    map: FxHashMap<String, String>,
+    map: FxHashMap<Symbol, Symbol>,
 }
 
 impl DefaultHashTypes {
+    // we are allowed to use `HashMap` and `HashSet` as identifiers for implementing the lint itself
+    #[allow(internal)]
     pub fn new() -> Self {
         let mut map = FxHashMap::default();
-        map.insert("HashMap".to_string(), "FxHashMap".to_string());
-        map.insert("HashSet".to_string(), "FxHashSet".to_string());
+        map.insert(sym::HashMap, sym::FxHashMap);
+        map.insert(sym::HashSet, sym::FxHashSet);
         Self { map }
     }
 }
@@ -32,11 +35,10 @@ pub fn new() -> Self {
 
 impl EarlyLintPass for DefaultHashTypes {
     fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
-        let ident_string = ident.to_string();
-        if let Some(replace) = self.map.get(&ident_string) {
+        if let Some(replace) = self.map.get(&ident.name) {
             let msg = format!(
                 "Prefer {} over {}, it has better performance",
-                replace, ident_string
+                replace, ident
             );
             let mut db = cx.struct_span_lint(DEFAULT_HASH_TYPES, ident.span, &msg);
             db.span_suggestion(
@@ -169,10 +171,10 @@ fn check_ty(&mut self, cx: &LateContext<'_, '_>, ty: &'tcx Ty) {
 }
 
 fn lint_ty_kind_usage(cx: &LateContext<'_, '_>, segment: &PathSegment) -> bool {
-    if segment.ident.as_str() == "TyKind" {
+    if segment.ident.name == sym::TyKind {
         if let Some(res) = segment.res {
             if let Some(did) = res.opt_def_id() {
-                return cx.match_def_path(did, &["rustc", "ty", "sty", "TyKind"]);
+                return cx.match_def_path(did, TYKIND_PATH);
             }
         }
     }
@@ -180,14 +182,18 @@ fn lint_ty_kind_usage(cx: &LateContext<'_, '_>, segment: &PathSegment) -> bool {
     false
 }
 
+const TYKIND_PATH: &[Symbol] = &[sym::rustc, sym::ty, sym::sty, sym::TyKind];
+const TY_PATH: &[Symbol] = &[sym::rustc, sym::ty, sym::Ty];
+const TYCTXT_PATH: &[Symbol] = &[sym::rustc, sym::ty, sym::context, sym::TyCtxt];
+
 fn is_ty_or_ty_ctxt(cx: &LateContext<'_, '_>, ty: &Ty) -> Option<String> {
     match &ty.node {
         TyKind::Path(qpath) => {
             if let QPath::Resolved(_, path) = qpath {
                 let did = path.res.opt_def_id()?;
-                if cx.match_def_path(did, &["rustc", "ty", "Ty"]) {
+                if cx.match_def_path(did, TY_PATH) {
                     return Some(format!("Ty{}", gen_args(path.segments.last().unwrap())));
-                } else if cx.match_def_path(did, &["rustc", "ty", "context", "TyCtxt"]) {
+                } else if cx.match_def_path(did, TYCTXT_PATH) {
                     return Some(format!("TyCtxt{}", gen_args(path.segments.last().unwrap())));
                 }
             }
index 9c926dff325bfb5a270f090d283c43c656660d1e..139f4343117af8b37ac2eb91a0b2d34791917c8c 100644 (file)
@@ -191,7 +191,7 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
         let store = self.sess.lint_store.borrow();
         let sess = self.sess;
         let bad_attr = |span| {
-            struct_span_err!(sess, span, E0452, "malformed lint attribute")
+            struct_span_err!(sess, span, E0452, "malformed lint attribute input")
         };
         for attr in attrs {
             let level = match Level::from_symbol(attr.name_or_empty()) {
@@ -238,18 +238,20 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
                                 }
                                 reason = Some(rationale);
                             } else {
-                                let mut err = bad_attr(name_value.span);
-                                err.help("reason must be a string literal");
-                                err.emit();
+                                bad_attr(name_value.span)
+                                    .span_label(name_value.span, "reason must be a string literal")
+                                    .emit();
                             }
                         } else {
-                            let mut err = bad_attr(item.span);
-                            err.emit();
+                            bad_attr(item.span)
+                                .span_label(item.span, "bad attribute argument")
+                                .emit();
                         }
                     },
                     ast::MetaItemKind::List(_) => {
-                        let mut err = bad_attr(item.span);
-                        err.emit();
+                        bad_attr(item.span)
+                            .span_label(item.span, "bad attribute argument")
+                            .emit();
                     }
                 }
             }
@@ -258,14 +260,20 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
                 let meta_item = match li.meta_item() {
                     Some(meta_item) if meta_item.is_word() => meta_item,
                     _ => {
-                        let mut err = bad_attr(li.span());
+                        let sp = li.span();
+                        let mut err = bad_attr(sp);
+                        let mut add_label = true;
                         if let Some(item) = li.meta_item() {
                             if let ast::MetaItemKind::NameValue(_) = item.node {
                                 if item.path == sym::reason {
-                                    err.help("reason in lint attribute must come last");
+                                    err.span_label(sp, "reason in lint attribute must come last");
+                                    add_label = false;
                                 }
                             }
                         }
+                        if add_label {
+                            err.span_label(sp, "bad attribute argument");
+                        }
                         err.emit();
                         continue;
                     }
@@ -318,15 +326,14 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
                                      Also `cfg_attr(cargo-clippy)` won't be necessary anymore",
                                     name
                                 );
-                                let mut err = lint::struct_lint_level(
+                                lint::struct_lint_level(
                                     self.sess,
                                     lint,
                                     lvl,
                                     src,
                                     Some(li.span().into()),
                                     &msg,
-                                );
-                                err.span_suggestion(
+                                ).span_suggestion(
                                     li.span(),
                                     "change it to",
                                     new_lint_name.to_string(),
index 2a9928567f4dcfa2fed79a3dd44afba6ed765089..14553a972b704923e8bc26ba6cf076bcb568e339 100644 (file)
@@ -72,7 +72,7 @@ fn insert_def_id(&mut self, def_id: DefId) {
     fn handle_res(&mut self, res: Res) {
         match res {
             Res::Def(DefKind::Const, _)
-            | Res::Def(DefKind::AssociatedConst, _)
+            | Res::Def(DefKind::AssocConst, _)
             | Res::Def(DefKind::TyAlias, _) => {
                 self.check_def_id(res.def_id());
             }
index d46bba92f3fc90947c66d07b91fdfddcc2952dca..35b6b76a395679f88165804f7ac0f89c9cebbcb0 100644 (file)
@@ -909,7 +909,7 @@ fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: Mat
                 | Res::Def(DefKind::Ctor(..), _)
                 | Res::Def(DefKind::Union, _)
                 | Res::Def(DefKind::TyAlias, _)
-                | Res::Def(DefKind::AssociatedTy, _)
+                | Res::Def(DefKind::AssocTy, _)
                 | Res::SelfTy(..) => {
                     debug!("struct cmt_pat={:?} pat={:?}", cmt_pat, pat);
                     delegate.matched_pat(pat, &cmt_pat, match_mode);
index 103580a598fcd9cea61e1c2804894fc985bf3d46..034ef32aafe016cff8fec1816a9b735cfabcf580 100644 (file)
@@ -210,8 +210,8 @@ fn collect_item(&mut self, item_index: usize, item_def_id: DefId) {
 pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
     attrs.iter().find_map(|attr| Some(match attr {
         _ if attr.check_name(sym::lang) => (attr.value_str()?, attr.span),
-        _ if attr.check_name(sym::panic_handler) => (Symbol::intern("panic_impl"), attr.span),
-        _ if attr.check_name(sym::alloc_error_handler) => (Symbol::intern("oom"), attr.span),
+        _ if attr.check_name(sym::panic_handler) => (sym::panic_impl, attr.span),
+        _ if attr.check_name(sym::alloc_error_handler) => (sym::oom, attr.span),
         _ => return None,
     }))
 }
index c7f8cf684e6b16c28c56408e92bc55b1999da574..c6b544469b5fa6840e68f60cd7204c701ff5838c 100644 (file)
@@ -703,7 +703,7 @@ pub fn cat_res(&self,
             Res::Def(DefKind::Ctor(..), _)
             | Res::Def(DefKind::Const, _)
             | Res::Def(DefKind::ConstParam, _)
-            | Res::Def(DefKind::AssociatedConst, _)
+            | Res::Def(DefKind::AssocConst, _)
             | Res::Def(DefKind::Fn, _)
             | Res::Def(DefKind::Method, _)
             | Res::SelfCtor(..) => {
@@ -1316,7 +1316,7 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR
 
                 for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
                     let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2)
-                    let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string())));
+                    let interior = InteriorField(FieldIndex(i, sym::integer(i)));
                     let subcmt = Rc::new(
                         self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior));
                     self.cat_pattern_(subcmt, &subpat, op)?;
@@ -1363,7 +1363,7 @@ fn cat_pattern_<F>(&self, mut cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McR
                 };
                 for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
                     let subpat_ty = self.pat_ty_adjusted(&subpat)?; // see (*2)
-                    let interior = InteriorField(FieldIndex(i, Name::intern(&i.to_string())));
+                    let interior = InteriorField(FieldIndex(i, sym::integer(i)));
                     let subcmt = Rc::new(
                         self.cat_imm_interior(pat, cmt.clone(), subpat_ty, interior));
                     self.cat_pattern_(subcmt, &subpat, op)?;
index e58083b5b76267458e78f9ac7c35e359a7276709..c9835dbd5e78f22845da1bede2fdc8b225720755 100644 (file)
@@ -118,7 +118,7 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
                             // If this path leads to a constant, then we need to
                             // recurse into the constant to continue finding
                             // items that are reachable.
-                            Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssociatedConst, _) => {
+                            Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => {
                                 self.worklist.push(hir_id);
                             }
 
index fa4e8e3d4769d34e2645048a60402aac2ff1757b..3d78b9b6382b72f68791051a7f3e16ac71dfacfc 100644 (file)
@@ -658,12 +658,15 @@ pub fn early_free_scope<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
             // The lifetime was defined on node that doesn't own a body,
             // which in practice can only mean a trait or an impl, that
             // is the parent of a method, and that is enforced below.
-            assert_eq!(Some(param_owner_id), self.root_parent,
-                       "free_scope: {:?} not recognized by the \
-                        region scope tree for {:?} / {:?}",
-                       param_owner,
-                       self.root_parent.map(|id| tcx.hir().local_def_id_from_hir_id(id)),
-                       self.root_body.map(|hir_id| DefId::local(hir_id.owner)));
+            if Some(param_owner_id) != self.root_parent {
+                tcx.sess.delay_span_bug(
+                    DUMMY_SP,
+                    &format!("free_scope: {:?} not recognized by the \
+                              region scope tree for {:?} / {:?}",
+                             param_owner,
+                             self.root_parent.map(|id| tcx.hir().local_def_id_from_hir_id(id)),
+                             self.root_body.map(|hir_id| DefId::local(hir_id.owner))));
+            }
 
             // The trait/impl lifetime is in scope for the method's body.
             self.root_body.unwrap().local_id
index 775da1de313fa0956286240569006e739022d4d9..736b4633b38f9865eeeaaf573b0857e9b8c23896 100644 (file)
@@ -1924,7 +1924,7 @@ fn visit_segment_args(&mut self, res: Res, depth: usize, generic_args: &'tcx hir
             }
         };
         let type_def_id = match res {
-            Res::Def(DefKind::AssociatedTy, def_id)
+            Res::Def(DefKind::AssocTy, def_id)
                 if depth == 1 => Some(parent_def_id(self, def_id)),
             Res::Def(DefKind::Variant, def_id)
                 if depth == 0 => Some(parent_def_id(self, def_id)),
@@ -2112,7 +2112,7 @@ fn visit_fn_like_elision(&mut self, inputs: &'tcx [hir::Ty], output: Option<&'tc
         };
 
         let has_self = match assoc_item_kind {
-            Some(hir::AssociatedItemKind::Method { has_self }) => has_self,
+            Some(hir::AssocItemKind::Method { has_self }) => has_self,
             _ => false,
         };
 
index ac0e99137cbc3ea68f76f7affc21f4d991347ffe..b81a4538d971dd9c58079682c9aeab68bdf9bb09 100644 (file)
@@ -437,7 +437,7 @@ pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Index<'tcx> {
                         reason: Some(Symbol::intern(reason)),
                         issue: 27812,
                     },
-                    feature: Symbol::intern("rustc_private"),
+                    feature: sym::rustc_private,
                     rustc_depr: None,
                     const_stability: None,
                     promotable: false,
@@ -527,8 +527,8 @@ fn skip_stability_check_due_to_privacy(self, mut def_id: DefId) -> bool {
         // Check if `def_id` is a trait method.
         match self.def_kind(def_id) {
             Some(DefKind::Method) |
-            Some(DefKind::AssociatedTy) |
-            Some(DefKind::AssociatedConst) => {
+            Some(DefKind::AssocTy) |
+            Some(DefKind::AssocConst) => {
                 if let ty::TraitContainer(trait_def_id) = self.associated_item(def_id).container {
                     // Trait methods do not declare visibility (even
                     // for visibility info in cstore). Use containing
@@ -880,7 +880,7 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     // FIXME: only remove `libc` when `stdbuild` is active.
     // FIXME: remove special casing for `test`.
     remaining_lib_features.remove(&Symbol::intern("libc"));
-    remaining_lib_features.remove(&Symbol::intern("test"));
+    remaining_lib_features.remove(&sym::test);
 
     let check_features =
         |remaining_lib_features: &mut FxHashMap<_, _>, defined_features: &[_]| {
index ca5feaee12ee4f6f903a6bdb0091de76a18a1231..0e2da4c577205010a32689fb2f584ce904d489b2 100644 (file)
@@ -7,7 +7,7 @@
 
 use crate::ty::layout::{Size, Align};
 use syntax::ast::Mutability;
-use std::iter;
+use std::{iter, fmt::{self, Display}};
 use crate::mir;
 use std::ops::{Deref, DerefMut};
 use rustc_data_structures::sorted_map::SortedMap;
@@ -22,6 +22,28 @@ pub enum InboundsCheck {
     MaybeDead,
 }
 
+/// Used by `check_in_alloc` to indicate context of check
+#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
+pub enum CheckInAllocMsg {
+    MemoryAccessTest,
+    NullPointerTest,
+    PointerArithmeticTest,
+    InboundsTest,
+}
+
+impl Display for CheckInAllocMsg {
+    /// When this is printed as an error the context looks like this
+    /// "{test name} failed: pointer must be in-bounds at offset..."
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", match *self {
+            CheckInAllocMsg::MemoryAccessTest => "Memory access",
+            CheckInAllocMsg::NullPointerTest => "Null pointer test",
+            CheckInAllocMsg::PointerArithmeticTest => "Pointer arithmetic",
+            CheckInAllocMsg::InboundsTest => "Inbounds test",
+        })
+    }
+}
+
 #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
 pub struct Allocation<Tag=(),Extra=()> {
     /// The actual bytes of the allocation.
@@ -131,9 +153,10 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
     fn check_bounds_ptr(
         &self,
         ptr: Pointer<Tag>,
+        msg: CheckInAllocMsg,
     ) -> EvalResult<'tcx> {
         let allocation_size = self.bytes.len() as u64;
-        ptr.check_in_alloc(Size::from_bytes(allocation_size), InboundsCheck::Live)
+        ptr.check_in_alloc(Size::from_bytes(allocation_size), msg)
     }
 
     /// Checks if the memory range beginning at `ptr` and of size `Size` is "in-bounds".
@@ -143,9 +166,10 @@ pub fn check_bounds(
         cx: &impl HasDataLayout,
         ptr: Pointer<Tag>,
         size: Size,
+        msg: CheckInAllocMsg,
     ) -> EvalResult<'tcx> {
         // if ptr.offset is in bounds, then so is ptr (because offset checks for overflow)
-        self.check_bounds_ptr(ptr.offset(size, cx)?)
+        self.check_bounds_ptr(ptr.offset(size, cx)?, msg)
     }
 }
 
@@ -164,9 +188,10 @@ fn get_bytes_internal(
         ptr: Pointer<Tag>,
         size: Size,
         check_defined_and_ptr: bool,
+        msg: CheckInAllocMsg,
     ) -> EvalResult<'tcx, &[u8]>
     {
-        self.check_bounds(cx, ptr, size)?;
+        self.check_bounds(cx, ptr, size, msg)?;
 
         if check_defined_and_ptr {
             self.check_defined(ptr, size)?;
@@ -192,7 +217,7 @@ pub fn get_bytes(
         size: Size,
     ) -> EvalResult<'tcx, &[u8]>
     {
-        self.get_bytes_internal(cx, ptr, size, true)
+        self.get_bytes_internal(cx, ptr, size, true, CheckInAllocMsg::MemoryAccessTest)
     }
 
     /// It is the caller's responsibility to handle undefined and pointer bytes.
@@ -205,7 +230,7 @@ pub fn get_bytes_with_undef_and_ptr(
         size: Size,
     ) -> EvalResult<'tcx, &[u8]>
     {
-        self.get_bytes_internal(cx, ptr, size, false)
+        self.get_bytes_internal(cx, ptr, size, false, CheckInAllocMsg::MemoryAccessTest)
     }
 
     /// Just calling this already marks everything as defined and removes relocations,
@@ -218,7 +243,7 @@ pub fn get_bytes_mut(
     ) -> EvalResult<'tcx, &mut [u8]>
     {
         assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`");
-        self.check_bounds(cx, ptr, size)?;
+        self.check_bounds(cx, ptr, size, CheckInAllocMsg::MemoryAccessTest)?;
 
         self.mark_definedness(ptr, size, true)?;
         self.clear_relocations(cx, ptr, size)?;
index 5c6fc6f49f0f0091bf8f144d42d00c5a3ebf9cf3..ac7c07c366d5105c0cd51660f30fb2fb678ab8a9 100644 (file)
@@ -8,7 +8,7 @@
 use rustc_target::spec::abi::Abi;
 use rustc_macros::HashStable;
 
-use super::{RawConst, Pointer, InboundsCheck, ScalarMaybeUndef};
+use super::{RawConst, Pointer, CheckInAllocMsg, ScalarMaybeUndef};
 
 use backtrace::Backtrace;
 
@@ -38,7 +38,7 @@ pub fn assert_reported(self) {
 }
 
 pub type ConstEvalRawResult<'tcx> = Result<RawConst<'tcx>, ErrorHandled>;
-pub type ConstEvalResult<'tcx> = Result<ty::Const<'tcx>, ErrorHandled>;
+pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
 
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct ConstEvalErr<'tcx> {
@@ -247,7 +247,7 @@ pub enum InterpError<'tcx, O> {
     InvalidDiscriminant(ScalarMaybeUndef),
     PointerOutOfBounds {
         ptr: Pointer,
-        check: InboundsCheck,
+        msg: CheckInAllocMsg,
         allocation_size: Size,
     },
     InvalidNullPointerUsage,
@@ -466,14 +466,10 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         use self::InterpError::*;
         match *self {
-            PointerOutOfBounds { ptr, check, allocation_size } => {
-                write!(f, "Pointer must be in-bounds{} at offset {}, but is outside bounds of \
-                           allocation {} which has size {}",
-                       match check {
-                           InboundsCheck::Live => " and live",
-                           InboundsCheck::MaybeDead => "",
-                       },
-                       ptr.offset.bytes(), ptr.alloc_id, allocation_size.bytes())
+            PointerOutOfBounds { ptr, msg, allocation_size } => {
+                write!(f, "{} failed: pointer must be in-bounds at offset {}, \
+                          but is outside bounds of allocation {} which has size {}",
+                    msg, ptr.offset.bytes(), ptr.alloc_id, allocation_size.bytes())
             },
             ValidationFailure(ref err) => {
                 write!(f, "type validation failed: {}", err)
index 2c619a7a25027efd7e6128f920e700cbc8adfa2c..595ea8bd34687c6451960d1e7e407b98ba064563 100644 (file)
@@ -19,7 +19,7 @@ macro_rules! err {
 
 pub use self::allocation::{
     InboundsCheck, Allocation, AllocationExtra,
-    Relocations, UndefMask,
+    Relocations, UndefMask, CheckInAllocMsg,
 };
 
 pub use self::pointer::{Pointer, PointerArithmetic};
index 59b7891b90fde918284e32a82dfdf68ffa0aeeec..9422abc4e6f715e8f9e52b950bdbd22282714301 100644 (file)
@@ -1,9 +1,11 @@
+use std::fmt;
+
 use crate::mir;
 use crate::ty::layout::{self, HasDataLayout, Size};
 use rustc_macros::HashStable;
 
 use super::{
-    AllocId, EvalResult, InboundsCheck,
+    AllocId, EvalResult, CheckInAllocMsg
 };
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -70,7 +72,7 @@ impl<T: layout::HasDataLayout> PointerArithmetic for T {}
 ///
 /// Pointer is also generic over the `Tag` associated with each pointer,
 /// which is used to do provenance tracking during execution.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd,
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd,
          RustcEncodable, RustcDecodable, Hash, HashStable)]
 pub struct Pointer<Tag=(),Id=AllocId> {
     pub alloc_id: Id,
@@ -80,6 +82,18 @@ pub struct Pointer<Tag=(),Id=AllocId> {
 
 static_assert_size!(Pointer, 16);
 
+impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Pointer<Tag, Id> {
+    default fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{:?}.{:#x}[{:?}]", self.alloc_id, self.offset.bytes(), self.tag)
+    }
+}
+// Specialization for no tag
+impl<Id: fmt::Debug> fmt::Debug for Pointer<(), Id> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{:?}.{:#x}", self.alloc_id, self.offset.bytes())
+    }
+}
+
 /// Produces a `Pointer` which points to the beginning of the Allocation
 impl From<AllocId> for Pointer {
     #[inline(always)]
@@ -163,12 +177,12 @@ pub fn erase_tag(self) -> Pointer {
     pub fn check_in_alloc(
         self,
         allocation_size: Size,
-        check: InboundsCheck,
+        msg: CheckInAllocMsg,
     ) -> EvalResult<'tcx, ()> {
         if self.offset > allocation_size {
             err!(PointerOutOfBounds {
                 ptr: self.erase_tag(),
-                check,
+                msg,
                 allocation_size,
             })
         } else {
index 551b86390db4c43d1e0a3253cf2a16c11776c2ae..72545f23f8e2bf3ac67a39ebef68f6afd60c0e76 100644 (file)
@@ -35,14 +35,12 @@ pub enum ConstValue<'tcx> {
     /// Not using the enum `Value` to encode that this must not be `Undef`.
     Scalar(Scalar),
 
-    /// Used only for slices and strings (`&[T]`, `&str`, `*const [T]`, `*mut str`, `Box<str>`,
-    /// etc.).
-    ///
-    /// Empty slices don't necessarily have an address backed by an `AllocId`, thus we also need to
-    /// enable integer pointers. The `Scalar` type covers exactly those two cases. While we could
-    /// create dummy-`AllocId`s, the additional code effort for the conversions doesn't seem worth
-    /// it.
-    Slice(Scalar, u64),
+    /// Used only for `&[u8]` and `&str`
+    Slice {
+        data: &'tcx Allocation,
+        start: usize,
+        end: usize,
+    },
 
     /// An allocation together with a pointer into the allocation.
     /// Invariant: the pointer's `AllocId` resolves to the allocation.
@@ -54,7 +52,7 @@ pub enum ConstValue<'tcx> {
 }
 
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(ConstValue<'_>, 40);
+static_assert_size!(ConstValue<'_>, 32);
 
 impl<'tcx> ConstValue<'tcx> {
     #[inline]
@@ -65,7 +63,7 @@ pub fn try_to_scalar(&self) -> Option<Scalar> {
             ConstValue::Placeholder(_) |
             ConstValue::ByRef(..) |
             ConstValue::Unevaluated(..) |
-            ConstValue::Slice(..) => None,
+            ConstValue::Slice { .. } => None,
             ConstValue::Scalar(val) => Some(val),
         }
     }
@@ -79,21 +77,13 @@ pub fn try_to_bits(&self, size: Size) -> Option<u128> {
     pub fn try_to_ptr(&self) -> Option<Pointer> {
         self.try_to_scalar()?.to_ptr().ok()
     }
-
-    #[inline]
-    pub fn new_slice(
-        val: Scalar,
-        len: u64,
-    ) -> Self {
-        ConstValue::Slice(val, len)
-    }
 }
 
 /// A `Scalar` represents an immediate, primitive value existing outside of a
 /// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 8 bytes in
 /// size. Like a range of bytes in an `Allocation`, a `Scalar` can either represent the raw bytes
 /// of a simple value or a pointer into another `Allocation`
-#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd,
+#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd,
          RustcEncodable, RustcDecodable, Hash, HashStable)]
 pub enum Scalar<Tag=(), Id=AllocId> {
     /// The raw bytes of a simple value.
@@ -113,6 +103,27 @@ pub enum Scalar<Tag=(), Id=AllocId> {
 #[cfg(target_arch = "x86_64")]
 static_assert_size!(Scalar, 24);
 
+impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Scalar<Tag, Id> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Scalar::Ptr(ptr) =>
+                write!(f, "{:?}", ptr),
+            &Scalar::Bits { bits, size } => {
+                if size == 0 {
+                    assert_eq!(bits, 0, "ZST value must be 0");
+                    write!(f, "<ZST>")
+                } else {
+                    assert_eq!(truncate(bits, Size::from_bytes(size as u64)), bits,
+                            "Scalar value {:#x} exceeds size of {} bytes", bits, size);
+                    // Format as hex number wide enough to fit any value of the given `size`.
+                    // So bits=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014".
+                    write!(f, "0x{:>0width$x}", bits, width=(size*2) as usize)
+                }
+            }
+        }
+    }
+}
+
 impl<Tag> fmt::Display for Scalar<Tag> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
@@ -412,7 +423,7 @@ fn from(ptr: Pointer<Tag>) -> Self {
     }
 }
 
-#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
 pub enum ScalarMaybeUndef<Tag=(), Id=AllocId> {
     Scalar(Scalar<Tag, Id>),
     Undef,
@@ -425,6 +436,15 @@ fn from(s: Scalar<Tag>) -> Self {
     }
 }
 
+impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for ScalarMaybeUndef<Tag, Id> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            ScalarMaybeUndef::Undef => write!(f, "Undef"),
+            ScalarMaybeUndef::Scalar(s) => write!(f, "{:?}", s),
+        }
+    }
+}
+
 impl<Tag> fmt::Display for ScalarMaybeUndef<Tag> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
index 6de4350c2aa988ad2eddebc850aec65bd685ca54..84aff8101a09d99c3ed55111ba46572bc30ad713 100644 (file)
@@ -9,8 +9,6 @@
 use crate::hir::{self, InlineAsm as HirInlineAsm};
 use crate::mir::interpret::{ConstValue, InterpError, Scalar};
 use crate::mir::visit::MirVisitable;
-use rustc_apfloat::ieee::{Double, Single};
-use rustc_apfloat::Float;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::graph::dominators::{dominators, Dominators};
 use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors};
 use crate::rustc_serialize::{self as serialize};
 use smallvec::SmallVec;
 use std::borrow::Cow;
-use std::fmt::{self, Debug, Formatter, Write};
+use std::fmt::{self, Debug, Formatter, Write, Display};
 use std::iter::FusedIterator;
 use std::ops::{Index, IndexMut};
 use std::slice;
 use std::vec::IntoIter;
 use std::{iter, mem, option, u32};
-use syntax::ast::{self, Name};
+use syntax::ast::Name;
 use syntax::symbol::{InternedString, Symbol};
 use syntax_pos::{Span, DUMMY_SP};
 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
@@ -1662,28 +1660,25 @@ pub fn fmt_successor_labels(&self) -> Vec<Cow<'static, str>> {
                 switch_ty,
                 ..
             } => {
-                let size = ty::tls::with(|tcx| {
+                ty::tls::with(|tcx| {
                     let param_env = ty::ParamEnv::empty();
                     let switch_ty = tcx.lift_to_global(&switch_ty).unwrap();
-                    tcx.layout_of(param_env.and(switch_ty)).unwrap().size
-                });
-                values
-                    .iter()
-                    .map(|&u| {
-                        let mut s = String::new();
-                        let c = ty::Const {
-                            val: ConstValue::Scalar(
-                                Scalar::Bits {
-                                    bits: u,
-                                    size: size.bytes() as u8,
-                                }.into(),
-                            ),
-                            ty: switch_ty,
-                        };
-                        fmt_const_val(&mut s, c).unwrap();
-                        s.into()
-                    }).chain(iter::once("otherwise".into()))
-                    .collect()
+                    let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size;
+                    values
+                        .iter()
+                        .map(|&u| {
+                            tcx.mk_const(ty::Const {
+                                val: ConstValue::Scalar(
+                                    Scalar::Bits {
+                                        bits: u,
+                                        size: size.bytes() as u8,
+                                    }.into(),
+                                ),
+                                ty: switch_ty,
+                            }).to_string().into()
+                        }).chain(iter::once("otherwise".into()))
+                        .collect()
+                })
             }
             Call {
                 destination: Some(_),
@@ -2331,9 +2326,7 @@ pub fn function_handle<'a>(
             span,
             ty,
             user_ty: None,
-            literal: tcx.mk_const(
-                ty::Const::zero_sized(ty),
-            ),
+            literal: ty::Const::zero_sized(tcx, ty),
         })
     }
 
@@ -2827,67 +2820,15 @@ pub struct Promoted {
 
 impl<'tcx> Debug for Constant<'tcx> {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
-        write!(fmt, "const ")?;
-        fmt_const_val(fmt, *self.literal)
-    }
-}
-/// Write a `ConstValue` in a way closer to the original source code than the `Debug` output.
-pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Result {
-    use crate::ty::TyKind::*;
-    let value = const_val.val;
-    let ty = const_val.ty;
-    // print some primitives
-    if let ConstValue::Scalar(Scalar::Bits { bits, .. }) = value {
-        match ty.sty {
-            Bool if bits == 0 => return write!(f, "false"),
-            Bool if bits == 1 => return write!(f, "true"),
-            Float(ast::FloatTy::F32) => return write!(f, "{}f32", Single::from_bits(bits)),
-            Float(ast::FloatTy::F64) => return write!(f, "{}f64", Double::from_bits(bits)),
-            Uint(ui) => return write!(f, "{:?}{}", bits, ui),
-            Int(i) => {
-                let bit_width = ty::tls::with(|tcx| {
-                    let ty = tcx.lift_to_global(&ty).unwrap();
-                    tcx.layout_of(ty::ParamEnv::empty().and(ty))
-                        .unwrap()
-                        .size
-                        .bits()
-                });
-                let shift = 128 - bit_width;
-                return write!(f, "{:?}{}", ((bits as i128) << shift) >> shift, i);
-            }
-            Char => return write!(f, "{:?}", ::std::char::from_u32(bits as u32).unwrap()),
-            _ => {}
-        }
+        write!(fmt, "{}", self)
     }
-    // print function definitions
-    if let FnDef(did, _) = ty.sty {
-        return write!(f, "{}", def_path_str(did));
-    }
-    // print string literals
-    if let ConstValue::Slice(ptr, len) = value {
-        if let Scalar::Ptr(ptr) = ptr {
-            if let Ref(_, &ty::TyS { sty: Str, .. }, _) = ty.sty {
-                return ty::tls::with(|tcx| {
-                    let alloc = tcx.alloc_map.lock().get(ptr.alloc_id);
-                    if let Some(interpret::AllocKind::Memory(alloc)) = alloc {
-                        assert_eq!(len as usize as u64, len);
-                        let slice =
-                            &alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
-                        let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri");
-                        write!(f, "{:?}", s)
-                    } else {
-                        write!(f, "pointer to erroneous constant {:?}, {:?}", ptr, len)
-                    }
-                });
-            }
-        }
-    }
-    // just raw dump everything else
-    write!(f, "{:?} : {}", value, ty)
 }
 
-fn def_path_str(def_id: DefId) -> String {
-    ty::tls::with(|tcx| tcx.def_path_str(def_id))
+impl<'tcx> Display for Constant<'tcx> {
+    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
+        write!(fmt, "const ")?;
+        write!(fmt, "{}", self.literal)
+    }
 }
 
 impl<'tcx> graph::DirectedGraph for Mir<'tcx> {
index c03cd7e268ef5ceed3e20e678624516bf12ed3fc..ed363800d79def6c82d5fb5efecd28663981ec0f 100644 (file)
         query associated_item_def_ids(_: DefId) -> &'tcx [DefId] {}
 
         /// Maps from a trait item to the trait item "descriptor".
-        query associated_item(_: DefId) -> ty::AssociatedItem {}
+        query associated_item(_: DefId) -> ty::AssocItem {}
 
         query impl_trait_ref(_: DefId) -> Option<ty::TraitRef<'tcx>> {}
         query impl_polarity(_: DefId) -> hir::ImplPolarity {}
index f16137bd2c27ade42d3d91d35403cbd5ae0b04d9..f4ee39d69883c5d933eb7926930d123bcf2c21aa 100644 (file)
@@ -19,7 +19,7 @@
 use syntax::edition::{Edition, EDITION_NAME_LIST, DEFAULT_EDITION};
 use syntax::parse::token;
 use syntax::parse;
-use syntax::symbol::Symbol;
+use syntax::symbol::{sym, Symbol};
 use syntax::feature_gate::UnstableFeatures;
 use errors::emitter::HumanReadableErrorType;
 
@@ -117,16 +117,16 @@ pub fn enabled(&self) -> bool {
 }
 
 #[derive(Clone, PartialEq, Hash)]
-pub enum PgoGenerate {
+pub enum SwitchWithOptPath {
     Enabled(Option<PathBuf>),
     Disabled,
 }
 
-impl PgoGenerate {
+impl SwitchWithOptPath {
     pub fn enabled(&self) -> bool {
         match *self {
-            PgoGenerate::Enabled(_) => true,
-            PgoGenerate::Disabled => false,
+            SwitchWithOptPath::Enabled(_) => true,
+            SwitchWithOptPath::Disabled => false,
         }
     }
 }
@@ -834,7 +834,7 @@ mod $mod_desc {
         pub const parse_linker_plugin_lto: Option<&str> =
             Some("either a boolean (`yes`, `no`, `on`, `off`, etc), \
                   or the path to the linker plugin");
-        pub const parse_pgo_generate: Option<&str> =
+        pub const parse_switch_with_opt_path: Option<&str> =
             Some("an optional path to the profiling data output directory");
         pub const parse_merge_functions: Option<&str> =
             Some("one of: `disabled`, `trampolines`, or `aliases`");
@@ -842,7 +842,7 @@ mod $mod_desc {
 
     #[allow(dead_code)]
     mod $mod_set {
-        use super::{$struct_name, Passes, Sanitizer, LtoCli, LinkerPluginLto, PgoGenerate};
+        use super::{$struct_name, Passes, Sanitizer, LtoCli, LinkerPluginLto, SwitchWithOptPath};
         use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel};
         use std::path::PathBuf;
         use std::str::FromStr;
@@ -1097,10 +1097,10 @@ fn parse_linker_plugin_lto(slot: &mut LinkerPluginLto, v: Option<&str>) -> bool
             true
         }
 
-        fn parse_pgo_generate(slot: &mut PgoGenerate, v: Option<&str>) -> bool {
+        fn parse_switch_with_opt_path(slot: &mut SwitchWithOptPath, v: Option<&str>) -> bool {
             *slot = match v {
-                None => PgoGenerate::Enabled(None),
-                Some(path) => PgoGenerate::Enabled(Some(PathBuf::from(path))),
+                None => SwitchWithOptPath::Enabled(None),
+                Some(path) => SwitchWithOptPath::Enabled(Some(PathBuf::from(path))),
             };
             true
         }
@@ -1379,9 +1379,10 @@ fn parse_merge_functions(slot: &mut Option<MergeFunctions>, v: Option<&str>) ->
         "extra arguments to prepend to the linker invocation (space separated)"),
     profile: bool = (false, parse_bool, [TRACKED],
                      "insert profiling code"),
-    pgo_gen: PgoGenerate = (PgoGenerate::Disabled, parse_pgo_generate, [TRACKED],
+    pgo_gen: SwitchWithOptPath = (SwitchWithOptPath::Disabled,
+        parse_switch_with_opt_path, [TRACKED],
         "Generate PGO profile data, to a given file, or to the default location if it's empty."),
-    pgo_use: String = (String::new(), parse_string, [TRACKED],
+    pgo_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
         "Use PGO profile data from the given profile file."),
     disable_instrumentation_preinliner: bool = (false, parse_bool, [TRACKED],
         "Disable the instrumentation pre-inliner, useful for profiling / PGO."),
@@ -1447,7 +1448,8 @@ fn parse_merge_functions(slot: &mut Option<MergeFunctions>, v: Option<&str>) ->
         "don't interleave execution of lints; allows benchmarking individual lints"),
     crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED],
         "inject the given attribute in the crate"),
-    self_profile: bool = (false, parse_bool, [UNTRACKED],
+    self_profile: SwitchWithOptPath = (SwitchWithOptPath::Disabled,
+        parse_switch_with_opt_path, [UNTRACKED],
         "run the self profiler and output the raw event data"),
     self_profile_events: Option<Vec<String>> = (None, parse_opt_comma_list, [UNTRACKED],
         "specifies which kinds of events get recorded by the self profiler"),
@@ -1503,31 +1505,31 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
         Some(Symbol::intern(vendor)),
     ));
     if sess.target.target.options.has_elf_tls {
-        ret.insert((Symbol::intern("target_thread_local"), None));
+        ret.insert((sym::target_thread_local, None));
     }
     for &i in &[8, 16, 32, 64, 128] {
         if i >= min_atomic_width && i <= max_atomic_width {
             let s = i.to_string();
             ret.insert((
-                Symbol::intern("target_has_atomic"),
+                sym::target_has_atomic,
                 Some(Symbol::intern(&s)),
             ));
             if &s == wordsz {
                 ret.insert((
-                    Symbol::intern("target_has_atomic"),
+                    sym::target_has_atomic,
                     Some(Symbol::intern("ptr")),
                 ));
             }
         }
     }
     if atomic_cas {
-        ret.insert((Symbol::intern("target_has_atomic"), Some(Symbol::intern("cas"))));
+        ret.insert((sym::target_has_atomic, Some(Symbol::intern("cas"))));
     }
     if sess.opts.debug_assertions {
         ret.insert((Symbol::intern("debug_assertions"), None));
     }
     if sess.opts.crate_types.contains(&CrateType::ProcMacro) {
-        ret.insert((Symbol::intern("proc_macro"), None));
+        ret.insert((sym::proc_macro, None));
     }
     ret
 }
@@ -1547,7 +1549,7 @@ pub fn build_configuration(sess: &Session, mut user_cfg: ast::CrateConfig) -> as
     let default_cfg = default_configuration(sess);
     // If the user wants a test runner, then add the test cfg
     if sess.opts.test {
-        user_cfg.insert((Symbol::intern("test"), None));
+        user_cfg.insert((sym::test, None));
     }
     user_cfg.extend(default_cfg.iter().cloned());
     user_cfg
@@ -2021,7 +2023,7 @@ pub fn build_session_options_and_crate_config(
         }
     }
 
-    if debugging_opts.pgo_gen.enabled() && !debugging_opts.pgo_use.is_empty() {
+    if debugging_opts.pgo_gen.enabled() && debugging_opts.pgo_use.is_some() {
         early_error(
             error_format,
             "options `-Z pgo-gen` and `-Z pgo-use` are exclusive",
@@ -2558,7 +2560,7 @@ mod dep_tracking {
     use std::path::PathBuf;
     use std::collections::hash_map::DefaultHasher;
     use super::{CrateType, DebugInfo, ErrorOutputType, OptLevel, OutputTypes,
-                Passes, Sanitizer, LtoCli, LinkerPluginLto, PgoGenerate};
+                Passes, Sanitizer, LtoCli, LinkerPluginLto, SwitchWithOptPath};
     use syntax::feature_gate::UnstableFeatures;
     use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel, TargetTriple};
     use syntax::edition::Edition;
@@ -2626,7 +2628,7 @@ fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) {
     impl_dep_tracking_hash_via_hash!(TargetTriple);
     impl_dep_tracking_hash_via_hash!(Edition);
     impl_dep_tracking_hash_via_hash!(LinkerPluginLto);
-    impl_dep_tracking_hash_via_hash!(PgoGenerate);
+    impl_dep_tracking_hash_via_hash!(SwitchWithOptPath);
 
     impl_dep_tracking_hash_for_sortable_vec_of!(String);
     impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);
@@ -2694,7 +2696,7 @@ mod tests {
         build_session_options_and_crate_config,
         to_crate_config
     };
-    use crate::session::config::{LtoCli, LinkerPluginLto, PgoGenerate, ExternEntry};
+    use crate::session::config::{LtoCli, LinkerPluginLto, SwitchWithOptPath, ExternEntry};
     use crate::session::build_session;
     use crate::session::search_paths::SearchPath;
     use std::collections::{BTreeMap, BTreeSet};
@@ -2702,7 +2704,7 @@ mod tests {
     use std::path::PathBuf;
     use super::{Externs, OutputType, OutputTypes};
     use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel};
-    use syntax::symbol::Symbol;
+    use syntax::symbol::sym;
     use syntax::edition::{Edition, DEFAULT_EDITION};
     use syntax;
     use super::Options;
@@ -2744,7 +2746,7 @@ fn test_switch_implies_cfg_test() {
             let (sessopts, cfg) = build_session_options_and_crate_config(matches);
             let sess = build_session(sessopts, None, registry);
             let cfg = build_configuration(&sess, to_crate_config(cfg));
-            assert!(cfg.contains(&(Symbol::intern("test"), None)));
+            assert!(cfg.contains(&(sym::test, None)));
         });
     }
 
@@ -2752,7 +2754,6 @@ fn test_switch_implies_cfg_test() {
     // another --cfg test
     #[test]
     fn test_switch_implies_cfg_test_unless_cfg_test() {
-        use syntax::symbol::sym;
         syntax::with_default_globals(|| {
             let matches = &match optgroups().parse(&["--test".to_string(),
                                                      "--cfg=test".to_string()]) {
@@ -3208,11 +3209,11 @@ fn test_codegen_options_tracking_hash() {
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
         opts = reference.clone();
-        opts.debugging_opts.pgo_gen = PgoGenerate::Enabled(None);
+        opts.debugging_opts.pgo_gen = SwitchWithOptPath::Enabled(None);
         assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
 
         opts = reference.clone();
-        opts.debugging_opts.pgo_use = String::from("abc");
+        opts.debugging_opts.pgo_use = Some(PathBuf::from("abc"));
         assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
 
         opts = reference.clone();
index 4d47491661e8639fba50b6752de90e7eaa5bae4d..974a5bb70e65300ba298b939e1eddbd6f9ae5793 100644 (file)
@@ -9,7 +9,7 @@
 use crate::lint::builtin::BuiltinLintDiagnostics;
 use crate::middle::allocator::AllocatorKind;
 use crate::middle::dependency_format;
-use crate::session::config::OutputType;
+use crate::session::config::{OutputType, SwitchWithOptPath};
 use crate::session::search_paths::{PathKind, SearchPath};
 use crate::util::nodemap::{FxHashMap, FxHashSet};
 use crate::util::common::{duration_to_secs_str, ErrorReported};
@@ -1137,8 +1137,18 @@ fn build_session_(
     driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
 ) -> Session {
     let self_profiler =
-        if sopts.debugging_opts.self_profile {
-            let profiler = SelfProfiler::new(&sopts.debugging_opts.self_profile_events);
+        if let SwitchWithOptPath::Enabled(ref d) = sopts.debugging_opts.self_profile {
+            let directory = if let Some(ref directory) = d {
+                directory
+            } else {
+                std::path::Path::new(".")
+            };
+
+            let profiler = SelfProfiler::new(
+                directory,
+                sopts.crate_name.as_ref().map(|s| &s[..]),
+                &sopts.debugging_opts.self_profile_events
+            );
             match profiler {
                 Ok(profiler) => {
                     crate::ty::query::QueryName::register_with_profiler(&profiler);
@@ -1272,6 +1282,15 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
         sess.err("Linker plugin based LTO is not supported together with \
                   `-C prefer-dynamic` when targeting MSVC");
     }
+
+    // Make sure that any given profiling data actually exists so LLVM can't
+    // decide to silently skip PGO.
+    if let Some(ref path) = sess.opts.debugging_opts.pgo_use {
+        if !path.exists() {
+            sess.err(&format!("File `{}` passed to `-Zpgo-use` does not exist.",
+                              path.display()));
+        }
+    }
 }
 
 /// Hash value constructed out of all the `-C metadata` arguments passed to the
index a4b9ed0a206b91a74f3c0e9ca21eca8d548a4459..4b555e54f397da8e3581262b9527208e2168a097 100644 (file)
@@ -993,7 +993,7 @@ fn vtable_methods<'a, 'tcx>(
     tcx.arena.alloc_from_iter(
         supertraits(tcx, trait_ref).flat_map(move |trait_ref| {
             let trait_methods = tcx.associated_items(trait_ref.def_id())
-                .filter(|item| item.kind == ty::AssociatedKind::Method);
+                .filter(|item| item.kind == ty::AssocKind::Method);
 
             // Now list each method's DefId and InternalSubsts (for within its trait).
             // If the method can never be called from this object, produce None.
index 55216f644a180626fdf1eb15369ce64999fe8c1a..5006ff75667e8c7655049985eccd18551c6dbd18 100644 (file)
@@ -35,7 +35,7 @@ pub enum ObjectSafetyViolation {
     Method(ast::Name, MethodViolationCode),
 
     /// Associated const.
-    AssociatedConst(ast::Name),
+    AssocConst(ast::Name),
 }
 
 impl ObjectSafetyViolation {
@@ -58,7 +58,7 @@ pub fn error_msg(&self) -> Cow<'static, str> {
                 format!("method `{}` has generic type parameters", name).into(),
             ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver) =>
                 format!("method `{}`'s receiver cannot be dispatched on", name).into(),
-            ObjectSafetyViolation::AssociatedConst(name) =>
+            ObjectSafetyViolation::AssocConst(name) =>
                 format!("the trait cannot contain associated consts like `{}`", name).into(),
         }
     }
@@ -119,7 +119,7 @@ fn object_safety_violations_for_trait(self, trait_def_id: DefId)
     {
         // Check methods for violations.
         let mut violations: Vec<_> = self.associated_items(trait_def_id)
-            .filter(|item| item.kind == ty::AssociatedKind::Method)
+            .filter(|item| item.kind == ty::AssocKind::Method)
             .filter_map(|item|
                 self.object_safety_violation_for_method(trait_def_id, &item)
                     .map(|code| ObjectSafetyViolation::Method(item.ident.name, code))
@@ -151,8 +151,8 @@ fn object_safety_violations_for_trait(self, trait_def_id: DefId)
         }
 
         violations.extend(self.associated_items(trait_def_id)
-            .filter(|item| item.kind == ty::AssociatedKind::Const)
-            .map(|item| ObjectSafetyViolation::AssociatedConst(item.ident.name)));
+            .filter(|item| item.kind == ty::AssocKind::Const)
+            .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name)));
 
         debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
                trait_def_id,
@@ -251,7 +251,7 @@ fn generics_require_sized_self(self, def_id: DefId) -> bool {
     /// Returns `Some(_)` if this method makes the containing trait not object safe.
     fn object_safety_violation_for_method(self,
                                           trait_def_id: DefId,
-                                          method: &ty::AssociatedItem)
+                                          method: &ty::AssocItem)
                                           -> Option<MethodViolationCode>
     {
         debug!("object_safety_violation_for_method({:?}, {:?})", trait_def_id, method);
@@ -270,7 +270,7 @@ fn object_safety_violation_for_method(self,
     /// otherwise ensure that they cannot be used when `Self=Trait`.
     pub fn is_vtable_safe_method(self,
                                  trait_def_id: DefId,
-                                 method: &ty::AssociatedItem)
+                                 method: &ty::AssocItem)
                                  -> bool
     {
         debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method);
@@ -291,7 +291,7 @@ pub fn is_vtable_safe_method(self,
     /// `Self:Sized`.
     fn virtual_call_violation_for_method(self,
                                          trait_def_id: DefId,
-                                         method: &ty::AssociatedItem)
+                                         method: &ty::AssocItem)
                                          -> Option<MethodViolationCode>
     {
         // The method's first parameter must be named `self`
@@ -439,7 +439,7 @@ fn object_ty_for_trait(self, trait_def_id: DefId, lifetime: ty::Region<'tcx>) ->
                 self.associated_items(super_trait_ref.def_id())
                     .map(move |item| (super_trait_ref, item))
             })
-            .filter(|(_, item)| item.kind == ty::AssociatedKind::Type)
+            .filter(|(_, item)| item.kind == ty::AssocKind::Type)
             .collect::<Vec<_>>();
 
         // existential predicates need to be in a specific order
@@ -520,7 +520,7 @@ fn object_ty_for_trait(self, trait_def_id: DefId, lifetime: ty::Region<'tcx>) ->
     #[allow(dead_code)]
     fn receiver_is_dispatchable(
         self,
-        method: &ty::AssociatedItem,
+        method: &ty::AssocItem,
         receiver_ty: Ty<'tcx>,
     ) -> bool {
         debug!("receiver_is_dispatchable: method = {:?}, receiver_ty = {:?}", method, receiver_ty);
index f9ceeb5bfc01b373e22b615a6056481c0dfa729f..1c17ace90c2fbbc458f1ea4e8dab464da5e67ed7 100644 (file)
@@ -226,12 +226,12 @@ pub fn try_parse(tcx: TyCtxt<'a, 'gcx, 'tcx>,
         Ok(result)
     }
 
-    fn verify(&self,
-              tcx: TyCtxt<'a, 'gcx, 'tcx>,
-              trait_def_id: DefId,
-              span: Span)
-              -> Result<(), ErrorReported>
-    {
+    fn verify(
+        &self,
+        tcx: TyCtxt<'a, 'gcx, 'tcx>,
+        trait_def_id: DefId,
+        span: Span,
+    ) -> Result<(), ErrorReported> {
         let name = tcx.item_name(trait_def_id);
         let generics = tcx.generics_of(trait_def_id);
         let parser = Parser::new(&self.0, None, vec![], false);
@@ -272,12 +272,12 @@ fn verify(&self,
         result
     }
 
-    pub fn format(&self,
-                  tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                  trait_ref: ty::TraitRef<'tcx>,
-                  options: &FxHashMap<String, String>)
-                  -> String
-    {
+    pub fn format(
+        &self,
+        tcx: TyCtxt<'a, 'gcx, 'tcx>,
+        trait_ref: ty::TraitRef<'tcx>,
+        options: &FxHashMap<String, String>,
+    ) -> String {
         let name = tcx.item_name(trait_ref.def_id);
         let trait_str = tcx.def_path_str(trait_ref.def_id);
         let generics = tcx.generics_of(trait_ref.def_id);
index 67e76f7625ceee237c6ef5f5018603365ad80f83..92d5d4f03190313ef5952c51fee1cf7e45ef8e87 100644 (file)
@@ -275,7 +275,7 @@ pub fn normalize_with_depth<'a, 'b, 'gcx, 'tcx, T>(
     where T : TypeFoldable<'tcx>
 {
     debug!("normalize_with_depth(depth={}, value={:?})", depth, value);
-    let mut normalizer = AssociatedTypeNormalizer::new(selcx, param_env, cause, depth);
+    let mut normalizer = AssocTypeNormalizer::new(selcx, param_env, cause, depth);
     let result = normalizer.fold(value);
     debug!("normalize_with_depth: depth={} result={:?} with {} obligations",
            depth, result, normalizer.obligations.len());
@@ -287,7 +287,7 @@ pub fn normalize_with_depth<'a, 'b, 'gcx, 'tcx, T>(
     }
 }
 
-struct AssociatedTypeNormalizer<'a, 'b: 'a, 'gcx: 'b+'tcx, 'tcx: 'b> {
+struct AssocTypeNormalizer<'a, 'b: 'a, 'gcx: 'b+'tcx, 'tcx: 'b> {
     selcx: &'a mut SelectionContext<'b, 'gcx, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     cause: ObligationCause<'tcx>,
@@ -295,14 +295,14 @@ struct AssociatedTypeNormalizer<'a, 'b: 'a, 'gcx: 'b+'tcx, 'tcx: 'b> {
     depth: usize,
 }
 
-impl<'a, 'b, 'gcx, 'tcx> AssociatedTypeNormalizer<'a, 'b, 'gcx, 'tcx> {
+impl<'a, 'b, 'gcx, 'tcx> AssocTypeNormalizer<'a, 'b, 'gcx, 'tcx> {
     fn new(selcx: &'a mut SelectionContext<'b, 'gcx, 'tcx>,
            param_env: ty::ParamEnv<'tcx>,
            cause: ObligationCause<'tcx>,
            depth: usize)
-           -> AssociatedTypeNormalizer<'a, 'b, 'gcx, 'tcx>
+           -> AssocTypeNormalizer<'a, 'b, 'gcx, 'tcx>
     {
-        AssociatedTypeNormalizer {
+        AssocTypeNormalizer {
             selcx,
             param_env,
             cause,
@@ -322,7 +322,7 @@ fn fold<T:TypeFoldable<'tcx>>(&mut self, value: &T) -> T {
     }
 }
 
-impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a, 'b, 'gcx, 'tcx> {
+impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssocTypeNormalizer<'a, 'b, 'gcx, 'tcx> {
     fn tcx<'c>(&'c self) -> TyCtxt<'c, 'gcx, 'tcx> {
         self.selcx.tcx()
     }
@@ -388,7 +388,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                                                               self.cause.clone(),
                                                               self.depth,
                                                               &mut self.obligations);
-                debug!("AssociatedTypeNormalizer: depth={} normalized {:?} to {:?}, \
+                debug!("AssocTypeNormalizer: depth={} normalized {:?} to {:?}, \
                         now with {} obligations",
                        self.depth, ty, normalized_ty, self.obligations.len());
                 normalized_ty
@@ -412,7 +412,6 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc
                         };
                         if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
                             let substs = tcx.lift_to_global(&substs).unwrap();
-                            let evaluated = tcx.mk_const(evaluated);
                             let evaluated = evaluated.subst(tcx, substs);
                             return evaluated;
                         }
@@ -426,7 +425,7 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc
                                 promoted: None
                             };
                             if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
-                                return tcx.mk_const(evaluated);
+                                return evaluated;
                             }
                         }
                     }
@@ -636,7 +635,7 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
                    projected_obligations);
 
             let result = if projected_ty.has_projections() {
-                let mut normalizer = AssociatedTypeNormalizer::new(selcx,
+                let mut normalizer = AssocTypeNormalizer::new(selcx,
                                                                    param_env,
                                                                    cause,
                                                                    depth+1);
@@ -1497,7 +1496,7 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
         };
     }
     let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node);
-    let ty = if let ty::AssociatedKind::Existential = assoc_ty.item.kind {
+    let ty = if let ty::AssocKind::Existential = assoc_ty.item.kind {
         let item_substs = InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id);
         tcx.mk_opaque(assoc_ty.item.def_id, item_substs)
     } else {
@@ -1518,7 +1517,7 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>(
     selcx: &SelectionContext<'cx, 'gcx, 'tcx>,
     impl_def_id: DefId,
     assoc_ty_def_id: DefId)
-    -> specialization_graph::NodeItem<ty::AssociatedItem>
+    -> specialization_graph::NodeItem<ty::AssocItem>
 {
     let tcx = selcx.tcx();
     let assoc_ty_name = tcx.associated_item(assoc_ty_def_id).ident;
@@ -1533,7 +1532,7 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>(
     // cycle error if the specialization graph is currently being built.
     let impl_node = specialization_graph::Node::Impl(impl_def_id);
     for item in impl_node.items(tcx) {
-        if item.kind == ty::AssociatedKind::Type &&
+        if item.kind == ty::AssocKind::Type &&
                 tcx.hygienic_eq(item.ident, assoc_ty_name, trait_def_id) {
             return specialization_graph::NodeItem {
                 node: specialization_graph::Node::Impl(impl_def_id),
@@ -1544,7 +1543,7 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>(
 
     if let Some(assoc_item) = trait_def
         .ancestors(tcx, impl_def_id)
-        .defs(tcx, assoc_ty_name, ty::AssociatedKind::Type, trait_def_id)
+        .defs(tcx, assoc_ty_name, ty::AssocKind::Type, trait_def_id)
         .next() {
         assoc_item
     } else {
index 9940249da8ba92743b0598ff6f77a3435e9d7b66..d09a9c107869b603bbfd3f33f47cbc4847ed9809 100644 (file)
@@ -202,7 +202,6 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc
                         };
                         if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
                             let substs = tcx.lift_to_global(&substs).unwrap();
-                            let evaluated = tcx.mk_const(evaluated);
                             let evaluated = evaluated.subst(tcx, substs);
                             return evaluated;
                         }
@@ -216,7 +215,7 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc
                                 promoted: None,
                             };
                             if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
-                                return tcx.mk_const(evaluated);
+                                return evaluated;
                             }
                         }
                     }
index fdd1a821e31b56964bae3db7af15581bc05fd1a7..5da4a1b9c5f36f81e4206d52706117e67b00d316 100644 (file)
@@ -112,7 +112,7 @@ pub fn translate_substs<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
 pub fn find_associated_item<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-    item: &ty::AssociatedItem,
+    item: &ty::AssocItem,
     substs: SubstsRef<'tcx>,
     impl_data: &super::VtableImplData<'tcx, ()>,
 ) -> (DefId, SubstsRef<'tcx>) {
index dae1518d722db2d1d4b466c5cc4624844bd3d6e4..9a90b9fdaeaaac42c353d60266cb3beb292f0ac5 100644 (file)
@@ -426,7 +426,7 @@ pub fn is_from_trait(&self) -> bool {
     pub fn items(
         &self,
         tcx: TyCtxt<'a, 'gcx, 'tcx>,
-    ) -> ty::AssociatedItemsIterator<'a, 'gcx, 'tcx> {
+    ) -> ty::AssocItemsIterator<'a, 'gcx, 'tcx> {
         tcx.associated_items(self.def_id())
     }
 
@@ -484,11 +484,11 @@ pub fn defs(
         self,
         tcx: TyCtxt<'a, 'gcx, 'tcx>,
         trait_item_name: Ident,
-        trait_item_kind: ty::AssociatedKind,
+        trait_item_kind: ty::AssocKind,
         trait_def_id: DefId,
-    ) -> impl Iterator<Item = NodeItem<ty::AssociatedItem>> + Captures<'gcx> + Captures<'tcx> + 'a {
+    ) -> impl Iterator<Item = NodeItem<ty::AssocItem>> + Captures<'gcx> + Captures<'tcx> + 'a {
         self.flat_map(move |node| {
-            use crate::ty::AssociatedKind::*;
+            use crate::ty::AssocKind::*;
             node.items(tcx).filter(move |impl_item| match (trait_item_kind, impl_item.kind) {
                 | (Const, Const)
                 | (Method, Method)
index 5ba23a9c45a4f3bf90bb80fd033c94aefbd9e120..2f87a743a012c9d41f584351391a1ad7c56a4722 100644 (file)
@@ -594,7 +594,7 @@ pub fn count_own_vtable_entries(self, trait_ref: ty::PolyTraitRef<'tcx>) -> usiz
         // Count number of methods and add them to the total offset.
         // Skip over associated types and constants.
         for trait_item in self.associated_items(trait_ref.def_id()) {
-            if trait_item.kind == ty::AssociatedKind::Method {
+            if trait_item.kind == ty::AssocKind::Method {
                 entries += 1;
             }
         }
@@ -614,10 +614,10 @@ pub fn get_vtable_index_of_object_method<N>(self,
         for trait_item in self.associated_items(object.upcast_trait_ref.def_id()) {
             if trait_item.def_id == method_def_id {
                 // The item with the ID we were given really ought to be a method.
-                assert_eq!(trait_item.kind, ty::AssociatedKind::Method);
+                assert_eq!(trait_item.kind, ty::AssocKind::Method);
                 return entries;
             }
-            if trait_item.kind == ty::AssociatedKind::Method {
+            if trait_item.kind == ty::AssocKind::Method {
                 entries += 1;
             }
         }
index 0843a3a55fc4103a2f0ac8be4cdb48a58f742b83..11aad87b70dd3e4ce5b70356e078cdcd853204c3 100644 (file)
@@ -111,7 +111,7 @@ pub fn method_call(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, source: Ty<'tcx>)
             hir::MutMutable => tcx.lang_items().deref_mut_trait()
         };
         let method_def_id = tcx.associated_items(trait_def_id.unwrap())
-            .find(|m| m.kind == ty::AssociatedKind::Method).unwrap().def_id;
+            .find(|m| m.kind == ty::AssocKind::Method).unwrap().def_id;
         (method_def_id, tcx.mk_substs_trait(source, &[]))
     }
 }
index d83b2ce842a88057df2322e1d550ad88e7d1882e..a56fe7d7003a1b0e31d1abce55b2fb1f0f78859e 100644 (file)
@@ -24,7 +24,7 @@
 use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
 use crate::middle::stability;
 use crate::mir::{self, Mir, interpret, ProjectionKind};
-use crate::mir::interpret::{ConstValue, Allocation};
+use crate::mir::interpret::{ConstValue, Allocation, Scalar};
 use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, Subst};
 use crate::ty::ReprOptions;
 use crate::traits;
@@ -1000,7 +1000,10 @@ fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonCons
         };
 
         CommonConsts {
-            err: mk_const(ty::Const::zero_sized(types.err)),
+            err: mk_const(ty::Const {
+                val: ConstValue::Scalar(Scalar::Bits { bits: 0, size: 0 }),
+                ty: types.err,
+            }),
         }
     }
 }
@@ -1822,14 +1825,6 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
 // this is the impl for `&'a InternalSubsts<'a>`
 nop_list_lift!{Kind<'a> => Kind<'tcx>}
 
-impl<'a, 'tcx> Lift<'tcx> for &'a mir::interpret::Allocation {
-    type Lifted = &'tcx mir::interpret::Allocation;
-    fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
-        assert!(tcx.global_arenas.const_allocs.in_arena(*self as *const _));
-        Some(unsafe { mem::transmute(*self) })
-    }
-}
-
 pub mod tls {
     use super::{GlobalCtxt, TyCtxt, ptr_eq};
 
@@ -2594,9 +2589,7 @@ pub fn mk_nil_ptr(self) -> Ty<'tcx> {
 
     #[inline]
     pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
-        self.mk_ty(Array(ty, self.mk_const(
-            ty::Const::from_usize(self.global_tcx(), n)
-        )))
+        self.mk_ty(Array(ty, ty::Const::from_usize(self.global_tcx(), n)))
     }
 
     #[inline]
index dbf9047f775bf2ea738ebd2c64730ef00242e408..dae28d51efc2ead309d4765d76a941708e3abb73 100644 (file)
@@ -939,7 +939,7 @@ fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
     fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
         let flags = FlagComputation::for_const(c);
         debug!("HasTypeFlagsVisitor: c={:?} c.flags={:?} self.flags={:?}", c, flags, self.flags);
-        flags.intersects(self.flags) || c.super_visit_with(self)
+        flags.intersects(self.flags)
     }
 }
 
index f54e69f352a4ed481a0436086f5de8a448e7f4d4..be15b1e3cc9e4c930831354a2c3d300f61e1166c 100644 (file)
@@ -341,7 +341,7 @@ pub fn is_vtable_shim(&self) -> bool {
 
 fn resolve_associated_item<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    trait_item: &ty::AssociatedItem,
+    trait_item: &ty::AssocItem,
     param_env: ty::ParamEnv<'tcx>,
     trait_id: DefId,
     rcvr_substs: SubstsRef<'tcx>,
@@ -450,7 +450,7 @@ fn fn_once_adapter_instance<'a, 'tcx>(
            substs);
     let fn_once = tcx.lang_items().fn_once_trait().unwrap();
     let call_once = tcx.associated_items(fn_once)
-        .find(|it| it.kind == ty::AssociatedKind::Method)
+        .find(|it| it.kind == ty::AssocKind::Method)
         .unwrap().def_id;
     let def = ty::InstanceDef::ClosureOnceShim { call_once };
 
index 99c3293168754dd9a15cb2073996fa08088c0970..f1d1abfa0fb4b55978bcdbd196887beab35aa4dd 100644 (file)
@@ -3,7 +3,7 @@
 #![allow(usage_of_ty_tykind)]
 
 pub use self::Variance::*;
-pub use self::AssociatedItemContainer::*;
+pub use self::AssocItemContainer::*;
 pub use self::BorrowKind::*;
 pub use self::IntVarValue::*;
 pub use self::fold::TypeFoldable;
@@ -134,12 +134,12 @@ pub struct Resolutions {
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]
-pub enum AssociatedItemContainer {
+pub enum AssocItemContainer {
     TraitContainer(DefId),
     ImplContainer(DefId),
 }
 
-impl AssociatedItemContainer {
+impl AssocItemContainer {
     /// Asserts that this is the `DefId` of an associated item declared
     /// in a trait, and returns the trait `DefId`.
     pub fn assert_trait(&self) -> DefId {
@@ -169,14 +169,14 @@ pub struct ImplHeader<'tcx> {
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, HashStable)]
-pub struct AssociatedItem {
+pub struct AssocItem {
     pub def_id: DefId,
     #[stable_hasher(project(name))]
     pub ident: Ident,
-    pub kind: AssociatedKind,
+    pub kind: AssocKind,
     pub vis: Visibility,
     pub defaultness: hir::Defaultness,
-    pub container: AssociatedItemContainer,
+    pub container: AssocItemContainer,
 
     /// Whether this is a method with an explicit self
     /// as its first argument, allowing method calls.
@@ -184,20 +184,20 @@ pub struct AssociatedItem {
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, RustcEncodable, RustcDecodable, HashStable)]
-pub enum AssociatedKind {
+pub enum AssocKind {
     Const,
     Method,
     Existential,
     Type
 }
 
-impl AssociatedItem {
+impl AssocItem {
     pub fn def_kind(&self) -> DefKind {
         match self.kind {
-            AssociatedKind::Const => DefKind::AssociatedConst,
-            AssociatedKind::Method => DefKind::Method,
-            AssociatedKind::Type => DefKind::AssociatedTy,
-            AssociatedKind::Existential => DefKind::AssociatedExistential,
+            AssocKind::Const => DefKind::AssocConst,
+            AssocKind::Method => DefKind::Method,
+            AssocKind::Type => DefKind::AssocTy,
+            AssocKind::Existential => DefKind::AssocExistential,
         }
     }
 
@@ -205,26 +205,26 @@ pub fn def_kind(&self) -> DefKind {
     /// for !
     pub fn relevant_for_never<'tcx>(&self) -> bool {
         match self.kind {
-            AssociatedKind::Existential |
-            AssociatedKind::Const |
-            AssociatedKind::Type => true,
+            AssocKind::Existential |
+            AssocKind::Const |
+            AssocKind::Type => true,
             // FIXME(canndrew): Be more thorough here, check if any argument is uninhabited.
-            AssociatedKind::Method => !self.method_has_self_argument,
+            AssocKind::Method => !self.method_has_self_argument,
         }
     }
 
     pub fn signature<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
         match self.kind {
-            ty::AssociatedKind::Method => {
+            ty::AssocKind::Method => {
                 // We skip the binder here because the binder would deanonymize all
                 // late-bound regions, and we don't want method signatures to show up
                 // `as for<'r> fn(&'r MyType)`.  Pretty-printing handles late-bound
                 // regions just fine, showing `fn(&MyType)`.
                 tcx.fn_sig(self.def_id).skip_binder().to_string()
             }
-            ty::AssociatedKind::Type => format!("type {};", self.ident),
-            ty::AssociatedKind::Existential => format!("existential type {};", self.ident),
-            ty::AssociatedKind::Const => {
+            ty::AssocKind::Type => format!("type {};", self.ident),
+            ty::AssocKind::Existential => format!("existential type {};", self.ident),
+            ty::AssocKind::Const => {
                 format!("const {}: {:?};", self.ident, tcx.type_of(self.def_id))
             }
         }
@@ -2343,7 +2343,7 @@ pub fn variant_of_res(&self, res: Res) -> &VariantDef {
             Res::Def(DefKind::Variant, vid) => self.variant_with_id(vid),
             Res::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid),
             Res::Def(DefKind::Struct, _) | Res::Def(DefKind::Union, _) |
-            Res::Def(DefKind::TyAlias, _) | Res::Def(DefKind::AssociatedTy, _) | Res::SelfTy(..) |
+            Res::Def(DefKind::TyAlias, _) | Res::Def(DefKind::AssocTy, _) | Res::SelfTy(..) |
             Res::SelfCtor(..) => self.non_enum_variant(),
             _ => bug!("unexpected res {:?} in variant_of_res", res)
         }
@@ -2793,9 +2793,9 @@ pub fn expr_span(self, id: NodeId) -> Span {
         }
     }
 
-    pub fn provided_trait_methods(self, id: DefId) -> Vec<AssociatedItem> {
+    pub fn provided_trait_methods(self, id: DefId) -> Vec<AssocItem> {
         self.associated_items(id)
-            .filter(|item| item.kind == AssociatedKind::Method && item.defaultness.has_value())
+            .filter(|item| item.kind == AssocKind::Method && item.defaultness.has_value())
             .collect()
     }
 
@@ -2805,7 +2805,7 @@ pub fn trait_relevant_for_never(self, did: DefId) -> bool {
         })
     }
 
-    pub fn opt_associated_item(self, def_id: DefId) -> Option<AssociatedItem> {
+    pub fn opt_associated_item(self, def_id: DefId) -> Option<AssocItem> {
         let is_associated_item = if let Some(hir_id) = self.hir().as_local_hir_id(def_id) {
             match self.hir().get_by_hir_id(hir_id) {
                 Node::TraitItem(_) | Node::ImplItem(_) => true,
@@ -2813,9 +2813,9 @@ pub fn opt_associated_item(self, def_id: DefId) -> Option<AssociatedItem> {
             }
         } else {
             match self.def_kind(def_id).expect("no def for def-id") {
-                DefKind::AssociatedConst
+                DefKind::AssocConst
                 | DefKind::Method
-                | DefKind::AssociatedTy => true,
+                | DefKind::AssocTy => true,
                 _ => false,
             }
         };
@@ -2831,18 +2831,18 @@ fn associated_item_from_trait_item_ref(self,
                                            parent_def_id: DefId,
                                            parent_vis: &hir::Visibility,
                                            trait_item_ref: &hir::TraitItemRef)
-                                           -> AssociatedItem {
+                                           -> AssocItem {
         let def_id = self.hir().local_def_id_from_hir_id(trait_item_ref.id.hir_id);
         let (kind, has_self) = match trait_item_ref.kind {
-            hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false),
-            hir::AssociatedItemKind::Method { has_self } => {
-                (ty::AssociatedKind::Method, has_self)
+            hir::AssocItemKind::Const => (ty::AssocKind::Const, false),
+            hir::AssocItemKind::Method { has_self } => {
+                (ty::AssocKind::Method, has_self)
             }
-            hir::AssociatedItemKind::Type => (ty::AssociatedKind::Type, false),
-            hir::AssociatedItemKind::Existential => bug!("only impls can have existentials"),
+            hir::AssocItemKind::Type => (ty::AssocKind::Type, false),
+            hir::AssocItemKind::Existential => bug!("only impls can have existentials"),
         };
 
-        AssociatedItem {
+        AssocItem {
             ident: trait_item_ref.ident,
             kind,
             // Visibility of trait items is inherited from their traits.
@@ -2857,18 +2857,18 @@ fn associated_item_from_trait_item_ref(self,
     fn associated_item_from_impl_item_ref(self,
                                           parent_def_id: DefId,
                                           impl_item_ref: &hir::ImplItemRef)
-                                          -> AssociatedItem {
+                                          -> AssocItem {
         let def_id = self.hir().local_def_id_from_hir_id(impl_item_ref.id.hir_id);
         let (kind, has_self) = match impl_item_ref.kind {
-            hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false),
-            hir::AssociatedItemKind::Method { has_self } => {
-                (ty::AssociatedKind::Method, has_self)
+            hir::AssocItemKind::Const => (ty::AssocKind::Const, false),
+            hir::AssocItemKind::Method { has_self } => {
+                (ty::AssocKind::Method, has_self)
             }
-            hir::AssociatedItemKind::Type => (ty::AssociatedKind::Type, false),
-            hir::AssociatedItemKind::Existential => (ty::AssociatedKind::Existential, false),
+            hir::AssocItemKind::Type => (ty::AssocKind::Type, false),
+            hir::AssocItemKind::Existential => (ty::AssocKind::Existential, false),
         };
 
-        AssociatedItem {
+        AssocItem {
             ident: impl_item_ref.ident,
             kind,
             // Visibility of trait impl items doesn't matter.
@@ -2893,13 +2893,13 @@ pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<usiz
     pub fn associated_items(
         self,
         def_id: DefId,
-    ) -> AssociatedItemsIterator<'a, 'gcx, 'tcx> {
+    ) -> AssocItemsIterator<'a, 'gcx, 'tcx> {
         // Ideally, we would use `-> impl Iterator` here, but it falls
         // afoul of the conservative "capture [restrictions]" we put
         // in place, so we use a hand-written iterator.
         //
         // [restrictions]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999
-        AssociatedItemsIterator {
+        AssocItemsIterator {
             tcx: self,
             def_ids: self.associated_item_def_ids(def_id),
             next_index: 0,
@@ -3104,23 +3104,23 @@ pub fn adjust_ident(self, mut ident: Ident, scope: DefId, block: hir::HirId) ->
     }
 }
 
-pub struct AssociatedItemsIterator<'a, 'gcx: 'tcx, 'tcx: 'a> {
+pub struct AssocItemsIterator<'a, 'gcx: 'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     def_ids: &'gcx [DefId],
     next_index: usize,
 }
 
-impl Iterator for AssociatedItemsIterator<'_, '_, '_> {
-    type Item = AssociatedItem;
+impl Iterator for AssocItemsIterator<'_, '_, '_> {
+    type Item = AssocItem;
 
-    fn next(&mut self) -> Option<AssociatedItem> {
+    fn next(&mut self) -> Option<AssocItem> {
         let def_id = self.def_ids.get(self.next_index)?;
         self.next_index += 1;
         Some(self.tcx.associated_item(*def_id))
     }
 }
 
-fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> AssociatedItem {
+fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> AssocItem {
     let id = tcx.hir().as_local_hir_id(def_id).unwrap();
     let parent_id = tcx.hir().get_parent_item(id);
     let parent_def_id = tcx.hir().local_def_id_from_hir_id(parent_id);
index d5d4f648444630152aff6318204d807301e79268..53d4466cfef684d8007e4b4c569ba64e15cfe634 100644 (file)
@@ -31,6 +31,7 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
     type Region;
     type Type;
     type DynExistential;
+    type Const;
 
     fn tcx(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>;
 
@@ -66,6 +67,11 @@ fn print_dyn_existential(
         predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
     ) -> Result<Self::DynExistential, Self::Error>;
 
+    fn print_const(
+        self,
+        ct: &'tcx ty::Const<'tcx>,
+    ) -> Result<Self::Const, Self::Error>;
+
     fn path_crate(
         self,
         cnum: CrateNum,
@@ -325,3 +331,11 @@ fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
         cx.print_dyn_existential(self)
     }
 }
+
+impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for &'tcx ty::Const<'tcx> {
+    type Output = P::Const;
+    type Error = P::Error;
+    fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
+        cx.print_const(self)
+    }
+}
index 06db4b9b65bcaf545ebad92ab6f816d3b2015ab7..4b4dd5d88d93add28055afb84bd9b0a7272af36a 100644 (file)
@@ -1,12 +1,16 @@
 use crate::hir;
-use crate::hir::def::Namespace;
+use crate::hir::def::{Namespace, DefKind};
 use crate::hir::map::{DefPathData, DisambiguatedDefPathData};
 use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use crate::middle::cstore::{ExternCrate, ExternCrateSource};
 use crate::middle::region;
 use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable};
 use crate::ty::subst::{Kind, Subst, UnpackedKind};
-use crate::mir::interpret::ConstValue;
+use crate::ty::layout::Size;
+use crate::mir::interpret::{ConstValue, sign_extend, Scalar};
+use syntax::ast;
+use rustc_apfloat::ieee::{Double, Single};
+use rustc_apfloat::Float;
 use rustc_target::spec::abi::Abi;
 use syntax::symbol::{kw, InternedString};
 
@@ -169,6 +173,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
         Region = Self,
         Type = Self,
         DynExistential = Self,
+        Const = Self,
     > +
     fmt::Write
 {
@@ -661,12 +666,10 @@ fn pretty_print_type(
             },
             ty::Array(ty, sz) => {
                 p!(write("["), print(ty), write("; "));
-                match sz.val {
-                    ConstValue::Unevaluated(..) |
-                    ConstValue::Infer(..) => p!(write("_")),
-                    ConstValue::Param(ParamConst { name, .. }) =>
-                        p!(write("{}", name)),
-                    _ => p!(write("{}", sz.unwrap_usize(self.tcx()))),
+                if let Some(n) = sz.assert_usize(self.tcx()) {
+                    p!(write("{}", n));
+                } else {
+                    p!(write("_"));
                 }
                 p!(write("]"))
             }
@@ -804,6 +807,113 @@ fn pretty_fn_sig(
 
         Ok(self)
     }
+
+    fn pretty_print_const(
+        mut self,
+        ct: &'tcx ty::Const<'tcx>,
+    ) -> Result<Self::Const, Self::Error> {
+        define_scoped_cx!(self);
+
+        let u8 = self.tcx().types.u8;
+        if let ty::FnDef(did, substs) = ct.ty.sty {
+            p!(print_value_path(did, substs));
+            return Ok(self);
+        }
+        if let ConstValue::Unevaluated(did, substs) = ct.val {
+            match self.tcx().def_kind(did) {
+                | Some(DefKind::Static)
+                | Some(DefKind::Const)
+                | Some(DefKind::AssocConst) => p!(print_value_path(did, substs)),
+                _ => if did.is_local() {
+                    let span = self.tcx().def_span(did);
+                    if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span) {
+                        p!(write("{}", snip))
+                    } else {
+                        p!(write("_: "), print(ct.ty))
+                    }
+                } else {
+                    p!(write("_: "), print(ct.ty))
+                },
+            }
+            return Ok(self);
+        }
+        if let ConstValue::Infer(..) = ct.val {
+            p!(write("_: "), print(ct.ty));
+            return Ok(self);
+        }
+        if let ConstValue::Param(ParamConst { name, .. }) = ct.val {
+            p!(write("{}", name));
+            return Ok(self);
+        }
+        if let ConstValue::Scalar(Scalar::Bits { bits, .. }) = ct.val {
+            match ct.ty.sty {
+                ty::Bool => {
+                    p!(write("{}", if bits == 0 { "false" } else { "true" }));
+                    return Ok(self);
+                },
+                ty::Float(ast::FloatTy::F32) => {
+                    p!(write("{}f32", Single::from_bits(bits)));
+                    return Ok(self);
+                },
+                ty::Float(ast::FloatTy::F64) => {
+                    p!(write("{}f64", Double::from_bits(bits)));
+                    return Ok(self);
+                },
+                ty::Uint(ui) => {
+                    p!(write("{}{}", bits, ui));
+                    return Ok(self);
+                },
+                ty::Int(i) =>{
+                    let ty = self.tcx().lift_to_global(&ct.ty).unwrap();
+                    let size = self.tcx().layout_of(ty::ParamEnv::empty().and(ty))
+                        .unwrap()
+                        .size;
+                    p!(write("{}{}", sign_extend(bits, size) as i128, i));
+                    return Ok(self);
+                },
+                ty::Char => {
+                    p!(write("{:?}", ::std::char::from_u32(bits as u32).unwrap()));
+                    return Ok(self);
+                }
+                _ => {},
+            }
+        }
+        if let ty::Ref(_, ref_ty, _) = ct.ty.sty {
+            let byte_str = match (ct.val, &ref_ty.sty) {
+                (ConstValue::Scalar(Scalar::Ptr(ptr)), ty::Array(t, n)) if *t == u8 => {
+                    let n = n.unwrap_usize(self.tcx());
+                    Some(self.tcx()
+                        .alloc_map.lock()
+                        .unwrap_memory(ptr.alloc_id)
+                        .get_bytes(&self.tcx(), ptr, Size::from_bytes(n)).unwrap())
+                },
+                (ConstValue::Slice { data, start, end }, ty::Slice(t)) if *t == u8 => {
+                    Some(&data.bytes[start..end])
+                },
+                (ConstValue::Slice { data, start, end }, ty::Str) => {
+                    let slice = &data.bytes[start..end];
+                    let s = ::std::str::from_utf8(slice)
+                        .expect("non utf8 str from miri");
+                    p!(write("{:?}", s));
+                    return Ok(self);
+                },
+                _ => None,
+            };
+            if let Some(byte_str) = byte_str {
+                p!(write("b\""));
+                for &c in byte_str {
+                    for e in std::ascii::escape_default(c) {
+                        self.write_char(e as char)?;
+                    }
+                }
+                p!(write("\""));
+                return Ok(self);
+            }
+        }
+        p!(write("{:?} : ", ct.val), print(ct.ty));
+
+        Ok(self)
+    }
 }
 
 // HACK(eddyb) boxed to avoid moving around a large struct by-value.
@@ -896,6 +1006,7 @@ impl<F: fmt::Write> Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> {
     type Region = Self;
     type Type = Self;
     type DynExistential = Self;
+    type Const = Self;
 
     fn tcx(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> {
         self.tcx
@@ -971,6 +1082,13 @@ fn print_dyn_existential(
         self.pretty_print_dyn_existential(predicates)
     }
 
+    fn print_const(
+        self,
+        ct: &'tcx ty::Const<'tcx>,
+    ) -> Result<Self::Const, Self::Error> {
+        self.pretty_print_const(ct)
+    }
+
     fn path_crate(
         mut self,
         cnum: CrateNum,
@@ -1444,6 +1562,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 forward_display_to_print! {
     Ty<'tcx>,
     &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
+    &'tcx ty::Const<'tcx>,
 
     // HACK(eddyb) these are exhaustive instead of generic,
     // because `for<'gcx: 'tcx, 'tcx>` isn't possible yet.
@@ -1533,15 +1652,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         p!(print_def_path(self.def_id, self.substs));
     }
 
-    &'tcx ty::Const<'tcx> {
-        match self.val {
-            ConstValue::Unevaluated(..) |
-            ConstValue::Infer(..) => p!(write("_")),
-            ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)),
-            _ => p!(write("{:?}", self)),
-        }
-    }
-
     ty::ParamTy {
         p!(write("{}", self.name))
     }
index cf04d6eac3ae0b608db0fd0168be15138edd7a83..0daa567052d5662ec881cad2b4c366f30b6c5ca4 100644 (file)
@@ -6,7 +6,7 @@
 use crate::hir::def::Namespace;
 use crate::mir::ProjectionKind;
 use crate::mir::interpret::ConstValue;
-use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst};
+use crate::ty::{self, Lift, Ty, TyCtxt, InferConst};
 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use crate::ty::print::{FmtPrinter, Printer};
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
@@ -14,7 +14,6 @@
 use crate::mir::interpret;
 
 use std::fmt;
-use std::marker::PhantomData;
 use std::rc::Rc;
 
 impl fmt::Debug for ty::GenericParamDef {
@@ -788,16 +787,6 @@ impl<'a, 'tcx> Lift<'tcx> for interpret::GlobalId<'a> {
     }
 }
 
-impl<'a, 'tcx> Lift<'tcx> for ConstVid<'a> {
-    type Lifted = ConstVid<'tcx>;
-    fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
-        Some(ConstVid {
-            index: self.index,
-            phantom: PhantomData,
-        })
-    }
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // TypeFoldable implementations.
 //
@@ -1356,7 +1345,7 @@ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F)
             ConstValue::Param(p) => ConstValue::Param(p.fold_with(folder)),
             ConstValue::Placeholder(p) => ConstValue::Placeholder(p),
             ConstValue::Scalar(a) => ConstValue::Scalar(a),
-            ConstValue::Slice(a, b) => ConstValue::Slice(a, b),
+            ConstValue::Slice { data, start, end } => ConstValue::Slice { data, start, end },
             ConstValue::Unevaluated(did, substs)
                 => ConstValue::Unevaluated(did, substs.fold_with(folder)),
         }
@@ -1369,7 +1358,7 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
             ConstValue::Param(p) => p.visit_with(visitor),
             ConstValue::Placeholder(_) => false,
             ConstValue::Scalar(_) => false,
-            ConstValue::Slice(..) => false,
+            ConstValue::Slice { .. } => false,
             ConstValue::Unevaluated(_, substs) => substs.visit_with(visitor),
         }
     }
index 0b5a6fce5cb8759056f2ad85e2898efe1c95229a..4711429502f3fd5c1eb17273523844f193718ff8 100644 (file)
@@ -998,7 +998,7 @@ pub fn from_ref_and_name(
         tcx: TyCtxt<'_, '_, '_>, trait_ref: ty::TraitRef<'tcx>, item_name: Ident
     ) -> ProjectionTy<'tcx> {
         let item_def_id = tcx.associated_items(trait_ref.def_id).find(|item| {
-            item.kind == ty::AssociatedKind::Type &&
+            item.kind == ty::AssocKind::Type &&
             tcx.hygienic_eq(item_name, item.ident, trait_ref.def_id)
         }).unwrap().def_id;
 
@@ -2207,18 +2207,19 @@ pub struct Const<'tcx> {
 }
 
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(Const<'_>, 48);
+static_assert_size!(Const<'_>, 40);
 
 impl<'tcx> Const<'tcx> {
     #[inline]
     pub fn from_scalar(
+        tcx: TyCtxt<'_, '_, 'tcx>,
         val: Scalar,
         ty: Ty<'tcx>,
-    ) -> Self {
-        Self {
+    ) -> &'tcx Self {
+        tcx.mk_const(Self {
             val: ConstValue::Scalar(val),
             ty,
-        }
+        })
     }
 
     #[inline]
@@ -2226,28 +2227,28 @@ pub fn from_bits(
         tcx: TyCtxt<'_, '_, 'tcx>,
         bits: u128,
         ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
-    ) -> Self {
+    ) -> &'tcx Self {
         let ty = tcx.lift_to_global(&ty).unwrap();
         let size = tcx.layout_of(ty).unwrap_or_else(|e| {
             panic!("could not compute layout for {:?}: {:?}", ty, e)
         }).size;
         let truncated = truncate(bits, size);
         assert_eq!(truncated, bits, "from_bits called with untruncated value");
-        Self::from_scalar(Scalar::Bits { bits, size: size.bytes() as u8 }, ty.value)
+        Self::from_scalar(tcx, Scalar::Bits { bits, size: size.bytes() as u8 }, ty.value)
     }
 
     #[inline]
-    pub fn zero_sized(ty: Ty<'tcx>) -> Self {
-        Self::from_scalar(Scalar::Bits { bits: 0, size: 0 }, ty)
+    pub fn zero_sized(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
+        Self::from_scalar(tcx, Scalar::Bits { bits: 0, size: 0 }, ty)
     }
 
     #[inline]
-    pub fn from_bool(tcx: TyCtxt<'_, '_, 'tcx>, v: bool) -> Self {
+    pub fn from_bool(tcx: TyCtxt<'_, '_, 'tcx>, v: bool) -> &'tcx Self {
         Self::from_bits(tcx, v as u128, ParamEnv::empty().and(tcx.types.bool))
     }
 
     #[inline]
-    pub fn from_usize(tcx: TyCtxt<'_, '_, 'tcx>, n: u64) -> Self {
+    pub fn from_usize(tcx: TyCtxt<'_, '_, 'tcx>, n: u64) -> &'tcx Self {
         Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize))
     }
 
index 72dfe581ba73586082b7848f030c4c190158448a..75ba1dd46ca2a8260f4390d720d06a1c63025f57 100644 (file)
@@ -479,21 +479,22 @@ fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
         // the specialized routine `ty::replace_late_regions()`.
         match *r {
             ty::ReEarlyBound(data) => {
-                let r = self.substs.get(data.index as usize).map(|k| k.unpack());
-                match r {
+                let rk = self.substs.get(data.index as usize).map(|k| k.unpack());
+                match rk {
                     Some(UnpackedKind::Lifetime(lt)) => {
                         self.shift_region_through_binders(lt)
                     }
                     _ => {
                         let span = self.span.unwrap_or(DUMMY_SP);
-                        span_bug!(
-                            span,
+                        let msg = format!(
                             "Region parameter out of range \
                              when substituting in region {} (root type={:?}) \
                              (index={})",
                             data.name,
                             self.root_ty,
                             data.index);
+                        self.tcx.sess.delay_span_bug(span, &msg);
+                        r
                     }
                 }
             }
index 585970e64df8d65b1a73636af3a4dd688fe71a17..8624856a4f55ca96fd0da56bc62403445bd47f07 100644 (file)
@@ -1,6 +1,8 @@
 use std::borrow::Cow;
 use std::error::Error;
+use std::fs;
 use std::mem::{self, Discriminant};
+use std::path::Path;
 use std::process;
 use std::thread::ThreadId;
 use std::u32;
@@ -71,10 +73,17 @@ pub struct SelfProfiler {
 }
 
 impl SelfProfiler {
-    pub fn new(event_filters: &Option<Vec<String>>) -> Result<SelfProfiler, Box<dyn Error>> {
-        let filename = format!("pid-{}.rustc_profile", process::id());
-        let path = std::path::Path::new(&filename);
-        let profiler = Profiler::new(path)?;
+    pub fn new(
+        output_directory: &Path,
+        crate_name: Option<&str>,
+        event_filters: &Option<Vec<String>>
+    ) -> Result<SelfProfiler, Box<dyn Error>> {
+        fs::create_dir_all(output_directory)?;
+
+        let crate_name = crate_name.unwrap_or("unknown-crate");
+        let filename = format!("{}-{}.rustc_profile", crate_name, process::id());
+        let path = output_directory.join(&filename);
+        let profiler = Profiler::new(&path)?;
 
         let query_event_kind = profiler.alloc_string("Query");
         let generic_activity_event_kind = profiler.alloc_string("GenericActivity");
index b9cd30694f6e8efe5f4f4b6687dfc8ad2d0a0b5f..3ec06b17aff22a66c1a238ee3835c2fb43201c4a 100644 (file)
@@ -91,9 +91,7 @@ impl MutVisitor for ExpandAllocatorDirectives<'_> {
             call_site: item.span, // use the call site of the static
             def_site: None,
             format: MacroAttribute(Symbol::intern(name)),
-            allow_internal_unstable: Some(vec![
-                Symbol::intern("rustc_attrs"),
-            ].into()),
+            allow_internal_unstable: Some(vec![sym::rustc_attrs].into()),
             allow_internal_unsafe: false,
             local_inner_macros: false,
             edition: self.sess.edition,
@@ -223,7 +221,7 @@ fn call_allocator(&self, method: &str, mut args: Vec<P<Expr>>) -> P<Expr> {
     }
 
     fn attrs(&self) -> Vec<Attribute> {
-        let special = Symbol::intern("rustc_std_internal_symbol");
+        let special = sym::rustc_std_internal_symbol;
         let special = self.cx.meta_word(self.span, special);
         vec![self.cx.attribute(self.span, special)]
     }
index 66ba95810a62516a109462f740955fed5c54afb8..d8a9f681639a049d28063c7d9cb348c1c81c57a7 100644 (file)
@@ -13,7 +13,7 @@
 use rustc::hir::def_id::LOCAL_CRATE;
 use rustc_codegen_ssa::back::write::{CodegenContext, ModuleConfig, run_assembler};
 use rustc_codegen_ssa::traits::*;
-use rustc::session::config::{self, OutputType, Passes, Lto, PgoGenerate};
+use rustc::session::config::{self, OutputType, Passes, Lto, SwitchWithOptPath};
 use rustc::session::Session;
 use rustc::ty::TyCtxt;
 use rustc_codegen_ssa::{RLIB_BYTECODE_EXTENSION, ModuleCodegen, CompiledModule};
@@ -707,7 +707,7 @@ pub unsafe fn with_llvm_pmb(llmod: &llvm::Module,
     let inline_threshold = config.inline_threshold;
 
     let pgo_gen_path = match config.pgo_gen {
-        PgoGenerate::Enabled(ref opt_dir_path) => {
+        SwitchWithOptPath::Enabled(ref opt_dir_path) => {
             let path = if let Some(dir_path) = opt_dir_path {
                 dir_path.join("default_%m.profraw")
             } else {
@@ -716,16 +716,14 @@ pub unsafe fn with_llvm_pmb(llmod: &llvm::Module,
 
             Some(CString::new(format!("{}", path.display())).unwrap())
         }
-        PgoGenerate::Disabled => {
+        SwitchWithOptPath::Disabled => {
             None
         }
     };
 
-    let pgo_use_path = if config.pgo_use.is_empty() {
-        None
-    } else {
-        Some(CString::new(config.pgo_use.as_bytes()).unwrap())
-    };
+    let pgo_use_path = config.pgo_use.as_ref().map(|path_buf| {
+        CString::new(path_buf.to_string_lossy().as_bytes()).unwrap()
+    });
 
     llvm::LLVMRustConfigurePassManagerBuilder(
         builder,
index 1c793996c83db65cc1cc2960546f358197812253..5abff2d8ec35042a08f4cae7a56dbddf8cb4df15 100644 (file)
@@ -13,7 +13,7 @@
 use rustc::dep_graph::cgu_reuse_tracker::CguReuseTracker;
 use rustc::middle::cstore::EncodedMetadata;
 use rustc::session::config::{self, OutputFilenames, OutputType, Passes, Lto,
-                             Sanitizer, PgoGenerate};
+                             Sanitizer, SwitchWithOptPath};
 use rustc::session::Session;
 use rustc::util::nodemap::FxHashMap;
 use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
@@ -56,8 +56,8 @@ pub struct ModuleConfig {
     /// Some(level) to optimize binary size, or None to not affect program size.
     pub opt_size: Option<config::OptLevel>,
 
-    pub pgo_gen: PgoGenerate,
-    pub pgo_use: String,
+    pub pgo_gen: SwitchWithOptPath,
+    pub pgo_use: Option<PathBuf>,
 
     // Flags indicating which outputs to produce.
     pub emit_pre_lto_bc: bool,
@@ -94,8 +94,8 @@ fn new(passes: Vec<String>) -> ModuleConfig {
             opt_level: None,
             opt_size: None,
 
-            pgo_gen: PgoGenerate::Disabled,
-            pgo_use: String::new(),
+            pgo_gen: SwitchWithOptPath::Disabled,
+            pgo_use: None,
 
             emit_no_opt_bc: false,
             emit_pre_lto_bc: false,
index 3f8dc420cf40278692c33ac0cffd5680a87331d0..eaa1dd186a536c39667e4bd3120a36f5719dba99 100644 (file)
@@ -13,7 +13,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     pub fn eval_mir_constant(
         &mut self,
         constant: &mir::Constant<'tcx>,
-    ) -> Result<ty::Const<'tcx>, ErrorHandled> {
+    ) -> Result<&'tcx ty::Const<'tcx>, ErrorHandled> {
         match constant.literal.val {
             mir::interpret::ConstValue::Unevaluated(def_id, ref substs) => {
                 let substs = self.monomorphize(substs);
@@ -26,7 +26,7 @@ pub fn eval_mir_constant(
                 };
                 self.cx.tcx().const_eval(ty::ParamEnv::reveal_all().and(cid))
             },
-            _ => Ok(*self.monomorphize(&constant.literal)),
+            _ => Ok(self.monomorphize(&constant.literal)),
         }
     }
 
@@ -36,7 +36,7 @@ pub fn simd_shuffle_indices(
         bx: &Bx,
         span: Span,
         ty: Ty<'tcx>,
-        constant: Result<ty::Const<'tcx>, ErrorHandled>,
+        constant: Result<&'tcx ty::Const<'tcx>, ErrorHandled>,
     ) -> (Bx::Value, Ty<'tcx>) {
         constant
             .map(|c| {
index 3db05b7214d659578533a4cc4ca701dc8ef9d5ce..ec471a1323eab917dd548d77c968fadb1b5d1621 100644 (file)
@@ -1,7 +1,7 @@
-use rustc::mir::interpret::{ConstValue, ErrorHandled};
+use rustc::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar};
 use rustc::mir;
 use rustc::ty;
-use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
+use rustc::ty::layout::{self, Align, LayoutOf, TyLayout, Size};
 
 use crate::base;
 use crate::MemFlags;
@@ -67,7 +67,7 @@ pub fn new_zst<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
 
     pub fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         bx: &mut Bx,
-        val: ty::Const<'tcx>
+        val: &'tcx ty::Const<'tcx>
     ) -> Result<Self, ErrorHandled> {
         let layout = bx.layout_of(val.ty);
 
@@ -92,17 +92,21 @@ pub fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
                 );
                 OperandValue::Immediate(llval)
             },
-            ConstValue::Slice(a, b) => {
+            ConstValue::Slice { data, start, end } => {
                 let a_scalar = match layout.abi {
                     layout::Abi::ScalarPair(ref a, _) => a,
                     _ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout)
                 };
+                let a = Scalar::from(Pointer::new(
+                    bx.tcx().alloc_map.lock().allocate(data),
+                    Size::from_bytes(start as u64),
+                )).into();
                 let a_llval = bx.scalar_to_backend(
                     a,
                     a_scalar,
                     bx.scalar_pair_element_backend_type(layout, 0, true),
                 );
-                let b_llval = bx.const_usize(b);
+                let b_llval = bx.const_usize((end - start) as u64);
                 OperandValue::Pair(a_llval, b_llval)
             },
             ConstValue::ByRef(ptr, alloc) => {
index 1a8647ed197b5c316f45db8ed205d3c68ec5c6b0..864071629078aab7e011b94c60b296f0cbf5c818 100644 (file)
@@ -96,6 +96,7 @@
 use rustc::ty::query::Providers;
 use rustc::ty::subst::{Kind, SubstsRef, UnpackedKind};
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
+use rustc::mir::interpret::{ConstValue, Scalar};
 use rustc::util::common::record_time;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_mir::monomorphize::item::{InstantiationMode, MonoItem, MonoItemExt};
@@ -391,6 +392,7 @@ impl Printer<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> {
     type Region = Self;
     type Type = Self;
     type DynExistential = Self;
+    type Const = Self;
 
     fn tcx(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
         self.tcx
@@ -436,6 +438,20 @@ fn print_dyn_existential(
         Ok(self)
     }
 
+    fn print_const(
+        mut self,
+        ct: &'tcx ty::Const<'tcx>,
+    ) -> Result<Self::Const, Self::Error> {
+        // only print integers
+        if let ConstValue::Scalar(Scalar::Bits { .. }) = ct.val {
+            if ct.ty.is_integral() {
+                return self.pretty_print_const(ct);
+            }
+        }
+        self.write_str("_")?;
+        Ok(self)
+    }
+
     fn path_crate(
         mut self,
         cnum: CrateNum,
index 09bb547191f491f29d4dc42f74c7e3f043c5e419..4ff996d1f5707a2b51379e884544c78d0a492410 100644 (file)
@@ -68,7 +68,7 @@ pub fn add_configuration(
     sess: &Session,
     codegen_backend: &dyn CodegenBackend,
 ) {
-    let tf = Symbol::intern("target_feature");
+    let tf = sym::target_feature;
 
     cfg.extend(
         codegen_backend
index d52e497cf63d9a14d8b78885285f3614239e107a..d184c671bbaf8a3234d9bffda63c91d07e4599e7 100644 (file)
@@ -1439,8 +1439,8 @@ fn check_ident_token(&mut self,
     {
         let next_edition = match cx.sess.edition() {
             Edition::Edition2015 => {
-                match &ident.as_str()[..] {
-                    "async" | "await" | "try" => Edition::Edition2018,
+                match ident.name {
+                    kw::Async | kw::Await | kw::Try => Edition::Edition2018,
 
                     // rust-lang/rust#56327: Conservatively do not
                     // attempt to report occurrences of `dyn` within
@@ -1454,7 +1454,7 @@ fn check_ident_token(&mut self,
                     // its precise role in the parsed AST and thus are
                     // assured this is truly an attempt to use it as
                     // an identifier.
-                    "dyn" if !under_macro => Edition::Edition2018,
+                    kw::Dyn if !under_macro => Edition::Edition2018,
 
                     _ => return,
                 }
index 3883682fa9df57f6ec88c4b113d44c634fec6708..1f6e54807d8cb16fdb504837d859c00d855ce455 100644 (file)
@@ -96,6 +96,7 @@ pub fn symbols(input: TokenStream) -> TokenStream {
 
     let mut keyword_stream = quote! {};
     let mut symbols_stream = quote! {};
+    let mut digits_stream = quote! {};
     let mut prefill_stream = quote! {};
     let mut counter = 0u32;
     let mut keys = HashSet::<String>::new();
@@ -106,6 +107,7 @@ pub fn symbols(input: TokenStream) -> TokenStream {
         }
     };
 
+    // Generate the listed keywords.
     for keyword in &input.keywords.0 {
         let name = &keyword.name;
         let value = &keyword.value;
@@ -119,6 +121,7 @@ pub fn symbols(input: TokenStream) -> TokenStream {
         counter += 1;
     }
 
+    // Generate the listed symbols.
     for symbol in &input.symbols.0 {
         let name = &symbol.name;
         let value = match &symbol.value {
@@ -135,6 +138,19 @@ pub fn symbols(input: TokenStream) -> TokenStream {
         counter += 1;
     }
 
+    // Generate symbols for the strings "0", "1", ..., "9".
+    for n in 0..10 {
+        let n = n.to_string();
+        check_dup(&n);
+        prefill_stream.extend(quote! {
+            #n,
+        });
+        digits_stream.extend(quote! {
+            Symbol::new(#counter),
+        });
+        counter += 1;
+    }
+
     let tt = TokenStream::from(quote! {
         macro_rules! keywords {
             () => {
@@ -145,6 +161,10 @@ macro_rules! keywords {
         macro_rules! symbols {
             () => {
                 #symbols_stream
+
+                pub const digits_array: &[Symbol; 10] = &[
+                    #digits_stream
+                ];
             }
         }
 
index fae4c244d6e1404a5e765c22255fa62b5e9386ff..cc79f7b077eb28365c913f65f86ab982b888c137 100644 (file)
@@ -431,9 +431,7 @@ pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
             let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
             let ext = SyntaxExtension::ProcMacro {
                 expander: Box::new(BangProcMacro { client }),
-                allow_internal_unstable: Some(vec![
-                    Symbol::intern("proc_macro_def_site"),
-                ].into()),
+                allow_internal_unstable: Some(vec![sym::proc_macro_def_site].into()),
                 edition: data.root.edition,
             };
             return LoadedMacro::ProcMacro(Lrc::new(ext));
@@ -473,7 +471,7 @@ pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
         })
     }
 
-    pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssociatedItem {
+    pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssocItem {
         self.get_crate_data(def.krate).get_associated_item(def.index)
     }
 }
index 958c81989ffd6707328578b888c95146a20c0923..a484928ce6c3663365970bcba5464dde29f38655 100644 (file)
@@ -401,7 +401,7 @@ impl<'tcx> EntryKind<'tcx> {
     fn def_kind(&self) -> Option<DefKind> {
         Some(match *self {
             EntryKind::Const(..) => DefKind::Const,
-            EntryKind::AssociatedConst(..) => DefKind::AssociatedConst,
+            EntryKind::AssocConst(..) => DefKind::AssocConst,
             EntryKind::ImmStatic |
             EntryKind::MutStatic |
             EntryKind::ForeignImmStatic |
@@ -415,8 +415,8 @@ fn def_kind(&self) -> Option<DefKind> {
             EntryKind::TypeParam => DefKind::TyParam,
             EntryKind::ConstParam => DefKind::ConstParam,
             EntryKind::Existential => DefKind::Existential,
-            EntryKind::AssociatedType(_) => DefKind::AssociatedTy,
-            EntryKind::AssociatedExistential(_) => DefKind::AssociatedExistential,
+            EntryKind::AssocType(_) => DefKind::AssocTy,
+            EntryKind::AssocExistential(_) => DefKind::AssocExistential,
             EntryKind::Mod(_) => DefKind::Mod,
             EntryKind::Variant(_) => DefKind::Variant,
             EntryKind::Trait(_) => DefKind::Trait,
@@ -873,7 +873,7 @@ pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Sessio
 
     pub fn const_is_rvalue_promotable_to_static(&self, id: DefIndex) -> bool {
         match self.entry(id).kind {
-            EntryKind::AssociatedConst(_, data, _) |
+            EntryKind::AssocConst(_, data, _) |
             EntryKind::Const(data, _) => data.ast_promotable,
             _ => bug!(),
         }
@@ -897,38 +897,38 @@ pub fn maybe_get_optimized_mir(&self,
     pub fn mir_const_qualif(&self, id: DefIndex) -> u8 {
         match self.entry(id).kind {
             EntryKind::Const(qualif, _) |
-            EntryKind::AssociatedConst(AssociatedContainer::ImplDefault, qualif, _) |
-            EntryKind::AssociatedConst(AssociatedContainer::ImplFinal, qualif, _) => {
+            EntryKind::AssocConst(AssocContainer::ImplDefault, qualif, _) |
+            EntryKind::AssocConst(AssocContainer::ImplFinal, qualif, _) => {
                 qualif.mir
             }
             _ => bug!(),
         }
     }
 
-    pub fn get_associated_item(&self, id: DefIndex) -> ty::AssociatedItem {
+    pub fn get_associated_item(&self, id: DefIndex) -> ty::AssocItem {
         let item = self.entry(id);
         let def_key = self.def_key(id);
         let parent = self.local_def_id(def_key.parent.unwrap());
         let name = def_key.disambiguated_data.data.get_opt_name().unwrap();
 
         let (kind, container, has_self) = match item.kind {
-            EntryKind::AssociatedConst(container, _, _) => {
-                (ty::AssociatedKind::Const, container, false)
+            EntryKind::AssocConst(container, _, _) => {
+                (ty::AssocKind::Const, container, false)
             }
             EntryKind::Method(data) => {
                 let data = data.decode(self);
-                (ty::AssociatedKind::Method, data.container, data.has_self)
+                (ty::AssocKind::Method, data.container, data.has_self)
             }
-            EntryKind::AssociatedType(container) => {
-                (ty::AssociatedKind::Type, container, false)
+            EntryKind::AssocType(container) => {
+                (ty::AssocKind::Type, container, false)
             }
-            EntryKind::AssociatedExistential(container) => {
-                (ty::AssociatedKind::Existential, container, false)
+            EntryKind::AssocExistential(container) => {
+                (ty::AssocKind::Existential, container, false)
             }
             _ => bug!("cannot get associated-item of `{:?}`", def_key)
         };
 
-        ty::AssociatedItem {
+        ty::AssocItem {
             ident: Ident::from_interned_str(name),
             kind,
             vis: item.visibility.decode(self),
@@ -1150,7 +1150,7 @@ pub fn exported_symbols(&self,
     pub fn get_rendered_const(&self, id: DefIndex) -> String {
         match self.entry(id).kind {
             EntryKind::Const(_, data) |
-            EntryKind::AssociatedConst(_, _, data) => data.decode(self).0,
+            EntryKind::AssocConst(_, _, data) => data.decode(self).0,
             _ => bug!(),
         }
     }
index 1a9d996131dc0ee9325c99e0fcd94696cfd9ae80..5d080de2645e30a4be6925a235c3f59acb81f0ab 100644 (file)
@@ -822,15 +822,15 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
 
         let container = match trait_item.defaultness {
             hir::Defaultness::Default { has_value: true } =>
-                AssociatedContainer::TraitWithDefault,
+                AssocContainer::TraitWithDefault,
             hir::Defaultness::Default { has_value: false } =>
-                AssociatedContainer::TraitRequired,
+                AssocContainer::TraitRequired,
             hir::Defaultness::Final =>
                 span_bug!(ast_item.span, "traits cannot have final items"),
         };
 
         let kind = match trait_item.kind {
-            ty::AssociatedKind::Const => {
+            ty::AssocKind::Const => {
                 let const_qualif =
                     if let hir::TraitItemKind::Const(_, Some(body)) = ast_item.node {
                         self.const_qualif(0, body)
@@ -842,9 +842,9 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
                     hir::print::to_string(self.tcx.hir(), |s| s.print_trait_item(ast_item));
                 let rendered_const = self.lazy(&RenderedConst(rendered));
 
-                EntryKind::AssociatedConst(container, const_qualif, rendered_const)
+                EntryKind::AssocConst(container, const_qualif, rendered_const)
             }
-            ty::AssociatedKind::Method => {
+            ty::AssocKind::Method => {
                 let fn_data = if let hir::TraitItemKind::Method(_, ref m) = ast_item.node {
                     let arg_names = match *m {
                         hir::TraitMethod::Required(ref names) => {
@@ -868,8 +868,8 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
                     has_self: trait_item.method_has_self_argument,
                 }))
             }
-            ty::AssociatedKind::Type => EntryKind::AssociatedType(container),
-            ty::AssociatedKind::Existential =>
+            ty::AssocKind::Type => EntryKind::AssocType(container),
+            ty::AssocKind::Existential =>
                 span_bug!(ast_item.span, "existential type in trait"),
         };
 
@@ -883,21 +883,21 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
             deprecation: self.encode_deprecation(def_id),
 
             ty: match trait_item.kind {
-                ty::AssociatedKind::Const |
-                ty::AssociatedKind::Method => {
+                ty::AssocKind::Const |
+                ty::AssocKind::Method => {
                     Some(self.encode_item_type(def_id))
                 }
-                ty::AssociatedKind::Type => {
+                ty::AssocKind::Type => {
                     if trait_item.defaultness.has_value() {
                         Some(self.encode_item_type(def_id))
                     } else {
                         None
                     }
                 }
-                ty::AssociatedKind::Existential => unreachable!(),
+                ty::AssocKind::Existential => unreachable!(),
             },
             inherent_impls: LazySeq::empty(),
-            variances: if trait_item.kind == ty::AssociatedKind::Method {
+            variances: if trait_item.kind == ty::AssocKind::Method {
                 self.encode_variances_of(def_id)
             } else {
                 LazySeq::empty()
@@ -931,25 +931,25 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
         let impl_item = self.tcx.associated_item(def_id);
 
         let container = match impl_item.defaultness {
-            hir::Defaultness::Default { has_value: true } => AssociatedContainer::ImplDefault,
-            hir::Defaultness::Final => AssociatedContainer::ImplFinal,
+            hir::Defaultness::Default { has_value: true } => AssocContainer::ImplDefault,
+            hir::Defaultness::Final => AssocContainer::ImplFinal,
             hir::Defaultness::Default { has_value: false } =>
                 span_bug!(ast_item.span, "impl items always have values (currently)"),
         };
 
         let kind = match impl_item.kind {
-            ty::AssociatedKind::Const => {
+            ty::AssocKind::Const => {
                 if let hir::ImplItemKind::Const(_, body_id) = ast_item.node {
                     let mir = self.tcx.at(ast_item.span).mir_const_qualif(def_id).0;
 
-                    EntryKind::AssociatedConst(container,
+                    EntryKind::AssocConst(container,
                         self.const_qualif(mir, body_id),
                         self.encode_rendered_const_for_body(body_id))
                 } else {
                     bug!()
                 }
             }
-            ty::AssociatedKind::Method => {
+            ty::AssocKind::Method => {
                 let fn_data = if let hir::ImplItemKind::Method(ref sig, body) = ast_item.node {
                     FnData {
                         constness: sig.header.constness,
@@ -965,8 +965,8 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
                     has_self: impl_item.method_has_self_argument,
                 }))
             }
-            ty::AssociatedKind::Existential => EntryKind::AssociatedExistential(container),
-            ty::AssociatedKind::Type => EntryKind::AssociatedType(container)
+            ty::AssocKind::Existential => EntryKind::AssocExistential(container),
+            ty::AssocKind::Type => EntryKind::AssocType(container)
         };
 
         let mir =
@@ -996,7 +996,7 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
 
             ty: Some(self.encode_item_type(def_id)),
             inherent_impls: LazySeq::empty(),
-            variances: if impl_item.kind == ty::AssociatedKind::Method {
+            variances: if impl_item.kind == ty::AssocKind::Method {
                 self.encode_variances_of(def_id)
             } else {
                 LazySeq::empty()
index 0ad3251540716306a31594dde118597f6e190e42..b9e5bdef27ab4bd1f6735be43ee4e59ed327aedb 100644 (file)
@@ -253,13 +253,13 @@ pub enum EntryKind<'tcx> {
     Trait(Lazy<TraitData<'tcx>>),
     Impl(Lazy<ImplData<'tcx>>),
     Method(Lazy<MethodData<'tcx>>),
-    AssociatedType(AssociatedContainer),
-    AssociatedExistential(AssociatedContainer),
-    AssociatedConst(AssociatedContainer, ConstQualif, Lazy<RenderedConst>),
+    AssocType(AssocContainer),
+    AssocExistential(AssocContainer),
+    AssocConst(AssocContainer, ConstQualif, Lazy<RenderedConst>),
     TraitAlias(Lazy<TraitAliasData<'tcx>>),
 }
 
-/// Additional data for EntryKind::Const and EntryKind::AssociatedConst
+/// Additional data for EntryKind::Const and EntryKind::AssocConst
 #[derive(Clone, Copy, RustcEncodable, RustcDecodable)]
 pub struct ConstQualif {
     pub mir: u8,
@@ -330,36 +330,36 @@ pub struct ImplData<'tcx> {
 /// is a trait or an impl and whether, in a trait, it has
 /// a default, or an in impl, whether it's marked "default".
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
-pub enum AssociatedContainer {
+pub enum AssocContainer {
     TraitRequired,
     TraitWithDefault,
     ImplDefault,
     ImplFinal,
 }
 
-impl AssociatedContainer {
-    pub fn with_def_id(&self, def_id: DefId) -> ty::AssociatedItemContainer {
+impl AssocContainer {
+    pub fn with_def_id(&self, def_id: DefId) -> ty::AssocItemContainer {
         match *self {
-            AssociatedContainer::TraitRequired |
-            AssociatedContainer::TraitWithDefault => ty::TraitContainer(def_id),
+            AssocContainer::TraitRequired |
+            AssocContainer::TraitWithDefault => ty::TraitContainer(def_id),
 
-            AssociatedContainer::ImplDefault |
-            AssociatedContainer::ImplFinal => ty::ImplContainer(def_id),
+            AssocContainer::ImplDefault |
+            AssocContainer::ImplFinal => ty::ImplContainer(def_id),
         }
     }
 
     pub fn defaultness(&self) -> hir::Defaultness {
         match *self {
-            AssociatedContainer::TraitRequired => hir::Defaultness::Default {
+            AssocContainer::TraitRequired => hir::Defaultness::Default {
                 has_value: false,
             },
 
-            AssociatedContainer::TraitWithDefault |
-            AssociatedContainer::ImplDefault => hir::Defaultness::Default {
+            AssocContainer::TraitWithDefault |
+            AssocContainer::ImplDefault => hir::Defaultness::Default {
                 has_value: true,
             },
 
-            AssociatedContainer::ImplFinal => hir::Defaultness::Final,
+            AssocContainer::ImplFinal => hir::Defaultness::Final,
         }
     }
 }
@@ -367,7 +367,7 @@ pub fn defaultness(&self) -> hir::Defaultness {
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct MethodData<'tcx> {
     pub fn_data: FnData<'tcx>,
-    pub container: AssociatedContainer,
+    pub container: AssocContainer,
     pub has_self: bool,
 }
 
index 4253962f144513d67f5289eaf5ff1f7bc3f71f9c..8022d1f0c7315dfd38dcd6397fb7d19d609b4e05 100644 (file)
@@ -158,18 +158,6 @@ pub(super) fn report_use_of_moved_or_uninitialized(
                         span,
                         format!("value moved{} here, in previous iteration of loop", move_msg),
                     );
-                    if Some(CompilerDesugaringKind::ForLoop) == span.compiler_desugaring_kind() {
-                        if let Ok(snippet) = self.infcx.tcx.sess.source_map()
-                            .span_to_snippet(span)
-                        {
-                            err.span_suggestion(
-                                move_span,
-                                "consider borrowing this to avoid moving it into the for loop",
-                                format!("&{}", snippet),
-                                Applicability::MaybeIncorrect,
-                            );
-                        }
-                    }
                     is_loop_move = true;
                 } else if move_site.traversed_back_edge {
                     err.span_label(
@@ -185,7 +173,17 @@ pub(super) fn report_use_of_moved_or_uninitialized(
                         &mut err,
                         format!("variable moved due to use{}", move_spans.describe()),
                     );
-                };
+                }
+                if Some(CompilerDesugaringKind::ForLoop) == move_span.compiler_desugaring_kind() {
+                    if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
+                        err.span_suggestion(
+                            move_span,
+                            "consider borrowing to avoid moving into the for loop",
+                            format!("&{}", snippet),
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                }
             }
 
             use_spans.var_span_label(
index 549f3b905559d002834a2d1a811b8af59676e5c5..63d5cd4372f4a1f11736427266c5567804bd14c5 100644 (file)
@@ -242,12 +242,7 @@ fn report(&mut self, error: GroupedMoveError<'tcx>) {
         let (mut err, err_span) = {
             let (span, original_path, kind): (Span, &Place<'tcx>, &IllegalMoveOriginKind<'_>) =
                 match error {
-                    GroupedMoveError::MovesFromPlace {
-                        span,
-                        ref original_path,
-                        ref kind,
-                        ..
-                    } |
+                    GroupedMoveError::MovesFromPlace { span, ref original_path, ref kind, .. } |
                     GroupedMoveError::MovesFromValue { span, ref original_path, ref kind, .. } |
                     GroupedMoveError::OtherIllegalMove { span, ref original_path, ref kind } => {
                         (span, original_path, kind)
@@ -257,81 +252,99 @@ fn report(&mut self, error: GroupedMoveError<'tcx>) {
             debug!("report: original_path={:?} span={:?}, kind={:?} \
                    original_path.is_upvar_field_projection={:?}", original_path, span, kind,
                    self.is_upvar_field_projection(original_path));
-            (
-                match kind {
-                    IllegalMoveOriginKind::Static => {
-                        self.infcx.tcx.cannot_move_out_of(span, "static item", origin)
-                    }
-                    IllegalMoveOriginKind::BorrowedContent { target_place: place } => {
-                        // Inspect the type of the content behind the
-                        // borrow to provide feedback about why this
-                        // was a move rather than a copy.
-                        let ty = place.ty(self.mir, self.infcx.tcx).ty;
-                        let is_upvar_field_projection =
-                            self.prefixes(&original_path, PrefixSet::All)
-                            .any(|p| self.is_upvar_field_projection(p).is_some());
-                        debug!("report: ty={:?}", ty);
-                        match ty.sty {
-                            ty::Array(..) | ty::Slice(..) =>
-                                self.infcx.tcx.cannot_move_out_of_interior_noncopy(
-                                    span, ty, None, origin
-                                ),
-                            ty::Closure(def_id, closure_substs)
-                                if def_id == self.mir_def_id && is_upvar_field_projection
-                            => {
-                                let closure_kind_ty =
-                                    closure_substs.closure_kind_ty(def_id, self.infcx.tcx);
-                                let closure_kind = closure_kind_ty.to_opt_closure_kind();
-                                let place_description = match closure_kind {
-                                    Some(ty::ClosureKind::Fn) => {
-                                        "captured variable in an `Fn` closure"
-                                    }
-                                    Some(ty::ClosureKind::FnMut) => {
-                                        "captured variable in an `FnMut` closure"
-                                    }
-                                    Some(ty::ClosureKind::FnOnce) => {
-                                        bug!("closure kind does not match first argument type")
-                                    }
-                                    None => bug!("closure kind not inferred by borrowck"),
-                                };
-                                debug!("report: closure_kind_ty={:?} closure_kind={:?} \
-                                       place_description={:?}", closure_kind_ty, closure_kind,
-                                       place_description);
-
-                                let mut diag = self.infcx.tcx.cannot_move_out_of(
-                                    span, place_description, origin);
-
-                                for prefix in self.prefixes(&original_path, PrefixSet::All) {
-                                    if let Some(field) = self.is_upvar_field_projection(prefix) {
-                                        let upvar_hir_id = self.upvars[field.index()].var_hir_id;
-                                        let upvar_span = self.infcx.tcx.hir().span_by_hir_id(
-                                            upvar_hir_id);
-                                        diag.span_label(upvar_span, "captured outer variable");
-                                        break;
-                                    }
+            let err = match kind {
+                IllegalMoveOriginKind::Static => {
+                    self.infcx.tcx.cannot_move_out_of(span, "static item", origin)
+                }
+                IllegalMoveOriginKind::BorrowedContent { target_place: place } => {
+                    // Inspect the type of the content behind the
+                    // borrow to provide feedback about why this
+                    // was a move rather than a copy.
+                    let ty = place.ty(self.mir, self.infcx.tcx).ty;
+                    let is_upvar_field_projection =
+                        self.prefixes(&original_path, PrefixSet::All)
+                        .any(|p| self.is_upvar_field_projection(p).is_some());
+                    debug!("report: ty={:?}", ty);
+                    let mut err = match ty.sty {
+                        ty::Array(..) | ty::Slice(..) =>
+                            self.infcx.tcx.cannot_move_out_of_interior_noncopy(
+                                span, ty, None, origin
+                            ),
+                        ty::Closure(def_id, closure_substs)
+                            if def_id == self.mir_def_id && is_upvar_field_projection
+                        => {
+                            let closure_kind_ty =
+                                closure_substs.closure_kind_ty(def_id, self.infcx.tcx);
+                            let closure_kind = closure_kind_ty.to_opt_closure_kind();
+                            let place_description = match closure_kind {
+                                Some(ty::ClosureKind::Fn) => {
+                                    "captured variable in an `Fn` closure"
+                                }
+                                Some(ty::ClosureKind::FnMut) => {
+                                    "captured variable in an `FnMut` closure"
+                                }
+                                Some(ty::ClosureKind::FnOnce) => {
+                                    bug!("closure kind does not match first argument type")
+                                }
+                                None => bug!("closure kind not inferred by borrowck"),
+                            };
+                            debug!("report: closure_kind_ty={:?} closure_kind={:?} \
+                                    place_description={:?}", closure_kind_ty, closure_kind,
+                                    place_description);
+
+                            let mut diag = self.infcx.tcx.cannot_move_out_of(
+                                span, place_description, origin);
+
+                            for prefix in self.prefixes(&original_path, PrefixSet::All) {
+                                if let Some(field) = self.is_upvar_field_projection(prefix) {
+                                    let upvar_hir_id = self.upvars[field.index()].var_hir_id;
+                                    let upvar_span = self.infcx.tcx.hir().span_by_hir_id(
+                                        upvar_hir_id);
+                                    diag.span_label(upvar_span, "captured outer variable");
+                                    break;
                                 }
-
-                                diag
                             }
-                            _ => {
-                                let source = self.borrowed_content_source(place);
-                                self.infcx.tcx.cannot_move_out_of(
-                                    span, &source.to_string(), origin
-                                )
-                            },
+
+                            diag
                         }
+                        _ => {
+                            let source = self.borrowed_content_source(place);
+                            self.infcx.tcx.cannot_move_out_of(
+                                span, &source.to_string(), origin
+                            )
+                        },
+                    };
+                    let orig_path_ty = format!(
+                        "{:?}",
+                        original_path.ty(self.mir, self.infcx.tcx).ty,
+                    );
+                    let snippet = self.infcx.tcx.sess.source_map().span_to_snippet(span).unwrap();
+                    let is_option = orig_path_ty.starts_with("std::option::Option");
+                    let is_result = orig_path_ty.starts_with("std::result::Result");
+                    if  is_option || is_result {
+                        err.span_suggestion(
+                            span,
+                            &format!("consider borrowing the `{}`'s content", if is_option {
+                                "Option"
+                            } else {
+                                "Result"
+                            }),
+                            format!("{}.as_ref()", snippet),
+                            Applicability::MaybeIncorrect,
+                        );
                     }
-                    IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
-                        self.infcx.tcx
-                            .cannot_move_out_of_interior_of_drop(span, ty, origin)
-                    }
-                    IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } =>
-                        self.infcx.tcx.cannot_move_out_of_interior_noncopy(
-                            span, ty, Some(*is_index), origin
-                        ),
-                },
-                span,
-            )
+                    err
+                }
+                IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
+                    self.infcx.tcx
+                        .cannot_move_out_of_interior_of_drop(span, ty, origin)
+                }
+                IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } =>
+                    self.infcx.tcx.cannot_move_out_of_interior_noncopy(
+                        span, ty, Some(*is_index), origin
+                    ),
+            };
+            (err, span)
         };
 
         self.add_move_hints(error, &mut err, err_span);
index ac44364aa695ebc1a89371ebc54fe914a4b60460..de8e75ca277ee78e54bf0056773510b617a32572 100644 (file)
@@ -29,7 +29,7 @@
 use rustc::infer::type_variable::TypeVariableOrigin;
 use rustc::mir::interpret::{InterpError::BoundsCheck, ConstValue};
 use rustc::mir::tcx::PlaceTy;
-use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext};
+use rustc::mir::visit::{PlaceContext, Visitor, NonMutatingUseContext};
 use rustc::mir::*;
 use rustc::traits::query::type_op;
 use rustc::traits::query::type_op::custom::CustomTypeOp;
@@ -447,92 +447,95 @@ fn sanitize_place(
         context: PlaceContext,
     ) -> PlaceTy<'tcx> {
         debug!("sanitize_place: {:?}", place);
-        let place_ty = match place {
-            Place::Base(PlaceBase::Local(index)) =>
-                PlaceTy::from_ty(self.mir.local_decls[*index].ty),
-            Place::Base(PlaceBase::Static(box Static { kind, ty: sty })) => {
-                let sty = self.sanitize_type(place, sty);
-                let check_err =
-                    |verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx>,
-                     place: &Place<'tcx>,
-                     ty,
-                     sty| {
-                        if let Err(terr) = verifier.cx.eq_types(
-                            sty,
-                            ty,
-                            location.to_locations(),
-                            ConstraintCategory::Boring,
-                        ) {
-                            span_mirbug!(
-                            verifier,
-                            place,
-                            "bad promoted type ({:?}: {:?}): {:?}",
-                            ty,
-                            sty,
-                            terr
-                        );
+
+        place.iterate(|place_base, place_projection| {
+            let mut place_ty = match place_base {
+                PlaceBase::Local(index) =>
+                    PlaceTy::from_ty(self.mir.local_decls[*index].ty),
+                PlaceBase::Static(box Static { kind, ty: sty }) => {
+                    let sty = self.sanitize_type(place, sty);
+                    let check_err =
+                        |verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx>,
+                         place: &Place<'tcx>,
+                         ty,
+                         sty| {
+                            if let Err(terr) = verifier.cx.eq_types(
+                                sty,
+                                ty,
+                                location.to_locations(),
+                                ConstraintCategory::Boring,
+                            ) {
+                                span_mirbug!(
+                                verifier,
+                                place,
+                                "bad promoted type ({:?}: {:?}): {:?}",
+                                ty,
+                                sty,
+                                terr
+                            );
+                            };
                         };
-                    };
-                match kind {
-                    StaticKind::Promoted(promoted) => {
-                        if !self.errors_reported {
-                            let promoted_mir = &self.mir.promoted[*promoted];
-                            self.sanitize_promoted(promoted_mir, location);
-
-                            let promoted_ty = promoted_mir.return_ty();
-                            check_err(self, place, promoted_ty, sty);
+                    match kind {
+                        StaticKind::Promoted(promoted) => {
+                            if !self.errors_reported {
+                                let promoted_mir = &self.mir.promoted[*promoted];
+                                self.sanitize_promoted(promoted_mir, location);
+
+                                let promoted_ty = promoted_mir.return_ty();
+                                check_err(self, place, promoted_ty, sty);
+                            }
                         }
-                    }
-                    StaticKind::Static(def_id) => {
-                        let ty = self.tcx().type_of(*def_id);
-                        let ty = self.cx.normalize(ty, location);
+                        StaticKind::Static(def_id) => {
+                            let ty = self.tcx().type_of(*def_id);
+                            let ty = self.cx.normalize(ty, location);
 
-                        check_err(self, place, ty, sty);
+                            check_err(self, place, ty, sty);
+                        }
                     }
+                    PlaceTy::from_ty(sty)
+                }
+            };
+
+            // FIXME use place_projection.is_empty() when is available
+            if let Place::Base(_) = place {
+                if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
+                    let tcx = self.tcx();
+                    let trait_ref = ty::TraitRef {
+                        def_id: tcx.lang_items().copy_trait().unwrap(),
+                        substs: tcx.mk_substs_trait(place_ty.ty, &[]),
+                    };
+
+                    // In order to have a Copy operand, the type T of the
+                    // value must be Copy. Note that we prove that T: Copy,
+                    // rather than using the `is_copy_modulo_regions`
+                    // test. This is important because
+                    // `is_copy_modulo_regions` ignores the resulting region
+                    // obligations and assumes they pass. This can result in
+                    // bounds from Copy impls being unsoundly ignored (e.g.,
+                    // #29149). Note that we decide to use Copy before knowing
+                    // whether the bounds fully apply: in effect, the rule is
+                    // that if a value of some type could implement Copy, then
+                    // it must.
+                    self.cx.prove_trait_ref(
+                        trait_ref,
+                        location.to_locations(),
+                        ConstraintCategory::CopyBound,
+                    );
                 }
-                PlaceTy::from_ty(sty)
             }
-            Place::Projection(ref proj) => {
-                let base_context = if context.is_mutating_use() {
-                    PlaceContext::MutatingUse(MutatingUseContext::Projection)
-                } else {
-                    PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
-                };
-                let base_ty = self.sanitize_place(&proj.base, location, base_context);
-                if base_ty.variant_index.is_none() {
-                    if base_ty.ty.references_error() {
+
+            for proj in place_projection {
+                if place_ty.variant_index.is_none() {
+                    if place_ty.ty.references_error() {
                         assert!(self.errors_reported);
                         return PlaceTy::from_ty(self.tcx().types.err);
                     }
                 }
-                self.sanitize_projection(base_ty, &proj.elem, place, location)
+                place_ty = self.sanitize_projection(place_ty, &proj.elem, place, location)
             }
-        };
-        if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
-            let tcx = self.tcx();
-            let trait_ref = ty::TraitRef {
-                def_id: tcx.lang_items().copy_trait().unwrap(),
-                substs: tcx.mk_substs_trait(place_ty.ty, &[]),
-            };
 
-            // In order to have a Copy operand, the type T of the
-            // value must be Copy. Note that we prove that T: Copy,
-            // rather than using the `is_copy_modulo_regions`
-            // test. This is important because
-            // `is_copy_modulo_regions` ignores the resulting region
-            // obligations and assumes they pass. This can result in
-            // bounds from Copy impls being unsoundly ignored (e.g.,
-            // #29149). Note that we decide to use Copy before knowing
-            // whether the bounds fully apply: in effect, the rule is
-            // that if a value of some type could implement Copy, then
-            // it must.
-            self.cx.prove_trait_ref(
-                trait_ref,
-                location.to_locations(),
-                ConstraintCategory::CopyBound,
-            );
-        }
-        place_ty
+            place_ty
+        })
     }
 
     fn sanitize_promoted(&mut self, promoted_mir: &'b Mir<'tcx>, location: Location) {
index 0c2a4ef45f104f3986d33da833a689eb1e30913c..caef8d8bc5a925820b1f7b1ec86581757113d220 100644 (file)
@@ -131,22 +131,20 @@ pub(super) fn is_active<'tcx>(
 /// Determines if a given borrow is borrowing local data
 /// This is called for all Yield statements on movable generators
 pub(super) fn borrow_of_local_data<'tcx>(place: &Place<'tcx>) -> bool {
-    match place {
-        Place::Base(PlaceBase::Static(..)) => false,
-        Place::Base(PlaceBase::Local(..)) => true,
-        Place::Projection(box proj) => {
-            match proj.elem {
-                // Reborrow of already borrowed data is ignored
-                // Any errors will be caught on the initial borrow
-                ProjectionElem::Deref => false,
+    place.iterate(|place_base, place_projection| {
+        match place_base {
+            PlaceBase::Static(..) => return false,
+            PlaceBase::Local(..) => {},
+        }
 
-                // For interior references and downcasts, find out if the base is local
-                ProjectionElem::Field(..)
-                    | ProjectionElem::Index(..)
-                    | ProjectionElem::ConstantIndex { .. }
-                | ProjectionElem::Subslice { .. }
-                | ProjectionElem::Downcast(..) => borrow_of_local_data(&proj.base),
+        for proj in place_projection {
+            // Reborrow of already borrowed data is ignored
+            // Any errors will be caught on the initial borrow
+            if proj.elem == ProjectionElem::Deref {
+                return false;
             }
         }
-    }
+
+        true
+    })
 }
index cf9a6165d71a249159c6e28d500523f0cd5eb7ad..9ad0e936e1b2d7b4283bd0b0c5f8f2134106eb8e 100644 (file)
@@ -25,40 +25,36 @@ fn ignore_borrow(
         mir: &Mir<'tcx>,
         locals_state_at_exit: &LocalsStateAtExit,
     ) -> bool {
-        match self {
-            // If a local variable is immutable, then we only need to track borrows to guard
-            // against two kinds of errors:
-            // * The variable being dropped while still borrowed (e.g., because the fn returns
-            //   a reference to a local variable)
-            // * The variable being moved while still borrowed
-            //
-            // In particular, the variable cannot be mutated -- the "access checks" will fail --
-            // so we don't have to worry about mutation while borrowed.
-            Place::Base(PlaceBase::Local(index)) => {
-                match locals_state_at_exit {
-                    LocalsStateAtExit::AllAreInvalidated => false,
-                    LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => {
-                        let ignore = !has_storage_dead_or_moved.contains(*index) &&
-                            mir.local_decls[*index].mutability == Mutability::Not;
-                        debug!("ignore_borrow: local {:?} => {:?}", index, ignore);
-                        ignore
+        self.iterate(|place_base, place_projection| {
+            let ignore = match place_base {
+                // If a local variable is immutable, then we only need to track borrows to guard
+                // against two kinds of errors:
+                // * The variable being dropped while still borrowed (e.g., because the fn returns
+                //   a reference to a local variable)
+                // * The variable being moved while still borrowed
+                //
+                // In particular, the variable cannot be mutated -- the "access checks" will fail --
+                // so we don't have to worry about mutation while borrowed.
+                PlaceBase::Local(index) => {
+                    match locals_state_at_exit {
+                        LocalsStateAtExit::AllAreInvalidated => false,
+                        LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => {
+                            let ignore = !has_storage_dead_or_moved.contains(*index) &&
+                                mir.local_decls[*index].mutability == Mutability::Not;
+                            debug!("ignore_borrow: local {:?} => {:?}", index, ignore);
+                            ignore
+                        }
                     }
                 }
-            }
-            Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) =>
-                false,
-            Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
-                tcx.is_mutable_static(*def_id)
-            }
-            Place::Projection(proj) => match proj.elem {
-                ProjectionElem::Field(..)
-                | ProjectionElem::Downcast(..)
-                | ProjectionElem::Subslice { .. }
-                | ProjectionElem::ConstantIndex { .. }
-                | ProjectionElem::Index(_) => proj.base.ignore_borrow(
-                    tcx, mir, locals_state_at_exit),
+                PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. }) =>
+                    false,
+                PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. }) => {
+                    tcx.is_mutable_static(*def_id)
+                }
+            };
 
-                ProjectionElem::Deref => {
+            for proj in place_projection {
+                if proj.elem == ProjectionElem::Deref {
                     let ty = proj.base.ty(mir, tcx).ty;
                     match ty.sty {
                         // For both derefs of raw pointers and `&T`
@@ -71,11 +67,13 @@ fn ignore_borrow(
                         // original path into a new variable and
                         // borrowed *that* one, leaving the original
                         // path unborrowed.
-                        ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) => true,
-                        _ => proj.base.ignore_borrow(tcx, mir, locals_state_at_exit),
+                        ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) => return true,
+                        _ => {}
                     }
                 }
-            },
-        }
+            }
+
+            ignore
+        })
     }
 }
index a0b504a99de9a7981778362410688bec60663dd7..07a9f294fb68cd455919ee2a63fa429b1053ff4d 100644 (file)
@@ -528,13 +528,9 @@ fn limit_capture_mutability(
             }) => {
                 // Not projected from the implicit `self` in a closure.
                 debug_assert!(
-                    match *base {
-                        Place::Base(PlaceBase::Local(local)) => local == Local::new(1),
-                        Place::Projection(box Projection {
-                            ref base,
-                            elem: ProjectionElem::Deref,
-                        }) => *base == Place::Base(PlaceBase::Local(Local::new(1))),
-                        _ => false,
+                    match base.local() {
+                        Some(local) => local == Local::new(1),
+                        None => false,
                     },
                     "Unexpected capture place"
                 );
index 58ca35abcb123ddb5f8cbec5470d3e652b80325f..8c2ef082c339fc2af044a52323bf30709c692f7a 100644 (file)
@@ -737,12 +737,12 @@ enum TestKind<'tcx> {
     SwitchInt {
         switch_ty: Ty<'tcx>,
         options: Vec<u128>,
-        indices: FxHashMap<ty::Const<'tcx>, usize>,
+        indices: FxHashMap<&'tcx ty::Const<'tcx>, usize>,
     },
 
     // test for equality
     Eq {
-        value: ty::Const<'tcx>,
+        value: &'tcx ty::Const<'tcx>,
         ty: Ty<'tcx>,
     },
 
index a5834b02ffc82858719a3d0497442808a3dba797..0995a2f7fdf491ec37bf0cb0adc4453e5e4f0c1d 100644 (file)
@@ -98,7 +98,7 @@ pub fn add_cases_to_switch<'pat>(&mut self,
                                      candidate: &Candidate<'pat, 'tcx>,
                                      switch_ty: Ty<'tcx>,
                                      options: &mut Vec<u128>,
-                                     indices: &mut FxHashMap<ty::Const<'tcx>, usize>)
+                                     indices: &mut FxHashMap<&'tcx ty::Const<'tcx>, usize>)
                                      -> bool
     {
         let match_pair = match candidate.match_pairs.iter().find(|mp| mp.place == *test_place) {
@@ -305,7 +305,6 @@ pub fn perform_test(&mut self,
                     }
                     let eq_def_id = self.hir.tcx().lang_items().eq_trait().unwrap();
                     let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, &[ty.into()]);
-                    let method = self.hir.tcx().mk_const(method);
 
                     let re_erased = self.hir.tcx().lifetimes.re_erased;
                     // take the argument by reference
@@ -371,8 +370,8 @@ pub fn perform_test(&mut self,
 
             TestKind::Range(PatternRange { ref lo, ref hi, ty, ref end }) => {
                 // Test `val` by computing `lo <= val && val <= hi`, using primitive comparisons.
-                let lo = self.literal_operand(test.span, ty.clone(), lo.clone());
-                let hi = self.literal_operand(test.span, ty.clone(), hi.clone());
+                let lo = self.literal_operand(test.span, ty, lo);
+                let hi = self.literal_operand(test.span, ty, hi);
                 let val = Operand::Copy(place.clone());
 
                 let fail = self.cfg.start_new_block();
@@ -724,7 +723,7 @@ fn error_simplifyable<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> !
     fn const_range_contains(
         &self,
         range: PatternRange<'tcx>,
-        value: ty::Const<'tcx>,
+        value: &'tcx ty::Const<'tcx>,
     ) -> Option<bool> {
         use std::cmp::Ordering::*;
 
@@ -744,7 +743,7 @@ fn const_range_contains(
     fn values_not_contained_in_range(
         &self,
         range: PatternRange<'tcx>,
-        indices: &FxHashMap<ty::Const<'tcx>, usize>,
+        indices: &FxHashMap<&'tcx ty::Const<'tcx>, usize>,
     ) -> Option<bool> {
         for &val in indices.keys() {
             if self.const_range_contains(range, val)? {
index d71a13dec5a2f971340dd3acf5bd6589ec9da708..daf59d7a1353c1f70913c51ebf5d343b18b88643 100644 (file)
@@ -27,13 +27,13 @@ pub fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'tcx> {
     pub fn literal_operand(&mut self,
                            span: Span,
                            ty: Ty<'tcx>,
-                           literal: ty::Const<'tcx>)
+                           literal: &'tcx ty::Const<'tcx>)
                            -> Operand<'tcx> {
         let constant = box Constant {
             span,
             ty,
             user_ty: None,
-            literal: self.hir.tcx().mk_const(literal),
+            literal,
         };
         Operand::Constant(constant)
     }
index 866b6492d10bcbfa85cc85f6fe6f3405c11d0988..c43bc41ba685ec7d1b1881fa6d4bf0223bab11f2 100644 (file)
@@ -5,6 +5,7 @@
 use std::borrow::{Borrow, Cow};
 use std::hash::Hash;
 use std::collections::hash_map::Entry;
+use std::convert::TryInto;
 
 use rustc::hir::def::DefKind;
 use rustc::hir::def_id::DefId;
@@ -65,7 +66,7 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>(
 fn mplace_to_const<'tcx>(
     ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
     mplace: MPlaceTy<'tcx>,
-) -> ty::Const<'tcx> {
+) -> &'tcx ty::Const<'tcx> {
     let MemPlace { ptr, align, meta } = *mplace;
     // extract alloc-offset pair
     assert!(meta.is_none());
@@ -79,17 +80,24 @@ fn mplace_to_const<'tcx>(
     // interned this?  I thought that is the entire point of that `FinishStatic` stuff?
     let alloc = ecx.tcx.intern_const_alloc(alloc);
     let val = ConstValue::ByRef(ptr, alloc);
-    ty::Const { val, ty: mplace.layout.ty }
+    ecx.tcx.mk_const(ty::Const { val, ty: mplace.layout.ty })
 }
 
 fn op_to_const<'tcx>(
     ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
     op: OpTy<'tcx>,
-) -> ty::Const<'tcx> {
+) -> &'tcx ty::Const<'tcx> {
     // We do not normalize just any data.  Only non-union scalars and slices.
     let normalize = match op.layout.abi {
         layout::Abi::Scalar(..) => op.layout.ty.ty_adt_def().map_or(true, |adt| !adt.is_union()),
-        layout::Abi::ScalarPair(..) => op.layout.ty.is_slice(),
+        layout::Abi::ScalarPair(..) => match op.layout.ty.sty {
+            ty::Ref(_, inner, _) => match inner.sty {
+                ty::Slice(elem) => elem == ecx.tcx.types.u8,
+                ty::Str => true,
+                _ => false,
+            },
+            _ => false,
+        },
         _ => false,
     };
     let normalized_op = if normalize {
@@ -101,10 +109,28 @@ fn op_to_const<'tcx>(
         Ok(mplace) => return mplace_to_const(ecx, mplace),
         Err(Immediate::Scalar(x)) =>
             ConstValue::Scalar(x.not_undef().unwrap()),
-        Err(Immediate::ScalarPair(a, b)) =>
-            ConstValue::Slice(a.not_undef().unwrap(), b.to_usize(ecx).unwrap()),
+        Err(Immediate::ScalarPair(a, b)) => {
+            let (data, start) = match a.not_undef().unwrap() {
+                Scalar::Ptr(ptr) => (
+                    ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id),
+                    ptr.offset.bytes(),
+                ),
+                Scalar::Bits { .. } => (
+                    ecx.tcx.intern_const_alloc(Allocation::from_byte_aligned_bytes(b"", ())),
+                    0,
+                ),
+            };
+            let len = b.to_usize(&ecx.tcx.tcx).unwrap();
+            let start = start.try_into().unwrap();
+            let len: usize = len.try_into().unwrap();
+            ConstValue::Slice {
+                data,
+                start,
+                end: start + len,
+            }
+        },
     };
-    ty::Const { val, ty: op.layout.ty }
+    ecx.tcx.mk_const(ty::Const { val, ty: op.layout.ty })
 }
 
 // Returns a pointer to where the result lives
@@ -450,8 +476,8 @@ pub fn const_field<'a, 'tcx>(
     param_env: ty::ParamEnv<'tcx>,
     variant: Option<VariantIdx>,
     field: mir::Field,
-    value: ty::Const<'tcx>,
-) -> ty::Const<'tcx> {
+    value: &'tcx ty::Const<'tcx>,
+) -> &'tcx ty::Const<'tcx> {
     trace!("const_field: {:?}, {:?}", field, value);
     let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env);
     // get the operand again
@@ -473,7 +499,7 @@ pub fn const_field<'a, 'tcx>(
 pub fn const_variant_index<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-    val: ty::Const<'tcx>,
+    val: &'tcx ty::Const<'tcx>,
 ) -> VariantIdx {
     trace!("const_variant_index: {:?}", val);
     let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env);
@@ -641,7 +667,7 @@ pub fn const_eval_raw_provider<'a, 'tcx>(
                 // note that validation may still cause a hard error on this very same constant,
                 // because any code that existed before validation could not have failed validation
                 // thus preventing such a hard error from being a backwards compatibility hazard
-                Some(DefKind::Const) | Some(DefKind::AssociatedConst) => {
+                Some(DefKind::Const) | Some(DefKind::AssocConst) => {
                     let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
                     err.report_as_lint(
                         tcx.at(tcx.def_span(def_id)),
index 42c2387b7052da02d6949cb95e37f0bd34f5d892..65cbc83fbcb84edb7337bb89f873bb30e4d9dac6 100644 (file)
@@ -91,16 +91,19 @@ struct BorrowedLocalsVisitor<'b, 'c: 'b> {
 }
 
 fn find_local<'tcx>(place: &Place<'tcx>) -> Option<Local> {
-    match *place {
-        Place::Base(PlaceBase::Local(l)) => Some(l),
-        Place::Base(PlaceBase::Static(..)) => None,
-        Place::Projection(ref proj) => {
-            match proj.elem {
-                ProjectionElem::Deref => None,
-                _ => find_local(&proj.base)
+    place.iterate(|place_base, place_projection| {
+        for proj in place_projection {
+            if proj.elem == ProjectionElem::Deref {
+                return None;
             }
         }
-    }
+
+        if let PlaceBase::Local(local) = place_base {
+            Some(*local)
+        } else {
+            None
+        }
+    })
 }
 
 impl<'tcx, 'b, 'c> Visitor<'tcx> for BorrowedLocalsVisitor<'b, 'c> {
index 7eb4428bf29530fa24a8daed0f69fc8574a945b9..ab0a2d87302c8fab064cecb9a3fde0f2f1dda68d 100644 (file)
@@ -95,15 +95,80 @@ fn move_path_for(&mut self, place: &Place<'tcx>)
                      -> Result<MovePathIndex, MoveError<'tcx>>
     {
         debug!("lookup({:?})", place);
-        match *place {
-            Place::Base(PlaceBase::Local(local)) => Ok(self.builder.data.rev_lookup.locals[local]),
-            Place::Base(PlaceBase::Static(..)) => {
-                Err(MoveError::cannot_move_out_of(self.loc, Static))
-            }
-            Place::Projection(ref proj) => {
-                self.move_path_for_projection(place, proj)
+        place.iterate(|place_base, place_projection| {
+            let mut base = match place_base {
+                PlaceBase::Local(local) => self.builder.data.rev_lookup.locals[*local],
+                PlaceBase::Static(..) => {
+                    return Err(MoveError::cannot_move_out_of(self.loc, Static));
+                }
+            };
+
+            for proj in place_projection {
+                let mir = self.builder.mir;
+                let tcx = self.builder.tcx;
+                let place_ty = proj.base.ty(mir, tcx).ty;
+                match place_ty.sty {
+                    ty::Ref(..) | ty::RawPtr(..) =>
+                        return Err(MoveError::cannot_move_out_of(
+                            self.loc,
+                            BorrowedContent {
+                                target_place: Place::Projection(Box::new(proj.clone())),
+                            })),
+                    ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() =>
+                        return Err(MoveError::cannot_move_out_of(self.loc,
+                                                                 InteriorOfTypeWithDestructor {
+                            container_ty: place_ty
+                        })),
+                    // move out of union - always move the entire union
+                    ty::Adt(adt, _) if adt.is_union() =>
+                        return Err(MoveError::UnionMove { path: base }),
+                    ty::Slice(_) =>
+                        return Err(MoveError::cannot_move_out_of(
+                            self.loc,
+                            InteriorOfSliceOrArray {
+                                ty: place_ty, is_index: match proj.elem {
+                                    ProjectionElem::Index(..) => true,
+                                    _ => false
+                                },
+                            })),
+                    ty::Array(..) => match proj.elem {
+                        ProjectionElem::Index(..) =>
+                            return Err(MoveError::cannot_move_out_of(
+                                self.loc,
+                                InteriorOfSliceOrArray {
+                                    ty: place_ty, is_index: true
+                                })),
+                        _ => {
+                            // FIXME: still badly broken
+                        }
+                    },
+                    _ => {}
+                };
+
+                base = match self
+                    .builder
+                    .data
+                    .rev_lookup
+                    .projections
+                    .entry((base, proj.elem.lift()))
+                {
+                    Entry::Occupied(ent) => *ent.get(),
+                    Entry::Vacant(ent) => {
+                        let path = MoveDataBuilder::new_move_path(
+                            &mut self.builder.data.move_paths,
+                            &mut self.builder.data.path_map,
+                            &mut self.builder.data.init_path_map,
+                            Some(base),
+                            Place::Projection(Box::new(proj.clone())),
+                        );
+                        ent.insert(path);
+                        path
+                    }
+                };
             }
-        }
+
+            Ok(base)
+        })
     }
 
     fn create_move_path(&mut self, place: &Place<'tcx>) {
@@ -111,66 +176,6 @@ fn create_move_path(&mut self, place: &Place<'tcx>) {
         // drop), so this not being a valid move path is OK.
         let _ = self.move_path_for(place);
     }
-
-    fn move_path_for_projection(&mut self,
-                                place: &Place<'tcx>,
-                                proj: &Projection<'tcx>)
-                                -> Result<MovePathIndex, MoveError<'tcx>>
-    {
-        let base = self.move_path_for(&proj.base)?;
-        let mir = self.builder.mir;
-        let tcx = self.builder.tcx;
-        let place_ty = proj.base.ty(mir, tcx).ty;
-        match place_ty.sty {
-            ty::Ref(..) | ty::RawPtr(..) =>
-                return Err(MoveError::cannot_move_out_of(
-                    self.loc,
-                    BorrowedContent { target_place: place.clone() })),
-            ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() =>
-                return Err(MoveError::cannot_move_out_of(self.loc,
-                                                         InteriorOfTypeWithDestructor {
-                    container_ty: place_ty
-                })),
-            // move out of union - always move the entire union
-            ty::Adt(adt, _) if adt.is_union() =>
-                return Err(MoveError::UnionMove { path: base }),
-            ty::Slice(_) =>
-                return Err(MoveError::cannot_move_out_of(
-                    self.loc,
-                    InteriorOfSliceOrArray {
-                        ty: place_ty, is_index: match proj.elem {
-                            ProjectionElem::Index(..) => true,
-                            _ => false
-                        },
-                    })),
-            ty::Array(..) => match proj.elem {
-                ProjectionElem::Index(..) =>
-                    return Err(MoveError::cannot_move_out_of(
-                        self.loc,
-                        InteriorOfSliceOrArray {
-                            ty: place_ty, is_index: true
-                        })),
-                _ => {
-                    // FIXME: still badly broken
-                }
-            },
-            _ => {}
-        };
-        match self.builder.data.rev_lookup.projections.entry((base, proj.elem.lift())) {
-            Entry::Occupied(ent) => Ok(*ent.get()),
-            Entry::Vacant(ent) => {
-                let path = MoveDataBuilder::new_move_path(
-                    &mut self.builder.data.move_paths,
-                    &mut self.builder.data.path_map,
-                    &mut self.builder.data.init_path_map,
-                    Some(base),
-                    place.clone()
-                );
-                ent.insert(path);
-                Ok(path)
-            }
-        }
-    }
 }
 
 impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
index 6d619793160fba312112709aa02b49f52a5ba0d3..7aaf44a8a890ee9e33ceddf0676191b285325018 100644 (file)
@@ -241,21 +241,22 @@ impl MovePathLookup {
     // unknown place, but will rather return the nearest available
     // parent.
     pub fn find(&self, place: &Place<'tcx>) -> LookupResult {
-        match *place {
-            Place::Base(PlaceBase::Local(local)) => LookupResult::Exact(self.locals[local]),
-            Place::Base(PlaceBase::Static(..)) => LookupResult::Parent(None),
-            Place::Projection(ref proj) => {
-                match self.find(&proj.base) {
-                    LookupResult::Exact(base_path) => {
-                        match self.projections.get(&(base_path, proj.elem.lift())) {
-                            Some(&subpath) => LookupResult::Exact(subpath),
-                            None => LookupResult::Parent(Some(base_path))
-                        }
-                    }
-                    inexact => inexact
+        place.iterate(|place_base, place_projection| {
+            let mut result = match place_base {
+                PlaceBase::Local(local) => self.locals[*local],
+                PlaceBase::Static(..) => return LookupResult::Parent(None),
+            };
+
+            for proj in place_projection {
+                if let Some(&subpath) = self.projections.get(&(result, proj.elem.lift())) {
+                    result = subpath;
+                } else {
+                    return LookupResult::Parent(Some(result));
                 }
             }
-        }
+
+            LookupResult::Exact(result)
+        })
     }
 
     pub fn find_local(&self, local: Local) -> MovePathIndex {
index caadc6055b5c617cbb34635c6624409dfb55660f..d2c86d36238e1eeb76358dfe8e9cb0cd32f71a69 100644 (file)
@@ -14,7 +14,7 @@
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     ty: Ty<'tcx>,
     neg: bool,
-) -> Result<ty::Const<'tcx>, LitToConstError> {
+) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
     use syntax::ast::*;
 
     let trunc = |n| {
     let lit = match *lit {
         LitKind::Str(ref s, _) => {
             let s = s.as_str();
-            let id = tcx.allocate_bytes(s.as_bytes());
-            ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64)
+            let allocation = Allocation::from_byte_aligned_bytes(s.as_bytes(), ());
+            let allocation = tcx.intern_const_alloc(allocation);
+            ConstValue::Slice { data: allocation, start: 0, end: s.len() }
         },
         LitKind::Err(ref s) => {
             let s = s.as_str();
-            let id = tcx.allocate_bytes(s.as_bytes());
-            return Ok(ty::Const {
-                val: ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64),
+            let allocation = Allocation::from_byte_aligned_bytes(s.as_bytes(), ());
+            let allocation = tcx.intern_const_alloc(allocation);
+            return Ok(tcx.mk_const(ty::Const {
+                val: ConstValue::Slice{ data: allocation, start: 0, end: s.len() },
                 ty: tcx.types.err,
-            });
+            }));
         },
         LitKind::ByteStr(ref data) => {
             let id = tcx.allocate_bytes(data);
@@ -71,7 +73,7 @@
         LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
         LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
     };
-    Ok(ty::Const { val: lit, ty })
+    Ok(tcx.mk_const(ty::Const { val: lit, ty }))
 }
 
 fn parse_float<'tcx>(
index d623f149988c7aed7893e9d1cc9614f7d26c9013..d0ea303a93c69e00474b72104a65d4613fa33c6b 100644 (file)
@@ -329,9 +329,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
         }
 
         hir::ExprKind::Lit(ref lit) => ExprKind::Literal {
-            literal: cx.tcx.mk_const(
-                cx.const_eval_literal(&lit.node, expr_ty, lit.span, false)
-            ),
+            literal: cx.const_eval_literal(&lit.node, expr_ty, lit.span, false),
             user_ty: None,
         },
 
@@ -429,9 +427,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             } else {
                 if let hir::ExprKind::Lit(ref lit) = arg.node {
                     ExprKind::Literal {
-                        literal: cx.tcx.mk_const(
-                            cx.const_eval_literal(&lit.node, expr_ty, lit.span, true)
-                        ),
+                        literal: cx.const_eval_literal(&lit.node, expr_ty, lit.span, true),
                         user_ty: None,
                     }
                 } else {
@@ -680,7 +676,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                         ty: var_ty,
                         span: expr.span,
                         kind: ExprKind::Literal {
-                            literal: cx.tcx.mk_const(literal),
+                            literal,
                             user_ty: None
                         },
                     }.to_ref();
@@ -694,10 +690,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                             // in case we are offsetting from a computed discriminant
                             // and not the beginning of discriminants (which is always `0`)
                             let substs = InternalSubsts::identity_for_item(cx.tcx(), did);
-                            let lhs = mk_const(ty::Const {
+                            let lhs = mk_const(cx.tcx().mk_const(ty::Const {
                                 val: ConstValue::Unevaluated(did, substs),
                                 ty: var_ty,
-                            });
+                            }));
                             let bin = ExprKind::Binary {
                                 op: BinOp::Add,
                                 lhs,
@@ -791,7 +787,7 @@ fn user_substs_applied_to_res(
         Res::Def(DefKind::Method, _) |
         Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) |
         Res::Def(DefKind::Const, _) |
-        Res::Def(DefKind::AssociatedConst, _) =>
+        Res::Def(DefKind::AssocConst, _) =>
             cx.tables().user_provided_types().get(hir_id).map(|u_ty| *u_ty),
 
         // A unit struct/variant which is used as a value (e.g.,
@@ -837,9 +833,7 @@ fn method_callee<'a, 'gcx, 'tcx>(
         ty,
         span,
         kind: ExprKind::Literal {
-            literal: cx.tcx().mk_const(
-                ty::Const::zero_sized(ty)
-            ),
+            literal: ty::Const::zero_sized(cx.tcx(), ty),
             user_ty,
         },
     }
@@ -902,9 +896,10 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             let user_ty = user_substs_applied_to_res(cx, expr.hir_id, res);
             debug!("convert_path_expr: user_ty={:?}", user_ty);
             ExprKind::Literal {
-                literal: cx.tcx.mk_const(ty::Const::zero_sized(
+                literal: ty::Const::zero_sized(
+                    cx.tcx,
                     cx.tables().node_type(expr.hir_id),
-                )),
+                ),
                 user_ty,
             }
         }
@@ -929,7 +924,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
         }
 
         Res::Def(DefKind::Const, def_id) |
-        Res::Def(DefKind::AssociatedConst, def_id) => {
+        Res::Def(DefKind::AssocConst, def_id) => {
             let user_ty = user_substs_applied_to_res(cx, expr.hir_id, res);
             debug!("convert_path_expr: (const) user_ty={:?}", user_ty);
             ExprKind::Literal {
index e8070b21bb8c7d9e0350fc244b391ca9439dae6a..9798d7e8a16ddb81e379d93a28046bcb6f453447 100644 (file)
@@ -106,7 +106,7 @@ pub fn usize_ty(&mut self) -> Ty<'tcx> {
     }
 
     pub fn usize_literal(&mut self, value: u64) -> &'tcx ty::Const<'tcx> {
-        self.tcx.mk_const(ty::Const::from_usize(self.tcx, value))
+        ty::Const::from_usize(self.tcx, value)
     }
 
     pub fn bool_ty(&mut self) -> Ty<'tcx> {
@@ -118,11 +118,11 @@ pub fn unit_ty(&mut self) -> Ty<'tcx> {
     }
 
     pub fn true_literal(&mut self) -> &'tcx ty::Const<'tcx> {
-        self.tcx.mk_const(ty::Const::from_bool(self.tcx, true))
+        ty::Const::from_bool(self.tcx, true)
     }
 
     pub fn false_literal(&mut self) -> &'tcx ty::Const<'tcx> {
-        self.tcx.mk_const(ty::Const::from_bool(self.tcx, false))
+        ty::Const::from_bool(self.tcx, false)
     }
 
     pub fn const_eval_literal(
@@ -131,7 +131,7 @@ pub fn const_eval_literal(
         ty: Ty<'tcx>,
         sp: Span,
         neg: bool,
-    ) -> ty::Const<'tcx> {
+    ) -> &'tcx ty::Const<'tcx> {
         trace!("const_eval_literal: {:#?}, {:?}, {:?}, {:?}", lit, ty, sp, neg);
 
         match lit_to_const(lit, self.tcx, ty, neg) {
@@ -166,14 +166,14 @@ pub fn trait_method(&mut self,
                         method_name: &str,
                         self_ty: Ty<'tcx>,
                         params: &[Kind<'tcx>])
-                        -> (Ty<'tcx>, ty::Const<'tcx>) {
+                        -> (Ty<'tcx>, &'tcx ty::Const<'tcx>) {
         let method_name = Symbol::intern(method_name);
         let substs = self.tcx.mk_substs_trait(self_ty, params);
         for item in self.tcx.associated_items(trait_def_id) {
-            if item.kind == ty::AssociatedKind::Method && item.ident.name == method_name {
+            if item.kind == ty::AssocKind::Method && item.ident.name == method_name {
                 let method_ty = self.tcx.type_of(item.def_id);
                 let method_ty = method_ty.subst(self.tcx, substs);
-                return (method_ty, ty::Const::zero_sized(method_ty));
+                return (method_ty, ty::Const::zero_sized(self.tcx, method_ty));
             }
         }
 
index fd4416fc2b7632acfd07a8efc5d50dc3cf108c19..29e9c425685e858bf9e3ac31b28dd7343b438bd8 100644 (file)
 use rustc::ty::layout::{Integer, IntegerExt, VariantIdx, Size};
 
 use rustc::mir::Field;
-use rustc::mir::interpret::{ConstValue, Scalar, truncate};
+use rustc::mir::interpret::{ConstValue, Scalar, truncate, AllocId, Pointer};
 use rustc::util::common::ErrorReported;
 
 use syntax::attr::{SignedInt, UnsignedInt};
 use std::iter::{FromIterator, IntoIterator};
 use std::ops::RangeInclusive;
 use std::u128;
+use std::convert::TryInto;
 
 pub fn expand_pattern<'a, 'tcx>(cx: &MatchCheckCtxt<'a, 'tcx>, pat: Pattern<'tcx>)
                                 -> &'a Pattern<'tcx>
@@ -221,16 +222,17 @@ fn fold_const_value_deref(
             // unsize array to slice if pattern is array but match value or other patterns are slice
             (ConstValue::Scalar(Scalar::Ptr(p)), ty::Array(t, n), ty::Slice(u)) => {
                 assert_eq!(t, u);
-                ConstValue::Slice(
-                    Scalar::Ptr(p),
-                    n.val.try_to_scalar()
-                        .unwrap()
-                        .to_usize(&self.tcx)
-                        .unwrap(),
-                )
+                ConstValue::Slice {
+                    data: self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id),
+                    start: p.offset.bytes().try_into().unwrap(),
+                    end: n.unwrap_usize(self.tcx).try_into().unwrap(),
+                }
             },
             // fat pointers stay the same
-            (ConstValue::Slice(..), _, _) => val,
+            | (ConstValue::Slice { .. }, _, _)
+            | (_, ty::Slice(_), ty::Slice(_))
+            | (_, ty::Str, ty::Str)
+            => val,
             // FIXME(oli-obk): this is reachable for `const FOO: &&&u32 = &&&42;` being used
             _ => bug!("cannot deref {:#?}, {} -> {}", val, crty, rty),
         }
@@ -255,10 +257,10 @@ fn fold_pattern(&mut self, pat: &Pattern<'tcx>) -> Pattern<'tcx> {
                         subpattern: Pattern {
                             ty: rty,
                             span: pat.span,
-                            kind: box PatternKind::Constant { value: Const {
-                                val: self.fold_const_value_deref(val, rty, crty),
+                            kind: box PatternKind::Constant { value: self.tcx.mk_const(Const {
+                                val: self.fold_const_value_deref(*val, rty, crty),
                                 ty: rty,
-                            } },
+                            }) },
                         }
                     }
                 }
@@ -423,7 +425,7 @@ enum Constructor<'tcx> {
     /// Enum variants.
     Variant(DefId),
     /// Literal values.
-    ConstantValue(ty::Const<'tcx>),
+    ConstantValue(&'tcx ty::Const<'tcx>),
     /// Ranges of literal values (`2...5` and `2..5`).
     ConstantRange(u128, u128, Ty<'tcx>, RangeEnd),
     /// Array patterns of length n.
@@ -786,9 +788,9 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>(
                         max_fixed_len,
                         n.unwrap_usize(cx.tcx),
                     ),
-                    (ConstValue::Slice(_, n), ty::Slice(_)) => max_fixed_len = cmp::max(
+                    (ConstValue::Slice{ start, end, .. }, ty::Slice(_)) => max_fixed_len = cmp::max(
                         max_fixed_len,
-                        n,
+                        (end - start) as u64,
                     ),
                     _ => {},
                 }
@@ -1424,49 +1426,24 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>,
 fn slice_pat_covered_by_const<'tcx>(
     tcx: TyCtxt<'_, 'tcx, '_>,
     _span: Span,
-    const_val: ty::Const<'tcx>,
+    const_val: &'tcx ty::Const<'tcx>,
     prefix: &[Pattern<'tcx>],
     slice: &Option<Pattern<'tcx>>,
     suffix: &[Pattern<'tcx>]
 ) -> Result<bool, ErrorReported> {
     let data: &[u8] = match (const_val.val, &const_val.ty.sty) {
         (ConstValue::ByRef(ptr, alloc), ty::Array(t, n)) => {
-            if *t != tcx.types.u8 {
-                // FIXME(oli-obk): can't mix const patterns with slice patterns and get
-                // any sort of exhaustiveness/unreachable check yet
-                // This solely means that we don't lint about unreachable patterns, even if some
-                // are definitely unreachable.
-                return Ok(false);
-            }
+            assert_eq!(*t, tcx.types.u8);
             let n = n.assert_usize(tcx).unwrap();
             alloc.get_bytes(&tcx, ptr, Size::from_bytes(n)).unwrap()
         },
-        // a slice fat pointer to a zero length slice
-        (ConstValue::Slice(Scalar::Bits { .. }, 0), ty::Slice(t)) => {
-            if *t != tcx.types.u8 {
-                // FIXME(oli-obk): can't mix const patterns with slice patterns and get
-                // any sort of exhaustiveness/unreachable check yet
-                // This solely means that we don't lint about unreachable patterns, even if some
-                // are definitely unreachable.
-                return Ok(false);
-            }
-            &[]
-        },
-        //
-        (ConstValue::Slice(Scalar::Ptr(ptr), n), ty::Slice(t)) => {
-            if *t != tcx.types.u8 {
-                // FIXME(oli-obk): can't mix const patterns with slice patterns and get
-                // any sort of exhaustiveness/unreachable check yet
-                // This solely means that we don't lint about unreachable patterns, even if some
-                // are definitely unreachable.
-                return Ok(false);
-            }
-            tcx.alloc_map
-                .lock()
-                .unwrap_memory(ptr.alloc_id)
-                .get_bytes(&tcx, ptr, Size::from_bytes(n))
-                .unwrap()
+        (ConstValue::Slice { data, start, end }, ty::Slice(t)) => {
+            assert_eq!(*t, tcx.types.u8);
+            let ptr = Pointer::new(AllocId(0), Size::from_bytes(start as u64));
+            data.get_bytes(&tcx, ptr, Size::from_bytes((end - start) as u64)).unwrap()
         },
+        // FIXME(oli-obk): create a way to extract fat pointers from ByRef
+        (_, ty::Slice(_)) => return Ok(false),
         _ => bug!(
             "slice_pat_covered_by_const: {:#?}, {:#?}, {:#?}, {:#?}",
             const_val, prefix, slice, suffix,
@@ -1774,11 +1751,12 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
                     // necessarily point to memory, they are usually just integers. The only time
                     // they should be pointing to memory is when they are subslices of nonzero
                     // slices
-                    let (opt_ptr, n, ty) = match value.ty.sty {
+                    let (alloc, offset, n, ty) = match value.ty.sty {
                         ty::Array(t, n) => {
                             match value.val {
                                 ConstValue::ByRef(ptr, alloc) => (
-                                    Some((ptr, alloc)),
+                                    alloc,
+                                    ptr.offset,
                                     n.unwrap_usize(cx.tcx),
                                     t,
                                 ),
@@ -1790,14 +1768,16 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
                         },
                         ty::Slice(t) => {
                             match value.val {
-                                ConstValue::Slice(ptr, n) => (
-                                    ptr.to_ptr().ok().map(|ptr| (
-                                        ptr,
-                                        cx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id),
-                                    )),
-                                    n,
+                                ConstValue::Slice { data, start, end } => (
+                                    data,
+                                    Size::from_bytes(start as u64),
+                                    (end - start) as u64,
                                     t,
                                 ),
+                                ConstValue::ByRef(..) => {
+                                    // FIXME(oli-obk): implement `deref` for `ConstValue`
+                                    return None;
+                                },
                                 _ => span_bug!(
                                     pat.span,
                                     "slice pattern constant must be scalar pair but is {:?}",
@@ -1814,31 +1794,22 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
                     };
                     if wild_patterns.len() as u64 == n {
                         // convert a constant slice/array pattern to a list of patterns.
-                        match (n, opt_ptr) {
-                            (0, _) => Some(SmallVec::new()),
-                            (_, Some((ptr, alloc))) => {
-                                let layout = cx.tcx.layout_of(cx.param_env.and(ty)).ok()?;
-                                (0..n).map(|i| {
-                                    let ptr = ptr.offset(layout.size * i, &cx.tcx).ok()?;
-                                    let scalar = alloc.read_scalar(
-                                        &cx.tcx, ptr, layout.size,
-                                    ).ok()?;
-                                    let scalar = scalar.not_undef().ok()?;
-                                    let value = ty::Const::from_scalar(scalar, ty);
-                                    let pattern = Pattern {
-                                        ty,
-                                        span: pat.span,
-                                        kind: box PatternKind::Constant { value },
-                                    };
-                                    Some(&*cx.pattern_arena.alloc(pattern))
-                                }).collect()
-                            },
-                            (_, None) => span_bug!(
-                                pat.span,
-                                "non zero length slice with const-val {:?}",
-                                value,
-                            ),
-                        }
+                        let layout = cx.tcx.layout_of(cx.param_env.and(ty)).ok()?;
+                        let ptr = Pointer::new(AllocId(0), offset);
+                        (0..n).map(|i| {
+                            let ptr = ptr.offset(layout.size * i, &cx.tcx).ok()?;
+                            let scalar = alloc.read_scalar(
+                                &cx.tcx, ptr, layout.size,
+                            ).ok()?;
+                            let scalar = scalar.not_undef().ok()?;
+                            let value = ty::Const::from_scalar(cx.tcx, scalar, ty);
+                            let pattern = Pattern {
+                                ty,
+                                span: pat.span,
+                                kind: box PatternKind::Constant { value },
+                            };
+                            Some(&*cx.pattern_arena.alloc(pattern))
+                        }).collect()
                     } else {
                         None
                     }
index a1b2e6461e5ba24c2f4cf9c86a0161cc0fc94838..0edf32d3a306cce1d2449f7548b0547bf0583da9 100644 (file)
@@ -102,7 +102,7 @@ fn report_inlining_errors(&self, pat_span: Span) {
                 PatternError::StaticInPattern(span) => {
                     self.span_e0158(span, "statics cannot be referenced in patterns")
                 }
-                PatternError::AssociatedConstInPattern(span) => {
+                PatternError::AssocConstInPattern(span) => {
                     self.span_e0158(span, "associated consts cannot be referenced in patterns")
                 }
                 PatternError::FloatBug => {
index 0576bb53d8f4219268ff2e1eb02dd97abe500723..d5cee871810f50a614c54f75762db6dc0e9752f5 100644 (file)
 use crate::hair::util::UserAnnotatedTyHelpers;
 use crate::hair::constant::*;
 
-use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
+use rustc::mir::{Field, BorrowKind, Mutability};
 use rustc::mir::{UserTypeProjection};
-use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend};
+use rustc::mir::interpret::{GlobalId, ConstValue, sign_extend, AllocId, Pointer};
 use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, UserType, DefIdTree};
 use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations};
 use rustc::ty::subst::{SubstsRef, Kind};
-use rustc::ty::layout::VariantIdx;
+use rustc::ty::layout::{VariantIdx, Size};
 use rustc::hir::{self, PatKind, RangeEnd};
 use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
@@ -32,7 +32,7 @@
 
 #[derive(Clone, Debug)]
 pub enum PatternError {
-    AssociatedConstInPattern(Span),
+    AssocConstInPattern(Span),
     StaticInPattern(Span),
     FloatBug,
     NonConstPath(Span),
@@ -152,7 +152,7 @@ pub enum PatternKind<'tcx> {
     },
 
     Constant {
-        value: ty::Const<'tcx>,
+        value: &'tcx ty::Const<'tcx>,
     },
 
     Range(PatternRange<'tcx>),
@@ -176,8 +176,8 @@ pub enum PatternKind<'tcx> {
 
 #[derive(Copy, Clone, Debug, PartialEq)]
 pub struct PatternRange<'tcx> {
-    pub lo: ty::Const<'tcx>,
-    pub hi: ty::Const<'tcx>,
+    pub lo: &'tcx ty::Const<'tcx>,
+    pub hi: &'tcx ty::Const<'tcx>,
     pub ty: Ty<'tcx>,
     pub end: RangeEnd,
 }
@@ -291,15 +291,15 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                 write!(f, "{}", subpattern)
             }
             PatternKind::Constant { value } => {
-                fmt_const_val(f, value)
+                write!(f, "{}", value)
             }
             PatternKind::Range(PatternRange { lo, hi, ty: _, end }) => {
-                fmt_const_val(f, lo)?;
+                write!(f, "{}", lo)?;
                 match end {
                     RangeEnd::Included => write!(f, "..=")?,
                     RangeEnd::Excluded => write!(f, "..")?,
                 }
-                fmt_const_val(f, hi)
+                write!(f, "{}", hi)
             }
             PatternKind::Slice { ref prefix, ref slice, ref suffix } |
             PatternKind::Array { ref prefix, ref slice, ref suffix } => {
@@ -769,7 +769,7 @@ fn lower_variant_or_leaf(
             | Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
             | Res::Def(DefKind::Union, _)
             | Res::Def(DefKind::TyAlias, _)
-            | Res::Def(DefKind::AssociatedTy, _)
+            | Res::Def(DefKind::AssocTy, _)
             | Res::SelfTy(..)
             | Res::SelfCtor(..) => {
                 PatternKind::Leaf { subpatterns }
@@ -811,11 +811,11 @@ fn lower_path(&mut self,
         let ty = self.tables.node_type(id);
         let res = self.tables.qpath_res(qpath, id);
         let is_associated_const = match res {
-            Res::Def(DefKind::AssociatedConst, _) => true,
+            Res::Def(DefKind::AssocConst, _) => true,
             _ => false,
         };
         let kind = match res {
-            Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssociatedConst, def_id) => {
+            Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssocConst, def_id) => {
                 let substs = self.tables.node_substs(id);
                 match ty::Instance::resolve(
                     self.tcx,
@@ -869,7 +869,7 @@ fn lower_path(&mut self,
                     },
                     None => {
                         self.errors.push(if is_associated_const {
-                            PatternError::AssociatedConstInPattern(span)
+                            PatternError::AssocConstInPattern(span)
                         } else {
                             PatternError::StaticInPattern(span)
                         });
@@ -942,7 +942,7 @@ fn lower_lit(&mut self, expr: &'tcx hir::Expr) -> PatternKind<'tcx> {
     fn const_to_pat(
         &self,
         instance: ty::Instance<'tcx>,
-        cv: ty::Const<'tcx>,
+        cv: &'tcx ty::Const<'tcx>,
         id: hir::HirId,
         span: Span,
     ) -> Pattern<'tcx> {
@@ -1205,7 +1205,7 @@ fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
             PatternKind::Constant {
                 value
             } => PatternKind::Constant {
-                value: value.fold_with(folder)
+                value,
             },
             PatternKind::Range(PatternRange {
                 lo,
@@ -1213,8 +1213,8 @@ fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
                 ty,
                 end,
             }) => PatternKind::Range(PatternRange {
-                lo: lo.fold_with(folder),
-                hi: hi.fold_with(folder),
+                lo,
+                hi,
                 ty: ty.fold_with(folder),
                 end,
             }),
@@ -1242,8 +1242,8 @@ fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
 
 pub fn compare_const_vals<'a, 'gcx, 'tcx>(
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
-    a: ty::Const<'tcx>,
-    b: ty::Const<'tcx>,
+    a: &'tcx ty::Const<'tcx>,
+    b: &'tcx ty::Const<'tcx>,
     ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
 ) -> Option<Ordering> {
     trace!("compare_const_vals: {:?}, {:?}", a, b);
@@ -1293,22 +1293,25 @@ pub fn compare_const_vals<'a, 'gcx, 'tcx>(
     if let ty::Str = ty.value.sty {
         match (a.val, b.val) {
             (
-                ConstValue::Slice(
-                    Scalar::Ptr(ptr_a),
-                    len_a,
-                ),
-                ConstValue::Slice(
-                    Scalar::Ptr(ptr_b),
-                    len_b,
-                ),
-            ) if ptr_a.offset.bytes() == 0 && ptr_b.offset.bytes() == 0 => {
-                if len_a == len_b {
-                    let map = tcx.alloc_map.lock();
-                    let alloc_a = map.unwrap_memory(ptr_a.alloc_id);
-                    let alloc_b = map.unwrap_memory(ptr_b.alloc_id);
-                    if alloc_a.bytes.len() as u64 == len_a {
-                        return from_bool(alloc_a == alloc_b);
-                    }
+                ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a },
+                ConstValue::Slice { data: alloc_b, start: offset_b, end: end_b },
+            ) => {
+                let len_a = end_a - offset_a;
+                let len_b = end_b - offset_b;
+                let a = alloc_a.get_bytes(
+                    &tcx,
+                    // invent a pointer, only the offset is relevant anyway
+                    Pointer::new(AllocId(0), Size::from_bytes(offset_a as u64)),
+                    Size::from_bytes(len_a as u64),
+                );
+                let b = alloc_b.get_bytes(
+                    &tcx,
+                    // invent a pointer, only the offset is relevant anyway
+                    Pointer::new(AllocId(0), Size::from_bytes(offset_b as u64)),
+                    Size::from_bytes(len_b as u64),
+                );
+                if let (Ok(a), Ok(b)) = (a, b) {
+                    return from_bool(a == b);
                 }
             }
             _ => (),
index d4c1e5416d565c50232d271ac1ec800c2c899f3b..2f89740876db10b86e577e65ef8dd082631d08c9 100644 (file)
@@ -513,7 +513,7 @@ pub fn push_stack_frame(
                 // statics and constants don't have `Storage*` statements, no need to look for them
                 Some(DefKind::Static)
                 | Some(DefKind::Const)
-                | Some(DefKind::AssociatedConst) => {},
+                | Some(DefKind::AssocConst) => {},
                 _ => {
                     trace!("push_stack_frame: {:?}: num_bbs: {}", span, mir.basic_blocks().len());
                     for block in mir.basic_blocks() {
index 9674822b47a3ddb7302997e509b7ac9a9d798d05..0cd258825acb8f14a5a47661c288bab45ee7423d 100644 (file)
@@ -20,7 +20,7 @@
 use super::{
     Pointer, AllocId, Allocation, GlobalId, AllocationExtra,
     EvalResult, Scalar, InterpError, AllocKind, PointerArithmetic,
-    Machine, AllocMap, MayLeak, ErrorHandled, InboundsCheck,
+    Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg, InboundsCheck,
 };
 
 #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
@@ -252,7 +252,8 @@ pub fn check_align(
             Scalar::Ptr(ptr) => {
                 // check this is not NULL -- which we can ensure only if this is in-bounds
                 // of some (potentially dead) allocation.
-                let align = self.check_bounds_ptr(ptr, InboundsCheck::MaybeDead)?;
+                let align = self.check_bounds_ptr(ptr, InboundsCheck::MaybeDead,
+                                                  CheckInAllocMsg::NullPointerTest)?;
                 (ptr.offset.bytes(), align)
             }
             Scalar::Bits { bits, size } => {
@@ -293,9 +294,10 @@ pub fn check_bounds_ptr(
         &self,
         ptr: Pointer<M::PointerTag>,
         liveness: InboundsCheck,
+        msg: CheckInAllocMsg,
     ) -> EvalResult<'tcx, Align> {
         let (allocation_size, align) = self.get_size_and_align(ptr.alloc_id, liveness)?;
-        ptr.check_in_alloc(allocation_size, liveness)?;
+        ptr.check_in_alloc(allocation_size, msg)?;
         Ok(align)
     }
 }
@@ -419,7 +421,7 @@ pub fn get_mut(
 
     /// Obtain the size and alignment of an allocation, even if that allocation has been deallocated
     ///
-    /// If `liveness` is `InboundsCheck::Dead`, this function always returns `Ok`
+    /// If `liveness` is `InboundsCheck::MaybeDead`, this function always returns `Ok`
     pub fn get_size_and_align(
         &self,
         id: AllocId,
index 9c2b491925f47553c9b1a99c2a5da3ebe404ef8e..c03b35c40c6db2e0a3f1063cc1ddacf2e54b4f9f 100644 (file)
@@ -7,9 +7,9 @@
 use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, VariantIdx};
 
 use rustc::mir::interpret::{
-    GlobalId, AllocId, InboundsCheck,
+    GlobalId, AllocId, CheckInAllocMsg,
     ConstValue, Pointer, Scalar,
-    EvalResult, InterpError,
+    EvalResult, InterpError, InboundsCheck,
     sign_extend, truncate,
 };
 use super::{
@@ -467,22 +467,36 @@ pub(super) fn eval_place_to_op(
         mir_place: &mir::Place<'tcx>,
         layout: Option<TyLayout<'tcx>>,
     ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
-        use rustc::mir::Place::*;
+        use rustc::mir::Place;
         use rustc::mir::PlaceBase;
-        let op = match *mir_place {
-            Base(PlaceBase::Local(mir::RETURN_PLACE)) => return err!(ReadFromReturnPointer),
-            Base(PlaceBase::Local(local)) => self.access_local(self.frame(), local, layout)?,
 
-            Projection(ref proj) => {
-                let op = self.eval_place_to_op(&proj.base, None)?;
-                self.operand_projection(op, &proj.elem)?
-            }
+        mir_place.iterate(|place_base, place_projection| {
+            let mut op = match place_base {
+                PlaceBase::Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer),
+                PlaceBase::Local(local) => {
+                    // FIXME use place_projection.is_empty() when is available
+                    // Do not use the layout passed in as argument if the base we are looking at
+                    // here is not the entire place.
+                    let layout = if let Place::Base(_) = mir_place {
+                        layout
+                    } else {
+                        None
+                    };
+
+                    self.access_local(self.frame(), *local, layout)?
+                }
+                PlaceBase::Static(place_static) => {
+                    self.eval_static_to_mplace(place_static)?.into()
+                }
+            };
 
-            _ => self.eval_place_to_mplace(mir_place)?.into(),
-        };
+            for proj in place_projection {
+                op = self.operand_projection(op, &proj.elem)?
+            }
 
-        trace!("eval_place_to_op: got {:?}", *op);
-        Ok(op)
+            trace!("eval_place_to_op: got {:?}", *op);
+            Ok(op)
+        })
     }
 
     /// Evaluate the operand, returning a place where you can then find the data.
@@ -500,7 +514,7 @@ pub fn eval_operand(
             Move(ref place) =>
                 self.eval_place_to_op(place, layout)?,
 
-            Constant(ref constant) => self.eval_const_to_op(*constant.literal, layout)?,
+            Constant(ref constant) => self.eval_const_to_op(constant.literal, layout)?,
         };
         trace!("{:?}: {:?}", mir_op, *op);
         Ok(op)
@@ -520,7 +534,7 @@ pub(super) fn eval_operands(
     // in patterns via the `const_eval` module
     crate fn eval_const_to_op(
         &self,
-        val: ty::Const<'tcx>,
+        val: &'tcx ty::Const<'tcx>,
         layout: Option<TyLayout<'tcx>>,
     ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
         let op = match val.val {
@@ -533,11 +547,16 @@ pub(super) fn eval_operands(
                     MemPlace::from_ptr(ptr.with_default_tag(), alloc.align)
                 )
             },
-            ConstValue::Slice(a, b) =>
+            ConstValue::Slice { data, start, end } =>
                 Operand::Immediate(Immediate::ScalarPair(
-                    a.with_default_tag().into(),
-                    Scalar::from_uint(b, self.tcx.data_layout.pointer_size)
-                        .with_default_tag().into(),
+                    Scalar::from(Pointer::new(
+                        self.tcx.alloc_map.lock().allocate(data),
+                        Size::from_bytes(start as u64),
+                    )).with_default_tag().into(),
+                    Scalar::from_uint(
+                        (end - start) as u64,
+                        self.tcx.data_layout.pointer_size,
+                    ).with_default_tag().into(),
                 )),
             ConstValue::Scalar(x) =>
                 Operand::Immediate(Immediate::Scalar(x.with_default_tag().into())),
@@ -626,7 +645,8 @@ pub fn read_discriminant(
                     ScalarMaybeUndef::Scalar(Scalar::Ptr(ptr)) => {
                         // The niche must be just 0 (which an inbounds pointer value never is)
                         let ptr_valid = niche_start == 0 && variants_start == variants_end &&
-                            self.memory.check_bounds_ptr(ptr, InboundsCheck::MaybeDead).is_ok();
+                            self.memory.check_bounds_ptr(ptr, InboundsCheck::MaybeDead,
+                                                         CheckInAllocMsg::NullPointerTest).is_ok();
                         if !ptr_valid {
                             return err!(InvalidDiscriminant(raw_discr.erase_tag()));
                         }
index 0cc480028161f170dac97c2741bccd8f52688faf..57d5ab71ecafd3922a6dda794f2bb5505ff87454 100644 (file)
@@ -562,15 +562,14 @@ pub fn place_projection(
 
     /// Evaluate statics and promoteds to an `MPlace`. Used to share some code between
     /// `eval_place` and `eval_place_to_op`.
-    pub(super) fn eval_place_to_mplace(
+    pub(super) fn eval_static_to_mplace(
         &self,
-        mir_place: &mir::Place<'tcx>
+        place_static: &mir::Static<'tcx>
     ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
-        use rustc::mir::Place::*;
-        use rustc::mir::PlaceBase;
-        use rustc::mir::{Static, StaticKind};
-        Ok(match *mir_place {
-            Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted), .. })) => {
+        use rustc::mir::StaticKind;
+
+        Ok(match place_static.kind {
+            StaticKind::Promoted(promoted) => {
                 let instance = self.frame().instance;
                 self.const_eval_raw(GlobalId {
                     instance,
@@ -578,7 +577,8 @@ pub(super) fn eval_place_to_mplace(
                 })?
             }
 
-            Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), ty })) => {
+            StaticKind::Static(def_id) => {
+                let ty = place_static.ty;
                 assert!(!ty.needs_subst());
                 let layout = self.layout_of(ty)?;
                 let instance = ty::Instance::mono(*self.tcx, def_id);
@@ -600,8 +600,6 @@ pub(super) fn eval_place_to_mplace(
                 let alloc = self.tcx.alloc_map.lock().intern_static(cid.instance.def_id());
                 MPlaceTy::from_aligned_ptr(Pointer::from(alloc).with_default_tag(), layout)
             }
-
-            _ => bug!("eval_place_to_mplace called on {:?}", mir_place),
         })
     }
 
@@ -609,40 +607,42 @@ pub(super) fn eval_place_to_mplace(
     /// place; for reading, a more efficient alternative is `eval_place_for_read`.
     pub fn eval_place(
         &mut self,
-        mir_place: &mir::Place<'tcx>
+        mir_place: &mir::Place<'tcx>,
     ) -> EvalResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
-        use rustc::mir::Place::*;
         use rustc::mir::PlaceBase;
-        let place = match *mir_place {
-            Base(PlaceBase::Local(mir::RETURN_PLACE)) => match self.frame().return_place {
-                Some(return_place) =>
-                    // We use our layout to verify our assumption; caller will validate
-                    // their layout on return.
-                    PlaceTy {
-                        place: *return_place,
-                        layout: self.layout_of(self.monomorphize(self.frame().mir.return_ty())?)?,
+
+        mir_place.iterate(|place_base, place_projection| {
+            let mut place = match place_base {
+                PlaceBase::Local(mir::RETURN_PLACE) => match self.frame().return_place {
+                    Some(return_place) => {
+                        // We use our layout to verify our assumption; caller will validate
+                        // their layout on return.
+                        PlaceTy {
+                            place: *return_place,
+                            layout: self
+                                .layout_of(self.monomorphize(self.frame().mir.return_ty())?)?,
+                        }
+                    }
+                    None => return err!(InvalidNullPointerUsage),
+                },
+                PlaceBase::Local(local) => PlaceTy {
+                    // This works even for dead/uninitialized locals; we check further when writing
+                    place: Place::Local {
+                        frame: self.cur_frame(),
+                        local: *local,
                     },
-                None => return err!(InvalidNullPointerUsage),
-            },
-            Base(PlaceBase::Local(local)) => PlaceTy {
-                // This works even for dead/uninitialized locals; we check further when writing
-                place: Place::Local {
-                    frame: self.cur_frame(),
-                    local,
+                    layout: self.layout_of_local(self.frame(), *local, None)?,
                 },
-                layout: self.layout_of_local(self.frame(), local, None)?,
-            },
+                PlaceBase::Static(place_static) => self.eval_static_to_mplace(place_static)?.into(),
+            };
 
-            Projection(ref proj) => {
-                let place = self.eval_place(&proj.base)?;
-                self.place_projection(place, &proj.elem)?
+            for proj in place_projection {
+                place = self.place_projection(place, &proj.elem)?
             }
 
-            _ => self.eval_place_to_mplace(mir_place)?.into(),
-        };
-
-        self.dump_place(place.place);
-        Ok(place)
+            self.dump_place(place.place);
+            Ok(place)
+        })
     }
 
     /// Write a scalar to a place
index 0d3ee830574ba1f41136435124588176529225d0..f9401d9763506d67b36579ce89eab5cc34367ae5 100644 (file)
@@ -2,13 +2,13 @@
 use std::hash::Hash;
 use std::ops::RangeInclusive;
 
-use syntax_pos::symbol::Symbol;
+use syntax_pos::symbol::{sym, Symbol};
 use rustc::hir;
 use rustc::ty::layout::{self, Size, Align, TyLayout, LayoutOf, VariantIdx};
 use rustc::ty;
 use rustc_data_structures::fx::FxHashSet;
 use rustc::mir::interpret::{
-    Scalar, AllocKind, EvalResult, InterpError,
+    Scalar, AllocKind, EvalResult, InterpError, CheckInAllocMsg,
 };
 
 use super::{
@@ -188,7 +188,7 @@ fn aggregate_field_path_elem(
 
                 PathElem::ClosureVar(name.unwrap_or_else(|| {
                     // Fall back to showing the field index.
-                    Symbol::intern(&field.to_string())
+                    sym::integer(field)
                 }))
             }
 
@@ -417,7 +417,7 @@ fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> EvalResult<'t
                         try_validation!(
                             self.ecx.memory
                                 .get(ptr.alloc_id)?
-                                .check_bounds(self.ecx, ptr, size),
+                                .check_bounds(self.ecx, ptr, size, CheckInAllocMsg::InboundsTest),
                             "dangling (not entirely in bounds) reference", self.path);
                     }
                     // Check if we have encountered this pointer+layout combination
index 572f7133cad84eb48190563dba2c3e491d97d006..51ceb2a01c3a428d48593209c0fcf8af3a7e5bad 100644 (file)
@@ -4,7 +4,7 @@
 use rustc::hir::map::blocks::FnLikeNode;
 use rustc::lint::builtin::UNCONDITIONAL_RECURSION;
 use rustc::mir::{self, Mir, TerminatorKind};
-use rustc::ty::{self, AssociatedItem, AssociatedItemContainer, Instance, TyCtxt};
+use rustc::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt};
 use rustc::ty::subst::InternalSubsts;
 
 pub fn check(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -63,8 +63,8 @@ fn check_fn_for_unconditional_recursion(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let param_env = tcx.param_env(def_id);
     let trait_substs_count =
         match tcx.opt_associated_item(def_id) {
-            Some(AssociatedItem {
-                container: AssociatedItemContainer::TraitContainer(trait_def_id),
+            Some(AssocItem {
+                container: AssocItemContainer::TraitContainer(trait_def_id),
                 ..
             }) => tcx.generics_of(trait_def_id).count(),
             _ => 0
index 91cf0fbb9b44f482ebb269f5caac8a6ec5ebb2e7..b90db7646d4929f1be224ccc83f112cfefbac787 100644 (file)
@@ -609,7 +609,7 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
     fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, location: Location) {
         debug!("visiting const {:?} @ {:?}", *constant, location);
 
-        collect_const(self.tcx, **constant, self.param_substs, self.output);
+        collect_const(self.tcx, *constant, self.param_substs, self.output);
 
         self.super_const(constant);
     }
@@ -1248,17 +1248,17 @@ fn def_id_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
 fn collect_const<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    constant: ty::Const<'tcx>,
+    constant: &'tcx ty::Const<'tcx>,
     param_substs: SubstsRef<'tcx>,
     output: &mut Vec<MonoItem<'tcx>>,
 ) {
     debug!("visiting const {:?}", constant);
 
     match constant.val {
-        ConstValue::Slice(Scalar::Ptr(ptr), _) |
         ConstValue::Scalar(Scalar::Ptr(ptr)) =>
             collect_miri(tcx, ptr.alloc_id, output),
-        ConstValue::ByRef(_ptr, alloc) => {
+        ConstValue::Slice { data: alloc, start: _, end: _ } |
+        ConstValue::ByRef(_, alloc) => {
             for &((), id) in alloc.relocations.values() {
                 collect_miri(tcx, id, output);
             }
index 6b40245d39a8eae5fb7c094cb85f3d8bd0d122d0..8b44f148facf6dd9608fbe88f8677a64bf08dfad 100644 (file)
@@ -401,7 +401,7 @@ pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) {
     // as well as the unprintable types of constants (see `push_type_name` for more details).
     pub fn push_const_name(&self, c: &Const<'tcx>, output: &mut String, debug: bool) {
         match c.val {
-            ConstValue::Scalar(..) | ConstValue::Slice(..) | ConstValue::ByRef(..) => {
+            ConstValue::Scalar(..) | ConstValue::Slice { .. } | ConstValue::ByRef(..) => {
                 // FIXME(const_generics): we could probably do a better job here.
                 write!(output, "{:?}", c).unwrap()
             }
index 7fa904d32cbb49dd777d5a8a3112ae34e749acd6..ff48c86817b49ef89b96f86d5d8acdecd432b4e1 100644 (file)
@@ -65,7 +65,7 @@ fn fn_once_adapter_instance<'a, 'tcx>(
            substs);
     let fn_once = tcx.lang_items().fn_once_trait().unwrap();
     let call_once = tcx.associated_items(fn_once)
-        .find(|it| it.kind == ty::AssociatedKind::Method)
+        .find(|it| it.kind == ty::AssocKind::Method)
         .unwrap().def_id;
     let def = ty::InstanceDef::ClosureOnceShim { call_once };
 
index b9224d973fe7b8fe9ca69f731aca2b72c3733971..12a1659e043c6b641acc90eb67faea6eee7b73f6 100644 (file)
@@ -84,7 +84,7 @@ fn make_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             let fn_mut = tcx.lang_items().fn_mut_trait().unwrap();
             let call_mut = tcx.global_tcx()
                 .associated_items(fn_mut)
-                .find(|it| it.kind == ty::AssociatedKind::Method)
+                .find(|it| it.kind == ty::AssocKind::Method)
                 .unwrap().def_id;
 
             build_call_shim(
@@ -458,9 +458,7 @@ fn make_clone_call(
             span: self.span,
             ty: func_ty,
             user_ty: None,
-            literal: tcx.mk_const(
-                ty::Const::zero_sized(func_ty),
-            ),
+            literal: ty::Const::zero_sized(tcx, func_ty),
         });
 
         let ref_loc = self.make_place(
@@ -520,9 +518,7 @@ fn make_usize(&self, value: u64) -> Box<Constant<'tcx>> {
             span: self.span,
             ty: self.tcx.types.usize,
             user_ty: None,
-            literal: self.tcx.mk_const(
-                ty::Const::from_usize(self.tcx, value),
-            ),
+            literal: ty::Const::from_usize(self.tcx, value),
         }
     }
 
@@ -762,9 +758,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 span,
                 ty,
                 user_ty: None,
-                literal: tcx.mk_const(
-                    ty::Const::zero_sized(ty)
-                ),
+                literal: ty::Const::zero_sized(tcx, ty),
              }),
              vec![rcvr])
         }
index 8f3dd72c4f2450a82ca151b53d8ebbe9128b72d6..11022be097cfd9e68799ee720d02d1007fc575e8 100644 (file)
@@ -45,7 +45,7 @@ fn run_pass<'a, 'tcx>(&self,
 
         let is_fn_like = FnLikeNode::from_node(tcx.hir().get_by_hir_id(hir_id)).is_some();
         let is_assoc_const = match tcx.def_kind(source.def_id()) {
-            Some(DefKind::AssociatedConst) => true,
+            Some(DefKind::AssocConst) => true,
             _ => false,
         };
 
@@ -282,7 +282,7 @@ fn eval_constant(
         c: &Constant<'tcx>,
     ) -> Option<Const<'tcx>> {
         self.ecx.tcx.span = c.span;
-        match self.ecx.eval_const_to_op(*c.literal, None) {
+        match self.ecx.eval_const_to_op(c.literal, None) {
             Ok(op) => {
                 Some(op)
             },
@@ -295,47 +295,51 @@ fn eval_constant(
     }
 
     fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option<Const<'tcx>> {
-        match *place {
-            Place::Base(PlaceBase::Local(loc)) => self.places[loc].clone(),
-            Place::Projection(ref proj) => match proj.elem {
-                ProjectionElem::Field(field, _) => {
-                    trace!("field proj on {:?}", proj.base);
-                    let base = self.eval_place(&proj.base, source_info)?;
+        trace!("eval_place(place={:?})", place);
+        place.iterate(|place_base, place_projection| {
+            let mut eval = match place_base {
+                PlaceBase::Local(loc) => self.places[*loc].clone()?,
+                PlaceBase::Static(box Static {kind: StaticKind::Promoted(promoted), ..}) => {
+                    let generics = self.tcx.generics_of(self.source.def_id());
+                    if generics.requires_monomorphization(self.tcx) {
+                        // FIXME: can't handle code with generics
+                        return None;
+                    }
+                    let substs = InternalSubsts::identity_for_item(self.tcx, self.source.def_id());
+                    let instance = Instance::new(self.source.def_id(), substs);
+                    let cid = GlobalId {
+                        instance,
+                        promoted: Some(*promoted),
+                    };
+                    // cannot use `const_eval` here, because that would require having the MIR
+                    // for the current function available, but we're producing said MIR right now
                     let res = self.use_ecx(source_info, |this| {
-                        this.ecx.operand_field(base, field.index() as u64)
+                        let mir = &this.promoted[*promoted];
+                        eval_promoted(this.tcx, cid, mir, this.param_env)
                     })?;
-                    Some(res)
-                },
-                // We could get more projections by using e.g., `operand_projection`,
-                // but we do not even have the stack frame set up properly so
-                // an `Index` projection would throw us off-track.
-                _ => None,
-            },
-            Place::Base(
-                PlaceBase::Static(box Static {kind: StaticKind::Promoted(promoted), ..})
-            ) => {
-                let generics = self.tcx.generics_of(self.source.def_id());
-                if generics.requires_monomorphization(self.tcx) {
-                    // FIXME: can't handle code with generics
-                    return None;
+                    trace!("evaluated promoted {:?} to {:?}", promoted, res);
+                    res.into()
                 }
-                let substs = InternalSubsts::identity_for_item(self.tcx, self.source.def_id());
-                let instance = Instance::new(self.source.def_id(), substs);
-                let cid = GlobalId {
-                    instance,
-                    promoted: Some(promoted),
-                };
-                // cannot use `const_eval` here, because that would require having the MIR
-                // for the current function available, but we're producing said MIR right now
-                let res = self.use_ecx(source_info, |this| {
-                    let mir = &this.promoted[promoted];
-                    eval_promoted(this.tcx, cid, mir, this.param_env)
-                })?;
-                trace!("evaluated promoted {:?} to {:?}", promoted, res);
-                Some(res.into())
-            },
-            _ => None,
-        }
+                _ => return None,
+            };
+
+            for proj in place_projection {
+                match proj.elem {
+                    ProjectionElem::Field(field, _) => {
+                        trace!("field proj on {:?}", proj.base);
+                        eval = self.use_ecx(source_info, |this| {
+                            this.ecx.operand_field(eval, field.index() as u64)
+                        })?;
+                    },
+                    // We could get more projections by using e.g., `operand_projection`,
+                    // but we do not even have the stack frame set up properly so
+                    // an `Index` projection would throw us off-track.
+                    _ => return None,
+                }
+            }
+
+            Some(eval)
+        })
     }
 
     fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option<Const<'tcx>> {
@@ -506,7 +510,8 @@ fn operand_from_scalar(&self, scalar: Scalar, ty: Ty<'tcx>, span: Span) -> Opera
                 span,
                 ty,
                 user_ty: None,
-                literal: self.tcx.mk_const(ty::Const::from_scalar(
+                literal: self.tcx.mk_const(*ty::Const::from_scalar(
+                    self.tcx,
                     scalar,
                     ty,
                 ))
@@ -515,6 +520,7 @@ fn operand_from_scalar(&self, scalar: Scalar, ty: Ty<'tcx>, span: Span) -> Opera
     }
 
     fn replace_with_const(&self, rval: &mut Rvalue<'tcx>, value: Const<'tcx>, span: Span) {
+        trace!("attepting to replace {:?} with {:?}", rval, value);
         self.ecx.validate_operand(
             value,
             vec![],
@@ -578,6 +584,10 @@ fn check(mir: &Mir<'_>) -> IndexVec<Local, bool> {
             // FIXME(oli-obk): lint variables until they are used in a condition
             // FIXME(oli-obk): lint if return value is constant
             *val = mir.local_kind(local) == LocalKind::Temp;
+
+            if !*val {
+                trace!("local {:?} can't be propagated because it's not a temporary", local);
+            }
         }
         cpv.visit_mir(mir);
         cpv.can_const_prop
@@ -597,6 +607,7 @@ fn visit_local(
             // FIXME(oli-obk): we could be more powerful here, if the multiple writes
             // only occur in independent execution paths
             MutatingUse(MutatingUseContext::Store) => if self.found_assignment[local] {
+                trace!("local {:?} can't be propagated because of multiple assignments", local);
                 self.can_const_prop[local] = false;
             } else {
                 self.found_assignment[local] = true
@@ -608,7 +619,10 @@ fn visit_local(
             NonMutatingUse(NonMutatingUseContext::Projection) |
             MutatingUse(MutatingUseContext::Projection) |
             NonUse(_) => {},
-            _ => self.can_const_prop[local] = false,
+            _ => {
+                trace!("local {:?} can't be propagaged because it's used: {:?}", local, context);
+                self.can_const_prop[local] = false;
+            },
         }
     }
 }
index 023a61588c42e9c964b754319659c4a2f136b725..6320cb442481448da19a9385b22d3dbce41a3c78 100644 (file)
@@ -533,9 +533,7 @@ fn constant_bool(&self, span: Span, val: bool) -> Rvalue<'tcx> {
             span,
             ty: self.tcx.types.bool,
             user_ty: None,
-            literal: self.tcx.mk_const(
-                ty::Const::from_bool(self.tcx, val),
-            ),
+            literal: ty::Const::from_bool(self.tcx, val),
         })))
     }
 
index 780b3c9686b6a27c9a193753cbb4abe0e7836185..ab2f2933a969e62519c2e65714d10a0db0b7f6e9 100644 (file)
@@ -757,9 +757,7 @@ fn insert_panic_block<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             span: mir.span,
             ty: tcx.types.bool,
             user_ty: None,
-            literal: tcx.mk_const(
-                ty::Const::from_bool(tcx, false),
-            ),
+            literal: ty::Const::from_bool(tcx, false),
         }),
         expected: true,
         msg: message,
index 24ec3219a2e7be317b5b9a9225f7a4ae4e31ff97..782af3024ad2c448b1fb6f776e199decad28cdf1 100644 (file)
@@ -440,19 +440,22 @@ fn inline_call(&self,
                 // writes to `i`. To prevent this we need to create a temporary
                 // borrow of the place and pass the destination as `*temp` instead.
                 fn dest_needs_borrow(place: &Place<'_>) -> bool {
-                    match *place {
-                        Place::Projection(ref p) => {
-                            match p.elem {
+                    place.iterate(|place_base, place_projection| {
+                        for proj in place_projection {
+                            match proj.elem {
                                 ProjectionElem::Deref |
-                                ProjectionElem::Index(_) => true,
-                                _ => dest_needs_borrow(&p.base)
+                                ProjectionElem::Index(_) => return true,
+                                _ => {}
                             }
                         }
-                        // Static variables need a borrow because the callee
-                        // might modify the same static.
-                        Place::Base(PlaceBase::Static(_)) => true,
-                        _ => false
-                    }
+
+                        match place_base {
+                            // Static variables need a borrow because the callee
+                            // might modify the same static.
+                            PlaceBase::Static(_) => true,
+                            _ => false
+                        }
+                    })
                 }
 
                 let dest = if dest_needs_borrow(&destination.0) {
index e1d41ba4fc509f151800216059972090e7dd1ae9..a1e2d0683d3800a37f3184e06299d15e80ad0d7c 100644 (file)
@@ -136,10 +136,10 @@ fn check_rvalue(
 ) -> McfResult {
     match rvalue {
         Rvalue::Repeat(operand, _) | Rvalue::Use(operand) => {
-            check_operand(tcx, mir, operand, span)
+            check_operand(operand, span)
         }
         Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) => {
-            check_place(tcx, mir, place, span)
+            check_place(place, span)
         }
         Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
             use rustc::ty::cast::CastTy;
@@ -153,11 +153,11 @@ fn check_rvalue(
                 (CastTy::RPtr(_), CastTy::Float) => bug!(),
                 (CastTy::RPtr(_), CastTy::Int(_)) => bug!(),
                 (CastTy::Ptr(_), CastTy::RPtr(_)) => bug!(),
-                _ => check_operand(tcx, mir, operand, span),
+                _ => check_operand(operand, span),
             }
         }
         Rvalue::Cast(CastKind::Pointer(PointerCast::MutToConstPointer), operand, _) => {
-            check_operand(tcx, mir, operand, span)
+            check_operand(operand, span)
         }
         Rvalue::Cast(CastKind::Pointer(PointerCast::UnsafeFnPointer), _, _) |
         Rvalue::Cast(CastKind::Pointer(PointerCast::ClosureFnPointer(_)), _, _) |
@@ -171,8 +171,8 @@ fn check_rvalue(
         )),
         // binops are fine on integers
         Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => {
-            check_operand(tcx, mir, lhs, span)?;
-            check_operand(tcx, mir, rhs, span)?;
+            check_operand(lhs, span)?;
+            check_operand(rhs, span)?;
             let ty = lhs.ty(mir, tcx);
             if ty.is_integral() || ty.is_bool() || ty.is_char() {
                 Ok(())
@@ -191,7 +191,7 @@ fn check_rvalue(
         Rvalue::UnaryOp(_, operand) => {
             let ty = operand.ty(mir, tcx);
             if ty.is_integral() || ty.is_bool() {
-                check_operand(tcx, mir, operand, span)
+                check_operand(operand, span)
             } else {
                 Err((
                     span,
@@ -201,7 +201,7 @@ fn check_rvalue(
         }
         Rvalue::Aggregate(_, operands) => {
             for operand in operands {
-                check_operand(tcx, mir, operand, span)?;
+                check_operand(operand, span)?;
             }
             Ok(())
         }
@@ -216,11 +216,11 @@ fn check_statement(
     let span = statement.source_info.span;
     match &statement.kind {
         StatementKind::Assign(place, rval) => {
-            check_place(tcx, mir, place, span)?;
+            check_place(place, span)?;
             check_rvalue(tcx, mir, rval, span)
         }
 
-        StatementKind::FakeRead(_, place) => check_place(tcx, mir, place, span),
+        StatementKind::FakeRead(_, place) => check_place(place, span),
 
         // just an assignment
         StatementKind::SetDiscriminant { .. } => Ok(()),
@@ -239,43 +239,40 @@ fn check_statement(
 }
 
 fn check_operand(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    mir: &'a Mir<'tcx>,
     operand: &Operand<'tcx>,
     span: Span,
 ) -> McfResult {
     match operand {
         Operand::Move(place) | Operand::Copy(place) => {
-            check_place(tcx, mir, place, span)
+            check_place(place, span)
         }
         Operand::Constant(_) => Ok(()),
     }
 }
 
-fn check_place(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    mir: &'a Mir<'tcx>,
-    place: &Place<'tcx>,
-    span: Span,
-) -> McfResult {
-    match place {
-        Place::Base(PlaceBase::Local(_)) => Ok(()),
-        // promoteds are always fine, they are essentially constants
-        Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) => Ok(()),
-        Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(_), .. })) =>
-            Err((span, "cannot access `static` items in const fn".into())),
-        Place::Projection(proj) => {
+fn check_place(place: &Place<'tcx>, span: Span) -> McfResult {
+    place.iterate(|place_base, place_projection| {
+        for proj in place_projection {
             match proj.elem {
-                | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. }
-                | ProjectionElem::Deref | ProjectionElem::Field(..) | ProjectionElem::Index(_) => {
-                    check_place(tcx, mir, &proj.base, span)
-                }
-                | ProjectionElem::Downcast(..) => {
-                    Err((span, "`match` or `if let` in `const fn` is unstable".into()))
+                ProjectionElem::Downcast(..) => {
+                    return Err((span, "`match` or `if let` in `const fn` is unstable".into()));
                 }
+                ProjectionElem::ConstantIndex { .. }
+                | ProjectionElem::Subslice { .. }
+                | ProjectionElem::Deref
+                | ProjectionElem::Field(..)
+                | ProjectionElem::Index(_) => {}
             }
         }
-    }
+
+        match place_base {
+            PlaceBase::Static(box Static { kind: StaticKind::Static(_), .. }) => {
+                Err((span, "cannot access `static` items in const fn".into()))
+            }
+            PlaceBase::Local(_)
+            | PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. }) => Ok(()),
+        }
+    })
 }
 
 fn check_terminator(
@@ -290,11 +287,11 @@ fn check_terminator(
         | TerminatorKind::Resume => Ok(()),
 
         TerminatorKind::Drop { location, .. } => {
-            check_place(tcx, mir, location, span)
+            check_place(location, span)
         }
         TerminatorKind::DropAndReplace { location, value, .. } => {
-            check_place(tcx, mir, location, span)?;
-            check_operand(tcx, mir, value, span)
+            check_place(location, span)?;
+            check_operand(value, span)
         },
 
         TerminatorKind::FalseEdges { .. } | TerminatorKind::SwitchInt { .. } => Err((
@@ -346,10 +343,10 @@ fn check_terminator(
                     )),
                 }
 
-                check_operand(tcx, mir, func, span)?;
+                check_operand(func, span)?;
 
                 for arg in args {
-                    check_operand(tcx, mir, arg, span)?;
+                    check_operand(arg, span)?;
                 }
                 Ok(())
             } else {
@@ -363,7 +360,7 @@ fn check_terminator(
             msg: _,
             target: _,
             cleanup: _,
-        } => check_operand(tcx, mir, cond, span),
+        } => check_operand(cond, span),
 
         TerminatorKind::FalseUnwind { .. } => {
             Err((span, "loops are not allowed in const fn".into()))
index 98ca7c32675c8b09e1ea0e1083090df7b9c326f7..ac5ebc5e2512a9de4b668b184ca70a7442751404 100644 (file)
@@ -975,9 +975,7 @@ fn constant_usize(&self, val: u16) -> Operand<'tcx> {
             span: self.source_info.span,
             ty: self.tcx().types.usize,
             user_ty: None,
-            literal: self.tcx().mk_const(
-                ty::Const::from_usize(self.tcx(), val.into())
-            ),
+            literal: ty::Const::from_usize(self.tcx(), val.into()),
         })
     }
 
index 94259fa523ccdf018bb7667074abfec1953a8978..cf90f44e6707fd19edfde4aeb3493bb1db3f9bc0 100644 (file)
@@ -588,7 +588,7 @@ fn write_mir_sig(
     match (kind, src.promoted) {
         (_, Some(i)) => write!(w, "{:?} in ", i)?,
         (Some(DefKind::Const), _)
-        | (Some(DefKind::AssociatedConst), _) => write!(w, "const ")?,
+        | (Some(DefKind::AssocConst), _) => write!(w, "const ")?,
         (Some(DefKind::Static), _) =>
             write!(w, "static {}", if tcx.is_mutable_static(src.def_id()) { "mut " } else { "" })?,
         (_, _) if is_function => write!(w, "fn ")?,
index 37917aaa4a80f4c2c7b39adcf6a2edee2319d60f..85cd602db591f6947449bc460cba813a661b442b 100644 (file)
@@ -351,7 +351,7 @@ fn check_expr_kind<'a, 'tcx>(
                 }
 
                 Res::Def(DefKind::Const, did) |
-                Res::Def(DefKind::AssociatedConst, did) => {
+                Res::Def(DefKind::AssocConst, did) => {
                     let promotable = if v.tcx.trait_of_item(did).is_some() {
                         // Don't peek inside trait associated constants.
                         NotPromotable
index 46cd66fe58546d0ae79df7a3fb0d24f5ef9dee82..4481892bcf244ca2ad572058a54669a7df136f04 100644 (file)
@@ -10,7 +10,7 @@
 use std::mem;
 use std::path::PathBuf;
 use syntax::ast;
-use syntax::span_err;
+use syntax::struct_span_err;
 use syntax::symbol::{Symbol, kw, sym};
 use syntax_pos::{Span, DUMMY_SP};
 
@@ -29,8 +29,10 @@ struct PluginLoader<'a> {
     plugins: Vec<PluginRegistrar>,
 }
 
-fn call_malformed_plugin_attribute(a: &Session, b: Span) {
-    span_err!(a, b, E0498, "malformed plugin attribute");
+fn call_malformed_plugin_attribute(sess: &Session, span: Span) {
+    struct_span_err!(sess, span, E0498, "malformed `plugin` attribute")
+        .span_label(span, "malformed attribute")
+        .emit();
 }
 
 /// Read plugin metadata and dynamically load registrar functions.
index 65b6a89aa0b4d4225cd98e14e44144f42d73feb3..68930533a285ca8dd26f13d7fb97417a6e2dd4ba 100644 (file)
@@ -11,7 +11,7 @@
 #[macro_use] extern crate syntax;
 
 use rustc::bug;
-use rustc::hir::{self, Node, PatKind, AssociatedItemKind};
+use rustc::hir::{self, Node, PatKind, AssocItemKind};
 use rustc::hir::def::{Res, DefKind};
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
@@ -624,7 +624,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                         let mut reach = self.reach(trait_item_ref.id.hir_id, item_level);
                         reach.generics().predicates();
 
-                        if trait_item_ref.kind == AssociatedItemKind::Type &&
+                        if trait_item_ref.kind == AssocItemKind::Type &&
                            !trait_item_ref.defaultness.has_value() {
                             // No type to visit.
                         } else {
@@ -1112,9 +1112,9 @@ fn visit_qpath(&mut self, qpath: &'tcx hir::QPath, id: hir::HirId, span: Span) {
         let def = def.filter(|(kind, _)| {
             match kind {
                 DefKind::Method
-                | DefKind::AssociatedConst
-                | DefKind::AssociatedTy
-                | DefKind::AssociatedExistential
+                | DefKind::AssocConst
+                | DefKind::AssocTy
+                | DefKind::AssocExistential
                 | DefKind::Static => true,
                 _ => false,
             }
@@ -1448,11 +1448,11 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                         if self.item_is_public(&impl_item_ref.id.hir_id, &impl_item_ref.vis) {
                             let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                             match impl_item_ref.kind {
-                                AssociatedItemKind::Const => {
+                                AssocItemKind::Const => {
                                     found_pub_static = true;
                                     intravisit::walk_impl_item(self, impl_item);
                                 }
-                                AssociatedItemKind::Method { has_self: false } => {
+                                AssocItemKind::Method { has_self: false } => {
                                     found_pub_static = true;
                                     intravisit::walk_impl_item(self, impl_item);
                                 }
@@ -1703,16 +1703,16 @@ fn check(&self, item_id: hir::HirId, required_visibility: ty::Visibility)
         }
     }
 
-    fn check_trait_or_impl_item(&self, hir_id: hir::HirId, assoc_item_kind: AssociatedItemKind,
+    fn check_trait_or_impl_item(&self, hir_id: hir::HirId, assoc_item_kind: AssocItemKind,
                                 defaultness: hir::Defaultness, vis: ty::Visibility) {
         let mut check = self.check(hir_id, vis);
 
         let (check_ty, is_assoc_ty) = match assoc_item_kind {
-            AssociatedItemKind::Const | AssociatedItemKind::Method { .. } => (true, false),
-            AssociatedItemKind::Type => (defaultness.has_value(), true),
+            AssocItemKind::Const | AssocItemKind::Method { .. } => (true, false),
+            AssocItemKind::Type => (defaultness.has_value(), true),
             // `ty()` for existential types is the underlying type,
             // it's not a part of interface, so we skip it.
-            AssociatedItemKind::Existential => (false, true),
+            AssocItemKind::Existential => (false, true),
         };
         check.in_assoc_ty = is_assoc_ty;
         check.generics().predicates();
index 8c516a4da4e5fca9b7055c3e0b7f01b3be70e34e..92faab192fa9ed6a66e8c9e23aaf81775e685d05 100644 (file)
@@ -705,7 +705,7 @@ fn build_reduced_graph_for_external_crate_res(
 
                 for child in self.cstore.item_children_untracked(def_id, self.session) {
                     let res = child.res.map_id(|_| panic!("unexpected id"));
-                    let ns = if let Res::Def(DefKind::AssociatedTy, _) = res {
+                    let ns = if let Res::Def(DefKind::AssocTy, _) = res {
                         TypeNS
                     } else { ValueNS };
                     self.define(module, child.ident, ns,
@@ -1033,14 +1033,14 @@ fn visit_trait_item(&mut self, item: &'a TraitItem) {
         // Add the item to the trait info.
         let item_def_id = self.resolver.definitions.local_def_id(item.id);
         let (res, ns) = match item.node {
-            TraitItemKind::Const(..) => (Res::Def(DefKind::AssociatedConst, item_def_id), ValueNS),
+            TraitItemKind::Const(..) => (Res::Def(DefKind::AssocConst, item_def_id), ValueNS),
             TraitItemKind::Method(ref sig, _) => {
                 if sig.decl.has_self() {
                     self.resolver.has_self.insert(item_def_id);
                 }
                 (Res::Def(DefKind::Method, item_def_id), ValueNS)
             }
-            TraitItemKind::Type(..) => (Res::Def(DefKind::AssociatedTy, item_def_id), TypeNS),
+            TraitItemKind::Type(..) => (Res::Def(DefKind::AssocTy, item_def_id), TypeNS),
             TraitItemKind::Macro(_) => bug!(),  // handled above
         };
 
index 8b5e2b86d5ee8025804b1c4b802497e0833759fb..d8292eebce79953afca7c9e61a533b2266dcc775 100644 (file)
@@ -432,7 +432,7 @@ fn smart_resolve_context_dependent_help(
                 err.note("can't use `Self` as a constructor, you must use the implemented struct");
             }
             (Res::Def(DefKind::TyAlias, _), _)
-            | (Res::Def(DefKind::AssociatedTy, _), _) if ns == ValueNS => {
+            | (Res::Def(DefKind::AssocTy, _), _) if ns == ValueNS => {
                 err.note("can't use a type alias as a constructor");
             }
             _ => return false,
index a7097a9475ede1bee0879ad74eb7a80898848adf..c05b69ab44f422ba98700e650befc143eb37ac2f 100644 (file)
@@ -589,7 +589,7 @@ fn is_expected(self, res: Res) -> bool {
                 | Res::Def(DefKind::Trait, _)
                 | Res::Def(DefKind::TraitAlias, _)
                 | Res::Def(DefKind::TyAlias, _)
-                | Res::Def(DefKind::AssociatedTy, _)
+                | Res::Def(DefKind::AssocTy, _)
                 | Res::PrimTy(..)
                 | Res::Def(DefKind::TyParam, _)
                 | Res::SelfTy(..)
@@ -615,14 +615,14 @@ fn is_expected(self, res: Res) -> bool {
                 | Res::Upvar(..)
                 | Res::Def(DefKind::Fn, _)
                 | Res::Def(DefKind::Method, _)
-                | Res::Def(DefKind::AssociatedConst, _)
+                | Res::Def(DefKind::AssocConst, _)
                 | Res::SelfCtor(..)
                 | Res::Def(DefKind::ConstParam, _) => true,
                 _ => false,
             },
             PathSource::Pat => match res {
                 Res::Def(DefKind::Ctor(_, CtorKind::Const), _) |
-                Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssociatedConst, _) |
+                Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) |
                 Res::SelfCtor(..) => true,
                 _ => false,
             },
@@ -635,14 +635,14 @@ fn is_expected(self, res: Res) -> bool {
                 | Res::Def(DefKind::Union, _)
                 | Res::Def(DefKind::Variant, _)
                 | Res::Def(DefKind::TyAlias, _)
-                | Res::Def(DefKind::AssociatedTy, _)
+                | Res::Def(DefKind::AssocTy, _)
                 | Res::SelfTy(..) => true,
                 _ => false,
             },
             PathSource::TraitItem(ns) => match res {
-                Res::Def(DefKind::AssociatedConst, _)
+                Res::Def(DefKind::AssocConst, _)
                 | Res::Def(DefKind::Method, _) if ns == ValueNS => true,
-                Res::Def(DefKind::AssociatedTy, _) if ns == TypeNS => true,
+                Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true,
                 _ => false,
             },
             PathSource::Visibility => match res {
@@ -1511,9 +1511,9 @@ fn is_glob_import(&self) -> bool {
 
     fn is_importable(&self) -> bool {
         match self.res() {
-            Res::Def(DefKind::AssociatedConst, _)
+            Res::Def(DefKind::AssocConst, _)
             | Res::Def(DefKind::Method, _)
-            | Res::Def(DefKind::AssociatedTy, _) => false,
+            | Res::Def(DefKind::AssocTy, _) => false,
             _ => true,
         }
     }
index 1fdfcc84926f659f4ed1cd76702b51594a4f456f..06758044a216694cf6e00d9efcfacd34986b9f68 100644 (file)
@@ -961,11 +961,11 @@ fn process_var_decl_multi(&mut self, pats: &'l [P<ast::Pat>]) {
                 }
                 Res::Def(HirDefKind::Ctor(..), _) |
                 Res::Def(HirDefKind::Const, _) |
-                Res::Def(HirDefKind::AssociatedConst, _) |
+                Res::Def(HirDefKind::AssocConst, _) |
                 Res::Def(HirDefKind::Struct, _) |
                 Res::Def(HirDefKind::Variant, _) |
                 Res::Def(HirDefKind::TyAlias, _) |
-                Res::Def(HirDefKind::AssociatedTy, _) |
+                Res::Def(HirDefKind::AssocTy, _) |
                 Res::SelfTy(..) => {
                     self.dump_path_ref(id, &ast::Path::from_ident(ident));
                 }
index 55471dbc00be5c75a3dfbdbd8bd3b8ba8966078f..8faa4c71807805159140ba11bcde2fb4f248dc4d 100644 (file)
@@ -723,8 +723,8 @@ fn fn_type(seg: &ast::PathSegment) -> bool {
             Res::Def(HirDefKind::TyAlias, def_id) |
             Res::Def(HirDefKind::ForeignTy, def_id) |
             Res::Def(HirDefKind::TraitAlias, def_id) |
-            Res::Def(HirDefKind::AssociatedExistential, def_id) |
-            Res::Def(HirDefKind::AssociatedTy, def_id) |
+            Res::Def(HirDefKind::AssocExistential, def_id) |
+            Res::Def(HirDefKind::AssocTy, def_id) |
             Res::Def(HirDefKind::Trait, def_id) |
             Res::Def(HirDefKind::Existential, def_id) |
             Res::Def(HirDefKind::TyParam, def_id) => {
@@ -754,7 +754,7 @@ fn fn_type(seg: &ast::PathSegment) -> bool {
             }
             Res::Def(HirDefKind::Static, _) |
             Res::Def(HirDefKind::Const, _) |
-            Res::Def(HirDefKind::AssociatedConst, _) |
+            Res::Def(HirDefKind::AssocConst, _) |
             Res::Def(HirDefKind::Ctor(..), _) => {
                 Some(Ref {
                     kind: RefKind::Variable,
index fa12d9c49dfc37ce383ade4ff37af9f88269c2d8..109863f8a56b2798e06ed2207b453c639f0f64f5 100644 (file)
@@ -586,7 +586,7 @@ fn make(&self, offset: usize, id: Option<NodeId>, scx: &SaveContext<'_, '_>) ->
                     refs: vec![],
                 })
             }
-            Res::Def(DefKind::AssociatedConst, _)
+            Res::Def(DefKind::AssocConst, _)
             | Res::Def(DefKind::Variant, _)
             | Res::Def(DefKind::Ctor(..), _) => {
                 let len = self.segments.len();
index ecea15a992250427a3bc6e8d7e161b8153e2e1bf..3ab25146331c15729d1b8dd1032a48a8f80769d2 100644 (file)
@@ -15,3 +15,4 @@ log = "0.4"
 rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 serialize = { path = "../libserialize" }
+syntax_pos = { path = "../libsyntax_pos" }
index 4b61057e5cf6cec4b5c5d13dc807880517297261..8fc5e6aae34d4b8051ef89b9afa6ea25a52d7bc1 100644 (file)
@@ -7,6 +7,7 @@
 use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive};
 
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
+use syntax_pos::symbol::{sym, Symbol};
 
 pub mod call;
 
@@ -552,6 +553,13 @@ pub fn ty_to_string(self) -> &'static str {
         }
     }
 
+    pub fn to_symbol(self) -> Symbol {
+        match self {
+            FloatTy::F32 => sym::f32,
+            FloatTy::F64 => sym::f64,
+        }
+    }
+
     pub fn bit_width(self) -> usize {
         match self {
             FloatTy::F32 => 32,
index 580b1571e52bb1dd55bc5254ecf05e87806b9e20..80b0868a551344f6ecc1ce6d05edfaf085aeedb7 100644 (file)
@@ -166,10 +166,10 @@ fn into_well_formed_goal(self) -> DomainGoal<'tcx> {
             | Some(DefKind::TraitAlias) => program_clauses_for_trait(tcx, def_id),
             // FIXME(eddyb) deduplicate this `associated_item` call with
             // `program_clauses_for_associated_type_{value,def}`.
-            Some(DefKind::AssociatedTy) => match tcx.associated_item(def_id).container {
-                ty::AssociatedItemContainer::ImplContainer(_) =>
+            Some(DefKind::AssocTy) => match tcx.associated_item(def_id).container {
+                ty::AssocItemContainer::ImplContainer(_) =>
                     program_clauses_for_associated_type_value(tcx, def_id),
-                ty::AssociatedItemContainer::TraitContainer(_) =>
+                ty::AssocItemContainer::TraitContainer(_) =>
                     program_clauses_for_associated_type_def(tcx, def_id)
             },
             Some(DefKind::Struct)
@@ -444,9 +444,9 @@ pub fn program_clauses_for_associated_type_def<'a, 'tcx>(
     // ```
 
     let item = tcx.associated_item(item_id);
-    debug_assert_eq!(item.kind, ty::AssociatedKind::Type);
+    debug_assert_eq!(item.kind, ty::AssocKind::Type);
     let trait_id = match item.container {
-        ty::AssociatedItemContainer::TraitContainer(trait_id) => trait_id,
+        ty::AssocItemContainer::TraitContainer(trait_id) => trait_id,
         _ => bug!("not an trait container"),
     };
 
@@ -582,9 +582,9 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
     // ```
 
     let item = tcx.associated_item(item_id);
-    debug_assert_eq!(item.kind, ty::AssociatedKind::Type);
+    debug_assert_eq!(item.kind, ty::AssocKind::Type);
     let impl_id = match item.container {
-        ty::AssociatedItemContainer::ImplContainer(impl_id) => impl_id,
+        ty::AssocItemContainer::ImplContainer(impl_id) => impl_id,
         _ => bug!("not an impl container"),
     };
 
index 3a2b0178ce4d099c525ea7457ed1bc3bc7bb5737..5b1a2e29c7642365d7208104bd7973e9d2ed20a8 100644 (file)
@@ -823,7 +823,7 @@ fn trait_defines_associated_type_named(&self,
                                            -> bool
     {
         self.tcx().associated_items(trait_def_id).any(|item| {
-            item.kind == ty::AssociatedKind::Type &&
+            item.kind == ty::AssocKind::Type &&
             self.tcx().hygienic_eq(assoc_name, item.ident, trait_def_id)
         })
     }
@@ -905,7 +905,7 @@ fn ast_type_binding_to_poly_projection_predicate(
         let (assoc_ident, def_scope) =
             tcx.adjust_ident(binding.item_name, candidate.def_id(), hir_ref_id);
         let assoc_ty = tcx.associated_items(candidate.def_id()).find(|i| {
-            i.kind == ty::AssociatedKind::Type && i.ident.modern() == assoc_ident
+            i.kind == ty::AssocKind::Type && i.ident.modern() == assoc_ident
         }).expect("missing associated type");
 
         if !assoc_ty.vis.is_accessible_from(def_scope, tcx) {
@@ -1045,7 +1045,7 @@ fn conv_object_ty_poly_trait_ref(&self,
                 ty::Predicate::Trait(pred) => {
                     associated_types
                         .extend(tcx.associated_items(pred.def_id())
-                        .filter(|item| item.kind == ty::AssociatedKind::Type)
+                        .filter(|item| item.kind == ty::AssocKind::Type)
                         .map(|item| item.def_id));
                 }
                 ty::Predicate::Projection(pred) => {
@@ -1300,7 +1300,7 @@ fn one_bound_for_assoc_type<I>(&self,
 
             for bound in bounds {
                 let bound_span = self.tcx().associated_items(bound.def_id()).find(|item| {
-                    item.kind == ty::AssociatedKind::Type &&
+                    item.kind == ty::AssocKind::Type &&
                         self.tcx().hygienic_eq(assoc_name, item.ident, bound.def_id())
                 })
                 .and_then(|item| self.tcx().hir().span_if_local(item.def_id));
@@ -1442,7 +1442,7 @@ pub fn associated_path_to_ty(
         let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, bound);
         let ty = self.normalize_ty(span, ty);
 
-        let kind = DefKind::AssociatedTy;
+        let kind = DefKind::AssocTy;
         if !item.vis.is_accessible_from(def_scope, tcx) {
             let msg = format!("{} `{}` is private", kind.descr(), assoc_ident);
             tcx.sess.span_err(span, &msg);
@@ -1685,7 +1685,7 @@ pub fn def_ids_for_value_path_segments(
 
             // Case 4. Reference to a method or associated const.
             DefKind::Method
-            | DefKind::AssociatedConst => {
+            | DefKind::AssocConst => {
                 if segments.len() >= 2 {
                     let generics = tcx.generics_of(def_id);
                     path_segs.push(PathSeg(generics.parent.unwrap(), last - 1));
@@ -1779,7 +1779,7 @@ pub fn res_to_ty(&self,
                 self.prohibit_generics(&path.segments);
                 tcx.mk_self_type()
             }
-            Res::Def(DefKind::AssociatedTy, def_id) => {
+            Res::Def(DefKind::AssocTy, def_id) => {
                 debug_assert!(path.segments.len() >= 2);
                 self.prohibit_generics(&path.segments[..path.segments.len() - 2]);
                 self.qpath_to_ty(span,
index e4b431e6e68f17bc653196b4818d043680b3d13c..a74a33b7448e2e3933cbce3de2996eb7f2f84b1b 100644 (file)
@@ -67,7 +67,7 @@ pub fn check_pat_walk(
             PatKind::Path(ref qpath) => {
                 let (def, _, _) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
                 match def {
-                    Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssociatedConst, _) => false,
+                    Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => false,
                     _ => true,
                 }
             }
@@ -1050,7 +1050,7 @@ fn check_pat_path(
                 return tcx.types.err;
             }
             Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::SelfCtor(..) |
-            Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssociatedConst, _) => {} // OK
+            Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => {} // OK
             _ => bug!("unexpected pattern resolution: {:?}", res)
         }
 
@@ -1107,7 +1107,7 @@ fn check_pat_tuple_struct(
                 on_error();
                 return tcx.types.err;
             }
-            Res::Def(DefKind::AssociatedConst, _) | Res::Def(DefKind::Method, _) => {
+            Res::Def(DefKind::AssocConst, _) | Res::Def(DefKind::Method, _) => {
                 report_unexpected_res(res);
                 return tcx.types.err;
             }
index 647d947485e689282c8b3a60088b30ffa1d4d8e5..1165890fe6432608df3e9d70f9dfd37c887f10b9 100644 (file)
@@ -24,9 +24,9 @@
 /// - `impl_trait_ref`: the TraitRef corresponding to the trait implementation
 
 pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                     impl_m: &ty::AssociatedItem,
+                                     impl_m: &ty::AssocItem,
                                      impl_m_span: Span,
-                                     trait_m: &ty::AssociatedItem,
+                                     trait_m: &ty::AssocItem,
                                      impl_trait_ref: ty::TraitRef<'tcx>,
                                      trait_item_span: Option<Span>) {
     debug!("compare_impl_method(impl_trait_ref={:?})",
@@ -74,9 +74,9 @@ pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                          impl_m: &ty::AssociatedItem,
+                                          impl_m: &ty::AssocItem,
                                           impl_m_span: Span,
-                                          trait_m: &ty::AssociatedItem,
+                                          trait_m: &ty::AssocItem,
                                           impl_trait_ref: ty::TraitRef<'tcx>)
                                           -> Result<(), ErrorReported> {
     let trait_to_impl_substs = impl_trait_ref.substs;
@@ -357,8 +357,8 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
 fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                 span: Span,
-                                                impl_m: &ty::AssociatedItem,
-                                                trait_m: &ty::AssociatedItem,
+                                                impl_m: &ty::AssocItem,
+                                                trait_m: &ty::AssocItem,
                                                 trait_generics: &ty::Generics,
                                                 impl_generics: &ty::Generics,
                                                 trait_to_skol_substs: SubstsRef<'tcx>)
@@ -410,9 +410,9 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
                                                      param_env: ty::ParamEnv<'tcx>,
                                                      terr: &TypeError<'_>,
                                                      cause: &ObligationCause<'tcx>,
-                                                     impl_m: &ty::AssociatedItem,
+                                                     impl_m: &ty::AssocItem,
                                                      impl_sig: ty::FnSig<'tcx>,
-                                                     trait_m: &ty::AssociatedItem,
+                                                     trait_m: &ty::AssocItem,
                                                      trait_sig: ty::FnSig<'tcx>)
                                                      -> (Span, Option<Span>) {
     let tcx = infcx.tcx;
@@ -496,9 +496,9 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
 }
 
 fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                               impl_m: &ty::AssociatedItem,
+                               impl_m: &ty::AssocItem,
                                impl_m_span: Span,
-                               trait_m: &ty::AssociatedItem,
+                               trait_m: &ty::AssocItem,
                                impl_trait_ref: ty::TraitRef<'tcx>)
                                -> Result<(), ErrorReported>
 {
@@ -510,7 +510,7 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // inscrutable, particularly for cases where one method has no
     // self.
 
-    let self_string = |method: &ty::AssociatedItem| {
+    let self_string = |method: &ty::AssocItem| {
         let untransformed_self_ty = match method.container {
             ty::ImplContainer(_) => impl_trait_ref.self_ty(),
             ty::TraitContainer(_) => tcx.mk_self_type()
@@ -582,9 +582,9 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
 fn compare_number_of_generics<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    impl_: &ty::AssociatedItem,
+    impl_: &ty::AssocItem,
     impl_span: Span,
-    trait_: &ty::AssociatedItem,
+    trait_: &ty::AssocItem,
     trait_span: Option<Span>,
 ) -> Result<(), ErrorReported> {
     let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts();
@@ -655,9 +655,9 @@ fn compare_number_of_generics<'a, 'tcx>(
 }
 
 fn compare_number_of_method_arguments<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                                impl_m: &ty::AssociatedItem,
+                                                impl_m: &ty::AssocItem,
                                                 impl_m_span: Span,
-                                                trait_m: &ty::AssociatedItem,
+                                                trait_m: &ty::AssocItem,
                                                 trait_item_span: Option<Span>)
                                                 -> Result<(), ErrorReported> {
     let impl_m_fty = tcx.fn_sig(impl_m.def_id);
@@ -739,8 +739,8 @@ trait `{}` has {}",
 }
 
 fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                        impl_m: &ty::AssociatedItem,
-                                        trait_m: &ty::AssociatedItem)
+                                        impl_m: &ty::AssocItem,
+                                        trait_m: &ty::AssocItem)
                                         -> Result<(), ErrorReported> {
     // FIXME(chrisvittal) Clean up this function, list of FIXME items:
     //     1. Better messages for the span labels
@@ -911,9 +911,9 @@ fn nested_visit_map<'this>(
 }
 
 pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                    impl_c: &ty::AssociatedItem,
+                                    impl_c: &ty::AssocItem,
                                     impl_c_span: Span,
-                                    trait_c: &ty::AssociatedItem,
+                                    trait_c: &ty::AssocItem,
                                     impl_trait_ref: ty::TraitRef<'tcx>) {
     debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref);
 
index a4e687b8f9080f4b4e8e535af1b36200c26dc7dc..724f8d886e8a76da0d311f22c9999ddaa6a3156b 100644 (file)
@@ -8,7 +8,7 @@
 use rustc::hir;
 use rustc::hir::Node;
 use rustc::hir::{print, lowering::is_range_literal};
-use rustc::ty::{self, Ty, AssociatedItem};
+use rustc::ty::{self, Ty, AssocItem};
 use rustc::ty::adjustment::AllowTwoPhase;
 use errors::{Applicability, DiagnosticBuilder};
 
@@ -179,7 +179,7 @@ fn suggest_compatible_variants(
     }
 
     pub fn get_conversion_methods(&self, span: Span, expected: Ty<'tcx>, checked_ty: Ty<'tcx>)
-                              -> Vec<AssociatedItem> {
+                              -> Vec<AssocItem> {
         let mut methods = self.probe_for_return_type(span,
                                                      probe::Mode::MethodCall,
                                                      expected,
@@ -205,9 +205,9 @@ pub fn get_conversion_methods(&self, span: Span, expected: Ty<'tcx>, checked_ty:
     }
 
     // This function checks if the method isn't static and takes other arguments than `self`.
-    fn has_no_input_arg(&self, method: &AssociatedItem) -> bool {
+    fn has_no_input_arg(&self, method: &AssocItem) -> bool {
         match method.kind {
-            ty::AssociatedKind::Method => {
+            ty::AssocKind::Method => {
                 self.tcx.fn_sig(method.def_id).inputs().skip_binder().len() == 1
             }
             _ => false,
index a4b1687ea53012e7f2aed116b495e0e85dca8dc4..65bc06b65e1fca18344c2a3e45b93635954fbe85 100644 (file)
@@ -71,7 +71,7 @@ pub struct NoMatchData<'tcx> {
     pub static_candidates: Vec<CandidateSource>,
     pub unsatisfied_predicates: Vec<TraitRef<'tcx>>,
     pub out_of_scope_traits: Vec<DefId>,
-    pub lev_candidate: Option<ty::AssociatedItem>,
+    pub lev_candidate: Option<ty::AssocItem>,
     pub mode: probe::Mode,
 }
 
@@ -79,7 +79,7 @@ impl<'tcx> NoMatchData<'tcx> {
     pub fn new(static_candidates: Vec<CandidateSource>,
                unsatisfied_predicates: Vec<TraitRef<'tcx>>,
                out_of_scope_traits: Vec<DefId>,
-               lev_candidate: Option<ty::AssociatedItem>,
+               lev_candidate: Option<ty::AssocItem>,
                mode: probe::Mode)
                -> Self {
         NoMatchData {
@@ -450,7 +450,7 @@ pub fn resolve_ufcs(
     /// Finds item with name `item_name` defined in impl/trait `def_id`
     /// and return it, or `None`, if no such item was defined there.
     pub fn associated_item(&self, def_id: DefId, item_name: ast::Ident, ns: Namespace)
-                           -> Option<ty::AssociatedItem> {
+                           -> Option<ty::AssocItem> {
         self.tcx.associated_items(def_id).find(|item| {
             Namespace::from(item.kind) == ns &&
             self.tcx.hygienic_eq(item_name, item.ident, def_id)
index 590ae9d46e8db42385f9e5856624d96fd69297fc..596ce008099a68162db9a7467f02a2dba296991f 100644 (file)
@@ -89,7 +89,7 @@ fn deref(&self) -> &Self::Target {
 #[derive(Debug)]
 struct Candidate<'tcx> {
     // Candidates are (I'm not quite sure, but they are mostly) basically
-    // some metadata on top of a `ty::AssociatedItem` (without substs).
+    // some metadata on top of a `ty::AssocItem` (without substs).
     //
     // However, method probing wants to be able to evaluate the predicates
     // for a function with the substs applied - for example, if a function
@@ -121,7 +121,7 @@ struct Candidate<'tcx> {
     // if `T: Sized`.
     xform_self_ty: Ty<'tcx>,
     xform_ret_ty: Option<Ty<'tcx>>,
-    item: ty::AssociatedItem,
+    item: ty::AssocItem,
     kind: CandidateKind<'tcx>,
     import_ids: SmallVec<[hir::HirId; 1]>,
 }
@@ -146,7 +146,7 @@ enum ProbeResult {
 
 #[derive(Debug, PartialEq, Clone)]
 pub struct Pick<'tcx> {
-    pub item: ty::AssociatedItem,
+    pub item: ty::AssocItem,
     pub kind: PickKind<'tcx>,
     pub import_ids: SmallVec<[hir::HirId; 1]>,
 
@@ -213,7 +213,7 @@ pub fn probe_for_return_type(&self,
                                  return_type: Ty<'tcx>,
                                  self_ty: Ty<'tcx>,
                                  scope_expr_id: hir::HirId)
-                                 -> Vec<ty::AssociatedItem> {
+                                 -> Vec<ty::AssocItem> {
         debug!("probe(self_ty={:?}, return_type={}, scope_expr_id={})",
                self_ty,
                return_type,
@@ -812,7 +812,7 @@ fn elaborate_bounds<F>(&mut self,
                            mut mk_cand: F)
         where F: for<'b> FnMut(&mut ProbeContext<'b, 'gcx, 'tcx>,
                                ty::PolyTraitRef<'tcx>,
-                               ty::AssociatedItem)
+                               ty::AssocItem)
     {
         let tcx = self.tcx;
         for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
@@ -861,11 +861,11 @@ fn assemble_extension_candidates_for_all_traits(&mut self) -> Result<(), MethodE
     }
 
     pub fn matches_return_type(&self,
-                               method: &ty::AssociatedItem,
+                               method: &ty::AssocItem,
                                self_ty: Option<Ty<'tcx>>,
                                expected: Ty<'tcx>) -> bool {
         match method.kind {
-            ty::AssociatedKind::Method => {
+            ty::AssocKind::Method => {
                 let fty = self.tcx.fn_sig(method.def_id);
                 self.probe(|_| {
                     let substs = self.fresh_substs_for_item(self.span, method.def_id);
@@ -1425,7 +1425,7 @@ fn collapse_candidates_to_trait_pick(&self, probes: &[(&Candidate<'tcx>, ProbeRe
     /// Similarly to `probe_for_return_type`, this method attempts to find the best matching
     /// candidate method where the method name may have been misspelt. Similarly to other
     /// Levenshtein based suggestions, we provide at most one such suggestion.
-    fn probe_for_lev_candidate(&mut self) -> Result<Option<ty::AssociatedItem>, MethodError<'tcx>> {
+    fn probe_for_lev_candidate(&mut self) -> Result<Option<ty::AssocItem>, MethodError<'tcx>> {
         debug!("Probing for method names similar to {:?}",
                self.method_name);
 
@@ -1441,7 +1441,7 @@ fn probe_for_lev_candidate(&mut self) -> Result<Option<ty::AssociatedItem>, Meth
 
             let method_names = pcx.candidate_method_names();
             pcx.allow_similar_names = false;
-            let applicable_close_candidates: Vec<ty::AssociatedItem> = method_names
+            let applicable_close_candidates: Vec<ty::AssocItem> = method_names
                 .iter()
                 .filter_map(|&method_name| {
                     pcx.reset();
@@ -1474,7 +1474,7 @@ fn probe_for_lev_candidate(&mut self) -> Result<Option<ty::AssociatedItem>, Meth
 
     ///////////////////////////////////////////////////////////////////////////
     // MISCELLANY
-    fn has_applicable_self(&self, item: &ty::AssociatedItem) -> bool {
+    fn has_applicable_self(&self, item: &ty::AssocItem) -> bool {
         // "Fast track" -- check for usage of sugar when in method call
         // mode.
         //
@@ -1483,9 +1483,9 @@ fn has_applicable_self(&self, item: &ty::AssociatedItem) -> bool {
         match self.mode {
             Mode::MethodCall => item.method_has_self_argument,
             Mode::Path => match item.kind {
-                ty::AssociatedKind::Existential |
-                ty::AssociatedKind::Type => false,
-                ty::AssociatedKind::Method | ty::AssociatedKind::Const => true
+                ty::AssocKind::Existential |
+                ty::AssocKind::Type => false,
+                ty::AssocKind::Method | ty::AssocKind::Const => true
             },
         }
         // FIXME -- check for types that deref to `Self`,
@@ -1501,11 +1501,11 @@ fn record_static_candidate(&mut self, source: CandidateSource) {
     }
 
     fn xform_self_ty(&self,
-                     item: &ty::AssociatedItem,
+                     item: &ty::AssocItem,
                      impl_ty: Ty<'tcx>,
                      substs: SubstsRef<'tcx>)
                      -> (Ty<'tcx>, Option<Ty<'tcx>>) {
-        if item.kind == ty::AssociatedKind::Method && self.mode == Mode::MethodCall {
+        if item.kind == ty::AssocKind::Method && self.mode == Mode::MethodCall {
             let sig = self.xform_method_sig(item.def_id, substs);
             (sig.inputs()[0], Some(sig.output()))
         } else {
@@ -1610,7 +1610,7 @@ fn erase_late_bound_regions<T>(&self, value: &ty::Binder<T>) -> T
 
     /// Finds the method with the appropriate name (or return type, as the case may be). If
     /// `allow_similar_names` is set, find methods with close-matching names.
-    fn impl_or_trait_item(&self, def_id: DefId) -> Vec<ty::AssociatedItem> {
+    fn impl_or_trait_item(&self, def_id: DefId) -> Vec<ty::AssocItem> {
         if let Some(name) = self.method_name {
             if self.allow_similar_names {
                 let max_dist = max(name.as_str().len(), 3) / 3;
index 655bf5722ae5af7eb2959a3790d34286178343ff..f60ad5547a278caac464c1cce5700acef8057937 100644 (file)
@@ -1499,17 +1499,17 @@ fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                            trait_def: &ty::TraitDef,
-                                           trait_item: &ty::AssociatedItem,
+                                           trait_item: &ty::AssocItem,
                                            impl_id: DefId,
                                            impl_item: &hir::ImplItem)
 {
     let ancestors = trait_def.ancestors(tcx, impl_id);
 
     let kind = match impl_item.node {
-        hir::ImplItemKind::Const(..) => ty::AssociatedKind::Const,
-        hir::ImplItemKind::Method(..) => ty::AssociatedKind::Method,
-        hir::ImplItemKind::Existential(..) => ty::AssociatedKind::Existential,
-        hir::ImplItemKind::Type(_) => ty::AssociatedKind::Type
+        hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
+        hir::ImplItemKind::Method(..) => ty::AssocKind::Method,
+        hir::ImplItemKind::Existential(..) => ty::AssocKind::Existential,
+        hir::ImplItemKind::Type(_) => ty::AssocKind::Type
     };
 
     let parent = ancestors.defs(tcx, trait_item.ident, kind, trait_def.def_id).nth(1)
@@ -1560,7 +1560,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             match impl_item.node {
                 hir::ImplItemKind::Const(..) => {
                     // Find associated const definition.
-                    if ty_trait_item.kind == ty::AssociatedKind::Const {
+                    if ty_trait_item.kind == ty::AssocKind::Const {
                         compare_const_impl(tcx,
                                            &ty_impl_item,
                                            impl_item.span,
@@ -1583,7 +1583,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 }
                 hir::ImplItemKind::Method(..) => {
                     let trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
-                    if ty_trait_item.kind == ty::AssociatedKind::Method {
+                    if ty_trait_item.kind == ty::AssocKind::Method {
                         compare_impl_method(tcx,
                                             &ty_impl_item,
                                             impl_item.span,
@@ -1605,7 +1605,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 }
                 hir::ImplItemKind::Existential(..) |
                 hir::ImplItemKind::Type(_) => {
-                    if ty_trait_item.kind == ty::AssociatedKind::Type {
+                    if ty_trait_item.kind == ty::AssocKind::Type {
                         if ty_trait_item.defaultness.has_value() {
                             overridden_associated_type = Some(impl_item);
                         }
@@ -2697,16 +2697,12 @@ fn try_index_step(&self,
 
     fn resolve_place_op(&self, op: PlaceOp, is_mut: bool) -> (Option<DefId>, ast::Ident) {
         let (tr, name) = match (op, is_mut) {
-            (PlaceOp::Deref, false) =>
-                (self.tcx.lang_items().deref_trait(), "deref"),
-            (PlaceOp::Deref, true) =>
-                (self.tcx.lang_items().deref_mut_trait(), "deref_mut"),
-            (PlaceOp::Index, false) =>
-                (self.tcx.lang_items().index_trait(), "index"),
-            (PlaceOp::Index, true) =>
-                (self.tcx.lang_items().index_mut_trait(), "index_mut"),
+            (PlaceOp::Deref, false) => (self.tcx.lang_items().deref_trait(), sym::deref),
+            (PlaceOp::Deref, true) => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
+            (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
+            (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
         };
-        (tr, ast::Ident::from_str(name))
+        (tr, ast::Ident::with_empty_ctxt(name))
     }
 
     fn try_overloaded_place_op(&self,
@@ -3746,7 +3742,7 @@ pub fn check_struct_path(&self,
             Res::Def(DefKind::Struct, _)
             | Res::Def(DefKind::Union, _)
             | Res::Def(DefKind::TyAlias, _)
-            | Res::Def(DefKind::AssociatedTy, _)
+            | Res::Def(DefKind::AssocTy, _)
             | Res::SelfTy(..) => {
                 match ty.sty {
                     ty::Adt(adt, substs) if !adt.is_enum() => {
@@ -4441,7 +4437,7 @@ fn check_expr_kind(
                 if element_ty.references_error() {
                     tcx.types.err
                 } else if let Ok(count) = count {
-                    tcx.mk_ty(ty::Array(t, tcx.mk_const(count)))
+                    tcx.mk_ty(ty::Array(t, count))
                 } else {
                     tcx.types.err
                 }
@@ -4948,7 +4944,7 @@ fn get_node_fn_decl(&self, node: Node<'_>) -> Option<(hir::FnDecl, ast::Ident, b
                 // This is less than ideal, it will not suggest a return type span on any
                 // method called `main`, regardless of whether it is actually the entry point,
                 // but it will still present it as the reason for the expected type.
-                Some((decl, ident, ident.name != Symbol::intern("main")))
+                Some((decl, ident, ident.name != sym::main))
             }),
             Node::TraitItem(&hir::TraitItem {
                 ident, node: hir::TraitItemKind::Method(hir::MethodSig {
@@ -5194,7 +5190,7 @@ pub fn rewrite_self_ctor(
         &self,
         res: Res,
         span: Span,
-    ) -> Result<(DefKind, DefId, Ty<'tcx>), ErrorReported> {
+    ) -> Result<Res, ErrorReported> {
         let tcx = self.tcx;
         if let Res::SelfCtor(impl_def_id) = res {
             let ty = self.impl_self_ty(span, impl_def_id).ty;
@@ -5204,11 +5200,7 @@ pub fn rewrite_self_ctor(
                 Some(adt_def) if adt_def.has_ctor() => {
                     let variant = adt_def.non_enum_variant();
                     let ctor_def_id = variant.ctor_def_id.unwrap();
-                    Ok((
-                        DefKind::Ctor(CtorOf::Struct, variant.ctor_kind),
-                        ctor_def_id,
-                        tcx.type_of(ctor_def_id),
-                    ))
+                    Ok(Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id))
                 }
                 _ => {
                     let mut err = tcx.sess.struct_span_err(span,
@@ -5235,15 +5227,7 @@ pub fn rewrite_self_ctor(
                 }
             }
         } else {
-            match res {
-                Res::Def(kind, def_id) => {
-                    // The things we are substituting into the type should not contain
-                    // escaping late-bound regions, and nor should the base type scheme.
-                    let ty = tcx.type_of(def_id);
-                    Ok((kind, def_id, ty))
-                }
-                _ => span_bug!(span, "unexpected res in rewrite_self_ctor: {:?}", res),
-            }
+            Ok(res)
         }
     }
 
@@ -5266,27 +5250,21 @@ pub fn instantiate_value_path(&self,
 
         let tcx = self.tcx;
 
-        match res {
-            Res::Local(hid) | Res::Upvar(hid, ..) => {
-                let ty = self.local_ty(span, hid).decl_ty;
-                let ty = self.normalize_associated_types_in(span, &ty);
-                self.write_ty(hir_id, ty);
-                return (ty, res);
-            }
-            _ => {}
-        }
-
-        let (kind, def_id, ty) = match self.rewrite_self_ctor(res, span) {
-            Ok(result) => result,
+        let res = match self.rewrite_self_ctor(res, span) {
+            Ok(res) => res,
             Err(ErrorReported) => return (tcx.types.err, res),
         };
-        let path_segs =
-            AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id);
+        let path_segs = match res {
+            Res::Local(_) | Res::Upvar(..) => Vec::new(),
+            Res::Def(kind, def_id) =>
+                AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id),
+            _ => bug!("instantiate_value_path on {:?}", res),
+        };
 
         let mut user_self_ty = None;
         let mut is_alias_variant_ctor = false;
-        match kind {
-            DefKind::Ctor(CtorOf::Variant, _) => {
+        match res {
+            Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
                 if let Some(self_ty) = self_ty {
                     let adt_def = self_ty.ty_adt_def().unwrap();
                     user_self_ty = Some(UserSelfTy {
@@ -5296,8 +5274,8 @@ pub fn instantiate_value_path(&self,
                     is_alias_variant_ctor = true;
                 }
             }
-            DefKind::Method
-            | DefKind::AssociatedConst => {
+            Res::Def(DefKind::Method, def_id)
+            | Res::Def(DefKind::AssocConst, def_id) => {
                 let container = tcx.associated_item(def_id).container;
                 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
                 match container {
@@ -5337,6 +5315,17 @@ pub fn instantiate_value_path(&self,
                 None
             }
         }));
+
+        match res {
+            Res::Local(hid) | Res::Upvar(hid, ..) => {
+                let ty = self.local_ty(span, hid).decl_ty;
+                let ty = self.normalize_associated_types_in(span, &ty);
+                self.write_ty(hir_id, ty);
+                return (ty, res);
+            }
+            _ => {}
+        }
+
         if generics_has_err {
             // Don't try to infer type parameters when prohibited generic arguments were given.
             user_self_ty = None;
@@ -5374,6 +5363,12 @@ pub fn instantiate_value_path(&self,
             tcx.generics_of(*def_id).has_self
         }).unwrap_or(false);
 
+        let def_id = res.def_id();
+
+        // The things we are substituting into the type should not contain
+        // escaping late-bound regions, and nor should the base type scheme.
+        let ty = tcx.type_of(def_id);
+
         let substs = AstConv::create_substs_for_generic_args(
             tcx,
             def_id,
@@ -5490,7 +5485,7 @@ pub fn instantiate_value_path(&self,
                ty_substituted);
         self.write_substs(hir_id, substs);
 
-        (ty_substituted, Res::Def(kind, def_id))
+        (ty_substituted, res)
     }
 
     fn check_rustc_args_require_const(&self,
index 7e7a8d59266737920c986d7ac5eddeca96d95ad5..e11172ae36d9b1c494a46c83015d032d624209fe 100644 (file)
@@ -190,12 +190,12 @@ fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         };
 
         match item.kind {
-            ty::AssociatedKind::Const => {
+            ty::AssocKind::Const => {
                 let ty = fcx.tcx.type_of(item.def_id);
                 let ty = fcx.normalize_associated_types_in(span, &ty);
                 fcx.register_wf_obligation(ty, span, code.clone());
             }
-            ty::AssociatedKind::Method => {
+            ty::AssocKind::Method => {
                 reject_shadowing_parameters(fcx.tcx, item.def_id);
                 let sig = fcx.tcx.fn_sig(item.def_id);
                 let sig = fcx.normalize_associated_types_in(span, &sig);
@@ -204,14 +204,14 @@ fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 let sig_if_method = sig_if_method.expect("bad signature for method");
                 check_method_receiver(fcx, sig_if_method, &item, self_ty);
             }
-            ty::AssociatedKind::Type => {
+            ty::AssocKind::Type => {
                 if item.defaultness.has_value() {
                     let ty = fcx.tcx.type_of(item.def_id);
                     let ty = fcx.normalize_associated_types_in(span, &ty);
                     fcx.register_wf_obligation(ty, span, code.clone());
                 }
             }
-            ty::AssociatedKind::Existential => {
+            ty::AssocKind::Existential => {
                 // do nothing, existential types check themselves
             }
         }
@@ -748,7 +748,7 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
 
 fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
                                            method_sig: &hir::MethodSig,
-                                           method: &ty::AssociatedItem,
+                                           method: &ty::AssocItem,
                                            self_ty: Ty<'tcx>)
 {
     // check that the method has a valid receiver type, given the type `Self`
index 45380d757b97d77d981c89366f7c20d090cff79b..00990a5c5b579fee2bdddb82a13e4e793232d851 100644 (file)
@@ -48,6 +48,8 @@
 use rustc::hir::GenericParamKind;
 use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
 
+use errors::Applicability;
+
 use std::iter;
 
 struct OnlySelfBounds(bool);
@@ -2400,13 +2402,18 @@ fn from_target_feature(
         Some(list) => list,
         None => return,
     };
+    let bad_item = |span| {
+        let msg = "malformed `target_feature` attribute input";
+        let code = "enable = \"..\"".to_owned();
+        tcx.sess.struct_span_err(span, &msg)
+            .span_suggestion(span, "must be of the form", code, Applicability::HasPlaceholders)
+            .emit();
+    };
     let rust_features = tcx.features();
     for item in list {
         // Only `enable = ...` is accepted in the meta item list
         if !item.check_name(sym::enable) {
-            let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
-                       currently";
-            tcx.sess.span_err(item.span(), &msg);
+            bad_item(item.span());
             continue;
         }
 
@@ -2414,9 +2421,7 @@ fn from_target_feature(
         let value = match item.value_str() {
             Some(value) => value,
             None => {
-                let msg = "#[target_feature] attribute must be of the form \
-                           #[target_feature(enable = \"..\")]";
-                tcx.sess.span_err(item.span(), &msg);
+                bad_item(item.span());
                 continue;
             }
         };
@@ -2428,12 +2433,14 @@ fn from_target_feature(
                 Some(g) => g,
                 None => {
                     let msg = format!(
-                        "the feature named `{}` is not valid for \
-                         this target",
+                        "the feature named `{}` is not valid for this target",
                         feature
                     );
                     let mut err = tcx.sess.struct_span_err(item.span(), &msg);
-
+                    err.span_label(
+                        item.span(),
+                        format!("`{}` is not valid for this target", feature),
+                    );
                     if feature.starts_with("+") {
                         let valid = whitelist.contains_key(&feature[1..]);
                         if valid {
@@ -2571,9 +2578,11 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
             }
         } else if attr.check_name(sym::target_feature) {
             if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
-                let msg = "#[target_feature(..)] can only be applied to \
-                           `unsafe` function";
-                tcx.sess.span_err(attr.span, msg);
+                let msg = "#[target_feature(..)] can only be applied to `unsafe` functions";
+                tcx.sess.struct_span_err(attr.span, msg)
+                    .span_label(attr.span, "can only be applied to `unsafe` functions")
+                    .span_label(tcx.def_span(id), "not an `unsafe` function")
+                    .emit();
             }
             from_target_feature(
                 tcx,
index e7ec5bc81c7695661c1dc046168adfd1773abdec..87476d37b35e7a74fd474394482b208990f57b4e 100644 (file)
@@ -111,7 +111,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         .map(|item_ref| tcx.hir().local_def_id_from_hir_id(item_ref.id.hir_id))
         .filter(|&def_id| {
             let item = tcx.associated_item(def_id);
-            item.kind == ty::AssociatedKind::Type && item.defaultness.has_value()
+            item.kind == ty::AssocKind::Type && item.defaultness.has_value()
         })
         .flat_map(|def_id| {
             cgp::parameters_for(&tcx.type_of(def_id), true)
index e8f6272810a37f9df1168c35d2b82baca74ab2ac..9b6c5bd9f429f40d3580da7883023312d22dd99a 100644 (file)
@@ -8,13 +8,13 @@ pub enum Namespace {
     Value,
 }
 
-impl From<ty::AssociatedKind> for Namespace {
-    fn from(a_kind: ty::AssociatedKind) -> Self {
+impl From<ty::AssocKind> for Namespace {
+    fn from(a_kind: ty::AssocKind) -> Self {
         match a_kind {
-            ty::AssociatedKind::Existential |
-            ty::AssociatedKind::Type => Namespace::Type,
-            ty::AssociatedKind::Const |
-            ty::AssociatedKind::Method => Namespace::Value,
+            ty::AssocKind::Existential |
+            ty::AssocKind::Type => Namespace::Type,
+            ty::AssocKind::Const |
+            ty::AssocKind::Method => Namespace::Value,
         }
     }
 }
index 9c3f522d8470fcbd69fe30dc66d8d840a80b5104..4ee63a4c9703b6c310491d0513193aee21b31ac9 100644 (file)
@@ -428,10 +428,10 @@ pub fn is_variant(&self) -> bool {
         self.type_() == ItemType::Variant
     }
     pub fn is_associated_type(&self) -> bool {
-        self.type_() == ItemType::AssociatedType
+        self.type_() == ItemType::AssocType
     }
     pub fn is_associated_const(&self) -> bool {
-        self.type_() == ItemType::AssociatedConst
+        self.type_() == ItemType::AssocConst
     }
     pub fn is_method(&self) -> bool {
         self.type_() == ItemType::Method
@@ -560,8 +560,8 @@ pub enum ItemEnum {
     MacroItem(Macro),
     ProcMacroItem(ProcMacro),
     PrimitiveItem(PrimitiveType),
-    AssociatedConstItem(Type, Option<String>),
-    AssociatedTypeItem(Vec<GenericBound>, Option<Type>),
+    AssocConstItem(Type, Option<String>),
+    AssocTypeItem(Vec<GenericBound>, Option<Type>),
     /// An item that has been stripped by a rustdoc pass
     StrippedItem(Box<ItemEnum>),
     KeywordItem(String),
@@ -588,7 +588,7 @@ pub fn generics(&self) -> Option<&Generics> {
     pub fn is_associated(&self) -> bool {
         match *self {
             ItemEnum::TypedefItem(_, _) |
-            ItemEnum::AssociatedTypeItem(_, _) => true,
+            ItemEnum::AssocTypeItem(_, _) => true,
             _ => false,
         }
     }
@@ -2206,7 +2206,7 @@ impl Clean<Item> for hir::TraitItem {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         let inner = match self.node {
             hir::TraitItemKind::Const(ref ty, default) => {
-                AssociatedConstItem(ty.clean(cx),
+                AssocConstItem(ty.clean(cx),
                                     default.map(|e| print_const_expr(cx, e)))
             }
             hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
@@ -2226,7 +2226,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
                 })
             }
             hir::TraitItemKind::Type(ref bounds, ref default) => {
-                AssociatedTypeItem(bounds.clean(cx), default.clean(cx))
+                AssocTypeItem(bounds.clean(cx), default.clean(cx))
             }
         };
         let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id);
@@ -2247,7 +2247,7 @@ impl Clean<Item> for hir::ImplItem {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         let inner = match self.node {
             hir::ImplItemKind::Const(ref ty, expr) => {
-                AssociatedConstItem(ty.clean(cx),
+                AssocConstItem(ty.clean(cx),
                                     Some(print_const_expr(cx, expr)))
             }
             hir::ImplItemKind::Method(ref sig, body) => {
@@ -2276,19 +2276,19 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
     }
 }
 
-impl<'tcx> Clean<Item> for ty::AssociatedItem {
+impl<'tcx> Clean<Item> for ty::AssocItem {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         let inner = match self.kind {
-            ty::AssociatedKind::Const => {
+            ty::AssocKind::Const => {
                 let ty = cx.tcx.type_of(self.def_id);
                 let default = if self.defaultness.has_value() {
                     Some(inline::print_inlined_const(cx, self.def_id))
                 } else {
                     None
                 };
-                AssociatedConstItem(ty.clean(cx), default)
+                AssocConstItem(ty.clean(cx), default)
             }
-            ty::AssociatedKind::Method => {
+            ty::AssocKind::Method => {
                 let generics = (cx.tcx.generics_of(self.def_id),
                                 &cx.tcx.explicit_predicates_of(self.def_id)).clean(cx);
                 let sig = cx.tcx.fn_sig(self.def_id);
@@ -2359,7 +2359,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
                     })
                 }
             }
-            ty::AssociatedKind::Type => {
+            ty::AssocKind::Type => {
                 let my_name = self.ident.name.clean(cx);
 
                 if let ty::TraitContainer(did) = self.container {
@@ -2404,7 +2404,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
                         None
                     };
 
-                    AssociatedTypeItem(bounds, ty.clean(cx))
+                    AssocTypeItem(bounds, ty.clean(cx))
                 } else {
                     TypedefItem(Typedef {
                         type_: cx.tcx.type_of(self.def_id).clean(cx),
@@ -2415,7 +2415,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
                     }, true)
                 }
             }
-            ty::AssociatedKind::Existential => unimplemented!(),
+            ty::AssocKind::Existential => unimplemented!(),
         };
 
         let visibility = match self.container {
@@ -2956,7 +2956,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Type {
             ty::Str => Primitive(PrimitiveType::Str),
             ty::Slice(ty) => Slice(box ty.clean(cx)),
             ty::Array(ty, n) => {
-                let mut n = *cx.tcx.lift(&n).expect("array lift failed");
+                let mut n = cx.tcx.lift(&n).expect("array lift failed");
                 if let ConstValue::Unevaluated(def_id, substs) = n.val {
                     let param_env = cx.tcx.param_env(def_id);
                     let cid = GlobalId {
@@ -4126,7 +4126,7 @@ fn name_from_pat(p: &hir::Pat) -> String {
     }
 }
 
-fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
+fn print_const(cx: &DocContext<'_>, n: &ty::Const<'_>) -> String {
     match n.val {
         ConstValue::Unevaluated(def_id, _) => {
             if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(def_id) {
@@ -4136,12 +4136,15 @@ fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
             }
         },
         _ => {
-            let mut s = String::new();
-            ::rustc::mir::fmt_const_val(&mut s, n).expect("fmt_const_val failed");
+            let mut s = n.to_string();
             // array lengths are obviously usize
             if s.ends_with("usize") {
                 let n = s.len() - "usize".len();
                 s.truncate(n);
+                if s.ends_with(": ") {
+                    let n = s.len() - ": ".len();
+                    s.truncate(n);
+                }
             }
             s
         },
@@ -4179,7 +4182,7 @@ fn resolve_type(cx: &DocContext<'_>,
         }
         Res::SelfTy(..)
         | Res::Def(DefKind::TyParam, _)
-        | Res::Def(DefKind::AssociatedTy, _) => true,
+        | Res::Def(DefKind::AssocTy, _) => true,
         _ => false,
     };
     let did = register_res(&*cx, path.res);
index 2784d5b3e10a0bbf85e5c46e9ea56afe54131c06..58e55d570a4f3336df942f258d7ed065fc812454 100644 (file)
@@ -722,7 +722,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
                                    "<a class=\"type\" href=\"{url}#{shortty}.{name}\" \
                                    title=\"type {path}::{name}\">{name}</a>",
                                    url = url,
-                                   shortty = ItemType::AssociatedType,
+                                   shortty = ItemType::AssocType,
                                    name = name,
                                    path = path.join("::"))?;
                         }
index 366e60b3ad9206e89282d7806dfcd69ee3cc7852..3f3f4c85e81fc5035f49d409a179b938cf615d5e 100644 (file)
@@ -33,9 +33,9 @@ pub enum ItemType {
     Variant         = 13,
     Macro           = 14,
     Primitive       = 15,
-    AssociatedType  = 16,
+    AssocType       = 16,
     Constant        = 17,
-    AssociatedConst = 18,
+    AssocConst      = 18,
     Union           = 19,
     ForeignType     = 20,
     Keyword         = 21,
@@ -83,8 +83,8 @@ fn from(item: &'a clean::Item) -> ItemType {
             clean::ForeignStaticItem(..)   => ItemType::Static, // no ForeignStatic
             clean::MacroItem(..)           => ItemType::Macro,
             clean::PrimitiveItem(..)       => ItemType::Primitive,
-            clean::AssociatedConstItem(..) => ItemType::AssociatedConst,
-            clean::AssociatedTypeItem(..)  => ItemType::AssociatedType,
+            clean::AssocConstItem(..)      => ItemType::AssocConst,
+            clean::AssocTypeItem(..)       => ItemType::AssocType,
             clean::ForeignTypeItem         => ItemType::ForeignType,
             clean::KeywordItem(..)         => ItemType::Keyword,
             clean::TraitAliasItem(..)      => ItemType::TraitAlias,
@@ -141,9 +141,9 @@ pub fn css_class(&self) -> &'static str {
             ItemType::Variant         => "variant",
             ItemType::Macro           => "macro",
             ItemType::Primitive       => "primitive",
-            ItemType::AssociatedType  => "associatedtype",
+            ItemType::AssocType       => "associatedtype",
             ItemType::Constant        => "constant",
-            ItemType::AssociatedConst => "associatedconstant",
+            ItemType::AssocConst      => "associatedconstant",
             ItemType::ForeignType     => "foreigntype",
             ItemType::Keyword         => "keyword",
             ItemType::Existential     => "existential",
@@ -162,7 +162,7 @@ pub fn name_space(&self) -> NameSpace {
             ItemType::Typedef |
             ItemType::Trait |
             ItemType::Primitive |
-            ItemType::AssociatedType |
+            ItemType::AssocType |
             ItemType::Existential |
             ItemType::TraitAlias |
             ItemType::ForeignType => NameSpace::Type,
@@ -177,7 +177,7 @@ pub fn name_space(&self) -> NameSpace {
             ItemType::StructField |
             ItemType::Variant |
             ItemType::Constant |
-            ItemType::AssociatedConst => NameSpace::Value,
+            ItemType::AssocConst => NameSpace::Value,
 
             ItemType::Macro |
             ItemType::ProcAttribute |
index b628bd450d314b8a690dea5e0beae786db59a0ef..efb59c22012bcaad76c538ae27480bca5aee74b8 100644 (file)
@@ -1554,12 +1554,12 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
         if let Some(ref s) = item.name {
             let (parent, is_inherent_impl_item) = match item.inner {
                 clean::StrippedItem(..) => ((None, None), false),
-                clean::AssociatedConstItem(..) |
+                clean::AssocConstItem(..) |
                 clean::TypedefItem(_, true) if self.parent_is_trait_impl => {
                     // skip associated items in trait impls
                     ((None, None), false)
                 }
-                clean::AssociatedTypeItem(..) |
+                clean::AssocTypeItem(..) |
                 clean::TyMethodItem(..) |
                 clean::StructFieldItem(..) |
                 clean::VariantItem(..) => {
@@ -1567,7 +1567,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
                       Some(&self.stack[..self.stack.len() - 1])),
                      false)
                 }
-                clean::MethodItem(..) | clean::AssociatedConstItem(..) => {
+                clean::MethodItem(..) | clean::AssocConstItem(..) => {
                     if self.parent_stack.is_empty() {
                         ((None, None), false)
                     } else {
@@ -3366,7 +3366,7 @@ fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>) -> String {
 
     let name = it.name.as_ref().unwrap();
     let ty = match it.type_() {
-        Typedef | AssociatedType => AssociatedType,
+        Typedef | AssocType => AssocType,
         s@_ => s,
     };
 
@@ -3511,11 +3511,11 @@ fn method(w: &mut fmt::Formatter<'_>,
         clean::MethodItem(ref m) => {
             method(w, item, m.header, &m.generics, &m.decl, link, parent)
         }
-        clean::AssociatedConstItem(ref ty, ref default) => {
+        clean::AssocConstItem(ref ty, ref default) => {
             assoc_const(w, item, ty, default.as_ref(), link,
                         if parent == ItemType::Trait { "    " } else { "" })
         }
-        clean::AssociatedTypeItem(ref bounds, ref default) => {
+        clean::AssocTypeItem(ref bounds, ref default) => {
             assoc_type(w, item, bounds, default.as_ref(), link,
                        if parent == ItemType::Trait { "    " } else { "" })
         }
@@ -4247,14 +4247,14 @@ fn doc_impl_item(w: &mut fmt::Formatter<'_>, cx: &Context, item: &clean::Item,
                 }
             }
             clean::TypedefItem(ref tydef, _) => {
-                let id = cx.derive_id(format!("{}.{}", ItemType::AssociatedType, name));
+                let id = cx.derive_id(format!("{}.{}", ItemType::AssocType, name));
                 let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
                 write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class)?;
                 write!(w, "<code id='{}'>", ns_id)?;
                 assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id), "")?;
                 write!(w, "</code></h4>")?;
             }
-            clean::AssociatedConstItem(ref ty, ref default) => {
+            clean::AssocConstItem(ref ty, ref default) => {
                 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)?;
@@ -4268,7 +4268,7 @@ fn doc_impl_item(w: &mut fmt::Formatter<'_>, cx: &Context, item: &clean::Item,
                 }
                 write!(w, "</h4>")?;
             }
-            clean::AssociatedTypeItem(ref bounds, ref default) => {
+            clean::AssocTypeItem(ref bounds, ref default) => {
                 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)?;
@@ -4946,8 +4946,8 @@ fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) {
         ItemType::Variant         => ("variants", "Variants"),
         ItemType::Macro           => ("macros", "Macros"),
         ItemType::Primitive       => ("primitives", "Primitive Types"),
-        ItemType::AssociatedType  => ("associated-types", "Associated Types"),
-        ItemType::AssociatedConst => ("associated-consts", "Associated Constants"),
+        ItemType::AssocType       => ("associated-types", "Associated Types"),
+        ItemType::AssocConst      => ("associated-consts", "Associated Constants"),
         ItemType::ForeignType     => ("foreign-types", "Foreign Types"),
         ItemType::Keyword         => ("keywords", "Keywords"),
         ItemType::Existential     => ("existentials", "Existentials"),
@@ -4974,7 +4974,7 @@ fn sidebar_module(fmt: &mut fmt::Formatter<'_>, _it: &clean::Item,
                    ItemType::Enum, ItemType::Constant, ItemType::Static, ItemType::Trait,
                    ItemType::Function, ItemType::Typedef, ItemType::Union, ItemType::Impl,
                    ItemType::TyMethod, ItemType::Method, ItemType::StructField, ItemType::Variant,
-                   ItemType::AssociatedType, ItemType::AssociatedConst, ItemType::ForeignType] {
+                   ItemType::AssocType, ItemType::AssocConst, ItemType::ForeignType] {
         if items.iter().any(|it| !it.is_stripped() && it.type_() == myty) {
             let (short, name) = item_ty_to_strs(&myty);
             sidebar.push_str(&format!("<li><a href=\"#{id}\">{name}</a></li>",
index 2c382a1c1759632806bb316f621aa582564b9fe0..860ea18a58ad0f8b78aa2bd038d5d6815f4a9e80 100644 (file)
@@ -75,8 +75,8 @@ fn resolve(&self,
                 // In case this is a trait item, skip the
                 // early return and try looking for the trait.
                 let value = match result.res {
-                    Res::Def(DefKind::Method, _) | Res::Def(DefKind::AssociatedConst, _) => true,
-                    Res::Def(DefKind::AssociatedTy, _) => false,
+                    Res::Def(DefKind::Method, _) | Res::Def(DefKind::AssocConst, _) => true,
+                    Res::Def(DefKind::AssocTy, _) => false,
                     Res::Def(DefKind::Variant, _) => return handle_variant(cx, result.res),
                     // Not a trait item; just return what we found.
                     _ => return Ok((result.res, None))
@@ -120,7 +120,7 @@ fn resolve(&self,
                 return cx.tcx.associated_items(did)
                     .find(|item| item.ident.name == item_name)
                     .and_then(|item| match item.kind {
-                        ty::AssociatedKind::Method => Some("method"),
+                        ty::AssocKind::Method => Some("method"),
                         _ => None,
                     })
                     .map(|out| (prim, Some(format!("{}#{}.{}", path, out, item_name))))
@@ -143,8 +143,8 @@ fn resolve(&self,
                                      .find(|item| item.ident.name == item_name);
                     if let Some(item) = item {
                         let out = match item.kind {
-                            ty::AssociatedKind::Method if ns == ValueNS => "method",
-                            ty::AssociatedKind::Const if ns == ValueNS => "associatedconstant",
+                            ty::AssocKind::Method if ns == ValueNS => "method",
+                            ty::AssocKind::Const if ns == ValueNS => "associatedconstant",
                             _ => return Err(())
                         };
                         Ok((ty.res, Some(format!("{}.{}", out, item_name))))
@@ -181,9 +181,9 @@ fn resolve(&self,
                                  .find(|item| item.ident.name == item_name);
                     if let Some(item) = item {
                         let kind = match item.kind {
-                            ty::AssociatedKind::Const if ns == ValueNS => "associatedconstant",
-                            ty::AssociatedKind::Type if ns == TypeNS => "associatedtype",
-                            ty::AssociatedKind::Method if ns == ValueNS => {
+                            ty::AssocKind::Const if ns == ValueNS => "associatedconstant",
+                            ty::AssocKind::Type if ns == TypeNS => "associatedtype",
+                            ty::AssocKind::Method if ns == ValueNS => {
                                 if item.defaultness.has_value() {
                                     "method"
                                 } else {
index d9af33ac5b622a39f288c14b3eca760c02900245..018ab5dea6081f54a9dc431ff508f65d36fbd1fa 100644 (file)
@@ -172,7 +172,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
             | clean::ForeignStaticItem(..)
             | clean::ConstantItem(..)
             | clean::UnionItem(..)
-            | clean::AssociatedConstItem(..)
+            | clean::AssocConstItem(..)
             | clean::TraitAliasItem(..)
             | clean::ForeignTypeItem => {
                 if i.def_id.is_local() {
@@ -214,7 +214,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
             clean::PrimitiveItem(..) => {}
 
             // Associated types are never stripped
-            clean::AssociatedTypeItem(..) => {}
+            clean::AssocTypeItem(..) => {}
 
             // Keywords are never stripped
             clean::KeywordItem(..) => {}
index c4c1170e539ae6c213f5a52a9a6f13971f4c3f04..d22dc9a71a40f110682bb3da5dc00b93a741f72d 100644 (file)
@@ -23,8 +23,18 @@ compiler_builtins = { version = "0.1.15" }
 profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
 hashbrown = { version = "0.3.0", features = ['rustc-dep-of-std'] }
-rustc-demangle = { version = "0.1.10", features = ['rustc-dep-of-std'] }
-backtrace-sys = { version = "0.1.24", features = ["rustc-dep-of-std"], optional = true }
+
+[dependencies.backtrace]
+version = "0.3.25"
+default-features = false # don't use coresymbolication on OSX
+features = [
+  "rustc-dep-of-std", # enable build support for integrating into libstd
+  "dbghelp",          # backtrace/symbolize on MSVC
+  "libbacktrace",     # symbolize on most platforms
+  "libunwind",        # backtrace on most platforms
+  "dladdr",           # symbolize on platforms w/o libbacktrace
+]
+optional = true
 
 [dev-dependencies]
 rand = "0.6.1"
@@ -51,7 +61,6 @@ cc = "1.0"
 [features]
 default = ["std_detect_file_io", "std_detect_dlsym_getauxval"]
 
-backtrace = ["backtrace-sys"]
 panic-unwind = ["panic_unwind"]
 profiler = ["profiler_builtins"]
 compiler-builtins-c = ["alloc/compiler-builtins-c"]
index 9058ea93d6de077d2717173df417931ac68c364e..00e840a53e9c0e05f9f2f12b58d450c5134ed62a 100644 (file)
@@ -465,7 +465,7 @@ pub struct JoinPathsError {
 /// # }
 /// ```
 ///
-/// Using `env::join_paths` with `env::spit_paths` to append an item to the `PATH` environment
+/// Using `env::join_paths` with [`env::split_paths`] to append an item to the `PATH` environment
 /// variable:
 ///
 /// ```
@@ -483,6 +483,8 @@ pub struct JoinPathsError {
 ///     Ok(())
 /// }
 /// ```
+///
+/// [`env::split_paths`]: fn.split_paths.html
 #[stable(feature = "env", since = "1.0.0")]
 pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
     where I: IntoIterator<Item=T>, T: AsRef<OsStr>
diff --git a/src/libstd/sys/cloudabi/backtrace.rs b/src/libstd/sys/cloudabi/backtrace.rs
deleted file mode 100644 (file)
index 17719a2..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-use crate::error::Error;
-use crate::ffi::CStr;
-use crate::fmt;
-use crate::intrinsics;
-use crate::io;
-use crate::sys_common::backtrace::Frame;
-
-use unwind as uw;
-
-pub struct BacktraceContext;
-
-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)] // if we know this is a function call, we can skip 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.
-    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),
-        )),
-    }
-}
-
-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 foreach_symbol_fileline<F>(_: Frame, _: F, _: &BacktraceContext) -> io::Result<bool>
-where
-    F: FnMut(&[u8], u32) -> io::Result<()>,
-{
-    // No way to obtain this information on CloudABI.
-    Ok(false)
-}
-
-pub fn resolve_symname<F>(frame: Frame, callback: F, _: &BacktraceContext) -> io::Result<()>
-where
-    F: FnOnce(Option<&str>) -> io::Result<()>,
-{
-    unsafe {
-        let mut info: Dl_info = intrinsics::init();
-        let symname =
-            if dladdr(frame.exact_position as *mut _, &mut info) == 0 || info.dli_sname.is_null() {
-                None
-            } else {
-                CStr::from_ptr(info.dli_sname).to_str().ok()
-            };
-        callback(symname)
-    }
-}
-
-#[repr(C)]
-struct Dl_info {
-    dli_fname: *const libc::c_char,
-    dli_fbase: *mut libc::c_void,
-    dli_sname: *const libc::c_char,
-    dli_saddr: *mut libc::c_void,
-}
-
-extern "C" {
-    fn dladdr(addr: *const libc::c_void, info: *mut Dl_info) -> libc::c_int;
-}
index 3f8e67a7af85ee7408029d70d9ca36a1c3c8bb58..c3b8bbd042606e17e1581d236a7fdb0975aebe21 100644 (file)
@@ -4,8 +4,6 @@
 #[path = "../unix/alloc.rs"]
 pub mod alloc;
 pub mod args;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
 #[path = "../unix/cmath.rs"]
 pub mod cmath;
 pub mod condvar;
diff --git a/src/libstd/sys/redox/backtrace/mod.rs b/src/libstd/sys/redox/backtrace/mod.rs
deleted file mode 100644 (file)
index 8ea2783..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/// See sys/unix/backtrace/mod.rs for an explanation of the method used here.
-
-pub use self::tracing::unwind_backtrace;
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-
-// tracing impls:
-mod tracing;
-// symbol resolvers:
-mod printing;
-
-pub mod gnu {
-    use crate::io;
-    use crate::fs;
-    use crate::vec::Vec;
-    use crate::ffi::OsStr;
-    use crate::os::unix::ffi::OsStrExt;
-    use crate::io::Read;
-    use libc::c_char;
-
-    pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
-        let mut exefile = fs::File::open("sys:exe")?;
-        let mut exename = Vec::new();
-        exefile.read_to_end(&mut exename)?;
-        if exename.last() == Some(&b'\n') {
-            exename.pop();
-        }
-        let file = fs::File::open(OsStr::from_bytes(&exename))?;
-        Ok((exename.into_iter().map(|c| c as c_char).collect(), file))
-    }
-}
-
-pub struct BacktraceContext;
diff --git a/src/libstd/sys/redox/backtrace/printing.rs b/src/libstd/sys/redox/backtrace/printing.rs
deleted file mode 100644 (file)
index 489eed4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-pub use crate::sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname};
diff --git a/src/libstd/sys/redox/backtrace/tracing.rs b/src/libstd/sys/redox/backtrace/tracing.rs
deleted file mode 100644 (file)
index 13f3433..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-use crate::error::Error;
-use crate::fmt;
-use crate::io;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-
-use unwind as uw;
-
-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)] // if we know this is a function call, we can skip it when
-                 // tracing
-pub fn unwind_backtrace(frames: &mut [Frame])
-    -> io::Result<(usize, BacktraceContext)>
-{
-    let mut cx = Context {
-        idx: 0,
-        frames: 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.
-    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)))
-        }
-    }
-}
-
-extern 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 _;
-    }
-
-    // dladdr() on osx gets whiny when we use FindEnclosingFunction, and
-    // it appears to work fine without it, so we only use
-    // FindEnclosingFunction on non-osx platforms. In doing so, we get a
-    // slightly more accurate stack trace in the process.
-    //
-    // This is often because panic involves the last instruction of a
-    // function being "call std::rt::begin_unwind", with no ret
-    // instructions after it. This means that the return instruction
-    // pointer points *outside* of the calling function, and by
-    // unwinding it we go back to the original function.
-    let symaddr = if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
-        ip
-    } else {
-        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
-}
index 0e8ed8e303d43a046d8ca236dce365a44c0111cf..354184f8af6e71dda54c0b3e9e6a19425ccc89c0 100644 (file)
@@ -8,8 +8,6 @@
 #[path = "../unix/alloc.rs"]
 pub mod alloc;
 pub mod args;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
 pub mod cmath;
 pub mod condvar;
 pub mod env;
diff --git a/src/libstd/sys/sgx/backtrace.rs b/src/libstd/sys/sgx/backtrace.rs
deleted file mode 100644 (file)
index 326737a..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-use crate::io;
-use crate::error::Error;
-use crate::fmt;
-use crate::sys_common::backtrace::Frame;
-use crate::sys::sgx::abi::mem::image_base;
-
-use unwind as uw;
-
-pub struct BacktraceContext;
-
-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
-}
-
-// 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<()>
-{
-    callback(Some(&format!("0x{:x}",
-            (frame.symbol_addr.wrapping_offset_from(image_base() as _)))))
-}
-
-pub fn foreach_symbol_fileline<F>(_: Frame,
-                                  _: F,
-                                  _: &BacktraceContext) -> io::Result<bool>
-    where F: FnMut(&[u8], u32) -> io::Result<()>
-{
-    Ok(false)
-}
index a99a534f41e3ce69e073fa16024b0426a7252406..01f5536ed7a6594a614d77c0896fbab98aa1883a 100644 (file)
@@ -12,8 +12,6 @@
 
 pub mod alloc;
 pub mod args;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
 pub mod cmath;
 pub mod condvar;
 pub mod env;
diff --git a/src/libstd/sys/unix/backtrace/mod.rs b/src/libstd/sys/unix/backtrace/mod.rs
deleted file mode 100644 (file)
index 0887e5a..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/// Backtrace support built on libgcc with some extra OS-specific support
-///
-/// Some methods of getting a backtrace:
-///
-/// * The backtrace() functions on unix. It turns out this doesn't work very
-///   well for green threads on macOS, and the address to symbol portion of it
-///   suffers problems that are described below.
-///
-/// * Using libunwind. This is more difficult than it sounds because libunwind
-///   isn't installed everywhere by default. It's also a bit of a hefty library,
-///   so possibly not the best option. When testing, libunwind was excellent at
-///   getting both accurate backtraces and accurate symbols across platforms.
-///   This route was not chosen in favor of the next option, however.
-///
-/// * We're already using libgcc_s for exceptions in rust (triggering thread
-///   unwinding and running destructors on the stack), and it turns out that it
-///   conveniently comes with a function that also gives us a backtrace. All of
-///   these functions look like _Unwind_*, but it's not quite the full
-///   repertoire of the libunwind API. Due to it already being in use, this was
-///   the chosen route of getting a backtrace.
-///
-/// After choosing libgcc_s for backtraces, the sad part is that it will only
-/// give us a stack trace of instruction pointers. Thankfully these instruction
-/// pointers are accurate (they work for green and native threads), but it's
-/// then up to us again to figure out how to translate these addresses to
-/// symbols. As with before, we have a few options. Before, that, a little bit
-/// of an interlude about symbols. This is my very limited knowledge about
-/// symbol tables, and this information is likely slightly wrong, but the
-/// general idea should be correct.
-///
-/// When talking about symbols, it's helpful to know a few things about where
-/// symbols are located. Some symbols are located in the dynamic symbol table
-/// of the executable which in theory means that they're available for dynamic
-/// linking and lookup. Other symbols end up only in the local symbol table of
-/// the file. This loosely corresponds to pub and priv functions in Rust.
-///
-/// Armed with this knowledge, we know that our solution for address to symbol
-/// translation will need to consult both the local and dynamic symbol tables.
-/// With that in mind, here's our options of translating an address to
-/// a symbol.
-///
-/// * Use dladdr(). The original backtrace()-based idea actually uses dladdr()
-///   behind the scenes to translate, and this is why backtrace() was not used.
-///   Conveniently, this method works fantastically on macOS. It appears dladdr()
-///   uses magic to consult the local symbol table, or we're putting everything
-///   in the dynamic symbol table anyway. Regardless, for macOS, this is the
-///   method used for translation. It's provided by the system and easy to do.o
-///
-///   Sadly, all other systems have a dladdr() implementation that does not
-///   consult the local symbol table. This means that most functions are blank
-///   because they don't have symbols. This means that we need another solution.
-///
-/// * Use unw_get_proc_name(). This is part of the libunwind api (not the
-///   libgcc_s version of the libunwind api), but involves taking a dependency
-///   to libunwind. We may pursue this route in the future if we bundle
-///   libunwind, but libunwind was unwieldy enough that it was not chosen at
-///   this time to provide this functionality.
-///
-/// * Shell out to a utility like `readelf`. Crazy though it may sound, it's a
-///   semi-reasonable solution. The stdlib already knows how to spawn processes,
-///   so in theory it could invoke readelf, parse the output, and consult the
-///   local/dynamic symbol tables from there. This ended up not getting chosen
-///   due to the craziness of the idea plus the advent of the next option.
-///
-/// * Use `libbacktrace`. It turns out that this is a small library bundled in
-///   the gcc repository which provides backtrace and symbol translation
-///   functionality. All we really need from it is the backtrace functionality,
-///   and we only really need this on everything that's not macOS, so this is the
-///   chosen route for now.
-///
-/// In summary, the current situation uses libgcc_s to get a trace of stack
-/// pointers, and we use dladdr() or libbacktrace to translate these addresses
-/// to symbols. This is a bit of a hokey implementation as-is, but it works for
-/// all unix platforms we support right now, so it at least gets the job done.
-
-pub use self::tracing::unwind_backtrace;
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-
-// tracing impls:
-mod tracing;
-// symbol resolvers:
-mod printing;
-
-#[cfg(not(target_os = "emscripten"))]
-pub mod gnu {
-    use crate::io;
-    use crate::fs;
-
-    use libc::c_char;
-
-    #[cfg(not(any(target_os = "macos", target_os = "ios")))]
-    pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
-        Err(io::Error::new(io::ErrorKind::Other, "Not implemented"))
-    }
-
-    #[cfg(any(target_os = "macos", target_os = "ios"))]
-    pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
-        use crate::env;
-        use crate::os::unix::ffi::OsStrExt;
-
-        let filename = env::current_exe()?;
-        let file = fs::File::open(&filename)?;
-        let mut filename_cstr: Vec<_> = filename.as_os_str().as_bytes().iter()
-            .map(|&x| x as c_char).collect();
-        filename_cstr.push(0); // Null terminate
-        Ok((filename_cstr, file))
-    }
-}
-
-pub struct BacktraceContext;
diff --git a/src/libstd/sys/unix/backtrace/printing/dladdr.rs b/src/libstd/sys/unix/backtrace/printing/dladdr.rs
deleted file mode 100644 (file)
index cf3bda6..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-use crate::io;
-use crate::intrinsics;
-use crate::ffi::CStr;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-
-pub fn resolve_symname<F>(frame: Frame,
-                          callback: F,
-                          _: &BacktraceContext) -> io::Result<()>
-    where F: FnOnce(Option<&str>) -> io::Result<()>
-{
-    unsafe {
-        let mut info: Dl_info = intrinsics::init();
-        let symname = if dladdr(frame.exact_position as *mut _, &mut info) == 0 ||
-                         info.dli_sname.is_null() {
-            None
-        } else {
-            CStr::from_ptr(info.dli_sname).to_str().ok()
-        };
-        callback(symname)
-    }
-}
-
-#[repr(C)]
-struct Dl_info {
-    dli_fname: *const libc::c_char,
-    dli_fbase: *mut libc::c_void,
-    dli_sname: *const libc::c_char,
-    dli_saddr: *mut libc::c_void,
-}
-
-extern {
-    fn dladdr(addr: *const libc::c_void, info: *mut Dl_info) -> libc::c_int;
-}
diff --git a/src/libstd/sys/unix/backtrace/printing/mod.rs b/src/libstd/sys/unix/backtrace/printing/mod.rs
deleted file mode 100644 (file)
index d090cae..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-mod dladdr;
-
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-use crate::io;
-
-#[cfg(target_os = "emscripten")]
-pub use self::dladdr::resolve_symname;
-
-#[cfg(target_os = "emscripten")]
-pub fn foreach_symbol_fileline<F>(_: Frame, _: F, _: &BacktraceContext) -> io::Result<bool>
-where
-    F: FnMut(&[u8], u32) -> io::Result<()>
-{
-    Ok(false)
-}
-
-#[cfg(not(target_os = "emscripten"))]
-pub use crate::sys_common::gnu::libbacktrace::foreach_symbol_fileline;
-
-#[cfg(not(target_os = "emscripten"))]
-pub fn resolve_symname<F>(frame: Frame, callback: F, bc: &BacktraceContext) -> io::Result<()>
-where
-    F: FnOnce(Option<&str>) -> io::Result<()>
-{
-    crate::sys_common::gnu::libbacktrace::resolve_symname(frame, |symname| {
-        if symname.is_some() {
-            callback(symname)
-        } else {
-            dladdr::resolve_symname(frame, callback, bc)
-        }
-    }, bc)
-}
diff --git a/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs b/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
deleted file mode 100644 (file)
index a628d10..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/// As always - iOS on arm uses SjLj exceptions and
-/// _Unwind_Backtrace is even not available there. Still,
-/// backtraces could be extracted using a backtrace function,
-/// which thanks god is public
-///
-/// As mentioned in a huge comment block in `super::super`, backtrace
-/// doesn't play well with green threads, so while it is extremely nice and
-/// simple to use it should be used only on iOS devices as the only viable
-/// option.
-
-use crate::io;
-use crate::ptr;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-
-#[inline(never)] // if we know this is a function call, we can skip it when
-                 // tracing
-pub fn unwind_backtrace(frames: &mut [Frame])
-    -> io::Result<(usize, BacktraceContext)>
-{
-    const FRAME_LEN: usize = 100;
-    assert!(FRAME_LEN >= frames.len());
-    let mut raw_frames = [ptr::null_mut(); FRAME_LEN];
-    let nb_frames = unsafe {
-        backtrace(raw_frames.as_mut_ptr(), raw_frames.len() as libc::c_int)
-    } as usize;
-    for (from, to) in raw_frames.iter().zip(frames.iter_mut()).take(nb_frames) {
-        *to = Frame {
-            exact_position: *from as *mut u8,
-            symbol_addr: *from as *mut u8,
-            inline_context: 0,
-        };
-    }
-    Ok((nb_frames as usize, BacktraceContext))
-}
-
-extern {
-    fn backtrace(buf: *mut *mut libc::c_void, sz: libc::c_int) -> libc::c_int;
-}
diff --git a/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs b/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs
deleted file mode 100644 (file)
index e637913..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-use crate::error::Error;
-use crate::fmt;
-use crate::io;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-
-use unwind as uw;
-
-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)] // if we know this is a function call, we can skip 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.
-    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)))
-        }
-    }
-}
-
-extern 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 _;
-    }
-
-    // dladdr() on osx gets whiny when we use FindEnclosingFunction, and
-    // it appears to work fine without it, so we only use
-    // FindEnclosingFunction on non-osx platforms. In doing so, we get a
-    // slightly more accurate stack trace in the process.
-    //
-    // This is often because panic involves the last instruction of a
-    // function being "call std::rt::begin_unwind", with no ret
-    // instructions after it. This means that the return instruction
-    // pointer points *outside* of the calling function, and by
-    // unwinding it we go back to the original function.
-    let symaddr = if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
-        ip
-    } else {
-        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
-}
diff --git a/src/libstd/sys/unix/backtrace/tracing/mod.rs b/src/libstd/sys/unix/backtrace/tracing/mod.rs
deleted file mode 100644 (file)
index 11863e6..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-pub use self::imp::*;
-
-#[cfg(not(all(target_os = "ios", target_arch = "arm")))]
-#[path = "gcc_s.rs"]
-mod imp;
-#[cfg(all(target_os = "ios", target_arch = "arm"))]
-#[path = "backtrace_fn.rs"]
-mod imp;
index c2b264ff8de1154788c3cbce34ff466732ba0c30..821623db2721e54216103b4d6532b4f1be37fbe2 100644 (file)
@@ -27,8 +27,6 @@
 pub mod alloc;
 pub mod args;
 pub mod android;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
 pub mod cmath;
 pub mod condvar;
 pub mod env;
diff --git a/src/libstd/sys/wasi/backtrace.rs b/src/libstd/sys/wasi/backtrace.rs
deleted file mode 100644 (file)
index 7d56b29..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-use crate::io;
-use crate::sys::unsupported;
-use crate::sys_common::backtrace::Frame;
-
-pub struct BacktraceContext;
-
-pub fn unwind_backtrace(_frames: &mut [Frame])
-    -> io::Result<(usize, BacktraceContext)>
-{
-    unsupported()
-}
-
-pub fn resolve_symname<F>(_frame: Frame,
-                          _callback: F,
-                          _: &BacktraceContext) -> io::Result<()>
-    where F: FnOnce(Option<&str>) -> io::Result<()>
-{
-    unsupported()
-}
-
-pub fn foreach_symbol_fileline<F>(_: Frame,
-                                  _: F,
-                                  _: &BacktraceContext) -> io::Result<bool>
-    where F: FnMut(&[u8], u32) -> io::Result<()>
-{
-    unsupported()
-}
index a9bb0151d0556544d997a23451bd11a9edf56221..e22434439f5bba61cf96266afd29e8eafeb57633 100644 (file)
@@ -21,8 +21,6 @@
 
 pub mod alloc;
 pub mod args;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
 #[path = "../wasm/cmath.rs"]
 pub mod cmath;
 #[path = "../wasm/condvar.rs"]
diff --git a/src/libstd/sys/wasm/backtrace.rs b/src/libstd/sys/wasm/backtrace.rs
deleted file mode 100644 (file)
index 7d56b29..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-use crate::io;
-use crate::sys::unsupported;
-use crate::sys_common::backtrace::Frame;
-
-pub struct BacktraceContext;
-
-pub fn unwind_backtrace(_frames: &mut [Frame])
-    -> io::Result<(usize, BacktraceContext)>
-{
-    unsupported()
-}
-
-pub fn resolve_symname<F>(_frame: Frame,
-                          _callback: F,
-                          _: &BacktraceContext) -> io::Result<()>
-    where F: FnOnce(Option<&str>) -> io::Result<()>
-{
-    unsupported()
-}
-
-pub fn foreach_symbol_fileline<F>(_: Frame,
-                                  _: F,
-                                  _: &BacktraceContext) -> io::Result<bool>
-    where F: FnMut(&[u8], u32) -> io::Result<()>
-{
-    unsupported()
-}
index 670d07de1d1e0b0ebe5499a882e9ac3597692d76..9ea8bd1653851326d8512c3b98ef6c9d8c884391 100644 (file)
@@ -23,8 +23,6 @@
 
 pub mod alloc;
 pub mod args;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
 pub mod cmath;
 pub mod env;
 pub mod fs;
diff --git a/src/libstd/sys/windows/backtrace/backtrace_gnu.rs b/src/libstd/sys/windows/backtrace/backtrace_gnu.rs
deleted file mode 100644 (file)
index 7ac1f81..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-use crate::io;
-use crate::sys::c;
-use crate::path::PathBuf;
-use crate::fs::{OpenOptions, File};
-use crate::sys::ext::fs::OpenOptionsExt;
-use crate::sys::handle::Handle;
-
-use libc::c_char;
-use super::super::{fill_utf16_buf, os2path, to_u16s, wide_char_to_multi_byte};
-
-fn query_full_process_image_name() -> io::Result<PathBuf> {
-    unsafe {
-        let process_handle = Handle::new(c::OpenProcess(c::PROCESS_QUERY_INFORMATION,
-                                                        c::FALSE,
-                                                        c::GetCurrentProcessId()));
-        fill_utf16_buf(|buf, mut sz| {
-            if c::QueryFullProcessImageNameW(process_handle.raw(), 0, buf, &mut sz) == 0 {
-                0
-            } else {
-                sz
-            }
-        }, os2path)
-    }
-}
-
-fn lock_and_get_executable_filename() -> io::Result<(PathBuf, File)> {
-    // We query the current image name, open the file without FILE_SHARE_DELETE so it
-    // can't be moved and then get the current image name again. If the names are the
-    // same than we have successfully locked the file
-    let image_name1 = query_full_process_image_name()?;
-    let file = OpenOptions::new()
-                .read(true)
-                .share_mode(c::FILE_SHARE_READ | c::FILE_SHARE_WRITE)
-                .open(&image_name1)?;
-    let image_name2 = query_full_process_image_name()?;
-
-    if image_name1 != image_name2 {
-        return Err(io::Error::new(io::ErrorKind::Other,
-                                  "executable moved while trying to lock it"));
-    }
-
-    Ok((image_name1, file))
-}
-
-// Get the executable filename for libbacktrace
-// This returns the path in the ANSI code page and a File which should remain open
-// for as long as the path should remain valid
-pub fn get_executable_filename() -> io::Result<(Vec<c_char>, File)> {
-    let (executable, file) = lock_and_get_executable_filename()?;
-    let u16_executable = to_u16s(executable.into_os_string())?;
-    Ok((wide_char_to_multi_byte(c::CP_ACP, c::WC_NO_BEST_FIT_CHARS,
-                                &u16_executable, true)?, file))
-}
diff --git a/src/libstd/sys/windows/backtrace/mod.rs b/src/libstd/sys/windows/backtrace/mod.rs
deleted file mode 100644 (file)
index c5b0cc8..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-//! As always, windows has something very different than unix, we mainly want
-//! to avoid having to depend too much on libunwind for windows.
-//!
-//! If you google around, you'll find a fair bit of references to built-in
-//! functions to get backtraces on windows. It turns out that most of these are
-//! in an external library called dbghelp. I was unable to find this library
-//! via `-ldbghelp`, but it is apparently normal to do the `dlopen` equivalent
-//! of it.
-//!
-//! You'll also find that there's a function called CaptureStackBackTrace
-//! mentioned frequently (which is also easy to use), but sadly I didn't have a
-//! copy of that function in my mingw install (maybe it was broken?). Instead,
-//! this takes the route of using StackWalk64 in order to walk the stack.
-
-#![allow(deprecated)] // dynamic_lib
-
-use crate::io;
-use crate::mem;
-use crate::ptr;
-use crate::sys::c;
-use crate::sys::dynamic_lib::DynamicLibrary;
-use crate::sys_common::backtrace::Frame;
-
-use libc::c_void;
-
-macro_rules! sym {
-    ($lib:expr, $e:expr, $t:ident) => (
-        $lib.symbol($e).map(|f| unsafe {
-            $crate::mem::transmute::<usize, $t>(f)
-        })
-    )
-}
-
-mod printing;
-
-#[cfg(target_env = "gnu")]
-#[path = "backtrace_gnu.rs"]
-pub mod gnu;
-
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-use self::printing::{load_printing_fns_64, load_printing_fns_ex};
-
-pub fn unwind_backtrace(frames: &mut [Frame]) -> io::Result<(usize, BacktraceContext)> {
-    let dbghelp = DynamicLibrary::open("dbghelp.dll")?;
-
-    // Fetch the symbols necessary from dbghelp.dll
-    let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn)?;
-    let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn)?;
-
-    // StackWalkEx might not be present and we'll fall back to StackWalk64
-    let sw_var = match sym!(dbghelp, "StackWalkEx", StackWalkExFn) {
-        Ok(StackWalkEx) => {
-            StackWalkVariant::StackWalkEx(StackWalkEx, load_printing_fns_ex(&dbghelp)?)
-        }
-        Err(e) => match sym!(dbghelp, "StackWalk64", StackWalk64Fn) {
-            Ok(StackWalk64) => {
-                StackWalkVariant::StackWalk64(StackWalk64, load_printing_fns_64(&dbghelp)?)
-            }
-            Err(..) => return Err(e),
-        },
-    };
-
-    // Allocate necessary structures for doing the stack walk
-    let process = unsafe { c::GetCurrentProcess() };
-
-    let backtrace_context = BacktraceContext {
-        handle: process,
-        SymCleanup,
-        StackWalkVariant: sw_var,
-        dbghelp,
-    };
-
-    // Initialize this process's symbols
-    let ret = unsafe { SymInitialize(process, ptr::null_mut(), c::TRUE) };
-    if ret != c::TRUE {
-        return Ok((0, backtrace_context));
-    }
-
-    // And now that we're done with all the setup, do the stack walking!
-    match backtrace_context.StackWalkVariant {
-        StackWalkVariant::StackWalkEx(StackWalkEx, _) => {
-            set_frames(StackWalkEx, frames).map(|i| (i, backtrace_context))
-        }
-
-        StackWalkVariant::StackWalk64(StackWalk64, _) => {
-            set_frames(StackWalk64, frames).map(|i| (i, backtrace_context))
-        }
-    }
-}
-
-fn set_frames<W: StackWalker>(StackWalk: W, frames: &mut [Frame]) -> io::Result<usize> {
-    let process = unsafe { c::GetCurrentProcess() };
-    let thread = unsafe { c::GetCurrentProcess() };
-    let mut context: c::CONTEXT = unsafe { mem::zeroed() };
-    unsafe { c::RtlCaptureContext(&mut context) };
-    let mut frame = W::Item::new();
-    let image = frame.init(&context);
-
-    let mut i = 0;
-    while i < frames.len()
-        && StackWalk.walk(image, process, thread, &mut frame, &mut context) == c::TRUE
-    {
-        let addr = frame.get_addr();
-        frames[i] = Frame {
-            symbol_addr: addr,
-            exact_position: addr,
-            inline_context: frame.get_inline_context(),
-        };
-
-        i += 1
-    }
-    Ok(i)
-}
-
-type SymInitializeFn = unsafe extern "system" fn(c::HANDLE, *mut c_void, c::BOOL) -> c::BOOL;
-type SymCleanupFn = unsafe extern "system" fn(c::HANDLE) -> c::BOOL;
-
-type StackWalkExFn = unsafe extern "system" fn(
-    c::DWORD,
-    c::HANDLE,
-    c::HANDLE,
-    *mut c::STACKFRAME_EX,
-    *mut c::CONTEXT,
-    *mut c_void,
-    *mut c_void,
-    *mut c_void,
-    *mut c_void,
-    c::DWORD,
-) -> c::BOOL;
-
-type StackWalk64Fn = unsafe extern "system" fn(
-    c::DWORD,
-    c::HANDLE,
-    c::HANDLE,
-    *mut c::STACKFRAME64,
-    *mut c::CONTEXT,
-    *mut c_void,
-    *mut c_void,
-    *mut c_void,
-    *mut c_void,
-) -> c::BOOL;
-
-trait StackWalker {
-    type Item: StackFrame;
-
-    fn walk(
-        &self,
-        _: c::DWORD,
-        _: c::HANDLE,
-        _: c::HANDLE,
-        _: &mut Self::Item,
-        _: &mut c::CONTEXT
-    ) -> c::BOOL;
-}
-
-impl StackWalker for StackWalkExFn {
-    type Item = c::STACKFRAME_EX;
-    fn walk(
-        &self,
-        image: c::DWORD,
-        process: c::HANDLE,
-        thread: c::HANDLE,
-        frame: &mut Self::Item,
-        context: &mut c::CONTEXT,
-    ) -> c::BOOL {
-        unsafe {
-            self(
-                image,
-                process,
-                thread,
-                frame,
-                context,
-                ptr::null_mut(),
-                ptr::null_mut(),
-                ptr::null_mut(),
-                ptr::null_mut(),
-                0,
-            )
-        }
-    }
-}
-
-impl StackWalker for StackWalk64Fn {
-    type Item = c::STACKFRAME64;
-    fn walk(
-        &self,
-        image: c::DWORD,
-        process: c::HANDLE,
-        thread: c::HANDLE,
-        frame: &mut Self::Item,
-        context: &mut c::CONTEXT,
-    ) -> c::BOOL {
-        unsafe {
-            self(
-                image,
-                process,
-                thread,
-                frame,
-                context,
-                ptr::null_mut(),
-                ptr::null_mut(),
-                ptr::null_mut(),
-                ptr::null_mut(),
-            )
-        }
-    }
-}
-
-trait StackFrame {
-    fn new() -> Self;
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD;
-    fn get_addr(&self) -> *const u8;
-    fn get_inline_context(&self) -> u32;
-}
-
-impl StackFrame for c::STACKFRAME_EX {
-    fn new() -> c::STACKFRAME_EX {
-        unsafe { mem::zeroed() }
-    }
-
-    #[cfg(target_arch = "x86")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Eip as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Esp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.Ebp as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_I386
-    }
-
-    #[cfg(target_arch = "x86_64")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Rip as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Rsp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.Rbp as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_AMD64
-    }
-
-    #[cfg(target_arch = "arm")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Pc as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Sp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.R11 as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_ARMNT
-    }
-
-    #[cfg(target_arch = "aarch64")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Pc as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Sp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.Fp as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_ARM64
-    }
-
-    fn get_addr(&self) -> *const u8 {
-        (self.AddrPC.Offset - 1) as *const u8
-    }
-
-    fn get_inline_context(&self) -> u32 {
-        self.InlineFrameContext
-    }
-}
-
-impl StackFrame for c::STACKFRAME64 {
-    fn new() -> c::STACKFRAME64 {
-        unsafe { mem::zeroed() }
-    }
-
-    #[cfg(target_arch = "x86")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Eip as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Esp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.Ebp as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_I386
-    }
-
-    #[cfg(target_arch = "x86_64")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Rip as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Rsp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.Rbp as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_AMD64
-    }
-
-    #[cfg(target_arch = "arm")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Pc as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Sp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.R11 as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_ARMNT
-    }
-
-    #[cfg(target_arch = "aarch64")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Pc as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Sp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.Fp as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_ARM64
-    }
-
-    fn get_addr(&self) -> *const u8 {
-        (self.AddrPC.Offset - 1) as *const u8
-    }
-
-    fn get_inline_context(&self) -> u32 {
-        0
-    }
-}
-
-enum StackWalkVariant {
-    StackWalkEx(StackWalkExFn, printing::PrintingFnsEx),
-    StackWalk64(StackWalk64Fn, printing::PrintingFns64),
-}
-
-pub struct BacktraceContext {
-    handle: c::HANDLE,
-    SymCleanup: SymCleanupFn,
-    // Only used in printing for msvc and not gnu
-    // The gnu version is effectively a ZST dummy.
-    #[allow(dead_code)]
-    StackWalkVariant: StackWalkVariant,
-    // keeping DynamycLibrary loaded until its functions no longer needed
-    #[allow(dead_code)]
-    dbghelp: DynamicLibrary,
-}
-
-impl Drop for BacktraceContext {
-    fn drop(&mut self) {
-        unsafe {
-            (self.SymCleanup)(self.handle);
-        }
-    }
-}
diff --git a/src/libstd/sys/windows/backtrace/printing/mod.rs b/src/libstd/sys/windows/backtrace/printing/mod.rs
deleted file mode 100644 (file)
index 9497d51..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#[cfg(target_env = "msvc")]
-#[path = "msvc.rs"]
-mod printing;
-
-#[cfg(target_env = "gnu")]
-mod printing {
-    pub use crate::sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname};
-
-    // dummy functions to mirror those present in msvc version.
-    use crate::sys::dynamic_lib::DynamicLibrary;
-    use crate::io;
-    pub struct PrintingFnsEx {}
-    pub struct PrintingFns64 {}
-    pub fn load_printing_fns_ex(_: &DynamicLibrary) -> io::Result<PrintingFnsEx> {
-        Ok(PrintingFnsEx{})
-    }
-    pub fn load_printing_fns_64(_: &DynamicLibrary) -> io::Result<PrintingFns64> {
-        Ok(PrintingFns64{})
-    }
-}
-
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-pub use self::printing::{load_printing_fns_ex, load_printing_fns_64,
-                         PrintingFnsEx, PrintingFns64};
diff --git a/src/libstd/sys/windows/backtrace/printing/msvc.rs b/src/libstd/sys/windows/backtrace/printing/msvc.rs
deleted file mode 100644 (file)
index 13a1512..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-use crate::ffi::CStr;
-use crate::io;
-use crate::mem;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys::backtrace::StackWalkVariant;
-use crate::sys::c;
-use crate::sys::dynamic_lib::DynamicLibrary;
-use crate::sys_common::backtrace::Frame;
-
-use libc::{c_char, c_ulong};
-
-// Structs holding printing functions and loaders for them
-// Two versions depending on whether dbghelp.dll has StackWalkEx or not
-// (the former being in newer Windows versions, the older being in Win7 and before)
-pub struct PrintingFnsEx {
-    resolve_symname: SymFromInlineContextFn,
-    sym_get_line: SymGetLineFromInlineContextFn,
-}
-pub struct PrintingFns64 {
-    resolve_symname: SymFromAddrFn,
-    sym_get_line: SymGetLineFromAddr64Fn,
-}
-
-pub fn load_printing_fns_ex(dbghelp: &DynamicLibrary) -> io::Result<PrintingFnsEx> {
-    Ok(PrintingFnsEx {
-        resolve_symname: sym!(dbghelp, "SymFromInlineContext", SymFromInlineContextFn)?,
-        sym_get_line: sym!(
-            dbghelp,
-            "SymGetLineFromInlineContext",
-            SymGetLineFromInlineContextFn
-        )?,
-    })
-}
-pub fn load_printing_fns_64(dbghelp: &DynamicLibrary) -> io::Result<PrintingFns64> {
-    Ok(PrintingFns64 {
-        resolve_symname: sym!(dbghelp, "SymFromAddr", SymFromAddrFn)?,
-        sym_get_line: sym!(dbghelp, "SymGetLineFromAddr64", SymGetLineFromAddr64Fn)?,
-    })
-}
-
-type SymFromAddrFn =
-    unsafe extern "system" fn(c::HANDLE, u64, *mut u64, *mut c::SYMBOL_INFO) -> c::BOOL;
-type SymFromInlineContextFn =
-    unsafe extern "system" fn(c::HANDLE, u64, c::ULONG, *mut u64, *mut c::SYMBOL_INFO) -> c::BOOL;
-
-type SymGetLineFromAddr64Fn =
-    unsafe extern "system" fn(c::HANDLE, u64, *mut u32, *mut c::IMAGEHLP_LINE64) -> c::BOOL;
-type SymGetLineFromInlineContextFn = unsafe extern "system" fn(
-    c::HANDLE,
-    u64,
-    c::ULONG,
-    u64,
-    *mut c::DWORD,
-    *mut c::IMAGEHLP_LINE64,
-) -> c::BOOL;
-
-/// Converts a pointer to symbol to its string value.
-pub fn resolve_symname<F>(frame: Frame, callback: F, context: &BacktraceContext) -> io::Result<()>
-where
-    F: FnOnce(Option<&str>) -> io::Result<()>,
-{
-    match context.StackWalkVariant {
-        StackWalkVariant::StackWalkEx(_, ref fns) => resolve_symname_internal(
-            |process: c::HANDLE,
-             symbol_address: u64,
-             inline_context: c::ULONG,
-             info: *mut c::SYMBOL_INFO| unsafe {
-                let mut displacement = 0u64;
-                (fns.resolve_symname)(
-                    process,
-                    symbol_address,
-                    inline_context,
-                    &mut displacement,
-                    info,
-                )
-            },
-            frame,
-            callback,
-            context,
-        ),
-        StackWalkVariant::StackWalk64(_, ref fns) => resolve_symname_internal(
-            |process: c::HANDLE,
-             symbol_address: u64,
-             _inline_context: c::ULONG,
-             info: *mut c::SYMBOL_INFO| unsafe {
-                let mut displacement = 0u64;
-                (fns.resolve_symname)(process, symbol_address, &mut displacement, info)
-            },
-            frame,
-            callback,
-            context,
-        ),
-    }
-}
-
-fn resolve_symname_internal<F, R>(
-    mut symbol_resolver: R,
-    frame: Frame,
-    callback: F,
-    context: &BacktraceContext,
-) -> io::Result<()>
-where
-    F: FnOnce(Option<&str>) -> io::Result<()>,
-    R: FnMut(c::HANDLE, u64, c::ULONG, *mut c::SYMBOL_INFO) -> c::BOOL,
-{
-    unsafe {
-        let mut info: c::SYMBOL_INFO = mem::zeroed();
-        info.MaxNameLen = c::MAX_SYM_NAME as c_ulong;
-        // the struct size in C.  the value is different to
-        // `size_of::<SYMBOL_INFO>() - MAX_SYM_NAME + 1` (== 81)
-        // due to struct alignment.
-        info.SizeOfStruct = 88;
-
-        let ret = symbol_resolver(
-            context.handle,
-            frame.symbol_addr as u64,
-            frame.inline_context,
-            &mut info,
-        );
-        let valid_range = if ret == c::TRUE && frame.symbol_addr as usize >= info.Address as usize {
-            if info.Size != 0 {
-                (frame.symbol_addr as usize) < info.Address as usize + info.Size as usize
-            } else {
-                true
-            }
-        } else {
-            false
-        };
-        let symname = if valid_range {
-            let ptr = info.Name.as_ptr() as *const c_char;
-            CStr::from_ptr(ptr).to_str().ok()
-        } else {
-            None
-        };
-        callback(symname)
-    }
-}
-
-pub fn foreach_symbol_fileline<F>(
-    frame: Frame,
-    callback: F,
-    context: &BacktraceContext,
-) -> io::Result<bool>
-where
-    F: FnMut(&[u8], u32) -> io::Result<()>,
-{
-    match context.StackWalkVariant {
-        StackWalkVariant::StackWalkEx(_, ref fns) => foreach_symbol_fileline_iternal(
-            |process: c::HANDLE,
-             frame_address: u64,
-             inline_context: c::ULONG,
-             line: *mut c::IMAGEHLP_LINE64| unsafe {
-                let mut displacement = 0u32;
-                (fns.sym_get_line)(
-                    process,
-                    frame_address,
-                    inline_context,
-                    0,
-                    &mut displacement,
-                    line,
-                )
-            },
-            frame,
-            callback,
-            context,
-        ),
-        StackWalkVariant::StackWalk64(_, ref fns) => foreach_symbol_fileline_iternal(
-            |process: c::HANDLE,
-             frame_address: u64,
-             _inline_context: c::ULONG,
-             line: *mut c::IMAGEHLP_LINE64| unsafe {
-                let mut displacement = 0u32;
-                (fns.sym_get_line)(process, frame_address, &mut displacement, line)
-            },
-            frame,
-            callback,
-            context,
-        ),
-    }
-}
-
-fn foreach_symbol_fileline_iternal<F, G>(
-    mut line_getter: G,
-    frame: Frame,
-    mut callback: F,
-    context: &BacktraceContext,
-) -> io::Result<bool>
-where
-    F: FnMut(&[u8], u32) -> io::Result<()>,
-    G: FnMut(c::HANDLE, u64, c::ULONG, *mut c::IMAGEHLP_LINE64) -> c::BOOL,
-{
-    unsafe {
-        let mut line: c::IMAGEHLP_LINE64 = mem::zeroed();
-        line.SizeOfStruct = mem::size_of::<c::IMAGEHLP_LINE64>() as u32;
-
-        let ret = line_getter(
-            context.handle,
-            frame.exact_position as u64,
-            frame.inline_context,
-            &mut line,
-        );
-        if ret == c::TRUE {
-            let name = CStr::from_ptr(line.Filename).to_bytes();
-            callback(name, line.LineNumber as u32)?;
-        }
-        Ok(false)
-    }
-}
index 518eccf754cffa008ad1cefce354a02b8a7cc62f..6ad338660c338c9ab662688a92770712adef9dc7 100644 (file)
@@ -5,8 +5,6 @@
 #![unstable(issue = "0", feature = "windows_c")]
 
 use crate::os::raw::{c_int, c_uint, c_ulong, c_long, c_longlong, c_ushort, c_char};
-#[cfg(target_arch = "x86_64")]
-use crate::os::raw::c_ulonglong;
 use crate::ptr;
 
 use libc::{wchar_t, size_t, c_void};
 pub type CHAR = c_char;
 pub type ULONG_PTR = usize;
 pub type ULONG = c_ulong;
-#[cfg(target_arch = "x86_64")]
-pub type ULONGLONG = u64;
-#[cfg(target_arch = "x86_64")]
-pub type DWORDLONG = ULONGLONG;
 
 pub type LPBOOL = *mut BOOL;
 pub type LPBYTE = *mut BYTE;
 
 pub const FIONBIO: c_ulong = 0x8004667e;
 
-#[cfg(target_arch = "arm")]
-const ARM_MAX_BREAKPOINTS: usize = 8;
-#[cfg(target_arch = "arm")]
-const ARM_MAX_WATCHPOINTS: usize = 1;
-
 #[repr(C)]
 #[derive(Copy)]
 pub struct WIN32_FIND_DATAW {
@@ -270,22 +259,6 @@ pub struct ipv6_mreq {
 pub const WAIT_TIMEOUT: DWORD = 258;
 pub const WAIT_FAILED: DWORD = 0xFFFFFFFF;
 
-#[cfg(target_env = "msvc")]
-#[cfg(feature = "backtrace")]
-pub const MAX_SYM_NAME: usize = 2000;
-#[cfg(target_arch = "x86")]
-#[cfg(feature = "backtrace")]
-pub const IMAGE_FILE_MACHINE_I386: DWORD = 0x014c;
-#[cfg(target_arch = "x86_64")]
-#[cfg(feature = "backtrace")]
-pub const IMAGE_FILE_MACHINE_AMD64: DWORD = 0x8664;
-#[cfg(target_arch = "aarch64")]
-#[cfg(feature = "backtrace")]
-pub const IMAGE_FILE_MACHINE_ARM64: DWORD = 0xAA64;
-#[cfg(target_arch = "arm")]
-#[cfg(feature = "backtrace")]
-pub const IMAGE_FILE_MACHINE_ARMNT: DWORD = 0x01c4;
-
 pub const EXCEPTION_CONTINUE_SEARCH: LONG = 0;
 pub const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
 pub const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15;
@@ -580,41 +553,6 @@ pub struct OVERLAPPED {
     pub hEvent: HANDLE,
 }
 
-#[repr(C)]
-#[cfg(target_env = "msvc")]
-#[cfg(feature = "backtrace")]
-pub struct SYMBOL_INFO {
-    pub SizeOfStruct: c_ulong,
-    pub TypeIndex: c_ulong,
-    pub Reserved: [u64; 2],
-    pub Index: c_ulong,
-    pub Size: c_ulong,
-    pub ModBase: u64,
-    pub Flags: c_ulong,
-    pub Value: u64,
-    pub Address: u64,
-    pub Register: c_ulong,
-    pub Scope: c_ulong,
-    pub Tag: c_ulong,
-    pub NameLen: c_ulong,
-    pub MaxNameLen: c_ulong,
-    // note that windows has this as 1, but it basically just means that
-    // the name is inline at the end of the struct. For us, we just bump
-    // the struct size up to MAX_SYM_NAME.
-    pub Name: [c_char; MAX_SYM_NAME],
-}
-
-#[repr(C)]
-#[cfg(target_env = "msvc")]
-#[cfg(feature = "backtrace")]
-pub struct IMAGEHLP_LINE64 {
-    pub SizeOfStruct: u32,
-    pub Key: *const c_void,
-    pub LineNumber: u32,
-    pub Filename: *const c_char,
-    pub Address: u64,
-}
-
 #[repr(C)]
 #[allow(dead_code)] // we only use some variants
 pub enum ADDRESS_MODE {
@@ -624,280 +562,8 @@ pub enum ADDRESS_MODE {
     AddrModeFlat,
 }
 
-#[repr(C)]
-#[cfg(feature = "backtrace")]
-pub struct ADDRESS64 {
-    pub Offset: u64,
-    pub Segment: u16,
-    pub Mode: ADDRESS_MODE,
-}
-
-#[repr(C)]
-#[cfg(feature = "backtrace")]
-pub struct STACKFRAME_EX {
-    pub AddrPC: ADDRESS64,
-    pub AddrReturn: ADDRESS64,
-    pub AddrFrame: ADDRESS64,
-    pub AddrStack: ADDRESS64,
-    pub AddrBStore: ADDRESS64,
-    pub FuncTableEntry: *mut c_void,
-    pub Params: [u64; 4],
-    pub Far: BOOL,
-    pub Virtual: BOOL,
-    pub Reserved: [u64; 3],
-    pub KdHelp: KDHELP64,
-    pub StackFrameSize: DWORD,
-    pub InlineFrameContext: DWORD,
-}
-
-#[repr(C)]
-#[cfg(feature = "backtrace")]
-pub struct STACKFRAME64 {
-    pub AddrPC: ADDRESS64,
-    pub AddrReturn: ADDRESS64,
-    pub AddrFrame: ADDRESS64,
-    pub AddrStack: ADDRESS64,
-    pub AddrBStore: ADDRESS64,
-    pub FuncTableEntry: *mut c_void,
-    pub Params: [u64; 4],
-    pub Far: BOOL,
-    pub Virtual: BOOL,
-    pub Reserved: [u64; 3],
-    pub KdHelp: KDHELP64,
-}
-
-#[repr(C)]
-#[cfg(feature = "backtrace")]
-pub struct KDHELP64 {
-    pub Thread: u64,
-    pub ThCallbackStack: DWORD,
-    pub ThCallbackBStore: DWORD,
-    pub NextCallback: DWORD,
-    pub FramePointer: DWORD,
-    pub KiCallUserMode: u64,
-    pub KeUserCallbackDispatcher: u64,
-    pub SystemRangeStart: u64,
-    pub KiUserExceptionDispatcher: u64,
-    pub StackBase: u64,
-    pub StackLimit: u64,
-    pub Reserved: [u64; 5],
-}
-
-#[cfg(target_arch = "x86")]
-#[repr(C)]
-pub struct CONTEXT {
-    pub ContextFlags: DWORD,
-    pub Dr0: DWORD,
-    pub Dr1: DWORD,
-    pub Dr2: DWORD,
-    pub Dr3: DWORD,
-    pub Dr6: DWORD,
-    pub Dr7: DWORD,
-    pub FloatSave: FLOATING_SAVE_AREA,
-    pub SegGs: DWORD,
-    pub SegFs: DWORD,
-    pub SegEs: DWORD,
-    pub SegDs: DWORD,
-    pub Edi: DWORD,
-    pub Esi: DWORD,
-    pub Ebx: DWORD,
-    pub Edx: DWORD,
-    pub Ecx: DWORD,
-    pub Eax: DWORD,
-    pub Ebp: DWORD,
-    pub Eip: DWORD,
-    pub SegCs: DWORD,
-    pub EFlags: DWORD,
-    pub Esp: DWORD,
-    pub SegSs: DWORD,
-    pub ExtendedRegisters: [u8; 512],
-}
-
-#[cfg(target_arch = "x86")]
-#[repr(C)]
-pub struct FLOATING_SAVE_AREA {
-    pub ControlWord: DWORD,
-    pub StatusWord: DWORD,
-    pub TagWord: DWORD,
-    pub ErrorOffset: DWORD,
-    pub ErrorSelector: DWORD,
-    pub DataOffset: DWORD,
-    pub DataSelector: DWORD,
-    pub RegisterArea: [u8; 80],
-    pub Cr0NpxState: DWORD,
-}
-
-#[cfg(target_arch = "x86_64")]
-#[repr(C, align(16))]
-pub struct CONTEXT {
-    pub P1Home: DWORDLONG,
-    pub P2Home: DWORDLONG,
-    pub P3Home: DWORDLONG,
-    pub P4Home: DWORDLONG,
-    pub P5Home: DWORDLONG,
-    pub P6Home: DWORDLONG,
-
-    pub ContextFlags: DWORD,
-    pub MxCsr: DWORD,
-
-    pub SegCs: WORD,
-    pub SegDs: WORD,
-    pub SegEs: WORD,
-    pub SegFs: WORD,
-    pub SegGs: WORD,
-    pub SegSs: WORD,
-    pub EFlags: DWORD,
-
-    pub Dr0: DWORDLONG,
-    pub Dr1: DWORDLONG,
-    pub Dr2: DWORDLONG,
-    pub Dr3: DWORDLONG,
-    pub Dr6: DWORDLONG,
-    pub Dr7: DWORDLONG,
-
-    pub Rax: DWORDLONG,
-    pub Rcx: DWORDLONG,
-    pub Rdx: DWORDLONG,
-    pub Rbx: DWORDLONG,
-    pub Rsp: DWORDLONG,
-    pub Rbp: DWORDLONG,
-    pub Rsi: DWORDLONG,
-    pub Rdi: DWORDLONG,
-    pub R8:  DWORDLONG,
-    pub R9:  DWORDLONG,
-    pub R10: DWORDLONG,
-    pub R11: DWORDLONG,
-    pub R12: DWORDLONG,
-    pub R13: DWORDLONG,
-    pub R14: DWORDLONG,
-    pub R15: DWORDLONG,
-
-    pub Rip: DWORDLONG,
-
-    pub FltSave: FLOATING_SAVE_AREA,
-
-    pub VectorRegister: [M128A; 26],
-    pub VectorControl: DWORDLONG,
-
-    pub DebugControl: DWORDLONG,
-    pub LastBranchToRip: DWORDLONG,
-    pub LastBranchFromRip: DWORDLONG,
-    pub LastExceptionToRip: DWORDLONG,
-    pub LastExceptionFromRip: DWORDLONG,
-}
-
-#[cfg(target_arch = "x86_64")]
-#[repr(C, align(16))]
-pub struct M128A {
-    pub Low:  c_ulonglong,
-    pub High: c_longlong
-}
-
-#[cfg(target_arch = "x86_64")]
-#[repr(C, align(16))]
-pub struct FLOATING_SAVE_AREA {
-    _Dummy: [u8; 512] // FIXME: Fill this out
-}
-
-#[cfg(target_arch = "arm")]
-#[repr(C)]
-pub struct CONTEXT {
-    pub ContextFlags: ULONG,
-    pub R0: ULONG,
-    pub R1: ULONG,
-    pub R2: ULONG,
-    pub R3: ULONG,
-    pub R4: ULONG,
-    pub R5: ULONG,
-    pub R6: ULONG,
-    pub R7: ULONG,
-    pub R8: ULONG,
-    pub R9: ULONG,
-    pub R10: ULONG,
-    pub R11: ULONG,
-    pub R12: ULONG,
-    pub Sp: ULONG,
-    pub Lr: ULONG,
-    pub Pc: ULONG,
-    pub Cpsr: ULONG,
-    pub Fpscr: ULONG,
-    pub Padding: ULONG,
-    pub D: [u64; 32],
-    pub Bvr: [ULONG; ARM_MAX_BREAKPOINTS],
-    pub Bcr: [ULONG; ARM_MAX_BREAKPOINTS],
-    pub Wvr: [ULONG; ARM_MAX_WATCHPOINTS],
-    pub Wcr: [ULONG; ARM_MAX_WATCHPOINTS],
-    pub Padding2: [ULONG; 2]
-}
-
-// FIXME(#43348): This structure is used for backtrace only, and a fake
-// definition is provided here only to allow rustdoc to pass type-check. This
-// will not appear in the final documentation. This should be also defined for
-// other architectures supported by Windows such as ARM, and for historical
-// interest, maybe MIPS and PowerPC as well.
-#[cfg(all(rustdoc, not(any(target_arch = "x86_64", target_arch = "x86",
-      target_arch = "aarch64", target_arch = "arm"))))]
 pub enum CONTEXT {}
 
-#[cfg(target_arch = "aarch64")]
-pub const ARM64_MAX_BREAKPOINTS: usize = 8;
-
-#[cfg(target_arch = "aarch64")]
-pub const ARM64_MAX_WATCHPOINTS: usize = 2;
-
-#[cfg(target_arch = "aarch64")]
-#[repr(C)]
-pub struct ARM64_NT_NEON128 {
-    pub D: [f64; 2],
-}
-
-#[cfg(target_arch = "aarch64")]
-#[repr(C, align(16))]
-pub struct CONTEXT {
-    pub ContextFlags: DWORD,
-    pub Cpsr: DWORD,
-    pub X0: u64,
-    pub X1: u64,
-    pub X2: u64,
-    pub X3: u64,
-    pub X4: u64,
-    pub X5: u64,
-    pub X6: u64,
-    pub X7: u64,
-    pub X8: u64,
-    pub X9: u64,
-    pub X10: u64,
-    pub X11: u64,
-    pub X12: u64,
-    pub X13: u64,
-    pub X14: u64,
-    pub X15: u64,
-    pub X16: u64,
-    pub X17: u64,
-    pub X18: u64,
-    pub X19: u64,
-    pub X20: u64,
-    pub X21: u64,
-    pub X22: u64,
-    pub X23: u64,
-    pub X24: u64,
-    pub X25: u64,
-    pub X26: u64,
-    pub X27: u64,
-    pub X28: u64,
-    pub Fp: u64,
-    pub Lr: u64,
-    pub Sp: u64,
-    pub Pc: u64,
-    pub V: [ARM64_NT_NEON128; 32],
-    pub Fpcr: DWORD,
-    pub Fpsr: DWORD,
-    pub Bcr: [DWORD; ARM64_MAX_BREAKPOINTS],
-    pub Bvr: [DWORD; ARM64_MAX_BREAKPOINTS],
-    pub Wcr: [DWORD; ARM64_MAX_WATCHPOINTS],
-    pub Wvr: [DWORD; ARM64_MAX_WATCHPOINTS],
-}
-
 #[repr(C)]
 pub struct SOCKADDR_STORAGE_LH {
     pub ss_family: ADDRESS_FAMILY,
@@ -1220,8 +886,6 @@ pub fn FindFirstFileW(fileName: LPCWSTR,
     pub fn FindNextFileW(findFile: HANDLE, findFileData: LPWIN32_FIND_DATAW)
                          -> BOOL;
     pub fn FindClose(findFile: HANDLE) -> BOOL;
-    #[cfg(feature = "backtrace")]
-    pub fn RtlCaptureContext(ctx: *mut CONTEXT);
     pub fn getsockopt(s: SOCKET,
                       level: c_int,
                       optname: c_int,
@@ -1252,10 +916,6 @@ pub fn getaddrinfo(node: *const c_char, service: *const c_char,
                        res: *mut *mut ADDRINFOA) -> c_int;
     pub fn freeaddrinfo(res: *mut ADDRINFOA);
 
-    #[cfg(feature = "backtrace")]
-    pub fn LoadLibraryW(name: LPCWSTR) -> HMODULE;
-    #[cfg(feature = "backtrace")]
-    pub fn FreeLibrary(handle: HMODULE) -> BOOL;
     pub fn GetProcAddress(handle: HMODULE,
                           name: LPCSTR) -> *mut c_void;
     pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
@@ -1361,34 +1021,3 @@ pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN {
         panic!("rwlocks not available")
     }
 }
-
-#[cfg(all(target_env = "gnu", feature = "backtrace"))]
-mod gnu {
-    use super::*;
-
-    pub const PROCESS_QUERY_INFORMATION: DWORD = 0x0400;
-
-    pub const CP_ACP: UINT = 0;
-
-    pub const WC_NO_BEST_FIT_CHARS: DWORD = 0x00000400;
-
-    extern "system" {
-        pub fn OpenProcess(dwDesiredAccess: DWORD,
-                           bInheritHandle: BOOL,
-                           dwProcessId: DWORD) -> HANDLE;
-    }
-
-    compat_fn! {
-        kernel32:
-
-        pub fn QueryFullProcessImageNameW(_hProcess: HANDLE,
-                                          _dwFlags: DWORD,
-                                          _lpExeName: LPWSTR,
-                                          _lpdwSize: LPDWORD) -> BOOL {
-            SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
-        }
-    }
-}
-
-#[cfg(all(target_env = "gnu", feature = "backtrace"))]
-pub use self::gnu::*;
diff --git a/src/libstd/sys/windows/dynamic_lib.rs b/src/libstd/sys/windows/dynamic_lib.rs
deleted file mode 100644 (file)
index b9d5105..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-use crate::os::windows::prelude::*;
-
-use crate::ffi::{CString, OsStr};
-use crate::io;
-use crate::sys::c;
-
-pub struct DynamicLibrary {
-    handle: c::HMODULE,
-}
-
-impl DynamicLibrary {
-    pub fn open(filename: &str) -> io::Result<DynamicLibrary> {
-        let filename = OsStr::new(filename)
-                             .encode_wide()
-                             .chain(Some(0))
-                             .collect::<Vec<_>>();
-        let result = unsafe {
-            c::LoadLibraryW(filename.as_ptr())
-        };
-        if result.is_null() {
-            Err(io::Error::last_os_error())
-        } else {
-            Ok(DynamicLibrary { handle: result })
-        }
-    }
-
-    pub fn symbol(&self, symbol: &str) -> io::Result<usize> {
-        let symbol = CString::new(symbol)?;
-        unsafe {
-            match c::GetProcAddress(self.handle, symbol.as_ptr()) as usize {
-                0 => Err(io::Error::last_os_error()),
-                n => Ok(n),
-            }
-        }
-    }
-}
-
-impl Drop for DynamicLibrary {
-    fn drop(&mut self) {
-        unsafe {
-            c::FreeLibrary(self.handle);
-        }
-    }
-}
index 1425254a2e12605911778573a6e3225352d64ca9..1cb5553912981a532a4273d107855e543a69d6ae 100644 (file)
 
 pub mod alloc;
 pub mod args;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
 pub mod c;
 pub mod cmath;
 pub mod condvar;
-#[cfg(feature = "backtrace")]
-pub mod dynamic_lib;
 pub mod env;
 pub mod ext;
 pub mod fast_thread_local;
index 8d8d8169b4383f226b28f516f15e5f6c48fe2448..a01b31e948b4e0930f212645787b7a70737bea05 100644 (file)
@@ -2,40 +2,17 @@
 /// supported platforms.
 
 use crate::env;
-use crate::io::prelude::*;
 use crate::io;
+use crate::io::prelude::*;
+use crate::mem;
 use crate::path::{self, Path};
 use crate::ptr;
-use crate::str;
 use crate::sync::atomic::{self, Ordering};
 use crate::sys::mutex::Mutex;
 
-use rustc_demangle::demangle;
-
-pub use crate::sys::backtrace::{
-    unwind_backtrace,
-    resolve_symname,
-    foreach_symbol_fileline,
-    BacktraceContext
-};
-
-#[cfg(target_pointer_width = "64")]
-pub const HEX_WIDTH: usize = 18;
-
-#[cfg(target_pointer_width = "32")]
-pub const HEX_WIDTH: usize = 10;
-
-/// Represents an item in the backtrace list. See `unwind_backtrace` for how
-/// it is created.
-#[derive(Debug, Copy, Clone)]
-pub struct Frame {
-    /// Exact address of the call that failed.
-    pub exact_position: *const u8,
-    /// Address of the enclosing function.
-    pub symbol_addr: *const u8,
-    /// Which inlined function is this frame referring to
-    pub inline_context: u32,
-}
+use backtrace::{BytesOrWideString, Frame, Symbol};
+
+pub const HEX_WIDTH: usize = 2 + 2 * mem::size_of::<usize>();
 
 /// Max number of frames to print.
 const MAX_NB_FRAMES: usize = 100;
@@ -49,7 +26,7 @@ pub fn print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
     // test mode immediately return here to optimize away any references to the
     // libbacktrace symbols
     if cfg!(test) {
-        return Ok(())
+        return Ok(());
     }
 
     // Use a lock to prevent mixed output in multithreading context.
@@ -63,75 +40,39 @@ pub fn print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
 }
 
 fn _print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
-    let mut frames = [Frame {
-        exact_position: ptr::null(),
-        symbol_addr: ptr::null(),
-        inline_context: 0,
-    }; MAX_NB_FRAMES];
-    let (nb_frames, context) = unwind_backtrace(&mut frames)?;
-    let (skipped_before, skipped_after) =
-        filter_frames(&frames[..nb_frames], format, &context);
-    if skipped_before + skipped_after > 0 {
-        writeln!(w, "note: Some details are omitted, \
-                     run with `RUST_BACKTRACE=full` for a verbose backtrace.")?;
-    }
     writeln!(w, "stack backtrace:")?;
 
-    let filtered_frames = &frames[..nb_frames - skipped_after];
-    for (index, frame) in filtered_frames.iter().skip(skipped_before).enumerate() {
-        resolve_symname(*frame, |symname| {
-            output(w, index, *frame, symname, format)
-        }, &context)?;
-        let has_more_filenames = foreach_symbol_fileline(*frame, |file, line| {
-            output_fileline(w, file, line, format)
-        }, &context)?;
-        if has_more_filenames {
-            w.write_all(b" <... and possibly more>")?;
-        }
-    }
-
-    Ok(())
-}
-
-/// Returns a number of frames to remove at the beginning and at the end of the
-/// backtrace, according to the backtrace format.
-fn filter_frames(frames: &[Frame],
-                 format: PrintFormat,
-                 context: &BacktraceContext) -> (usize, usize)
-{
-    if format == PrintFormat::Full {
-        return (0, 0);
-    }
-
-    let skipped_before = 0;
-
-    let skipped_after = frames.len() - frames.iter().position(|frame| {
-        let mut is_marker = false;
-        let _ = resolve_symname(*frame, |symname| {
-            if let Some(mangled_symbol_name) = symname {
-                // Use grep to find the concerned functions
-                if mangled_symbol_name.contains("__rust_begin_short_backtrace") {
-                    is_marker = true;
-                }
+    let mut printer = Printer::new(format, w);
+    unsafe {
+        backtrace::trace_unsynchronized(|frame| {
+            let mut hit = false;
+            backtrace::resolve_frame_unsynchronized(frame, |symbol| {
+                hit = true;
+                printer.output(frame, Some(symbol));
+            });
+            if !hit {
+                printer.output(frame, None);
             }
-            Ok(())
-        }, context);
-        is_marker
-    }).unwrap_or(frames.len());
-
-    if skipped_before + skipped_after >= frames.len() {
-        // Avoid showing completely empty backtraces
-        return (0, 0);
+            !printer.done
+        });
     }
-
-    (skipped_before, skipped_after)
+    if printer.skipped {
+        writeln!(
+            w,
+            "note: Some details are omitted, \
+             run with `RUST_BACKTRACE=full` for a verbose backtrace."
+        )?;
+    }
+    Ok(())
 }
 
-
 /// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
 #[inline(never)]
 pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
-    where F: FnOnce() -> T, F: Send, T: Send
+where
+    F: FnOnce() -> T,
+    F: Send,
+    T: Send,
 {
     f()
 }
@@ -156,7 +97,7 @@ pub fn log_enabled() -> Option<PrintFormat> {
         _ => return Some(PrintFormat::Full),
     }
 
-    let val = env::var_os("RUST_BACKTRACE").and_then(|x|
+    let val = env::var_os("RUST_BACKTRACE").and_then(|x| {
         if &x == "0" {
             None
         } else if &x == "full" {
@@ -164,80 +105,141 @@ pub fn log_enabled() -> Option<PrintFormat> {
         } else {
             Some(PrintFormat::Short)
         }
+    });
+    ENABLED.store(
+        match val {
+            Some(v) => v as isize,
+            None => 1,
+        },
+        Ordering::SeqCst,
     );
-    ENABLED.store(match val {
-        Some(v) => v as isize,
-        None => 1,
-    }, Ordering::SeqCst);
     val
 }
 
-/// Prints the symbol of the backtrace frame.
-///
-/// These output functions should now be used everywhere to ensure consistency.
-/// You may want to also use `output_fileline`.
-fn output(w: &mut dyn Write, idx: usize, frame: Frame,
-              s: Option<&str>, format: PrintFormat) -> io::Result<()> {
-    // Remove the `17: 0x0 - <unknown>` line.
-    if format == PrintFormat::Short && frame.exact_position == ptr::null() {
-        return Ok(());
+struct Printer<'a, 'b> {
+    format: PrintFormat,
+    done: bool,
+    skipped: bool,
+    idx: usize,
+    out: &'a mut (dyn Write + 'b),
+}
+
+impl<'a, 'b> Printer<'a, 'b> {
+    fn new(format: PrintFormat, out: &'a mut (dyn Write + 'b)) -> Printer<'a, 'b> {
+        Printer { format, done: false, skipped: false, idx: 0, out }
     }
-    match format {
-        PrintFormat::Full => write!(w,
-                                    "  {:2}: {:2$?} - ",
-                                    idx,
-                                    frame.exact_position,
-                                    HEX_WIDTH)?,
-        PrintFormat::Short => write!(w, "  {:2}: ", idx)?,
+
+    /// Prints the symbol of the backtrace frame.
+    ///
+    /// These output functions should now be used everywhere to ensure consistency.
+    /// You may want to also use `output_fileline`.
+    fn output(&mut self, frame: &Frame, symbol: Option<&Symbol>) {
+        if self.idx > MAX_NB_FRAMES {
+            self.done = true;
+            self.skipped = true;
+            return;
+        }
+        if self._output(frame, symbol).is_err() {
+            self.done = true;
+        }
+        self.idx += 1;
     }
-    match s {
-        Some(string) => {
-            let symbol = demangle(string);
-            match format {
-                PrintFormat::Full => write!(w, "{}", symbol)?,
-                // strip the trailing hash if short mode
-                PrintFormat::Short => write!(w, "{:#}", symbol)?,
+
+    fn _output(&mut self, frame: &Frame, symbol: Option<&Symbol>) -> io::Result<()> {
+        if self.format == PrintFormat::Short {
+            if let Some(sym) = symbol.and_then(|s| s.name()).and_then(|s| s.as_str()) {
+                if sym.contains("__rust_begin_short_backtrace") {
+                    self.skipped = true;
+                    self.done = true;
+                    return Ok(());
+                }
+            }
+
+            // Remove the `17: 0x0 - <unknown>` line.
+            if self.format == PrintFormat::Short && frame.ip() == ptr::null_mut() {
+                self.skipped = true;
+                return Ok(());
             }
         }
-        None => w.write_all(b"<unknown>")?,
-    }
-    w.write_all(b"\n")
-}
 
-/// Prints the filename and line number of the backtrace frame.
-///
-/// See also `output`.
-#[allow(dead_code)]
-fn output_fileline(w: &mut dyn Write,
-                   file: &[u8],
-                   line: u32,
-                   format: PrintFormat) -> io::Result<()> {
-    // prior line: "  ##: {:2$} - func"
-    w.write_all(b"")?;
-    match format {
-        PrintFormat::Full => write!(w,
-                                    "           {:1$}",
-                                    "",
-                                    HEX_WIDTH)?,
-        PrintFormat::Short => write!(w, "           ")?,
-    }
+        match self.format {
+            PrintFormat::Full => {
+                write!(self.out, "  {:2}: {:2$?} - ", self.idx, frame.ip(), HEX_WIDTH)?
+            }
+            PrintFormat::Short => write!(self.out, "  {:2}: ", self.idx)?,
+        }
 
-    let file = str::from_utf8(file).unwrap_or("<unknown>");
-    let file_path = Path::new(file);
-    let mut already_printed = false;
-    if format == PrintFormat::Short && file_path.is_absolute() {
-        if let Ok(cwd) = env::current_dir() {
-            if let Ok(stripped) = file_path.strip_prefix(&cwd) {
-                if let Some(s) = stripped.to_str() {
-                    write!(w, "  at .{}{}:{}", path::MAIN_SEPARATOR, s, line)?;
-                    already_printed = true;
+        match symbol.and_then(|s| s.name()) {
+            Some(symbol) => {
+                match self.format {
+                    PrintFormat::Full => write!(self.out, "{}", symbol)?,
+                    // strip the trailing hash if short mode
+                    PrintFormat::Short => write!(self.out, "{:#}", symbol)?,
                 }
             }
+            None => self.out.write_all(b"<unknown>")?,
         }
-    }
-    if !already_printed {
-        write!(w, "  at {}:{}", file, line)?;
+        self.out.write_all(b"\n")?;
+        if let Some(sym) = symbol {
+            self.output_fileline(sym)?;
+        }
+        Ok(())
     }
 
-    w.write_all(b"\n")
+    /// Prints the filename and line number of the backtrace frame.
+    ///
+    /// See also `output`.
+    fn output_fileline(&mut self, symbol: &Symbol) -> io::Result<()> {
+        #[cfg(windows)]
+        let path_buf;
+        let file = match symbol.filename_raw() {
+            #[cfg(unix)]
+            Some(BytesOrWideString::Bytes(bytes)) => {
+                use crate::os::unix::prelude::*;
+                Path::new(crate::ffi::OsStr::from_bytes(bytes))
+            }
+            #[cfg(not(unix))]
+            Some(BytesOrWideString::Bytes(bytes)) => {
+                Path::new(crate::str::from_utf8(bytes).unwrap_or("<unknown>"))
+            }
+            #[cfg(windows)]
+            Some(BytesOrWideString::Wide(wide)) => {
+                use crate::os::windows::prelude::*;
+                path_buf = crate::ffi::OsString::from_wide(wide);
+                Path::new(&path_buf)
+            }
+            #[cfg(not(windows))]
+            Some(BytesOrWideString::Wide(_wide)) => {
+                Path::new("<unknown>")
+            }
+            None => return Ok(()),
+        };
+        let line = match symbol.lineno() {
+            Some(line) => line,
+            None => return Ok(()),
+        };
+        // prior line: "  ##: {:2$} - func"
+        self.out.write_all(b"")?;
+        match self.format {
+            PrintFormat::Full => write!(self.out, "           {:1$}", "", HEX_WIDTH)?,
+            PrintFormat::Short => write!(self.out, "           ")?,
+        }
+
+        let mut already_printed = false;
+        if self.format == PrintFormat::Short && file.is_absolute() {
+            if let Ok(cwd) = env::current_dir() {
+                if let Ok(stripped) = file.strip_prefix(&cwd) {
+                    if let Some(s) = stripped.to_str() {
+                        write!(self.out, "  at .{}{}:{}", path::MAIN_SEPARATOR, s, line)?;
+                        already_printed = true;
+                    }
+                }
+            }
+        }
+        if !already_printed {
+            write!(self.out, "  at {}:{}", file.display(), line)?;
+        }
+
+        self.out.write_all(b"\n")
+    }
 }
diff --git a/src/libstd/sys_common/gnu/libbacktrace.rs b/src/libstd/sys_common/gnu/libbacktrace.rs
deleted file mode 100644 (file)
index 6cd0502..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-use backtrace_sys::backtrace_state;
-
-use crate::ffi::CStr;
-use crate::io;
-use crate::mem;
-use crate::ptr;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-
-pub fn foreach_symbol_fileline<F>(frame: Frame,
-                                  mut f: F,
-                                  _: &BacktraceContext) -> io::Result<bool>
-where F: FnMut(&[u8], u32) -> io::Result<()>
-{
-    // pcinfo may return an arbitrary number of file:line pairs,
-    // in the order of stack trace (i.e., inlined calls first).
-    // in order to avoid allocation, we stack-allocate a fixed size of entries.
-    const FILELINE_SIZE: usize = 32;
-    let mut fileline_buf = [(ptr::null(), !0); FILELINE_SIZE];
-    let ret;
-    let fileline_count = {
-        let state = unsafe { init_state() };
-        if state.is_null() {
-            return Err(io::Error::new(
-                io::ErrorKind::Other,
-                "failed to allocate libbacktrace state")
-            )
-        }
-        let mut fileline_win: &mut [FileLine] = &mut fileline_buf;
-        let fileline_addr = &mut fileline_win as *mut &mut [FileLine];
-        ret = unsafe {
-            backtrace_sys::backtrace_pcinfo(
-                state,
-                frame.exact_position as libc::uintptr_t,
-                pcinfo_cb,
-                error_cb,
-                fileline_addr as *mut libc::c_void,
-            )
-        };
-        FILELINE_SIZE - fileline_win.len()
-    };
-    if ret == 0 {
-        for &(file, line) in &fileline_buf[..fileline_count] {
-            if file.is_null() { continue; } // just to be sure
-            let file = unsafe { CStr::from_ptr(file).to_bytes() };
-            f(file, line)?;
-        }
-        Ok(fileline_count == FILELINE_SIZE)
-    } else {
-        Ok(false)
-    }
-}
-
-/// Converts a pointer to symbol to its string value.
-pub fn resolve_symname<F>(frame: Frame,
-                          callback: F,
-                          _: &BacktraceContext) -> io::Result<()>
-    where F: FnOnce(Option<&str>) -> io::Result<()>
-{
-    let symname = {
-        let state = unsafe { init_state() };
-        if state.is_null() {
-            return Err(io::Error::new(
-                io::ErrorKind::Other,
-                "failed to allocate libbacktrace state")
-            )
-        }
-        let mut data: *const libc::c_char = ptr::null();
-        let data_addr = &mut data as *mut *const libc::c_char;
-        let ret = unsafe {
-            backtrace_sys::backtrace_syminfo(
-                state,
-                frame.symbol_addr as libc::uintptr_t,
-                syminfo_cb,
-                error_cb,
-                data_addr as *mut libc::c_void,
-            )
-        };
-        if ret == 0 || data.is_null() {
-            None
-        } else {
-            unsafe {
-                CStr::from_ptr(data).to_str().ok()
-            }
-        }
-    };
-    callback(symname)
-}
-
-////////////////////////////////////////////////////////////////////////
-// helper callbacks
-////////////////////////////////////////////////////////////////////////
-
-type FileLine = (*const libc::c_char, u32);
-
-extern fn error_cb(_data: *mut libc::c_void, _msg: *const libc::c_char,
-                   _errnum: libc::c_int) {
-    // do nothing for now
-}
-extern fn syminfo_cb(data: *mut libc::c_void,
-                     _pc: libc::uintptr_t,
-                     symname: *const libc::c_char,
-                     _symval: libc::uintptr_t,
-                     _symsize: libc::uintptr_t) {
-    let slot = data as *mut *const libc::c_char;
-    unsafe { *slot = symname; }
-}
-extern fn pcinfo_cb(data: *mut libc::c_void,
-                    _pc: libc::uintptr_t,
-                    filename: *const libc::c_char,
-                    lineno: libc::c_int,
-                    _function: *const libc::c_char) -> libc::c_int {
-    if !filename.is_null() {
-        let slot = data as *mut &mut [FileLine];
-        let buffer = unsafe {ptr::read(slot)};
-
-        // if the buffer is not full, add file:line to the buffer
-        // and adjust the buffer for next possible calls to pcinfo_cb.
-        if !buffer.is_empty() {
-            buffer[0] = (filename, lineno as u32);
-            unsafe { ptr::write(slot, &mut buffer[1..]); }
-        }
-    }
-
-    0
-}
-
-// The libbacktrace API supports creating a state, but it does not
-// support destroying a state. I personally take this to mean that a
-// state is meant to be created and then live forever.
-//
-// I would love to register an at_exit() handler which cleans up this
-// state, but libbacktrace provides no way to do so.
-//
-// With these constraints, this function has a statically cached state
-// that is calculated the first time this is requested. Remember that
-// backtracing all happens serially (one global lock).
-//
-// Things don't work so well on not-Linux since libbacktrace can't track
-// down that executable this is. We at one point used env::current_exe but
-// it turns out that there are some serious security issues with that
-// approach.
-//
-// Specifically, on certain platforms like BSDs, a malicious actor can cause
-// an arbitrary file to be placed at the path returned by current_exe.
-// libbacktrace does not behave defensively in the presence of ill-formed
-// DWARF information, and has been demonstrated to segfault in at least one
-// case. There is no evidence at the moment to suggest that a more carefully
-// constructed file can't cause arbitrary code execution. As a result of all
-// of this, we don't hint libbacktrace with the path to the current process.
-unsafe fn init_state() -> *mut backtrace_state {
-    static mut STATE: *mut backtrace_state = ptr::null_mut();
-    if !STATE.is_null() { return STATE  }
-
-    let filename = match crate::sys::backtrace::gnu::get_executable_filename() {
-        Ok((filename, file)) => {
-            // filename is purposely leaked here since libbacktrace requires
-            // it to stay allocated permanently, file is also leaked so that
-            // the file stays locked
-            let filename_ptr = filename.as_ptr();
-            mem::forget(filename);
-            mem::forget(file);
-            filename_ptr
-        },
-        Err(_) => ptr::null(),
-    };
-
-    STATE = backtrace_sys::backtrace_create_state(
-        filename,
-        0,
-        error_cb,
-        ptr::null_mut(),
-    );
-    STATE
-}
diff --git a/src/libstd/sys_common/gnu/mod.rs b/src/libstd/sys_common/gnu/mod.rs
deleted file mode 100644 (file)
index d695969..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#![allow(missing_docs)]
-#![allow(non_camel_case_types)]
-#![allow(non_snake_case)]
-
-pub mod libbacktrace;
index 78e159942643f551ca54d4858f92d34077fe0e54..c4daedefd8e6d20c34dc088108eb613678a0c2d5 100644 (file)
@@ -77,12 +77,6 @@ macro_rules! rtunwrap {
     }
 }
 
-#[cfg(feature = "backtrace")]
-#[cfg(any(all(unix, not(target_os = "emscripten")),
-          all(windows, target_env = "gnu"),
-          target_os = "redox"))]
-pub mod gnu;
-
 // common error constructors
 
 /// A trait for viewing representations from std types
index 3276f152575f7780e2d888594738d81a8ae9d3c3..75e83bd9f9c74db2f0b606452781f3e389da361e 100644 (file)
@@ -10,7 +10,7 @@
 use crate::print::pprust;
 use crate::ptr::P;
 use crate::source_map::{dummy_spanned, respan, Spanned};
-use crate::symbol::{kw, Symbol};
+use crate::symbol::{kw, sym, Symbol};
 use crate::tokenstream::TokenStream;
 use crate::ThinVec;
 
@@ -1531,6 +1531,17 @@ pub fn ty_to_string(&self) -> &'static str {
         }
     }
 
+    pub fn to_symbol(&self) -> Symbol {
+        match *self {
+            IntTy::Isize => sym::isize,
+            IntTy::I8 => sym::i8,
+            IntTy::I16 => sym::i16,
+            IntTy::I32 => sym::i32,
+            IntTy::I64 => sym::i64,
+            IntTy::I128 => sym::i128,
+        }
+    }
+
     pub fn val_to_string(&self, val: i128) -> String {
         // Cast to a `u128` so we can correctly print `INT128_MIN`. All integral types
         // are parsed as `u128`, so we wouldn't want to print an extra negative
@@ -1572,6 +1583,17 @@ pub fn ty_to_string(&self) -> &'static str {
         }
     }
 
+    pub fn to_symbol(&self) -> Symbol {
+        match *self {
+            UintTy::Usize => sym::usize,
+            UintTy::U8 => sym::u8,
+            UintTy::U16 => sym::u16,
+            UintTy::U32 => sym::u32,
+            UintTy::U64 => sym::u64,
+            UintTy::U128 => sym::u128,
+        }
+    }
+
     pub fn val_to_string(&self, val: u128) -> String {
         format!("{}{}", val, self.ty_to_string())
     }
index 65ca96afab1292be47cf18688b1f0708ec6da054..b96f13335b2fecf8833a692b2aacf45c93a99ad2 100644 (file)
@@ -92,7 +92,15 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op
                     }
 
                     diagnostic.map(|d| {
-                        span_err!(d, attr.span, E0633, "malformed `#[unwind]` attribute");
+                        struct_span_err!(d, attr.span, E0633, "malformed `unwind` attribute input")
+                            .span_label(attr.span, "invalid argument")
+                            .span_suggestions(
+                                attr.span,
+                                "the allowed arguments are `allowed` and `aborts`",
+                                (vec!["allowed", "aborts"]).into_iter()
+                                    .map(|s| format!("#[unwind({})]", s)),
+                                Applicability::MachineApplicable,
+                            ).emit();
                     });
                 }
             }
index 2f75a8c9db57e453f9165f5bb5819aef15c06791..48948e4d0d79c1829c30cbbf199319c4ab046737 100644 (file)
@@ -278,7 +278,14 @@ pub fn meta(&self) -> Option<MetaItem> {
     pub fn parse<'a, T, F>(&self, sess: &'a ParseSess, mut f: F) -> PResult<'a, T>
         where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
     {
-        let mut parser = Parser::new(sess, self.tokens.clone(), None, false, false);
+        let mut parser = Parser::new(
+            sess,
+            self.tokens.clone(),
+            None,
+            false,
+            false,
+            Some("attribute"),
+        );
         let result = f(&mut parser)?;
         if parser.token != token::Eof {
             parser.unexpected()?;
index c82936afa3d9f0f96d815a36eddb05c326901a2c..fc413caa428dd748e8cf7610f10ac424034021fa 100644 (file)
@@ -94,6 +94,22 @@ fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
         if !attr.check_name(sym::cfg_attr) {
             return vec![attr];
         }
+        if attr.tokens.len() == 0 {
+            self.sess.span_diagnostic
+                .struct_span_err(
+                    attr.span,
+                    "malformed `cfg_attr` attribute input",
+                ).span_suggestion(
+                    attr.span,
+                    "missing condition and attribute",
+                    "#[cfg_attr(condition, attribute, other_attribute, ...)]".to_owned(),
+                    Applicability::HasPlaceholders,
+                ).note("for more information, visit \
+                       <https://doc.rust-lang.org/reference/conditional-compilation.html\
+                       #the-cfg_attr-attribute>")
+                .emit();
+            return Vec::new();
+        }
 
         let (cfg_predicate, expanded_attrs) = match attr.parse(self.sess, |parser| {
             parser.expect(&token::OpenDelim(token::Paren))?;
index f1a20d54065743fd4de8578406d75aa0f6b64662..d72193ffe1205a269405d007db7b17e9f4cd8272 100644 (file)
@@ -11,7 +11,7 @@
 use crate::parse::token;
 use crate::ptr::P;
 use crate::symbol::{kw, sym, Ident, Symbol};
-use crate::ThinVec;
+use crate::{ThinVec, MACRO_ARGUMENTS};
 use crate::tokenstream::{self, TokenStream};
 
 use errors::{DiagnosticBuilder, DiagnosticId};
@@ -850,7 +850,7 @@ pub fn monotonic_expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
     }
 
     pub fn new_parser_from_tts(&self, tts: &[tokenstream::TokenTree]) -> parser::Parser<'a> {
-        parse::stream_to_parser(self.parse_sess, tts.iter().cloned().collect())
+        parse::stream_to_parser(self.parse_sess, tts.iter().cloned().collect(), MACRO_ARGUMENTS)
     }
     pub fn source_map(&self) -> &'a SourceMap { self.parse_sess.source_map() }
     pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
@@ -969,10 +969,10 @@ pub fn set_trace_macros(&mut self, x: bool) {
     pub fn ident_of(&self, st: &str) -> ast::Ident {
         ast::Ident::from_str(st)
     }
-    pub fn std_path(&self, components: &[&str]) -> Vec<ast::Ident> {
+    pub fn std_path(&self, components: &[Symbol]) -> Vec<ast::Ident> {
         let def_site = DUMMY_SP.apply_mark(self.current_expansion.mark);
         iter::once(Ident::new(kw::DollarCrate, def_site))
-            .chain(components.iter().map(|s| self.ident_of(s)))
+            .chain(components.iter().map(|&s| Ident::with_empty_ctxt(s)))
             .collect()
     }
     pub fn name_of(&self, st: &str) -> ast::Name {
index ad8fb12deb7f6b34cd33954514ccc0b8a3a277da..9c0ffc1f6e8cb39174077c0ffcacbe465d6fd510 100644 (file)
@@ -3,11 +3,11 @@
 use crate::source_map::{dummy_spanned, respan, Spanned};
 use crate::ext::base::ExtCtxt;
 use crate::ptr::P;
-use crate::symbol::{Symbol, kw};
+use crate::symbol::{kw, sym, Symbol};
 use crate::ThinVec;
 
 use rustc_target::spec::abi::Abi;
-use syntax_pos::{Pos, Span, DUMMY_SP};
+use syntax_pos::{Pos, Span};
 
 pub trait AstBuilder {
     // paths
@@ -49,7 +49,6 @@ fn ty_ptr(&self, span: Span,
               ty: P<ast::Ty>,
               mutbl: ast::Mutability) -> P<ast::Ty>;
 
-    fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty>;
     fn ty_infer(&self, sp: Span) -> P<ast::Ty>;
 
     fn typaram(&self,
@@ -425,15 +424,6 @@ fn ty_ptr(&self,
                 ast::TyKind::Ptr(self.ty_mt(ty, mutbl)))
     }
 
-    fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty> {
-        self.ty_path(
-            self.path_all(DUMMY_SP,
-                          true,
-                          self.std_path(&["option", "Option"]),
-                          vec![ast::GenericArg::Type(ty)],
-                          Vec::new()))
-    }
-
     fn ty_infer(&self, span: Span) -> P<ast::Ty> {
         self.ty(span, ast::TyKind::Infer)
     }
@@ -735,7 +725,7 @@ fn expr_vec(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
         self.expr(sp, ast::ExprKind::Array(exprs))
     }
     fn expr_vec_ng(&self, sp: Span) -> P<ast::Expr> {
-        self.expr_call_global(sp, self.std_path(&["vec", "Vec", "new"]),
+        self.expr_call_global(sp, self.std_path(&[sym::vec, sym::Vec, sym::new]),
                               Vec::new())
     }
     fn expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
@@ -751,12 +741,12 @@ fn expr_cast(&self, sp: Span, expr: P<ast::Expr>, ty: P<ast::Ty>) -> P<ast::Expr
 
 
     fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
-        let some = self.std_path(&["option", "Option", "Some"]);
+        let some = self.std_path(&[sym::option, sym::Option, sym::Some]);
         self.expr_call_global(sp, some, vec![expr])
     }
 
     fn expr_none(&self, sp: Span) -> P<ast::Expr> {
-        let none = self.std_path(&["option", "Option", "None"]);
+        let none = self.std_path(&[sym::option, sym::Option, sym::None]);
         let none = self.path_global(sp, none);
         self.expr_path(none)
     }
@@ -780,7 +770,7 @@ fn expr_fail(&self, span: Span, msg: Symbol) -> P<ast::Expr> {
         let expr_loc_ptr = self.expr_addr_of(span, expr_loc_tuple);
         self.expr_call_global(
             span,
-            self.std_path(&["rt", "begin_panic"]),
+            self.std_path(&[sym::rt, sym::begin_panic]),
             vec![
                 self.expr_str(span, msg),
                 expr_loc_ptr])
@@ -791,19 +781,19 @@ fn expr_unreachable(&self, span: Span) -> P<ast::Expr> {
     }
 
     fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
-        let ok = self.std_path(&["result", "Result", "Ok"]);
+        let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]);
         self.expr_call_global(sp, ok, vec![expr])
     }
 
     fn expr_err(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
-        let err = self.std_path(&["result", "Result", "Err"]);
+        let err = self.std_path(&[sym::result, sym::Result, sym::Err]);
         self.expr_call_global(sp, err, vec![expr])
     }
 
     fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> {
-        let ok = self.std_path(&["result", "Result", "Ok"]);
+        let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]);
         let ok_path = self.path_global(sp, ok);
-        let err = self.std_path(&["result", "Result", "Err"]);
+        let err = self.std_path(&[sym::result, sym::Result, sym::Err]);
         let err_path = self.path_global(sp, err);
 
         let binding_variable = self.ident_of("__try_var");
@@ -867,25 +857,25 @@ fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat> {
     }
 
     fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
-        let some = self.std_path(&["option", "Option", "Some"]);
+        let some = self.std_path(&[sym::option, sym::Option, sym::Some]);
         let path = self.path_global(span, some);
         self.pat_tuple_struct(span, path, vec![pat])
     }
 
     fn pat_none(&self, span: Span) -> P<ast::Pat> {
-        let some = self.std_path(&["option", "Option", "None"]);
+        let some = self.std_path(&[sym::option, sym::Option, sym::None]);
         let path = self.path_global(span, some);
         self.pat_path(span, path)
     }
 
     fn pat_ok(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
-        let some = self.std_path(&["result", "Result", "Ok"]);
+        let some = self.std_path(&[sym::result, sym::Result, sym::Ok]);
         let path = self.path_global(span, some);
         self.pat_tuple_struct(span, path, vec![pat])
     }
 
     fn pat_err(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
-        let some = self.std_path(&["result", "Result", "Err"]);
+        let some = self.std_path(&[sym::result, sym::Result, sym::Err]);
         let path = self.path_global(span, some);
         self.pat_tuple_struct(span, path, vec![pat])
     }
index 6e789c4c7086b71ad6036a0654573b2a02ee6b8e..a2cf4a2a82d8df674fcd33ed4e308d7993d94fec 100644 (file)
@@ -5,6 +5,7 @@
 use crate::ext::build::AstBuilder;
 use crate::parse::parser::PathStyle;
 use crate::symbol::{Symbol, sym};
+use crate::errors::Applicability;
 
 use syntax_pos::Span;
 
@@ -17,8 +18,13 @@ pub fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) ->
             return true;
         }
         if !attr.is_meta_item_list() {
-            cx.span_err(attr.span,
-                        "attribute must be of the form `#[derive(Trait1, Trait2, ...)]`");
+            cx.struct_span_err(attr.span, "malformed `derive` attribute input")
+                .span_suggestion(
+                    attr.span,
+                    "missing traits to be derived",
+                    "#[derive(Trait1, Trait2, ...)]".to_owned(),
+                    Applicability::HasPlaceholders,
+                ).emit();
             return false;
         }
 
@@ -58,10 +64,7 @@ pub fn add_derived_markers<T>(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P
         call_site: span,
         def_site: None,
         format: ExpnFormat::MacroAttribute(Symbol::intern(&pretty_name)),
-        allow_internal_unstable: Some(vec![
-            Symbol::intern("rustc_attrs"),
-            Symbol::intern("structural_match"),
-        ].into()),
+        allow_internal_unstable: Some(vec![sym::rustc_attrs, sym::structural_match].into()),
         allow_internal_unsafe: false,
         local_inner_macros: false,
         edition: cx.parse_sess.edition,
@@ -74,7 +77,7 @@ pub fn add_derived_markers<T>(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P
             attrs.push(cx.attribute(span, meta));
         }
         if names.contains(&Symbol::intern("Copy")) {
-            let meta = cx.meta_word(span, Symbol::intern("rustc_copy_clone_marker"));
+            let meta = cx.meta_word(span, sym::rustc_copy_clone_marker);
             attrs.push(cx.attribute(span, meta));
         }
     });
index fbe052252a1140de41ec7e91b974a28b91c2d293..c2a73b662c680b7137f6e70813e98f84fb7f6291 100644 (file)
@@ -938,7 +938,7 @@ fn expand_derive_invoc(&mut self,
             }
             BuiltinDerive(func) => {
                 expn_info.allow_internal_unstable = Some(vec![
-                    Symbol::intern("rustc_attrs"),
+                    sym::rustc_attrs,
                     Symbol::intern("derive_clone_copy"),
                     Symbol::intern("derive_eq"),
                     Symbol::intern("libstd_sys_internals"), // RustcDeserialize and RustcSerialize
index fa1f85c0e7b572a3f4cd903c7bec7acb95afea40..7b7cf80760f5c3f920feda9ba0eeb6f45f60e71d 100644 (file)
@@ -80,7 +80,7 @@
 use crate::parse::parser::{Parser, PathStyle};
 use crate::parse::token::{self, DocComment, Nonterminal, Token};
 use crate::print::pprust;
-use crate::symbol::kw;
+use crate::symbol::{kw, sym, Symbol};
 use crate::tokenstream::{DelimSpan, TokenStream};
 
 use errors::FatalError;
@@ -598,7 +598,7 @@ fn inner_parse_loop<'root, 'tt>(
                 TokenTree::MetaVarDecl(_, _, id) => {
                     // Built-in nonterminals never start with these tokens,
                     // so we can eliminate them from consideration.
-                    if may_begin_with(&*id.as_str(), token) {
+                    if may_begin_with(id.name, token) {
                         bb_items.push(item);
                     }
                 }
@@ -658,7 +658,14 @@ pub fn parse(
     recurse_into_modules: bool,
 ) -> NamedParseResult {
     // Create a parser that can be used for the "black box" parts.
-    let mut parser = Parser::new(sess, tts, directory, recurse_into_modules, true);
+    let mut parser = Parser::new(
+        sess,
+        tts,
+        directory,
+        recurse_into_modules,
+        true,
+        crate::MACRO_ARGUMENTS,
+    );
 
     // A queue of possible matcher positions. We initialize it with the matcher position in which
     // the "dot" is before the first token of the first token tree in `ms`. `inner_parse_loop` then
@@ -784,7 +791,7 @@ pub fn parse(
                 let match_cur = item.match_cur;
                 item.push_match(
                     match_cur,
-                    MatchedNonterminal(Lrc::new(parse_nt(&mut parser, span, &ident.as_str()))),
+                    MatchedNonterminal(Lrc::new(parse_nt(&mut parser, span, ident.name))),
                 );
                 item.idx += 1;
                 item.match_cur += 1;
@@ -812,7 +819,7 @@ fn get_macro_ident(token: &Token) -> Option<(Ident, bool)> {
 ///
 /// Returning `false` is a *stability guarantee* that such a matcher will *never* begin with that
 /// token. Be conservative (return true) if not sure.
-fn may_begin_with(name: &str, token: &Token) -> bool {
+fn may_begin_with(name: Symbol, token: &Token) -> bool {
     /// Checks whether the non-terminal may contain a single (non-keyword) identifier.
     fn may_be_ident(nt: &token::Nonterminal) -> bool {
         match *nt {
@@ -822,16 +829,16 @@ fn may_be_ident(nt: &token::Nonterminal) -> bool {
     }
 
     match name {
-        "expr" => token.can_begin_expr(),
-        "ty" => token.can_begin_type(),
-        "ident" => get_macro_ident(token).is_some(),
-        "literal" => token.can_begin_literal_or_bool(),
-        "vis" => match *token {
+        sym::expr => token.can_begin_expr(),
+        sym::ty => token.can_begin_type(),
+        sym::ident => get_macro_ident(token).is_some(),
+        sym::literal => token.can_begin_literal_or_bool(),
+        sym::vis => match *token {
             // The follow-set of :vis + "priv" keyword + interpolated
             Token::Comma | Token::Ident(..) | Token::Interpolated(_) => true,
             _ => token.can_begin_type(),
         },
-        "block" => match *token {
+        sym::block => match *token {
             Token::OpenDelim(token::Brace) => true,
             Token::Interpolated(ref nt) => match **nt {
                 token::NtItem(_)
@@ -845,7 +852,7 @@ fn may_be_ident(nt: &token::Nonterminal) -> bool {
             },
             _ => false,
         },
-        "path" | "meta" => match *token {
+        sym::path | sym::meta => match *token {
             Token::ModSep | Token::Ident(..) => true,
             Token::Interpolated(ref nt) => match **nt {
                 token::NtPath(_) | token::NtMeta(_) => true,
@@ -853,7 +860,7 @@ fn may_be_ident(nt: &token::Nonterminal) -> bool {
             },
             _ => false,
         },
-        "pat" => match *token {
+        sym::pat => match *token {
             Token::Ident(..) |               // box, ref, mut, and other identifiers (can stricten)
             Token::OpenDelim(token::Paren) |    // tuple pattern
             Token::OpenDelim(token::Bracket) |  // slice pattern
@@ -869,7 +876,7 @@ fn may_be_ident(nt: &token::Nonterminal) -> bool {
             Token::Interpolated(ref nt) => may_be_ident(nt),
             _ => false,
         },
-        "lifetime" => match *token {
+        sym::lifetime => match *token {
             Token::Lifetime(_) => true,
             Token::Interpolated(ref nt) => match **nt {
                 token::NtLifetime(_) | token::NtTT(_) => true,
@@ -896,34 +903,34 @@ fn may_be_ident(nt: &token::Nonterminal) -> bool {
 /// # Returns
 ///
 /// The parsed non-terminal.
-fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
-    if name == "tt" {
+fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> Nonterminal {
+    if name == sym::tt {
         return token::NtTT(p.parse_token_tree());
     }
     // check at the beginning and the parser checks after each bump
     p.process_potential_macro_variable();
     match name {
-        "item" => match panictry!(p.parse_item()) {
+        sym::item => match panictry!(p.parse_item()) {
             Some(i) => token::NtItem(i),
             None => {
                 p.fatal("expected an item keyword").emit();
                 FatalError.raise();
             }
         },
-        "block" => token::NtBlock(panictry!(p.parse_block())),
-        "stmt" => match panictry!(p.parse_stmt()) {
+        sym::block => token::NtBlock(panictry!(p.parse_block())),
+        sym::stmt => match panictry!(p.parse_stmt()) {
             Some(s) => token::NtStmt(s),
             None => {
                 p.fatal("expected a statement").emit();
                 FatalError.raise();
             }
         },
-        "pat" => token::NtPat(panictry!(p.parse_pat(None))),
-        "expr" => token::NtExpr(panictry!(p.parse_expr())),
-        "literal" => token::NtLiteral(panictry!(p.parse_literal_maybe_minus())),
-        "ty" => token::NtTy(panictry!(p.parse_ty())),
+        sym::pat => token::NtPat(panictry!(p.parse_pat(None))),
+        sym::expr => token::NtExpr(panictry!(p.parse_expr())),
+        sym::literal => token::NtLiteral(panictry!(p.parse_literal_maybe_minus())),
+        sym::ty => token::NtTy(panictry!(p.parse_ty())),
         // this could be handled like a token, since it is one
-        "ident" => if let Some((ident, is_raw)) = get_macro_ident(&p.token) {
+        sym::ident => if let Some((ident, is_raw)) = get_macro_ident(&p.token) {
             let span = p.span;
             p.bump();
             token::NtIdent(Ident::new(ident.name, span), is_raw)
@@ -932,10 +939,10 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
             p.fatal(&format!("expected ident, found {}", &token_str)).emit();
             FatalError.raise()
         }
-        "path" => token::NtPath(panictry!(p.parse_path(PathStyle::Type))),
-        "meta" => token::NtMeta(panictry!(p.parse_meta_item())),
-        "vis" => token::NtVis(panictry!(p.parse_visibility(true))),
-        "lifetime" => if p.check_lifetime() {
+        sym::path => token::NtPath(panictry!(p.parse_path(PathStyle::Type))),
+        sym::meta => token::NtMeta(panictry!(p.parse_meta_item())),
+        sym::vis => token::NtVis(panictry!(p.parse_visibility(true))),
+        sym::lifetime => if p.check_lifetime() {
             token::NtLifetime(p.expect_lifetime().ident)
         } else {
             let token_str = pprust::token_to_string(&p.token);
index 37c49112dcaaceb22dcd42b1841620734fc2435c..285c88357a6a8c7dd3a6718e2bf14e945eab2717 100644 (file)
@@ -172,7 +172,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt<'_>,
                     path: Cow::from(cx.current_expansion.module.directory.as_path()),
                     ownership: cx.current_expansion.directory_ownership,
                 };
-                let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false);
+                let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false, None);
                 p.root_module_name = cx.current_expansion.module.mod_path.last()
                     .map(|id| id.as_str().to_string());
 
@@ -396,7 +396,7 @@ pub fn compile(
                         future this will become a hard error. Please use `allow_internal_unstable(\
                         foo, bar)` to only allow the `foo` and `bar` features",
                     );
-                    vec![Symbol::intern("allow_internal_unstable_backcompat_hack")].into()
+                    vec![sym::allow_internal_unstable_backcompat_hack].into()
                 })
             );
         let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe);
index 6a049b80acae225c851ab9af390fc92593ce82e3..b2646efe3e4649f34f6eb99866dcfd9e3321b157 100644 (file)
@@ -25,7 +25,7 @@
 use crate::symbol::{Symbol, kw, sym};
 use crate::tokenstream::TokenTree;
 
-use errors::{DiagnosticBuilder, Handler};
+use errors::{Applicability, DiagnosticBuilder, Handler};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_target::spec::abi::Abi;
 use syntax_pos::{Span, DUMMY_SP};
@@ -1422,7 +1422,7 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
         Normal,
         template!(
             Word,
-            List: r#"/*opt*/ since = "version", /*opt*/ note = "reason"#,
+            List: r#"/*opt*/ since = "version", /*opt*/ note = "reason""#,
             NameValueStr: "reason"
         ),
         Ungated
@@ -1858,24 +1858,32 @@ fn check_builtin_attribute(&mut self, attr: &ast::Attribute, name: Symbol,
 
         match attr.parse_meta(self.context.parse_sess) {
             Ok(meta) => if !should_skip(name) && !template.compatible(&meta.node) {
+                let error_msg = format!("malformed `{}` attribute input", name);
                 let mut msg = "attribute must be of the form ".to_owned();
+                let mut suggestions = vec![];
                 let mut first = true;
                 if template.word {
                     first = false;
-                    msg.push_str(&format!("`#[{}{}]`", name, ""));
+                    let code = format!("#[{}]", name);
+                    msg.push_str(&format!("`{}`", &code));
+                    suggestions.push(code);
                 }
                 if let Some(descr) = template.list {
                     if !first {
                         msg.push_str(" or ");
                     }
                     first = false;
-                    msg.push_str(&format!("`#[{}({})]`", name, descr));
+                    let code = format!("#[{}({})]", name, descr);
+                    msg.push_str(&format!("`{}`", &code));
+                    suggestions.push(code);
                 }
                 if let Some(descr) = template.name_value_str {
                     if !first {
                         msg.push_str(" or ");
                     }
-                    msg.push_str(&format!("`#[{} = \"{}\"]`", name, descr));
+                    let code = format!("#[{} = \"{}\"]", name, descr);
+                    msg.push_str(&format!("`{}`", &code));
+                    suggestions.push(code);
                 }
                 if should_warn(name) {
                     self.context.parse_sess.buffer_lint(
@@ -1885,7 +1893,17 @@ fn check_builtin_attribute(&mut self, attr: &ast::Attribute, name: Symbol,
                         &msg,
                     );
                 } else {
-                    self.context.parse_sess.span_diagnostic.span_err(meta.span, &msg);
+                    self.context.parse_sess.span_diagnostic.struct_span_err(meta.span, &error_msg)
+                        .span_suggestions(
+                            meta.span,
+                            if suggestions.len() == 1 {
+                                "must be of the form"
+                            } else {
+                                "the following are the possible correct uses"
+                            },
+                            suggestions.into_iter(),
+                            Applicability::HasPlaceholders,
+                        ).emit();
                 }
             }
             Err(mut err) => err.emit(),
@@ -2298,6 +2316,8 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
         let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
         if let Some(reason) = reason {
             err.span_note(span, reason);
+        } else {
+            err.span_label(span, "feature has been removed");
         }
         err.emit();
     }
@@ -2379,12 +2399,24 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
             None => continue,
         };
 
+        let bad_input = |span| {
+            struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input")
+        };
+
         for mi in list {
             let name = match mi.ident() {
                 Some(ident) if mi.is_word() => ident.name,
-                _ => {
-                    span_err!(span_handler, mi.span(), E0556,
-                            "malformed feature, expected just one word");
+                Some(ident) => {
+                    bad_input(mi.span()).span_suggestion(
+                        mi.span(),
+                        "expected just one word",
+                        format!("{}", ident.name),
+                        Applicability::MaybeIncorrect,
+                    ).emit();
+                    continue
+                }
+                None => {
+                    bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit();
                     continue
                 }
             };
index 5eda975bc9ee464c62c8aafedcde336a1b5c0118..4229121b3d0759cdf370a535e66700b1aac43679 100644 (file)
@@ -31,6 +31,8 @@
 use ast::AttrId;
 use syntax_pos::edition::Edition;
 
+const MACRO_ARGUMENTS: Option<&'static str> = Some("macro arguments");
+
 // A variant of 'try!' that panics on an Err. This is used as a crutch on the
 // way towards a non-panic!-prone parser. It should be used for fatal parsing
 // errors; eventually we plan to convert all code using panictry to just use
index 8ac5beb21b5308405f13fba01b6a67725a07846f..b3d49524d7668599e9d37ed6d46907db65981776 100644 (file)
 use crate::ast;
 use crate::ast::{
-    BlockCheckMode, Expr, ExprKind, Item, ItemKind, Pat, PatKind, QSelf, Ty, TyKind, VariantData,
+    BlockCheckMode, BinOpKind, Expr, ExprKind, Item, ItemKind, Pat, PatKind, PathSegment, QSelf,
+    Ty, TyKind, VariantData,
 };
-use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType};
-use crate::parse::token;
-use crate::parse::PResult;
-use crate::parse::Parser;
+use crate::parse::{SeqSep, token, PResult, Parser};
+use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType};
 use crate::print::pprust;
 use crate::ptr::P;
 use crate::source_map::Spanned;
-use crate::symbol::kw;
+use crate::symbol::{kw, sym};
 use crate::ThinVec;
-use errors::{Applicability, DiagnosticBuilder};
-use log::debug;
-use syntax_pos::Span;
+use crate::util::parser::AssocOp;
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
+use syntax_pos::{Span, DUMMY_SP, MultiSpan};
+use log::{debug, trace};
+
+pub enum Error {
+    FileNotFoundForModule {
+        mod_name: String,
+        default_path: String,
+        secondary_path: String,
+        dir_path: String,
+    },
+    DuplicatePaths {
+        mod_name: String,
+        default_path: String,
+        secondary_path: String,
+    },
+    UselessDocComment,
+    InclusiveRangeWithNoEnd,
+}
+
+impl Error {
+    fn span_err<S: Into<MultiSpan>>(
+        self,
+        sp: S,
+        handler: &errors::Handler,
+    ) -> DiagnosticBuilder<'_> {
+        match self {
+            Error::FileNotFoundForModule {
+                ref mod_name,
+                ref default_path,
+                ref secondary_path,
+                ref dir_path,
+            } => {
+                let mut err = struct_span_err!(
+                    handler,
+                    sp,
+                    E0583,
+                    "file not found for module `{}`",
+                    mod_name,
+                );
+                err.help(&format!(
+                    "name the file either {} or {} inside the directory \"{}\"",
+                    default_path,
+                    secondary_path,
+                    dir_path,
+                ));
+                err
+            }
+            Error::DuplicatePaths { ref mod_name, ref default_path, ref secondary_path } => {
+                let mut err = struct_span_err!(
+                    handler,
+                    sp,
+                    E0584,
+                    "file for module `{}` found at both {} and {}",
+                    mod_name,
+                    default_path,
+                    secondary_path,
+                );
+                err.help("delete or rename one of them to remove the ambiguity");
+                err
+            }
+            Error::UselessDocComment => {
+                let mut err = struct_span_err!(
+                    handler,
+                    sp,
+                    E0585,
+                    "found a documentation comment that doesn't document anything",
+                );
+                err.help("doc comments must come before what they document, maybe a comment was \
+                          intended with `//`?");
+                err
+            }
+            Error::InclusiveRangeWithNoEnd => {
+                let mut err = struct_span_err!(
+                    handler,
+                    sp,
+                    E0586,
+                    "inclusive range with no end",
+                );
+                err.help("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)");
+                err
+            }
+        }
+    }
+}
 
 pub trait RecoverQPath: Sized + 'static {
     const PATH_STYLE: PathStyle = PathStyle::Expr;
@@ -63,6 +145,364 @@ fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
 }
 
 impl<'a> Parser<'a> {
+    pub fn fatal(&self, m: &str) -> DiagnosticBuilder<'a> {
+        self.span_fatal(self.span, m)
+    }
+
+    pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
+        self.sess.span_diagnostic.struct_span_fatal(sp, m)
+    }
+
+    pub fn span_fatal_err<S: Into<MultiSpan>>(&self, sp: S, err: Error) -> DiagnosticBuilder<'a> {
+        err.span_err(sp, self.diagnostic())
+    }
+
+    pub fn bug(&self, m: &str) -> ! {
+        self.sess.span_diagnostic.span_bug(self.span, m)
+    }
+
+    pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) {
+        self.sess.span_diagnostic.span_err(sp, m)
+    }
+
+    crate fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
+        self.sess.span_diagnostic.struct_span_err(sp, m)
+    }
+
+    crate fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> ! {
+        self.sess.span_diagnostic.span_bug(sp, m)
+    }
+
+    crate fn cancel(&self, err: &mut DiagnosticBuilder<'_>) {
+        self.sess.span_diagnostic.cancel(err)
+    }
+
+    crate fn diagnostic(&self) -> &'a errors::Handler {
+        &self.sess.span_diagnostic
+    }
+
+    crate fn expected_ident_found(&self) -> DiagnosticBuilder<'a> {
+        let mut err = self.struct_span_err(
+            self.span,
+            &format!("expected identifier, found {}", self.this_token_descr()),
+        );
+        if let token::Ident(ident, false) = &self.token {
+            if ident.is_raw_guess() {
+                err.span_suggestion(
+                    self.span,
+                    "you can escape reserved keywords to use them as identifiers",
+                    format!("r#{}", ident),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+        }
+        if let Some(token_descr) = self.token_descr() {
+            err.span_label(self.span, format!("expected identifier, found {}", token_descr));
+        } else {
+            err.span_label(self.span, "expected identifier");
+            if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) {
+                err.span_suggestion(
+                    self.span,
+                    "remove this comma",
+                    String::new(),
+                    Applicability::MachineApplicable,
+                );
+            }
+        }
+        err
+    }
+
+    pub fn expected_one_of_not_found(
+        &mut self,
+        edible: &[token::Token],
+        inedible: &[token::Token],
+    ) -> PResult<'a, bool /* recovered */> {
+        fn tokens_to_string(tokens: &[TokenType]) -> String {
+            let mut i = tokens.iter();
+            // This might be a sign we need a connect method on Iterator.
+            let b = i.next()
+                     .map_or(String::new(), |t| t.to_string());
+            i.enumerate().fold(b, |mut b, (i, a)| {
+                if tokens.len() > 2 && i == tokens.len() - 2 {
+                    b.push_str(", or ");
+                } else if tokens.len() == 2 && i == tokens.len() - 2 {
+                    b.push_str(" or ");
+                } else {
+                    b.push_str(", ");
+                }
+                b.push_str(&a.to_string());
+                b
+            })
+        }
+
+        let mut expected = edible.iter()
+            .map(|x| TokenType::Token(x.clone()))
+            .chain(inedible.iter().map(|x| TokenType::Token(x.clone())))
+            .chain(self.expected_tokens.iter().cloned())
+            .collect::<Vec<_>>();
+        expected.sort_by_cached_key(|x| x.to_string());
+        expected.dedup();
+        let expect = tokens_to_string(&expected[..]);
+        let actual = self.this_token_to_string();
+        let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {
+            let short_expect = if expected.len() > 6 {
+                format!("{} possible tokens", expected.len())
+            } else {
+                expect.clone()
+            };
+            (format!("expected one of {}, found `{}`", expect, actual),
+                (self.sess.source_map().next_point(self.prev_span),
+                format!("expected one of {} here", short_expect)))
+        } else if expected.is_empty() {
+            (format!("unexpected token: `{}`", actual),
+                (self.prev_span, "unexpected token after this".to_string()))
+        } else {
+            (format!("expected {}, found `{}`", expect, actual),
+                (self.sess.source_map().next_point(self.prev_span),
+                format!("expected {} here", expect)))
+        };
+        self.last_unexpected_token_span = Some(self.span);
+        let mut err = self.fatal(&msg_exp);
+        if self.token.is_ident_named(sym::and) {
+            err.span_suggestion_short(
+                self.span,
+                "use `&&` instead of `and` for the boolean operator",
+                "&&".to_string(),
+                Applicability::MaybeIncorrect,
+            );
+        }
+        if self.token.is_ident_named(sym::or) {
+            err.span_suggestion_short(
+                self.span,
+                "use `||` instead of `or` for the boolean operator",
+                "||".to_string(),
+                Applicability::MaybeIncorrect,
+            );
+        }
+        let sp = if self.token == token::Token::Eof {
+            // This is EOF, don't want to point at the following char, but rather the last token
+            self.prev_span
+        } else {
+            label_sp
+        };
+        match self.recover_closing_delimiter(&expected.iter().filter_map(|tt| match tt {
+            TokenType::Token(t) => Some(t.clone()),
+            _ => None,
+        }).collect::<Vec<_>>(), err) {
+            Err(e) => err = e,
+            Ok(recovered) => {
+                return Ok(recovered);
+            }
+        }
+
+        let is_semi_suggestable = expected.iter().any(|t| match t {
+            TokenType::Token(token::Semi) => true, // we expect a `;` here
+            _ => false,
+        }) && ( // a `;` would be expected before the current keyword
+            self.token.is_keyword(kw::Break) ||
+            self.token.is_keyword(kw::Continue) ||
+            self.token.is_keyword(kw::For) ||
+            self.token.is_keyword(kw::If) ||
+            self.token.is_keyword(kw::Let) ||
+            self.token.is_keyword(kw::Loop) ||
+            self.token.is_keyword(kw::Match) ||
+            self.token.is_keyword(kw::Return) ||
+            self.token.is_keyword(kw::While)
+        );
+        let cm = self.sess.source_map();
+        match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
+            (Ok(ref a), Ok(ref b)) if a.line != b.line && is_semi_suggestable => {
+                // The spans are in different lines, expected `;` and found `let` or `return`.
+                // High likelihood that it is only a missing `;`.
+                err.span_suggestion_short(
+                    label_sp,
+                    "a semicolon may be missing here",
+                    ";".to_string(),
+                    Applicability::MaybeIncorrect,
+                );
+                err.emit();
+                return Ok(true);
+            }
+            (Ok(ref a), Ok(ref b)) if a.line == b.line => {
+                // When the spans are in the same line, it means that the only content between
+                // them is whitespace, point at the found token in that case:
+                //
+                // X |     () => { syntax error };
+                //   |                    ^^^^^ expected one of 8 possible tokens here
+                //
+                // instead of having:
+                //
+                // X |     () => { syntax error };
+                //   |                   -^^^^^ unexpected token
+                //   |                   |
+                //   |                   expected one of 8 possible tokens here
+                err.span_label(self.span, label_exp);
+            }
+            _ if self.prev_span == syntax_pos::DUMMY_SP => {
+                // Account for macro context where the previous span might not be
+                // available to avoid incorrect output (#54841).
+                err.span_label(self.span, "unexpected token");
+            }
+            _ => {
+                err.span_label(sp, label_exp);
+                err.span_label(self.span, "unexpected token");
+            }
+        }
+        Err(err)
+    }
+
+    /// Eats and discards tokens until one of `kets` is encountered. Respects token trees,
+    /// passes through any errors encountered. Used for error recovery.
+    crate fn eat_to_tokens(&mut self, kets: &[&token::Token]) {
+        let handler = self.diagnostic();
+
+        if let Err(ref mut err) = self.parse_seq_to_before_tokens(
+            kets,
+            SeqSep::none(),
+            TokenExpectType::Expect,
+            |p| Ok(p.parse_token_tree()),
+        ) {
+            handler.cancel(err);
+        }
+    }
+
+    /// This function checks if there are trailing angle brackets and produces
+    /// a diagnostic to suggest removing them.
+    ///
+    /// ```ignore (diagnostic)
+    /// let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>();
+    ///                                                        ^^ help: remove extra angle brackets
+    /// ```
+    crate fn check_trailing_angle_brackets(&mut self, segment: &PathSegment, end: token::Token) {
+        // This function is intended to be invoked after parsing a path segment where there are two
+        // cases:
+        //
+        // 1. A specific token is expected after the path segment.
+        //    eg. `x.foo(`, `x.foo::<u32>(` (parenthesis - method call),
+        //        `Foo::`, or `Foo::<Bar>::` (mod sep - continued path).
+        // 2. No specific token is expected after the path segment.
+        //    eg. `x.foo` (field access)
+        //
+        // This function is called after parsing `.foo` and before parsing the token `end` (if
+        // present). This includes any angle bracket arguments, such as `.foo::<u32>` or
+        // `Foo::<Bar>`.
+
+        // We only care about trailing angle brackets if we previously parsed angle bracket
+        // arguments. This helps stop us incorrectly suggesting that extra angle brackets be
+        // removed in this case:
+        //
+        // `x.foo >> (3)` (where `x.foo` is a `u32` for example)
+        //
+        // This case is particularly tricky as we won't notice it just looking at the tokens -
+        // it will appear the same (in terms of upcoming tokens) as below (since the `::<u32>` will
+        // have already been parsed):
+        //
+        // `x.foo::<u32>>>(3)`
+        let parsed_angle_bracket_args = segment.args
+            .as_ref()
+            .map(|args| args.is_angle_bracketed())
+            .unwrap_or(false);
+
+        debug!(
+            "check_trailing_angle_brackets: parsed_angle_bracket_args={:?}",
+            parsed_angle_bracket_args,
+        );
+        if !parsed_angle_bracket_args {
+            return;
+        }
+
+        // Keep the span at the start so we can highlight the sequence of `>` characters to be
+        // removed.
+        let lo = self.span;
+
+        // We need to look-ahead to see if we have `>` characters without moving the cursor forward
+        // (since we might have the field access case and the characters we're eating are
+        // actual operators and not trailing characters - ie `x.foo >> 3`).
+        let mut position = 0;
+
+        // We can encounter `>` or `>>` tokens in any order, so we need to keep track of how
+        // many of each (so we can correctly pluralize our error messages) and continue to
+        // advance.
+        let mut number_of_shr = 0;
+        let mut number_of_gt = 0;
+        while self.look_ahead(position, |t| {
+            trace!("check_trailing_angle_brackets: t={:?}", t);
+            if *t == token::BinOp(token::BinOpToken::Shr) {
+                number_of_shr += 1;
+                true
+            } else if *t == token::Gt {
+                number_of_gt += 1;
+                true
+            } else {
+                false
+            }
+        }) {
+            position += 1;
+        }
+
+        // If we didn't find any trailing `>` characters, then we have nothing to error about.
+        debug!(
+            "check_trailing_angle_brackets: number_of_gt={:?} number_of_shr={:?}",
+            number_of_gt, number_of_shr,
+        );
+        if number_of_gt < 1 && number_of_shr < 1 {
+            return;
+        }
+
+        // Finally, double check that we have our end token as otherwise this is the
+        // second case.
+        if self.look_ahead(position, |t| {
+            trace!("check_trailing_angle_brackets: t={:?}", t);
+            *t == end
+        }) {
+            // Eat from where we started until the end token so that parsing can continue
+            // as if we didn't have those extra angle brackets.
+            self.eat_to_tokens(&[&end]);
+            let span = lo.until(self.span);
+
+            let plural = number_of_gt > 1 || number_of_shr >= 1;
+            self.diagnostic()
+                .struct_span_err(
+                    span,
+                    &format!("unmatched angle bracket{}", if plural { "s" } else { "" }),
+                )
+                .span_suggestion(
+                    span,
+                    &format!("remove extra angle bracket{}", if plural { "s" } else { "" }),
+                    String::new(),
+                    Applicability::MachineApplicable,
+                )
+                .emit();
+        }
+    }
+
+    /// Produce an error if comparison operators are chained (RFC #558).
+    /// We only need to check lhs, not rhs, because all comparison ops
+    /// have same precedence and are left-associative
+    crate fn check_no_chained_comparison(&self, lhs: &Expr, outer_op: &AssocOp) {
+        debug_assert!(outer_op.is_comparison(),
+                      "check_no_chained_comparison: {:?} is not comparison",
+                      outer_op);
+        match lhs.node {
+            ExprKind::Binary(op, _, _) if op.node.is_comparison() => {
+                // respan to include both operators
+                let op_span = op.span.to(self.span);
+                let mut err = self.diagnostic().struct_span_err(op_span,
+                    "chained comparison operators require parentheses");
+                if op.node == BinOpKind::Lt &&
+                    *outer_op == AssocOp::Less ||  // Include `<` to provide this recommendation
+                    *outer_op == AssocOp::Greater  // even in a case like the following:
+                {                                  //     Foo<Bar<Baz<Qux, ()>>>
+                    err.help(
+                        "use `::<...>` instead of `<...>` if you meant to specify type arguments");
+                    err.help("or use `(...)` if you meant to specify fn arguments");
+                }
+                err.emit();
+            }
+            _ => {}
+        }
+    }
+
     crate fn maybe_report_ambiguous_plus(
         &mut self,
         allow_plus: bool,
@@ -201,7 +641,7 @@ impl<'a> Parser<'a> {
 
         let mut path = ast::Path {
             segments: Vec::new(),
-            span: syntax_pos::DUMMY_SP,
+            span: DUMMY_SP,
         };
         self.parse_path_segments(&mut path.segments, T::PATH_STYLE)?;
         path.span = ty_span.to(self.prev_span);
@@ -267,6 +707,58 @@ impl<'a> Parser<'a> {
         }
     }
 
+    /// Create a `DiagnosticBuilder` for an unexpected token `t` and try to recover if it is a
+    /// closing delimiter.
+    pub fn unexpected_try_recover(
+        &mut self,
+        t: &token::Token,
+    ) -> PResult<'a, bool /* recovered */> {
+        let token_str = pprust::token_to_string(t);
+        let this_token_str = self.this_token_descr();
+        let (prev_sp, sp) = match (&self.token, self.subparser_name) {
+            // Point at the end of the macro call when reaching end of macro arguments.
+            (token::Token::Eof, Some(_)) => {
+                let sp = self.sess.source_map().next_point(self.span);
+                (sp, sp)
+            }
+            // We don't want to point at the following span after DUMMY_SP.
+            // This happens when the parser finds an empty TokenStream.
+            _ if self.prev_span == DUMMY_SP => (self.span, self.span),
+            // EOF, don't want to point at the following char, but rather the last token.
+            (token::Token::Eof, None) => (self.prev_span, self.span),
+            _ => (self.sess.source_map().next_point(self.prev_span), self.span),
+        };
+        let msg = format!(
+            "expected `{}`, found {}",
+            token_str,
+            match (&self.token, self.subparser_name) {
+                (token::Token::Eof, Some(origin)) => format!("end of {}", origin),
+                _ => this_token_str,
+            },
+        );
+        let mut err = self.struct_span_err(sp, &msg);
+        let label_exp = format!("expected `{}`", token_str);
+        match self.recover_closing_delimiter(&[t.clone()], err) {
+            Err(e) => err = e,
+            Ok(recovered) => {
+                return Ok(recovered);
+            }
+        }
+        let cm = self.sess.source_map();
+        match (cm.lookup_line(prev_sp.lo()), cm.lookup_line(sp.lo())) {
+            (Ok(ref a), Ok(ref b)) if a.line == b.line => {
+                // When the spans are in the same line, it means that the only content
+                // between them is whitespace, point only at the found token.
+                err.span_label(sp, label_exp);
+            }
+            _ => {
+                err.span_label(prev_sp, label_exp);
+                err.span_label(sp, "unexpected token");
+            }
+        }
+        Err(err)
+    }
+
     /// Consume alternative await syntaxes like `await <expr>`, `await? <expr>`, `await(<expr>)`
     /// and `await { <expr> }`.
     crate fn parse_incorrect_await_syntax(
@@ -542,6 +1034,138 @@ impl<'a> Parser<'a> {
         }
     }
 
+    crate fn check_for_for_in_in_typo(&mut self, in_span: Span) {
+        if self.eat_keyword(kw::In) {
+            // a common typo: `for _ in in bar {}`
+            let mut err = self.sess.span_diagnostic.struct_span_err(
+                self.prev_span,
+                "expected iterable, found keyword `in`",
+            );
+            err.span_suggestion_short(
+                in_span.until(self.prev_span),
+                "remove the duplicated `in`",
+                String::new(),
+                Applicability::MachineApplicable,
+            );
+            err.emit();
+        }
+    }
+
+    crate fn expected_semi_or_open_brace(&mut self) -> PResult<'a, ast::TraitItem> {
+        let token_str = self.this_token_descr();
+        let mut err = self.fatal(&format!("expected `;` or `{{`, found {}", token_str));
+        err.span_label(self.span, "expected `;` or `{`");
+        Err(err)
+    }
+
+    crate fn eat_incorrect_doc_comment(&mut self, applied_to: &str) {
+        if let token::DocComment(_) = self.token {
+            let mut err = self.diagnostic().struct_span_err(
+                self.span,
+                &format!("documentation comments cannot be applied to {}", applied_to),
+            );
+            err.span_label(self.span, "doc comments are not allowed here");
+            err.emit();
+            self.bump();
+        } else if self.token == token::Pound && self.look_ahead(1, |t| {
+            *t == token::OpenDelim(token::Bracket)
+        }) {
+            let lo = self.span;
+            // Skip every token until next possible arg.
+            while self.token != token::CloseDelim(token::Bracket) {
+                self.bump();
+            }
+            let sp = lo.to(self.span);
+            self.bump();
+            let mut err = self.diagnostic().struct_span_err(
+                sp,
+                &format!("attributes cannot be applied to {}", applied_to),
+            );
+            err.span_label(sp, "attributes are not allowed here");
+            err.emit();
+        }
+    }
+
+    crate fn argument_without_type(
+        &mut self,
+        err: &mut DiagnosticBuilder<'_>,
+        pat: P<ast::Pat>,
+        require_name: bool,
+        is_trait_item: bool,
+    ) {
+        // If we find a pattern followed by an identifier, it could be an (incorrect)
+        // C-style parameter declaration.
+        if self.check_ident() && self.look_ahead(1, |t| {
+            *t == token::Comma || *t == token::CloseDelim(token::Paren)
+        }) {
+            let ident = self.parse_ident().unwrap();
+            let span = pat.span.with_hi(ident.span.hi());
+
+            err.span_suggestion(
+                span,
+                "declare the type after the parameter binding",
+                String::from("<identifier>: <type>"),
+                Applicability::HasPlaceholders,
+            );
+        } else if require_name && is_trait_item {
+            if let PatKind::Ident(_, ident, _) = pat.node {
+                err.span_suggestion(
+                    pat.span,
+                    "explicitly ignore parameter",
+                    format!("_: {}", ident),
+                    Applicability::MachineApplicable,
+                );
+            }
+
+            err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
+        }
+    }
+
+    crate fn recover_arg_parse(&mut self) -> PResult<'a, (P<ast::Pat>, P<ast::Ty>)> {
+        let pat = self.parse_pat(Some("argument name"))?;
+        self.expect(&token::Colon)?;
+        let ty = self.parse_ty()?;
+
+        let mut err = self.diagnostic().struct_span_err_with_code(
+            pat.span,
+            "patterns aren't allowed in methods without bodies",
+            DiagnosticId::Error("E0642".into()),
+        );
+        err.span_suggestion_short(
+            pat.span,
+            "give this argument a name or use an underscore to ignore it",
+            "_".to_owned(),
+            Applicability::MachineApplicable,
+        );
+        err.emit();
+
+        // Pretend the pattern is `_`, to avoid duplicate errors from AST validation.
+        let pat = P(Pat {
+            node: PatKind::Wild,
+            span: pat.span,
+            id: ast::DUMMY_NODE_ID
+        });
+        Ok((pat, ty))
+    }
+
+    crate fn recover_bad_self_arg(
+        &mut self,
+        mut arg: ast::Arg,
+        is_trait_item: bool,
+    ) -> PResult<'a, ast::Arg> {
+        let sp = arg.pat.span;
+        arg.ty.node = TyKind::Err;
+        let mut err = self.struct_span_err(sp, "unexpected `self` parameter in function");
+        if is_trait_item {
+            err.span_label(sp, "must be the first associated function parameter");
+        } else {
+            err.span_label(sp, "not valid as function parameter");
+            err.note("`self` is only valid as the first parameter of an associated function");
+        }
+        err.emit();
+        Ok(arg)
+    }
+
     crate fn consume_block(&mut self, delim: token::DelimToken) {
         let mut brace_depth = 0;
         loop {
@@ -562,4 +1186,23 @@ impl<'a> Parser<'a> {
         }
     }
 
+    crate fn expected_expression_found(&self) -> DiagnosticBuilder<'a> {
+        let (span, msg) = match (&self.token, self.subparser_name) {
+            (&token::Token::Eof, Some(origin)) => {
+                let sp = self.sess.source_map().next_point(self.span);
+                (sp, format!("expected expression, found end of {}", origin))
+            }
+            _ => (self.span, format!(
+                "expected expression, found {}",
+                self.this_token_descr(),
+            )),
+        };
+        let mut err = self.struct_span_err(span, &msg);
+        let sp = self.sess.source_map().start_point(self.span);
+        if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
+            self.sess.expr_parentheses_needed(&mut err, *sp, None);
+        }
+        err.span_label(span, "expected expression");
+        err
+    }
 }
index deb76d6d70a33f319d49ff15897cbfdcd4715d5c..a06a84f162a96a266b7b78e38d4acde9911fdf37 100644 (file)
@@ -1,7 +1,7 @@
 use crate::ast::{self, Ident};
 use crate::parse::ParseSess;
 use crate::parse::token::{self, Token};
-use crate::symbol::Symbol;
+use crate::symbol::{sym, Symbol};
 use crate::parse::unescape;
 use crate::parse::unescape_error_reporting::{emit_unescape_error, push_escaped_char};
 
@@ -754,7 +754,7 @@ fn scan_number(&mut self, c: char) -> (token::LitKind, Symbol) {
                 }
                 _ => {
                     // just a 0
-                    return (token::Integer, self.name_from(start_bpos));
+                    return (token::Integer, sym::integer(0));
                 }
             }
         } else if c.is_digit(10) {
index 0305b1f59b94652e4f1027bdd10af7c85fbf4d1d..18019a89130e7f49219f62bb86a2139c7f574dda 100644 (file)
@@ -171,12 +171,15 @@ fn from_lit_token(lit: token::Lit) -> Result<LitKind, LitError> {
     /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing).
     pub fn to_lit_token(&self) -> token::Lit {
         let (kind, symbol, suffix) = match *self {
-            LitKind::Str(string, ast::StrStyle::Cooked) => {
-                let escaped = string.as_str().escape_default().to_string();
-                (token::Str, Symbol::intern(&escaped), None)
+            LitKind::Str(symbol, ast::StrStyle::Cooked) => {
+                // Don't re-intern unless the escaped string is different.
+                let s = &symbol.as_str();
+                let escaped = s.escape_default().to_string();
+                let symbol = if escaped == *s { symbol } else { Symbol::intern(&escaped) };
+                (token::Str, symbol, None)
             }
-            LitKind::Str(string, ast::StrStyle::Raw(n)) => {
-                (token::StrRaw(n), string, None)
+            LitKind::Str(symbol, ast::StrStyle::Raw(n)) => {
+                (token::StrRaw(n), symbol, None)
             }
             LitKind::ByteStr(ref bytes) => {
                 let string = bytes.iter().cloned().flat_map(ascii::escape_default)
@@ -193,14 +196,14 @@ pub fn to_lit_token(&self) -> token::Lit {
             }
             LitKind::Int(n, ty) => {
                 let suffix = match ty {
-                    ast::LitIntType::Unsigned(ty) => Some(Symbol::intern(ty.ty_to_string())),
-                    ast::LitIntType::Signed(ty) => Some(Symbol::intern(ty.ty_to_string())),
+                    ast::LitIntType::Unsigned(ty) => Some(ty.to_symbol()),
+                    ast::LitIntType::Signed(ty) => Some(ty.to_symbol()),
                     ast::LitIntType::Unsuffixed => None,
                 };
-                (token::Integer, Symbol::intern(&n.to_string()), suffix)
+                (token::Integer, sym::integer(n), suffix)
             }
             LitKind::Float(symbol, ty) => {
-                (token::Float, symbol, Some(Symbol::intern(ty.ty_to_string())))
+                (token::Float, symbol, Some(ty.to_symbol()))
             }
             LitKind::FloatUnsuffixed(symbol) => {
                 (token::Float, symbol, None)
index 1073fc6f3ab4d3a00e760aa918fdb2a9a92a7772..f7a7aba9ecbaa1fdf3063012ebc4ed77a3d2b065 100644 (file)
@@ -236,7 +236,7 @@ fn maybe_source_file_to_parser(
 ) -> Result<Parser<'_>, Vec<Diagnostic>> {
     let end_pos = source_file.end_pos;
     let (stream, unclosed_delims) = maybe_file_to_stream(sess, source_file, None)?;
-    let mut parser = stream_to_parser(sess, stream);
+    let mut parser = stream_to_parser(sess, stream, None);
     parser.unclosed_delims = unclosed_delims;
     if parser.token == token::Eof && parser.span.is_dummy() {
         parser.span = Span::new(end_pos, end_pos, parser.span.ctxt());
@@ -248,7 +248,7 @@ fn maybe_source_file_to_parser(
 // must preserve old name for now, because quote! from the *existing*
 // compiler expands into it
 pub fn new_parser_from_tts(sess: &ParseSess, tts: Vec<TokenTree>) -> Parser<'_> {
-    stream_to_parser(sess, tts.into_iter().collect())
+    stream_to_parser(sess, tts.into_iter().collect(), crate::MACRO_ARGUMENTS)
 }
 
 
@@ -328,8 +328,12 @@ pub fn maybe_file_to_stream(
 }
 
 /// Given stream and the `ParseSess`, produces a parser.
-pub fn stream_to_parser(sess: &ParseSess, stream: TokenStream) -> Parser<'_> {
-    Parser::new(sess, stream, None, true, false)
+pub fn stream_to_parser<'a>(
+    sess: &'a ParseSess,
+    stream: TokenStream,
+    subparser_name: Option<&'static str>,
+) -> Parser<'a> {
+    Parser::new(sess, stream, None, true, false, subparser_name)
 }
 
 /// Given stream, the `ParseSess` and the base directory, produces a parser.
@@ -343,10 +347,12 @@ pub fn stream_to_parser(sess: &ParseSess, stream: TokenStream) -> Parser<'_> {
 /// The main usage of this function is outside of rustc, for those who uses
 /// libsyntax as a library. Please do not remove this function while refactoring
 /// just because it is not used in rustc codebase!
-pub fn stream_to_parser_with_base_dir<'a>(sess: &'a ParseSess,
-                                          stream: TokenStream,
-                                          base_dir: Directory<'a>) -> Parser<'a> {
-    Parser::new(sess, stream, Some(base_dir), true, false)
+pub fn stream_to_parser_with_base_dir<'a>(
+    sess: &'a ParseSess,
+    stream: TokenStream,
+    base_dir: Directory<'a>,
+) -> Parser<'a> {
+    Parser::new(sess, stream, Some(base_dir), true, false, None)
 }
 
 /// A sequence separator.
index 11c566b65e50a0bf237b0eb1aff0001e9424d735..07efeaa4cf264ce03b45d5e1c13f52d1c8422a8a 100644 (file)
 use crate::ThinVec;
 use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
 use crate::symbol::{kw, sym, Symbol};
+use crate::parse::diagnostics::Error;
 
 use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
 use rustc_target::spec::abi::{self, Abi};
-use syntax_pos::{
-    Span, MultiSpan, BytePos, FileName,
-    hygiene::CompilerDesugaringKind,
-};
-use log::{debug, trace};
+use syntax_pos::{Span, BytePos, DUMMY_SP, FileName, hygiene::CompilerDesugaringKind};
+use log::debug;
 
 use std::borrow::Cow;
 use std::cmp;
@@ -217,7 +215,7 @@ pub struct Parser<'a> {
     /// into modules, and sub-parsers have new values for this name.
     pub root_module_name: Option<String>,
     crate expected_tokens: Vec<TokenType>,
-    token_cursor: TokenCursor,
+    crate token_cursor: TokenCursor,
     desugar_doc_comments: bool,
     /// Whether we should configure out of line modules as we parse.
     pub cfg_mods: bool,
@@ -232,7 +230,9 @@ pub struct Parser<'a> {
     /// it gets removed from here. Every entry left at the end gets emitted as an independent
     /// error.
     crate unclosed_delims: Vec<UnmatchedBrace>,
-    last_unexpected_token_span: Option<Span>,
+    crate last_unexpected_token_span: Option<Span>,
+    /// If present, this `Parser` is not parsing Rust code but rather a macro call.
+    crate subparser_name: Option<&'static str>,
 }
 
 impl<'a> Drop for Parser<'a> {
@@ -243,19 +243,19 @@ fn drop(&mut self) {
 }
 
 #[derive(Clone)]
-struct TokenCursor {
-    frame: TokenCursorFrame,
-    stack: Vec<TokenCursorFrame>,
+crate struct TokenCursor {
+    crate frame: TokenCursorFrame,
+    crate stack: Vec<TokenCursorFrame>,
 }
 
 #[derive(Clone)]
-struct TokenCursorFrame {
-    delim: token::DelimToken,
-    span: DelimSpan,
-    open_delim: bool,
-    tree_cursor: tokenstream::Cursor,
-    close_delim: bool,
-    last_token: LastToken,
+crate struct TokenCursorFrame {
+    crate delim: token::DelimToken,
+    crate span: DelimSpan,
+    crate open_delim: bool,
+    crate tree_cursor: tokenstream::Cursor,
+    crate close_delim: bool,
+    crate last_token: LastToken,
 }
 
 /// This is used in `TokenCursorFrame` above to track tokens that are consumed
@@ -276,7 +276,7 @@ struct TokenCursorFrame {
 /// You can find some more example usage of this in the `collect_tokens` method
 /// on the parser.
 #[derive(Clone)]
-enum LastToken {
+crate enum LastToken {
     Collecting(Vec<TreeAndJoint>),
     Was(Option<TreeAndJoint>),
 }
@@ -309,7 +309,7 @@ fn next(&mut self) -> TokenAndSpan {
                 self.frame = frame;
                 continue
             } else {
-                return TokenAndSpan { tok: token::Eof, sp: syntax_pos::DUMMY_SP }
+                return TokenAndSpan { tok: token::Eof, sp: DUMMY_SP }
             };
 
             match self.frame.last_token {
@@ -428,65 +428,6 @@ pub struct ModulePathSuccess {
     warn: bool,
 }
 
-pub enum Error {
-    FileNotFoundForModule {
-        mod_name: String,
-        default_path: String,
-        secondary_path: String,
-        dir_path: String,
-    },
-    DuplicatePaths {
-        mod_name: String,
-        default_path: String,
-        secondary_path: String,
-    },
-    UselessDocComment,
-    InclusiveRangeWithNoEnd,
-}
-
-impl Error {
-    fn span_err<S: Into<MultiSpan>>(self,
-                                        sp: S,
-                                        handler: &errors::Handler) -> DiagnosticBuilder<'_> {
-        match self {
-            Error::FileNotFoundForModule { ref mod_name,
-                                           ref default_path,
-                                           ref secondary_path,
-                                           ref dir_path } => {
-                let mut err = struct_span_err!(handler, sp, E0583,
-                                               "file not found for module `{}`", mod_name);
-                err.help(&format!("name the file either {} or {} inside the directory \"{}\"",
-                                  default_path,
-                                  secondary_path,
-                                  dir_path));
-                err
-            }
-            Error::DuplicatePaths { ref mod_name, ref default_path, ref secondary_path } => {
-                let mut err = struct_span_err!(handler, sp, E0584,
-                                               "file for module `{}` found at both {} and {}",
-                                               mod_name,
-                                               default_path,
-                                               secondary_path);
-                err.help("delete or rename one of them to remove the ambiguity");
-                err
-            }
-            Error::UselessDocComment => {
-                let mut err = struct_span_err!(handler, sp, E0585,
-                                  "found a documentation comment that doesn't document anything");
-                err.help("doc comments must come before what they document, maybe a comment was \
-                          intended with `//`?");
-                err
-            }
-            Error::InclusiveRangeWithNoEnd => {
-                let mut err = struct_span_err!(handler, sp, E0586,
-                                               "inclusive range with no end");
-                err.help("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)");
-                err
-            }
-        }
-    }
-}
-
 #[derive(Debug)]
 enum LhsExpr {
     NotYetParsed,
@@ -527,23 +468,25 @@ fn dummy_arg(span: Span) -> Arg {
 }
 
 #[derive(Copy, Clone, Debug)]
-enum TokenExpectType {
+crate enum TokenExpectType {
     Expect,
     NoExpect,
 }
 
 impl<'a> Parser<'a> {
-    pub fn new(sess: &'a ParseSess,
-               tokens: TokenStream,
-               directory: Option<Directory<'a>>,
-               recurse_into_file_modules: bool,
-               desugar_doc_comments: bool)
-               -> Self {
+    pub fn new(
+        sess: &'a ParseSess,
+        tokens: TokenStream,
+        directory: Option<Directory<'a>>,
+        recurse_into_file_modules: bool,
+        desugar_doc_comments: bool,
+        subparser_name: Option<&'static str>,
+    ) -> Self {
         let mut parser = Parser {
             sess,
             token: token::Whitespace,
-            span: syntax_pos::DUMMY_SP,
-            prev_span: syntax_pos::DUMMY_SP,
+            span: DUMMY_SP,
+            prev_span: DUMMY_SP,
             meta_var_span: None,
             prev_token_kind: PrevTokenKind::Other,
             restrictions: Restrictions::empty(),
@@ -568,6 +511,7 @@ pub fn new(sess: &'a ParseSess,
             max_angle_bracket_count: 0,
             unclosed_delims: Vec::new(),
             last_unexpected_token_span: None,
+            subparser_name,
         };
 
         let tok = parser.next_tok();
@@ -605,7 +549,7 @@ pub fn this_token_to_string(&self) -> String {
         pprust::token_to_string(&self.token)
     }
 
-    fn token_descr(&self) -> Option<&'static str> {
+    crate fn token_descr(&self) -> Option<&'static str> {
         Some(match &self.token {
             t if t.is_special_ident() => "reserved identifier",
             t if t.is_used_keyword() => "keyword",
@@ -631,44 +575,13 @@ fn token_descr(&self) -> Option<&'static str> {
     }
 
     /// Expects and consumes the token `t`. Signals an error if the next token is not `t`.
-    pub fn expect(&mut self, t: &token::Token) -> PResult<'a,  bool /* recovered */> {
+    pub fn expect(&mut self, t: &token::Token) -> PResult<'a, bool /* recovered */> {
         if self.expected_tokens.is_empty() {
             if self.token == *t {
                 self.bump();
                 Ok(false)
             } else {
-                let token_str = pprust::token_to_string(t);
-                let this_token_str = self.this_token_descr();
-                let mut err = self.fatal(&format!("expected `{}`, found {}",
-                                                  token_str,
-                                                  this_token_str));
-
-                let sp = if self.token == token::Token::Eof {
-                    // EOF, don't want to point at the following char, but rather the last token
-                    self.prev_span
-                } else {
-                    self.sess.source_map().next_point(self.prev_span)
-                };
-                let label_exp = format!("expected `{}`", token_str);
-                match self.recover_closing_delimiter(&[t.clone()], err) {
-                    Err(e) => err = e,
-                    Ok(recovered) => {
-                        return Ok(recovered);
-                    }
-                }
-                let cm = self.sess.source_map();
-                match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
-                    (Ok(ref a), Ok(ref b)) if a.line == b.line => {
-                        // When the spans are in the same line, it means that the only content
-                        // between them is whitespace, point only at the found token.
-                        err.span_label(self.span, label_exp);
-                    }
-                    _ => {
-                        err.span_label(sp, label_exp);
-                        err.span_label(self.span, "unexpected token");
-                    }
-                }
-                Err(err)
+                self.unexpected_try_recover(t)
             }
         } else {
             self.expect_one_of(slice::from_ref(t), &[])
@@ -683,23 +596,6 @@ pub fn expect_one_of(
         edible: &[token::Token],
         inedible: &[token::Token],
     ) -> PResult<'a, bool /* recovered */> {
-        fn tokens_to_string(tokens: &[TokenType]) -> String {
-            let mut i = tokens.iter();
-            // This might be a sign we need a connect method on Iterator.
-            let b = i.next()
-                     .map_or(String::new(), |t| t.to_string());
-            i.enumerate().fold(b, |mut b, (i, a)| {
-                if tokens.len() > 2 && i == tokens.len() - 2 {
-                    b.push_str(", or ");
-                } else if tokens.len() == 2 && i == tokens.len() - 2 {
-                    b.push_str(" or ");
-                } else {
-                    b.push_str(", ");
-                }
-                b.push_str(&a.to_string());
-                b
-            })
-        }
         if edible.contains(&self.token) {
             self.bump();
             Ok(false)
@@ -709,127 +605,15 @@ fn tokens_to_string(tokens: &[TokenType]) -> String {
         } else if self.last_unexpected_token_span == Some(self.span) {
             FatalError.raise();
         } else {
-            let mut expected = edible.iter()
-                .map(|x| TokenType::Token(x.clone()))
-                .chain(inedible.iter().map(|x| TokenType::Token(x.clone())))
-                .chain(self.expected_tokens.iter().cloned())
-                .collect::<Vec<_>>();
-            expected.sort_by_cached_key(|x| x.to_string());
-            expected.dedup();
-            let expect = tokens_to_string(&expected[..]);
-            let actual = self.this_token_to_string();
-            let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {
-                let short_expect = if expected.len() > 6 {
-                    format!("{} possible tokens", expected.len())
-                } else {
-                    expect.clone()
-                };
-                (format!("expected one of {}, found `{}`", expect, actual),
-                 (self.sess.source_map().next_point(self.prev_span),
-                  format!("expected one of {} here", short_expect)))
-            } else if expected.is_empty() {
-                (format!("unexpected token: `{}`", actual),
-                 (self.prev_span, "unexpected token after this".to_string()))
-            } else {
-                (format!("expected {}, found `{}`", expect, actual),
-                 (self.sess.source_map().next_point(self.prev_span),
-                  format!("expected {} here", expect)))
-            };
-            self.last_unexpected_token_span = Some(self.span);
-            let mut err = self.fatal(&msg_exp);
-            if self.token.is_ident_named("and") {
-                err.span_suggestion_short(
-                    self.span,
-                    "use `&&` instead of `and` for the boolean operator",
-                    "&&".to_string(),
-                    Applicability::MaybeIncorrect,
-                );
-            }
-            if self.token.is_ident_named("or") {
-                err.span_suggestion_short(
-                    self.span,
-                    "use `||` instead of `or` for the boolean operator",
-                    "||".to_string(),
-                    Applicability::MaybeIncorrect,
-                );
-            }
-            let sp = if self.token == token::Token::Eof {
-                // This is EOF, don't want to point at the following char, but rather the last token
-                self.prev_span
-            } else {
-                label_sp
-            };
-            match self.recover_closing_delimiter(&expected.iter().filter_map(|tt| match tt {
-                TokenType::Token(t) => Some(t.clone()),
-                _ => None,
-            }).collect::<Vec<_>>(), err) {
-                Err(e) => err = e,
-                Ok(recovered) => {
-                    return Ok(recovered);
-                }
-            }
-
-            let is_semi_suggestable = expected.iter().any(|t| match t {
-                TokenType::Token(token::Semi) => true, // we expect a `;` here
-                _ => false,
-            }) && ( // a `;` would be expected before the current keyword
-                self.token.is_keyword(kw::Break) ||
-                self.token.is_keyword(kw::Continue) ||
-                self.token.is_keyword(kw::For) ||
-                self.token.is_keyword(kw::If) ||
-                self.token.is_keyword(kw::Let) ||
-                self.token.is_keyword(kw::Loop) ||
-                self.token.is_keyword(kw::Match) ||
-                self.token.is_keyword(kw::Return) ||
-                self.token.is_keyword(kw::While)
-            );
-            let cm = self.sess.source_map();
-            match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
-                (Ok(ref a), Ok(ref b)) if a.line != b.line && is_semi_suggestable => {
-                    // The spans are in different lines, expected `;` and found `let` or `return`.
-                    // High likelihood that it is only a missing `;`.
-                    err.span_suggestion_short(
-                        label_sp,
-                        "a semicolon may be missing here",
-                        ";".to_string(),
-                        Applicability::MaybeIncorrect,
-                    );
-                    err.emit();
-                    return Ok(true);
-                }
-                (Ok(ref a), Ok(ref b)) if a.line == b.line => {
-                    // When the spans are in the same line, it means that the only content between
-                    // them is whitespace, point at the found token in that case:
-                    //
-                    // X |     () => { syntax error };
-                    //   |                    ^^^^^ expected one of 8 possible tokens here
-                    //
-                    // instead of having:
-                    //
-                    // X |     () => { syntax error };
-                    //   |                   -^^^^^ unexpected token
-                    //   |                   |
-                    //   |                   expected one of 8 possible tokens here
-                    err.span_label(self.span, label_exp);
-                }
-                _ if self.prev_span == syntax_pos::DUMMY_SP => {
-                    // Account for macro context where the previous span might not be
-                    // available to avoid incorrect output (#54841).
-                    err.span_label(self.span, "unexpected token");
-                }
-                _ => {
-                    err.span_label(sp, label_exp);
-                    err.span_label(self.span, "unexpected token");
-                }
-            }
-            Err(err)
+            self.expected_one_of_not_found(edible, inedible)
         }
     }
 
     /// Returns the span of expr, if it was not interpolated or the span of the interpolated token.
-    fn interpolated_or_expr_span(&self,
-                                 expr: PResult<'a, P<Expr>>)
-                                 -> PResult<'a, (Span, P<Expr>)> {
+    fn interpolated_or_expr_span(
+        &self,
+        expr: PResult<'a, P<Expr>>,
+    ) -> PResult<'a, (Span, P<Expr>)> {
         expr.map(|e| {
             if self.prev_token_kind == PrevTokenKind::Interpolated {
                 (self.prev_span, e)
@@ -839,36 +623,6 @@ fn interpolated_or_expr_span(&self,
         })
     }
 
-    fn expected_ident_found(&self) -> DiagnosticBuilder<'a> {
-        let mut err = self.struct_span_err(self.span,
-                                           &format!("expected identifier, found {}",
-                                                    self.this_token_descr()));
-        if let token::Ident(ident, false) = &self.token {
-            if ident.is_raw_guess() {
-                err.span_suggestion(
-                    self.span,
-                    "you can escape reserved keywords to use them as identifiers",
-                    format!("r#{}", ident),
-                    Applicability::MaybeIncorrect,
-                );
-            }
-        }
-        if let Some(token_descr) = self.token_descr() {
-            err.span_label(self.span, format!("expected identifier, found {}", token_descr));
-        } else {
-            err.span_label(self.span, "expected identifier");
-            if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) {
-                err.span_suggestion(
-                    self.span,
-                    "remove this comma",
-                    String::new(),
-                    Applicability::MachineApplicable,
-                );
-            }
-        }
-        err
-    }
-
     pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
         self.parse_ident_common(true)
     }
@@ -951,7 +705,7 @@ fn expect_keyword(&mut self, kw: Symbol) -> PResult<'a, ()> {
         }
     }
 
-    fn check_ident(&mut self) -> bool {
+    crate fn check_ident(&mut self) -> bool {
         if self.token.is_ident() {
             true
         } else {
@@ -1141,19 +895,6 @@ fn expect_gt(&mut self) -> PResult<'a, ()> {
         }
     }
 
-    /// Eats and discards tokens until one of `kets` is encountered. Respects token trees,
-    /// passes through any errors encountered. Used for error recovery.
-    fn eat_to_tokens(&mut self, kets: &[&token::Token]) {
-        let handler = self.diagnostic();
-
-        if let Err(ref mut err) = self.parse_seq_to_before_tokens(kets,
-                                                                  SeqSep::none(),
-                                                                  TokenExpectType::Expect,
-                                                                  |p| Ok(p.parse_token_tree())) {
-            handler.cancel(err);
-        }
-    }
-
     /// Parses a sequence, including the closing delimiter. The function
     /// `f` must consume tokens until reaching the next separator or
     /// closing bracket.
@@ -1185,7 +926,7 @@ pub fn parse_seq_to_before_end<T, F>(
         self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f)
     }
 
-    fn parse_seq_to_before_tokens<T, F>(
+    crate fn parse_seq_to_before_tokens<T, F>(
         &mut self,
         kets: &[&token::Token],
         sep: SeqSep,
@@ -1345,35 +1086,6 @@ pub fn look_ahead<R, F>(&self, dist: usize, f: F) -> R where
             None => self.look_ahead_span(dist - 1),
         }
     }
-    pub fn fatal(&self, m: &str) -> DiagnosticBuilder<'a> {
-        self.sess.span_diagnostic.struct_span_fatal(self.span, m)
-    }
-    pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
-        self.sess.span_diagnostic.struct_span_fatal(sp, m)
-    }
-    fn span_fatal_err<S: Into<MultiSpan>>(&self, sp: S, err: Error) -> DiagnosticBuilder<'a> {
-        err.span_err(sp, self.diagnostic())
-    }
-    fn bug(&self, m: &str) -> ! {
-        self.sess.span_diagnostic.span_bug(self.span, m)
-    }
-    fn span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) {
-        self.sess.span_diagnostic.span_err(sp, m)
-    }
-    crate fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
-        self.sess.span_diagnostic.struct_span_err(sp, m)
-    }
-    crate fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> ! {
-        self.sess.span_diagnostic.span_bug(sp, m)
-    }
-
-    fn cancel(&self, err: &mut DiagnosticBuilder<'_>) {
-        self.sess.span_diagnostic.cancel(err)
-    }
-
-    crate fn diagnostic(&self) -> &'a errors::Handler {
-        &self.sess.span_diagnostic
-    }
 
     /// Is the current token one of the keywords that signals a bare function type?
     fn token_is_bare_fn_keyword(&mut self) -> bool {
@@ -1533,20 +1245,12 @@ fn parse_trait_item_(&mut self,
                             Some(body)
                         }
                         _ => {
-                            let token_str = self.this_token_descr();
-                            let mut err = self.fatal(&format!("expected `;` or `{{`, found {}",
-                                                              token_str));
-                            err.span_label(self.span, "expected `;` or `{`");
-                            return Err(err);
+                            return self.expected_semi_or_open_brace();
                         }
                     }
                 }
                 _ => {
-                    let token_str = self.this_token_descr();
-                    let mut err = self.fatal(&format!("expected `;` or `{{`, found {}",
-                                                      token_str));
-                    err.span_label(self.span, "expected `;` or `{`");
-                    return Err(err);
+                    return self.expected_semi_or_open_brace();
                 }
             };
             (ident, ast::TraitItemKind::Method(sig, body), generics)
@@ -1802,79 +1506,24 @@ fn is_named_argument(&self) -> bool {
 
     /// Skips unexpected attributes and doc comments in this position and emits an appropriate
     /// error.
-    fn eat_incorrect_doc_comment(&mut self, applied_to: &str) {
-        if let token::DocComment(_) = self.token {
-            let mut err = self.diagnostic().struct_span_err(
-                self.span,
-                &format!("documentation comments cannot be applied to {}", applied_to),
-            );
-            err.span_label(self.span, "doc comments are not allowed here");
-            err.emit();
-            self.bump();
-        } else if self.token == token::Pound && self.look_ahead(1, |t| {
-            *t == token::OpenDelim(token::Bracket)
-        }) {
-            let lo = self.span;
-            // Skip every token until next possible arg.
-            while self.token != token::CloseDelim(token::Bracket) {
-                self.bump();
-            }
-            let sp = lo.to(self.span);
-            self.bump();
-            let mut err = self.diagnostic().struct_span_err(
-                sp,
-                &format!("attributes cannot be applied to {}", applied_to),
-            );
-            err.span_label(sp, "attributes are not allowed here");
-            err.emit();
-        }
-    }
-
     /// This version of parse arg doesn't necessarily require identifier names.
-    fn parse_arg_general(&mut self, require_name: bool, is_trait_item: bool,
-                         allow_c_variadic: bool) -> PResult<'a, Arg> {
-        if let Ok(Some(_)) = self.parse_self_arg() {
-            let mut err = self.struct_span_err(self.prev_span,
-                "unexpected `self` argument in function");
-            err.span_label(self.prev_span,
-                "`self` is only valid as the first argument of an associated function");
-            return Err(err);
+    fn parse_arg_general(
+        &mut self,
+        require_name: bool,
+        is_trait_item: bool,
+        allow_c_variadic: bool,
+    ) -> PResult<'a, Arg> {
+        if let Ok(Some(arg)) = self.parse_self_arg() {
+            return self.recover_bad_self_arg(arg, is_trait_item);
         }
 
         let (pat, ty) = if require_name || self.is_named_argument() {
-            debug!("parse_arg_general parse_pat (require_name:{})",
-                   require_name);
+            debug!("parse_arg_general parse_pat (require_name:{})", require_name);
             self.eat_incorrect_doc_comment("method arguments");
             let pat = self.parse_pat(Some("argument name"))?;
 
             if let Err(mut err) = self.expect(&token::Colon) {
-                // If we find a pattern followed by an identifier, it could be an (incorrect)
-                // C-style parameter declaration.
-                if self.check_ident() && self.look_ahead(1, |t| {
-                    *t == token::Comma || *t == token::CloseDelim(token::Paren)
-                }) {
-                    let ident = self.parse_ident().unwrap();
-                    let span = pat.span.with_hi(ident.span.hi());
-
-                    err.span_suggestion(
-                        span,
-                        "declare the type after the parameter binding",
-                        String::from("<identifier>: <type>"),
-                        Applicability::HasPlaceholders,
-                    );
-                } else if require_name && is_trait_item {
-                    if let PatKind::Ident(_, ident, _) = pat.node {
-                        err.span_suggestion(
-                            pat.span,
-                            "explicitly ignore parameter",
-                            format!("_: {}", ident),
-                            Applicability::MachineApplicable,
-                        );
-                    }
-
-                    err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
-                }
-
+                self.argument_without_type(&mut err, pat, require_name, is_trait_item);
                 return Err(err);
             }
 
@@ -1911,30 +1560,7 @@ fn parse_arg_general(&mut self, require_name: bool, is_trait_item: bool,
                     // Recover from attempting to parse the argument as a type without pattern.
                     err.cancel();
                     mem::replace(self, parser_snapshot_before_ty);
-                    let pat = self.parse_pat(Some("argument name"))?;
-                    self.expect(&token::Colon)?;
-                    let ty = self.parse_ty()?;
-
-                    let mut err = self.diagnostic().struct_span_err_with_code(
-                        pat.span,
-                        "patterns aren't allowed in methods without bodies",
-                        DiagnosticId::Error("E0642".into()),
-                    );
-                    err.span_suggestion_short(
-                        pat.span,
-                        "give this argument a name or use an underscore to ignore it",
-                        "_".to_owned(),
-                        Applicability::MachineApplicable,
-                    );
-                    err.emit();
-
-                    // Pretend the pattern is `_`, to avoid duplicate errors from AST validation.
-                    let pat = P(Pat {
-                        node: PatKind::Wild,
-                        span: pat.span,
-                        id: ast::DUMMY_NODE_ID
-                    });
-                    (pat, ty)
+                    self.recover_arg_parse()?
                 }
             }
         };
@@ -1942,11 +1568,6 @@ fn parse_arg_general(&mut self, require_name: bool, is_trait_item: bool,
         Ok(Arg { ty, pat, id: ast::DUMMY_NODE_ID, source: ast::ArgSource::Normal })
     }
 
-    /// Parses a single function argument.
-    crate fn parse_arg(&mut self) -> PResult<'a, Arg> {
-        self.parse_arg_general(true, false, false)
-    }
-
     /// Parses an argument in a lambda header (e.g., `|arg, arg|`).
     fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> {
         let pat = self.parse_pat(Some("argument name"))?;
@@ -2041,7 +1662,7 @@ fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (QSelf, ast::Path)> {
             path = self.parse_path(PathStyle::Type)?;
             path_span = path_lo.to(self.prev_span);
         } else {
-            path = ast::Path { segments: Vec::new(), span: syntax_pos::DUMMY_SP };
+            path = ast::Path { segments: Vec::new(), span: DUMMY_SP };
             path_span = self.span.to(self.span);
         }
 
@@ -2627,17 +2248,7 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
                         }
                         Err(mut err) => {
                             self.cancel(&mut err);
-                            let msg = format!("expected expression, found {}",
-                                              self.this_token_descr());
-                            let mut err = self.fatal(&msg);
-                            let sp = self.sess.source_map().start_point(self.span);
-                            if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow()
-                                .get(&sp)
-                            {
-                                self.sess.expr_parentheses_needed(&mut err, *sp, None);
-                            }
-                            err.span_label(self.span, "expected expression");
-                            return Err(err);
+                            return Err(self.expected_expression_found());
                         }
                     }
                 }
@@ -2921,116 +2532,6 @@ fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Exp
         })
     }
 
-    /// This function checks if there are trailing angle brackets and produces
-    /// a diagnostic to suggest removing them.
-    ///
-    /// ```ignore (diagnostic)
-    /// let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>();
-    ///                                                        ^^ help: remove extra angle brackets
-    /// ```
-    fn check_trailing_angle_brackets(&mut self, segment: &PathSegment, end: token::Token) {
-        // This function is intended to be invoked after parsing a path segment where there are two
-        // cases:
-        //
-        // 1. A specific token is expected after the path segment.
-        //    eg. `x.foo(`, `x.foo::<u32>(` (parenthesis - method call),
-        //        `Foo::`, or `Foo::<Bar>::` (mod sep - continued path).
-        // 2. No specific token is expected after the path segment.
-        //    eg. `x.foo` (field access)
-        //
-        // This function is called after parsing `.foo` and before parsing the token `end` (if
-        // present). This includes any angle bracket arguments, such as `.foo::<u32>` or
-        // `Foo::<Bar>`.
-
-        // We only care about trailing angle brackets if we previously parsed angle bracket
-        // arguments. This helps stop us incorrectly suggesting that extra angle brackets be
-        // removed in this case:
-        //
-        // `x.foo >> (3)` (where `x.foo` is a `u32` for example)
-        //
-        // This case is particularly tricky as we won't notice it just looking at the tokens -
-        // it will appear the same (in terms of upcoming tokens) as below (since the `::<u32>` will
-        // have already been parsed):
-        //
-        // `x.foo::<u32>>>(3)`
-        let parsed_angle_bracket_args = segment.args
-            .as_ref()
-            .map(|args| args.is_angle_bracketed())
-            .unwrap_or(false);
-
-        debug!(
-            "check_trailing_angle_brackets: parsed_angle_bracket_args={:?}",
-            parsed_angle_bracket_args,
-        );
-        if !parsed_angle_bracket_args {
-            return;
-        }
-
-        // Keep the span at the start so we can highlight the sequence of `>` characters to be
-        // removed.
-        let lo = self.span;
-
-        // We need to look-ahead to see if we have `>` characters without moving the cursor forward
-        // (since we might have the field access case and the characters we're eating are
-        // actual operators and not trailing characters - ie `x.foo >> 3`).
-        let mut position = 0;
-
-        // We can encounter `>` or `>>` tokens in any order, so we need to keep track of how
-        // many of each (so we can correctly pluralize our error messages) and continue to
-        // advance.
-        let mut number_of_shr = 0;
-        let mut number_of_gt = 0;
-        while self.look_ahead(position, |t| {
-            trace!("check_trailing_angle_brackets: t={:?}", t);
-            if *t == token::BinOp(token::BinOpToken::Shr) {
-                number_of_shr += 1;
-                true
-            } else if *t == token::Gt {
-                number_of_gt += 1;
-                true
-            } else {
-                false
-            }
-        }) {
-            position += 1;
-        }
-
-        // If we didn't find any trailing `>` characters, then we have nothing to error about.
-        debug!(
-            "check_trailing_angle_brackets: number_of_gt={:?} number_of_shr={:?}",
-            number_of_gt, number_of_shr,
-        );
-        if number_of_gt < 1 && number_of_shr < 1 {
-            return;
-        }
-
-        // Finally, double check that we have our end token as otherwise this is the
-        // second case.
-        if self.look_ahead(position, |t| {
-            trace!("check_trailing_angle_brackets: t={:?}", t);
-            *t == end
-        }) {
-            // Eat from where we started until the end token so that parsing can continue
-            // as if we didn't have those extra angle brackets.
-            self.eat_to_tokens(&[&end]);
-            let span = lo.until(self.span);
-
-            let plural = number_of_gt > 1 || number_of_shr >= 1;
-            self.diagnostic()
-                .struct_span_err(
-                    span,
-                    &format!("unmatched angle bracket{}", if plural { "s" } else { "" }),
-                )
-                .span_suggestion(
-                    span,
-                    &format!("remove extra angle bracket{}", if plural { "s" } else { "" }),
-                    String::new(),
-                    Applicability::MachineApplicable,
-                )
-                .emit();
-        }
-    }
-
     fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
         let mut e = e0;
         let mut hi;
@@ -3258,7 +2759,7 @@ fn parse_prefix_expr(&mut self,
                 let (span, e) = self.interpolated_or_expr_span(e)?;
                 (lo.to(span), ExprKind::Box(e))
             }
-            token::Ident(..) if self.token.is_ident_named("not") => {
+            token::Ident(..) if self.token.is_ident_named(sym::not) => {
                 // `not` is just an ordinary identifier in Rust-the-language,
                 // but as `rustc`-the-compiler, we can issue clever diagnostics
                 // for confused users who really want to say `!`
@@ -3592,33 +3093,6 @@ fn parse_assoc_op_cast(&mut self, lhs: P<Expr>, lhs_span: Span,
         }
     }
 
-    /// Produce an error if comparison operators are chained (RFC #558).
-    /// We only need to check lhs, not rhs, because all comparison ops
-    /// have same precedence and are left-associative
-    fn check_no_chained_comparison(&self, lhs: &Expr, outer_op: &AssocOp) {
-        debug_assert!(outer_op.is_comparison(),
-                      "check_no_chained_comparison: {:?} is not comparison",
-                      outer_op);
-        match lhs.node {
-            ExprKind::Binary(op, _, _) if op.node.is_comparison() => {
-                // respan to include both operators
-                let op_span = op.span.to(self.span);
-                let mut err = self.diagnostic().struct_span_err(op_span,
-                    "chained comparison operators require parentheses");
-                if op.node == BinOpKind::Lt &&
-                    *outer_op == AssocOp::Less ||  // Include `<` to provide this recommendation
-                    *outer_op == AssocOp::Greater  // even in a case like the following:
-                {                                  //     Foo<Bar<Baz<Qux, ()>>>
-                    err.help(
-                        "use `::<...>` instead of `<...>` if you meant to specify type arguments");
-                    err.help("or use `(...)` if you meant to specify fn arguments");
-                }
-                err.emit();
-            }
-            _ => {}
-        }
-    }
-
     /// Parse prefix-forms of range notation: `..expr`, `..`, `..=expr`
     fn parse_prefix_range_expr(&mut self,
                                already_parsed_attrs: Option<ThinVec<Attribute>>)
@@ -3645,7 +3119,7 @@ fn parse_prefix_range_expr(&mut self,
                     hi = x.span;
                     x
                 })?)
-         } else {
+        } else {
             None
         };
         let limits = if tok == token::DotDot {
@@ -3795,20 +3269,7 @@ fn parse_for_expr(&mut self, opt_label: Option<Label>,
             err.emit();
         }
         let in_span = self.prev_span;
-        if self.eat_keyword(kw::In) {
-            // a common typo: `for _ in in bar {}`
-            let mut err = self.sess.span_diagnostic.struct_span_err(
-                self.prev_span,
-                "expected iterable, found keyword `in`",
-            );
-            err.span_suggestion_short(
-                in_span.until(self.prev_span),
-                "remove the duplicated `in`",
-                String::new(),
-                Applicability::MachineApplicable,
-            );
-            err.emit();
-        }
+        self.check_for_for_in_in_typo(in_span);
         let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
         let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?;
         attrs.extend(iattrs);
@@ -5131,7 +4592,7 @@ pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
             let do_not_suggest_help =
                 self.token.is_keyword(kw::In) || self.token == token::Colon;
 
-            if self.token.is_ident_named("and") {
+            if self.token.is_ident_named(sym::and) {
                 e.span_suggestion_short(
                     self.span,
                     "use `&&` instead of `and` for the boolean operator",
@@ -5139,7 +4600,7 @@ pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
                     Applicability::MaybeIncorrect,
                 );
             }
-            if self.token.is_ident_named("or") {
+            if self.token.is_ident_named(sym::or) {
                 e.span_suggestion_short(
                     self.span,
                     "use `||` instead of `or` for the boolean operator",
@@ -5592,7 +5053,7 @@ fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
                 where_clause: WhereClause {
                     id: ast::DUMMY_NODE_ID,
                     predicates: Vec::new(),
-                    span: syntax_pos::DUMMY_SP,
+                    span: DUMMY_SP,
                 },
                 span: span_lo.to(self.prev_span),
             })
@@ -5838,7 +5299,7 @@ fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> {
         let mut where_clause = WhereClause {
             id: ast::DUMMY_NODE_ID,
             predicates: Vec::new(),
-            span: syntax_pos::DUMMY_SP,
+            span: DUMMY_SP,
         };
 
         if !self.eat_keyword(kw::Where) {
@@ -6326,7 +5787,7 @@ fn complain_if_pub_macro(&self, vis: &VisibilityKind, sp: Span) {
             VisibilityKind::Inherited => {}
             _ => {
                 let is_macro_rules: bool = match self.token {
-                    token::Ident(sid, _) => sid.name == Symbol::intern("macro_rules"),
+                    token::Ident(sid, _) => sid.name == sym::macro_rules,
                     _ => false,
                 };
                 let mut err = if is_macro_rules {
@@ -6390,7 +5851,9 @@ fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool)
             let (constness, unsafety, mut asyncness, abi) = self.parse_fn_front_matter()?;
             let ident = self.parse_ident()?;
             let mut generics = self.parse_generics()?;
-            let mut decl = self.parse_fn_decl_with_self(|p| p.parse_arg())?;
+            let mut decl = self.parse_fn_decl_with_self(|p| {
+                p.parse_arg_general(true, true, false)
+            })?;
             generics.where_clause = self.parse_where_clause()?;
             self.construct_async_arguments(&mut asyncness, &mut decl);
             *at_end = true;
@@ -7005,7 +6468,7 @@ fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo>
                             Ident::with_empty_ctxt(sym::warn_directory_ownership)),
                         tokens: TokenStream::empty(),
                         is_sugared_doc: false,
-                        span: syntax_pos::DUMMY_SP,
+                        span: DUMMY_SP,
                     };
                     attr::mark_known(&attr);
                     attrs.push(attr);
@@ -7013,7 +6476,7 @@ fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo>
                 Ok((id, ItemKind::Mod(module), Some(attrs)))
             } else {
                 let placeholder = ast::Mod {
-                    inner: syntax_pos::DUMMY_SP,
+                    inner: DUMMY_SP,
                     items: Vec::new(),
                     inline: false
                 };
index e5361b2db4e9e4b29cb529257c90b2dcea4d6435..47185df8d616563a0cf23bf24372cb5ad32d9a71 100644 (file)
@@ -391,9 +391,9 @@ pub fn is_ident(&self) -> bool {
 
     /// Returns `true` if the token is a identifier whose name is the given
     /// string slice.
-    crate fn is_ident_named(&self, name: &str) -> bool {
+    crate fn is_ident_named(&self, name: Symbol) -> bool {
         match self.ident() {
-            Some((ident, _)) => ident.as_str() == name,
+            Some((ident, _)) => ident.name == name,
             None => false
         }
     }
index 398705857bb7e91351f2c668fb6867af9438cca6..eea94f0d19458fa44146fa960121ad0519bc1ec4 100644 (file)
@@ -20,9 +20,7 @@ fn ignored_span(sp: Span, edition: Edition) -> Span {
         call_site: DUMMY_SP,
         def_site: None,
         format: MacroAttribute(Symbol::intern("std_inject")),
-        allow_internal_unstable: Some(vec![
-            Symbol::intern("prelude_import"),
-        ].into()),
+        allow_internal_unstable: Some(vec![sym::prelude_import].into()),
         allow_internal_unsafe: false,
         local_inner_macros: false,
         edition,
@@ -98,7 +96,7 @@ pub fn maybe_inject_crates_ref(
     krate.module.items.insert(0, P(ast::Item {
         attrs: vec![ast::Attribute {
             style: ast::AttrStyle::Outer,
-            path: ast::Path::from_ident(ast::Ident::new(Symbol::intern("prelude_import"), span)),
+            path: ast::Path::from_ident(ast::Ident::new(sym::prelude_import, span)),
             tokens: TokenStream::empty(),
             id: attr::mk_attr_id(),
             is_sugared_doc: false,
index d1e11da4e7cc26175b4270c8b9b376db03708f4e..1998ec19f13bf7033e28618d3ca8afc482502d83 100644 (file)
@@ -283,12 +283,8 @@ fn generate_test_harness(sess: &ParseSess,
     mark.set_expn_info(ExpnInfo {
         call_site: DUMMY_SP,
         def_site: None,
-        format: MacroAttribute(Symbol::intern("test_case")),
-        allow_internal_unstable: Some(vec![
-            Symbol::intern("main"),
-            Symbol::intern("test"),
-            Symbol::intern("rustc_attrs"),
-        ].into()),
+        format: MacroAttribute(sym::test_case),
+        allow_internal_unstable: Some(vec![sym::main, sym::test, sym::rustc_attrs].into()),
         allow_internal_unsafe: false,
         local_inner_macros: false,
         edition: sess.edition,
@@ -347,14 +343,14 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     let call_test_main = ecx.stmt_expr(call_test_main);
 
     // #![main]
-    let main_meta = ecx.meta_word(sp, Symbol::intern("main"));
+    let main_meta = ecx.meta_word(sp, sym::main);
     let main_attr = ecx.attribute(sp, main_meta);
 
     // extern crate test as test_gensym
     let test_extern_stmt = ecx.stmt_item(sp, ecx.item(sp,
         test_id,
         vec![],
-        ast::ItemKind::ExternCrate(Some(Symbol::intern("test")))
+        ast::ItemKind::ExternCrate(Some(sym::test))
     ));
 
     // pub fn main() { ... }
index 79efc6bf689c4c8b75f09fa1178ccc124124a67a..397fb45513c15a08529608781d2c15b729c14e32 100644 (file)
@@ -49,6 +49,28 @@ pub enum TokenTree {
     Delimited(DelimSpan, DelimToken, TokenStream),
 }
 
+// Ensure all fields of `TokenTree` is `Send` and `Sync`.
+#[cfg(parallel_compiler)]
+fn _dummy()
+where
+    Span: Send + Sync,
+    token::Token: Send + Sync,
+    DelimSpan: Send + Sync,
+    DelimToken: Send + Sync,
+    TokenStream: Send + Sync,
+{}
+
+// These are safe since we ensure that they hold for all fields in the `_dummy` function.
+//
+// These impls are only here because the compiler takes forever to compute the Send and Sync
+// bounds without them.
+// FIXME: Remove these impls when the compiler can compute the bounds quickly again.
+// See https://github.com/rust-lang/rust/issues/60846
+#[cfg(parallel_compiler)]
+unsafe impl Send for TokenTree {}
+#[cfg(parallel_compiler)]
+unsafe impl Sync for TokenTree {}
+
 impl TokenTree {
     /// Use this token tree as a matcher to parse given tts.
     pub fn parse(cx: &base::ExtCtxt<'_>, mtch: &[quoted::TokenTree], tts: TokenStream)
index b8e89c3ecf8762191b77c84cd88ca3416f98a956..4d7083c1a790b955abbef10861be3c7f156d0c80 100644 (file)
@@ -11,7 +11,7 @@
 use syntax::feature_gate;
 use syntax::parse::{self, token};
 use syntax::ptr::P;
-use syntax::symbol::{Symbol, sym};
+use syntax::symbol::{kw, sym, Symbol};
 use syntax::ast::AsmDialect;
 use syntax_pos::Span;
 use syntax::tokenstream;
@@ -93,7 +93,7 @@ fn parse_inline_asm<'a>(
         })
         .unwrap_or(tts.len());
     let mut p = cx.new_parser_from_tts(&tts[first_colon..]);
-    let mut asm = Symbol::intern("");
+    let mut asm = kw::Invalid;
     let mut asm_str_style = None;
     let mut outputs = Vec::new();
     let mut inputs = Vec::new();
@@ -138,7 +138,11 @@ fn parse_inline_asm<'a>(
                 if p2.token != token::Eof {
                     let mut extra_tts = p2.parse_all_token_trees()?;
                     extra_tts.extend(tts[first_colon..].iter().cloned());
-                    p = parse::stream_to_parser(cx.parse_sess, extra_tts.into_iter().collect());
+                    p = parse::stream_to_parser(
+                        cx.parse_sess,
+                        extra_tts.into_iter().collect(),
+                        Some("inline assembly"),
+                    );
                 }
 
                 asm = s;
index a11cd9c6f761dbab4b714eb77e5b73f46381c1d8..13342c8e28e2ff3bf4d7e22c9ed0b6c2c6bffeeb 100644 (file)
@@ -8,7 +8,7 @@
 use syntax::parse::parser::Parser;
 use syntax::print::pprust;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{sym, Symbol};
 use syntax::tokenstream::{TokenStream, TokenTree};
 use syntax_pos::{Span, DUMMY_SP};
 
@@ -27,7 +27,7 @@ pub fn expand_assert<'cx>(
 
     let sp = sp.apply_mark(cx.current_expansion.mark);
     let panic_call = Mac_ {
-        path: Path::from_ident(Ident::new(Symbol::intern("panic"), sp)),
+        path: Path::from_ident(Ident::new(sym::panic, sp)),
         tts: custom_message.unwrap_or_else(|| {
             TokenStream::from(TokenTree::Token(
                 DUMMY_SP,
index a39e0a6e9730380e74a890636281fb9a33208ea4..b3b6328e2ca7306536dff1787ca2ac07fcd8d2bb 100644 (file)
@@ -7,7 +7,7 @@
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
-use syntax::symbol::{Symbol, kw, sym};
+use syntax::symbol::{kw, sym, Symbol};
 use syntax_pos::Span;
 
 pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>,
@@ -76,7 +76,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>,
         _ => cx.span_bug(span, "#[derive(Clone)] on trait item or impl item"),
     }
 
-    let inline = cx.meta_word(span, Symbol::intern("inline"));
+    let inline = cx.meta_word(span, sym::inline);
     let attrs = vec![cx.attribute(span, inline)];
     let trait_def = TraitDef {
         span,
@@ -115,7 +115,7 @@ fn assert_ty_bounds(cx: &mut ExtCtxt<'_>, stmts: &mut Vec<ast::Stmt>,
         // set the expn ID so we can use the unstable struct.
         let span = span.with_ctxt(cx.backtrace());
         let assert_path = cx.path_all(span, true,
-                                        cx.std_path(&["clone", helper_name]),
+                                        cx.std_path(&[sym::clone, Symbol::intern(helper_name)]),
                                         vec![GenericArg::Type(ty)], vec![]);
         stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path)));
     }
@@ -157,7 +157,7 @@ fn cs_clone(name: &str,
             -> P<Expr> {
     let ctor_path;
     let all_fields;
-    let fn_path = cx.std_path(&["clone", "Clone", "clone"]);
+    let fn_path = cx.std_path(&[sym::clone, sym::Clone, sym::clone]);
     let subcall = |cx: &mut ExtCtxt<'_>, field: &FieldInfo<'_>| {
         let args = vec![cx.expr_addr_of(field.span, field.self_.clone())];
         cx.expr_call_global(field.span, fn_path.clone(), args)
index a1035ff641fa191fdf15b2b87ec89ed8922d5d5b..1d981e0ff7906ba8b4788c6bb9cbcdbfa84c19d6 100644 (file)
@@ -6,7 +6,7 @@
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{sym, Symbol};
 use syntax_pos::Span;
 
 pub fn expand_deriving_eq(cx: &mut ExtCtxt<'_>,
@@ -14,9 +14,9 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt<'_>,
                           mitem: &MetaItem,
                           item: &Annotatable,
                           push: &mut dyn FnMut(Annotatable)) {
-    let inline = cx.meta_word(span, Symbol::intern("inline"));
-    let hidden = cx.meta_list_item_word(span, Symbol::intern("hidden"));
-    let doc = cx.meta_list(span, Symbol::intern("doc"), vec![hidden]);
+    let inline = cx.meta_word(span, sym::inline);
+    let hidden = cx.meta_list_item_word(span, sym::hidden);
+    let doc = cx.meta_list(span, sym::doc, vec![hidden]);
     let attrs = vec![cx.attribute(span, inline), cx.attribute(span, doc)];
     let trait_def = TraitDef {
         span,
@@ -54,7 +54,7 @@ fn assert_ty_bounds(cx: &mut ExtCtxt<'_>, stmts: &mut Vec<ast::Stmt>,
         // set the expn ID so we can use the unstable struct.
         let span = span.with_ctxt(cx.backtrace());
         let assert_path = cx.path_all(span, true,
-                                        cx.std_path(&["cmp", helper_name]),
+                                        cx.std_path(&[sym::cmp, Symbol::intern(helper_name)]),
                                         vec![GenericArg::Type(ty)], vec![]);
         stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path)));
     }
index e4f939c151f3ef1564b3e35de6ca619fc04a54de..b25a9e4c50fbe9e87735ede37ae3a3b03e094e3c 100644 (file)
@@ -6,7 +6,7 @@
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 pub fn expand_deriving_ord(cx: &mut ExtCtxt<'_>,
@@ -14,7 +14,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt<'_>,
                            mitem: &MetaItem,
                            item: &Annotatable,
                            push: &mut dyn FnMut(Annotatable)) {
-    let inline = cx.meta_word(span, Symbol::intern("inline"));
+    let inline = cx.meta_word(span, sym::inline);
     let attrs = vec![cx.attribute(span, inline)];
     let trait_def = TraitDef {
         span,
@@ -55,9 +55,9 @@ pub fn ordering_collapsed(cx: &mut ExtCtxt<'_>,
 
 pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
     let test_id = cx.ident_of("cmp").gensym();
-    let equals_path = cx.path_global(span, cx.std_path(&["cmp", "Ordering", "Equal"]));
+    let equals_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
 
-    let cmp_path = cx.std_path(&["cmp", "Ord", "cmp"]);
+    let cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]);
 
     // Builds:
     //
index 07026ae37391997aa3f723f59830904194a22bf4..6172f27261ecf730971d8d11994208d7dc4cf84c 100644 (file)
@@ -6,7 +6,7 @@
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt<'_>,
@@ -62,7 +62,7 @@ fn cs_ne(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr>
 
     macro_rules! md {
         ($name:expr, $f:ident) => { {
-            let inline = cx.meta_word(span, Symbol::intern("inline"));
+            let inline = cx.meta_word(span, sym::inline);
             let attrs = vec![cx.attribute(span, inline)];
             MethodDef {
                 name: $name,
index e99abeb118ea2f116194edf46a96efcc95f4d196..3980741f252dd947e92e15fc7644405728c97bdf 100644 (file)
@@ -8,7 +8,7 @@
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{sym, Symbol};
 use syntax_pos::Span;
 
 pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt<'_>,
@@ -18,7 +18,7 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt<'_>,
                                    push: &mut dyn FnMut(Annotatable)) {
     macro_rules! md {
         ($name:expr, $op:expr, $equal:expr) => { {
-            let inline = cx.meta_word(span, Symbol::intern("inline"));
+            let inline = cx.meta_word(span, sym::inline);
             let attrs = vec![cx.attribute(span, inline)];
             MethodDef {
                 name: $name,
@@ -42,7 +42,7 @@ macro_rules! md {
                                     vec![Box::new(ordering_ty)],
                                     PathKind::Std));
 
-    let inline = cx.meta_word(span, Symbol::intern("inline"));
+    let inline = cx.meta_word(span, sym::inline);
     let attrs = vec![cx.attribute(span, inline)];
 
     let partial_cmp_def = MethodDef {
@@ -114,11 +114,11 @@ pub fn some_ordering_collapsed(cx: &mut ExtCtxt<'_>,
 
 pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
     let test_id = cx.ident_of("cmp").gensym();
-    let ordering = cx.path_global(span, cx.std_path(&["cmp", "Ordering", "Equal"]));
+    let ordering = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
     let ordering_expr = cx.expr_path(ordering.clone());
     let equals_expr = cx.expr_some(span, ordering_expr);
 
-    let partial_cmp_path = cx.std_path(&["cmp", "PartialOrd", "partial_cmp"]);
+    let partial_cmp_path = cx.std_path(&[sym::cmp, sym::PartialOrd, sym::partial_cmp]);
 
     // Builds:
     //
@@ -188,7 +188,8 @@ fn cs_op(less: bool,
          span: Span,
          substr: &Substructure<'_>) -> P<Expr> {
     let ordering_path = |cx: &mut ExtCtxt<'_>, name: &str| {
-        cx.expr_path(cx.path_global(span, cx.std_path(&["cmp", "Ordering", name])))
+        cx.expr_path(cx.path_global(
+            span, cx.std_path(&[sym::cmp, sym::Ordering, Symbol::intern(name)])))
     };
 
     let par_cmp = |cx: &mut ExtCtxt<'_>, span, self_f: P<Expr>, other_fs: &[P<Expr>], default| {
@@ -198,9 +199,9 @@ fn cs_op(less: bool,
         };
 
         // `PartialOrd::partial_cmp(self.fi, other.fi)`
-        let cmp_path = cx.expr_path(cx.path_global(span, cx.std_path(&["cmp",
-                                                                       "PartialOrd",
-                                                                       "partial_cmp"])));
+        let cmp_path = cx.expr_path(cx.path_global(span, cx.std_path(&[sym::cmp,
+                                                                       sym::PartialOrd,
+                                                                       sym::partial_cmp])));
         let cmp = cx.expr_call(span,
                                cmp_path,
                                vec![cx.expr_addr_of(span, self_f),
@@ -208,9 +209,9 @@ fn cs_op(less: bool,
 
         let default = ordering_path(cx, default);
         // `Option::unwrap_or(_, Ordering::Equal)`
-        let unwrap_path = cx.expr_path(cx.path_global(span, cx.std_path(&["option",
-                                                                          "Option",
-                                                                          "unwrap_or"])));
+        let unwrap_path = cx.expr_path(cx.path_global(span, cx.std_path(&[sym::option,
+                                                                          sym::Option,
+                                                                          sym::unwrap_or])));
         cx.expr_call(span, unwrap_path, vec![cmp, default])
     };
 
@@ -256,9 +257,9 @@ fn cs_op(less: bool,
 
             // `Ordering::then_with(Option::unwrap_or(..), ..)`
             let then_with_path = cx.expr_path(cx.path_global(span,
-                                                             cx.std_path(&["cmp",
-                                                                           "Ordering",
-                                                                           "then_with"])));
+                                                             cx.std_path(&[sym::cmp,
+                                                                           sym::Ordering,
+                                                                           sym::then_with])));
             cx.expr_call(span, then_with_path, vec![par_cmp, cx.lambda0(span, subexpr)])
         },
         |cx, args| {
index e73110717e97968209e3b82eb5ab1ceeddd68328..975d96951dc5571d54d8090ca80b1362e5ecb44d 100644 (file)
@@ -89,7 +89,7 @@ fn expand(&self,
         let error_count_before = ecx.parse_sess.span_diagnostic.err_count();
         let msg = "proc-macro derive produced unparseable tokens";
 
-        let mut parser = parse::stream_to_parser(ecx.parse_sess, stream);
+        let mut parser = parse::stream_to_parser(ecx.parse_sess, stream, Some("proc-macro derive"));
         let mut items = vec![];
 
         loop {
index 2fc1fc9140dc38ce096b3f0b4cb12b74d928ba0f..dec4c2dfc3b5eb50ccfdf05b8a84d6540bbf8df8 100644 (file)
@@ -9,6 +9,7 @@
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
+use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, Span};
 
 pub fn expand_deriving_debug(cx: &mut ExtCtxt<'_>,
@@ -82,7 +83,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
 
                 let expr = cx.expr_method_call(span,
                                                 builder_expr.clone(),
-                                                Ident::from_str("field"),
+                                                Ident::with_empty_ctxt(sym::field),
                                                 vec![field]);
 
                 // Use `let _ = expr;` to avoid triggering the
@@ -106,7 +107,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
                 let field = cx.expr_addr_of(field.span, field);
                 let expr = cx.expr_method_call(span,
                                                 builder_expr.clone(),
-                                                Ident::from_str("field"),
+                                                Ident::with_empty_ctxt(sym::field),
                                                 vec![name, field]);
                 stmts.push(stmt_let_undescore(cx, span, expr));
             }
index 6db0a29165a4a05e24e082fc2e71b42bd4de56a9..fd8e87e2fefd17fc0674a7f096d4deb45e58a2ff 100644 (file)
@@ -6,7 +6,7 @@
 use syntax::ext::base::{Annotatable, DummyResult, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{kw, sym};
 use syntax::span_err;
 use syntax_pos::Span;
 
@@ -15,7 +15,7 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt<'_>,
                                mitem: &MetaItem,
                                item: &Annotatable,
                                push: &mut dyn FnMut(Annotatable)) {
-    let inline = cx.meta_word(span, Symbol::intern("inline"));
+    let inline = cx.meta_word(span, sym::inline);
     let attrs = vec![cx.attribute(span, inline)];
     let trait_def = TraitDef {
         span,
@@ -47,7 +47,8 @@ fn default_substructure(cx: &mut ExtCtxt<'_>,
                         trait_span: Span,
                         substr: &Substructure<'_>)
                         -> P<Expr> {
-    let default_ident = cx.std_path(&["default", "Default", "default"]);
+    // Note that `kw::Default` is "default" and `sym::Default` is "Default"!
+    let default_ident = cx.std_path(&[kw::Default, sym::Default, kw::Default]);
     let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new());
 
     return match *substr.fields {
index 0689eb50f9ca2b65f4c53ec5dfe1f9f3a0bdb88e..7e3082a87d99252b532824d96d10a95115168091 100644 (file)
@@ -666,14 +666,13 @@ fn create_derived_impl(&self,
         let self_type = cx.ty_path(path);
 
         let attr = cx.attribute(self.span,
-                                cx.meta_word(self.span,
-                                             Symbol::intern("automatically_derived")));
+                                cx.meta_word(self.span, sym::automatically_derived));
         // Just mark it now since we know that it'll end up used downstream
         attr::mark_used(&attr);
         let opt_trait_ref = Some(trait_ref);
         let unused_qual = {
             let word = cx.meta_list_item_word(self.span, Symbol::intern("unused_qualifications"));
-            cx.attribute(self.span, cx.meta_list(self.span, Symbol::intern("allow"), vec![word]))
+            cx.attribute(self.span, cx.meta_list(self.span, sym::allow, vec![word]))
         };
 
         let mut a = vec![attr, unused_qual];
index 0d4f2ddc3be7b02fd8267cd34d410297b1719ba7..e7f99d4578226382ea4c67f501c4488433bde4ff 100644 (file)
@@ -6,6 +6,7 @@
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
+use syntax::symbol::sym;
 use syntax_pos::Span;
 
 pub fn expand_deriving_hash(cx: &mut ExtCtxt<'_>,
@@ -60,7 +61,7 @@ fn hash_substructure(cx: &mut ExtCtxt<'_>, trait_span: Span, substr: &Substructu
     };
     let call_hash = |span, thing_expr| {
         let hash_path = {
-            let strs = cx.std_path(&["hash", "Hash", "hash"]);
+            let strs = cx.std_path(&[sym::hash, sym::Hash, sym::hash]);
 
             cx.expr_path(cx.path_global(span, strs))
         };
index c27de692d887cc050114ac6d7d4d3ec69410817c..ac41f30e6b39fafd57748a06c5010d50588bda8d 100644 (file)
@@ -145,12 +145,12 @@ fn call_intrinsic(cx: &ExtCtxt<'_>,
         span = span.with_ctxt(cx.backtrace());
     } else { // Avoid instability errors with user defined curstom derives, cc #36316
         let mut info = cx.current_expansion.mark.expn_info().unwrap();
-        info.allow_internal_unstable = Some(vec![Symbol::intern("core_intrinsics")].into());
+        info.allow_internal_unstable = Some(vec![sym::core_intrinsics].into());
         let mark = Mark::fresh(Mark::root());
         mark.set_expn_info(info);
         span = span.with_ctxt(SyntaxContext::empty().apply_mark(mark));
     }
-    let path = cx.std_path(&["intrinsics", intrinsic]);
+    let path = cx.std_path(&[sym::intrinsics, Symbol::intern(intrinsic)]);
     let call = cx.expr_call_global(span, path, args);
 
     cx.expr_block(P(ast::Block {
index 72a66ae3845d0c53032a04a0a22364544c611955..b7f2ecf0f9137b9931b40aecca232d8df3a18f5f 100644 (file)
@@ -27,7 +27,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
             let lt = cx.lifetime(sp, Ident::with_empty_ctxt(kw::StaticLifetime));
             cx.expr_path(cx.path_all(sp,
                                      true,
-                                     cx.std_path(&["option", "Option", "None"]),
+                                     cx.std_path(&[sym::option, sym::Option, sym::None]),
                                      vec![GenericArg::Type(cx.ty_rptr(sp,
                                                      cx.ty_ident(sp,
                                                                  Ident::with_empty_ctxt(sym::str)),
@@ -37,7 +37,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
         }
         Ok(s) => {
             cx.expr_call_global(sp,
-                                cx.std_path(&["option", "Option", "Some"]),
+                                cx.std_path(&[sym::option, sym::Option, sym::Some]),
                                 vec![cx.expr_str(sp, Symbol::intern(&s))])
         }
     };
index 9e54c0634b666b43a4bae4f333f27bc8fe774646..b5be45547cfbe3149545aa775736162bdef7ac7b 100644 (file)
@@ -387,7 +387,7 @@ fn build_index_map(&mut self) {
     }
 
     fn rtpath(ecx: &ExtCtxt<'_>, s: &str) -> Vec<ast::Ident> {
-        ecx.std_path(&["fmt", "rt", "v1", s])
+        ecx.std_path(&[sym::fmt, sym::rt, sym::v1, Symbol::intern(s)])
     }
 
     fn build_count(&self, c: parse::Count<'_>) -> P<ast::Expr> {
@@ -644,7 +644,7 @@ fn into_expr(self) -> P<ast::Expr> {
             ("new_v1_formatted", vec![pieces, args_slice, fmt])
         };
 
-        let path = self.ecx.std_path(&["fmt", "Arguments", fn_name]);
+        let path = self.ecx.std_path(&[sym::fmt, sym::Arguments, Symbol::intern(fn_name)]);
         self.ecx.expr_call_global(self.macsp, path, fn_args)
     }
 
@@ -675,14 +675,14 @@ fn format_arg(ecx: &ExtCtxt<'_>,
                 }
             }
             Count => {
-                let path = ecx.std_path(&["fmt", "ArgumentV1", "from_usize"]);
+                let path = ecx.std_path(&[sym::fmt, sym::ArgumentV1, sym::from_usize]);
                 return ecx.expr_call_global(macsp, path, vec![arg]);
             }
         };
 
-        let path = ecx.std_path(&["fmt", trait_, "fmt"]);
+        let path = ecx.std_path(&[sym::fmt, Symbol::intern(trait_), sym::fmt]);
         let format_fn = ecx.path_global(sp, path);
-        let path = ecx.std_path(&["fmt", "ArgumentV1", "new"]);
+        let path = ecx.std_path(&[sym::fmt, sym::ArgumentV1, sym::new]);
         ecx.expr_call_global(macsp, path, vec![arg, ecx.expr_path(format_fn)])
     }
 }
index e5fc7aab61db41c57f995805e9ff512546223511..fc0015442750123062ad42535a0fca8a2ae18238 100644 (file)
@@ -42,8 +42,8 @@
 use rustc_data_structures::sync::Lrc;
 use syntax::ast;
 use syntax::ext::base::{MacroExpanderFn, NormalTT, NamedSyntaxExtension, MultiModifier};
-use syntax::symbol::Symbol;
 use syntax::edition::Edition;
+use syntax::symbol::{sym, Symbol};
 
 pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
                          user_exts: Vec<NamedSyntaxExtension>,
@@ -93,30 +93,26 @@ macro_rules! register {
         assert: assert::expand_assert,
     }
 
-    register(Symbol::intern("test_case"), MultiModifier(Box::new(test_case::expand)));
-    register(Symbol::intern("test"), MultiModifier(Box::new(test::expand_test)));
-    register(Symbol::intern("bench"), MultiModifier(Box::new(test::expand_bench)));
+    register(sym::test_case, MultiModifier(Box::new(test_case::expand)));
+    register(sym::test, MultiModifier(Box::new(test::expand_test)));
+    register(sym::bench, MultiModifier(Box::new(test::expand_bench)));
 
     // format_args uses `unstable` things internally.
     register(Symbol::intern("format_args"),
              NormalTT {
                 expander: Box::new(format::expand_format_args),
                 def_info: None,
-                allow_internal_unstable: Some(vec![
-                    Symbol::intern("fmt_internals"),
-                ].into()),
+                allow_internal_unstable: Some(vec![sym::fmt_internals].into()),
                 allow_internal_unsafe: false,
                 local_inner_macros: false,
                 unstable_feature: None,
                 edition,
             });
-    register(Symbol::intern("format_args_nl"),
+    register(sym::format_args_nl,
              NormalTT {
                  expander: Box::new(format::expand_format_args_nl),
                  def_info: None,
-                 allow_internal_unstable: Some(vec![
-                     Symbol::intern("fmt_internals"),
-                 ].into()),
+                 allow_internal_unstable: Some(vec![sym::fmt_internals].into()),
                  allow_internal_unsafe: false,
                  local_inner_macros: false,
                  unstable_feature: None,
index a485bb19808db2a90a7495f73d7a62332673a607..5b8f4f35f2dd10f9f57d39a2617b8d4d887a0e10 100644 (file)
@@ -351,9 +351,9 @@ fn mk_decls(
     mark.set_expn_info(ExpnInfo {
         call_site: DUMMY_SP,
         def_site: None,
-        format: MacroAttribute(Symbol::intern("proc_macro")),
+        format: MacroAttribute(sym::proc_macro),
         allow_internal_unstable: Some(vec![
-            Symbol::intern("rustc_attrs"),
+            sym::rustc_attrs,
             Symbol::intern("proc_macro_internals"),
         ].into()),
         allow_internal_unsafe: false,
@@ -420,7 +420,7 @@ fn mk_decls(
         ast::Mutability::Immutable,
         cx.expr_vec_slice(span, decls),
     ).map(|mut i| {
-        let attr = cx.meta_word(span, Symbol::intern("rustc_proc_macro_decls"));
+        let attr = cx.meta_word(span, sym::rustc_proc_macro_decls);
         i.attrs.push(cx.attribute(span, attr));
         i.vis = respan(span, ast::VisibilityKind::Public);
         i
index beac92894b77ad7b0e803860cf515b6e3bfd21d9..53730d2d080223010ac2892edfc86fd94f9af206 100644 (file)
@@ -14,7 +14,7 @@
 use syntax::parse::{self, token, ParseSess};
 use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
 use syntax_pos::hygiene::{SyntaxContext, Transparency};
-use syntax_pos::symbol::{kw, Symbol};
+use syntax_pos::symbol::{kw, sym, Symbol};
 use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
 
 trait FromInternal<T> {
@@ -159,7 +159,7 @@ macro_rules! op {
                     escaped.extend(ch.escape_debug());
                 }
                 let stream = vec![
-                    Ident(ast::Ident::new(Symbol::intern("doc"), span), false),
+                    Ident(ast::Ident::new(sym::doc, span), false),
                     Eq,
                     Token::lit(token::Str, Symbol::intern(&escaped), None),
                 ]
index 8ee61a3f67f591b890b728b20266f636e0a47a82..c20dc6cb2d7cdbb9ecd9f297384f2c7e7d926538 100644 (file)
@@ -65,11 +65,8 @@ pub fn expand_test_or_bench(
         mark.set_expn_info(ExpnInfo {
             call_site: DUMMY_SP,
             def_site: None,
-            format: MacroAttribute(Symbol::intern("test")),
-            allow_internal_unstable: Some(vec![
-                Symbol::intern("rustc_attrs"),
-                Symbol::intern("test"),
-            ].into()),
+            format: MacroAttribute(sym::test),
+            allow_internal_unstable: Some(vec![sym::rustc_attrs, sym::test].into()),
             allow_internal_unsafe: false,
             local_inner_macros: false,
             edition: cx.parse_sess.edition,
@@ -130,11 +127,11 @@ pub fn expand_test_or_bench(
     let mut test_const = cx.item(sp, ast::Ident::new(item.ident.name, sp).gensym(),
         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"))
+            cx.attribute(attr_sp, cx.meta_list(attr_sp, sym::cfg, vec![
+                cx.meta_list_item_word(attr_sp, sym::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, sym::rustc_test_marker)),
         ],
         // const $ident: test::TestDescAndFn =
         ast::ItemKind::Const(cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
@@ -180,7 +177,7 @@ pub fn expand_test_or_bench(
     let test_extern = cx.item(sp,
         test_id,
         vec![],
-        ast::ItemKind::ExternCrate(Some(Symbol::intern("test")))
+        ast::ItemKind::ExternCrate(Some(sym::test))
     );
 
     log::debug!("Synthetic test item:\n{}\n", pprust::item_to_string(&test_const));
index 5b1ae167ce31543850a1475dcf5f9379536baaa6..cffecdd0f18e79fdb02734b112b205b028a1e84b 100644 (file)
@@ -14,7 +14,7 @@
 use syntax::ext::hygiene::{Mark, SyntaxContext};
 use syntax::ast;
 use syntax::source_map::respan;
-use syntax::symbol::{Symbol, sym};
+use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, Span};
 use syntax::source_map::{ExpnInfo, MacroAttribute};
 use syntax::feature_gate;
@@ -40,11 +40,8 @@ pub fn expand(
         mark.set_expn_info(ExpnInfo {
             call_site: DUMMY_SP,
             def_site: None,
-            format: MacroAttribute(Symbol::intern("test_case")),
-            allow_internal_unstable: Some(vec![
-                Symbol::intern("test"),
-                Symbol::intern("rustc_attrs"),
-            ].into()),
+            format: MacroAttribute(sym::test_case),
+            allow_internal_unstable: Some(vec![sym::test, sym::rustc_attrs].into()),
             allow_internal_unsafe: false,
             local_inner_macros: false,
             edition: ecx.parse_sess.edition,
@@ -59,7 +56,7 @@ pub fn expand(
         item.ident = item.ident.gensym();
         item.attrs.push(
             ecx.attribute(sp,
-                ecx.meta_word(sp, Symbol::intern("rustc_test_marker")))
+                ecx.meta_word(sp, sym::rustc_test_marker))
         );
         item
     });
index b1e1a056db4adaa736f8cd057adc33bc520c8835..8847e94127be6db5f6439dd47037bdbb2d1821be 100644 (file)
@@ -9,10 +9,10 @@
 use rustc_macros::symbols;
 use serialize::{Decodable, Decoder, Encodable, Encoder};
 
-use std::fmt;
-use std::str;
 use std::cmp::{PartialEq, Ordering, PartialOrd, Ord};
+use std::fmt;
 use std::hash::{Hash, Hasher};
+use std::str;
 
 use crate::hygiene::SyntaxContext;
 use crate::{Span, DUMMY_SP, GLOBALS};
     // Symbols that can be referred to with syntax_pos::sym::*. The symbol is
     // the stringified identifier unless otherwise specified (e.g.
     // `proc_dash_macro` represents "proc-macro").
+    //
+    // As well as the symbols listed, there are symbols for the the strings
+    // "0", "1", ..., "9", which are accessible via `sym::integer`.
     Symbols {
         aarch64_target_feature,
         abi,
         allow_internal_unstable,
         allow_internal_unstable_backcompat_hack,
         always,
+        and,
         any,
         arbitrary_self_types,
+        Arguments,
+        ArgumentV1,
         arm_target_feature,
         asm,
         associated_consts,
         automatically_derived,
         avx512_target_feature,
         await_macro,
+        begin_panic,
+        bench,
         bin,
         bind_by_move_pattern_guards,
         block,
         cfg_target_thread_local,
         cfg_target_vendor,
         clone,
+        Clone,
         clone_closures,
         clone_from,
         closure_to_fn_coercion,
+        cmp,
         cmpxchg16b_target_feature,
         cold,
         compile_error,
         const_raw_ptr_to_usize_cast,
         const_transmute,
         contents,
+        context,
         convert,
         copy_closures,
         core,
         custom_test_frameworks,
         c_variadic,
         decl_macro,
+        Default,
         default_lib_allocator,
         default_type_parameter_fallback,
         default_type_params,
         deny,
         deprecated,
+        deref,
+        deref_mut,
         derive,
         doc,
         doc_alias,
         enable,
         err,
         Err,
+        Equal,
         except,
         exclusive_range_pattern,
         exhaustive_integer_patterns,
         existential_type,
         expected,
         export_name,
+        expr,
         extern_absolute_paths,
         external_doc,
         extern_crate_item_prelude,
         f64,
         feature,
         ffi_returns_twice,
+        field,
         field_init_shorthand,
         file,
+        fmt,
+        fmt_internals,
         fn_must_use,
         forbid,
         format_args_nl,
         from_error,
         from_generator,
         from_ok,
+        from_usize,
         fundamental,
         future,
         Future,
+        FxHashSet,
+        FxHashMap,
         gen_future,
         generators,
         generic_associated_types,
         global_allocator,
         global_asm,
         globs,
+        hash,
+        Hash,
+        HashSet,
+        HashMap,
         hexagon_target_feature,
         hidden,
         homogeneous_aggregate,
         impl_header_lifetime_elision,
         impl_trait_in_bindings,
         import_shadowing,
+        index,
+        index_mut,
         in_band_lifetimes,
         include,
         inclusive_range_syntax,
         issue,
         issue_5723_bootstrap,
         issue_tracker_base_url,
+        item,
         item_like_imports,
         iter,
         Iterator,
         lang,
         lang_items,
         lib,
+        lifetime,
         link,
         linkage,
         link_args,
         link_name,
         link_section,
         lint_reasons,
+        literal,
         local_inner_macros,
         log_syntax,
         loop_break_value,
         negate_unsigned,
         never,
         never_type,
+        new,
         next,
         __next,
         nll,
         option,
         Option,
         opt_out_copy,
+        or,
+        Ord,
+        Ordering,
         Output,
         overlapping_marker_traits,
         packed,
+        panic,
         panic_handler,
         panic_impl,
         panic_implementation,
         panic_runtime,
+        partial_cmp,
+        PartialOrd,
         passes,
+        pat,
         path,
         pattern_parentheses,
         Pending,
         proc_dash_macro: "proc-macro",
         proc_macro,
         proc_macro_attribute,
+        proc_macro_def_site,
         proc_macro_derive,
         proc_macro_expr,
         proc_macro_gen,
         Result,
         Return,
         rlib,
+        rt,
         rtm_target_feature,
         rust,
         rust_2015_preview,
         rust_2018_preview,
         rust_begin_unwind,
+        rustc,
         rustc_allocator_nounwind,
         rustc_allow_const_fn_ptr,
         rustc_args_required_const,
         static_recursion,
         std,
         str,
+        stmt,
         stmt_expr_attributes,
         stop_after_dataflow,
         struct_field_attributes,
         struct_inherit,
         structural_match,
         struct_variant,
+        sty,
         suggestion,
         target_feature,
         target_has_atomic,
         test,
         test_2018_feature,
         test_accepted_feature,
+        test_case,
         test_removed_feature,
         test_runner,
+        then_with,
         thread_local,
         tool_attributes,
         tool_lints,
         Try,
         try_blocks,
         try_trait,
+        tt,
         tuple_indexing,
+        Ty,
         ty,
+        TyCtxt,
+        TyKind,
         type_alias_enum_variants,
         type_ascription,
         type_length_limit,
         untagged_unions,
         unwind,
         unwind_attributes,
+        unwrap_or,
         used,
         use_extern_macros,
         use_nested_groups,
         usize,
         v1,
         val,
+        vec,
+        Vec,
         vis,
         visible_private_types,
         volatile,
@@ -866,20 +919,13 @@ pub struct Interner {
 }
 
 impl Interner {
-    fn prefill(init: &[&str]) -> Self {
-        let mut this = Interner::default();
-        this.names.reserve(init.len());
-        this.strings.reserve(init.len());
-
-        // We can't allocate empty strings in the arena, so handle this here.
-        assert!(kw::Invalid.as_u32() == 0 && init[0].is_empty());
-        this.names.insert("", kw::Invalid);
-        this.strings.push("");
-
-        for string in &init[1..] {
-            this.intern(string);
+    fn prefill(init: &[&'static str]) -> Self {
+        let symbols = (0 .. init.len() as u32).map(Symbol::new);
+        Interner {
+            strings: init.to_vec(),
+            names: init.iter().copied().zip(symbols).collect(),
+            ..Default::default()
         }
-        this
     }
 
     pub fn intern(&mut self, string: &str) -> Symbol {
@@ -942,8 +988,21 @@ pub mod kw {
 
 // This module has a very short name because it's used a lot.
 pub mod sym {
+    use std::convert::TryInto;
     use super::Symbol;
+
     symbols!();
+
+    // Get the symbol for an integer. The first few non-negative integers each
+    // have a static symbol and therefore are fast.
+    pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
+        if let Result::Ok(idx) = n.try_into() {
+            if let Option::Some(&sym) = digits_array.get(idx) {
+                return sym;
+            }
+        }
+        Symbol::intern(&n.to_string())
+    }
 }
 
 impl Symbol {
index 7f7db2a21251ac8864bcc07faf4a30001c2d6634..8bd0d74cd1710673bd62e8a34d22a1c7118e04f9 100644 (file)
@@ -22,7 +22,6 @@
 #![unstable(feature = "test", issue = "27812")]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))]
 #![feature(asm)]
-#![feature(fnbox)]
 #![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc, rustc_private))]
 #![feature(nll)]
 #![feature(set_stdio)]
@@ -56,7 +55,6 @@
 
 use std::any::Any;
 use std::borrow::Cow;
-use std::boxed::FnBox;
 use std::cmp;
 use std::collections::BTreeMap;
 use std::env;
@@ -174,7 +172,7 @@ pub trait TDynBenchFn: Send {
 pub enum TestFn {
     StaticTestFn(fn()),
     StaticBenchFn(fn(&mut Bencher)),
-    DynTestFn(Box<dyn FnBox() + Send>),
+    DynTestFn(Box<dyn FnOnce() + Send>),
     DynBenchFn(Box<dyn TDynBenchFn + 'static>),
 }
 
@@ -1447,7 +1445,7 @@ fn run_test_inner(
         desc: TestDesc,
         monitor_ch: Sender<MonitorMsg>,
         nocapture: bool,
-        testfn: Box<dyn FnBox() + Send>,
+        testfn: Box<dyn FnOnce() + Send>,
         concurrency: Concurrent,
     ) {
         // Buffer for capturing standard I/O
index 17dba63054eac12f1813935724e4de73e19eaff4..d928d0888a0dfaf34a9580b731feeafb03b5aedd 100644 (file)
@@ -12,7 +12,7 @@
 # source tarball for a stable release you'll likely see `1.x.0` for rustc and
 # `0.x.0` for Cargo where they were released on `date`.
 
-date: 2019-04-11
+date: 2019-05-23
 rustc: beta
 cargo: beta
 
index ee6adfefe3e360b3a0ec00bd878d1fceb2de619e..9f55d8496440561a2b4f0b3bf6c6fd3ebe246129 100644 (file)
@@ -52,7 +52,7 @@ fn drop(&mut self) {
 //         StorageDead(_2);
 //         StorageLive(_4);
 //         _4 = move _1;
-//         _3 = const std::mem::drop(move _4) -> [return: bb5, unwind: bb7];
+//         _3 = const std::mem::drop::<std::boxed::Box<S>>(move _4) -> [return: bb5, unwind: bb7];
 //     }
 //
 //     bb5: {
diff --git a/src/test/mir-opt/byte_slice.rs b/src/test/mir-opt/byte_slice.rs
new file mode 100644 (file)
index 0000000..7edfa3e
--- /dev/null
@@ -0,0 +1,15 @@
+// compile-flags: -Z mir-opt-level=0
+
+fn main() {
+    let x = b"foo";
+    let y = [5u8, b'x'];
+}
+
+// END RUST SOURCE
+// START rustc.main.EraseRegions.after.mir
+// ...
+// _1 = const b"foo";
+// ...
+// _2 = [const 5u8, const 120u8];
+// ...
+// END rustc.main.EraseRegions.after.mir
index 0f79f43ee2df07e8cc07457b4277270133d1e675..a2c5fb920cd30ff872b844aea5807f0c62a79dd3 100644 (file)
@@ -25,7 +25,7 @@ fn y(&self) -> u32 {
 // ...
 // bb0: {
 // ...
-//     _0 = const X::y(move _2) -> bb1;
+//     _0 = const <dyn X as X>::y(move _2) -> bb1;
 // }
 // ...
 // END rustc.test.Inline.after.mir
index 8f9f2535aa5f8c6ddd8f84adb5ec003ca00fb7d8..4ad4311113a3ad0ec39c6d8ca5c67c2aa46a1faa 100644 (file)
@@ -30,7 +30,7 @@ fn main() {
 // ...
 // bb0: {
 // ...
-//     _0 = const X::y(move _2) -> bb1;
+//     _0 = const <dyn X as X>::y(move _2) -> bb1;
 // }
 // ...
 // END rustc.test2.Inline.after.mir
index bf22f00b5055241febebe48805840a533a8cb617..447f3a07a6a98d830df8107ed9b4696bd979f442 100644 (file)
@@ -93,7 +93,7 @@ fn main() {
 //         StorageDead(_3);
 //         StorageLive(_6);
 //         _6 = &_2;
-//         _5 = const std::mem::drop(move _6) -> [return: bb19, unwind: bb4];
+//         _5 = const std::mem::drop::<&i32>(move _6) -> [return: bb19, unwind: bb4];
 //     }
 //     bb19: {
 //         StorageDead(_6);
index 606503151c985911077be563dde3d98a1da4174e..67a55101d829f7a99a69c1deb6d7742bec2bfc7f 100644 (file)
@@ -1,5 +1,6 @@
 // Test that we don't ICE when trying to dump MIR for unusual item types and
 // that we don't create filenames containing `<` and `>`
+// ignore-tidy-linelength
 
 struct A;
 
@@ -68,7 +69,7 @@ fn main() {
 // }
 // bb7: {
 //     _2 = &mut (*_1);
-//     _3 = const std::ops::Drop::drop(move _2) -> [return: bb6, unwind: bb5];
+//     _3 = const <std::vec::Vec<i32> as std::ops::Drop>::drop(move _2) -> [return: bb6, unwind: bb5];
 // }
 // END rustc.ptr-real_drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir
 
diff --git a/src/test/pretty/issue-54752-async-block.rs b/src/test/pretty/issue-54752-async-block.rs
deleted file mode 100644 (file)
index 6930ee1..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#![feature(async_await)]
-#![allow(unused_parens)]
-
-// edition:2018
-// pp-exact
-
-fn main() { let _a = (async  { }); }
diff --git a/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile
new file mode 100644 (file)
index 0000000..59a7d61
--- /dev/null
@@ -0,0 +1,87 @@
+# needs-matching-clang
+
+# This test makes sure that cross-language inlining can be used in conjunction
+# with profile-guided optimization. The test only tests that the whole workflow
+# can be executed without anything crashing. It does not test whether PGO or
+# xLTO have any specific effect on the generated code.
+
+-include ../tools.mk
+
+COMMON_FLAGS=-Copt-level=3 -Ccodegen-units=1
+
+# LLVM doesn't support instrumenting binaries that use SEH:
+# https://bugs.llvm.org/show_bug.cgi?id=41279
+#
+# Things work fine with -Cpanic=abort though.
+ifdef IS_MSVC
+COMMON_FLAGS+= -Cpanic=abort
+endif
+
+all: cpp-executable rust-executable
+
+cpp-executable:
+       $(RUSTC) -Clinker-plugin-lto=on \
+                -Zpgo-gen="$(TMPDIR)"/cpp-profdata \
+                -o "$(TMPDIR)"/librustlib-xlto.a \
+                $(COMMON_FLAGS) \
+                ./rustlib.rs
+       $(CLANG) -flto=thin \
+                -fprofile-generate="$(TMPDIR)"/cpp-profdata \
+                -fuse-ld=lld \
+                -L "$(TMPDIR)" \
+                -lrustlib-xlto \
+                -o "$(TMPDIR)"/cmain \
+                -O3 \
+                ./cmain.c
+       $(TMPDIR)/cmain
+       # Postprocess the profiling data so it can be used by the compiler
+       "$(LLVM_BIN_DIR)"/llvm-profdata merge \
+               -o "$(TMPDIR)"/cpp-profdata/merged.profdata \
+               "$(TMPDIR)"/cpp-profdata/default_*.profraw
+       $(RUSTC) -Clinker-plugin-lto=on \
+                -Zpgo-use="$(TMPDIR)"/cpp-profdata/merged.profdata \
+                -o "$(TMPDIR)"/librustlib-xlto.a \
+                $(COMMON_FLAGS) \
+                ./rustlib.rs
+       $(CLANG) -flto=thin \
+                -fprofile-use="$(TMPDIR)"/cpp-profdata/merged.profdata \
+                -fuse-ld=lld \
+                -L "$(TMPDIR)" \
+                -lrustlib-xlto \
+                -o "$(TMPDIR)"/cmain \
+                -O3 \
+                ./cmain.c
+
+rust-executable:
+       exit
+       $(CLANG) ./clib.c -fprofile-generate="$(TMPDIR)"/rs-profdata -flto=thin -c -o $(TMPDIR)/clib.o -O3
+       (cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o)
+       $(RUSTC) -Clinker-plugin-lto=on \
+                -Zpgo-gen="$(TMPDIR)"/rs-profdata \
+                -L$(TMPDIR) \
+                $(COMMON_FLAGS) \
+                -Clinker=$(CLANG) \
+                -Clink-arg=-fuse-ld=lld \
+                -o $(TMPDIR)/rsmain \
+                ./main.rs
+       $(TMPDIR)/rsmain
+       # Postprocess the profiling data so it can be used by the compiler
+       "$(LLVM_BIN_DIR)"/llvm-profdata merge \
+               -o "$(TMPDIR)"/rs-profdata/merged.profdata \
+               "$(TMPDIR)"/rs-profdata/default_*.profraw
+       $(CLANG) ./clib.c \
+                -fprofile-use="$(TMPDIR)"/rs-profdata/merged.profdata \
+                -flto=thin \
+                -c \
+                -o $(TMPDIR)/clib.o \
+                -O3
+       rm "$(TMPDIR)"/libxyz.a
+       (cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o)
+       $(RUSTC) -Clinker-plugin-lto=on \
+                -Zpgo-use="$(TMPDIR)"/rs-profdata/merged.profdata \
+                -L$(TMPDIR) \
+                $(COMMON_FLAGS) \
+                -Clinker=$(CLANG) \
+                -Clink-arg=-fuse-ld=lld \
+                -o $(TMPDIR)/rsmain \
+                ./main.rs
diff --git a/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/clib.c b/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/clib.c
new file mode 100644 (file)
index 0000000..90f33f2
--- /dev/null
@@ -0,0 +1,9 @@
+#include <stdint.h>
+
+uint32_t c_always_inlined() {
+    return 1234;
+}
+
+__attribute__((noinline)) uint32_t c_never_inlined() {
+    return 12345;
+}
diff --git a/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/cmain.c b/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/cmain.c
new file mode 100644 (file)
index 0000000..e3f2482
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdint.h>
+
+// A trivial function defined in Rust, returning a constant value. This should
+// always be inlined.
+uint32_t rust_always_inlined();
+
+
+uint32_t rust_never_inlined();
+
+int main(int argc, char** argv) {
+    return (rust_never_inlined() + rust_always_inlined()) * 0;
+}
diff --git a/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/main.rs b/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/main.rs
new file mode 100644 (file)
index 0000000..8129dcb
--- /dev/null
@@ -0,0 +1,11 @@
+#[link(name = "xyz")]
+extern "C" {
+    fn c_always_inlined() -> u32;
+    fn c_never_inlined() -> u32;
+}
+
+fn main() {
+    unsafe {
+        println!("blub: {}", c_always_inlined() + c_never_inlined());
+    }
+}
diff --git a/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/rustlib.rs b/src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/rustlib.rs
new file mode 100644 (file)
index 0000000..8a74d74
--- /dev/null
@@ -0,0 +1,12 @@
+#![crate_type="staticlib"]
+
+#[no_mangle]
+pub extern "C" fn rust_always_inlined() -> u32 {
+    42
+}
+
+#[no_mangle]
+#[inline(never)]
+pub extern "C" fn rust_never_inlined() -> u32 {
+    421
+}
diff --git a/src/test/run-pass/async-await.rs b/src/test/run-pass/async-await.rs
deleted file mode 100644 (file)
index 49fd8b8..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-// edition:2018
-// aux-build:arc_wake.rs
-
-#![feature(async_await)]
-
-extern crate arc_wake;
-
-use std::pin::Pin;
-use std::future::Future;
-use std::sync::{
-    Arc,
-    atomic::{self, AtomicUsize},
-};
-use std::task::{Context, Poll};
-use arc_wake::ArcWake;
-
-struct Counter {
-    wakes: AtomicUsize,
-}
-
-impl ArcWake for Counter {
-    fn wake(self: Arc<Self>) {
-        Self::wake_by_ref(&self)
-    }
-    fn wake_by_ref(arc_self: &Arc<Self>) {
-        arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst);
-    }
-}
-
-struct WakeOnceThenComplete(bool);
-
-fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) }
-
-impl Future for WakeOnceThenComplete {
-    type Output = ();
-    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
-        if self.0 {
-            Poll::Ready(())
-        } else {
-            cx.waker().wake_by_ref();
-            self.0 = true;
-            Poll::Pending
-        }
-    }
-}
-
-fn async_block(x: u8) -> impl Future<Output = u8> {
-    async move {
-        wake_and_yield_once().await;
-        x
-    }
-}
-
-fn async_block_with_borrow_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
-    async move {
-        wake_and_yield_once().await;
-        *x
-    }
-}
-
-fn async_nonmove_block(x: u8) -> impl Future<Output = u8> {
-    async move {
-        let future = async {
-            wake_and_yield_once().await;
-            x
-        };
-        future.await
-    }
-}
-
-fn async_closure(x: u8) -> impl Future<Output = u8> {
-    (async move |x: u8| -> u8 {
-        wake_and_yield_once().await;
-        x
-    })(x)
-}
-
-async fn async_fn(x: u8) -> u8 {
-    wake_and_yield_once().await;
-    x
-}
-
-async fn generic_async_fn<T>(x: T) -> T {
-    wake_and_yield_once().await;
-    x
-}
-
-async fn async_fn_with_borrow(x: &u8) -> u8 {
-    wake_and_yield_once().await;
-    *x
-}
-
-async fn async_fn_with_borrow_named_lifetime<'a>(x: &'a u8) -> u8 {
-    wake_and_yield_once().await;
-    *x
-}
-
-fn async_fn_with_impl_future_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
-    async move {
-        wake_and_yield_once().await;
-        *x
-    }
-}
-
-/* FIXME(cramertj) support when `existential type T<'a, 'b>:;` works
-async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 {
-    await!(wake_and_yield_once());
-    *x
-}
-*/
-
-async fn async_fn_multiple_args_named_lifetime<'a>(x: &'a u8, _y: &'a u8) -> u8 {
-    wake_and_yield_once().await;
-    *x
-}
-
-fn async_fn_with_internal_borrow(y: u8) -> impl Future<Output = u8> {
-    async move {
-        async_fn_with_borrow_named_lifetime(&y).await
-    }
-}
-
-unsafe async fn unsafe_async_fn(x: u8) -> u8 {
-    wake_and_yield_once().await;
-    x
-}
-
-struct Foo;
-
-trait Bar {
-    fn foo() {}
-}
-
-impl Foo {
-    async fn async_method(x: u8) -> u8 {
-        unsafe {
-            unsafe_async_fn(x).await
-        }
-    }
-}
-
-fn test_future_yields_once_then_returns<F, Fut>(f: F)
-where
-    F: FnOnce(u8) -> Fut,
-    Fut: Future<Output = u8>,
-{
-    let mut fut = Box::pin(f(9));
-    let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) });
-    let waker = ArcWake::into_waker(counter.clone());
-    let mut cx = Context::from_waker(&waker);
-    assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst));
-    assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx));
-    assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst));
-    assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx));
-}
-
-fn main() {
-    macro_rules! test {
-        ($($fn_name:expr,)*) => { $(
-            test_future_yields_once_then_returns($fn_name);
-        )* }
-    }
-
-    macro_rules! test_with_borrow {
-        ($($fn_name:expr,)*) => { $(
-            test_future_yields_once_then_returns(|x| {
-                async move {
-                    $fn_name(&x).await
-                }
-            });
-        )* }
-    }
-
-    test! {
-        async_block,
-        async_nonmove_block,
-        async_closure,
-        async_fn,
-        generic_async_fn,
-        async_fn_with_internal_borrow,
-        Foo::async_method,
-        |x| {
-            async move {
-                unsafe { unsafe_async_fn(x).await }
-            }
-        },
-    }
-    test_with_borrow! {
-        async_block_with_borrow_named_lifetime,
-        async_fn_with_borrow,
-        async_fn_with_borrow_named_lifetime,
-        async_fn_with_impl_future_named_lifetime,
-        |x| {
-            async move {
-                async_fn_multiple_args_named_lifetime(x, x).await
-            }
-        },
-    }
-}
diff --git a/src/test/run-pass/await-macro.rs b/src/test/run-pass/await-macro.rs
deleted file mode 100644 (file)
index e1b4328..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-// edition:2018
-// aux-build:arc_wake.rs
-
-#![feature(async_await, await_macro)]
-
-extern crate arc_wake;
-
-use std::pin::Pin;
-use std::future::Future;
-use std::sync::{
-    Arc,
-    atomic::{self, AtomicUsize},
-};
-use std::task::{Context, Poll};
-use arc_wake::ArcWake;
-
-struct Counter {
-    wakes: AtomicUsize,
-}
-
-impl ArcWake for Counter {
-    fn wake(self: Arc<Self>) {
-        Self::wake_by_ref(&self)
-    }
-    fn wake_by_ref(arc_self: &Arc<Self>) {
-        arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst);
-    }
-}
-
-struct WakeOnceThenComplete(bool);
-
-fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) }
-
-impl Future for WakeOnceThenComplete {
-    type Output = ();
-    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
-        if self.0 {
-            Poll::Ready(())
-        } else {
-            cx.waker().wake_by_ref();
-            self.0 = true;
-            Poll::Pending
-        }
-    }
-}
-
-fn async_block(x: u8) -> impl Future<Output = u8> {
-    async move {
-        await!(wake_and_yield_once());
-        x
-    }
-}
-
-fn async_block_with_borrow_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
-    async move {
-        await!(wake_and_yield_once());
-        *x
-    }
-}
-
-fn async_nonmove_block(x: u8) -> impl Future<Output = u8> {
-    async move {
-        let future = async {
-            await!(wake_and_yield_once());
-            x
-        };
-        await!(future)
-    }
-}
-
-fn async_closure(x: u8) -> impl Future<Output = u8> {
-    (async move |x: u8| -> u8 {
-        await!(wake_and_yield_once());
-        x
-    })(x)
-}
-
-async fn async_fn(x: u8) -> u8 {
-    await!(wake_and_yield_once());
-    x
-}
-
-async fn generic_async_fn<T>(x: T) -> T {
-    await!(wake_and_yield_once());
-    x
-}
-
-async fn async_fn_with_borrow(x: &u8) -> u8 {
-    await!(wake_and_yield_once());
-    *x
-}
-
-async fn async_fn_with_borrow_named_lifetime<'a>(x: &'a u8) -> u8 {
-    await!(wake_and_yield_once());
-    *x
-}
-
-fn async_fn_with_impl_future_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
-    async move {
-        await!(wake_and_yield_once());
-        *x
-    }
-}
-
-/* FIXME(cramertj) support when `existential type T<'a, 'b>:;` works
-async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 {
-    await!(wake_and_yield_once());
-    *x
-}
-*/
-
-async fn async_fn_multiple_args_named_lifetime<'a>(x: &'a u8, _y: &'a u8) -> u8 {
-    await!(wake_and_yield_once());
-    *x
-}
-
-fn async_fn_with_internal_borrow(y: u8) -> impl Future<Output = u8> {
-    async move {
-        await!(async_fn_with_borrow_named_lifetime(&y))
-    }
-}
-
-unsafe async fn unsafe_async_fn(x: u8) -> u8 {
-    await!(wake_and_yield_once());
-    x
-}
-
-struct Foo;
-
-trait Bar {
-    fn foo() {}
-}
-
-impl Foo {
-    async fn async_method(x: u8) -> u8 {
-        unsafe {
-            await!(unsafe_async_fn(x))
-        }
-    }
-}
-
-fn test_future_yields_once_then_returns<F, Fut>(f: F)
-where
-    F: FnOnce(u8) -> Fut,
-    Fut: Future<Output = u8>,
-{
-    let mut fut = Box::pin(f(9));
-    let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) });
-    let waker = ArcWake::into_waker(counter.clone());
-    let mut cx = Context::from_waker(&waker);
-    assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst));
-    assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx));
-    assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst));
-    assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx));
-}
-
-fn main() {
-    macro_rules! test {
-        ($($fn_name:expr,)*) => { $(
-            test_future_yields_once_then_returns($fn_name);
-        )* }
-    }
-
-    macro_rules! test_with_borrow {
-        ($($fn_name:expr,)*) => { $(
-            test_future_yields_once_then_returns(|x| {
-                async move {
-                    await!($fn_name(&x))
-                }
-            });
-        )* }
-    }
-
-    test! {
-        async_block,
-        async_nonmove_block,
-        async_closure,
-        async_fn,
-        generic_async_fn,
-        async_fn_with_internal_borrow,
-        Foo::async_method,
-        |x| {
-            async move {
-                unsafe { await!(unsafe_async_fn(x)) }
-            }
-        },
-    }
-    test_with_borrow! {
-        async_block_with_borrow_named_lifetime,
-        async_fn_with_borrow,
-        async_fn_with_borrow_named_lifetime,
-        async_fn_with_impl_future_named_lifetime,
-        |x| {
-            async move {
-                await!(async_fn_multiple_args_named_lifetime(x, x))
-            }
-        },
-    }
-}
diff --git a/src/test/run-pass/generator/issue-59972.rs b/src/test/run-pass/generator/issue-59972.rs
deleted file mode 100644 (file)
index 995da4f..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// compile-flags: --edition=2018
-
-#![feature(async_await, await_macro)]
-
-pub enum Uninhabited { }
-
-fn uninhabited_async() -> Uninhabited {
-    unreachable!()
-}
-
-async fn noop() { }
-
-#[allow(unused)]
-async fn contains_never() {
-    let error = uninhabited_async();
-    await!(noop());
-    let error2 = error;
-}
-
-#[allow(unused_must_use)]
-fn main() {
-    contains_never();
-}
diff --git a/src/test/run-pass/issue-55809.rs b/src/test/run-pass/issue-55809.rs
deleted file mode 100644 (file)
index b7e60b7..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// edition:2018
-// run-pass
-
-#![feature(async_await)]
-
-trait Foo { }
-
-impl Foo for () { }
-
-impl<'a, T> Foo for &'a mut T where T: Foo { }
-
-async fn foo_async<T>(_v: T) -> u8 where T: Foo {
-    0
-}
-
-async fn bad<T>(v: T) -> u8 where T: Foo {
-    foo_async(v).await
-}
-
-async fn async_main() {
-    let mut v = ();
-
-    let _ = bad(&mut v).await;
-    let _ = foo_async(&mut v).await;
-    let _ = bad(v).await;
-}
-
-fn main() {
-    let _ = async_main();
-}
index 5ec54ada13bb0f396c56fb94b5e1d7e27b4e8213..74a4dd5d8515b3825743b6b1f1f971a58cae4093 100644 (file)
@@ -1,4 +1,5 @@
 #![feature(fnbox)]
+#![allow(deprecated, deprecated_in_future)]
 
 use std::boxed::FnBox;
 
diff --git a/src/test/ui/E0501.rs b/src/test/ui/E0501.rs
deleted file mode 100644 (file)
index 3e39d9a..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-fn inside_closure(x: &mut i32) {
-}
-
-fn outside_closure_1(x: &mut i32) {
-}
-
-fn outside_closure_2(x: &i32) {
-}
-
-fn foo(a: &mut i32) {
-    let bar = || {
-        inside_closure(a)
-    };
-    outside_closure_1(a);
-    //~^ ERROR cannot borrow `*a` as mutable because previous closure requires unique access
-
-    outside_closure_2(a);
-    //~^ ERROR cannot borrow `*a` as immutable because previous closure requires unique access
-
-    drop(bar);
-}
-
-fn main() {
-}
diff --git a/src/test/ui/E0501.stderr b/src/test/ui/E0501.stderr
deleted file mode 100644 (file)
index 53d98d7..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-error[E0501]: cannot borrow `*a` as mutable because previous closure requires unique access
-  --> $DIR/E0501.rs:14:23
-   |
-LL |     let bar = || {
-   |               -- closure construction occurs here
-LL |         inside_closure(a)
-   |                        - first borrow occurs due to use of `a` in closure
-LL |     };
-LL |     outside_closure_1(a);
-   |                       ^ second borrow occurs here
-...
-LL |     drop(bar);
-   |          --- first borrow later used here
-
-error[E0501]: cannot borrow `*a` as immutable because previous closure requires unique access
-  --> $DIR/E0501.rs:17:23
-   |
-LL |     let bar = || {
-   |               -- closure construction occurs here
-LL |         inside_closure(a)
-   |                        - first borrow occurs due to use of `a` in closure
-...
-LL |     outside_closure_2(a);
-   |                       ^ second borrow occurs here
-...
-LL |     drop(bar);
-   |          --- first borrow later used here
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0501`.
diff --git a/src/test/ui/E0506.rs b/src/test/ui/E0506.rs
deleted file mode 100644 (file)
index 062a44a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-struct FancyNum {
-    num: u8,
-}
-
-fn main() {
-    let mut fancy_num = FancyNum { num: 5 };
-    let fancy_ref = &fancy_num;
-    fancy_num = FancyNum { num: 6 }; //~ ERROR [E0506]
-
-    println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
-}
diff --git a/src/test/ui/E0506.stderr b/src/test/ui/E0506.stderr
deleted file mode 100644 (file)
index 17f883f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0506]: cannot assign to `fancy_num` because it is borrowed
-  --> $DIR/E0506.rs:8:5
-   |
-LL |     let fancy_ref = &fancy_num;
-   |                     ---------- borrow of `fancy_num` occurs here
-LL |     fancy_num = FancyNum { num: 6 };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `fancy_num` occurs here
-LL | 
-LL |     println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
-   |                                                 ------------- borrow later used here
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0506`.
diff --git a/src/test/ui/E0508-fail.rs b/src/test/ui/E0508-fail.rs
deleted file mode 100644 (file)
index 072c3d6..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-struct NonCopy;
-
-fn main() {
-    let array = [NonCopy; 1];
-    let _value = array[0];  //~ ERROR [E0508]
-}
diff --git a/src/test/ui/E0508-fail.stderr b/src/test/ui/E0508-fail.stderr
deleted file mode 100644 (file)
index 63590be..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
-  --> $DIR/E0508-fail.rs:5:18
-   |
-LL |     let _value = array[0];
-   |                  ^^^^^^^^
-   |                  |
-   |                  cannot move out of here
-   |                  help: consider borrowing here: `&array[0]`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0508`.
diff --git a/src/test/ui/E0508.rs b/src/test/ui/E0508.rs
deleted file mode 100644 (file)
index 072c3d6..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-struct NonCopy;
-
-fn main() {
-    let array = [NonCopy; 1];
-    let _value = array[0];  //~ ERROR [E0508]
-}
diff --git a/src/test/ui/E0508.stderr b/src/test/ui/E0508.stderr
deleted file mode 100644 (file)
index 983062e..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
-  --> $DIR/E0508.rs:5:18
-   |
-LL |     let _value = array[0];
-   |                  ^^^^^^^^
-   |                  |
-   |                  cannot move out of here
-   |                  help: consider borrowing here: `&array[0]`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0508`.
diff --git a/src/test/ui/E0583.rs b/src/test/ui/E0583.rs
deleted file mode 100644 (file)
index 969de79..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-mod module_that_doesnt_exist; //~ ERROR E0583
-
-fn main() {
-}
diff --git a/src/test/ui/E0583.stderr b/src/test/ui/E0583.stderr
deleted file mode 100644 (file)
index ef7a48b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0583]: file not found for module `module_that_doesnt_exist`
-  --> $DIR/E0583.rs:1:5
-   |
-LL | mod module_that_doesnt_exist;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: name the file either module_that_doesnt_exist.rs or module_that_doesnt_exist/mod.rs inside the directory "$DIR"
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0583`.
diff --git a/src/test/ui/E0594.rs b/src/test/ui/E0594.rs
deleted file mode 100644 (file)
index 8b0cae7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-static NUM: i32 = 18;
-
-fn main() {
-    NUM = 20; //~ ERROR cannot assign to immutable static item `NUM`
-}
diff --git a/src/test/ui/E0594.stderr b/src/test/ui/E0594.stderr
deleted file mode 100644 (file)
index c00ec42..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error[E0594]: cannot assign to immutable static item `NUM`
-  --> $DIR/E0594.rs:4:5
-   |
-LL |     NUM = 20;
-   |     ^^^^^^^^ cannot assign
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/E0596.rs b/src/test/ui/E0596.rs
deleted file mode 100644 (file)
index 9e2f5ee..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-fn main() {
-    let x = 1;
-    let y = &mut x; //~ ERROR [E0596]
-}
diff --git a/src/test/ui/E0596.stderr b/src/test/ui/E0596.stderr
deleted file mode 100644 (file)
index 79bc258..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
-  --> $DIR/E0596.rs:3:13
-   |
-LL |     let x = 1;
-   |         - help: consider changing this to be mutable: `mut x`
-LL |     let y = &mut x;
-   |             ^^^^^^ cannot borrow as mutable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/E0642.rs b/src/test/ui/E0642.rs
deleted file mode 100644 (file)
index cfbd362..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#[derive(Clone, Copy)]
-struct S;
-
-trait T {
-    fn foo((x, y): (i32, i32)); //~ ERROR patterns aren't allowed in methods without bodies
-
-    fn bar((x, y): (i32, i32)) {} //~ ERROR patterns aren't allowed in methods without bodies
-
-    fn method(S { .. }: S) {} //~ ERROR patterns aren't allowed in methods without bodies
-
-    fn f(&ident: &S) {} // ok
-    fn g(&&ident: &&S) {} // ok
-    fn h(mut ident: S) {} // ok
-}
-
-fn main() {}
diff --git a/src/test/ui/E0642.stderr b/src/test/ui/E0642.stderr
deleted file mode 100644 (file)
index da25514..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-error[E0642]: patterns aren't allowed in methods without bodies
-  --> $DIR/E0642.rs:5:12
-   |
-LL |     fn foo((x, y): (i32, i32));
-   |            ^^^^^^
-help: give this argument a name or use an underscore to ignore it
-   |
-LL |     fn foo(_: (i32, i32));
-   |            ^
-
-error[E0642]: patterns aren't allowed in methods without bodies
-  --> $DIR/E0642.rs:7:12
-   |
-LL |     fn bar((x, y): (i32, i32)) {}
-   |            ^^^^^^
-help: give this argument a name or use an underscore to ignore it
-   |
-LL |     fn bar(_: (i32, i32)) {}
-   |            ^
-
-error[E0642]: patterns aren't allowed in methods without bodies
-  --> $DIR/E0642.rs:9:15
-   |
-LL |     fn method(S { .. }: S) {}
-   |               ^^^^^^^^
-help: give this argument a name or use an underscore to ignore it
-   |
-LL |     fn method(_: S) {}
-   |               ^
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0642`.
diff --git a/src/test/ui/E0660.rs b/src/test/ui/E0660.rs
deleted file mode 100644 (file)
index 6280d39..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#![feature(asm)]
-
-fn main() {
-    let a;
-    asm!("nop" "nop");
-    //~^ ERROR E0660
-    asm!("nop" "nop" : "=r"(a));
-    //~^ ERROR E0660
-}
diff --git a/src/test/ui/E0660.stderr b/src/test/ui/E0660.stderr
deleted file mode 100644 (file)
index ce34a9b..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0660]: malformed inline assembly
-  --> $DIR/E0660.rs:5:5
-   |
-LL |     asm!("nop" "nop");
-   |     ^^^^^^^^^^^^^^^^^^
-
-error[E0660]: malformed inline assembly
-  --> $DIR/E0660.rs:7:5
-   |
-LL |     asm!("nop" "nop" : "=r"(a));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
-
diff --git a/src/test/ui/E0661.rs b/src/test/ui/E0661.rs
deleted file mode 100644 (file)
index 8d355a8..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#![feature(asm)]
-
-fn main() {
-    let a;
-    asm!("nop" : "r"(a));
-    //~^ ERROR E0661
-}
diff --git a/src/test/ui/E0661.stderr b/src/test/ui/E0661.stderr
deleted file mode 100644 (file)
index 30a23fd..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error[E0661]: output operand constraint lacks '=' or '+'
-  --> $DIR/E0661.rs:5:18
-   |
-LL |     asm!("nop" : "r"(a));
-   |                  ^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/E0662.rs b/src/test/ui/E0662.rs
deleted file mode 100644 (file)
index 7fe528c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#![feature(asm)]
-
-fn main() {
-    asm!("xor %eax, %eax"
-         :
-         : "=test"("a") //~ ERROR E0662
-        );
-}
diff --git a/src/test/ui/E0662.stderr b/src/test/ui/E0662.stderr
deleted file mode 100644 (file)
index 0d3701a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error[E0662]: input operand constraint contains '='
-  --> $DIR/E0662.rs:6:12
-   |
-LL |          : "=test"("a")
-   |            ^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/E0663.rs b/src/test/ui/E0663.rs
deleted file mode 100644 (file)
index e5b8156..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#![feature(asm)]
-
-fn main() {
-    asm!("xor %eax, %eax"
-         :
-         : "+test"("a") //~ ERROR E0663
-        );
-}
diff --git a/src/test/ui/E0663.stderr b/src/test/ui/E0663.stderr
deleted file mode 100644 (file)
index 46a079a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error[E0663]: input operand constraint contains '+'
-  --> $DIR/E0663.rs:6:12
-   |
-LL |          : "+test"("a")
-   |            ^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/E0664.rs b/src/test/ui/E0664.rs
deleted file mode 100644 (file)
index 29ec7ce..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#![feature(asm)]
-
-fn main() {
-    asm!("mov $$0x200, %eax"
-         :
-         :
-         : "{eax}" //~ ERROR E0664
-        );
-}
diff --git a/src/test/ui/E0664.stderr b/src/test/ui/E0664.stderr
deleted file mode 100644 (file)
index 3a99fce..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error[E0664]: clobber should not be surrounded by braces
-  --> $DIR/E0664.rs:7:12
-   |
-LL |          : "{eax}"
-   |            ^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/E0665.rs b/src/test/ui/E0665.rs
deleted file mode 100644 (file)
index cfd42bd..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#[derive(Default)] //~ ERROR E0665
-enum Food {
-    Sweet,
-    Salty,
-}
-
-fn main() {
-}
diff --git a/src/test/ui/E0665.stderr b/src/test/ui/E0665.stderr
deleted file mode 100644 (file)
index 84fe3c0..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error[E0665]: `Default` cannot be derived for enums, only structs
-  --> $DIR/E0665.rs:1:10
-   |
-LL | #[derive(Default)]
-   |          ^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/E0705.rs b/src/test/ui/E0705.rs
deleted file mode 100644 (file)
index cc2b8f6..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// compile-pass
-
-// This is a stub feature that doesn't control anything, so to make tidy happy,
-// gate-test-test_2018_feature
-
-#![feature(test_2018_feature)]
-//~^ WARN the feature `test_2018_feature` is included in the Rust 2018 edition
-#![feature(rust_2018_preview)]
-
-fn main() {}
diff --git a/src/test/ui/E0705.stderr b/src/test/ui/E0705.stderr
deleted file mode 100644 (file)
index 1cb83f2..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-warning[E0705]: the feature `test_2018_feature` is included in the Rust 2018 edition
-  --> $DIR/E0705.rs:6:12
-   |
-LL | #![feature(test_2018_feature)]
-   |            ^^^^^^^^^^^^^^^^^
-
index fced38caaba913630bb38b3af2bad12a09309b85..a26ee23894f6dcd04db477b1901adadf00331715 100644 (file)
@@ -12,3 +12,4 @@ LL | trait Foo: Iterator<Item = i32> {}
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0284`.
index 26e5a6a503c6f99ebc61516e52ae9c11966380bb..da14a69ae306a67baece987e98b21226ce43256f 100644 (file)
@@ -6,3 +6,4 @@ LL |     let x: isize = Foo::bar();
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0284`.
diff --git a/src/test/ui/async-await/async-await.rs b/src/test/ui/async-await/async-await.rs
new file mode 100644 (file)
index 0000000..6fa013e
--- /dev/null
@@ -0,0 +1,201 @@
+// run-pass
+
+// edition:2018
+// aux-build:arc_wake.rs
+
+#![feature(async_await)]
+
+extern crate arc_wake;
+
+use std::pin::Pin;
+use std::future::Future;
+use std::sync::{
+    Arc,
+    atomic::{self, AtomicUsize},
+};
+use std::task::{Context, Poll};
+use arc_wake::ArcWake;
+
+struct Counter {
+    wakes: AtomicUsize,
+}
+
+impl ArcWake for Counter {
+    fn wake(self: Arc<Self>) {
+        Self::wake_by_ref(&self)
+    }
+    fn wake_by_ref(arc_self: &Arc<Self>) {
+        arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst);
+    }
+}
+
+struct WakeOnceThenComplete(bool);
+
+fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) }
+
+impl Future for WakeOnceThenComplete {
+    type Output = ();
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
+        if self.0 {
+            Poll::Ready(())
+        } else {
+            cx.waker().wake_by_ref();
+            self.0 = true;
+            Poll::Pending
+        }
+    }
+}
+
+fn async_block(x: u8) -> impl Future<Output = u8> {
+    async move {
+        wake_and_yield_once().await;
+        x
+    }
+}
+
+fn async_block_with_borrow_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
+    async move {
+        wake_and_yield_once().await;
+        *x
+    }
+}
+
+fn async_nonmove_block(x: u8) -> impl Future<Output = u8> {
+    async move {
+        let future = async {
+            wake_and_yield_once().await;
+            x
+        };
+        future.await
+    }
+}
+
+fn async_closure(x: u8) -> impl Future<Output = u8> {
+    (async move |x: u8| -> u8 {
+        wake_and_yield_once().await;
+        x
+    })(x)
+}
+
+async fn async_fn(x: u8) -> u8 {
+    wake_and_yield_once().await;
+    x
+}
+
+async fn generic_async_fn<T>(x: T) -> T {
+    wake_and_yield_once().await;
+    x
+}
+
+async fn async_fn_with_borrow(x: &u8) -> u8 {
+    wake_and_yield_once().await;
+    *x
+}
+
+async fn async_fn_with_borrow_named_lifetime<'a>(x: &'a u8) -> u8 {
+    wake_and_yield_once().await;
+    *x
+}
+
+fn async_fn_with_impl_future_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
+    async move {
+        wake_and_yield_once().await;
+        *x
+    }
+}
+
+/* FIXME(cramertj) support when `existential type T<'a, 'b>:;` works
+async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 {
+    await!(wake_and_yield_once());
+    *x
+}
+*/
+
+async fn async_fn_multiple_args_named_lifetime<'a>(x: &'a u8, _y: &'a u8) -> u8 {
+    wake_and_yield_once().await;
+    *x
+}
+
+fn async_fn_with_internal_borrow(y: u8) -> impl Future<Output = u8> {
+    async move {
+        async_fn_with_borrow_named_lifetime(&y).await
+    }
+}
+
+unsafe async fn unsafe_async_fn(x: u8) -> u8 {
+    wake_and_yield_once().await;
+    x
+}
+
+struct Foo;
+
+trait Bar {
+    fn foo() {}
+}
+
+impl Foo {
+    async fn async_method(x: u8) -> u8 {
+        unsafe {
+            unsafe_async_fn(x).await
+        }
+    }
+}
+
+fn test_future_yields_once_then_returns<F, Fut>(f: F)
+where
+    F: FnOnce(u8) -> Fut,
+    Fut: Future<Output = u8>,
+{
+    let mut fut = Box::pin(f(9));
+    let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) });
+    let waker = ArcWake::into_waker(counter.clone());
+    let mut cx = Context::from_waker(&waker);
+    assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst));
+    assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx));
+    assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst));
+    assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx));
+}
+
+fn main() {
+    macro_rules! test {
+        ($($fn_name:expr,)*) => { $(
+            test_future_yields_once_then_returns($fn_name);
+        )* }
+    }
+
+    macro_rules! test_with_borrow {
+        ($($fn_name:expr,)*) => { $(
+            test_future_yields_once_then_returns(|x| {
+                async move {
+                    $fn_name(&x).await
+                }
+            });
+        )* }
+    }
+
+    test! {
+        async_block,
+        async_nonmove_block,
+        async_closure,
+        async_fn,
+        generic_async_fn,
+        async_fn_with_internal_borrow,
+        Foo::async_method,
+        |x| {
+            async move {
+                unsafe { unsafe_async_fn(x).await }
+            }
+        },
+    }
+    test_with_borrow! {
+        async_block_with_borrow_named_lifetime,
+        async_fn_with_borrow,
+        async_fn_with_borrow_named_lifetime,
+        async_fn_with_impl_future_named_lifetime,
+        |x| {
+            async move {
+                async_fn_multiple_args_named_lifetime(x, x).await
+            }
+        },
+    }
+}
diff --git a/src/test/ui/async-await/async-fn-multiple-lifetimes.rs b/src/test/ui/async-await/async-fn-multiple-lifetimes.rs
new file mode 100644 (file)
index 0000000..e3ac817
--- /dev/null
@@ -0,0 +1,19 @@
+// edition:2018
+
+#![feature(arbitrary_self_types, async_await, await_macro, pin)]
+
+use std::ops::Add;
+
+async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}
+//~^ ERROR ambiguous lifetime bound in `async fn`
+
+async fn multiple_hrtb_and_single_named_lifetime_ok<'c>(
+    _: impl for<'a> Add<&'a u8>,
+    _: impl for<'b> Add<&'b u8>,
+    _: &'c u8,
+) {}
+
+async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
+//~^ ambiguous lifetime bound in `async fn`
+
+fn main() {}
diff --git a/src/test/ui/async-await/async-fn-multiple-lifetimes.stderr b/src/test/ui/async-await/async-fn-multiple-lifetimes.stderr
new file mode 100644 (file)
index 0000000..8c3ee2b
--- /dev/null
@@ -0,0 +1,20 @@
+error: ambiguous lifetime bound in `async fn`
+  --> $DIR/async-fn-multiple-lifetimes.rs:7:65
+   |
+LL | async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}
+   |                                                                 ^ neither `'a` nor `'b` outlives the other
+   |
+   = note: multiple unrelated lifetimes are not allowed in `async fn`.
+   = note: if you're using argument-position elided lifetimes, consider switching to a single named lifetime.
+
+error: ambiguous lifetime bound in `async fn`
+  --> $DIR/async-fn-multiple-lifetimes.rs:16:52
+   |
+LL | async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
+   |                                                    ^ the elided lifetimes here do not outlive one another
+   |
+   = note: multiple unrelated lifetimes are not allowed in `async fn`.
+   = note: if you're using argument-position elided lifetimes, consider switching to a single named lifetime.
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/async-await/async-fn-path-elision.rs b/src/test/ui/async-await/async-fn-path-elision.rs
new file mode 100644 (file)
index 0000000..8db7631
--- /dev/null
@@ -0,0 +1,16 @@
+// edition:2018
+
+#![feature(async_await, await_macro)]
+#![allow(dead_code)]
+
+struct HasLifetime<'a>(&'a bool);
+
+async fn error(lt: HasLifetime) { //~ ERROR implicit elided lifetime not allowed here
+    if *lt.0 {}
+}
+
+fn no_error(lt: HasLifetime) {
+    if *lt.0 {}
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/async-fn-path-elision.stderr b/src/test/ui/async-await/async-fn-path-elision.stderr
new file mode 100644 (file)
index 0000000..3b311ba
--- /dev/null
@@ -0,0 +1,8 @@
+error[E0726]: implicit elided lifetime not allowed here
+  --> $DIR/async-fn-path-elision.rs:8:20
+   |
+LL | async fn error(lt: HasLifetime) {
+   |                    ^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/async-matches-expr.rs b/src/test/ui/async-await/async-matches-expr.rs
new file mode 100644 (file)
index 0000000..f375d58
--- /dev/null
@@ -0,0 +1,13 @@
+// compile-pass
+// edition:2018
+
+#![feature(async_await, await_macro)]
+
+macro_rules! match_expr {
+    ($x:expr) => {}
+}
+
+fn main() {
+    match_expr!(async {});
+    match_expr!(async || {});
+}
diff --git a/src/test/ui/async-await/async-with-closure.rs b/src/test/ui/async-await/async-with-closure.rs
new file mode 100644 (file)
index 0000000..856a778
--- /dev/null
@@ -0,0 +1,26 @@
+// compile-pass
+// edition:2018
+
+#![feature(async_await, await_macro)]
+
+trait MyClosure {
+    type Args;
+}
+
+impl<R> MyClosure for dyn FnMut() -> R
+where R: 'static {
+    type Args = ();
+}
+
+struct MyStream<C: ?Sized + MyClosure> {
+    x: C::Args,
+}
+
+async fn get_future<C: ?Sized + MyClosure>(_stream: MyStream<C>) {}
+
+async fn f() {
+    let messages: MyStream<FnMut()> = unimplemented!();
+    await!(get_future(messages));
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/auxiliary/issue-60674.rs b/src/test/ui/async-await/auxiliary/issue-60674.rs
deleted file mode 100644 (file)
index 680c6e5..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// force-host
-// no-prefer-dynamic
-#![crate_type = "proc-macro"]
-
-extern crate proc_macro;
-use proc_macro::TokenStream;
-
-#[proc_macro_attribute]
-pub fn attr(_args: TokenStream, input: TokenStream) -> TokenStream {
-    println!("{}", input);
-    TokenStream::new()
-}
diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.rs b/src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.rs
new file mode 100644 (file)
index 0000000..c4f3f3e
--- /dev/null
@@ -0,0 +1,36 @@
+#![feature(async_await, await_macro)]
+#![allow(non_camel_case_types)]
+#![deny(keyword_idents)]
+
+mod outer_mod {
+    pub mod await { //~ ERROR `await` is a keyword in the 2018 edition
+    //~^ WARN this was previously accepted by the compiler
+        pub struct await; //~ ERROR `await` is a keyword in the 2018 edition
+        //~^ WARN this was previously accepted by the compiler
+    }
+}
+use outer_mod::await::await; //~ ERROR `await` is a keyword in the 2018 edition
+//~^ ERROR `await` is a keyword in the 2018 edition
+//~^^ WARN this was previously accepted by the compiler
+//~^^^ WARN this was previously accepted by the compiler
+
+struct Foo { await: () }
+//~^ ERROR `await` is a keyword in the 2018 edition
+//~^^ WARN this was previously accepted by the compiler
+
+impl Foo { fn await() {} }
+//~^ ERROR `await` is a keyword in the 2018 edition
+//~^^ WARN this was previously accepted by the compiler
+
+macro_rules! await {
+//~^ ERROR `await` is a keyword in the 2018 edition
+//~^^ WARN this was previously accepted by the compiler
+    () => {}
+}
+
+fn main() {
+    match await { await => {} } //~ ERROR `await` is a keyword in the 2018 edition
+    //~^ ERROR `await` is a keyword in the 2018 edition
+    //~^^ WARN this was previously accepted by the compiler
+    //~^^^ WARN this was previously accepted by the compiler
+}
diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.stderr b/src/test/ui/async-await/await-keyword/2015-edition-error-in-non-macro-position.stderr
new file mode 100644 (file)
index 0000000..067ecd6
--- /dev/null
@@ -0,0 +1,88 @@
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:6:13
+   |
+LL |     pub mod await {
+   |             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+note: lint level defined here
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:3:9
+   |
+LL | #![deny(keyword_idents)]
+   |         ^^^^^^^^^^^^^^
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:8:20
+   |
+LL |         pub struct await;
+   |                    ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:12:16
+   |
+LL | use outer_mod::await::await;
+   |                ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:12:23
+   |
+LL | use outer_mod::await::await;
+   |                       ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:17:14
+   |
+LL | struct Foo { await: () }
+   |              ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:21:15
+   |
+LL | impl Foo { fn await() {} }
+   |               ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:25:14
+   |
+LL | macro_rules! await {
+   |              ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:32:11
+   |
+LL |     match await { await => {} }
+   |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-error-in-non-macro-position.rs:32:19
+   |
+LL |     match await { await => {} }
+   |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: aborting due to 9 previous errors
+
diff --git a/src/test/ui/async-await/await-keyword/2015-edition-warning.fixed b/src/test/ui/async-await/await-keyword/2015-edition-warning.fixed
new file mode 100644 (file)
index 0000000..c58496c
--- /dev/null
@@ -0,0 +1,27 @@
+// run-rustfix
+
+#![allow(non_camel_case_types)]
+#![deny(keyword_idents)]
+
+mod outer_mod {
+    pub mod r#await {
+//~^ ERROR `await` is a keyword
+//~| WARN was previously accepted
+        pub struct r#await;
+//~^ ERROR `await` is a keyword
+//~| WARN was previously accepted
+    }
+}
+use outer_mod::r#await::r#await;
+//~^ ERROR `await` is a keyword
+//~| ERROR `await` is a keyword
+//~| WARN was previously accepted
+//~| WARN was previously accepted
+
+fn main() {
+    match r#await { r#await => {} }
+//~^ ERROR `await` is a keyword
+//~| ERROR `await` is a keyword
+//~| WARN was previously accepted
+//~| WARN was previously accepted
+}
diff --git a/src/test/ui/async-await/await-keyword/2015-edition-warning.rs b/src/test/ui/async-await/await-keyword/2015-edition-warning.rs
new file mode 100644 (file)
index 0000000..a7543a1
--- /dev/null
@@ -0,0 +1,27 @@
+// run-rustfix
+
+#![allow(non_camel_case_types)]
+#![deny(keyword_idents)]
+
+mod outer_mod {
+    pub mod await {
+//~^ ERROR `await` is a keyword
+//~| WARN was previously accepted
+        pub struct await;
+//~^ ERROR `await` is a keyword
+//~| WARN was previously accepted
+    }
+}
+use outer_mod::await::await;
+//~^ ERROR `await` is a keyword
+//~| ERROR `await` is a keyword
+//~| WARN was previously accepted
+//~| WARN was previously accepted
+
+fn main() {
+    match await { await => {} }
+//~^ ERROR `await` is a keyword
+//~| ERROR `await` is a keyword
+//~| WARN was previously accepted
+//~| WARN was previously accepted
+}
diff --git a/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr b/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr
new file mode 100644 (file)
index 0000000..d9ae1b9
--- /dev/null
@@ -0,0 +1,61 @@
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-warning.rs:7:13
+   |
+LL |     pub mod await {
+   |             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+note: lint level defined here
+  --> $DIR/2015-edition-warning.rs:4:9
+   |
+LL | #![deny(keyword_idents)]
+   |         ^^^^^^^^^^^^^^
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-warning.rs:10:20
+   |
+LL |         pub struct await;
+   |                    ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-warning.rs:15:16
+   |
+LL | use outer_mod::await::await;
+   |                ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-warning.rs:15:23
+   |
+LL | use outer_mod::await::await;
+   |                       ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-warning.rs:22:11
+   |
+LL |     match await { await => {} }
+   |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-warning.rs:22:19
+   |
+LL |     match await { await => {} }
+   |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs
new file mode 100644 (file)
index 0000000..f59f116
--- /dev/null
@@ -0,0 +1,25 @@
+// edition:2018
+
+#![allow(non_camel_case_types)]
+#![feature(async_await, await_macro)]
+
+mod outer_mod {
+    pub mod await { //~ ERROR expected identifier, found reserved keyword `await`
+        pub struct await; //~ ERROR expected identifier, found reserved keyword `await`
+    }
+}
+use self::outer_mod::await::await; //~ ERROR expected identifier, found reserved keyword `await`
+//~^ ERROR expected identifier, found reserved keyword `await`
+
+struct Foo { await: () }
+//~^ ERROR expected identifier, found reserved keyword `await`
+
+impl Foo { fn await() {} }
+//~^ ERROR expected identifier, found reserved keyword `await`
+
+macro_rules! await {
+//~^ ERROR expected identifier, found reserved keyword `await`
+    () => {}
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr
new file mode 100644 (file)
index 0000000..c4b82b2
--- /dev/null
@@ -0,0 +1,72 @@
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:7:13
+   |
+LL |     pub mod await {
+   |             ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     pub mod r#await {
+   |             ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:8:20
+   |
+LL |         pub struct await;
+   |                    ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |         pub struct r#await;
+   |                    ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:11:22
+   |
+LL | use self::outer_mod::await::await;
+   |                      ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL | use self::outer_mod::r#await::await;
+   |                      ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:11:29
+   |
+LL | use self::outer_mod::await::await;
+   |                             ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL | use self::outer_mod::await::r#await;
+   |                             ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:14:14
+   |
+LL | struct Foo { await: () }
+   |              ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL | struct Foo { r#await: () }
+   |              ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:17:15
+   |
+LL | impl Foo { fn await() {} }
+   |               ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL | impl Foo { fn r#await() {} }
+   |               ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:20:14
+   |
+LL | macro_rules! await {
+   |              ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL | macro_rules! r#await {
+   |              ^^^^^^^
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error.rs b/src/test/ui/async-await/await-keyword/2018-edition-error.rs
new file mode 100644 (file)
index 0000000..d856869
--- /dev/null
@@ -0,0 +1,12 @@
+// edition:2018
+#![allow(non_camel_case_types)]
+
+mod outer_mod {
+    pub mod await { //~ ERROR expected identifier
+        pub struct await; //~ ERROR expected identifier
+    }
+}
+use self::outer_mod::await::await; //~ ERROR expected identifier
+    //~^ ERROR expected identifier, found reserved keyword `await`
+
+fn main() {}
diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error.stderr b/src/test/ui/async-await/await-keyword/2018-edition-error.stderr
new file mode 100644 (file)
index 0000000..8afe5c1
--- /dev/null
@@ -0,0 +1,42 @@
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error.rs:5:13
+   |
+LL |     pub mod await {
+   |             ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     pub mod r#await {
+   |             ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error.rs:6:20
+   |
+LL |         pub struct await;
+   |                    ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |         pub struct r#await;
+   |                    ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error.rs:9:22
+   |
+LL | use self::outer_mod::await::await;
+   |                      ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL | use self::outer_mod::r#await::await;
+   |                      ^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/2018-edition-error.rs:9:29
+   |
+LL | use self::outer_mod::await::await;
+   |                             ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL | use self::outer_mod::await::r#await;
+   |                             ^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
new file mode 100644 (file)
index 0000000..e1e5bdd
--- /dev/null
@@ -0,0 +1,111 @@
+// edition:2018
+
+#![feature(async_await)]
+
+async fn bar() -> Result<(), ()> {
+    Ok(())
+}
+
+async fn foo1() -> Result<(), ()> {
+    let _ = await bar(); //~ ERROR incorrect use of `await`
+    Ok(())
+}
+async fn foo2() -> Result<(), ()> {
+    let _ = await? bar(); //~ ERROR incorrect use of `await`
+    Ok(())
+}
+async fn foo3() -> Result<(), ()> {
+    let _ = await bar()?; //~ ERROR incorrect use of `await`
+    //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
+    Ok(())
+}
+async fn foo21() -> Result<(), ()> {
+    let _ = await { bar() }; //~ ERROR incorrect use of `await`
+    Ok(())
+}
+async fn foo22() -> Result<(), ()> {
+    let _ = await(bar()); //~ ERROR incorrect use of `await`
+    Ok(())
+}
+async fn foo23() -> Result<(), ()> {
+    let _ = await { bar() }?; //~ ERROR incorrect use of `await`
+    Ok(())
+}
+async fn foo4() -> Result<(), ()> {
+    let _ = (await bar())?; //~ ERROR incorrect use of `await`
+    Ok(())
+}
+async fn foo5() -> Result<(), ()> {
+    let _ = bar().await(); //~ ERROR incorrect use of `await`
+    Ok(())
+}
+async fn foo6() -> Result<(), ()> {
+    let _ = bar().await()?; //~ ERROR incorrect use of `await`
+    Ok(())
+}
+async fn foo7() -> Result<(), ()> {
+    let _ = bar().await; // OK
+    Ok(())
+}
+async fn foo8() -> Result<(), ()> {
+    let _ = bar().await?; // OK
+    Ok(())
+}
+fn foo9() -> Result<(), ()> {
+    let _ = await bar(); //~ ERROR `await` is only allowed inside `async` functions and blocks
+    //~^ ERROR incorrect use of `await`
+    Ok(())
+}
+fn foo10() -> Result<(), ()> {
+    let _ = await? bar(); //~ ERROR `await` is only allowed inside `async` functions and blocks
+    //~^ ERROR incorrect use of `await`
+    Ok(())
+}
+fn foo11() -> Result<(), ()> {
+    let _ = await bar()?; //~ ERROR `await` is only allowed inside `async` functions and blocks
+    //~^ ERROR incorrect use of `await`
+    Ok(())
+}
+fn foo12() -> Result<(), ()> {
+    let _ = (await bar())?; //~ ERROR `await` is only allowed inside `async` functions and blocks
+    //~^ ERROR incorrect use of `await`
+    Ok(())
+}
+fn foo13() -> Result<(), ()> {
+    let _ = bar().await(); //~ ERROR `await` is only allowed inside `async` functions and blocks
+    //~^ ERROR incorrect use of `await`
+    Ok(())
+}
+fn foo14() -> Result<(), ()> {
+    let _ = bar().await()?; //~ ERROR `await` is only allowed inside `async` functions and blocks
+    //~^ ERROR incorrect use of `await`
+    Ok(())
+}
+fn foo15() -> Result<(), ()> {
+    let _ = bar().await; //~ ERROR `await` is only allowed inside `async` functions and blocks
+    Ok(())
+}
+fn foo16() -> Result<(), ()> {
+    let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks
+    Ok(())
+}
+fn foo24() -> Result<(), ()> {
+    fn foo() -> Result<(), ()> {
+        let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks
+        Ok(())
+    }
+    foo()
+}
+fn foo25() -> Result<(), ()> {
+    let foo = || {
+        let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks
+        Ok(())
+    };
+    foo()
+}
+
+fn main() {
+    match await { await => () }
+    //~^ ERROR expected expression, found `=>`
+    //~| ERROR incorrect use of `await`
+} //~ ERROR expected one of `.`, `?`, `{`, or an operator, found `}`
diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
new file mode 100644 (file)
index 0000000..380da44
--- /dev/null
@@ -0,0 +1,207 @@
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:10:13
+   |
+LL |     let _ = await bar();
+   |             ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:14:13
+   |
+LL |     let _ = await? bar();
+   |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:18:13
+   |
+LL |     let _ = await bar()?;
+   |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:23:13
+   |
+LL |     let _ = await { bar() };
+   |             ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:27:13
+   |
+LL |     let _ = await(bar());
+   |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `(bar()).await`
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:31:13
+   |
+LL |     let _ = await { bar() }?;
+   |             ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:35:14
+   |
+LL |     let _ = (await bar())?;
+   |              ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:39:24
+   |
+LL |     let _ = bar().await();
+   |                        ^^ help: `await` is not a method call, remove the parentheses
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:43:24
+   |
+LL |     let _ = bar().await()?;
+   |                        ^^ help: `await` is not a method call, remove the parentheses
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:55:13
+   |
+LL |     let _ = await bar();
+   |             ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:60:13
+   |
+LL |     let _ = await? bar();
+   |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:65:13
+   |
+LL |     let _ = await bar()?;
+   |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:70:14
+   |
+LL |     let _ = (await bar())?;
+   |              ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:75:24
+   |
+LL |     let _ = bar().await();
+   |                        ^^ help: `await` is not a method call, remove the parentheses
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:80:24
+   |
+LL |     let _ = bar().await()?;
+   |                        ^^ help: `await` is not a method call, remove the parentheses
+
+error: expected expression, found `=>`
+  --> $DIR/incorrect-syntax-suggestions.rs:108:25
+   |
+LL |     match await { await => () }
+   |                   ----- ^^ expected expression
+   |                   |
+   |                   while parsing this incorrect await expression
+
+error: incorrect use of `await`
+  --> $DIR/incorrect-syntax-suggestions.rs:108:11
+   |
+LL |     match await { await => () }
+   |           ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await`
+
+error: expected one of `.`, `?`, `{`, or an operator, found `}`
+  --> $DIR/incorrect-syntax-suggestions.rs:111:1
+   |
+LL |     match await { await => () }
+   |     -----                      - expected one of `.`, `?`, `{`, or an operator here
+   |     |
+   |     while parsing this match expression
+...
+LL | }
+   | ^ unexpected token
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/incorrect-syntax-suggestions.rs:55:13
+   |
+LL | fn foo9() -> Result<(), ()> {
+   |    ---- this is not `async`
+LL |     let _ = await bar();
+   |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/incorrect-syntax-suggestions.rs:60:13
+   |
+LL | fn foo10() -> Result<(), ()> {
+   |    ----- this is not `async`
+LL |     let _ = await? bar();
+   |             ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/incorrect-syntax-suggestions.rs:65:13
+   |
+LL | fn foo11() -> Result<(), ()> {
+   |    ----- this is not `async`
+LL |     let _ = await bar()?;
+   |             ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/incorrect-syntax-suggestions.rs:70:14
+   |
+LL | fn foo12() -> Result<(), ()> {
+   |    ----- this is not `async`
+LL |     let _ = (await bar())?;
+   |              ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/incorrect-syntax-suggestions.rs:75:13
+   |
+LL | fn foo13() -> Result<(), ()> {
+   |    ----- this is not `async`
+LL |     let _ = bar().await();
+   |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/incorrect-syntax-suggestions.rs:80:13
+   |
+LL | fn foo14() -> Result<(), ()> {
+   |    ----- this is not `async`
+LL |     let _ = bar().await()?;
+   |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/incorrect-syntax-suggestions.rs:85:13
+   |
+LL | fn foo15() -> Result<(), ()> {
+   |    ----- this is not `async`
+LL |     let _ = bar().await;
+   |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/incorrect-syntax-suggestions.rs:89:13
+   |
+LL | fn foo16() -> Result<(), ()> {
+   |    ----- this is not `async`
+LL |     let _ = bar().await?;
+   |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/incorrect-syntax-suggestions.rs:94:17
+   |
+LL |     fn foo() -> Result<(), ()> {
+   |        --- this is not `async`
+LL |         let _ = bar().await?;
+   |                 ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/incorrect-syntax-suggestions.rs:101:17
+   |
+LL |     let foo = || {
+   |               -- this is not `async`
+LL |         let _ = bar().await?;
+   |                 ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
+  --> $DIR/incorrect-syntax-suggestions.rs:18:19
+   |
+LL |     let _ = await bar()?;
+   |                   ^^^^^^ the `?` operator cannot be applied to type `impl std::future::Future`
+   |
+   = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
+   = note: required by `std::ops::Try::into_result`
+
+error: aborting due to 29 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/await-keyword/post_expansion_error.rs b/src/test/ui/async-await/await-keyword/post_expansion_error.rs
new file mode 100644 (file)
index 0000000..b4c899b
--- /dev/null
@@ -0,0 +1,10 @@
+// edition:2018
+
+macro_rules! r#await {
+    () => { println!("Hello, world!") }
+}
+
+fn main() {
+    await!()
+    //~^ ERROR expected expression, found `)`
+}
diff --git a/src/test/ui/async-await/await-keyword/post_expansion_error.stderr b/src/test/ui/async-await/await-keyword/post_expansion_error.stderr
new file mode 100644 (file)
index 0000000..4e52597
--- /dev/null
@@ -0,0 +1,10 @@
+error: expected expression, found `)`
+  --> $DIR/post_expansion_error.rs:8:12
+   |
+LL |     await!()
+   |     -----  ^ expected expression
+   |     |
+   |     while parsing this await macro call
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/await-macro.rs b/src/test/ui/async-await/await-macro.rs
new file mode 100644 (file)
index 0000000..1b80758
--- /dev/null
@@ -0,0 +1,201 @@
+// run-pass
+
+// edition:2018
+// aux-build:arc_wake.rs
+
+#![feature(async_await, await_macro)]
+
+extern crate arc_wake;
+
+use std::pin::Pin;
+use std::future::Future;
+use std::sync::{
+    Arc,
+    atomic::{self, AtomicUsize},
+};
+use std::task::{Context, Poll};
+use arc_wake::ArcWake;
+
+struct Counter {
+    wakes: AtomicUsize,
+}
+
+impl ArcWake for Counter {
+    fn wake(self: Arc<Self>) {
+        Self::wake_by_ref(&self)
+    }
+    fn wake_by_ref(arc_self: &Arc<Self>) {
+        arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst);
+    }
+}
+
+struct WakeOnceThenComplete(bool);
+
+fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) }
+
+impl Future for WakeOnceThenComplete {
+    type Output = ();
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
+        if self.0 {
+            Poll::Ready(())
+        } else {
+            cx.waker().wake_by_ref();
+            self.0 = true;
+            Poll::Pending
+        }
+    }
+}
+
+fn async_block(x: u8) -> impl Future<Output = u8> {
+    async move {
+        await!(wake_and_yield_once());
+        x
+    }
+}
+
+fn async_block_with_borrow_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
+    async move {
+        await!(wake_and_yield_once());
+        *x
+    }
+}
+
+fn async_nonmove_block(x: u8) -> impl Future<Output = u8> {
+    async move {
+        let future = async {
+            await!(wake_and_yield_once());
+            x
+        };
+        await!(future)
+    }
+}
+
+fn async_closure(x: u8) -> impl Future<Output = u8> {
+    (async move |x: u8| -> u8 {
+        await!(wake_and_yield_once());
+        x
+    })(x)
+}
+
+async fn async_fn(x: u8) -> u8 {
+    await!(wake_and_yield_once());
+    x
+}
+
+async fn generic_async_fn<T>(x: T) -> T {
+    await!(wake_and_yield_once());
+    x
+}
+
+async fn async_fn_with_borrow(x: &u8) -> u8 {
+    await!(wake_and_yield_once());
+    *x
+}
+
+async fn async_fn_with_borrow_named_lifetime<'a>(x: &'a u8) -> u8 {
+    await!(wake_and_yield_once());
+    *x
+}
+
+fn async_fn_with_impl_future_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a {
+    async move {
+        await!(wake_and_yield_once());
+        *x
+    }
+}
+
+/* FIXME(cramertj) support when `existential type T<'a, 'b>:;` works
+async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 {
+    await!(wake_and_yield_once());
+    *x
+}
+*/
+
+async fn async_fn_multiple_args_named_lifetime<'a>(x: &'a u8, _y: &'a u8) -> u8 {
+    await!(wake_and_yield_once());
+    *x
+}
+
+fn async_fn_with_internal_borrow(y: u8) -> impl Future<Output = u8> {
+    async move {
+        await!(async_fn_with_borrow_named_lifetime(&y))
+    }
+}
+
+unsafe async fn unsafe_async_fn(x: u8) -> u8 {
+    await!(wake_and_yield_once());
+    x
+}
+
+struct Foo;
+
+trait Bar {
+    fn foo() {}
+}
+
+impl Foo {
+    async fn async_method(x: u8) -> u8 {
+        unsafe {
+            await!(unsafe_async_fn(x))
+        }
+    }
+}
+
+fn test_future_yields_once_then_returns<F, Fut>(f: F)
+where
+    F: FnOnce(u8) -> Fut,
+    Fut: Future<Output = u8>,
+{
+    let mut fut = Box::pin(f(9));
+    let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) });
+    let waker = ArcWake::into_waker(counter.clone());
+    let mut cx = Context::from_waker(&waker);
+    assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst));
+    assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx));
+    assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst));
+    assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx));
+}
+
+fn main() {
+    macro_rules! test {
+        ($($fn_name:expr,)*) => { $(
+            test_future_yields_once_then_returns($fn_name);
+        )* }
+    }
+
+    macro_rules! test_with_borrow {
+        ($($fn_name:expr,)*) => { $(
+            test_future_yields_once_then_returns(|x| {
+                async move {
+                    await!($fn_name(&x))
+                }
+            });
+        )* }
+    }
+
+    test! {
+        async_block,
+        async_nonmove_block,
+        async_closure,
+        async_fn,
+        generic_async_fn,
+        async_fn_with_internal_borrow,
+        Foo::async_method,
+        |x| {
+            async move {
+                unsafe { await!(unsafe_async_fn(x)) }
+            }
+        },
+    }
+    test_with_borrow! {
+        async_block_with_borrow_named_lifetime,
+        async_fn_with_borrow,
+        async_fn_with_borrow_named_lifetime,
+        async_fn_with_impl_future_named_lifetime,
+        |x| {
+            async move {
+                await!(async_fn_multiple_args_named_lifetime(x, x))
+            }
+        },
+    }
+}
diff --git a/src/test/ui/async-await/dont-print-desugared-async.rs b/src/test/ui/async-await/dont-print-desugared-async.rs
new file mode 100644 (file)
index 0000000..8150a26
--- /dev/null
@@ -0,0 +1,9 @@
+// Test that we don't show variables with from async fn desugaring
+
+// edition:2018
+#![feature(async_await)]
+
+async fn async_fn(&ref mut s: &[i32]) {}
+//~^ ERROR cannot borrow data in a `&` reference as mutable [E0596]
+
+fn main() {}
diff --git a/src/test/ui/async-await/dont-print-desugared-async.stderr b/src/test/ui/async-await/dont-print-desugared-async.stderr
new file mode 100644 (file)
index 0000000..47726ba
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0596]: cannot borrow data in a `&` reference as mutable
+  --> $DIR/dont-print-desugared-async.rs:6:20
+   |
+LL | async fn async_fn(&ref mut s: &[i32]) {}
+   |                   -^^^^^^^^^
+   |                   ||
+   |                   |cannot borrow as mutable through `&` reference
+   |                   help: consider changing this to be a mutable reference: `&mut ref mut s`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/async-await/drop-order-for-async-fn-parameters-by-ref-binding.rs b/src/test/ui/async-await/drop-order-for-async-fn-parameters-by-ref-binding.rs
deleted file mode 100644 (file)
index c2b59ee..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-// aux-build:arc_wake.rs
-// edition:2018
-// run-pass
-
-#![allow(unused_variables)]
-#![feature(async_await, await_macro)]
-
-// Test that the drop order for parameters in a fn and async fn matches up. Also test that
-// parameters (used or unused) are not dropped until the async fn completes execution.
-// See also #54716.
-
-extern crate arc_wake;
-
-use arc_wake::ArcWake;
-use std::cell::RefCell;
-use std::future::Future;
-use std::marker::PhantomData;
-use std::sync::Arc;
-use std::rc::Rc;
-use std::task::Context;
-
-struct EmptyWaker;
-
-impl ArcWake for EmptyWaker {
-    fn wake(self: Arc<Self>) {}
-}
-
-#[derive(Debug, Eq, PartialEq)]
-enum DropOrder {
-    Function,
-    Val(&'static str),
-}
-
-type DropOrderListPtr = Rc<RefCell<Vec<DropOrder>>>;
-
-struct D(&'static str, DropOrderListPtr);
-
-impl Drop for D {
-    fn drop(&mut self) {
-        self.1.borrow_mut().push(DropOrder::Val(self.0));
-    }
-}
-
-/// Check that unused bindings are dropped after the function is polled.
-async fn foo_async(ref mut x: D, ref mut _y: D) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-fn foo_sync(ref mut x: D, ref mut _y: D) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-/// Check that underscore patterns are dropped after the function is polled.
-async fn bar_async(ref mut x: D, _: D) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-fn bar_sync(ref mut x: D, _: D) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-/// Check that underscore patterns within more complex patterns are dropped after the function
-/// is polled.
-async fn baz_async((ref mut x, _): (D, D)) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-fn baz_sync((ref mut x, _): (D, D)) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-/// Check that underscore and unused bindings within and outwith more complex patterns are dropped
-/// after the function is polled.
-async fn foobar_async(ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-fn foobar_sync(ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-struct Foo;
-
-impl Foo {
-    /// Check that unused bindings are dropped after the method is polled.
-    async fn foo_async(ref mut x: D, ref mut _y: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn foo_sync(ref mut x: D, ref mut _y: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    /// Check that underscore patterns are dropped after the method is polled.
-    async fn bar_async(ref mut x: D, _: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn bar_sync(ref mut x: D, _: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    /// Check that underscore patterns within more complex patterns are dropped after the method
-    /// is polled.
-    async fn baz_async((ref mut x, _): (D, D)) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn baz_sync((ref mut x, _): (D, D)) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    /// Check that underscore and unused bindings within and outwith more complex patterns are
-    /// dropped after the method is polled.
-    async fn foobar_async(
-        ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
-    ) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn foobar_sync(
-        ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
-    ) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-}
-
-struct Bar<'a>(PhantomData<&'a ()>);
-
-impl<'a> Bar<'a> {
-    /// Check that unused bindings are dropped after the method with self is polled.
-    async fn foo_async(&'a self, ref mut x: D, ref mut _y: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn foo_sync(&'a self, ref mut x: D, ref mut _y: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    /// Check that underscore patterns are dropped after the method with self is polled.
-    async fn bar_async(&'a self, ref mut x: D, _: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn bar_sync(&'a self, ref mut x: D, _: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    /// Check that underscore patterns within more complex patterns are dropped after the method
-    /// with self is polled.
-    async fn baz_async(&'a self, (ref mut x, _): (D, D)) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn baz_sync(&'a self, (ref mut x, _): (D, D)) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    /// Check that underscore and unused bindings within and outwith more complex patterns are
-    /// dropped after the method with self is polled.
-    async fn foobar_async(
-        &'a self, ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
-    ) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn foobar_sync(
-        &'a self, ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
-    ) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-}
-
-fn assert_drop_order_after_poll<Fut: Future<Output = ()>>(
-    f: impl FnOnce(DropOrderListPtr) -> Fut,
-    g: impl FnOnce(DropOrderListPtr),
-) {
-    let empty = Arc::new(EmptyWaker);
-    let waker = ArcWake::into_waker(empty);
-    let mut cx = Context::from_waker(&waker);
-
-    let actual_order = Rc::new(RefCell::new(Vec::new()));
-    let mut fut = Box::pin(f(actual_order.clone()));
-    let _ = fut.as_mut().poll(&mut cx);
-
-    let expected_order = Rc::new(RefCell::new(Vec::new()));
-    g(expected_order.clone());
-
-    assert_eq!(*actual_order.borrow(), *expected_order.borrow());
-}
-
-fn main() {
-    // Free functions (see doc comment on function for what it tests).
-    assert_drop_order_after_poll(|l| foo_async(D("x", l.clone()), D("_y", l.clone())),
-                                 |l| foo_sync(D("x", l.clone()), D("_y", l.clone())));
-    assert_drop_order_after_poll(|l| bar_async(D("x", l.clone()), D("_", l.clone())),
-                                 |l| bar_sync(D("x", l.clone()), D("_", l.clone())));
-    assert_drop_order_after_poll(|l| baz_async((D("x", l.clone()), D("_", l.clone()))),
-                                 |l| baz_sync((D("x", l.clone()), D("_", l.clone()))));
-    assert_drop_order_after_poll(
-        |l| {
-            foobar_async(
-                D("x", l.clone()),
-                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
-                D("_", l.clone()),
-                D("_y", l.clone()),
-            )
-        },
-        |l| {
-            foobar_sync(
-                D("x", l.clone()),
-                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
-                D("_", l.clone()),
-                D("_y", l.clone()),
-            )
-        },
-    );
-
-    // Methods w/out self (see doc comment on function for what it tests).
-    assert_drop_order_after_poll(|l| Foo::foo_async(D("x", l.clone()), D("_y", l.clone())),
-                                 |l| Foo::foo_sync(D("x", l.clone()), D("_y", l.clone())));
-    assert_drop_order_after_poll(|l| Foo::bar_async(D("x", l.clone()), D("_", l.clone())),
-                                 |l| Foo::bar_sync(D("x", l.clone()), D("_", l.clone())));
-    assert_drop_order_after_poll(|l| Foo::baz_async((D("x", l.clone()), D("_", l.clone()))),
-                                 |l| Foo::baz_sync((D("x", l.clone()), D("_", l.clone()))));
-    assert_drop_order_after_poll(
-        |l| {
-            Foo::foobar_async(
-                D("x", l.clone()),
-                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
-                D("_", l.clone()),
-                D("_y", l.clone()),
-            )
-        },
-        |l| {
-            Foo::foobar_sync(
-                D("x", l.clone()),
-                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
-                D("_", l.clone()),
-                D("_y", l.clone()),
-            )
-        },
-    );
-
-    // Methods (see doc comment on function for what it tests).
-    let b = Bar(Default::default());
-    assert_drop_order_after_poll(|l| b.foo_async(D("x", l.clone()), D("_y", l.clone())),
-                                 |l| b.foo_sync(D("x", l.clone()), D("_y", l.clone())));
-    assert_drop_order_after_poll(|l| b.bar_async(D("x", l.clone()), D("_", l.clone())),
-                                 |l| b.bar_sync(D("x", l.clone()), D("_", l.clone())));
-    assert_drop_order_after_poll(|l| b.baz_async((D("x", l.clone()), D("_", l.clone()))),
-                                 |l| b.baz_sync((D("x", l.clone()), D("_", l.clone()))));
-    assert_drop_order_after_poll(
-        |l| {
-            b.foobar_async(
-                D("x", l.clone()),
-                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
-                D("_", l.clone()),
-                D("_y", l.clone()),
-            )
-        },
-        |l| {
-            b.foobar_sync(
-                D("x", l.clone()),
-                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
-                D("_", l.clone()),
-                D("_y", l.clone()),
-            )
-        },
-    );
-}
diff --git a/src/test/ui/async-await/drop-order-for-async-fn-parameters.rs b/src/test/ui/async-await/drop-order-for-async-fn-parameters.rs
deleted file mode 100644 (file)
index 708c570..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-// aux-build:arc_wake.rs
-// edition:2018
-// run-pass
-
-#![allow(unused_variables)]
-#![feature(async_await, await_macro)]
-
-// Test that the drop order for parameters in a fn and async fn matches up. Also test that
-// parameters (used or unused) are not dropped until the async fn completes execution.
-// See also #54716.
-
-extern crate arc_wake;
-
-use arc_wake::ArcWake;
-use std::cell::RefCell;
-use std::future::Future;
-use std::marker::PhantomData;
-use std::sync::Arc;
-use std::rc::Rc;
-use std::task::Context;
-
-struct EmptyWaker;
-
-impl ArcWake for EmptyWaker {
-    fn wake(self: Arc<Self>) {}
-}
-
-#[derive(Debug, Eq, PartialEq)]
-enum DropOrder {
-    Function,
-    Val(&'static str),
-}
-
-type DropOrderListPtr = Rc<RefCell<Vec<DropOrder>>>;
-
-struct D(&'static str, DropOrderListPtr);
-
-impl Drop for D {
-    fn drop(&mut self) {
-        self.1.borrow_mut().push(DropOrder::Val(self.0));
-    }
-}
-
-/// Check that unused bindings are dropped after the function is polled.
-async fn foo_async(x: D, _y: D) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-fn foo_sync(x: D, _y: D) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-/// Check that underscore patterns are dropped after the function is polled.
-async fn bar_async(x: D, _: D) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-fn bar_sync(x: D, _: D) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-/// Check that underscore patterns within more complex patterns are dropped after the function
-/// is polled.
-async fn baz_async((x, _): (D, D)) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-fn baz_sync((x, _): (D, D)) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-/// Check that underscore and unused bindings within and outwith more complex patterns are dropped
-/// after the function is polled.
-async fn foobar_async(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-fn foobar_sync(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
-    x.1.borrow_mut().push(DropOrder::Function);
-}
-
-struct Foo;
-
-impl Foo {
-    /// Check that unused bindings are dropped after the method is polled.
-    async fn foo_async(x: D, _y: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn foo_sync(x: D, _y: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    /// Check that underscore patterns are dropped after the method is polled.
-    async fn bar_async(x: D, _: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn bar_sync(x: D, _: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    /// Check that underscore patterns within more complex patterns are dropped after the method
-    /// is polled.
-    async fn baz_async((x, _): (D, D)) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn baz_sync((x, _): (D, D)) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    /// Check that underscore and unused bindings within and outwith more complex patterns are
-    /// dropped after the method is polled.
-    async fn foobar_async(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn foobar_sync(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-}
-
-struct Bar<'a>(PhantomData<&'a ()>);
-
-impl<'a> Bar<'a> {
-    /// Check that unused bindings are dropped after the method with self is polled.
-    async fn foo_async(&'a self, x: D, _y: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn foo_sync(&'a self, x: D, _y: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    /// Check that underscore patterns are dropped after the method with self is polled.
-    async fn bar_async(&'a self, x: D, _: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn bar_sync(&'a self, x: D, _: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    /// Check that underscore patterns within more complex patterns are dropped after the method
-    /// with self is polled.
-    async fn baz_async(&'a self, (x, _): (D, D)) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn baz_sync(&'a self, (x, _): (D, D)) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    /// Check that underscore and unused bindings within and outwith more complex patterns are
-    /// dropped after the method with self is polled.
-    async fn foobar_async(&'a self, x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-
-    fn foobar_sync(&'a self, x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
-        x.1.borrow_mut().push(DropOrder::Function);
-    }
-}
-
-fn assert_drop_order_after_poll<Fut: Future<Output = ()>>(
-    f: impl FnOnce(DropOrderListPtr) -> Fut,
-    g: impl FnOnce(DropOrderListPtr),
-) {
-    let empty = Arc::new(EmptyWaker);
-    let waker = ArcWake::into_waker(empty);
-    let mut cx = Context::from_waker(&waker);
-
-    let actual_order = Rc::new(RefCell::new(Vec::new()));
-    let mut fut = Box::pin(f(actual_order.clone()));
-    let _ = fut.as_mut().poll(&mut cx);
-
-    let expected_order = Rc::new(RefCell::new(Vec::new()));
-    g(expected_order.clone());
-
-    assert_eq!(*actual_order.borrow(), *expected_order.borrow());
-}
-
-fn main() {
-    // Free functions (see doc comment on function for what it tests).
-    assert_drop_order_after_poll(|l| foo_async(D("x", l.clone()), D("_y", l.clone())),
-                                 |l| foo_sync(D("x", l.clone()), D("_y", l.clone())));
-    assert_drop_order_after_poll(|l| bar_async(D("x", l.clone()), D("_", l.clone())),
-                                 |l| bar_sync(D("x", l.clone()), D("_", l.clone())));
-    assert_drop_order_after_poll(|l| baz_async((D("x", l.clone()), D("_", l.clone()))),
-                                 |l| baz_sync((D("x", l.clone()), D("_", l.clone()))));
-    assert_drop_order_after_poll(
-        |l| {
-            foobar_async(
-                D("x", l.clone()),
-                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
-                D("_", l.clone()),
-                D("_y", l.clone()),
-            )
-        },
-        |l| {
-            foobar_sync(
-                D("x", l.clone()),
-                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
-                D("_", l.clone()),
-                D("_y", l.clone()),
-            )
-        },
-    );
-
-    // Methods w/out self (see doc comment on function for what it tests).
-    assert_drop_order_after_poll(|l| Foo::foo_async(D("x", l.clone()), D("_y", l.clone())),
-                                 |l| Foo::foo_sync(D("x", l.clone()), D("_y", l.clone())));
-    assert_drop_order_after_poll(|l| Foo::bar_async(D("x", l.clone()), D("_", l.clone())),
-                                 |l| Foo::bar_sync(D("x", l.clone()), D("_", l.clone())));
-    assert_drop_order_after_poll(|l| Foo::baz_async((D("x", l.clone()), D("_", l.clone()))),
-                                 |l| Foo::baz_sync((D("x", l.clone()), D("_", l.clone()))));
-    assert_drop_order_after_poll(
-        |l| {
-            Foo::foobar_async(
-                D("x", l.clone()),
-                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
-                D("_", l.clone()),
-                D("_y", l.clone()),
-            )
-        },
-        |l| {
-            Foo::foobar_sync(
-                D("x", l.clone()),
-                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
-                D("_", l.clone()),
-                D("_y", l.clone()),
-            )
-        },
-    );
-
-    // Methods (see doc comment on function for what it tests).
-    let b = Bar(Default::default());
-    assert_drop_order_after_poll(|l| b.foo_async(D("x", l.clone()), D("_y", l.clone())),
-                                 |l| b.foo_sync(D("x", l.clone()), D("_y", l.clone())));
-    assert_drop_order_after_poll(|l| b.bar_async(D("x", l.clone()), D("_", l.clone())),
-                                 |l| b.bar_sync(D("x", l.clone()), D("_", l.clone())));
-    assert_drop_order_after_poll(|l| b.baz_async((D("x", l.clone()), D("_", l.clone()))),
-                                 |l| b.baz_sync((D("x", l.clone()), D("_", l.clone()))));
-    assert_drop_order_after_poll(
-        |l| {
-            b.foobar_async(
-                D("x", l.clone()),
-                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
-                D("_", l.clone()),
-                D("_y", l.clone()),
-            )
-        },
-        |l| {
-            b.foobar_sync(
-                D("x", l.clone()),
-                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
-                D("_", l.clone()),
-                D("_y", l.clone()),
-            )
-        },
-    );
-}
diff --git a/src/test/ui/async-await/drop-order-locals-are-hidden.rs b/src/test/ui/async-await/drop-order-locals-are-hidden.rs
deleted file mode 100644 (file)
index bcdb887..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// edition:2018
-
-#![allow(unused_variables)]
-#![feature(async_await)]
-
-async fn foobar_async(x: u32, (a, _, _c): (u32, u32, u32), _: u32, _y: u32) {
-    assert_eq!(__arg1, (1, 2, 3)); //~ ERROR cannot find value `__arg1` in this scope [E0425]
-    assert_eq!(__arg2, 4); //~ ERROR cannot find value `__arg2` in this scope [E0425]
-}
-
-async fn baz_async(ref mut x: u32, ref y: u32) {
-    assert_eq!(__arg0, 1); //~ ERROR cannot find value `__arg0` in this scope [E0425]
-    assert_eq!(__arg1, 2); //~ ERROR cannot find value `__arg1` in this scope [E0425]
-}
-
-fn main() {}
diff --git a/src/test/ui/async-await/drop-order-locals-are-hidden.stderr b/src/test/ui/async-await/drop-order-locals-are-hidden.stderr
deleted file mode 100644 (file)
index 484e1f4..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-error[E0425]: cannot find value `__arg1` in this scope
-  --> $DIR/drop-order-locals-are-hidden.rs:7:16
-   |
-LL |     assert_eq!(__arg1, (1, 2, 3));
-   |                ^^^^^^ not found in this scope
-
-error[E0425]: cannot find value `__arg2` in this scope
-  --> $DIR/drop-order-locals-are-hidden.rs:8:16
-   |
-LL |     assert_eq!(__arg2, 4);
-   |                ^^^^^^ not found in this scope
-
-error[E0425]: cannot find value `__arg0` in this scope
-  --> $DIR/drop-order-locals-are-hidden.rs:12:16
-   |
-LL |     assert_eq!(__arg0, 1);
-   |                ^^^^^^ not found in this scope
-
-error[E0425]: cannot find value `__arg1` in this scope
-  --> $DIR/drop-order-locals-are-hidden.rs:13:16
-   |
-LL |     assert_eq!(__arg1, 2);
-   |                ^^^^^^ not found in this scope
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/async-await/drop-order/auxiliary/arc_wake.rs b/src/test/ui/async-await/drop-order/auxiliary/arc_wake.rs
new file mode 100644 (file)
index 0000000..c21886f
--- /dev/null
@@ -0,0 +1,64 @@
+// edition:2018
+
+use std::sync::Arc;
+use std::task::{
+    Waker, RawWaker, RawWakerVTable,
+};
+
+macro_rules! waker_vtable {
+    ($ty:ident) => {
+        &RawWakerVTable::new(
+            clone_arc_raw::<$ty>,
+            wake_arc_raw::<$ty>,
+            wake_by_ref_arc_raw::<$ty>,
+            drop_arc_raw::<$ty>,
+        )
+    };
+}
+
+pub trait ArcWake {
+    fn wake(self: Arc<Self>);
+
+    fn wake_by_ref(arc_self: &Arc<Self>) {
+        arc_self.clone().wake()
+    }
+
+    fn into_waker(wake: Arc<Self>) -> Waker where Self: Sized
+    {
+        let ptr = Arc::into_raw(wake) as *const ();
+
+        unsafe {
+            Waker::from_raw(RawWaker::new(ptr, waker_vtable!(Self)))
+        }
+    }
+}
+
+unsafe fn increase_refcount<T: ArcWake>(data: *const ()) {
+    // Retain Arc by creating a copy
+    let arc: Arc<T> = Arc::from_raw(data as *const T);
+    let arc_clone = arc.clone();
+    // Forget the Arcs again, so that the refcount isn't decrased
+    let _ = Arc::into_raw(arc);
+    let _ = Arc::into_raw(arc_clone);
+}
+
+unsafe fn clone_arc_raw<T: ArcWake>(data: *const ()) -> RawWaker {
+    increase_refcount::<T>(data);
+    RawWaker::new(data, waker_vtable!(T))
+}
+
+unsafe fn drop_arc_raw<T: ArcWake>(data: *const ()) {
+    // Drop Arc
+    let _: Arc<T> = Arc::from_raw(data as *const T);
+}
+
+unsafe fn wake_arc_raw<T: ArcWake>(data: *const ()) {
+    let arc: Arc<T> = Arc::from_raw(data as *const T);
+    ArcWake::wake(arc);
+}
+
+unsafe fn wake_by_ref_arc_raw<T: ArcWake>(data: *const ()) {
+    let arc: Arc<T> = Arc::from_raw(data as *const T);
+    ArcWake::wake_by_ref(&arc);
+    let _ = Arc::into_raw(arc);
+}
diff --git a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs
new file mode 100644 (file)
index 0000000..c2b59ee
--- /dev/null
@@ -0,0 +1,271 @@
+// aux-build:arc_wake.rs
+// edition:2018
+// run-pass
+
+#![allow(unused_variables)]
+#![feature(async_await, await_macro)]
+
+// Test that the drop order for parameters in a fn and async fn matches up. Also test that
+// parameters (used or unused) are not dropped until the async fn completes execution.
+// See also #54716.
+
+extern crate arc_wake;
+
+use arc_wake::ArcWake;
+use std::cell::RefCell;
+use std::future::Future;
+use std::marker::PhantomData;
+use std::sync::Arc;
+use std::rc::Rc;
+use std::task::Context;
+
+struct EmptyWaker;
+
+impl ArcWake for EmptyWaker {
+    fn wake(self: Arc<Self>) {}
+}
+
+#[derive(Debug, Eq, PartialEq)]
+enum DropOrder {
+    Function,
+    Val(&'static str),
+}
+
+type DropOrderListPtr = Rc<RefCell<Vec<DropOrder>>>;
+
+struct D(&'static str, DropOrderListPtr);
+
+impl Drop for D {
+    fn drop(&mut self) {
+        self.1.borrow_mut().push(DropOrder::Val(self.0));
+    }
+}
+
+/// Check that unused bindings are dropped after the function is polled.
+async fn foo_async(ref mut x: D, ref mut _y: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+fn foo_sync(ref mut x: D, ref mut _y: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+/// Check that underscore patterns are dropped after the function is polled.
+async fn bar_async(ref mut x: D, _: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+fn bar_sync(ref mut x: D, _: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+/// Check that underscore patterns within more complex patterns are dropped after the function
+/// is polled.
+async fn baz_async((ref mut x, _): (D, D)) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+fn baz_sync((ref mut x, _): (D, D)) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+/// Check that underscore and unused bindings within and outwith more complex patterns are dropped
+/// after the function is polled.
+async fn foobar_async(ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+fn foobar_sync(ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+struct Foo;
+
+impl Foo {
+    /// Check that unused bindings are dropped after the method is polled.
+    async fn foo_async(ref mut x: D, ref mut _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn foo_sync(ref mut x: D, ref mut _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore patterns are dropped after the method is polled.
+    async fn bar_async(ref mut x: D, _: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn bar_sync(ref mut x: D, _: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore patterns within more complex patterns are dropped after the method
+    /// is polled.
+    async fn baz_async((ref mut x, _): (D, D)) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn baz_sync((ref mut x, _): (D, D)) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore and unused bindings within and outwith more complex patterns are
+    /// dropped after the method is polled.
+    async fn foobar_async(
+        ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
+    ) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn foobar_sync(
+        ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
+    ) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+}
+
+struct Bar<'a>(PhantomData<&'a ()>);
+
+impl<'a> Bar<'a> {
+    /// Check that unused bindings are dropped after the method with self is polled.
+    async fn foo_async(&'a self, ref mut x: D, ref mut _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn foo_sync(&'a self, ref mut x: D, ref mut _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore patterns are dropped after the method with self is polled.
+    async fn bar_async(&'a self, ref mut x: D, _: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn bar_sync(&'a self, ref mut x: D, _: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore patterns within more complex patterns are dropped after the method
+    /// with self is polled.
+    async fn baz_async(&'a self, (ref mut x, _): (D, D)) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn baz_sync(&'a self, (ref mut x, _): (D, D)) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore and unused bindings within and outwith more complex patterns are
+    /// dropped after the method with self is polled.
+    async fn foobar_async(
+        &'a self, ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
+    ) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn foobar_sync(
+        &'a self, ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
+    ) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+}
+
+fn assert_drop_order_after_poll<Fut: Future<Output = ()>>(
+    f: impl FnOnce(DropOrderListPtr) -> Fut,
+    g: impl FnOnce(DropOrderListPtr),
+) {
+    let empty = Arc::new(EmptyWaker);
+    let waker = ArcWake::into_waker(empty);
+    let mut cx = Context::from_waker(&waker);
+
+    let actual_order = Rc::new(RefCell::new(Vec::new()));
+    let mut fut = Box::pin(f(actual_order.clone()));
+    let _ = fut.as_mut().poll(&mut cx);
+
+    let expected_order = Rc::new(RefCell::new(Vec::new()));
+    g(expected_order.clone());
+
+    assert_eq!(*actual_order.borrow(), *expected_order.borrow());
+}
+
+fn main() {
+    // Free functions (see doc comment on function for what it tests).
+    assert_drop_order_after_poll(|l| foo_async(D("x", l.clone()), D("_y", l.clone())),
+                                 |l| foo_sync(D("x", l.clone()), D("_y", l.clone())));
+    assert_drop_order_after_poll(|l| bar_async(D("x", l.clone()), D("_", l.clone())),
+                                 |l| bar_sync(D("x", l.clone()), D("_", l.clone())));
+    assert_drop_order_after_poll(|l| baz_async((D("x", l.clone()), D("_", l.clone()))),
+                                 |l| baz_sync((D("x", l.clone()), D("_", l.clone()))));
+    assert_drop_order_after_poll(
+        |l| {
+            foobar_async(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+        |l| {
+            foobar_sync(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+    );
+
+    // Methods w/out self (see doc comment on function for what it tests).
+    assert_drop_order_after_poll(|l| Foo::foo_async(D("x", l.clone()), D("_y", l.clone())),
+                                 |l| Foo::foo_sync(D("x", l.clone()), D("_y", l.clone())));
+    assert_drop_order_after_poll(|l| Foo::bar_async(D("x", l.clone()), D("_", l.clone())),
+                                 |l| Foo::bar_sync(D("x", l.clone()), D("_", l.clone())));
+    assert_drop_order_after_poll(|l| Foo::baz_async((D("x", l.clone()), D("_", l.clone()))),
+                                 |l| Foo::baz_sync((D("x", l.clone()), D("_", l.clone()))));
+    assert_drop_order_after_poll(
+        |l| {
+            Foo::foobar_async(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+        |l| {
+            Foo::foobar_sync(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+    );
+
+    // Methods (see doc comment on function for what it tests).
+    let b = Bar(Default::default());
+    assert_drop_order_after_poll(|l| b.foo_async(D("x", l.clone()), D("_y", l.clone())),
+                                 |l| b.foo_sync(D("x", l.clone()), D("_y", l.clone())));
+    assert_drop_order_after_poll(|l| b.bar_async(D("x", l.clone()), D("_", l.clone())),
+                                 |l| b.bar_sync(D("x", l.clone()), D("_", l.clone())));
+    assert_drop_order_after_poll(|l| b.baz_async((D("x", l.clone()), D("_", l.clone()))),
+                                 |l| b.baz_sync((D("x", l.clone()), D("_", l.clone()))));
+    assert_drop_order_after_poll(
+        |l| {
+            b.foobar_async(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+        |l| {
+            b.foobar_sync(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+    );
+}
diff --git a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs
new file mode 100644 (file)
index 0000000..708c570
--- /dev/null
@@ -0,0 +1,263 @@
+// aux-build:arc_wake.rs
+// edition:2018
+// run-pass
+
+#![allow(unused_variables)]
+#![feature(async_await, await_macro)]
+
+// Test that the drop order for parameters in a fn and async fn matches up. Also test that
+// parameters (used or unused) are not dropped until the async fn completes execution.
+// See also #54716.
+
+extern crate arc_wake;
+
+use arc_wake::ArcWake;
+use std::cell::RefCell;
+use std::future::Future;
+use std::marker::PhantomData;
+use std::sync::Arc;
+use std::rc::Rc;
+use std::task::Context;
+
+struct EmptyWaker;
+
+impl ArcWake for EmptyWaker {
+    fn wake(self: Arc<Self>) {}
+}
+
+#[derive(Debug, Eq, PartialEq)]
+enum DropOrder {
+    Function,
+    Val(&'static str),
+}
+
+type DropOrderListPtr = Rc<RefCell<Vec<DropOrder>>>;
+
+struct D(&'static str, DropOrderListPtr);
+
+impl Drop for D {
+    fn drop(&mut self) {
+        self.1.borrow_mut().push(DropOrder::Val(self.0));
+    }
+}
+
+/// Check that unused bindings are dropped after the function is polled.
+async fn foo_async(x: D, _y: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+fn foo_sync(x: D, _y: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+/// Check that underscore patterns are dropped after the function is polled.
+async fn bar_async(x: D, _: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+fn bar_sync(x: D, _: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+/// Check that underscore patterns within more complex patterns are dropped after the function
+/// is polled.
+async fn baz_async((x, _): (D, D)) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+fn baz_sync((x, _): (D, D)) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+/// Check that underscore and unused bindings within and outwith more complex patterns are dropped
+/// after the function is polled.
+async fn foobar_async(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+fn foobar_sync(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+struct Foo;
+
+impl Foo {
+    /// Check that unused bindings are dropped after the method is polled.
+    async fn foo_async(x: D, _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn foo_sync(x: D, _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore patterns are dropped after the method is polled.
+    async fn bar_async(x: D, _: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn bar_sync(x: D, _: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore patterns within more complex patterns are dropped after the method
+    /// is polled.
+    async fn baz_async((x, _): (D, D)) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn baz_sync((x, _): (D, D)) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore and unused bindings within and outwith more complex patterns are
+    /// dropped after the method is polled.
+    async fn foobar_async(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn foobar_sync(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+}
+
+struct Bar<'a>(PhantomData<&'a ()>);
+
+impl<'a> Bar<'a> {
+    /// Check that unused bindings are dropped after the method with self is polled.
+    async fn foo_async(&'a self, x: D, _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn foo_sync(&'a self, x: D, _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore patterns are dropped after the method with self is polled.
+    async fn bar_async(&'a self, x: D, _: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn bar_sync(&'a self, x: D, _: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore patterns within more complex patterns are dropped after the method
+    /// with self is polled.
+    async fn baz_async(&'a self, (x, _): (D, D)) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn baz_sync(&'a self, (x, _): (D, D)) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    /// Check that underscore and unused bindings within and outwith more complex patterns are
+    /// dropped after the method with self is polled.
+    async fn foobar_async(&'a self, x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+
+    fn foobar_sync(&'a self, x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
+        x.1.borrow_mut().push(DropOrder::Function);
+    }
+}
+
+fn assert_drop_order_after_poll<Fut: Future<Output = ()>>(
+    f: impl FnOnce(DropOrderListPtr) -> Fut,
+    g: impl FnOnce(DropOrderListPtr),
+) {
+    let empty = Arc::new(EmptyWaker);
+    let waker = ArcWake::into_waker(empty);
+    let mut cx = Context::from_waker(&waker);
+
+    let actual_order = Rc::new(RefCell::new(Vec::new()));
+    let mut fut = Box::pin(f(actual_order.clone()));
+    let _ = fut.as_mut().poll(&mut cx);
+
+    let expected_order = Rc::new(RefCell::new(Vec::new()));
+    g(expected_order.clone());
+
+    assert_eq!(*actual_order.borrow(), *expected_order.borrow());
+}
+
+fn main() {
+    // Free functions (see doc comment on function for what it tests).
+    assert_drop_order_after_poll(|l| foo_async(D("x", l.clone()), D("_y", l.clone())),
+                                 |l| foo_sync(D("x", l.clone()), D("_y", l.clone())));
+    assert_drop_order_after_poll(|l| bar_async(D("x", l.clone()), D("_", l.clone())),
+                                 |l| bar_sync(D("x", l.clone()), D("_", l.clone())));
+    assert_drop_order_after_poll(|l| baz_async((D("x", l.clone()), D("_", l.clone()))),
+                                 |l| baz_sync((D("x", l.clone()), D("_", l.clone()))));
+    assert_drop_order_after_poll(
+        |l| {
+            foobar_async(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+        |l| {
+            foobar_sync(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+    );
+
+    // Methods w/out self (see doc comment on function for what it tests).
+    assert_drop_order_after_poll(|l| Foo::foo_async(D("x", l.clone()), D("_y", l.clone())),
+                                 |l| Foo::foo_sync(D("x", l.clone()), D("_y", l.clone())));
+    assert_drop_order_after_poll(|l| Foo::bar_async(D("x", l.clone()), D("_", l.clone())),
+                                 |l| Foo::bar_sync(D("x", l.clone()), D("_", l.clone())));
+    assert_drop_order_after_poll(|l| Foo::baz_async((D("x", l.clone()), D("_", l.clone()))),
+                                 |l| Foo::baz_sync((D("x", l.clone()), D("_", l.clone()))));
+    assert_drop_order_after_poll(
+        |l| {
+            Foo::foobar_async(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+        |l| {
+            Foo::foobar_sync(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+    );
+
+    // Methods (see doc comment on function for what it tests).
+    let b = Bar(Default::default());
+    assert_drop_order_after_poll(|l| b.foo_async(D("x", l.clone()), D("_y", l.clone())),
+                                 |l| b.foo_sync(D("x", l.clone()), D("_y", l.clone())));
+    assert_drop_order_after_poll(|l| b.bar_async(D("x", l.clone()), D("_", l.clone())),
+                                 |l| b.bar_sync(D("x", l.clone()), D("_", l.clone())));
+    assert_drop_order_after_poll(|l| b.baz_async((D("x", l.clone()), D("_", l.clone()))),
+                                 |l| b.baz_sync((D("x", l.clone()), D("_", l.clone()))));
+    assert_drop_order_after_poll(
+        |l| {
+            b.foobar_async(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+        |l| {
+            b.foobar_sync(
+                D("x", l.clone()),
+                (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
+                D("_", l.clone()),
+                D("_y", l.clone()),
+            )
+        },
+    );
+}
diff --git a/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.rs b/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.rs
new file mode 100644 (file)
index 0000000..bcdb887
--- /dev/null
@@ -0,0 +1,16 @@
+// edition:2018
+
+#![allow(unused_variables)]
+#![feature(async_await)]
+
+async fn foobar_async(x: u32, (a, _, _c): (u32, u32, u32), _: u32, _y: u32) {
+    assert_eq!(__arg1, (1, 2, 3)); //~ ERROR cannot find value `__arg1` in this scope [E0425]
+    assert_eq!(__arg2, 4); //~ ERROR cannot find value `__arg2` in this scope [E0425]
+}
+
+async fn baz_async(ref mut x: u32, ref y: u32) {
+    assert_eq!(__arg0, 1); //~ ERROR cannot find value `__arg0` in this scope [E0425]
+    assert_eq!(__arg1, 2); //~ ERROR cannot find value `__arg1` in this scope [E0425]
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr b/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr
new file mode 100644 (file)
index 0000000..484e1f4
--- /dev/null
@@ -0,0 +1,27 @@
+error[E0425]: cannot find value `__arg1` in this scope
+  --> $DIR/drop-order-locals-are-hidden.rs:7:16
+   |
+LL |     assert_eq!(__arg1, (1, 2, 3));
+   |                ^^^^^^ not found in this scope
+
+error[E0425]: cannot find value `__arg2` in this scope
+  --> $DIR/drop-order-locals-are-hidden.rs:8:16
+   |
+LL |     assert_eq!(__arg2, 4);
+   |                ^^^^^^ not found in this scope
+
+error[E0425]: cannot find value `__arg0` in this scope
+  --> $DIR/drop-order-locals-are-hidden.rs:12:16
+   |
+LL |     assert_eq!(__arg0, 1);
+   |                ^^^^^^ not found in this scope
+
+error[E0425]: cannot find value `__arg1` in this scope
+  --> $DIR/drop-order-locals-are-hidden.rs:13:16
+   |
+LL |     assert_eq!(__arg1, 2);
+   |                ^^^^^^ not found in this scope
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.rs b/src/test/ui/async-await/edition-deny-async-fns-2015.rs
new file mode 100644 (file)
index 0000000..e1111f9
--- /dev/null
@@ -0,0 +1,34 @@
+// edition:2015
+
+#![feature(async_await)]
+
+async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
+
+fn baz() { async fn foo() {} } //~ ERROR `async fn` is not permitted in the 2015 edition
+
+async fn async_baz() { //~ ERROR `async fn` is not permitted in the 2015 edition
+    async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition
+}
+
+struct Foo {}
+
+impl Foo {
+    async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
+}
+
+trait Bar {
+    async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
+                      //~^ ERROR trait fns cannot be declared `async`
+}
+
+fn main() {
+    macro_rules! accept_item { ($x:item) => {} }
+
+    accept_item! {
+        async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
+    }
+
+    let inside_closure = || {
+        async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition
+    };
+}
diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
new file mode 100644 (file)
index 0000000..05a0612
--- /dev/null
@@ -0,0 +1,57 @@
+error[E0670]: `async fn` is not permitted in the 2015 edition
+  --> $DIR/edition-deny-async-fns-2015.rs:5:1
+   |
+LL | async fn foo() {}
+   | ^^^^^
+
+error[E0670]: `async fn` is not permitted in the 2015 edition
+  --> $DIR/edition-deny-async-fns-2015.rs:7:12
+   |
+LL | fn baz() { async fn foo() {} }
+   |            ^^^^^
+
+error[E0670]: `async fn` is not permitted in the 2015 edition
+  --> $DIR/edition-deny-async-fns-2015.rs:10:5
+   |
+LL |     async fn bar() {}
+   |     ^^^^^
+
+error[E0670]: `async fn` is not permitted in the 2015 edition
+  --> $DIR/edition-deny-async-fns-2015.rs:9:1
+   |
+LL | async fn async_baz() {
+   | ^^^^^
+
+error[E0670]: `async fn` is not permitted in the 2015 edition
+  --> $DIR/edition-deny-async-fns-2015.rs:32:9
+   |
+LL |         async fn bar() {}
+   |         ^^^^^
+
+error[E0670]: `async fn` is not permitted in the 2015 edition
+  --> $DIR/edition-deny-async-fns-2015.rs:28:9
+   |
+LL |         async fn foo() {}
+   |         ^^^^^
+
+error[E0670]: `async fn` is not permitted in the 2015 edition
+  --> $DIR/edition-deny-async-fns-2015.rs:16:5
+   |
+LL |     async fn foo() {}
+   |     ^^^^^
+
+error[E0706]: trait fns cannot be declared `async`
+  --> $DIR/edition-deny-async-fns-2015.rs:20:5
+   |
+LL |     async fn foo() {}
+   |     ^^^^^^^^^^^^^^^^^
+
+error[E0670]: `async fn` is not permitted in the 2015 edition
+  --> $DIR/edition-deny-async-fns-2015.rs:20:5
+   |
+LL |     async fn foo() {}
+   |     ^^^^^
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0670`.
diff --git a/src/test/ui/async-await/issue-60518.rs b/src/test/ui/async-await/issue-60518.rs
deleted file mode 100644 (file)
index f603c5b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// compile-pass
-// edition:2018
-
-#![feature(async_await)]
-
-// This is a regression test to ensure that simple bindings (where replacement arguments aren't
-// created during async fn lowering) that have their DefId used during HIR lowering (such as impl
-// trait) are visited during def collection and thus have a DefId.
-
-async fn foo(ws: impl Iterator<Item = ()>) {}
-
-fn main() {}
diff --git a/src/test/ui/async-await/issue-60674.rs b/src/test/ui/async-await/issue-60674.rs
deleted file mode 100644 (file)
index ecb8080..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// aux-build:issue-60674.rs
-// compile-pass
-// edition:2018
-#![feature(async_await)]
-
-// This is a regression test that ensures that `mut` patterns are not lost when provided as input
-// to a proc macro.
-
-extern crate issue_60674;
-
-#[issue_60674::attr]
-async fn f(mut x: u8) {}
-
-#[issue_60674::attr]
-async fn g((mut x, y, mut z): (u8, u8, u8)) {}
-
-#[issue_60674::attr]
-async fn g(mut x: u8, (a, mut b, c): (u8, u8, u8), y: u8) {}
-
-fn main() {}
diff --git a/src/test/ui/async-await/issue-60674.stdout b/src/test/ui/async-await/issue-60674.stdout
deleted file mode 100644 (file)
index 86c3591..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-async fn f(mut x: u8) { }
-async fn g((mut x, y, mut z): (u8, u8, u8)) { }
-async fn g(mut x: u8, (a, mut b, c): (u8, u8, u8), y: u8) { }
diff --git a/src/test/ui/async-await/issues/auxiliary/issue-60674.rs b/src/test/ui/async-await/issues/auxiliary/issue-60674.rs
new file mode 100644 (file)
index 0000000..680c6e5
--- /dev/null
@@ -0,0 +1,12 @@
+// force-host
+// no-prefer-dynamic
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro_attribute]
+pub fn attr(_args: TokenStream, input: TokenStream) -> TokenStream {
+    println!("{}", input);
+    TokenStream::new()
+}
diff --git a/src/test/ui/async-await/issues/issue-51719.rs b/src/test/ui/async-await/issues/issue-51719.rs
new file mode 100644 (file)
index 0000000..5966edd
--- /dev/null
@@ -0,0 +1,13 @@
+// edition:2018
+//
+// Tests that the .await syntax can't be used to make a generator
+
+#![feature(async_await)]
+
+async fn foo() {}
+
+fn make_generator() {
+    let _gen = || foo.await; //~ ERROR `await` is only allowed inside `async` functions and blocks
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-51719.stderr b/src/test/ui/async-await/issues/issue-51719.stderr
new file mode 100644 (file)
index 0000000..c06165b
--- /dev/null
@@ -0,0 +1,10 @@
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/issue-51719.rs:10:19
+   |
+LL |     let _gen = || foo.await;
+   |                -- ^^^^^^^^^ only allowed inside `async` functions and blocks
+   |                |
+   |                this is not `async`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/issues/issue-51751.rs b/src/test/ui/async-await/issues/issue-51751.rs
new file mode 100644 (file)
index 0000000..7afd7ec
--- /dev/null
@@ -0,0 +1,13 @@
+// edition:2018
+
+#![feature(async_await)]
+
+async fn inc(limit: i64) -> i64 {
+    limit + 1
+}
+
+fn main() {
+    let result = inc(10000);
+    let finished = result.await;
+    //~^ ERROR `await` is only allowed inside `async` functions and blocks
+}
diff --git a/src/test/ui/async-await/issues/issue-51751.stderr b/src/test/ui/async-await/issues/issue-51751.stderr
new file mode 100644 (file)
index 0000000..97b63d1
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/issue-51751.rs:11:20
+   |
+LL | fn main() {
+   |    ---- this is not `async`
+LL |     let result = inc(10000);
+LL |     let finished = result.await;
+   |                    ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/issues/issue-53249.rs b/src/test/ui/async-await/issues/issue-53249.rs
new file mode 100644 (file)
index 0000000..9e4ff43
--- /dev/null
@@ -0,0 +1,47 @@
+// compile-pass
+// edition:2018
+
+#![feature(arbitrary_self_types, async_await, await_macro)]
+
+use std::task::{self, Poll};
+use std::future::Future;
+use std::marker::Unpin;
+use std::pin::Pin;
+
+// This is a regression test for a ICE/unbounded recursion issue relating to async-await.
+
+#[derive(Debug)]
+#[must_use = "futures do nothing unless polled"]
+pub struct Lazy<F> {
+    f: Option<F>
+}
+
+impl<F> Unpin for Lazy<F> {}
+
+pub fn lazy<F, R>(f: F) -> Lazy<F>
+    where F: FnOnce(&mut task::Context) -> R,
+{
+    Lazy { f: Some(f) }
+}
+
+impl<R, F> Future for Lazy<F>
+    where F: FnOnce(&mut task::Context) -> R,
+{
+    type Output = R;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context) -> Poll<R> {
+        Poll::Ready((self.f.take().unwrap())(cx))
+    }
+}
+
+async fn __receive<WantFn, Fut>(want: WantFn) -> ()
+    where Fut: Future<Output = ()>, WantFn: Fn(&Box<Send + 'static>) -> Fut,
+{
+    await!(lazy(|_| ()));
+}
+
+pub fn basic_spawn_receive() {
+    async { await!(__receive(|_| async { () })) };
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-54752-async-block.rs b/src/test/ui/async-await/issues/issue-54752-async-block.rs
new file mode 100644 (file)
index 0000000..0036de9
--- /dev/null
@@ -0,0 +1,9 @@
+// run-pass
+
+// edition:2018
+// pp-exact
+
+#![feature(async_await)]
+#![allow(unused_parens)]
+
+fn main() { let _a = (async  { }); }
diff --git a/src/test/ui/async-await/issues/issue-54974.rs b/src/test/ui/async-await/issues/issue-54974.rs
new file mode 100644 (file)
index 0000000..d6f1887
--- /dev/null
@@ -0,0 +1,16 @@
+// compile-pass
+// edition:2018
+
+#![feature(async_await, await_macro)]
+
+use std::sync::Arc;
+
+trait SomeTrait: Send + Sync + 'static {
+    fn do_something(&self);
+}
+
+async fn my_task(obj: Arc<SomeTrait>) {
+    unimplemented!()
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-55324.rs b/src/test/ui/async-await/issues/issue-55324.rs
new file mode 100644 (file)
index 0000000..4572e54
--- /dev/null
@@ -0,0 +1,14 @@
+// compile-pass
+// edition:2018
+
+#![feature(async_await, await_macro)]
+
+use std::future::Future;
+
+#[allow(unused)]
+async fn foo<F: Future<Output = i32>>(x: &i32, future: F) -> i32 {
+    let y = await!(future);
+    *x + y
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-55809.rs b/src/test/ui/async-await/issues/issue-55809.rs
new file mode 100644 (file)
index 0000000..b7e60b7
--- /dev/null
@@ -0,0 +1,30 @@
+// edition:2018
+// run-pass
+
+#![feature(async_await)]
+
+trait Foo { }
+
+impl Foo for () { }
+
+impl<'a, T> Foo for &'a mut T where T: Foo { }
+
+async fn foo_async<T>(_v: T) -> u8 where T: Foo {
+    0
+}
+
+async fn bad<T>(v: T) -> u8 where T: Foo {
+    foo_async(v).await
+}
+
+async fn async_main() {
+    let mut v = ();
+
+    let _ = bad(&mut v).await;
+    let _ = foo_async(&mut v).await;
+    let _ = bad(v).await;
+}
+
+fn main() {
+    let _ = async_main();
+}
diff --git a/src/test/ui/async-await/issues/issue-58885.rs b/src/test/ui/async-await/issues/issue-58885.rs
new file mode 100644 (file)
index 0000000..99d87b2
--- /dev/null
@@ -0,0 +1,21 @@
+// compile-pass
+// edition:2018
+
+#![feature(async_await, await_macro)]
+
+struct Xyz {
+    a: u64,
+}
+
+trait Foo {}
+
+impl Xyz {
+    async fn do_sth<'a>(
+        &'a self, foo: &'a dyn Foo
+    ) -> bool
+    {
+        true
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-59001.rs b/src/test/ui/async-await/issues/issue-59001.rs
new file mode 100644 (file)
index 0000000..c758244
--- /dev/null
@@ -0,0 +1,17 @@
+// compile-pass
+// edition:2018
+
+#![feature(async_await, await_macro)]
+
+use std::future::Future;
+
+#[allow(unused)]
+async fn enter<'a, F, R>(mut callback: F)
+where
+    F: FnMut(&'a mut i32) -> R,
+    R: Future<Output = ()> + 'a,
+{
+    unimplemented!()
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-59972.rs b/src/test/ui/async-await/issues/issue-59972.rs
new file mode 100644 (file)
index 0000000..31e7a65
--- /dev/null
@@ -0,0 +1,25 @@
+// run-pass
+
+// compile-flags: --edition=2018
+
+#![feature(async_await, await_macro)]
+
+pub enum Uninhabited { }
+
+fn uninhabited_async() -> Uninhabited {
+    unreachable!()
+}
+
+async fn noop() { }
+
+#[allow(unused)]
+async fn contains_never() {
+    let error = uninhabited_async();
+    await!(noop());
+    let error2 = error;
+}
+
+#[allow(unused_must_use)]
+fn main() {
+    contains_never();
+}
diff --git a/src/test/ui/async-await/issues/issue-60518.rs b/src/test/ui/async-await/issues/issue-60518.rs
new file mode 100644 (file)
index 0000000..f603c5b
--- /dev/null
@@ -0,0 +1,12 @@
+// compile-pass
+// edition:2018
+
+#![feature(async_await)]
+
+// This is a regression test to ensure that simple bindings (where replacement arguments aren't
+// created during async fn lowering) that have their DefId used during HIR lowering (such as impl
+// trait) are visited during def collection and thus have a DefId.
+
+async fn foo(ws: impl Iterator<Item = ()>) {}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs b/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs
new file mode 100644 (file)
index 0000000..a4fe865
--- /dev/null
@@ -0,0 +1,30 @@
+// Test that existential types are allowed to contain late-bound regions.
+
+// compile-pass
+// edition:2018
+
+#![feature(async_await, existential_type)]
+
+use std::future::Future;
+
+pub existential type Func: Sized;
+
+// Late bound region should be allowed to escape the function, since it's bound
+// in the type.
+fn null_function_ptr() -> Func {
+    None::<for<'a> fn(&'a ())>
+}
+
+async fn async_nop(_: &u8) {}
+
+pub existential type ServeFut: Future<Output=()>;
+
+// Late bound regions occur in the generator witness type here.
+fn serve() -> ServeFut {
+    async move {
+        let x = 5;
+        async_nop(&x).await
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-60674.rs b/src/test/ui/async-await/issues/issue-60674.rs
new file mode 100644 (file)
index 0000000..ecb8080
--- /dev/null
@@ -0,0 +1,20 @@
+// aux-build:issue-60674.rs
+// compile-pass
+// edition:2018
+#![feature(async_await)]
+
+// This is a regression test that ensures that `mut` patterns are not lost when provided as input
+// to a proc macro.
+
+extern crate issue_60674;
+
+#[issue_60674::attr]
+async fn f(mut x: u8) {}
+
+#[issue_60674::attr]
+async fn g((mut x, y, mut z): (u8, u8, u8)) {}
+
+#[issue_60674::attr]
+async fn g(mut x: u8, (a, mut b, c): (u8, u8, u8), y: u8) {}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-60674.stdout b/src/test/ui/async-await/issues/issue-60674.stdout
new file mode 100644 (file)
index 0000000..86c3591
--- /dev/null
@@ -0,0 +1,3 @@
+async fn f(mut x: u8) { }
+async fn g((mut x, y, mut z): (u8, u8, u8)) { }
+async fn g(mut x: u8, (a, mut b, c): (u8, u8, u8), y: u8) { }
diff --git a/src/test/ui/async-await/no-args-non-move-async-closure.rs b/src/test/ui/async-await/no-args-non-move-async-closure.rs
new file mode 100644 (file)
index 0000000..345f19b
--- /dev/null
@@ -0,0 +1,8 @@
+// edition:2018
+
+#![feature(async_await, await_macro)]
+
+fn main() {
+    let _ = async |x: u8| {};
+    //~^ ERROR `async` non-`move` closures with arguments are not currently supported
+}
diff --git a/src/test/ui/async-await/no-args-non-move-async-closure.stderr b/src/test/ui/async-await/no-args-non-move-async-closure.stderr
new file mode 100644 (file)
index 0000000..1b4b862
--- /dev/null
@@ -0,0 +1,10 @@
+error[E0708]: `async` non-`move` closures with arguments are not currently supported
+  --> $DIR/no-args-non-move-async-closure.rs:6:13
+   |
+LL |     let _ = async |x: u8| {};
+   |             ^^^^^^^^^^^^^
+   |
+   = help: consider using `let` statements to manually capture variables by reference before entering an `async move` closure
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.rs b/src/test/ui/async-await/recursive-async-impl-trait-type.rs
new file mode 100644 (file)
index 0000000..a4e0801
--- /dev/null
@@ -0,0 +1,11 @@
+// edition:2018
+// Test that impl trait does not allow creating recursive types that are
+// otherwise forbidden when using `async` and `await`.
+
+#![feature(await_macro, async_await, generators)]
+
+async fn recursive_async_function() -> () { //~ ERROR
+    await!(recursive_async_function());
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr
new file mode 100644 (file)
index 0000000..abc9ff5
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0720]: opaque type expands to a recursive type
+  --> $DIR/recursive-async-impl-trait-type.rs:7:40
+   |
+LL | async fn recursive_async_function() -> () {
+   |                                        ^^ expands to self-referential type
+   |
+   = note: expanded type is `std::future::GenFuture<[static generator@$DIR/recursive-async-impl-trait-type.rs:7:43: 9:2 {impl std::future::Future, ()}]>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0720`.
diff --git a/src/test/ui/async-await/unresolved_type_param.rs b/src/test/ui/async-await/unresolved_type_param.rs
new file mode 100644 (file)
index 0000000..77174b0
--- /dev/null
@@ -0,0 +1,15 @@
+// Provoke an unresolved type error (T).
+// Error message should pinpoint the type parameter T as needing to be bound
+// (rather than give a general error message)
+// edition:2018
+#![feature(async_await)]
+async fn bar<T>() -> () {}
+
+async fn foo() {
+    bar().await;
+    //~^ ERROR type inside generator must be known in this context
+    //~| NOTE cannot infer type for `T`
+    //~| NOTE the type is part of the generator because of this `yield`
+    //~| NOTE in this expansion of desugaring of `await`
+}
+fn main() {}
diff --git a/src/test/ui/async-await/unresolved_type_param.stderr b/src/test/ui/async-await/unresolved_type_param.stderr
new file mode 100644 (file)
index 0000000..afb9adf
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0698]: type inside generator must be known in this context
+  --> $DIR/unresolved_type_param.rs:9:5
+   |
+LL |     bar().await;
+   |     ^^^ cannot infer type for `T`
+   |
+note: the type is part of the generator because of this `yield`
+  --> $DIR/unresolved_type_param.rs:9:5
+   |
+LL |     bar().await;
+   |     ^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0698`.
diff --git a/src/test/ui/async-fn-multiple-lifetimes.rs b/src/test/ui/async-fn-multiple-lifetimes.rs
deleted file mode 100644 (file)
index e3ac817..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// edition:2018
-
-#![feature(arbitrary_self_types, async_await, await_macro, pin)]
-
-use std::ops::Add;
-
-async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}
-//~^ ERROR ambiguous lifetime bound in `async fn`
-
-async fn multiple_hrtb_and_single_named_lifetime_ok<'c>(
-    _: impl for<'a> Add<&'a u8>,
-    _: impl for<'b> Add<&'b u8>,
-    _: &'c u8,
-) {}
-
-async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
-//~^ ambiguous lifetime bound in `async fn`
-
-fn main() {}
diff --git a/src/test/ui/async-fn-multiple-lifetimes.stderr b/src/test/ui/async-fn-multiple-lifetimes.stderr
deleted file mode 100644 (file)
index 8c3ee2b..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-error: ambiguous lifetime bound in `async fn`
-  --> $DIR/async-fn-multiple-lifetimes.rs:7:65
-   |
-LL | async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}
-   |                                                                 ^ neither `'a` nor `'b` outlives the other
-   |
-   = note: multiple unrelated lifetimes are not allowed in `async fn`.
-   = note: if you're using argument-position elided lifetimes, consider switching to a single named lifetime.
-
-error: ambiguous lifetime bound in `async fn`
-  --> $DIR/async-fn-multiple-lifetimes.rs:16:52
-   |
-LL | async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
-   |                                                    ^ the elided lifetimes here do not outlive one another
-   |
-   = note: multiple unrelated lifetimes are not allowed in `async fn`.
-   = note: if you're using argument-position elided lifetimes, consider switching to a single named lifetime.
-
-error: aborting due to 2 previous errors
-
diff --git a/src/test/ui/async-fn-path-elision.rs b/src/test/ui/async-fn-path-elision.rs
deleted file mode 100644 (file)
index 8db7631..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// edition:2018
-
-#![feature(async_await, await_macro)]
-#![allow(dead_code)]
-
-struct HasLifetime<'a>(&'a bool);
-
-async fn error(lt: HasLifetime) { //~ ERROR implicit elided lifetime not allowed here
-    if *lt.0 {}
-}
-
-fn no_error(lt: HasLifetime) {
-    if *lt.0 {}
-}
-
-fn main() {}
diff --git a/src/test/ui/async-fn-path-elision.stderr b/src/test/ui/async-fn-path-elision.stderr
deleted file mode 100644 (file)
index 3b311ba..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error[E0726]: implicit elided lifetime not allowed here
-  --> $DIR/async-fn-path-elision.rs:8:20
-   |
-LL | async fn error(lt: HasLifetime) {
-   |                    ^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/async-matches-expr.rs b/src/test/ui/async-matches-expr.rs
deleted file mode 100644 (file)
index f375d58..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// compile-pass
-// edition:2018
-
-#![feature(async_await, await_macro)]
-
-macro_rules! match_expr {
-    ($x:expr) => {}
-}
-
-fn main() {
-    match_expr!(async {});
-    match_expr!(async || {});
-}
diff --git a/src/test/ui/async-with-closure.rs b/src/test/ui/async-with-closure.rs
deleted file mode 100644 (file)
index 856a778..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// compile-pass
-// edition:2018
-
-#![feature(async_await, await_macro)]
-
-trait MyClosure {
-    type Args;
-}
-
-impl<R> MyClosure for dyn FnMut() -> R
-where R: 'static {
-    type Args = ();
-}
-
-struct MyStream<C: ?Sized + MyClosure> {
-    x: C::Args,
-}
-
-async fn get_future<C: ?Sized + MyClosure>(_stream: MyStream<C>) {}
-
-async fn f() {
-    let messages: MyStream<FnMut()> = unimplemented!();
-    await!(get_future(messages));
-}
-
-fn main() {}
diff --git a/src/test/ui/auxiliary/issue-59764.rs b/src/test/ui/auxiliary/issue-59764.rs
deleted file mode 100644 (file)
index a92eed9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-pub mod foo {
-    #[macro_export]
-    macro_rules! makro {
-        ($foo:ident) => {
-            fn $foo() { }
-        }
-    }
-
-    pub fn baz() {}
-
-    pub fn foobar() {}
-
-    pub mod barbaz {
-        pub fn barfoo() {}
-    }
-}
-
-pub fn foobaz() {}
diff --git a/src/test/ui/await-keyword/2015-edition-error-in-non-macro-position.rs b/src/test/ui/await-keyword/2015-edition-error-in-non-macro-position.rs
deleted file mode 100644 (file)
index c4f3f3e..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#![feature(async_await, await_macro)]
-#![allow(non_camel_case_types)]
-#![deny(keyword_idents)]
-
-mod outer_mod {
-    pub mod await { //~ ERROR `await` is a keyword in the 2018 edition
-    //~^ WARN this was previously accepted by the compiler
-        pub struct await; //~ ERROR `await` is a keyword in the 2018 edition
-        //~^ WARN this was previously accepted by the compiler
-    }
-}
-use outer_mod::await::await; //~ ERROR `await` is a keyword in the 2018 edition
-//~^ ERROR `await` is a keyword in the 2018 edition
-//~^^ WARN this was previously accepted by the compiler
-//~^^^ WARN this was previously accepted by the compiler
-
-struct Foo { await: () }
-//~^ ERROR `await` is a keyword in the 2018 edition
-//~^^ WARN this was previously accepted by the compiler
-
-impl Foo { fn await() {} }
-//~^ ERROR `await` is a keyword in the 2018 edition
-//~^^ WARN this was previously accepted by the compiler
-
-macro_rules! await {
-//~^ ERROR `await` is a keyword in the 2018 edition
-//~^^ WARN this was previously accepted by the compiler
-    () => {}
-}
-
-fn main() {
-    match await { await => {} } //~ ERROR `await` is a keyword in the 2018 edition
-    //~^ ERROR `await` is a keyword in the 2018 edition
-    //~^^ WARN this was previously accepted by the compiler
-    //~^^^ WARN this was previously accepted by the compiler
-}
diff --git a/src/test/ui/await-keyword/2015-edition-error-in-non-macro-position.stderr b/src/test/ui/await-keyword/2015-edition-error-in-non-macro-position.stderr
deleted file mode 100644 (file)
index 067ecd6..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-in-non-macro-position.rs:6:13
-   |
-LL |     pub mod await {
-   |             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-note: lint level defined here
-  --> $DIR/2015-edition-error-in-non-macro-position.rs:3:9
-   |
-LL | #![deny(keyword_idents)]
-   |         ^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-in-non-macro-position.rs:8:20
-   |
-LL |         pub struct await;
-   |                    ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-in-non-macro-position.rs:12:16
-   |
-LL | use outer_mod::await::await;
-   |                ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-in-non-macro-position.rs:12:23
-   |
-LL | use outer_mod::await::await;
-   |                       ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-in-non-macro-position.rs:17:14
-   |
-LL | struct Foo { await: () }
-   |              ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-in-non-macro-position.rs:21:15
-   |
-LL | impl Foo { fn await() {} }
-   |               ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-in-non-macro-position.rs:25:14
-   |
-LL | macro_rules! await {
-   |              ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-in-non-macro-position.rs:32:11
-   |
-LL |     match await { await => {} }
-   |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-in-non-macro-position.rs:32:19
-   |
-LL |     match await { await => {} }
-   |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: aborting due to 9 previous errors
-
diff --git a/src/test/ui/await-keyword/2015-edition-warning.fixed b/src/test/ui/await-keyword/2015-edition-warning.fixed
deleted file mode 100644 (file)
index c58496c..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// run-rustfix
-
-#![allow(non_camel_case_types)]
-#![deny(keyword_idents)]
-
-mod outer_mod {
-    pub mod r#await {
-//~^ ERROR `await` is a keyword
-//~| WARN was previously accepted
-        pub struct r#await;
-//~^ ERROR `await` is a keyword
-//~| WARN was previously accepted
-    }
-}
-use outer_mod::r#await::r#await;
-//~^ ERROR `await` is a keyword
-//~| ERROR `await` is a keyword
-//~| WARN was previously accepted
-//~| WARN was previously accepted
-
-fn main() {
-    match r#await { r#await => {} }
-//~^ ERROR `await` is a keyword
-//~| ERROR `await` is a keyword
-//~| WARN was previously accepted
-//~| WARN was previously accepted
-}
diff --git a/src/test/ui/await-keyword/2015-edition-warning.rs b/src/test/ui/await-keyword/2015-edition-warning.rs
deleted file mode 100644 (file)
index a7543a1..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// run-rustfix
-
-#![allow(non_camel_case_types)]
-#![deny(keyword_idents)]
-
-mod outer_mod {
-    pub mod await {
-//~^ ERROR `await` is a keyword
-//~| WARN was previously accepted
-        pub struct await;
-//~^ ERROR `await` is a keyword
-//~| WARN was previously accepted
-    }
-}
-use outer_mod::await::await;
-//~^ ERROR `await` is a keyword
-//~| ERROR `await` is a keyword
-//~| WARN was previously accepted
-//~| WARN was previously accepted
-
-fn main() {
-    match await { await => {} }
-//~^ ERROR `await` is a keyword
-//~| ERROR `await` is a keyword
-//~| WARN was previously accepted
-//~| WARN was previously accepted
-}
diff --git a/src/test/ui/await-keyword/2015-edition-warning.stderr b/src/test/ui/await-keyword/2015-edition-warning.stderr
deleted file mode 100644 (file)
index d9ae1b9..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-warning.rs:7:13
-   |
-LL |     pub mod await {
-   |             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-note: lint level defined here
-  --> $DIR/2015-edition-warning.rs:4:9
-   |
-LL | #![deny(keyword_idents)]
-   |         ^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-warning.rs:10:20
-   |
-LL |         pub struct await;
-   |                    ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-warning.rs:15:16
-   |
-LL | use outer_mod::await::await;
-   |                ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-warning.rs:15:23
-   |
-LL | use outer_mod::await::await;
-   |                       ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-warning.rs:22:11
-   |
-LL |     match await { await => {} }
-   |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-warning.rs:22:19
-   |
-LL |     match await { await => {} }
-   |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
-
-error: aborting due to 6 previous errors
-
diff --git a/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.rs b/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.rs
deleted file mode 100644 (file)
index f59f116..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// edition:2018
-
-#![allow(non_camel_case_types)]
-#![feature(async_await, await_macro)]
-
-mod outer_mod {
-    pub mod await { //~ ERROR expected identifier, found reserved keyword `await`
-        pub struct await; //~ ERROR expected identifier, found reserved keyword `await`
-    }
-}
-use self::outer_mod::await::await; //~ ERROR expected identifier, found reserved keyword `await`
-//~^ ERROR expected identifier, found reserved keyword `await`
-
-struct Foo { await: () }
-//~^ ERROR expected identifier, found reserved keyword `await`
-
-impl Foo { fn await() {} }
-//~^ ERROR expected identifier, found reserved keyword `await`
-
-macro_rules! await {
-//~^ ERROR expected identifier, found reserved keyword `await`
-    () => {}
-}
-
-fn main() {}
diff --git a/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.stderr b/src/test/ui/await-keyword/2018-edition-error-in-non-macro-position.stderr
deleted file mode 100644 (file)
index c4b82b2..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error-in-non-macro-position.rs:7:13
-   |
-LL |     pub mod await {
-   |             ^^^^^ expected identifier, found reserved keyword
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL |     pub mod r#await {
-   |             ^^^^^^^
-
-error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error-in-non-macro-position.rs:8:20
-   |
-LL |         pub struct await;
-   |                    ^^^^^ expected identifier, found reserved keyword
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL |         pub struct r#await;
-   |                    ^^^^^^^
-
-error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error-in-non-macro-position.rs:11:22
-   |
-LL | use self::outer_mod::await::await;
-   |                      ^^^^^ expected identifier, found reserved keyword
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL | use self::outer_mod::r#await::await;
-   |                      ^^^^^^^
-
-error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error-in-non-macro-position.rs:11:29
-   |
-LL | use self::outer_mod::await::await;
-   |                             ^^^^^ expected identifier, found reserved keyword
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL | use self::outer_mod::await::r#await;
-   |                             ^^^^^^^
-
-error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error-in-non-macro-position.rs:14:14
-   |
-LL | struct Foo { await: () }
-   |              ^^^^^ expected identifier, found reserved keyword
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL | struct Foo { r#await: () }
-   |              ^^^^^^^
-
-error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error-in-non-macro-position.rs:17:15
-   |
-LL | impl Foo { fn await() {} }
-   |               ^^^^^ expected identifier, found reserved keyword
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL | impl Foo { fn r#await() {} }
-   |               ^^^^^^^
-
-error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error-in-non-macro-position.rs:20:14
-   |
-LL | macro_rules! await {
-   |              ^^^^^ expected identifier, found reserved keyword
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL | macro_rules! r#await {
-   |              ^^^^^^^
-
-error: aborting due to 7 previous errors
-
diff --git a/src/test/ui/await-keyword/2018-edition-error.rs b/src/test/ui/await-keyword/2018-edition-error.rs
deleted file mode 100644 (file)
index d856869..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// edition:2018
-#![allow(non_camel_case_types)]
-
-mod outer_mod {
-    pub mod await { //~ ERROR expected identifier
-        pub struct await; //~ ERROR expected identifier
-    }
-}
-use self::outer_mod::await::await; //~ ERROR expected identifier
-    //~^ ERROR expected identifier, found reserved keyword `await`
-
-fn main() {}
diff --git a/src/test/ui/await-keyword/2018-edition-error.stderr b/src/test/ui/await-keyword/2018-edition-error.stderr
deleted file mode 100644 (file)
index 8afe5c1..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error.rs:5:13
-   |
-LL |     pub mod await {
-   |             ^^^^^ expected identifier, found reserved keyword
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL |     pub mod r#await {
-   |             ^^^^^^^
-
-error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error.rs:6:20
-   |
-LL |         pub struct await;
-   |                    ^^^^^ expected identifier, found reserved keyword
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL |         pub struct r#await;
-   |                    ^^^^^^^
-
-error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error.rs:9:22
-   |
-LL | use self::outer_mod::await::await;
-   |                      ^^^^^ expected identifier, found reserved keyword
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL | use self::outer_mod::r#await::await;
-   |                      ^^^^^^^
-
-error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error.rs:9:29
-   |
-LL | use self::outer_mod::await::await;
-   |                             ^^^^^ expected identifier, found reserved keyword
-help: you can escape reserved keywords to use them as identifiers
-   |
-LL | use self::outer_mod::await::r#await;
-   |                             ^^^^^^^
-
-error: aborting due to 4 previous errors
-
diff --git a/src/test/ui/await-keyword/incorrect-syntax-suggestions.rs b/src/test/ui/await-keyword/incorrect-syntax-suggestions.rs
deleted file mode 100644 (file)
index e1e5bdd..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-// edition:2018
-
-#![feature(async_await)]
-
-async fn bar() -> Result<(), ()> {
-    Ok(())
-}
-
-async fn foo1() -> Result<(), ()> {
-    let _ = await bar(); //~ ERROR incorrect use of `await`
-    Ok(())
-}
-async fn foo2() -> Result<(), ()> {
-    let _ = await? bar(); //~ ERROR incorrect use of `await`
-    Ok(())
-}
-async fn foo3() -> Result<(), ()> {
-    let _ = await bar()?; //~ ERROR incorrect use of `await`
-    //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
-    Ok(())
-}
-async fn foo21() -> Result<(), ()> {
-    let _ = await { bar() }; //~ ERROR incorrect use of `await`
-    Ok(())
-}
-async fn foo22() -> Result<(), ()> {
-    let _ = await(bar()); //~ ERROR incorrect use of `await`
-    Ok(())
-}
-async fn foo23() -> Result<(), ()> {
-    let _ = await { bar() }?; //~ ERROR incorrect use of `await`
-    Ok(())
-}
-async fn foo4() -> Result<(), ()> {
-    let _ = (await bar())?; //~ ERROR incorrect use of `await`
-    Ok(())
-}
-async fn foo5() -> Result<(), ()> {
-    let _ = bar().await(); //~ ERROR incorrect use of `await`
-    Ok(())
-}
-async fn foo6() -> Result<(), ()> {
-    let _ = bar().await()?; //~ ERROR incorrect use of `await`
-    Ok(())
-}
-async fn foo7() -> Result<(), ()> {
-    let _ = bar().await; // OK
-    Ok(())
-}
-async fn foo8() -> Result<(), ()> {
-    let _ = bar().await?; // OK
-    Ok(())
-}
-fn foo9() -> Result<(), ()> {
-    let _ = await bar(); //~ ERROR `await` is only allowed inside `async` functions and blocks
-    //~^ ERROR incorrect use of `await`
-    Ok(())
-}
-fn foo10() -> Result<(), ()> {
-    let _ = await? bar(); //~ ERROR `await` is only allowed inside `async` functions and blocks
-    //~^ ERROR incorrect use of `await`
-    Ok(())
-}
-fn foo11() -> Result<(), ()> {
-    let _ = await bar()?; //~ ERROR `await` is only allowed inside `async` functions and blocks
-    //~^ ERROR incorrect use of `await`
-    Ok(())
-}
-fn foo12() -> Result<(), ()> {
-    let _ = (await bar())?; //~ ERROR `await` is only allowed inside `async` functions and blocks
-    //~^ ERROR incorrect use of `await`
-    Ok(())
-}
-fn foo13() -> Result<(), ()> {
-    let _ = bar().await(); //~ ERROR `await` is only allowed inside `async` functions and blocks
-    //~^ ERROR incorrect use of `await`
-    Ok(())
-}
-fn foo14() -> Result<(), ()> {
-    let _ = bar().await()?; //~ ERROR `await` is only allowed inside `async` functions and blocks
-    //~^ ERROR incorrect use of `await`
-    Ok(())
-}
-fn foo15() -> Result<(), ()> {
-    let _ = bar().await; //~ ERROR `await` is only allowed inside `async` functions and blocks
-    Ok(())
-}
-fn foo16() -> Result<(), ()> {
-    let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks
-    Ok(())
-}
-fn foo24() -> Result<(), ()> {
-    fn foo() -> Result<(), ()> {
-        let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks
-        Ok(())
-    }
-    foo()
-}
-fn foo25() -> Result<(), ()> {
-    let foo = || {
-        let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks
-        Ok(())
-    };
-    foo()
-}
-
-fn main() {
-    match await { await => () }
-    //~^ ERROR expected expression, found `=>`
-    //~| ERROR incorrect use of `await`
-} //~ ERROR expected one of `.`, `?`, `{`, or an operator, found `}`
diff --git a/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/await-keyword/incorrect-syntax-suggestions.stderr
deleted file mode 100644 (file)
index 380da44..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:10:13
-   |
-LL |     let _ = await bar();
-   |             ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:14:13
-   |
-LL |     let _ = await? bar();
-   |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:18:13
-   |
-LL |     let _ = await bar()?;
-   |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:23:13
-   |
-LL |     let _ = await { bar() };
-   |             ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:27:13
-   |
-LL |     let _ = await(bar());
-   |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `(bar()).await`
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:31:13
-   |
-LL |     let _ = await { bar() }?;
-   |             ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:35:14
-   |
-LL |     let _ = (await bar())?;
-   |              ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:39:24
-   |
-LL |     let _ = bar().await();
-   |                        ^^ help: `await` is not a method call, remove the parentheses
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:43:24
-   |
-LL |     let _ = bar().await()?;
-   |                        ^^ help: `await` is not a method call, remove the parentheses
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:55:13
-   |
-LL |     let _ = await bar();
-   |             ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:60:13
-   |
-LL |     let _ = await? bar();
-   |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:65:13
-   |
-LL |     let _ = await bar()?;
-   |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:70:14
-   |
-LL |     let _ = (await bar())?;
-   |              ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:75:24
-   |
-LL |     let _ = bar().await();
-   |                        ^^ help: `await` is not a method call, remove the parentheses
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:80:24
-   |
-LL |     let _ = bar().await()?;
-   |                        ^^ help: `await` is not a method call, remove the parentheses
-
-error: expected expression, found `=>`
-  --> $DIR/incorrect-syntax-suggestions.rs:108:25
-   |
-LL |     match await { await => () }
-   |                   ----- ^^ expected expression
-   |                   |
-   |                   while parsing this incorrect await expression
-
-error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:108:11
-   |
-LL |     match await { await => () }
-   |           ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await`
-
-error: expected one of `.`, `?`, `{`, or an operator, found `}`
-  --> $DIR/incorrect-syntax-suggestions.rs:111:1
-   |
-LL |     match await { await => () }
-   |     -----                      - expected one of `.`, `?`, `{`, or an operator here
-   |     |
-   |     while parsing this match expression
-...
-LL | }
-   | ^ unexpected token
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:55:13
-   |
-LL | fn foo9() -> Result<(), ()> {
-   |    ---- this is not `async`
-LL |     let _ = await bar();
-   |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:60:13
-   |
-LL | fn foo10() -> Result<(), ()> {
-   |    ----- this is not `async`
-LL |     let _ = await? bar();
-   |             ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:65:13
-   |
-LL | fn foo11() -> Result<(), ()> {
-   |    ----- this is not `async`
-LL |     let _ = await bar()?;
-   |             ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:70:14
-   |
-LL | fn foo12() -> Result<(), ()> {
-   |    ----- this is not `async`
-LL |     let _ = (await bar())?;
-   |              ^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:75:13
-   |
-LL | fn foo13() -> Result<(), ()> {
-   |    ----- this is not `async`
-LL |     let _ = bar().await();
-   |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:80:13
-   |
-LL | fn foo14() -> Result<(), ()> {
-   |    ----- this is not `async`
-LL |     let _ = bar().await()?;
-   |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:85:13
-   |
-LL | fn foo15() -> Result<(), ()> {
-   |    ----- this is not `async`
-LL |     let _ = bar().await;
-   |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:89:13
-   |
-LL | fn foo16() -> Result<(), ()> {
-   |    ----- this is not `async`
-LL |     let _ = bar().await?;
-   |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:94:17
-   |
-LL |     fn foo() -> Result<(), ()> {
-   |        --- this is not `async`
-LL |         let _ = bar().await?;
-   |                 ^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:101:17
-   |
-LL |     let foo = || {
-   |               -- this is not `async`
-LL |         let _ = bar().await?;
-   |                 ^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
-  --> $DIR/incorrect-syntax-suggestions.rs:18:19
-   |
-LL |     let _ = await bar()?;
-   |                   ^^^^^^ the `?` operator cannot be applied to type `impl std::future::Future`
-   |
-   = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
-   = note: required by `std::ops::Try::into_result`
-
-error: aborting due to 29 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/await-keyword/post_expansion_error.rs b/src/test/ui/await-keyword/post_expansion_error.rs
deleted file mode 100644 (file)
index b4c899b..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// edition:2018
-
-macro_rules! r#await {
-    () => { println!("Hello, world!") }
-}
-
-fn main() {
-    await!()
-    //~^ ERROR expected expression, found `)`
-}
diff --git a/src/test/ui/await-keyword/post_expansion_error.stderr b/src/test/ui/await-keyword/post_expansion_error.stderr
deleted file mode 100644 (file)
index 4e52597..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-error: expected expression, found `)`
-  --> $DIR/post_expansion_error.rs:8:12
-   |
-LL |     await!()
-   |     -----  ^ expected expression
-   |     |
-   |     while parsing this await macro call
-
-error: aborting due to previous error
-
index 41287c259149754437a8e071597a502d8e7e6b61..c242b6c2c20a28047a87918c1ebe2385284ec52c 100644 (file)
@@ -1,7 +1,3 @@
-#![feature(core, fnbox)]
-
-use std::boxed::FnBox;
-
 struct FuncContainer {
     f1: fn(data: u8),
     f2: extern "C" fn(data: u8),
@@ -18,7 +14,7 @@ struct Obj<F> where F: FnOnce() -> u32 {
 }
 
 struct BoxedObj {
-    boxed_closure: Box<FnBox() -> u32>,
+    boxed_closure: Box<FnOnce() -> u32>,
 }
 
 struct Wrapper<F> where F: FnMut() -> u32 {
@@ -29,8 +25,8 @@ fn func() -> u32 {
     0
 }
 
-fn check_expression() -> Obj<Box<FnBox() -> u32>> {
-    Obj { closure: Box::new(|| 42_u32) as Box<FnBox() -> u32>, not_closure: 42 }
+fn check_expression() -> Obj<Box<FnOnce() -> u32>> {
+    Obj { closure: Box::new(|| 42_u32) as Box<FnOnce() -> u32>, not_closure: 42 }
 }
 
 fn main() {
@@ -48,7 +44,7 @@ fn main() {
     let boxed_fn = BoxedObj { boxed_closure: Box::new(func) };
     boxed_fn.boxed_closure();//~ ERROR no method named `boxed_closure` found
 
-    let boxed_closure = BoxedObj { boxed_closure: Box::new(|| 42_u32) as Box<FnBox() -> u32> };
+    let boxed_closure = BoxedObj { boxed_closure: Box::new(|| 42_u32) as Box<FnOnce() -> u32> };
     boxed_closure.boxed_closure();//~ ERROR no method named `boxed_closure` found
 
     // test expression writing in the notes
index 2107318d87b5bda7ccd86f59976f26d1ab55c27c..351cfef1b53ea0517de30663cd7a9b88ad62926e 100644 (file)
@@ -1,5 +1,5 @@
-error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-2392.rs:39:36: 39:41]>` in the current scope
-  --> $DIR/issue-2392.rs:40:15
+error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope
+  --> $DIR/issue-2392.rs:36:15
    |
 LL | struct Obj<F> where F: FnOnce() -> u32 {
    | -------------------------------------- method `closure` not found for this
@@ -11,8 +11,8 @@ help: to call the function stored in `closure`, surround the field access with p
 LL |     (o_closure.closure)();
    |     ^                 ^
 
-error[E0599]: no method named `not_closure` found for type `Obj<[closure@$DIR/issue-2392.rs:39:36: 39:41]>` in the current scope
-  --> $DIR/issue-2392.rs:42:15
+error[E0599]: no method named `not_closure` found for type `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope
+  --> $DIR/issue-2392.rs:38:15
    |
 LL | struct Obj<F> where F: FnOnce() -> u32 {
    | -------------------------------------- method `not_closure` not found for this
@@ -23,7 +23,7 @@ LL |     o_closure.not_closure();
    |               field, not a method
 
 error[E0599]: no method named `closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
-  --> $DIR/issue-2392.rs:46:12
+  --> $DIR/issue-2392.rs:42:12
    |
 LL | struct Obj<F> where F: FnOnce() -> u32 {
    | -------------------------------------- method `closure` not found for this
@@ -36,7 +36,7 @@ LL |     (o_func.closure)();
    |     ^              ^
 
 error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope
-  --> $DIR/issue-2392.rs:49:14
+  --> $DIR/issue-2392.rs:45:14
    |
 LL | struct BoxedObj {
    | --------------- method `boxed_closure` not found for this
@@ -49,7 +49,7 @@ LL |     (boxed_fn.boxed_closure)();
    |     ^                      ^
 
 error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope
-  --> $DIR/issue-2392.rs:52:19
+  --> $DIR/issue-2392.rs:48:19
    |
 LL | struct BoxedObj {
    | --------------- method `boxed_closure` not found for this
@@ -62,7 +62,7 @@ LL |     (boxed_closure.boxed_closure)();
    |     ^                           ^
 
 error[E0599]: no method named `closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
-  --> $DIR/issue-2392.rs:57:12
+  --> $DIR/issue-2392.rs:53:12
    |
 LL | struct Obj<F> where F: FnOnce() -> u32 {
    | -------------------------------------- method `closure` not found for this
@@ -75,7 +75,7 @@ LL |     (w.wrap.closure)();
    |     ^              ^
 
 error[E0599]: no method named `not_closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
-  --> $DIR/issue-2392.rs:59:12
+  --> $DIR/issue-2392.rs:55:12
    |
 LL | struct Obj<F> where F: FnOnce() -> u32 {
    | -------------------------------------- method `not_closure` not found for this
@@ -85,8 +85,8 @@ LL |     w.wrap.not_closure();
    |            |
    |            field, not a method
 
-error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<(dyn std::boxed::FnBox<(), Output = u32> + 'static)>>` in the current scope
-  --> $DIR/issue-2392.rs:62:24
+error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<(dyn std::ops::FnOnce() -> u32 + 'static)>>` in the current scope
+  --> $DIR/issue-2392.rs:58:24
    |
 LL | struct Obj<F> where F: FnOnce() -> u32 {
    | -------------------------------------- method `closure` not found for this
@@ -99,7 +99,7 @@ LL |     (check_expression().closure)();
    |     ^                          ^
 
 error[E0599]: no method named `f1` found for type `FuncContainer` in the current scope
-  --> $DIR/issue-2392.rs:68:31
+  --> $DIR/issue-2392.rs:64:31
    |
 LL | struct FuncContainer {
    | -------------------- method `f1` not found for this
@@ -112,7 +112,7 @@ LL |             ((*self.container).f1)(1);
    |             ^                    ^
 
 error[E0599]: no method named `f2` found for type `FuncContainer` in the current scope
-  --> $DIR/issue-2392.rs:69:31
+  --> $DIR/issue-2392.rs:65:31
    |
 LL | struct FuncContainer {
    | -------------------- method `f2` not found for this
@@ -125,7 +125,7 @@ LL |             ((*self.container).f2)(1);
    |             ^                    ^
 
 error[E0599]: no method named `f3` found for type `FuncContainer` in the current scope
-  --> $DIR/issue-2392.rs:70:31
+  --> $DIR/issue-2392.rs:66:31
    |
 LL | struct FuncContainer {
    | -------------------- method `f3` not found for this
index 5528c2fca6a3ba43e3ddba53fc864af54b789953..544cd05cdbebf9cb7a40964eb2fbfb6b01c02ff9 100644 (file)
@@ -8,7 +8,7 @@ error[E0282]: type annotations needed
   --> $DIR/cannot-infer-const-args.rs:9:5
    |
 LL |     foo();
-   |     ^^^ cannot infer type for `fn() -> usize {foo::<_>}`
+   |     ^^^ cannot infer type for `fn() -> usize {foo::<_: usize>}`
 
 error: aborting due to previous error
 
index 30ab1f4d5ec0d0d0340217fc9c475dd6e9480617..3cc6de5bc4285ce48465f066f61d2ed725f070be 100644 (file)
@@ -4,7 +4,7 @@ error[E0005]: refutable pattern in function argument: `&[]` not covered
 LL | const fn slice([a, b]: &[i32]) -> i32 {
    |                ^^^^^^ pattern `&[]` not covered
 
-error[E0723]: can only call other `const fn` within a `const fn`, but `const std::ops::Add::add` is not stable as `const fn`
+error[E0723]: can only call other `const fn` within a `const fn`, but `const <&i32 as std::ops::Add>::add` is not stable as `const fn`
   --> $DIR/const_let_refutable.rs:4:5
    |
 LL |     a + b
index 2ca76667bd118fb5c1bc2a95c329ad4d347594d4..cdd696ee7fbff06b1d4581a4e49929e8d02791d7 100644 (file)
@@ -4,7 +4,7 @@ error[E0005]: refutable pattern in function argument: `&[]` not covered
 LL | const fn slice([a, b]: &[i32]) -> i32 {
    |                ^^^^^^ pattern `&[]` not covered
 
-error[E0723]: can only call other `const fn` within a `const fn`, but `const std::ops::Add::add` is not stable as `const fn`
+error[E0723]: can only call other `const fn` within a `const fn`, but `const <&i32 as std::ops::Add>::add` is not stable as `const fn`
   --> $DIR/const_let_refutable.rs:4:5
    |
 LL |     a + b
index c936a550b3aca006107d387564d674fff0c24926..141664c109228a0d1fb6d87f2d7f5eb2674e829d 100644 (file)
@@ -2,7 +2,7 @@ error[E0557]: feature has been removed
   --> $DIR/deprecated_no_stack_check.rs:2:12
    |
 LL | #![feature(no_stack_check)]
-   |            ^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^ feature has been removed
 
 error: aborting due to previous error
 
index 7e0d8cdfc2f723f1b28a998a1c9d2de7643bfa20..fbdfbd1600d7a3eedd987731c03859316a363d75 100644 (file)
@@ -1,4 +1,4 @@
-#[deprecated = b"test"] //~ ERROR attribute must be of the form
+#[deprecated = b"test"] //~ ERROR malformed `deprecated` attribute
 fn foo() {}
 
 fn main() {}
index 28bc2e2c2d8f4ed6910677f822e74570bc68bec8..a82eed24814cf77a8bca11f8e3a909c711b13c83 100644 (file)
@@ -1,8 +1,16 @@
-error: attribute must be of the form `#[deprecated]` or `#[deprecated(/*opt*/ since = "version", /*opt*/ note = "reason)]` or `#[deprecated = "reason"]`
+error: malformed `deprecated` attribute input
   --> $DIR/invalid-literal.rs:1:1
    |
 LL | #[deprecated = b"test"]
    | ^^^^^^^^^^^^^^^^^^^^^^^
+help: the following are the possible correct uses
+   |
+LL | #[deprecated]
+   | ^^^^^^^^^^^^^
+LL | #[deprecated(/*opt*/ since = "version", /*opt*/ note = "reason")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[deprecated = "reason"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/e0119/auxiliary/complex_impl_support.rs b/src/test/ui/e0119/auxiliary/complex_impl_support.rs
deleted file mode 100644 (file)
index ad5bb10..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-use std::marker::PhantomData;
-
-pub trait External {}
-
-pub struct M<'a, 'b, 'c, T, U, V> {
-    a: PhantomData<&'a ()>,
-    b: PhantomData<&'b ()>,
-    c: PhantomData<&'c ()>,
-    d: PhantomData<T>,
-    e: PhantomData<U>,
-    f: PhantomData<V>,
-}
-
-impl<'a, 'b, 'c, T, U, V, W> External for (T, M<'a, 'b, 'c, Box<U>, V, W>)
-where
-    'b: 'a,
-    T: 'a,
-    U: (FnOnce(T) -> V) + 'static,
-    V: Iterator<Item=T> + Clone,
-    W: std::ops::Add,
-    W::Output: Copy,
-{}
diff --git a/src/test/ui/e0119/auxiliary/issue-23563-a.rs b/src/test/ui/e0119/auxiliary/issue-23563-a.rs
deleted file mode 100644 (file)
index 4e85bcc..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// Ref: https://github.com/rust-lang/rust/issues/23563#issuecomment-260751672
-
-pub trait LolTo<T> {
-    fn convert_to(&self) -> T;
-}
-
-pub trait LolInto<T>: Sized {
-    fn convert_into(self) -> T;
-}
-
-pub trait LolFrom<T> {
-    fn from(T) -> Self;
-}
-
-impl<'a, T: ?Sized, U> LolInto<U> for &'a T where T: LolTo<U> {
-    fn convert_into(self) -> U {
-        self.convert_to()
-    }
-}
-
-impl<T, U> LolFrom<T> for U where T: LolInto<U> {
-    fn from(t: T) -> U {
-        t.convert_into()
-    }
-}
diff --git a/src/test/ui/e0119/complex-impl.rs b/src/test/ui/e0119/complex-impl.rs
deleted file mode 100644 (file)
index 3cba39e..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// aux-build:complex_impl_support.rs
-
-extern crate complex_impl_support;
-
-use complex_impl_support::{External, M};
-
-struct Q;
-
-impl<R> External for (Q, R) {} //~ ERROR must be used
-//~^ ERROR conflicting implementations of trait
-
-fn main() {}
diff --git a/src/test/ui/e0119/complex-impl.stderr b/src/test/ui/e0119/complex-impl.stderr
deleted file mode 100644 (file)
index 7ed89a5..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-error[E0119]: conflicting implementations of trait `complex_impl_support::External` for type `(Q, complex_impl_support::M<'_, '_, '_, std::boxed::Box<_>, _, _>)`:
-  --> $DIR/complex-impl.rs:9:1
-   |
-LL | impl<R> External for (Q, R) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: conflicting implementation in crate `complex_impl_support`:
-           - impl<'a, 'b, 'c, T, U, V, W> complex_impl_support::External for (T, complex_impl_support::M<'a, 'b, 'c, std::boxed::Box<U>, V, W>)
-             where <U as std::ops::FnOnce<(T,)>>::Output == V, <V as std::iter::Iterator>::Item == T, 'b : 'a, T : 'a, U: std::ops::FnOnce<(T,)>, U : 'static, V: std::iter::Iterator, V: std::clone::Clone, W: std::ops::Add, <W as std::ops::Add>::Output: std::marker::Copy;
-
-error[E0210]: type parameter `R` must be used as the type parameter for some local type (e.g., `MyStruct<R>`)
-  --> $DIR/complex-impl.rs:9:1
-   |
-LL | impl<R> External for (Q, R) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `R` must be used as the type parameter for some local type
-   |
-   = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0119, E0210.
-For more information about an error, try `rustc --explain E0119`.
diff --git a/src/test/ui/e0119/conflict-with-std.rs b/src/test/ui/e0119/conflict-with-std.rs
deleted file mode 100644 (file)
index c9db2ba..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-use std::marker::PhantomData;
-use std::convert::{TryFrom, AsRef};
-
-struct Q;
-impl AsRef<Q> for Box<Q> { //~ ERROR conflicting implementations
-    fn as_ref(&self) -> &Q {
-        &**self
-    }
-}
-
-struct S;
-impl From<S> for S { //~ ERROR conflicting implementations
-    fn from(s: S) -> S {
-        s
-    }
-}
-
-struct X;
-impl TryFrom<X> for X { //~ ERROR conflicting implementations
-    type Error = ();
-    fn try_from(u: X) -> Result<X, ()> {
-        Ok(u)
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/e0119/conflict-with-std.stderr b/src/test/ui/e0119/conflict-with-std.stderr
deleted file mode 100644 (file)
index 3e0c71e..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-error[E0119]: conflicting implementations of trait `std::convert::AsRef<Q>` for type `std::boxed::Box<Q>`:
-  --> $DIR/conflict-with-std.rs:5:1
-   |
-LL | impl AsRef<Q> for Box<Q> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: conflicting implementation in crate `alloc`:
-           - impl<T> std::convert::AsRef<T> for std::boxed::Box<T>
-             where T: ?Sized;
-
-error[E0119]: conflicting implementations of trait `std::convert::From<S>` for type `S`:
-  --> $DIR/conflict-with-std.rs:12:1
-   |
-LL | impl From<S> for S {
-   | ^^^^^^^^^^^^^^^^^^
-   |
-   = note: conflicting implementation in crate `core`:
-           - impl<T> std::convert::From<T> for T;
-
-error[E0119]: conflicting implementations of trait `std::convert::TryFrom<X>` for type `X`:
-  --> $DIR/conflict-with-std.rs:19:1
-   |
-LL | impl TryFrom<X> for X {
-   | ^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: conflicting implementation in crate `core`:
-           - impl<T, U> std::convert::TryFrom<U> for T
-             where U: std::convert::Into<T>;
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/e0119/issue-23563.rs b/src/test/ui/e0119/issue-23563.rs
deleted file mode 100644 (file)
index f578560..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// aux-build:issue-23563-a.rs
-
-// Ref: https://github.com/rust-lang/rust/issues/23563#issuecomment-260751672
-
-extern crate issue_23563_a as a;
-
-use a::LolFrom;
-use a::LolInto;
-use a::LolTo;
-
-struct LocalType<T>(Option<T>);
-
-impl<'a, T> LolFrom<&'a [T]> for LocalType<T> { //~ ERROR conflicting implementations of trait
-    fn from(_: &'a [T]) -> LocalType<T> { LocalType(None) }
-}
-
-impl<T> LolInto<LocalType<T>> for LocalType<T> {
-    fn convert_into(self) -> LocalType<T> {
-        self
-    }
-}
-
-impl LolTo<LocalType<u8>> for [u8] {
-    fn convert_to(&self) -> LocalType<u8> {
-        LocalType(None)
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/e0119/issue-23563.stderr b/src/test/ui/e0119/issue-23563.stderr
deleted file mode 100644 (file)
index 8011689..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0119]: conflicting implementations of trait `a::LolFrom<&[_]>` for type `LocalType<_>`:
-  --> $DIR/issue-23563.rs:13:1
-   |
-LL | impl<'a, T> LolFrom<&'a [T]> for LocalType<T> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: conflicting implementation in crate `issue_23563_a`:
-           - impl<T, U> a::LolFrom<T> for U
-             where T: a::LolInto<U>;
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/e0119/issue-27403.rs b/src/test/ui/e0119/issue-27403.rs
deleted file mode 100644 (file)
index b03a564..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-pub struct GenX<S> {
-    inner: S,
-}
-
-impl<S> Into<S> for GenX<S> { //~ ERROR conflicting implementations
-    fn into(self) -> S {
-        self.inner
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/e0119/issue-27403.stderr b/src/test/ui/e0119/issue-27403.stderr
deleted file mode 100644 (file)
index cba1043..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0119]: conflicting implementations of trait `std::convert::Into<_>` for type `GenX<_>`:
-  --> $DIR/issue-27403.rs:5:1
-   |
-LL | impl<S> Into<S> for GenX<S> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: conflicting implementation in crate `core`:
-           - impl<T, U> std::convert::Into<U> for T
-             where U: std::convert::From<T>;
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/e0119/issue-28981.rs b/src/test/ui/e0119/issue-28981.rs
deleted file mode 100644 (file)
index c31b212..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-use std::ops::Deref;
-
-struct Foo;
-
-impl<Foo> Deref for Foo { } //~ ERROR must be used
-//~^ ERROR conflicting implementations
-
-fn main() {}
diff --git a/src/test/ui/e0119/issue-28981.stderr b/src/test/ui/e0119/issue-28981.stderr
deleted file mode 100644 (file)
index 70c83e1..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-error[E0119]: conflicting implementations of trait `std::ops::Deref` for type `&_`:
-  --> $DIR/issue-28981.rs:5:1
-   |
-LL | impl<Foo> Deref for Foo { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: conflicting implementation in crate `core`:
-           - impl<T> std::ops::Deref for &T
-             where T: ?Sized;
-
-error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g., `MyStruct<Foo>`)
-  --> $DIR/issue-28981.rs:5:1
-   |
-LL | impl<Foo> Deref for Foo { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^ type parameter `Foo` must be used as the type parameter for some local type
-   |
-   = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0119, E0210.
-For more information about an error, try `rustc --explain E0119`.
diff --git a/src/test/ui/e0119/so-37347311.rs b/src/test/ui/e0119/so-37347311.rs
deleted file mode 100644 (file)
index d5f624b..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Ref: https://stackoverflow.com/q/37347311
-
-trait Storage {
-    type Error;
-}
-
-enum MyError<S: Storage> {
-    StorageProblem(S::Error),
-}
-
-impl<S: Storage> From<S::Error> for MyError<S> { //~ ERROR conflicting implementations
-    fn from(error: S::Error) -> MyError<S> {
-        MyError::StorageProblem(error)
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/e0119/so-37347311.stderr b/src/test/ui/e0119/so-37347311.stderr
deleted file mode 100644 (file)
index f2166de..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0119]: conflicting implementations of trait `std::convert::From<MyError<_>>` for type `MyError<_>`:
-  --> $DIR/so-37347311.rs:11:1
-   |
-LL | impl<S: Storage> From<S::Error> for MyError<S> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: conflicting implementation in crate `core`:
-           - impl<T> std::convert::From<T> for T;
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/editions/edition-deny-async-fns-2015.rs b/src/test/ui/editions/edition-deny-async-fns-2015.rs
deleted file mode 100644 (file)
index e1111f9..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// edition:2015
-
-#![feature(async_await)]
-
-async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
-
-fn baz() { async fn foo() {} } //~ ERROR `async fn` is not permitted in the 2015 edition
-
-async fn async_baz() { //~ ERROR `async fn` is not permitted in the 2015 edition
-    async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition
-}
-
-struct Foo {}
-
-impl Foo {
-    async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
-}
-
-trait Bar {
-    async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
-                      //~^ ERROR trait fns cannot be declared `async`
-}
-
-fn main() {
-    macro_rules! accept_item { ($x:item) => {} }
-
-    accept_item! {
-        async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
-    }
-
-    let inside_closure = || {
-        async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition
-    };
-}
diff --git a/src/test/ui/editions/edition-deny-async-fns-2015.stderr b/src/test/ui/editions/edition-deny-async-fns-2015.stderr
deleted file mode 100644 (file)
index 05a0612..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:5:1
-   |
-LL | async fn foo() {}
-   | ^^^^^
-
-error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:7:12
-   |
-LL | fn baz() { async fn foo() {} }
-   |            ^^^^^
-
-error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:10:5
-   |
-LL |     async fn bar() {}
-   |     ^^^^^
-
-error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:9:1
-   |
-LL | async fn async_baz() {
-   | ^^^^^
-
-error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:32:9
-   |
-LL |         async fn bar() {}
-   |         ^^^^^
-
-error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:28:9
-   |
-LL |         async fn foo() {}
-   |         ^^^^^
-
-error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:16:5
-   |
-LL |     async fn foo() {}
-   |     ^^^^^
-
-error[E0706]: trait fns cannot be declared `async`
-  --> $DIR/edition-deny-async-fns-2015.rs:20:5
-   |
-LL |     async fn foo() {}
-   |     ^^^^^^^^^^^^^^^^^
-
-error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:20:5
-   |
-LL |     async fn foo() {}
-   |     ^^^^^
-
-error: aborting due to 9 previous errors
-
-For more information about this error, try `rustc --explain E0670`.
index 7c3093309f9e1b3f29206c8cd56c94cb3f5c0bb9..7f074168f8e02c42c67bca54f4d1866741c8092a 100644 (file)
@@ -1,8 +1,8 @@
-error[E0452]: malformed lint attribute
+error[E0452]: malformed lint attribute input
   --> $DIR/E0452.rs:1:10
    |
 LL | #![allow(foo = "")]
-   |          ^^^^^^^^
+   |          ^^^^^^^^ bad attribute argument
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0501.rs b/src/test/ui/error-codes/E0501.rs
new file mode 100644 (file)
index 0000000..3e39d9a
--- /dev/null
@@ -0,0 +1,24 @@
+fn inside_closure(x: &mut i32) {
+}
+
+fn outside_closure_1(x: &mut i32) {
+}
+
+fn outside_closure_2(x: &i32) {
+}
+
+fn foo(a: &mut i32) {
+    let bar = || {
+        inside_closure(a)
+    };
+    outside_closure_1(a);
+    //~^ ERROR cannot borrow `*a` as mutable because previous closure requires unique access
+
+    outside_closure_2(a);
+    //~^ ERROR cannot borrow `*a` as immutable because previous closure requires unique access
+
+    drop(bar);
+}
+
+fn main() {
+}
diff --git a/src/test/ui/error-codes/E0501.stderr b/src/test/ui/error-codes/E0501.stderr
new file mode 100644 (file)
index 0000000..53d98d7
--- /dev/null
@@ -0,0 +1,31 @@
+error[E0501]: cannot borrow `*a` as mutable because previous closure requires unique access
+  --> $DIR/E0501.rs:14:23
+   |
+LL |     let bar = || {
+   |               -- closure construction occurs here
+LL |         inside_closure(a)
+   |                        - first borrow occurs due to use of `a` in closure
+LL |     };
+LL |     outside_closure_1(a);
+   |                       ^ second borrow occurs here
+...
+LL |     drop(bar);
+   |          --- first borrow later used here
+
+error[E0501]: cannot borrow `*a` as immutable because previous closure requires unique access
+  --> $DIR/E0501.rs:17:23
+   |
+LL |     let bar = || {
+   |               -- closure construction occurs here
+LL |         inside_closure(a)
+   |                        - first borrow occurs due to use of `a` in closure
+...
+LL |     outside_closure_2(a);
+   |                       ^ second borrow occurs here
+...
+LL |     drop(bar);
+   |          --- first borrow later used here
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0501`.
diff --git a/src/test/ui/error-codes/E0506.rs b/src/test/ui/error-codes/E0506.rs
new file mode 100644 (file)
index 0000000..062a44a
--- /dev/null
@@ -0,0 +1,11 @@
+struct FancyNum {
+    num: u8,
+}
+
+fn main() {
+    let mut fancy_num = FancyNum { num: 5 };
+    let fancy_ref = &fancy_num;
+    fancy_num = FancyNum { num: 6 }; //~ ERROR [E0506]
+
+    println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
+}
diff --git a/src/test/ui/error-codes/E0506.stderr b/src/test/ui/error-codes/E0506.stderr
new file mode 100644 (file)
index 0000000..17f883f
--- /dev/null
@@ -0,0 +1,14 @@
+error[E0506]: cannot assign to `fancy_num` because it is borrowed
+  --> $DIR/E0506.rs:8:5
+   |
+LL |     let fancy_ref = &fancy_num;
+   |                     ---------- borrow of `fancy_num` occurs here
+LL |     fancy_num = FancyNum { num: 6 };
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `fancy_num` occurs here
+LL | 
+LL |     println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
+   |                                                 ------------- borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0506`.
diff --git a/src/test/ui/error-codes/E0508-fail.rs b/src/test/ui/error-codes/E0508-fail.rs
new file mode 100644 (file)
index 0000000..072c3d6
--- /dev/null
@@ -0,0 +1,6 @@
+struct NonCopy;
+
+fn main() {
+    let array = [NonCopy; 1];
+    let _value = array[0];  //~ ERROR [E0508]
+}
diff --git a/src/test/ui/error-codes/E0508-fail.stderr b/src/test/ui/error-codes/E0508-fail.stderr
new file mode 100644 (file)
index 0000000..63590be
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
+  --> $DIR/E0508-fail.rs:5:18
+   |
+LL |     let _value = array[0];
+   |                  ^^^^^^^^
+   |                  |
+   |                  cannot move out of here
+   |                  help: consider borrowing here: `&array[0]`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0508`.
diff --git a/src/test/ui/error-codes/E0508.rs b/src/test/ui/error-codes/E0508.rs
new file mode 100644 (file)
index 0000000..072c3d6
--- /dev/null
@@ -0,0 +1,6 @@
+struct NonCopy;
+
+fn main() {
+    let array = [NonCopy; 1];
+    let _value = array[0];  //~ ERROR [E0508]
+}
diff --git a/src/test/ui/error-codes/E0508.stderr b/src/test/ui/error-codes/E0508.stderr
new file mode 100644 (file)
index 0000000..983062e
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
+  --> $DIR/E0508.rs:5:18
+   |
+LL |     let _value = array[0];
+   |                  ^^^^^^^^
+   |                  |
+   |                  cannot move out of here
+   |                  help: consider borrowing here: `&array[0]`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0508`.
diff --git a/src/test/ui/error-codes/E0583.rs b/src/test/ui/error-codes/E0583.rs
new file mode 100644 (file)
index 0000000..969de79
--- /dev/null
@@ -0,0 +1,4 @@
+mod module_that_doesnt_exist; //~ ERROR E0583
+
+fn main() {
+}
diff --git a/src/test/ui/error-codes/E0583.stderr b/src/test/ui/error-codes/E0583.stderr
new file mode 100644 (file)
index 0000000..ef7a48b
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0583]: file not found for module `module_that_doesnt_exist`
+  --> $DIR/E0583.rs:1:5
+   |
+LL | mod module_that_doesnt_exist;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: name the file either module_that_doesnt_exist.rs or module_that_doesnt_exist/mod.rs inside the directory "$DIR"
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0583`.
diff --git a/src/test/ui/error-codes/E0594.rs b/src/test/ui/error-codes/E0594.rs
new file mode 100644 (file)
index 0000000..8b0cae7
--- /dev/null
@@ -0,0 +1,5 @@
+static NUM: i32 = 18;
+
+fn main() {
+    NUM = 20; //~ ERROR cannot assign to immutable static item `NUM`
+}
diff --git a/src/test/ui/error-codes/E0594.stderr b/src/test/ui/error-codes/E0594.stderr
new file mode 100644 (file)
index 0000000..c00ec42
--- /dev/null
@@ -0,0 +1,8 @@
+error[E0594]: cannot assign to immutable static item `NUM`
+  --> $DIR/E0594.rs:4:5
+   |
+LL |     NUM = 20;
+   |     ^^^^^^^^ cannot assign
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/error-codes/E0596.rs b/src/test/ui/error-codes/E0596.rs
new file mode 100644 (file)
index 0000000..9e2f5ee
--- /dev/null
@@ -0,0 +1,4 @@
+fn main() {
+    let x = 1;
+    let y = &mut x; //~ ERROR [E0596]
+}
diff --git a/src/test/ui/error-codes/E0596.stderr b/src/test/ui/error-codes/E0596.stderr
new file mode 100644 (file)
index 0000000..79bc258
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
+  --> $DIR/E0596.rs:3:13
+   |
+LL |     let x = 1;
+   |         - help: consider changing this to be mutable: `mut x`
+LL |     let y = &mut x;
+   |             ^^^^^^ cannot borrow as mutable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/error-codes/E0642.rs b/src/test/ui/error-codes/E0642.rs
new file mode 100644 (file)
index 0000000..cfbd362
--- /dev/null
@@ -0,0 +1,16 @@
+#[derive(Clone, Copy)]
+struct S;
+
+trait T {
+    fn foo((x, y): (i32, i32)); //~ ERROR patterns aren't allowed in methods without bodies
+
+    fn bar((x, y): (i32, i32)) {} //~ ERROR patterns aren't allowed in methods without bodies
+
+    fn method(S { .. }: S) {} //~ ERROR patterns aren't allowed in methods without bodies
+
+    fn f(&ident: &S) {} // ok
+    fn g(&&ident: &&S) {} // ok
+    fn h(mut ident: S) {} // ok
+}
+
+fn main() {}
diff --git a/src/test/ui/error-codes/E0642.stderr b/src/test/ui/error-codes/E0642.stderr
new file mode 100644 (file)
index 0000000..da25514
--- /dev/null
@@ -0,0 +1,33 @@
+error[E0642]: patterns aren't allowed in methods without bodies
+  --> $DIR/E0642.rs:5:12
+   |
+LL |     fn foo((x, y): (i32, i32));
+   |            ^^^^^^
+help: give this argument a name or use an underscore to ignore it
+   |
+LL |     fn foo(_: (i32, i32));
+   |            ^
+
+error[E0642]: patterns aren't allowed in methods without bodies
+  --> $DIR/E0642.rs:7:12
+   |
+LL |     fn bar((x, y): (i32, i32)) {}
+   |            ^^^^^^
+help: give this argument a name or use an underscore to ignore it
+   |
+LL |     fn bar(_: (i32, i32)) {}
+   |            ^
+
+error[E0642]: patterns aren't allowed in methods without bodies
+  --> $DIR/E0642.rs:9:15
+   |
+LL |     fn method(S { .. }: S) {}
+   |               ^^^^^^^^
+help: give this argument a name or use an underscore to ignore it
+   |
+LL |     fn method(_: S) {}
+   |               ^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0642`.
diff --git a/src/test/ui/error-codes/E0660.rs b/src/test/ui/error-codes/E0660.rs
new file mode 100644 (file)
index 0000000..6280d39
--- /dev/null
@@ -0,0 +1,9 @@
+#![feature(asm)]
+
+fn main() {
+    let a;
+    asm!("nop" "nop");
+    //~^ ERROR E0660
+    asm!("nop" "nop" : "=r"(a));
+    //~^ ERROR E0660
+}
diff --git a/src/test/ui/error-codes/E0660.stderr b/src/test/ui/error-codes/E0660.stderr
new file mode 100644 (file)
index 0000000..ce34a9b
--- /dev/null
@@ -0,0 +1,14 @@
+error[E0660]: malformed inline assembly
+  --> $DIR/E0660.rs:5:5
+   |
+LL |     asm!("nop" "nop");
+   |     ^^^^^^^^^^^^^^^^^^
+
+error[E0660]: malformed inline assembly
+  --> $DIR/E0660.rs:7:5
+   |
+LL |     asm!("nop" "nop" : "=r"(a));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/error-codes/E0661.rs b/src/test/ui/error-codes/E0661.rs
new file mode 100644 (file)
index 0000000..8d355a8
--- /dev/null
@@ -0,0 +1,7 @@
+#![feature(asm)]
+
+fn main() {
+    let a;
+    asm!("nop" : "r"(a));
+    //~^ ERROR E0661
+}
diff --git a/src/test/ui/error-codes/E0661.stderr b/src/test/ui/error-codes/E0661.stderr
new file mode 100644 (file)
index 0000000..30a23fd
--- /dev/null
@@ -0,0 +1,8 @@
+error[E0661]: output operand constraint lacks '=' or '+'
+  --> $DIR/E0661.rs:5:18
+   |
+LL |     asm!("nop" : "r"(a));
+   |                  ^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/error-codes/E0662.rs b/src/test/ui/error-codes/E0662.rs
new file mode 100644 (file)
index 0000000..7fe528c
--- /dev/null
@@ -0,0 +1,8 @@
+#![feature(asm)]
+
+fn main() {
+    asm!("xor %eax, %eax"
+         :
+         : "=test"("a") //~ ERROR E0662
+        );
+}
diff --git a/src/test/ui/error-codes/E0662.stderr b/src/test/ui/error-codes/E0662.stderr
new file mode 100644 (file)
index 0000000..0d3701a
--- /dev/null
@@ -0,0 +1,8 @@
+error[E0662]: input operand constraint contains '='
+  --> $DIR/E0662.rs:6:12
+   |
+LL |          : "=test"("a")
+   |            ^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/error-codes/E0663.rs b/src/test/ui/error-codes/E0663.rs
new file mode 100644 (file)
index 0000000..e5b8156
--- /dev/null
@@ -0,0 +1,8 @@
+#![feature(asm)]
+
+fn main() {
+    asm!("xor %eax, %eax"
+         :
+         : "+test"("a") //~ ERROR E0663
+        );
+}
diff --git a/src/test/ui/error-codes/E0663.stderr b/src/test/ui/error-codes/E0663.stderr
new file mode 100644 (file)
index 0000000..46a079a
--- /dev/null
@@ -0,0 +1,8 @@
+error[E0663]: input operand constraint contains '+'
+  --> $DIR/E0663.rs:6:12
+   |
+LL |          : "+test"("a")
+   |            ^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/error-codes/E0664.rs b/src/test/ui/error-codes/E0664.rs
new file mode 100644 (file)
index 0000000..29ec7ce
--- /dev/null
@@ -0,0 +1,9 @@
+#![feature(asm)]
+
+fn main() {
+    asm!("mov $$0x200, %eax"
+         :
+         :
+         : "{eax}" //~ ERROR E0664
+        );
+}
diff --git a/src/test/ui/error-codes/E0664.stderr b/src/test/ui/error-codes/E0664.stderr
new file mode 100644 (file)
index 0000000..3a99fce
--- /dev/null
@@ -0,0 +1,8 @@
+error[E0664]: clobber should not be surrounded by braces
+  --> $DIR/E0664.rs:7:12
+   |
+LL |          : "{eax}"
+   |            ^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/error-codes/E0665.rs b/src/test/ui/error-codes/E0665.rs
new file mode 100644 (file)
index 0000000..cfd42bd
--- /dev/null
@@ -0,0 +1,8 @@
+#[derive(Default)] //~ ERROR E0665
+enum Food {
+    Sweet,
+    Salty,
+}
+
+fn main() {
+}
diff --git a/src/test/ui/error-codes/E0665.stderr b/src/test/ui/error-codes/E0665.stderr
new file mode 100644 (file)
index 0000000..84fe3c0
--- /dev/null
@@ -0,0 +1,8 @@
+error[E0665]: `Default` cannot be derived for enums, only structs
+  --> $DIR/E0665.rs:1:10
+   |
+LL | #[derive(Default)]
+   |          ^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/error-codes/E0705.rs b/src/test/ui/error-codes/E0705.rs
new file mode 100644 (file)
index 0000000..cc2b8f6
--- /dev/null
@@ -0,0 +1,10 @@
+// compile-pass
+
+// This is a stub feature that doesn't control anything, so to make tidy happy,
+// gate-test-test_2018_feature
+
+#![feature(test_2018_feature)]
+//~^ WARN the feature `test_2018_feature` is included in the Rust 2018 edition
+#![feature(rust_2018_preview)]
+
+fn main() {}
diff --git a/src/test/ui/error-codes/E0705.stderr b/src/test/ui/error-codes/E0705.stderr
new file mode 100644 (file)
index 0000000..1cb83f2
--- /dev/null
@@ -0,0 +1,6 @@
+warning[E0705]: the feature `test_2018_feature` is included in the Rust 2018 edition
+  --> $DIR/E0705.rs:6:12
+   |
+LL | #![feature(test_2018_feature)]
+   |            ^^^^^^^^^^^^^^^^^
+
diff --git a/src/test/ui/error-codes/e0119/auxiliary/complex_impl_support.rs b/src/test/ui/error-codes/e0119/auxiliary/complex_impl_support.rs
new file mode 100644 (file)
index 0000000..ad5bb10
--- /dev/null
@@ -0,0 +1,22 @@
+use std::marker::PhantomData;
+
+pub trait External {}
+
+pub struct M<'a, 'b, 'c, T, U, V> {
+    a: PhantomData<&'a ()>,
+    b: PhantomData<&'b ()>,
+    c: PhantomData<&'c ()>,
+    d: PhantomData<T>,
+    e: PhantomData<U>,
+    f: PhantomData<V>,
+}
+
+impl<'a, 'b, 'c, T, U, V, W> External for (T, M<'a, 'b, 'c, Box<U>, V, W>)
+where
+    'b: 'a,
+    T: 'a,
+    U: (FnOnce(T) -> V) + 'static,
+    V: Iterator<Item=T> + Clone,
+    W: std::ops::Add,
+    W::Output: Copy,
+{}
diff --git a/src/test/ui/error-codes/e0119/auxiliary/issue-23563-a.rs b/src/test/ui/error-codes/e0119/auxiliary/issue-23563-a.rs
new file mode 100644 (file)
index 0000000..4e85bcc
--- /dev/null
@@ -0,0 +1,25 @@
+// Ref: https://github.com/rust-lang/rust/issues/23563#issuecomment-260751672
+
+pub trait LolTo<T> {
+    fn convert_to(&self) -> T;
+}
+
+pub trait LolInto<T>: Sized {
+    fn convert_into(self) -> T;
+}
+
+pub trait LolFrom<T> {
+    fn from(T) -> Self;
+}
+
+impl<'a, T: ?Sized, U> LolInto<U> for &'a T where T: LolTo<U> {
+    fn convert_into(self) -> U {
+        self.convert_to()
+    }
+}
+
+impl<T, U> LolFrom<T> for U where T: LolInto<U> {
+    fn from(t: T) -> U {
+        t.convert_into()
+    }
+}
diff --git a/src/test/ui/error-codes/e0119/complex-impl.rs b/src/test/ui/error-codes/e0119/complex-impl.rs
new file mode 100644 (file)
index 0000000..3cba39e
--- /dev/null
@@ -0,0 +1,12 @@
+// aux-build:complex_impl_support.rs
+
+extern crate complex_impl_support;
+
+use complex_impl_support::{External, M};
+
+struct Q;
+
+impl<R> External for (Q, R) {} //~ ERROR must be used
+//~^ ERROR conflicting implementations of trait
+
+fn main() {}
diff --git a/src/test/ui/error-codes/e0119/complex-impl.stderr b/src/test/ui/error-codes/e0119/complex-impl.stderr
new file mode 100644 (file)
index 0000000..7ed89a5
--- /dev/null
@@ -0,0 +1,22 @@
+error[E0119]: conflicting implementations of trait `complex_impl_support::External` for type `(Q, complex_impl_support::M<'_, '_, '_, std::boxed::Box<_>, _, _>)`:
+  --> $DIR/complex-impl.rs:9:1
+   |
+LL | impl<R> External for (Q, R) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `complex_impl_support`:
+           - impl<'a, 'b, 'c, T, U, V, W> complex_impl_support::External for (T, complex_impl_support::M<'a, 'b, 'c, std::boxed::Box<U>, V, W>)
+             where <U as std::ops::FnOnce<(T,)>>::Output == V, <V as std::iter::Iterator>::Item == T, 'b : 'a, T : 'a, U: std::ops::FnOnce<(T,)>, U : 'static, V: std::iter::Iterator, V: std::clone::Clone, W: std::ops::Add, <W as std::ops::Add>::Output: std::marker::Copy;
+
+error[E0210]: type parameter `R` must be used as the type parameter for some local type (e.g., `MyStruct<R>`)
+  --> $DIR/complex-impl.rs:9:1
+   |
+LL | impl<R> External for (Q, R) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `R` must be used as the type parameter for some local type
+   |
+   = note: only traits defined in the current crate can be implemented for a type parameter
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0119, E0210.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/src/test/ui/error-codes/e0119/conflict-with-std.rs b/src/test/ui/error-codes/e0119/conflict-with-std.rs
new file mode 100644 (file)
index 0000000..c9db2ba
--- /dev/null
@@ -0,0 +1,26 @@
+use std::marker::PhantomData;
+use std::convert::{TryFrom, AsRef};
+
+struct Q;
+impl AsRef<Q> for Box<Q> { //~ ERROR conflicting implementations
+    fn as_ref(&self) -> &Q {
+        &**self
+    }
+}
+
+struct S;
+impl From<S> for S { //~ ERROR conflicting implementations
+    fn from(s: S) -> S {
+        s
+    }
+}
+
+struct X;
+impl TryFrom<X> for X { //~ ERROR conflicting implementations
+    type Error = ();
+    fn try_from(u: X) -> Result<X, ()> {
+        Ok(u)
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/error-codes/e0119/conflict-with-std.stderr b/src/test/ui/error-codes/e0119/conflict-with-std.stderr
new file mode 100644 (file)
index 0000000..3e0c71e
--- /dev/null
@@ -0,0 +1,32 @@
+error[E0119]: conflicting implementations of trait `std::convert::AsRef<Q>` for type `std::boxed::Box<Q>`:
+  --> $DIR/conflict-with-std.rs:5:1
+   |
+LL | impl AsRef<Q> for Box<Q> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `alloc`:
+           - impl<T> std::convert::AsRef<T> for std::boxed::Box<T>
+             where T: ?Sized;
+
+error[E0119]: conflicting implementations of trait `std::convert::From<S>` for type `S`:
+  --> $DIR/conflict-with-std.rs:12:1
+   |
+LL | impl From<S> for S {
+   | ^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `core`:
+           - impl<T> std::convert::From<T> for T;
+
+error[E0119]: conflicting implementations of trait `std::convert::TryFrom<X>` for type `X`:
+  --> $DIR/conflict-with-std.rs:19:1
+   |
+LL | impl TryFrom<X> for X {
+   | ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `core`:
+           - impl<T, U> std::convert::TryFrom<U> for T
+             where U: std::convert::Into<T>;
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/error-codes/e0119/issue-23563.rs b/src/test/ui/error-codes/e0119/issue-23563.rs
new file mode 100644 (file)
index 0000000..f578560
--- /dev/null
@@ -0,0 +1,29 @@
+// aux-build:issue-23563-a.rs
+
+// Ref: https://github.com/rust-lang/rust/issues/23563#issuecomment-260751672
+
+extern crate issue_23563_a as a;
+
+use a::LolFrom;
+use a::LolInto;
+use a::LolTo;
+
+struct LocalType<T>(Option<T>);
+
+impl<'a, T> LolFrom<&'a [T]> for LocalType<T> { //~ ERROR conflicting implementations of trait
+    fn from(_: &'a [T]) -> LocalType<T> { LocalType(None) }
+}
+
+impl<T> LolInto<LocalType<T>> for LocalType<T> {
+    fn convert_into(self) -> LocalType<T> {
+        self
+    }
+}
+
+impl LolTo<LocalType<u8>> for [u8] {
+    fn convert_to(&self) -> LocalType<u8> {
+        LocalType(None)
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/error-codes/e0119/issue-23563.stderr b/src/test/ui/error-codes/e0119/issue-23563.stderr
new file mode 100644 (file)
index 0000000..8011689
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0119]: conflicting implementations of trait `a::LolFrom<&[_]>` for type `LocalType<_>`:
+  --> $DIR/issue-23563.rs:13:1
+   |
+LL | impl<'a, T> LolFrom<&'a [T]> for LocalType<T> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `issue_23563_a`:
+           - impl<T, U> a::LolFrom<T> for U
+             where T: a::LolInto<U>;
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/error-codes/e0119/issue-27403.rs b/src/test/ui/error-codes/e0119/issue-27403.rs
new file mode 100644 (file)
index 0000000..b03a564
--- /dev/null
@@ -0,0 +1,11 @@
+pub struct GenX<S> {
+    inner: S,
+}
+
+impl<S> Into<S> for GenX<S> { //~ ERROR conflicting implementations
+    fn into(self) -> S {
+        self.inner
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/error-codes/e0119/issue-27403.stderr b/src/test/ui/error-codes/e0119/issue-27403.stderr
new file mode 100644 (file)
index 0000000..cba1043
--- /dev/null
@@ -0,0 +1,13 @@
+error[E0119]: conflicting implementations of trait `std::convert::Into<_>` for type `GenX<_>`:
+  --> $DIR/issue-27403.rs:5:1
+   |
+LL | impl<S> Into<S> for GenX<S> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `core`:
+           - impl<T, U> std::convert::Into<U> for T
+             where U: std::convert::From<T>;
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/error-codes/e0119/issue-28981.rs b/src/test/ui/error-codes/e0119/issue-28981.rs
new file mode 100644 (file)
index 0000000..c31b212
--- /dev/null
@@ -0,0 +1,8 @@
+use std::ops::Deref;
+
+struct Foo;
+
+impl<Foo> Deref for Foo { } //~ ERROR must be used
+//~^ ERROR conflicting implementations
+
+fn main() {}
diff --git a/src/test/ui/error-codes/e0119/issue-28981.stderr b/src/test/ui/error-codes/e0119/issue-28981.stderr
new file mode 100644 (file)
index 0000000..70c83e1
--- /dev/null
@@ -0,0 +1,22 @@
+error[E0119]: conflicting implementations of trait `std::ops::Deref` for type `&_`:
+  --> $DIR/issue-28981.rs:5:1
+   |
+LL | impl<Foo> Deref for Foo { }
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `core`:
+           - impl<T> std::ops::Deref for &T
+             where T: ?Sized;
+
+error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g., `MyStruct<Foo>`)
+  --> $DIR/issue-28981.rs:5:1
+   |
+LL | impl<Foo> Deref for Foo { }
+   | ^^^^^^^^^^^^^^^^^^^^^^^ type parameter `Foo` must be used as the type parameter for some local type
+   |
+   = note: only traits defined in the current crate can be implemented for a type parameter
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0119, E0210.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/src/test/ui/error-codes/e0119/so-37347311.rs b/src/test/ui/error-codes/e0119/so-37347311.rs
new file mode 100644 (file)
index 0000000..d5f624b
--- /dev/null
@@ -0,0 +1,17 @@
+// Ref: https://stackoverflow.com/q/37347311
+
+trait Storage {
+    type Error;
+}
+
+enum MyError<S: Storage> {
+    StorageProblem(S::Error),
+}
+
+impl<S: Storage> From<S::Error> for MyError<S> { //~ ERROR conflicting implementations
+    fn from(error: S::Error) -> MyError<S> {
+        MyError::StorageProblem(error)
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/error-codes/e0119/so-37347311.stderr b/src/test/ui/error-codes/e0119/so-37347311.stderr
new file mode 100644 (file)
index 0000000..f2166de
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `std::convert::From<MyError<_>>` for type `MyError<_>`:
+  --> $DIR/so-37347311.rs:11:1
+   |
+LL | impl<S: Storage> From<S::Error> for MyError<S> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `core`:
+           - impl<T> std::convert::From<T> for T;
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/existential_types/issue-60655-latebound-regions.rs b/src/test/ui/existential_types/issue-60655-latebound-regions.rs
deleted file mode 100644 (file)
index a4fe865..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// Test that existential types are allowed to contain late-bound regions.
-
-// compile-pass
-// edition:2018
-
-#![feature(async_await, existential_type)]
-
-use std::future::Future;
-
-pub existential type Func: Sized;
-
-// Late bound region should be allowed to escape the function, since it's bound
-// in the type.
-fn null_function_ptr() -> Func {
-    None::<for<'a> fn(&'a ())>
-}
-
-async fn async_nop(_: &u8) {}
-
-pub existential type ServeFut: Future<Output=()>;
-
-// Late bound regions occur in the generator witness type here.
-fn serve() -> ServeFut {
-    async move {
-        let x = 5;
-        async_nop(&x).await
-    }
-}
-
-fn main() {}
index 725f2e0b9d008425028e5351648eaa90c00ea18c..4ced941aad5d0cd949d7d05adb080356151641e4 100644 (file)
@@ -13,7 +13,7 @@ mod inner { #![macro_use(my_macro)] }
     //~^ ERROR arguments to macro_use are not allowed here
 
     #[macro_use = "2700"] struct S;
-    //~^ ERROR attribute must be of the form
+    //~^ ERROR malformed `macro_use` attribute
 
     #[macro_use] fn f() { }
 
index 8074528c0e060cf99b6e93542f3b5e52c2a20472..665fe2880871edc421802e8f1cb920e2d0cbad30 100644 (file)
@@ -16,11 +16,17 @@ error: arguments to macro_use are not allowed here
 LL |     mod inner { #![macro_use(my_macro)] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: attribute must be of the form `#[macro_use]` or `#[macro_use(name1, name2, ...)]`
+error: malformed `macro_use` attribute input
   --> $DIR/issue-43106-gating-of-macro_use.rs:15:5
    |
 LL |     #[macro_use = "2700"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^
+help: the following are the possible correct uses
+   |
+LL |     #[macro_use] struct S;
+   |     ^^^^^^^^^^^^
+LL |     #[macro_use(name1, name2, ...)] struct S;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
index fb4cc94f779fe7242a5bc7a59d159595b2dbe2a4..f8aa23d95e5b6c24ea04bc27bb6963fbf3d80c10 100644 (file)
@@ -1,13 +1,9 @@
-#![feature(
-    foo_bar_baz,
-    foo(bar),
-    foo = "baz"
-)]
-//~^^^ ERROR: malformed feature
-//~^^^ ERROR: malformed feature
+#![feature(foo_bar_baz, foo(bar), foo = "baz", foo)]
+//~^ ERROR malformed `feature`
+//~| ERROR malformed `feature`
 
-#![feature] //~ ERROR: attribute must be of the form
-#![feature = "foo"] //~ ERROR: attribute must be of the form
+#![feature] //~ ERROR malformed `feature` attribute
+#![feature = "foo"] //~ ERROR malformed `feature` attribute
 
 #![feature(test_removed_feature)] //~ ERROR: feature has been removed
 
index 5a3cfc962e05c6564b039c3fabf75378dcba2a13..ff6780e66a8ce3fcb150924d0f293d7c575a9bb5 100644 (file)
@@ -1,32 +1,32 @@
-error[E0556]: malformed feature, expected just one word
-  --> $DIR/gated-bad-feature.rs:3:5
+error[E0556]: malformed `feature` attribute input
+  --> $DIR/gated-bad-feature.rs:1:25
    |
-LL |     foo(bar),
-   |     ^^^^^^^^
+LL | #![feature(foo_bar_baz, foo(bar), foo = "baz", foo)]
+   |                         ^^^^^^^^ help: expected just one word: `foo`
 
-error[E0556]: malformed feature, expected just one word
-  --> $DIR/gated-bad-feature.rs:4:5
+error[E0556]: malformed `feature` attribute input
+  --> $DIR/gated-bad-feature.rs:1:35
    |
-LL |     foo = "baz"
-   |     ^^^^^^^^^^^
+LL | #![feature(foo_bar_baz, foo(bar), foo = "baz", foo)]
+   |                                   ^^^^^^^^^^^ help: expected just one word: `foo`
 
 error[E0557]: feature has been removed
-  --> $DIR/gated-bad-feature.rs:12:12
+  --> $DIR/gated-bad-feature.rs:8:12
    |
 LL | #![feature(test_removed_feature)]
-   |            ^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^^^ feature has been removed
 
-error: attribute must be of the form `#[feature(name1, name1, ...)]`
-  --> $DIR/gated-bad-feature.rs:9:1
+error: malformed `feature` attribute input
+  --> $DIR/gated-bad-feature.rs:5:1
    |
 LL | #![feature]
-   | ^^^^^^^^^^^
+   | ^^^^^^^^^^^ help: must be of the form: `#[feature(name1, name1, ...)]`
 
-error: attribute must be of the form `#[feature(name1, name1, ...)]`
-  --> $DIR/gated-bad-feature.rs:10:1
+error: malformed `feature` attribute input
+  --> $DIR/gated-bad-feature.rs:6:1
    |
 LL | #![feature = "foo"]
-   | ^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[feature(name1, name1, ...)]`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/generator/unresolved_type_param.rs b/src/test/ui/generator/unresolved_type_param.rs
deleted file mode 100644 (file)
index 77174b0..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Provoke an unresolved type error (T).
-// Error message should pinpoint the type parameter T as needing to be bound
-// (rather than give a general error message)
-// edition:2018
-#![feature(async_await)]
-async fn bar<T>() -> () {}
-
-async fn foo() {
-    bar().await;
-    //~^ ERROR type inside generator must be known in this context
-    //~| NOTE cannot infer type for `T`
-    //~| NOTE the type is part of the generator because of this `yield`
-    //~| NOTE in this expansion of desugaring of `await`
-}
-fn main() {}
diff --git a/src/test/ui/generator/unresolved_type_param.stderr b/src/test/ui/generator/unresolved_type_param.stderr
deleted file mode 100644 (file)
index afb9adf..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0698]: type inside generator must be known in this context
-  --> $DIR/unresolved_type_param.rs:9:5
-   |
-LL |     bar().await;
-   |     ^^^ cannot infer type for `T`
-   |
-note: the type is part of the generator because of this `yield`
-  --> $DIR/unresolved_type_param.rs:9:5
-   |
-LL |     bar().await;
-   |     ^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0698`.
diff --git a/src/test/ui/impl-trait/recursive-async-impl-trait-type.rs b/src/test/ui/impl-trait/recursive-async-impl-trait-type.rs
deleted file mode 100644 (file)
index a4e0801..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// edition:2018
-// Test that impl trait does not allow creating recursive types that are
-// otherwise forbidden when using `async` and `await`.
-
-#![feature(await_macro, async_await, generators)]
-
-async fn recursive_async_function() -> () { //~ ERROR
-    await!(recursive_async_function());
-}
-
-fn main() {}
diff --git a/src/test/ui/impl-trait/recursive-async-impl-trait-type.stderr b/src/test/ui/impl-trait/recursive-async-impl-trait-type.stderr
deleted file mode 100644 (file)
index abc9ff5..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0720]: opaque type expands to a recursive type
-  --> $DIR/recursive-async-impl-trait-type.rs:7:40
-   |
-LL | async fn recursive_async_function() -> () {
-   |                                        ^^ expands to self-referential type
-   |
-   = note: expanded type is `std::future::GenFuture<[static generator@$DIR/recursive-async-impl-trait-type.rs:7:43: 9:2 {impl std::future::Future, ()}]>`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0720`.
index 741ba5f41ce16b9caf72e7b40a58bf226f86f64d..a003a01941bdee3981b4cd322c7273d7be338f4e 100644 (file)
@@ -1,5 +1,6 @@
 fn a(&self) { }
-//~^ ERROR unexpected `self` argument in function
-//~| NOTE `self` is only valid as the first argument of an associated function
+//~^ ERROR unexpected `self` parameter in function
+//~| NOTE not valid as function parameter
+//~| NOTE `self` is only valid as the first parameter of an associated function
 
 fn main() { }
index 6a878b619d813651d91fa60bb63c34c1481ce960..23de6502094f0e7cf5093f4c92e75980856d1475 100644 (file)
@@ -1,8 +1,10 @@
-error: unexpected `self` argument in function
-  --> $DIR/bare-fn-start.rs:1:7
+error: unexpected `self` parameter in function
+  --> $DIR/bare-fn-start.rs:1:6
    |
 LL | fn a(&self) { }
-   |       ^^^^ `self` is only valid as the first argument of an associated function
+   |      ^^^^^ not valid as function parameter
+   |
+   = note: `self` is only valid as the first parameter of an associated function
 
 error: aborting due to previous error
 
index 704fa996ca631a73fe1b3333ce1eae9406cbac02..73d68e8b7a5ab340375bb570688a08f734313d92 100644 (file)
@@ -1,5 +1,6 @@
 fn b(foo: u32, &mut self) { }
-//~^ ERROR unexpected `self` argument in function
-//~| NOTE `self` is only valid as the first argument of an associated function
+//~^ ERROR unexpected `self` parameter in function
+//~| NOTE not valid as function parameter
+//~| NOTE `self` is only valid as the first parameter of an associated function
 
 fn main() { }
index b13f746a4ec584a5bc3e2b62bc0de418247a8bbb..601a51bb4a96a4b8f535477acf4ade088d69e4bc 100644 (file)
@@ -1,8 +1,10 @@
-error: unexpected `self` argument in function
-  --> $DIR/bare-fn.rs:1:21
+error: unexpected `self` parameter in function
+  --> $DIR/bare-fn.rs:1:16
    |
 LL | fn b(foo: u32, &mut self) { }
-   |                     ^^^^ `self` is only valid as the first argument of an associated function
+   |                ^^^^^^^^^ not valid as function parameter
+   |
+   = note: `self` is only valid as the first parameter of an associated function
 
 error: aborting due to previous error
 
index 31e867bc7641f4f263374b28e4814a5a39c6b4ef..1e8220d7b4a781743c41f810a3f3957a9e2f7479 100644 (file)
@@ -2,8 +2,8 @@ struct Foo {}
 
 impl Foo {
     fn c(foo: u32, self) {}
-    //~^ ERROR unexpected `self` argument in function
-    //~| NOTE `self` is only valid as the first argument of an associated function
+    //~^ ERROR unexpected `self` parameter in function
+    //~| NOTE must be the first associated function parameter
 
     fn good(&mut self, foo: u32) {}
 }
index b3c2cc5b5ebe0874e1f222f695c4b3f0733f5c89..96a2251c036b19658c016a5f6dab9110e7219c60 100644 (file)
@@ -1,8 +1,8 @@
-error: unexpected `self` argument in function
+error: unexpected `self` parameter in function
   --> $DIR/trait-fn.rs:4:20
    |
 LL |     fn c(foo: u32, self) {}
-   |                    ^^^^ `self` is only valid as the first argument of an associated function
+   |                    ^^^^ must be the first associated function parameter
 
 error: aborting due to previous error
 
index 8157ccdcbf0b95e87c8ee1a6d53b5a9e640a16ed..621587af35ed702a6698889ea551854fcce3e79f 100644 (file)
@@ -1,5 +1,5 @@
 // regression test for issue 16974
-#![crate_type(lib)]  //~ ERROR attribute must be of the form
+#![crate_type(lib)]  //~ ERROR malformed `crate_type` attribute input
 
 fn my_lib_fn() {}
 
index cb3faedfedb8bd90de802f74761b6c3c5ee78e0a..92bed231586f9eacde055fbffa681c9e49d9dbe8 100644 (file)
@@ -1,8 +1,8 @@
-error: attribute must be of the form `#[crate_type = "bin|lib|..."]`
+error: malformed `crate_type` attribute input
   --> $DIR/invalid_crate_type_syntax.rs:2:1
    |
 LL | #![crate_type(lib)]
-   | ^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "bin|lib|..."]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-53249.rs b/src/test/ui/issue-53249.rs
deleted file mode 100644 (file)
index 9e4ff43..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-// compile-pass
-// edition:2018
-
-#![feature(arbitrary_self_types, async_await, await_macro)]
-
-use std::task::{self, Poll};
-use std::future::Future;
-use std::marker::Unpin;
-use std::pin::Pin;
-
-// This is a regression test for a ICE/unbounded recursion issue relating to async-await.
-
-#[derive(Debug)]
-#[must_use = "futures do nothing unless polled"]
-pub struct Lazy<F> {
-    f: Option<F>
-}
-
-impl<F> Unpin for Lazy<F> {}
-
-pub fn lazy<F, R>(f: F) -> Lazy<F>
-    where F: FnOnce(&mut task::Context) -> R,
-{
-    Lazy { f: Some(f) }
-}
-
-impl<R, F> Future for Lazy<F>
-    where F: FnOnce(&mut task::Context) -> R,
-{
-    type Output = R;
-
-    fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context) -> Poll<R> {
-        Poll::Ready((self.f.take().unwrap())(cx))
-    }
-}
-
-async fn __receive<WantFn, Fut>(want: WantFn) -> ()
-    where Fut: Future<Output = ()>, WantFn: Fn(&Box<Send + 'static>) -> Fut,
-{
-    await!(lazy(|_| ()));
-}
-
-pub fn basic_spawn_receive() {
-    async { await!(__receive(|_| async { () })) };
-}
-
-fn main() {}
diff --git a/src/test/ui/issue-59508-1.rs b/src/test/ui/issue-59508-1.rs
deleted file mode 100644 (file)
index 4fbed9b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#![allow(dead_code)]
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
-
-// This test checks that generic parameter re-ordering diagnostic suggestions mention that
-// consts come after types and lifetimes when the `const_generics` feature is enabled.
-// We cannot run rustfix on this test because of the above const generics warning.
-
-struct A;
-
-impl A {
-    pub fn do_things<T, 'a, 'b: 'a>() {
-    //~^ ERROR lifetime parameters must be declared prior to type parameters
-        println!("panic");
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issue-59508-1.stderr b/src/test/ui/issue-59508-1.stderr
deleted file mode 100644 (file)
index 8fb7d7c..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-warning: the feature `const_generics` is incomplete and may cause the compiler to crash
-  --> $DIR/issue-59508-1.rs:2:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-
-error: lifetime parameters must be declared prior to type parameters
-  --> $DIR/issue-59508-1.rs:12:25
-   |
-LL |     pub fn do_things<T, 'a, 'b: 'a>() {
-   |                     ----^^--^^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b: 'a, T>`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issue-59508.fixed b/src/test/ui/issue-59508.fixed
deleted file mode 100644 (file)
index b5c60a1..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// run-rustfix
-
-#![allow(dead_code)]
-
-// This test checks that generic parameter re-ordering diagnostic suggestions contain bounds.
-
-struct A;
-
-impl A {
-    pub fn do_things<'a, 'b: 'a, T>() {
-    //~^ ERROR lifetime parameters must be declared prior to type parameters
-        println!("panic");
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issue-59508.rs b/src/test/ui/issue-59508.rs
deleted file mode 100644 (file)
index 0b39c5d..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// run-rustfix
-
-#![allow(dead_code)]
-
-// This test checks that generic parameter re-ordering diagnostic suggestions contain bounds.
-
-struct A;
-
-impl A {
-    pub fn do_things<T, 'a, 'b: 'a>() {
-    //~^ ERROR lifetime parameters must be declared prior to type parameters
-        println!("panic");
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issue-59508.stderr b/src/test/ui/issue-59508.stderr
deleted file mode 100644 (file)
index c0fdb2e..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: lifetime parameters must be declared prior to type parameters
-  --> $DIR/issue-59508.rs:10:25
-   |
-LL |     pub fn do_things<T, 'a, 'b: 'a>() {
-   |                     ----^^--^^----- help: reorder the parameters: lifetimes, then types: `<'a, 'b: 'a, T>`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issue-59756.fixed b/src/test/ui/issue-59756.fixed
deleted file mode 100644 (file)
index 7b55d0f..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// run-rustfix
-
-#![allow(warnings)]
-
-struct A;
-struct B;
-
-fn foo() -> Result<A, B> {
-    Ok(A)
-}
-
-fn bar() -> Result<A, B> {
-    foo()
-    //~^ ERROR try expression alternatives have incompatible types [E0308]
-}
-
-fn main() {}
diff --git a/src/test/ui/issue-59756.rs b/src/test/ui/issue-59756.rs
deleted file mode 100644 (file)
index cccae39..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// run-rustfix
-
-#![allow(warnings)]
-
-struct A;
-struct B;
-
-fn foo() -> Result<A, B> {
-    Ok(A)
-}
-
-fn bar() -> Result<A, B> {
-    foo()?
-    //~^ ERROR try expression alternatives have incompatible types [E0308]
-}
-
-fn main() {}
diff --git a/src/test/ui/issue-59756.stderr b/src/test/ui/issue-59756.stderr
deleted file mode 100644 (file)
index d462328..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0308]: try expression alternatives have incompatible types
-  --> $DIR/issue-59756.rs:13:5
-   |
-LL |     foo()?
-   |     ^^^^^-
-   |     |    |
-   |     |    help: try removing this `?`
-   |     expected enum `std::result::Result`, found struct `A`
-   |
-   = note: expected type `std::result::Result<A, B>`
-              found type `A`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issue-59764.rs b/src/test/ui/issue-59764.rs
deleted file mode 100644 (file)
index 09dee8c..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-// aux-build:issue-59764.rs
-// compile-flags:--extern issue_59764
-// edition:2018
-
-#![allow(warnings)]
-
-// This tests the suggestion to import macros from the root of a crate. This aims to capture
-// the case where a user attempts to import a macro from the definition location instead of the
-// root of the crate and the macro is annotated with `#![macro_export]`.
-
-// Edge cases..
-
-mod multiple_imports_same_line_at_end {
-    use issue_59764::foo::{baz, makro};
-    //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-}
-
-mod multiple_imports_multiline_at_end_trailing_comma {
-    use issue_59764::foo::{
-        baz,
-        makro, //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-    };
-}
-
-mod multiple_imports_multiline_at_end {
-    use issue_59764::foo::{
-        baz,
-        makro //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-    };
-}
-
-mod multiple_imports_same_line_in_middle {
-    use issue_59764::foo::{baz, makro, foobar};
-    //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-}
-
-mod multiple_imports_multiline_in_middle_trailing_comma {
-    use issue_59764::foo::{
-        baz,
-        makro, //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-        foobar,
-    };
-}
-
-mod multiple_imports_multiline_in_middle {
-    use issue_59764::foo::{
-        baz,
-        makro, //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-        foobar
-    };
-}
-
-mod nested_imports {
-    use issue_59764::{foobaz, foo::makro};
-    //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-}
-
-mod nested_multiple_imports {
-    use issue_59764::{foobaz, foo::{baz, makro}};
-    //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-}
-
-mod nested_multiline_multiple_imports_trailing_comma {
-    use issue_59764::{
-        foobaz,
-        foo::{
-            baz,
-            makro, //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-        },
-    };
-}
-
-mod nested_multiline_multiple_imports {
-    use issue_59764::{
-        foobaz,
-        foo::{
-            baz,
-            makro //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-        }
-    };
-}
-
-mod doubly_nested_multiple_imports {
-    use issue_59764::{foobaz, foo::{baz, makro, barbaz::{barfoo}}};
-    //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-}
-
-mod doubly_multiline_nested_multiple_imports {
-    use issue_59764::{
-        foobaz,
-        foo::{
-            baz,
-            makro, //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-            barbaz::{
-                barfoo,
-            }
-        }
-    };
-}
-
-mod renamed_import {
-    use issue_59764::foo::makro as baz;
-    //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-}
-
-mod renamed_multiple_imports {
-    use issue_59764::foo::{baz, makro as foobar};
-    //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-}
-
-mod lots_of_whitespace {
-    use
-        issue_59764::{
-
-            foobaz,
-
-
-            foo::{baz,
-
-                makro as foobar} //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-
-        };
-}
-
-// Simple case..
-
-use issue_59764::foo::makro;
-//~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
-
-makro!(bar);
-//~^ ERROR cannot determine resolution for the macro `makro`
-
-fn main() {
-    bar();
-    //~^ ERROR cannot find function `bar` in this scope [E0425]
-}
diff --git a/src/test/ui/issue-59764.stderr b/src/test/ui/issue-59764.stderr
deleted file mode 100644 (file)
index f266e90..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:14:33
-   |
-LL |     use issue_59764::foo::{baz, makro};
-   |                                 ^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |     use issue_59764::{makro, foo::{baz}};
-   |                      ^^^^^^^^^       --^^
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:21:9
-   |
-LL |         makro,
-   |         ^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |     use issue_59764::{makro, foo::{
-LL |         baz,
-LL |
-LL |     }};
-   |
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:28:9
-   |
-LL |         makro
-   |         ^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |     use issue_59764::{makro, foo::{
-LL |         baz,
-LL |
-LL |     }};
-   |
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:33:33
-   |
-LL |     use issue_59764::foo::{baz, makro, foobar};
-   |                                 ^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |     use issue_59764::{makro, foo::{baz, foobar}};
-   |                      ^^^^^^^^^         --      ^^
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:40:9
-   |
-LL |         makro,
-   |         ^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |     use issue_59764::{makro, foo::{
-LL |         baz,
-LL |
-LL |         foobar,
-LL |     }};
-   |
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:48:9
-   |
-LL |         makro,
-   |         ^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |     use issue_59764::{makro, foo::{
-LL |         baz,
-LL |
-LL |         foobar
-LL |     }};
-   |
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:54:31
-   |
-LL |     use issue_59764::{foobaz, foo::makro};
-   |                               ^^^^^^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |     use issue_59764::{makro, foobaz};
-   |                      ^^^^^^^      --
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:59:42
-   |
-LL |     use issue_59764::{foobaz, foo::{baz, makro}};
-   |                                          ^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |     use issue_59764::{makro, foobaz, foo::{baz}};
-   |                      ^^^^^^^                 --
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:68:13
-   |
-LL |             makro,
-   |             ^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |     use issue_59764::{makro, 
-LL |         foobaz,
-LL |         foo::{
-LL |             baz,
-LL |
-   |
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:78:13
-   |
-LL |             makro
-   |             ^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |     use issue_59764::{makro, 
-LL |         foobaz,
-LL |         foo::{
-LL |             baz,
-LL |
-   |
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:84:42
-   |
-LL |     use issue_59764::{foobaz, foo::{baz, makro, barbaz::{barfoo}}};
-   |                                          ^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |     use issue_59764::{makro, foobaz, foo::{baz, barbaz::{barfoo}}};
-   |                      ^^^^^^^                   --
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:93:13
-   |
-LL |             makro,
-   |             ^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |     use issue_59764::{makro, 
-LL |         foobaz,
-LL |         foo::{
-LL |             baz,
-LL |
-   |
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:102:9
-   |
-LL |     use issue_59764::foo::makro as baz;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |     use issue_59764::makro as baz;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:107:33
-   |
-LL |     use issue_59764::foo::{baz, makro as foobar};
-   |                                 ^^^^^^^^^^^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |     use issue_59764::{makro as foobar, foo::{baz}};
-   |                      ^^^^^^^^^^^^^^^^^^^       --^^
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:120:17
-   |
-LL |                 makro as foobar}
-   |                 ^^^^^^^^^^^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL |         issue_59764::{makro as foobar, 
-LL | 
-LL |             foobaz,
-LL | 
-LL | 
-LL |             foo::{baz}
-   |
-
-error[E0432]: unresolved import `issue_59764::foo::makro`
-  --> $DIR/issue-59764.rs:127:5
-   |
-LL | use issue_59764::foo::makro;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ no `makro` in `foo`
-   |
-   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
-help: a macro with this name exists at the root of the crate
-   |
-LL | use issue_59764::makro;
-   |     ^^^^^^^^^^^^^^^^^^
-
-error: cannot determine resolution for the macro `makro`
-  --> $DIR/issue-59764.rs:130:1
-   |
-LL | makro!(bar);
-   | ^^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
-error[E0425]: cannot find function `bar` in this scope
-  --> $DIR/issue-59764.rs:134:5
-   |
-LL |     bar();
-   |     ^^^ not found in this scope
-
-error: aborting due to 18 previous errors
-
-Some errors have detailed explanations: E0425, E0432.
-For more information about an error, try `rustc --explain E0425`.
diff --git a/src/test/ui/issue-60075.rs b/src/test/ui/issue-60075.rs
deleted file mode 100644 (file)
index 5788716..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-fn main() {}
-
-trait T {
-    fn qux() -> Option<usize> {
-        let _ = if true {
-        });
-//~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `;`
-//~^^ ERROR expected one of `.`, `;`, `?`, `else`, or an operator, found `}`
-//~^^^ ERROR 6:11: 6:12: expected identifier, found `;`
-//~^^^^ ERROR missing `fn`, `type`, or `const` for trait-item declaration
-        Some(4)
-    }
diff --git a/src/test/ui/issue-60075.stderr b/src/test/ui/issue-60075.stderr
deleted file mode 100644 (file)
index ac97d32..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-error: expected one of `.`, `;`, `?`, `else`, or an operator, found `}`
-  --> $DIR/issue-60075.rs:6:10
-   |
-LL |         });
-   |          ^ expected one of `.`, `;`, `?`, `else`, or an operator here
-
-error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `;`
-  --> $DIR/issue-60075.rs:6:11
-   |
-LL |     fn qux() -> Option<usize> {
-   |                               - unclosed delimiter
-LL |         let _ = if true {
-LL |         });
-   |           ^ help: `}` may belong here
-
-error: expected identifier, found `;`
-  --> $DIR/issue-60075.rs:6:11
-   |
-LL |         });
-   |           ^ expected identifier
-
-error: missing `fn`, `type`, or `const` for trait-item declaration
-  --> $DIR/issue-60075.rs:6:12
-   |
-LL |           });
-   |  ____________^
-LL | |
-LL | |
-LL | |
-LL | |
-LL | |         Some(4)
-   | |________^ missing `fn`, `type`, or `const`
-
-error: aborting due to 4 previous errors
-
diff --git a/src/test/ui/issue-60622.rs b/src/test/ui/issue-60622.rs
deleted file mode 100644 (file)
index d6a0189..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// ignore-tidy-linelength
-
-#![deny(warnings)]
-
-struct Borked {}
-
-impl Borked {
-    fn a(&self) {}
-}
-
-fn run_wild<T>(b: &Borked) {
-    b.a::<'_, T>();
-    //~^ ERROR cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
-    //~^^ ERROR wrong number of type arguments: expected 0, found 1
-    //~^^^ WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-}
-
-fn main() {}
diff --git a/src/test/ui/issue-60622.stderr b/src/test/ui/issue-60622.stderr
deleted file mode 100644 (file)
index 0c337c3..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
-  --> $DIR/issue-60622.rs:12:11
-   |
-LL |     fn a(&self) {}
-   |          - the late bound lifetime parameter is introduced here
-...
-LL |     b.a::<'_, T>();
-   |           ^^
-   |
-note: lint level defined here
-  --> $DIR/issue-60622.rs:3:9
-   |
-LL | #![deny(warnings)]
-   |         ^^^^^^^^
-   = note: #[deny(late_bound_lifetime_arguments)] implied by #[deny(warnings)]
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
-
-error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/issue-60622.rs:12:15
-   |
-LL |     b.a::<'_, T>();
-   |               ^ unexpected type argument
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/issues/auxiliary/issue-59764.rs b/src/test/ui/issues/auxiliary/issue-59764.rs
new file mode 100644 (file)
index 0000000..a92eed9
--- /dev/null
@@ -0,0 +1,18 @@
+pub mod foo {
+    #[macro_export]
+    macro_rules! makro {
+        ($foo:ident) => {
+            fn $foo() { }
+        }
+    }
+
+    pub fn baz() {}
+
+    pub fn foobar() {}
+
+    pub mod barbaz {
+        pub fn barfoo() {}
+    }
+}
+
+pub fn foobaz() {}
index b9e2e80492b370142b2837b1e41d88bcbc0f5916..64694c7a8d0b66dbb9c917c8e667500af41a1d70 100644 (file)
@@ -6,3 +6,4 @@ LL |         self.input_stream(&mut stream);
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0284`.
index 74667d74334cc20cb50b3316d0f6670ef15f6088..b80907560c385724e0ceba22ad511ceca96f9e66 100644 (file)
@@ -24,7 +24,7 @@ fn main() {
     #[repr]
     let _y = "123";
     //~^^ ERROR attribute should not be applied to a statement
-    //~| ERROR attribute must be of the form
+    //~| ERROR malformed `repr` attribute
 
     fn foo() {}
 
@@ -34,5 +34,5 @@ fn foo() {}
 
     let _z = #[repr] 1;
     //~^ ERROR attribute should not be applied to an expression
-    //~| ERROR attribute must be of the form
+    //~| ERROR malformed `repr` attribute
 }
index c72e3eab8539f369ce988fa33b8a4945c3142d75..c2f0cc6f0ffed2a6b2e5d4f1a015436490351039 100644 (file)
@@ -1,14 +1,14 @@
-error: attribute must be of the form `#[repr(C, packed, ...)]`
+error: malformed `repr` attribute input
   --> $DIR/issue-43988.rs:24:5
    |
 LL |     #[repr]
-   |     ^^^^^^^
+   |     ^^^^^^^ help: must be of the form: `#[repr(C, packed, ...)]`
 
-error: attribute must be of the form `#[repr(C, packed, ...)]`
+error: malformed `repr` attribute input
   --> $DIR/issue-43988.rs:35:14
    |
 LL |     let _z = #[repr] 1;
-   |              ^^^^^^^
+   |              ^^^^^^^ help: must be of the form: `#[repr(C, packed, ...)]`
 
 error[E0518]: attribute should be applied to function or closure
   --> $DIR/issue-43988.rs:5:5
diff --git a/src/test/ui/issues/issue-51719.rs b/src/test/ui/issues/issue-51719.rs
deleted file mode 100644 (file)
index 5966edd..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// edition:2018
-//
-// Tests that the .await syntax can't be used to make a generator
-
-#![feature(async_await)]
-
-async fn foo() {}
-
-fn make_generator() {
-    let _gen = || foo.await; //~ ERROR `await` is only allowed inside `async` functions and blocks
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-51719.stderr b/src/test/ui/issues/issue-51719.stderr
deleted file mode 100644 (file)
index c06165b..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-51719.rs:10:19
-   |
-LL |     let _gen = || foo.await;
-   |                -- ^^^^^^^^^ only allowed inside `async` functions and blocks
-   |                |
-   |                this is not `async`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-51751.rs b/src/test/ui/issues/issue-51751.rs
deleted file mode 100644 (file)
index 7afd7ec..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// edition:2018
-
-#![feature(async_await)]
-
-async fn inc(limit: i64) -> i64 {
-    limit + 1
-}
-
-fn main() {
-    let result = inc(10000);
-    let finished = result.await;
-    //~^ ERROR `await` is only allowed inside `async` functions and blocks
-}
diff --git a/src/test/ui/issues/issue-51751.stderr b/src/test/ui/issues/issue-51751.stderr
deleted file mode 100644 (file)
index 97b63d1..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-51751.rs:11:20
-   |
-LL | fn main() {
-   |    ---- this is not `async`
-LL |     let result = inc(10000);
-LL |     let finished = result.await;
-   |                    ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-54974.rs b/src/test/ui/issues/issue-54974.rs
deleted file mode 100644 (file)
index d6f1887..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// compile-pass
-// edition:2018
-
-#![feature(async_await, await_macro)]
-
-use std::sync::Arc;
-
-trait SomeTrait: Send + Sync + 'static {
-    fn do_something(&self);
-}
-
-async fn my_task(obj: Arc<SomeTrait>) {
-    unimplemented!()
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-55324.rs b/src/test/ui/issues/issue-55324.rs
deleted file mode 100644 (file)
index 4572e54..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// compile-pass
-// edition:2018
-
-#![feature(async_await, await_macro)]
-
-use std::future::Future;
-
-#[allow(unused)]
-async fn foo<F: Future<Output = i32>>(x: &i32, future: F) -> i32 {
-    let y = await!(future);
-    *x + y
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-58885.rs b/src/test/ui/issues/issue-58885.rs
deleted file mode 100644 (file)
index 99d87b2..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// compile-pass
-// edition:2018
-
-#![feature(async_await, await_macro)]
-
-struct Xyz {
-    a: u64,
-}
-
-trait Foo {}
-
-impl Xyz {
-    async fn do_sth<'a>(
-        &'a self, foo: &'a dyn Foo
-    ) -> bool
-    {
-        true
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-59001.rs b/src/test/ui/issues/issue-59001.rs
deleted file mode 100644 (file)
index c758244..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// compile-pass
-// edition:2018
-
-#![feature(async_await, await_macro)]
-
-use std::future::Future;
-
-#[allow(unused)]
-async fn enter<'a, F, R>(mut callback: F)
-where
-    F: FnMut(&'a mut i32) -> R,
-    R: Future<Output = ()> + 'a,
-{
-    unimplemented!()
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-59508-1.rs b/src/test/ui/issues/issue-59508-1.rs
new file mode 100644 (file)
index 0000000..4fbed9b
--- /dev/null
@@ -0,0 +1,18 @@
+#![allow(dead_code)]
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+// This test checks that generic parameter re-ordering diagnostic suggestions mention that
+// consts come after types and lifetimes when the `const_generics` feature is enabled.
+// We cannot run rustfix on this test because of the above const generics warning.
+
+struct A;
+
+impl A {
+    pub fn do_things<T, 'a, 'b: 'a>() {
+    //~^ ERROR lifetime parameters must be declared prior to type parameters
+        println!("panic");
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-59508-1.stderr b/src/test/ui/issues/issue-59508-1.stderr
new file mode 100644 (file)
index 0000000..8fb7d7c
--- /dev/null
@@ -0,0 +1,14 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/issue-59508-1.rs:2:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/issue-59508-1.rs:12:25
+   |
+LL |     pub fn do_things<T, 'a, 'b: 'a>() {
+   |                     ----^^--^^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b: 'a, T>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issues/issue-59508.fixed b/src/test/ui/issues/issue-59508.fixed
new file mode 100644 (file)
index 0000000..b5c60a1
--- /dev/null
@@ -0,0 +1,16 @@
+// run-rustfix
+
+#![allow(dead_code)]
+
+// This test checks that generic parameter re-ordering diagnostic suggestions contain bounds.
+
+struct A;
+
+impl A {
+    pub fn do_things<'a, 'b: 'a, T>() {
+    //~^ ERROR lifetime parameters must be declared prior to type parameters
+        println!("panic");
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-59508.rs b/src/test/ui/issues/issue-59508.rs
new file mode 100644 (file)
index 0000000..0b39c5d
--- /dev/null
@@ -0,0 +1,16 @@
+// run-rustfix
+
+#![allow(dead_code)]
+
+// This test checks that generic parameter re-ordering diagnostic suggestions contain bounds.
+
+struct A;
+
+impl A {
+    pub fn do_things<T, 'a, 'b: 'a>() {
+    //~^ ERROR lifetime parameters must be declared prior to type parameters
+        println!("panic");
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-59508.stderr b/src/test/ui/issues/issue-59508.stderr
new file mode 100644 (file)
index 0000000..c0fdb2e
--- /dev/null
@@ -0,0 +1,8 @@
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/issue-59508.rs:10:25
+   |
+LL |     pub fn do_things<T, 'a, 'b: 'a>() {
+   |                     ----^^--^^----- help: reorder the parameters: lifetimes, then types: `<'a, 'b: 'a, T>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issues/issue-59756.fixed b/src/test/ui/issues/issue-59756.fixed
new file mode 100644 (file)
index 0000000..7b55d0f
--- /dev/null
@@ -0,0 +1,17 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+struct A;
+struct B;
+
+fn foo() -> Result<A, B> {
+    Ok(A)
+}
+
+fn bar() -> Result<A, B> {
+    foo()
+    //~^ ERROR try expression alternatives have incompatible types [E0308]
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-59756.rs b/src/test/ui/issues/issue-59756.rs
new file mode 100644 (file)
index 0000000..cccae39
--- /dev/null
@@ -0,0 +1,17 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+struct A;
+struct B;
+
+fn foo() -> Result<A, B> {
+    Ok(A)
+}
+
+fn bar() -> Result<A, B> {
+    foo()?
+    //~^ ERROR try expression alternatives have incompatible types [E0308]
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-59756.stderr b/src/test/ui/issues/issue-59756.stderr
new file mode 100644 (file)
index 0000000..d462328
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0308]: try expression alternatives have incompatible types
+  --> $DIR/issue-59756.rs:13:5
+   |
+LL |     foo()?
+   |     ^^^^^-
+   |     |    |
+   |     |    help: try removing this `?`
+   |     expected enum `std::result::Result`, found struct `A`
+   |
+   = note: expected type `std::result::Result<A, B>`
+              found type `A`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-59764.rs b/src/test/ui/issues/issue-59764.rs
new file mode 100644 (file)
index 0000000..09dee8c
--- /dev/null
@@ -0,0 +1,136 @@
+// aux-build:issue-59764.rs
+// compile-flags:--extern issue_59764
+// edition:2018
+
+#![allow(warnings)]
+
+// This tests the suggestion to import macros from the root of a crate. This aims to capture
+// the case where a user attempts to import a macro from the definition location instead of the
+// root of the crate and the macro is annotated with `#![macro_export]`.
+
+// Edge cases..
+
+mod multiple_imports_same_line_at_end {
+    use issue_59764::foo::{baz, makro};
+    //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+}
+
+mod multiple_imports_multiline_at_end_trailing_comma {
+    use issue_59764::foo::{
+        baz,
+        makro, //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+    };
+}
+
+mod multiple_imports_multiline_at_end {
+    use issue_59764::foo::{
+        baz,
+        makro //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+    };
+}
+
+mod multiple_imports_same_line_in_middle {
+    use issue_59764::foo::{baz, makro, foobar};
+    //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+}
+
+mod multiple_imports_multiline_in_middle_trailing_comma {
+    use issue_59764::foo::{
+        baz,
+        makro, //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+        foobar,
+    };
+}
+
+mod multiple_imports_multiline_in_middle {
+    use issue_59764::foo::{
+        baz,
+        makro, //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+        foobar
+    };
+}
+
+mod nested_imports {
+    use issue_59764::{foobaz, foo::makro};
+    //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+}
+
+mod nested_multiple_imports {
+    use issue_59764::{foobaz, foo::{baz, makro}};
+    //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+}
+
+mod nested_multiline_multiple_imports_trailing_comma {
+    use issue_59764::{
+        foobaz,
+        foo::{
+            baz,
+            makro, //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+        },
+    };
+}
+
+mod nested_multiline_multiple_imports {
+    use issue_59764::{
+        foobaz,
+        foo::{
+            baz,
+            makro //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+        }
+    };
+}
+
+mod doubly_nested_multiple_imports {
+    use issue_59764::{foobaz, foo::{baz, makro, barbaz::{barfoo}}};
+    //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+}
+
+mod doubly_multiline_nested_multiple_imports {
+    use issue_59764::{
+        foobaz,
+        foo::{
+            baz,
+            makro, //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+            barbaz::{
+                barfoo,
+            }
+        }
+    };
+}
+
+mod renamed_import {
+    use issue_59764::foo::makro as baz;
+    //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+}
+
+mod renamed_multiple_imports {
+    use issue_59764::foo::{baz, makro as foobar};
+    //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+}
+
+mod lots_of_whitespace {
+    use
+        issue_59764::{
+
+            foobaz,
+
+
+            foo::{baz,
+
+                makro as foobar} //~ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+
+        };
+}
+
+// Simple case..
+
+use issue_59764::foo::makro;
+//~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
+
+makro!(bar);
+//~^ ERROR cannot determine resolution for the macro `makro`
+
+fn main() {
+    bar();
+    //~^ ERROR cannot find function `bar` in this scope [E0425]
+}
diff --git a/src/test/ui/issues/issue-59764.stderr b/src/test/ui/issues/issue-59764.stderr
new file mode 100644 (file)
index 0000000..f266e90
--- /dev/null
@@ -0,0 +1,241 @@
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:14:33
+   |
+LL |     use issue_59764::foo::{baz, makro};
+   |                                 ^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |     use issue_59764::{makro, foo::{baz}};
+   |                      ^^^^^^^^^       --^^
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:21:9
+   |
+LL |         makro,
+   |         ^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |     use issue_59764::{makro, foo::{
+LL |         baz,
+LL |
+LL |     }};
+   |
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:28:9
+   |
+LL |         makro
+   |         ^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |     use issue_59764::{makro, foo::{
+LL |         baz,
+LL |
+LL |     }};
+   |
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:33:33
+   |
+LL |     use issue_59764::foo::{baz, makro, foobar};
+   |                                 ^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |     use issue_59764::{makro, foo::{baz, foobar}};
+   |                      ^^^^^^^^^         --      ^^
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:40:9
+   |
+LL |         makro,
+   |         ^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |     use issue_59764::{makro, foo::{
+LL |         baz,
+LL |
+LL |         foobar,
+LL |     }};
+   |
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:48:9
+   |
+LL |         makro,
+   |         ^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |     use issue_59764::{makro, foo::{
+LL |         baz,
+LL |
+LL |         foobar
+LL |     }};
+   |
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:54:31
+   |
+LL |     use issue_59764::{foobaz, foo::makro};
+   |                               ^^^^^^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |     use issue_59764::{makro, foobaz};
+   |                      ^^^^^^^      --
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:59:42
+   |
+LL |     use issue_59764::{foobaz, foo::{baz, makro}};
+   |                                          ^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |     use issue_59764::{makro, foobaz, foo::{baz}};
+   |                      ^^^^^^^                 --
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:68:13
+   |
+LL |             makro,
+   |             ^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |     use issue_59764::{makro, 
+LL |         foobaz,
+LL |         foo::{
+LL |             baz,
+LL |
+   |
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:78:13
+   |
+LL |             makro
+   |             ^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |     use issue_59764::{makro, 
+LL |         foobaz,
+LL |         foo::{
+LL |             baz,
+LL |
+   |
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:84:42
+   |
+LL |     use issue_59764::{foobaz, foo::{baz, makro, barbaz::{barfoo}}};
+   |                                          ^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |     use issue_59764::{makro, foobaz, foo::{baz, barbaz::{barfoo}}};
+   |                      ^^^^^^^                   --
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:93:13
+   |
+LL |             makro,
+   |             ^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |     use issue_59764::{makro, 
+LL |         foobaz,
+LL |         foo::{
+LL |             baz,
+LL |
+   |
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:102:9
+   |
+LL |     use issue_59764::foo::makro as baz;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |     use issue_59764::makro as baz;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:107:33
+   |
+LL |     use issue_59764::foo::{baz, makro as foobar};
+   |                                 ^^^^^^^^^^^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |     use issue_59764::{makro as foobar, foo::{baz}};
+   |                      ^^^^^^^^^^^^^^^^^^^       --^^
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:120:17
+   |
+LL |                 makro as foobar}
+   |                 ^^^^^^^^^^^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL |         issue_59764::{makro as foobar, 
+LL | 
+LL |             foobaz,
+LL | 
+LL | 
+LL |             foo::{baz}
+   |
+
+error[E0432]: unresolved import `issue_59764::foo::makro`
+  --> $DIR/issue-59764.rs:127:5
+   |
+LL | use issue_59764::foo::makro;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ no `makro` in `foo`
+   |
+   = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined
+help: a macro with this name exists at the root of the crate
+   |
+LL | use issue_59764::makro;
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: cannot determine resolution for the macro `makro`
+  --> $DIR/issue-59764.rs:130:1
+   |
+LL | makro!(bar);
+   | ^^^^^
+   |
+   = note: import resolution is stuck, try simplifying macro imports
+
+error[E0425]: cannot find function `bar` in this scope
+  --> $DIR/issue-59764.rs:134:5
+   |
+LL |     bar();
+   |     ^^^ not found in this scope
+
+error: aborting due to 18 previous errors
+
+Some errors have detailed explanations: E0425, E0432.
+For more information about an error, try `rustc --explain E0425`.
diff --git a/src/test/ui/issues/issue-60075.rs b/src/test/ui/issues/issue-60075.rs
new file mode 100644 (file)
index 0000000..5788716
--- /dev/null
@@ -0,0 +1,12 @@
+fn main() {}
+
+trait T {
+    fn qux() -> Option<usize> {
+        let _ = if true {
+        });
+//~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `;`
+//~^^ ERROR expected one of `.`, `;`, `?`, `else`, or an operator, found `}`
+//~^^^ ERROR 6:11: 6:12: expected identifier, found `;`
+//~^^^^ ERROR missing `fn`, `type`, or `const` for trait-item declaration
+        Some(4)
+    }
diff --git a/src/test/ui/issues/issue-60075.stderr b/src/test/ui/issues/issue-60075.stderr
new file mode 100644 (file)
index 0000000..ac97d32
--- /dev/null
@@ -0,0 +1,35 @@
+error: expected one of `.`, `;`, `?`, `else`, or an operator, found `}`
+  --> $DIR/issue-60075.rs:6:10
+   |
+LL |         });
+   |          ^ expected one of `.`, `;`, `?`, `else`, or an operator here
+
+error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `;`
+  --> $DIR/issue-60075.rs:6:11
+   |
+LL |     fn qux() -> Option<usize> {
+   |                               - unclosed delimiter
+LL |         let _ = if true {
+LL |         });
+   |           ^ help: `}` may belong here
+
+error: expected identifier, found `;`
+  --> $DIR/issue-60075.rs:6:11
+   |
+LL |         });
+   |           ^ expected identifier
+
+error: missing `fn`, `type`, or `const` for trait-item declaration
+  --> $DIR/issue-60075.rs:6:12
+   |
+LL |           });
+   |  ____________^
+LL | |
+LL | |
+LL | |
+LL | |
+LL | |         Some(4)
+   | |________^ missing `fn`, `type`, or `const`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/issues/issue-60622.rs b/src/test/ui/issues/issue-60622.rs
new file mode 100644 (file)
index 0000000..d6a0189
--- /dev/null
@@ -0,0 +1,18 @@
+// ignore-tidy-linelength
+
+#![deny(warnings)]
+
+struct Borked {}
+
+impl Borked {
+    fn a(&self) {}
+}
+
+fn run_wild<T>(b: &Borked) {
+    b.a::<'_, T>();
+    //~^ ERROR cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+    //~^^ ERROR wrong number of type arguments: expected 0, found 1
+    //~^^^ WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-60622.stderr b/src/test/ui/issues/issue-60622.stderr
new file mode 100644 (file)
index 0000000..0c337c3
--- /dev/null
@@ -0,0 +1,27 @@
+error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+  --> $DIR/issue-60622.rs:12:11
+   |
+LL |     fn a(&self) {}
+   |          - the late bound lifetime parameter is introduced here
+...
+LL |     b.a::<'_, T>();
+   |           ^^
+   |
+note: lint level defined here
+  --> $DIR/issue-60622.rs:3:9
+   |
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: #[deny(late_bound_lifetime_arguments)] implied by #[deny(warnings)]
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
+
+error[E0107]: wrong number of type arguments: expected 0, found 1
+  --> $DIR/issue-60622.rs:12:15
+   |
+LL |     b.a::<'_, T>();
+   |               ^ unexpected type argument
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/issues/issue-60989.rs b/src/test/ui/issues/issue-60989.rs
new file mode 100644 (file)
index 0000000..930e98b
--- /dev/null
@@ -0,0 +1,18 @@
+struct A {}
+struct B {}
+
+impl From<A> for B {
+    fn from(a: A) -> B {
+        B{}
+    }
+}
+
+fn main() {
+    let c1 = ();
+    c1::<()>;
+    //~^ ERROR type arguments are not allowed for this type
+
+    let c1 = A {};
+    c1::<Into<B>>;
+    //~^ ERROR type arguments are not allowed for this type
+}
diff --git a/src/test/ui/issues/issue-60989.stderr b/src/test/ui/issues/issue-60989.stderr
new file mode 100644 (file)
index 0000000..55a0b96
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/issue-60989.rs:12:10
+   |
+LL |     c1::<()>;
+   |          ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/issue-60989.rs:16:10
+   |
+LL |     c1::<Into<B>>;
+   |          ^^^^^^^ type argument not allowed
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0109`.
diff --git a/src/test/ui/issues/issue-61108.rs b/src/test/ui/issues/issue-61108.rs
new file mode 100644 (file)
index 0000000..0a883b9
--- /dev/null
@@ -0,0 +1,7 @@
+fn main() {
+    let mut bad_letters = vec!['e', 't', 'o', 'i'];
+    for l in bad_letters {
+        // something here
+    }
+    bad_letters.push('s'); //~ ERROR borrow of moved value: `bad_letters`
+}
diff --git a/src/test/ui/issues/issue-61108.stderr b/src/test/ui/issues/issue-61108.stderr
new file mode 100644 (file)
index 0000000..8523a6f
--- /dev/null
@@ -0,0 +1,17 @@
+error[E0382]: borrow of moved value: `bad_letters`
+  --> $DIR/issue-61108.rs:6:5
+   |
+LL |     let mut bad_letters = vec!['e', 't', 'o', 'i'];
+   |         --------------- move occurs because `bad_letters` has type `std::vec::Vec<char>`, which does not implement the `Copy` trait
+LL |     for l in bad_letters {
+   |              -----------
+   |              |
+   |              value moved here
+   |              help: consider borrowing to avoid moving into the for loop: `&bad_letters`
+...
+LL |     bad_letters.push('s');
+   |     ^^^^^^^^^^^ value borrowed here after move
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
index c97a4320f1d2092907e5e0e87e68b5f8c35a9dad..0d327677d5469923805047d75a67060d96c9c25d 100644 (file)
@@ -1,4 +1,4 @@
-#![deny = "foo"] //~ ERROR attribute must be of the form
+#![deny = "foo"] //~ ERROR malformed `deny` attribute input
 #![allow(bar = "baz")] //~ ERROR malformed lint attribute
 
 fn main() { }
index f5b9e2b0a0f6dc7435f50012cf57816a8b3b7cce..f4876290ddb5d16f5cc4dc9e25168d42f13a02ec 100644 (file)
@@ -1,14 +1,14 @@
-error[E0452]: malformed lint attribute
+error[E0452]: malformed lint attribute input
   --> $DIR/lint-malformed.rs:2:10
    |
 LL | #![allow(bar = "baz")]
-   |          ^^^^^^^^^^^
+   |          ^^^^^^^^^^^ bad attribute argument
 
-error: attribute must be of the form `#[deny(lint1, lint2, ..., /*opt*/ reason = "...")]`
+error: malformed `deny` attribute input
   --> $DIR/lint-malformed.rs:1:1
    |
 LL | #![deny = "foo"]
-   | ^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[deny(lint1, lint2, ..., /*opt*/ reason = "...")]`
 
 error: aborting due to 2 previous errors
 
index e42b329338b5a2c71d47759b0e7051dd0ef1209d..84db885ac0949a6ffd0cef6c26b4bcfa0c39e55d 100644 (file)
@@ -2,23 +2,27 @@
 
 #![warn(absolute_paths_not_starting_with_crate, reason = 0)]
 //~^ ERROR malformed lint attribute
-//~| HELP reason must be a string literal
+//~| NOTE reason must be a string literal
 #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
 //~^ ERROR malformed lint attribute
-//~| HELP reason must be a string literal
+//~| NOTE reason must be a string literal
 #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
 //~^ ERROR malformed lint attribute
+//~| NOTE bad attribute argument
 #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
 //~^ ERROR malformed lint attribute
+//~| NOTE bad attribute argument
 #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
 //~^ ERROR malformed lint attribute
+//~| NOTE bad attribute argument
 #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
 //~^ ERROR malformed lint attribute
-//~| HELP reason in lint attribute must come last
+//~| NOTE reason in lint attribute must come last
 #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
 //~^ ERROR malformed lint attribute
-//~| HELP reason in lint attribute must come last
+//~| NOTE reason in lint attribute must come last
 #![warn(missing_copy_implementations, reason)]
 //~^ WARN unknown lint
+//~| NOTE #[warn(unknown_lints)] on by default
 
 fn main() {}
index 6842686ecbab581a38343874bb5bdc2ec3c179a2..ff4a0f36bbda400ece5573f49fc188d39a6543d7 100644 (file)
@@ -1,55 +1,47 @@
-error[E0452]: malformed lint attribute
+error[E0452]: malformed lint attribute input
   --> $DIR/reasons-erroneous.rs:3:58
    |
 LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)]
-   |                                                          ^
-   |
-   = help: reason must be a string literal
+   |                                                          ^ reason must be a string literal
 
-error[E0452]: malformed lint attribute
+error[E0452]: malformed lint attribute input
   --> $DIR/reasons-erroneous.rs:6:40
    |
 LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
-   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: reason must be a string literal
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal
 
-error[E0452]: malformed lint attribute
+error[E0452]: malformed lint attribute input
   --> $DIR/reasons-erroneous.rs:9:29
    |
 LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
-error[E0452]: malformed lint attribute
-  --> $DIR/reasons-erroneous.rs:11:23
+error[E0452]: malformed lint attribute input
+  --> $DIR/reasons-erroneous.rs:12:23
    |
 LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
-error[E0452]: malformed lint attribute
-  --> $DIR/reasons-erroneous.rs:13:36
+error[E0452]: malformed lint attribute input
+  --> $DIR/reasons-erroneous.rs:15:36
    |
 LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
-   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
-error[E0452]: malformed lint attribute
-  --> $DIR/reasons-erroneous.rs:15:44
+error[E0452]: malformed lint attribute input
+  --> $DIR/reasons-erroneous.rs:18:44
    |
 LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
-   |                                            ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: reason in lint attribute must come last
+   |                                            ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
 
-error[E0452]: malformed lint attribute
-  --> $DIR/reasons-erroneous.rs:18:25
+error[E0452]: malformed lint attribute input
+  --> $DIR/reasons-erroneous.rs:21:25
    |
 LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: reason in lint attribute must come last
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
 
 warning: unknown lint: `reason`
-  --> $DIR/reasons-erroneous.rs:21:39
+  --> $DIR/reasons-erroneous.rs:24:39
    |
 LL | #![warn(missing_copy_implementations, reason)]
    |                                       ^^^^^^
index b634cf2d9944c1d826eb5283a89101c1ea74205d..fd4f93091944cd5af20d48bfad1f05a82f47584d 100644 (file)
@@ -12,17 +12,17 @@ error: expected expression, found keyword `struct`
 LL |     format!(struct);
    |             ^^^^^^ expected expression
 
-error: expected expression, found `<eof>`
-  --> $DIR/format-parse-errors.rs:4:23
+error: expected expression, found end of macro arguments
+  --> $DIR/format-parse-errors.rs:4:24
    |
 LL |     format!("s", name =);
-   |                       ^ expected expression
+   |                        ^ expected expression
 
-error: expected `=`, found `<eof>`
-  --> $DIR/format-parse-errors.rs:5:29
+error: expected `=`, found end of macro arguments
+  --> $DIR/format-parse-errors.rs:5:32
    |
 LL |     format!("s", foo = foo, bar);
-   |                             ^^^ expected `=`
+   |                                ^ expected `=`
 
 error: expected expression, found keyword `struct`
   --> $DIR/format-parse-errors.rs:6:24
index 74d22102c664df426763d75cdc0cbe2e07e0e7e6..3e53e15601b0b9aafd601ca3a6ada5668a1b40b5 100644 (file)
@@ -1,17 +1,13 @@
-#[derive(Copy(Bad))]
-//~^ ERROR expected one of `)`, `,`, or `::`, found `(`
+#[derive(Copy(Bad))] //~ ERROR expected one of `)`, `,`, or `::`, found `(`
 struct Test1;
 
-#[derive(Copy="bad")]
-//~^ ERROR expected one of `)`, `,`, or `::`, found `=`
+#[derive(Copy="bad")] //~ ERROR expected one of `)`, `,`, or `::`, found `=`
 struct Test2;
 
-#[derive()]
-//~^ WARNING empty trait list
+#[derive()] //~ WARNING empty trait list
 struct Test3;
 
-#[derive]
-//~^ ERROR attribute must be of the form
+#[derive] //~ ERROR malformed `derive` attribute input
 struct Test4;
 
 fn main() {}
index f546f74220a1c699b522a8f84dec080c2177e930..dfbc5faedac592098bd536f9dc1cd3f651c624d2 100644 (file)
@@ -5,22 +5,22 @@ LL | #[derive(Copy(Bad))]
    |              ^ expected one of `)`, `,`, or `::` here
 
 error: expected one of `)`, `,`, or `::`, found `=`
-  --> $DIR/malformed-derive-entry.rs:5:14
+  --> $DIR/malformed-derive-entry.rs:4:14
    |
 LL | #[derive(Copy="bad")]
    |              ^ expected one of `)`, `,`, or `::` here
 
 warning: empty trait list in `derive`
-  --> $DIR/malformed-derive-entry.rs:9:1
+  --> $DIR/malformed-derive-entry.rs:7:1
    |
 LL | #[derive()]
    | ^^^^^^^^^^^
 
-error: attribute must be of the form `#[derive(Trait1, Trait2, ...)]`
-  --> $DIR/malformed-derive-entry.rs:13:1
+error: malformed `derive` attribute input
+  --> $DIR/malformed-derive-entry.rs:10:1
    |
 LL | #[derive]
-   | ^^^^^^^^^
+   | ^^^^^^^^^ help: missing traits to be derived: `#[derive(Trait1, Trait2, ...)]`
 
 error: aborting due to 3 previous errors
 
index 16e7a952ef2d072885230cc58b083f7b2fd34421..28f6c8e7a6f6739d731117c2b717ad2c0acd51b9 100644 (file)
@@ -1,4 +1,4 @@
 #![feature(plugin)]
-#![plugin] //~ ERROR attribute must be of the form
+#![plugin] //~ ERROR malformed `plugin` attribute
 
 fn main() {}
index cc0ac182d7064a9a986359720bd9bea87ddea3ef..a863cd48596563e836be2c454ce6728e3ab3fdeb 100644 (file)
@@ -1,8 +1,8 @@
-error: attribute must be of the form `#[plugin(name|name(args))]`
+error: malformed `plugin` attribute input
   --> $DIR/malformed-plugin-1.rs:2:1
    |
 LL | #![plugin]
-   | ^^^^^^^^^^
+   | ^^^^^^^^^^ help: must be of the form: `#[plugin(name|name(args))]`
 
 error: aborting due to previous error
 
index 70a1d7f85e8b6907c4b32e5ef3230094d5137435..8ec7a71da29b3bd71dcd62d8c2c511dd95fbedd7 100644 (file)
@@ -1,4 +1,4 @@
 #![feature(plugin)]
-#![plugin="bleh"] //~ ERROR attribute must be of the form
+#![plugin="bleh"] //~ ERROR malformed `plugin` attribute
 
 fn main() {}
index 617b13b2654f8198b4058cefbcd894ce76a8d984..6eb0c50ca939840bd55d6fbfa07ae6e22c5cbbc4 100644 (file)
@@ -1,8 +1,8 @@
-error: attribute must be of the form `#[plugin(name|name(args))]`
+error: malformed `plugin` attribute input
   --> $DIR/malformed-plugin-2.rs:2:1
    |
 LL | #![plugin="bleh"]
-   | ^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[plugin(name|name(args))]`
 
 error: aborting due to previous error
 
index 1b70ff3bdb7c11531b3fc2cca707daa45c898aa0..c4713616b6258a5f838fb061138a67a6d79ec247 100644 (file)
@@ -1,4 +1,4 @@
 #![feature(plugin)]
-#![plugin(foo="bleh")] //~ ERROR malformed plugin attribute
+#![plugin(foo="bleh")] //~ ERROR malformed `plugin` attribute
 
 fn main() {}
index bcbbcd48c66ba0056c0f33af1b2eefdf335074c1..f93fa0f65e85a28d0cf54a0bc3553beb1cf5cf7e 100644 (file)
@@ -1,8 +1,8 @@
-error[E0498]: malformed plugin attribute
+error[E0498]: malformed `plugin` attribute
   --> $DIR/malformed-plugin-3.rs:2:1
    |
 LL | #![plugin(foo="bleh")]
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^ malformed attribute
 
 error: aborting due to previous error
 
index f91c6bedb2b2130b8b76049f0afe9bc7c957d4bc..e67fbdd5ddd32d4776df583db21a26e9c7045214 100644 (file)
@@ -1,13 +1,13 @@
-#[cfg_attr] //~ ERROR expected `(`, found `<eof>`
+#[cfg_attr] //~ ERROR malformed `cfg_attr` attribute
 struct S1;
 
 #[cfg_attr = ""] //~ ERROR expected `(`, found `=`
 struct S2;
 
-#[derive] //~ ERROR attribute must be of the form
+#[derive] //~ ERROR malformed `derive` attribute
 struct S3;
 
-#[derive = ""] //~ ERROR attribute must be of the form
+#[derive = ""] //~ ERROR malformed `derive` attribute
 struct S4;
 
 fn main() {}
index 8c23424087c04aaf76b5aba56c83dd3f8b083157..319c05eadbf1dbfcb4955f82608179217f946177 100644 (file)
@@ -1,25 +1,28 @@
-error: expected `(`, found `<eof>`
+error: malformed `cfg_attr` attribute input
+  --> $DIR/malformed-special-attrs.rs:1:1
+   |
+LL | #[cfg_attr]
+   | ^^^^^^^^^^^ help: missing condition and attribute: `#[cfg_attr(condition, attribute, other_attribute, ...)]`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
 
 error: expected `(`, found `=`
   --> $DIR/malformed-special-attrs.rs:4:12
    |
-LL | #[cfg_attr]
-   | - expected `(`
-...
 LL | #[cfg_attr = ""]
-   |            ^ unexpected token
+   |            ^ expected `(`
 
-error: attribute must be of the form `#[derive(Trait1, Trait2, ...)]`
+error: malformed `derive` attribute input
   --> $DIR/malformed-special-attrs.rs:7:1
    |
 LL | #[derive]
-   | ^^^^^^^^^
+   | ^^^^^^^^^ help: missing traits to be derived: `#[derive(Trait1, Trait2, ...)]`
 
-error: attribute must be of the form `#[derive(Trait1, Trait2, ...)]`
+error: malformed `derive` attribute input
   --> $DIR/malformed-special-attrs.rs:10:1
    |
 LL | #[derive = ""]
-   | ^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^ help: missing traits to be derived: `#[derive(Trait1, Trait2, ...)]`
 
 error: aborting due to 4 previous errors
 
index e34c288c027c22f04b8740437a6b38cbefe3e122..009695b177f965d1fa0ecf88272d5073814ab906 100644 (file)
@@ -1,11 +1,9 @@
 #![feature(unwind_attributes)]
 
-#[unwind]
-//~^ ERROR attribute must be of the form
+#[unwind] //~ ERROR malformed `unwind` attribute
 extern "C" fn f1() {}
 
-#[unwind = ""]
-//~^ ERROR attribute must be of the form
+#[unwind = ""] //~ ERROR malformed `unwind` attribute
 extern "C" fn f2() {}
 
 fn main() {}
index 852136eed91bde56a9e74a5c7e14f0bab2181614..0a553e8a245f6e51d5e83f1b3f4ad34ec8ac1946 100644 (file)
@@ -1,14 +1,14 @@
-error: attribute must be of the form `#[unwind(allowed|aborts)]`
+error: malformed `unwind` attribute input
   --> $DIR/malformed-unwind-1.rs:3:1
    |
 LL | #[unwind]
-   | ^^^^^^^^^
+   | ^^^^^^^^^ help: must be of the form: `#[unwind(allowed|aborts)]`
 
-error: attribute must be of the form `#[unwind(allowed|aborts)]`
-  --> $DIR/malformed-unwind-1.rs:7:1
+error: malformed `unwind` attribute input
+  --> $DIR/malformed-unwind-1.rs:6:1
    |
 LL | #[unwind = ""]
-   | ^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^ help: must be of the form: `#[unwind(allowed|aborts)]`
 
 error: aborting due to 2 previous errors
 
index d4955b43309308020e177cbe64c8c369c110d3de..9aafc7ca9b851db1e567e7077edd5d71b1b206fe 100644 (file)
@@ -1,11 +1,11 @@
 #![feature(unwind_attributes)]
 
 #[unwind(allowed, aborts)]
-//~^ ERROR malformed `#[unwind]` attribute
+//~^ ERROR malformed `unwind` attribute
 extern "C" fn f1() {}
 
 #[unwind(unsupported)]
-//~^ ERROR malformed `#[unwind]` attribute
+//~^ ERROR malformed `unwind` attribute
 extern "C" fn f2() {}
 
 fn main() {}
index 88fc4e00a2fd3dbd0d521b56141889890f056b59..ed88b9afd87580090f88291f0ba6433b1dbcd248 100644 (file)
@@ -1,14 +1,26 @@
-error[E0633]: malformed `#[unwind]` attribute
+error[E0633]: malformed `unwind` attribute input
   --> $DIR/malformed-unwind-2.rs:3:1
    |
 LL | #[unwind(allowed, aborts)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid argument
+help: the allowed arguments are `allowed` and `aborts`
+   |
+LL | #[unwind(allowed)]
+   |
+LL | #[unwind(aborts)]
+   |
 
-error[E0633]: malformed `#[unwind]` attribute
+error[E0633]: malformed `unwind` attribute input
   --> $DIR/malformed-unwind-2.rs:7:1
    |
 LL | #[unwind(unsupported)]
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^ invalid argument
+help: the allowed arguments are `allowed` and `aborts`
+   |
+LL | #[unwind(allowed)]
+   |
+LL | #[unwind(aborts)]
+   |
 
 error: aborting due to 2 previous errors
 
index f8bcec78650e87c6d129c2d7098b26bacf63b8de..9e07f0eaeea7ffe4ce6f5c2a083a218c30fbf29d 100644 (file)
@@ -1,15 +1,12 @@
 #![feature(marker_trait_attr)]
 
-#[marker(always)]
+#[marker(always)] //~ ERROR malformed `marker` attribute
 trait Marker1 {}
-//~^^ ERROR attribute must be of the form
 
-#[marker("never")]
+#[marker("never")] //~ ERROR malformed `marker` attribute
 trait Marker2 {}
-//~^^ ERROR attribute must be of the form
 
-#[marker(key = "value")]
+#[marker(key = "value")] //~ ERROR malformed `marker` attribute
 trait Marker3 {}
-//~^^ ERROR attribute must be of the form `#[marker]`
 
 fn main() {}
index 2b31dcb4760a01ff44eef8579d859bc744171d80..6f9c9508e7e5525bba26ff2e31cb324597e6ebe6 100644 (file)
@@ -1,20 +1,20 @@
-error: attribute must be of the form `#[marker]`
+error: malformed `marker` attribute input
   --> $DIR/marker-attribute-with-values.rs:3:1
    |
 LL | #[marker(always)]
-   | ^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]`
 
-error: attribute must be of the form `#[marker]`
-  --> $DIR/marker-attribute-with-values.rs:7:1
+error: malformed `marker` attribute input
+  --> $DIR/marker-attribute-with-values.rs:6:1
    |
 LL | #[marker("never")]
-   | ^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]`
 
-error: attribute must be of the form `#[marker]`
-  --> $DIR/marker-attribute-with-values.rs:11:1
+error: malformed `marker` attribute input
+  --> $DIR/marker-attribute-with-values.rs:9:1
    |
 LL | #[marker(key = "value")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/nll/dont-print-desugared-async.rs b/src/test/ui/nll/dont-print-desugared-async.rs
deleted file mode 100644 (file)
index 8150a26..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// Test that we don't show variables with from async fn desugaring
-
-// edition:2018
-#![feature(async_await)]
-
-async fn async_fn(&ref mut s: &[i32]) {}
-//~^ ERROR cannot borrow data in a `&` reference as mutable [E0596]
-
-fn main() {}
diff --git a/src/test/ui/nll/dont-print-desugared-async.stderr b/src/test/ui/nll/dont-print-desugared-async.stderr
deleted file mode 100644 (file)
index 47726ba..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0596]: cannot borrow data in a `&` reference as mutable
-  --> $DIR/dont-print-desugared-async.rs:6:20
-   |
-LL | async fn async_fn(&ref mut s: &[i32]) {}
-   |                   -^^^^^^^^^
-   |                   ||
-   |                   |cannot borrow as mutable through `&` reference
-   |                   help: consider changing this to be a mutable reference: `&mut ref mut s`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/no-args-non-move-async-closure.rs b/src/test/ui/no-args-non-move-async-closure.rs
deleted file mode 100644 (file)
index 345f19b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// edition:2018
-
-#![feature(async_await, await_macro)]
-
-fn main() {
-    let _ = async |x: u8| {};
-    //~^ ERROR `async` non-`move` closures with arguments are not currently supported
-}
diff --git a/src/test/ui/no-args-non-move-async-closure.stderr b/src/test/ui/no-args-non-move-async-closure.stderr
deleted file mode 100644 (file)
index 1b4b862..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-error[E0708]: `async` non-`move` closures with arguments are not currently supported
-  --> $DIR/no-args-non-move-async-closure.rs:6:13
-   |
-LL |     let _ = async |x: u8| {};
-   |             ^^^^^^^^^^^^^
-   |
-   = help: consider using `let` statements to manually capture variables by reference before entering an `async move` closure
-
-error: aborting due to previous error
-
index 392c6fd0dfa13ef0385a856b2a522a37e8ec1cdd..d8e687e04a76d94b93a133126b0f43adc25d195f 100644 (file)
@@ -1,5 +1,5 @@
 // regression test for issue 11256
-#![crate_type]  //~ ERROR attribute must be of the form
+#![crate_type]  //~ ERROR malformed `crate_type` attribute
 
 fn main() {
     return
index ec79420d4dd4843c0c40a769b0d94ed8eddd2c5f..f34df4e2dd143f66758a82124e847f2bc6f3623c 100644 (file)
@@ -1,8 +1,8 @@
-error: attribute must be of the form `#[crate_type = "bin|lib|..."]`
+error: malformed `crate_type` attribute input
   --> $DIR/no_crate_type.rs:2:1
    |
 LL | #![crate_type]
-   | ^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "bin|lib|..."]`
 
 error: aborting due to previous error
 
index 846db63024cfb3415d19eb4db3c3ba5dc86ba6d7..5357c3bff9a8ae776cd18241cf3c5bbe84517bc1 100644 (file)
@@ -15,7 +15,7 @@ trait MyFromIterator<A> {
 }
 
 #[rustc_on_unimplemented]
-//~^ ERROR attribute must be of the form
+//~^ ERROR malformed `rustc_on_unimplemented` attribute
 trait BadAnnotation1
 {}
 
index abbe9f0fcd41e51f6d1ef117a1c6374034aff4fb..20b2169f45824e95733148c911834a5cdee9ffa5 100644 (file)
@@ -1,8 +1,14 @@
-error: attribute must be of the form `#[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")]` or `#[rustc_on_unimplemented = "message"]`
+error: malformed `rustc_on_unimplemented` attribute input
   --> $DIR/bad-annotation.rs:17:1
    |
 LL | #[rustc_on_unimplemented]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
+help: the following are the possible correct uses
+   |
+LL | #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")]
+   |
+LL | #[rustc_on_unimplemented = "message"]
+   |
 
 error[E0230]: there is no parameter `C` on trait `BadAnnotation2`
   --> $DIR/bad-annotation.rs:22:1
diff --git a/src/test/ui/parser/macro/bad-macro-argument.rs b/src/test/ui/parser/macro/bad-macro-argument.rs
new file mode 100644 (file)
index 0000000..4b6d238
--- /dev/null
@@ -0,0 +1,4 @@
+fn main() {
+    let message = "world";
+    println!("Hello, {}", message/); //~ ERROR expected expression
+}
diff --git a/src/test/ui/parser/macro/bad-macro-argument.stderr b/src/test/ui/parser/macro/bad-macro-argument.stderr
new file mode 100644 (file)
index 0000000..3cd8acc
--- /dev/null
@@ -0,0 +1,8 @@
+error: expected expression, found end of macro arguments
+  --> $DIR/bad-macro-argument.rs:3:35
+   |
+LL |     println!("Hello, {}", message/);
+   |                                   ^ expected expression
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/self-in-function-arg.rs b/src/test/ui/parser/self-in-function-arg.rs
new file mode 100644 (file)
index 0000000..6172ffe
--- /dev/null
@@ -0,0 +1,3 @@
+fn foo(x:i32, self: i32) -> i32 { self } //~ ERROR unexpected `self` parameter in function
+
+fn main() {}
diff --git a/src/test/ui/parser/self-in-function-arg.stderr b/src/test/ui/parser/self-in-function-arg.stderr
new file mode 100644 (file)
index 0000000..f58df9b
--- /dev/null
@@ -0,0 +1,10 @@
+error: unexpected `self` parameter in function
+  --> $DIR/self-in-function-arg.rs:1:15
+   |
+LL | fn foo(x:i32, self: i32) -> i32 { self }
+   |               ^^^^ not valid as function parameter
+   |
+   = note: `self` is only valid as the first parameter of an associated function
+
+error: aborting due to previous error
+
index 260c2e04d74f78a9bf6dfa188df0c03a3bb19bc0..fabaea0535f5bdea8a7d263cc428d807fd476428 100644 (file)
@@ -1,4 +1,4 @@
-thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:1083:5
+thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:1085:5
 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
 
 error: internal compiler error: unexpected panic
index 6cfef115d08dc0fc0697211e4d56d45e3b92c253..a36c550f530a9a0f90113cb0f112b4db701a1532 100644 (file)
@@ -6,13 +6,13 @@ fn main() {
     match s {
         MAGIC_TEST => (),
         [0x00, 0x00, 0x00, 0x00] => (),
-        [4, 5, 6, 7] => (), //~ ERROR unreachable pattern
+        [4, 5, 6, 7] => (), // FIXME(oli-obk): this should warn, but currently does not
         _ => (),
     }
     match s {
         [0x00, 0x00, 0x00, 0x00] => (),
         MAGIC_TEST => (),
-        [4, 5, 6, 7] => (), //~ ERROR unreachable pattern
+        [4, 5, 6, 7] => (), // FIXME(oli-obk): this should warn, but currently does not
         _ => (),
     }
     match s {
index e2c408a90e4e1de68bbdf96254fb9f77c9515636..0c7401269dfc744c3f4ac02dee90ff2b4a4e4f0a 100644 (file)
@@ -1,8 +1,8 @@
 error: unreachable pattern
-  --> $DIR/slice-pattern-const-2.rs:9:9
+  --> $DIR/slice-pattern-const-2.rs:28:9
    |
-LL |         [4, 5, 6, 7] => (),
-   |         ^^^^^^^^^^^^
+LL |         FOO => (),
+   |         ^^^
    |
 note: lint level defined here
   --> $DIR/slice-pattern-const-2.rs:1:9
@@ -10,17 +10,5 @@ note: lint level defined here
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: unreachable pattern
-  --> $DIR/slice-pattern-const-2.rs:15:9
-   |
-LL |         [4, 5, 6, 7] => (),
-   |         ^^^^^^^^^^^^
-
-error: unreachable pattern
-  --> $DIR/slice-pattern-const-2.rs:28:9
-   |
-LL |         FOO => (),
-   |         ^^^
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
index c609cae90240ced7031f9e90a659c469a9411ad3..fab98f0ce5ebe68f1411d3681d994d2049785462 100644 (file)
@@ -9,7 +9,7 @@
 
 fn main() {
     let _ = #[no_output] "Hello, world!";
-    //~^ ERROR expected expression, found `<eof>`
+    //~^ ERROR expected expression, found end of macro arguments
 
     let _ = #[duplicate] "Hello, world!";
     //~^ ERROR macro expansion ignores token `,` and any following
index 5d2fb59ff1f66b0051d2f478463afd47a9b826da..49fe0bd0fcfe280cd9e1f9a81c6ed735ca4bdb7a 100644 (file)
@@ -1,4 +1,4 @@
-error: expected expression, found `<eof>`
+error: expected expression, found end of macro arguments
   --> $DIR/attr-invalid-exprs.rs:11:13
    |
 LL |     let _ = #[no_output] "Hello, world!";
index ac7d0b4c2b6c98efd97c76ed659c0a7e2ef2f39e..04c88dcef50ac5d2bdf4cf60559712fd946addb7 100644 (file)
@@ -6,20 +6,18 @@
 extern crate proc_macro;
 use proc_macro::*;
 
-#[proc_macro_derive]
-//~^ ERROR: attribute must be of the form
+#[proc_macro_derive] //~ ERROR malformed `proc_macro_derive` attribute
 pub fn foo1(input: TokenStream) -> TokenStream { input }
 
-#[proc_macro_derive = ""]
-//~^ ERROR: attribute must be of the form
+#[proc_macro_derive = ""] //~ ERROR malformed `proc_macro_derive` attribute
 pub fn foo2(input: TokenStream) -> TokenStream { input }
 
 #[proc_macro_derive(d3, a, b)]
-//~^ ERROR: attribute must have either one or two arguments
+//~^ ERROR attribute must have either one or two arguments
 pub fn foo3(input: TokenStream) -> TokenStream { input }
 
 #[proc_macro_derive(d4, attributes(a), b)]
-//~^ ERROR: attribute must have either one or two arguments
+//~^ ERROR attribute must have either one or two arguments
 pub fn foo4(input: TokenStream) -> TokenStream { input }
 
 #[proc_macro_derive("a")]
index cc17d383569fccb65da126312076c01e70aa13cf..e632875cb16e5bcb503876d7f95b8ff8a45fafe4 100644 (file)
 error: attribute must have either one or two arguments
-  --> $DIR/attribute.rs:17:1
+  --> $DIR/attribute.rs:15:1
    |
 LL | #[proc_macro_derive(d3, a, b)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: attribute must have either one or two arguments
-  --> $DIR/attribute.rs:21:1
+  --> $DIR/attribute.rs:19:1
    |
 LL | #[proc_macro_derive(d4, attributes(a), b)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: not a meta item
-  --> $DIR/attribute.rs:25:21
+  --> $DIR/attribute.rs:23:21
    |
 LL | #[proc_macro_derive("a")]
    |                     ^^^
 
 error: must only be one word
-  --> $DIR/attribute.rs:29:21
+  --> $DIR/attribute.rs:27:21
    |
 LL | #[proc_macro_derive(d6 = "")]
    |                     ^^^^^^^
 
 error: must only be one word
-  --> $DIR/attribute.rs:33:21
+  --> $DIR/attribute.rs:31:21
    |
 LL | #[proc_macro_derive(m::d7)]
    |                     ^^^^^
 
 error: must only be one word
-  --> $DIR/attribute.rs:37:21
+  --> $DIR/attribute.rs:35:21
    |
 LL | #[proc_macro_derive(d8(a))]
    |                     ^^^^^
 
 error: `self` cannot be a name of derive macro
-  --> $DIR/attribute.rs:41:21
+  --> $DIR/attribute.rs:39:21
    |
 LL | #[proc_macro_derive(self)]
    |                     ^^^^
 
 error: cannot override a built-in derive macro
-  --> $DIR/attribute.rs:45:21
+  --> $DIR/attribute.rs:43:21
    |
 LL | #[proc_macro_derive(PartialEq)]
    |                     ^^^^^^^^^
 
 error: second argument must be `attributes`
-  --> $DIR/attribute.rs:49:26
+  --> $DIR/attribute.rs:47:26
    |
 LL | #[proc_macro_derive(d11, a)]
    |                          ^
 
 error: attribute must be of form: `attributes(foo, bar)`
-  --> $DIR/attribute.rs:49:26
+  --> $DIR/attribute.rs:47:26
    |
 LL | #[proc_macro_derive(d11, a)]
    |                          ^
 
 error: attribute must be of form: `attributes(foo, bar)`
-  --> $DIR/attribute.rs:54:26
+  --> $DIR/attribute.rs:52:26
    |
 LL | #[proc_macro_derive(d12, attributes)]
    |                          ^^^^^^^^^^
 
 error: not a meta item
-  --> $DIR/attribute.rs:58:37
+  --> $DIR/attribute.rs:56:37
    |
 LL | #[proc_macro_derive(d13, attributes("a"))]
    |                                     ^^^
 
 error: must only be one word
-  --> $DIR/attribute.rs:62:37
+  --> $DIR/attribute.rs:60:37
    |
 LL | #[proc_macro_derive(d14, attributes(a = ""))]
    |                                     ^^^^^^
 
 error: must only be one word
-  --> $DIR/attribute.rs:66:37
+  --> $DIR/attribute.rs:64:37
    |
 LL | #[proc_macro_derive(d15, attributes(m::a))]
    |                                     ^^^^
 
 error: must only be one word
-  --> $DIR/attribute.rs:70:37
+  --> $DIR/attribute.rs:68:37
    |
 LL | #[proc_macro_derive(d16, attributes(a(b)))]
    |                                     ^^^^
 
 error: `self` cannot be a name of derive helper attribute
-  --> $DIR/attribute.rs:74:37
+  --> $DIR/attribute.rs:72:37
    |
 LL | #[proc_macro_derive(d17, attributes(self))]
    |                                     ^^^^
 
-error: attribute must be of the form `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
+error: malformed `proc_macro_derive` attribute input
   --> $DIR/attribute.rs:9:1
    |
 LL | #[proc_macro_derive]
-   | ^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
 
-error: attribute must be of the form `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
-  --> $DIR/attribute.rs:13:1
+error: malformed `proc_macro_derive` attribute input
+  --> $DIR/attribute.rs:12:1
    |
 LL | #[proc_macro_derive = ""]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
 
 error: aborting due to 18 previous errors
 
index c5ec4925e4310891f9794698a74b54ef6d7a80a7..6bbe022c690fe934c6415813a853f499716d00a3 100644 (file)
@@ -7,20 +7,20 @@
 
 use proc_macro::TokenStream;
 
-#[proc_macro = "test"] //~ ERROR attribute must be of the form
+#[proc_macro = "test"] //~ ERROR malformed `proc_macro` attribute
 pub fn a(a: TokenStream) -> TokenStream { a }
 
-#[proc_macro()] //~ ERROR attribute must be of the form
+#[proc_macro()] //~ ERROR malformed `proc_macro` attribute
 pub fn c(a: TokenStream) -> TokenStream { a }
 
-#[proc_macro(x)] //~ ERROR attribute must be of the form
+#[proc_macro(x)] //~ ERROR malformed `proc_macro` attribute
 pub fn d(a: TokenStream) -> TokenStream { a }
 
-#[proc_macro_attribute = "test"] //~ ERROR attribute must be of the form
+#[proc_macro_attribute = "test"] //~ ERROR malformed `proc_macro_attribute` attribute
 pub fn e(_: TokenStream, a: TokenStream) -> TokenStream { a }
 
-#[proc_macro_attribute()] //~ ERROR attribute must be of the form
+#[proc_macro_attribute()] //~ ERROR malformed `proc_macro_attribute` attribute
 pub fn g(_: TokenStream, a: TokenStream) -> TokenStream { a }
 
-#[proc_macro_attribute(x)] //~ ERROR attribute must be of the form
+#[proc_macro_attribute(x)] //~ ERROR malformed `proc_macro_attribute` attribute
 pub fn h(_: TokenStream, a: TokenStream) -> TokenStream { a }
index 8dff60d0dc556e7a2f3e2c290a8c6da419a988ed..fe411fa5e1f8e27dd2825747c96fe6fdce35953c 100644 (file)
@@ -1,38 +1,38 @@
-error: attribute must be of the form `#[proc_macro]`
+error: malformed `proc_macro` attribute input
   --> $DIR/invalid-attributes.rs:10:1
    |
 LL | #[proc_macro = "test"]
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]`
 
-error: attribute must be of the form `#[proc_macro]`
+error: malformed `proc_macro` attribute input
   --> $DIR/invalid-attributes.rs:13:1
    |
 LL | #[proc_macro()]
-   | ^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]`
 
-error: attribute must be of the form `#[proc_macro]`
+error: malformed `proc_macro` attribute input
   --> $DIR/invalid-attributes.rs:16:1
    |
 LL | #[proc_macro(x)]
-   | ^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]`
 
-error: attribute must be of the form `#[proc_macro_attribute]`
+error: malformed `proc_macro_attribute` attribute input
   --> $DIR/invalid-attributes.rs:19:1
    |
 LL | #[proc_macro_attribute = "test"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]`
 
-error: attribute must be of the form `#[proc_macro_attribute]`
+error: malformed `proc_macro_attribute` attribute input
   --> $DIR/invalid-attributes.rs:22:1
    |
 LL | #[proc_macro_attribute()]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]`
 
-error: attribute must be of the form `#[proc_macro_attribute]`
+error: malformed `proc_macro_attribute` attribute input
   --> $DIR/invalid-attributes.rs:25:1
    |
 LL | #[proc_macro_attribute(x)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]`
 
 error: aborting due to 6 previous errors
 
index 2a1bdf57a88cbe3c68b307abb05ce7430a399662..f62a540572c934661246e79c7050cc3885c76afe 100644 (file)
@@ -6,3 +6,4 @@ LL |     l.iter().map(f).collect()?
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0284`.
index 9d844745f4299e336d9a84b02e7019f7d03ce737..564d6732601024661009d2de0e6eea59ddebef02 100644 (file)
@@ -1,13 +1,10 @@
-#[repr]
-//~^ ERROR attribute must be of the form
+#[repr] //~ ERROR malformed `repr` attribute
 struct _A {}
 
-#[repr = "B"]
-//~^ ERROR attribute must be of the form
+#[repr = "B"] //~ ERROR malformed `repr` attribute
 struct _B {}
 
-#[repr = "C"]
-//~^ ERROR attribute must be of the form
+#[repr = "C"] //~ ERROR malformed `repr` attribute
 struct _C {}
 
 #[repr(C)]
index 7ebfe083ddd01b77f4c2536c27e5d8631a1bc085..e756510a437c844ab8ed6925683e4a6a8d5730e3 100644 (file)
@@ -1,20 +1,20 @@
-error: attribute must be of the form `#[repr(C, packed, ...)]`
+error: malformed `repr` attribute input
   --> $DIR/repr.rs:1:1
    |
 LL | #[repr]
-   | ^^^^^^^
+   | ^^^^^^^ help: must be of the form: `#[repr(C, packed, ...)]`
 
-error: attribute must be of the form `#[repr(C, packed, ...)]`
-  --> $DIR/repr.rs:5:1
+error: malformed `repr` attribute input
+  --> $DIR/repr.rs:4:1
    |
 LL | #[repr = "B"]
-   | ^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^ help: must be of the form: `#[repr(C, packed, ...)]`
 
-error: attribute must be of the form `#[repr(C, packed, ...)]`
-  --> $DIR/repr.rs:9:1
+error: malformed `repr` attribute input
+  --> $DIR/repr.rs:7:1
    |
 LL | #[repr = "C"]
-   | ^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^ help: must be of the form: `#[repr(C, packed, ...)]`
 
 error: aborting due to 3 previous errors
 
index 3375210fc59ebd105cfe7adda4e3a79ab09a646f..b7938e1afa3bc165db21d7f34dee8a8d940d6c03 100644 (file)
@@ -1,7 +1,7 @@
 #![feature(non_exhaustive)]
 
 #[non_exhaustive(anything)]
-//~^ ERROR attribute must be of the form
+//~^ ERROR malformed `non_exhaustive` attribute
 struct Foo;
 
 #[non_exhaustive]
index ff082e6fc429ed78584d6d48a49b700665bcf3e4..21dc340d21204b42663689a90f4d039763b1c90f 100644 (file)
@@ -1,8 +1,8 @@
-error: attribute must be of the form `#[non_exhaustive]`
+error: malformed `non_exhaustive` attribute input
   --> $DIR/invalid-attribute.rs:3:1
    |
 LL | #[non_exhaustive(anything)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[non_exhaustive]`
 
 error[E0701]: attribute can only be applied to a struct or enum
   --> $DIR/invalid-attribute.rs:7:1
diff --git a/src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.rs b/src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.rs
new file mode 100644 (file)
index 0000000..84fbb47
--- /dev/null
@@ -0,0 +1,14 @@
+// rust-lang/rust#60654: Do not ICE on an attempt to use GATs that is
+// missing the feature gate.
+
+struct Foo;
+
+impl Iterator for Foo {
+    type Item<'b> = &'b Foo; //~ ERROR generic associated types are unstable [E0658]
+
+    fn next(&mut self) -> Option<Self::Item> {
+        None
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.stderr b/src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.stderr
new file mode 100644 (file)
index 0000000..27b1d73
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0658]: generic associated types are unstable
+  --> $DIR/gat-dont-ice-on-absent-feature.rs:7:5
+   |
+LL |     type Item<'b> = &'b Foo;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/44265
+   = help: add #![feature(generic_associated_types)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
index 3fd54bc02e41748bc2629a7bbe0c12c21eb5bfdb..c64899c1e9240db697ce0a715d3dbd6c23c43f3a 100644 (file)
@@ -5,24 +5,24 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 mod bogus_attribute_types_2 {
-    #[unstable] //~ ERROR attribute must be of the form
+    #[unstable] //~ ERROR malformed `unstable` attribute
     fn f1() { }
 
-    #[unstable = "b"] //~ ERROR attribute must be of the form
+    #[unstable = "b"] //~ ERROR malformed `unstable` attribute
     fn f2() { }
 
-    #[stable] //~ ERROR attribute must be of the form
+    #[stable] //~ ERROR malformed `stable` attribute
     fn f3() { }
 
-    #[stable = "a"] //~ ERROR attribute must be of the form
+    #[stable = "a"] //~ ERROR malformed `stable` attribute
     fn f4() { }
 
     #[stable(feature = "a", since = "b")]
-    #[rustc_deprecated] //~ ERROR attribute must be of the form
+    #[rustc_deprecated] //~ ERROR malformed `rustc_deprecated` attribute
     fn f5() { }
 
     #[stable(feature = "a", since = "b")]
-    #[rustc_deprecated = "a"] //~ ERROR attribute must be of the form
+    #[rustc_deprecated = "a"] //~ ERROR malformed `rustc_deprecated` attribute
     fn f6() { }
 }
 
index d85b628c3c34997a729dc06c3c8c4968768b2c27..9d23b344ed15e07e83b27c81fdf668211321a8f1 100644 (file)
@@ -1,38 +1,38 @@
-error: attribute must be of the form `#[unstable(feature = "name", reason = "...", issue = "N")]`
+error: malformed `unstable` attribute input
   --> $DIR/stability-attribute-sanity-4.rs:8:5
    |
 LL |     #[unstable]
-   |     ^^^^^^^^^^^
+   |     ^^^^^^^^^^^ help: must be of the form: `#[unstable(feature = "name", reason = "...", issue = "N")]`
 
-error: attribute must be of the form `#[unstable(feature = "name", reason = "...", issue = "N")]`
+error: malformed `unstable` attribute input
   --> $DIR/stability-attribute-sanity-4.rs:11:5
    |
 LL |     #[unstable = "b"]
-   |     ^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[unstable(feature = "name", reason = "...", issue = "N")]`
 
-error: attribute must be of the form `#[stable(feature = "name", since = "version")]`
+error: malformed `stable` attribute input
   --> $DIR/stability-attribute-sanity-4.rs:14:5
    |
 LL |     #[stable]
-   |     ^^^^^^^^^
+   |     ^^^^^^^^^ help: must be of the form: `#[stable(feature = "name", since = "version")]`
 
-error: attribute must be of the form `#[stable(feature = "name", since = "version")]`
+error: malformed `stable` attribute input
   --> $DIR/stability-attribute-sanity-4.rs:17:5
    |
 LL |     #[stable = "a"]
-   |     ^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^ help: must be of the form: `#[stable(feature = "name", since = "version")]`
 
-error: attribute must be of the form `#[rustc_deprecated(since = "version", reason = "...")]`
+error: malformed `rustc_deprecated` attribute input
   --> $DIR/stability-attribute-sanity-4.rs:21:5
    |
 LL |     #[rustc_deprecated]
-   |     ^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_deprecated(since = "version", reason = "...")]`
 
-error: attribute must be of the form `#[rustc_deprecated(since = "version", reason = "...")]`
+error: malformed `rustc_deprecated` attribute input
   --> $DIR/stability-attribute-sanity-4.rs:25:5
    |
 LL |     #[rustc_deprecated = "a"]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_deprecated(since = "version", reason = "...")]`
 
 error: aborting due to 6 previous errors
 
index 10287f59ccec94e4114a1ed89bc88c9a2ee578bc..36bced9e4332bdda069e3aa8e09b51b069d47158 100644 (file)
@@ -13,11 +13,10 @@ LL |     let a = vec![1, 2, 3];
    |         - move occurs because `a` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
 LL |     for i in &a {
 LL |         for j in a {
-   |                  ^ value moved here, in previous iteration of loop
-help: consider borrowing this to avoid moving it into the for loop
-   |
-LL |         for j in &a {
-   |                  ^^
+   |                  ^
+   |                  |
+   |                  value moved here, in previous iteration of loop
+   |                  help: consider borrowing to avoid moving into the for loop: `&a`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/suggestions/option-content-move.fixed b/src/test/ui/suggestions/option-content-move.fixed
new file mode 100644 (file)
index 0000000..f163cd1
--- /dev/null
@@ -0,0 +1,39 @@
+//run-rustfix
+
+pub struct LipogramCorpora {
+    selections: Vec<(char, Option<String>)>,
+}
+
+impl LipogramCorpora {
+    pub fn validate_all(&mut self) -> Result<(), char> {
+        for selection in &self.selections {
+            if selection.1.is_some() {
+                if selection.1.as_ref().unwrap().contains(selection.0) {
+                //~^ ERROR cannot move out of borrowed content
+                    return Err(selection.0);
+                }
+            }
+        }
+        Ok(())
+    }
+}
+
+pub struct LipogramCorpora2 {
+    selections: Vec<(char, Result<String, String>)>,
+}
+
+impl LipogramCorpora2 {
+    pub fn validate_all(&mut self) -> Result<(), char> {
+        for selection in &self.selections {
+            if selection.1.is_ok() {
+                if selection.1.as_ref().unwrap().contains(selection.0) {
+                //~^ ERROR cannot move out of borrowed content
+                    return Err(selection.0);
+                }
+            }
+        }
+        Ok(())
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/option-content-move.rs b/src/test/ui/suggestions/option-content-move.rs
new file mode 100644 (file)
index 0000000..350486a
--- /dev/null
@@ -0,0 +1,39 @@
+//run-rustfix
+
+pub struct LipogramCorpora {
+    selections: Vec<(char, Option<String>)>,
+}
+
+impl LipogramCorpora {
+    pub fn validate_all(&mut self) -> Result<(), char> {
+        for selection in &self.selections {
+            if selection.1.is_some() {
+                if selection.1.unwrap().contains(selection.0) {
+                //~^ ERROR cannot move out of borrowed content
+                    return Err(selection.0);
+                }
+            }
+        }
+        Ok(())
+    }
+}
+
+pub struct LipogramCorpora2 {
+    selections: Vec<(char, Result<String, String>)>,
+}
+
+impl LipogramCorpora2 {
+    pub fn validate_all(&mut self) -> Result<(), char> {
+        for selection in &self.selections {
+            if selection.1.is_ok() {
+                if selection.1.unwrap().contains(selection.0) {
+                //~^ ERROR cannot move out of borrowed content
+                    return Err(selection.0);
+                }
+            }
+        }
+        Ok(())
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/option-content-move.stderr b/src/test/ui/suggestions/option-content-move.stderr
new file mode 100644 (file)
index 0000000..0a325ac
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/option-content-move.rs:11:20
+   |
+LL |                 if selection.1.unwrap().contains(selection.0) {
+   |                    ^^^^^^^^^^^
+   |                    |
+   |                    cannot move out of borrowed content
+   |                    help: consider borrowing the `Option`'s content: `selection.1.as_ref()`
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/option-content-move.rs:29:20
+   |
+LL |                 if selection.1.unwrap().contains(selection.0) {
+   |                    ^^^^^^^^^^^
+   |                    |
+   |                    cannot move out of borrowed content
+   |                    help: consider borrowing the `Result`'s content: `selection.1.as_ref()`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0507`.
diff --git a/src/test/ui/symbol-names/impl2.rs b/src/test/ui/symbol-names/impl2.rs
new file mode 100644 (file)
index 0000000..d48b182
--- /dev/null
@@ -0,0 +1,14 @@
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+trait Foo {
+    fn baz();
+}
+
+impl Foo for [u8; 1 + 2] {
+    #[rustc_def_path] //~ ERROR def-path(<[u8; _] as Foo>::baz)
+    fn baz() { }
+}
+
+fn main() {
+}
diff --git a/src/test/ui/symbol-names/impl2.stderr b/src/test/ui/symbol-names/impl2.stderr
new file mode 100644 (file)
index 0000000..de26fed
--- /dev/null
@@ -0,0 +1,8 @@
+error: def-path(<[u8; _] as Foo>::baz)
+  --> $DIR/impl2.rs:9:5
+   |
+LL |     #[rustc_def_path]
+   |     ^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
index ddae8870905adfca7f9bc5120a68f8fab915d2f4..ac02c9cc648c2a3db88c4938c56aae94b6ef449a 100644 (file)
 #![feature(target_feature)]
 
 #[target_feature = "+sse2"]
-//~^ ERROR: must be of the form
+//~^ ERROR malformed `target_feature` attribute
 #[target_feature(enable = "foo")]
-//~^ ERROR: not valid for this target
+//~^ ERROR not valid for this target
+//~| NOTE `foo` is not valid for this target
 #[target_feature(bar)]
-//~^ ERROR: only accepts sub-keys
+//~^ ERROR malformed `target_feature` attribute
 #[target_feature(disable = "baz")]
-//~^ ERROR: only accepts sub-keys
+//~^ ERROR malformed `target_feature` attribute
 unsafe fn foo() {}
 
 #[target_feature(enable = "sse2")]
-//~^ ERROR: can only be applied to `unsafe` function
+//~^ ERROR #[target_feature(..)] can only be applied to `unsafe` functions
+//~| NOTE can only be applied to `unsafe` functions
 fn bar() {}
+//~^ NOTE not an `unsafe` function
 
 #[target_feature(enable = "sse2")]
-//~^ ERROR: should be applied to a function
+//~^ ERROR attribute should be applied to a function
 mod another {}
+//~^ NOTE not a function
 
 #[inline(always)]
 //~^ ERROR: cannot use #[inline(always)]
index 3662ea976a46d74a1ddf7ee054c92ba853f0fa5d..ff9678efdddc27de0a8ab045b3021ed28e08fa70 100644 (file)
@@ -1,35 +1,38 @@
-error: attribute must be of the form `#[target_feature(enable = "name")]`
+error: malformed `target_feature` attribute input
   --> $DIR/target-feature-wrong.rs:16:1
    |
 LL | #[target_feature = "+sse2"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]`
 
 error: the feature named `foo` is not valid for this target
   --> $DIR/target-feature-wrong.rs:18:18
    |
 LL | #[target_feature(enable = "foo")]
-   |                  ^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^ `foo` is not valid for this target
 
-error: #[target_feature(..)] only accepts sub-keys of `enable` currently
-  --> $DIR/target-feature-wrong.rs:20:18
+error: malformed `target_feature` attribute input
+  --> $DIR/target-feature-wrong.rs:21:18
    |
 LL | #[target_feature(bar)]
-   |                  ^^^
+   |                  ^^^ help: must be of the form: `enable = ".."`
 
-error: #[target_feature(..)] only accepts sub-keys of `enable` currently
-  --> $DIR/target-feature-wrong.rs:22:18
+error: malformed `target_feature` attribute input
+  --> $DIR/target-feature-wrong.rs:23:18
    |
 LL | #[target_feature(disable = "baz")]
-   |                  ^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."`
 
-error: #[target_feature(..)] can only be applied to `unsafe` function
-  --> $DIR/target-feature-wrong.rs:26:1
+error: #[target_feature(..)] can only be applied to `unsafe` functions
+  --> $DIR/target-feature-wrong.rs:27:1
    |
 LL | #[target_feature(enable = "sse2")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can only be applied to `unsafe` functions
+...
+LL | fn bar() {}
+   | ----------- not an `unsafe` function
 
 error: attribute should be applied to a function
-  --> $DIR/target-feature-wrong.rs:30:1
+  --> $DIR/target-feature-wrong.rs:33:1
    |
 LL | #[target_feature(enable = "sse2")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -38,7 +41,7 @@ LL | mod another {}
    | -------------- not a function
 
 error: cannot use #[inline(always)] with #[target_feature]
-  --> $DIR/target-feature-wrong.rs:34:1
+  --> $DIR/target-feature-wrong.rs:38:1
    |
 LL | #[inline(always)]
    | ^^^^^^^^^^^^^^^^^
index c4fcfb725b4be00c72eb9cf30c7d8b095577c280..545f354259be4e9745ea00a524c0e4c51df01aa6 160000 (submodule)
@@ -1 +1 @@
-Subproject commit c4fcfb725b4be00c72eb9cf30c7d8b095577c280
+Subproject commit 545f354259be4e9745ea00a524c0e4c51df01aa6
index a8eeb7cdb135da1cd582c6093c1739732727a4a2..46e64911ad43c519c61d22afef7f82625dd9c4a8 160000 (submodule)
@@ -1 +1 @@
-Subproject commit a8eeb7cdb135da1cd582c6093c1739732727a4a2
+Subproject commit 46e64911ad43c519c61d22afef7f82625dd9c4a8
index 290c4481c005e552871a44230bd4a898b66effc7..18d682640db011ce963cb5136632e287a297d215 100644 (file)
@@ -38,6 +38,7 @@ features = [
   "objbase",
   "profileapi",
   "processenv",
+  "processthreadsapi",
   "psapi",
   "schannel",
   "securitybaseapi",
index 8626ba060bf713f66ddc37332d9774db9681340b..ad3ac986c94f6c8f6561ff646e5bde5b1fe9178e 100644 (file)
@@ -47,6 +47,9 @@
     "adler32",            // BSD-3-Clause AND Zlib, cargo dep that isn't used
     "fortanix-sgx-abi",   // MPL-2.0+, libstd but only for `sgx` target
     "constant_time_eq",   // CC0-1.0, rustfmt
+    "utf8parse",          // Apache-2.0 OR MIT, cargo via strip-ansi-escapes
+    "vte",                // Apache-2.0 OR MIT, cargo via strip-ansi-escapes
+    "sized-chunks",       // MPL-2.0+, cargo via im-rc
 ];
 
 /// Which crates to check against the whitelist?
@@ -61,6 +64,7 @@
     Crate("aho-corasick"),
     Crate("arrayvec"),
     Crate("atty"),
+    Crate("autocfg"),
     Crate("backtrace"),
     Crate("backtrace-sys"),
     Crate("bitflags"),
@@ -241,7 +245,7 @@ pub fn check(path: &Path, bad: &mut bool) {
         }
 
         let toml = dir.path().join("Cargo.toml");
-        *bad = *bad || !check_license(&toml);
+        *bad = !check_license(&toml) || *bad;
     }
     assert!(saw_dir, "no vendored source");
 }
index b725fbe3d7425736a4ad73f6b70a5e1e0d2dcee6..837be69f7caddff7834166ed1eaf7bfee410f659 100644 (file)
@@ -61,6 +61,7 @@
     "src/libstd/net/test.rs",
     "src/libstd/sys_common/mod.rs",
     "src/libstd/sys_common/net.rs",
+    "src/libstd/sys_common/backtrace.rs",
     "src/libterm", // Not sure how to make this crate portable, but test crate needs it.
     "src/libtest", // Probably should defer to unstable `std::sys` APIs.
     "src/libstd/sync/mpsc", // some tests are only run on non-emscripten