]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #62257 - RalfJung:miri-c-str, r=estebank
authorMazdak Farrokhzad <twingoow@gmail.com>
Sat, 6 Jul 2019 00:37:56 +0000 (02:37 +0200)
committerGitHub <noreply@github.com>
Sat, 6 Jul 2019 00:37:56 +0000 (02:37 +0200)
forward read_c_str method from Memory to Alloc

This is more convenient to call when one starts with a `Scalar` (which is the common case).

`read_c_str` is only used in Miri.

1296 files changed:
.azure-pipelines/auto.yml
.azure-pipelines/steps/run.yml
.mailmap
.travis.yml
Cargo.lock
README.md
RELEASES.md
appveyor.yml
src/bootstrap/bin/rustc.rs
src/bootstrap/channel.rs
src/bootstrap/config.rs
src/bootstrap/flags.rs
src/doc/rustc-guide
src/doc/rustc/src/SUMMARY.md
src/doc/rustc/src/codegen-options/index.md
src/doc/rustc/src/profile-guided-optimization.md [new file with mode: 0644]
src/doc/rustdoc/src/documentation-tests.md
src/doc/unstable-book/src/language-features/member-constraints.md [new file with mode: 0644]
src/doc/unstable-book/src/language-features/slice-patterns.md
src/doc/unstable-book/src/language-features/type-alias-enum-variants.md [deleted file]
src/etc/cpu-usage-over-time-plot.sh
src/etc/gdb_load_rust_pretty_printers.py
src/liballoc/alloc.rs
src/liballoc/boxed.rs
src/liballoc/collections/binary_heap.rs
src/liballoc/collections/btree/map.rs
src/liballoc/collections/btree/node.rs
src/liballoc/collections/btree/set.rs
src/liballoc/collections/linked_list.rs
src/liballoc/collections/vec_deque.rs
src/liballoc/lib.rs
src/liballoc/str.rs
src/liballoc/string.rs
src/liballoc/tests/vec.rs
src/liballoc/vec.rs
src/libarena/lib.rs
src/libcore/ascii.rs
src/libcore/char/methods.rs
src/libcore/convert.rs
src/libcore/ffi.rs
src/libcore/future/future.rs
src/libcore/intrinsics.rs
src/libcore/lib.rs
src/libcore/marker.rs
src/libcore/mem/maybe_uninit.rs
src/libcore/mem/mod.rs
src/libcore/num/mod.rs
src/libcore/ops/index.rs
src/libcore/option.rs
src/libcore/ptr/mod.rs
src/libcore/ptr/non_null.rs
src/libcore/slice/mod.rs
src/libcore/str/mod.rs
src/libcore/tests/ascii.rs
src/libcore/tests/fmt/mod.rs
src/libcore/tests/pattern.rs
src/libcore/tests/ptr.rs
src/libcore/tests/slice.rs
src/libfmt_macros/lib.rs
src/libproc_macro/bridge/buffer.rs
src/libproc_macro/bridge/scoped_cell.rs
src/libproc_macro/lib.rs
src/librustc/cfg/construct.rs
src/librustc/cfg/mod.rs
src/librustc/dep_graph/dep_tracking_map.rs
src/librustc/dep_graph/graph.rs
src/librustc/hir/check_attr.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/definitions.rs
src/librustc/hir/map/hir_id_validator.rs
src/librustc/hir/map/mod.rs
src/librustc/hir/mod.rs
src/librustc/hir/print.rs
src/librustc/hir/ptr.rs [new file with mode: 0644]
src/librustc/hir/upvars.rs
src/librustc/infer/canonical/mod.rs
src/librustc/infer/canonical/query_response.rs
src/librustc/infer/error_reporting/mod.rs
src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
src/librustc/infer/lexical_region_resolve/mod.rs
src/librustc/infer/mod.rs
src/librustc/infer/nll_relate/mod.rs
src/librustc/infer/opaque_types/mod.rs
src/librustc/infer/outlives/free_region_map.rs
src/librustc/infer/outlives/obligations.rs
src/librustc/infer/region_constraints/mod.rs
src/librustc/infer/type_variable.rs
src/librustc/lib.rs
src/librustc/lint/context.rs
src/librustc/lint/internal.rs
src/librustc/lint/mod.rs
src/librustc/middle/cstore.rs
src/librustc/middle/dead.rs
src/librustc/middle/dependency_format.rs
src/librustc/middle/entry.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/intrinsicck.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/lib_features.rs
src/librustc/middle/liveness.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/error.rs
src/librustc/mir/interpret/value.rs
src/librustc/mir/mod.rs
src/librustc/mir/mono.rs
src/librustc/query/mod.rs
src/librustc/session/config.rs
src/librustc/session/config/tests.rs
src/librustc/session/mod.rs
src/librustc/traits/coherence.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/fulfill.rs
src/librustc/traits/mod.rs
src/librustc/traits/object_safety.rs
src/librustc/traits/project.rs
src/librustc/traits/query/normalize.rs
src/librustc/traits/query/type_op/custom.rs
src/librustc/traits/query/type_op/mod.rs
src/librustc/traits/select.rs
src/librustc/traits/specialize/mod.rs
src/librustc/traits/util.rs
src/librustc/ty/codec.rs
src/librustc/ty/context.rs
src/librustc/ty/erase_regions.rs
src/librustc/ty/flags.rs
src/librustc/ty/fold.rs
src/librustc/ty/inhabitedness/def_id_forest.rs
src/librustc/ty/mod.rs
src/librustc/ty/query/on_disk_cache.rs
src/librustc/ty/query/plumbing.rs
src/librustc/ty/relate.rs
src/librustc/ty/structural_impls.rs
src/librustc/ty/sty.rs
src/librustc/ty/trait_def.rs
src/librustc/util/common.rs
src/librustc_allocator/lib.rs
src/librustc_borrowck/borrowck/check_loans.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_borrowck/dataflow.rs
src/librustc_borrowck/lib.rs
src/librustc_codegen_llvm/attributes.rs
src/librustc_codegen_llvm/back/archive.rs
src/librustc_codegen_llvm/back/write.rs
src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/builder.rs
src/librustc_codegen_llvm/common.rs
src/librustc_codegen_llvm/intrinsic.rs
src/librustc_codegen_llvm/lib.rs
src/librustc_codegen_ssa/back/command.rs
src/librustc_codegen_ssa/back/link.rs
src/librustc_codegen_ssa/back/symbol_export.rs
src/librustc_codegen_ssa/back/write.rs
src/librustc_codegen_ssa/base.rs
src/librustc_codegen_ssa/debuginfo/mod.rs
src/librustc_codegen_ssa/lib.rs
src/librustc_codegen_ssa/mir/analyze.rs
src/librustc_codegen_ssa/traits/backend.rs
src/librustc_codegen_ssa/traits/builder.rs
src/librustc_codegen_utils/lib.rs
src/librustc_codegen_utils/symbol_names_test.rs
src/librustc_data_structures/binary_search_util/mod.rs [new file with mode: 0644]
src/librustc_data_structures/binary_search_util/test.rs [new file with mode: 0644]
src/librustc_data_structures/bit_set.rs
src/librustc_data_structures/fingerprint.rs
src/librustc_data_structures/graph/implementation/mod.rs
src/librustc_data_structures/graph/iterate/mod.rs
src/librustc_data_structures/graph/mod.rs
src/librustc_data_structures/graph/reference.rs
src/librustc_data_structures/graph/scc/mod.rs
src/librustc_data_structures/graph/test.rs
src/librustc_data_structures/graph/vec_graph/mod.rs [new file with mode: 0644]
src/librustc_data_structures/graph/vec_graph/test.rs [new file with mode: 0644]
src/librustc_data_structures/indexed_vec.rs
src/librustc_data_structures/lib.rs
src/librustc_data_structures/macros.rs
src/librustc_data_structures/transitive_relation.rs
src/librustc_driver/lib.rs
src/librustc_driver/pretty.rs
src/librustc_errors/emitter.rs
src/librustc_errors/lib.rs
src/librustc_incremental/assert_dep_graph.rs
src/librustc_incremental/assert_module_sources.rs
src/librustc_incremental/lib.rs
src/librustc_incremental/persist/dirty_clean.rs
src/librustc_incremental/persist/load.rs
src/librustc_incremental/persist/save.rs
src/librustc_interface/lib.rs
src/librustc_interface/passes.rs
src/librustc_interface/proc_macro_decls.rs
src/librustc_interface/util.rs
src/librustc_lint/builtin.rs
src/librustc_lint/lib.rs
src/librustc_lint/nonstandard_style.rs
src/librustc_lint/types.rs
src/librustc_lint/unused.rs
src/librustc_macros/src/lib.rs
src/librustc_macros/src/query.rs
src/librustc_metadata/creader.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/foreign_modules.rs
src/librustc_metadata/lib.rs
src/librustc_metadata/link_args.rs
src/librustc_metadata/native_libs.rs
src/librustc_mir/borrow_check/mod.rs
src/librustc_mir/borrow_check/nll/constraints/graph.rs
src/librustc_mir/borrow_check/nll/constraints/mod.rs
src/librustc_mir/borrow_check/nll/member_constraints.rs [new file with mode: 0644]
src/librustc_mir/borrow_check/nll/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/values.rs
src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs
src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs
src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/borrow_check/nll/universal_regions.rs
src/librustc_mir/borrow_check/path_utils.rs
src/librustc_mir/build/expr/category.rs
src/librustc_mir/build/matches/mod.rs
src/librustc_mir/build/matches/simplify.rs
src/librustc_mir/build/matches/test.rs
src/librustc_mir/build/mod.rs
src/librustc_mir/build/scope.rs
src/librustc_mir/const_eval.rs
src/librustc_mir/dataflow/at_location.rs
src/librustc_mir/dataflow/impls/borrowed_locals.rs
src/librustc_mir/dataflow/impls/storage_liveness.rs
src/librustc_mir/dataflow/mod.rs
src/librustc_mir/error_codes.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/cx/mod.rs
src/librustc_mir/hair/cx/to_ref.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/cast.rs
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/intrinsics.rs
src/librustc_mir/interpret/machine.rs
src/librustc_mir/interpret/memory.rs
src/librustc_mir/interpret/mod.rs
src/librustc_mir/interpret/operand.rs
src/librustc_mir/interpret/operator.rs
src/librustc_mir/interpret/place.rs
src/librustc_mir/interpret/step.rs
src/librustc_mir/interpret/terminator.rs
src/librustc_mir/interpret/traits.rs
src/librustc_mir/interpret/validity.rs
src/librustc_mir/interpret/visitor.rs
src/librustc_mir/lib.rs
src/librustc_mir/monomorphize/collector.rs
src/librustc_mir/monomorphize/item.rs
src/librustc_mir/monomorphize/partitioning.rs
src/librustc_mir/shim.rs
src/librustc_mir/transform/add_retag.rs
src/librustc_mir/transform/check_unsafety.rs
src/librustc_mir/transform/const_prop.rs
src/librustc_mir/transform/dump_mir.rs
src/librustc_mir/transform/generator.rs
src/librustc_mir/transform/mod.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/simplify.rs
src/librustc_mir/transform/simplify_branches.rs
src/librustc_mir/util/def_use.rs
src/librustc_mir/util/graphviz.rs
src/librustc_mir/util/liveness.rs
src/librustc_mir/util/mod.rs
src/librustc_passes/ast_validation.rs
src/librustc_passes/hir_stats.rs
src/librustc_passes/layout_test.rs
src/librustc_passes/lib.rs
src/librustc_passes/loops.rs
src/librustc_passes/rvalue_promotion.rs
src/librustc_plugin/build.rs
src/librustc_plugin/registry.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/librustc_resolve/resolve_imports.rs
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/lib.rs
src/librustc_target/abi/call/x86_64.rs
src/librustc_target/lib.rs
src/librustc_target/spec/windows_msvc_base.rs
src/librustc_traits/chalk_context/mod.rs
src/librustc_traits/chalk_context/program_clauses/primitive.rs
src/librustc_traits/dropck_outlives.rs
src/librustc_traits/lib.rs
src/librustc_traits/lowering/environment.rs
src/librustc_traits/lowering/mod.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/expr.rs
src/librustc_typeck/check/generator_interior.rs
src/librustc_typeck/check/intrinsic.rs
src/librustc_typeck/check/method/mod.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/upvar.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/check_unused.rs
src/librustc_typeck/coherence/builtin.rs
src/librustc_typeck/coherence/inherent_impls.rs
src/librustc_typeck/coherence/inherent_impls_overlap.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/orphan.rs
src/librustc_typeck/coherence/unsafety.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/impl_wf_check.rs
src/librustc_typeck/lib.rs
src/librustc_typeck/outlives/implicit_infer.rs
src/librustc_typeck/outlives/mod.rs
src/librustc_typeck/outlives/test.rs
src/librustc_typeck/outlives/utils.rs
src/librustc_typeck/variance/constraints.rs
src/librustc_typeck/variance/mod.rs
src/librustc_typeck/variance/solve.rs
src/librustc_typeck/variance/terms.rs
src/librustc_typeck/variance/test.rs
src/librustdoc/clean/cfg.rs
src/librustdoc/clean/mod.rs
src/librustdoc/clean/simplify.rs
src/librustdoc/core.rs
src/librustdoc/doctree.rs
src/librustdoc/html/format.rs
src/librustdoc/html/item_type.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/rustdoc.css
src/librustdoc/html/toc.rs
src/librustdoc/lib.rs
src/librustdoc/markdown.rs
src/librustdoc/passes/collapse_docs.rs
src/librustdoc/passes/collect_trait_impls.rs
src/librustdoc/test.rs
src/librustdoc/visit_ast.rs
src/libserialize/json.rs
src/libstd/collections/hash/map.rs
src/libstd/io/mod.rs
src/libstd/io/util.rs
src/libstd/lib.rs
src/libstd/panic.rs
src/libstd/panicking.rs
src/libstd/process.rs
src/libstd/sync/mpsc/sync.rs
src/libstd/sys/cloudabi/mod.rs
src/libstd/sys/redox/ext/net.rs
src/libstd/sys/sgx/mod.rs
src/libstd/sys/unix/ext/net.rs
src/libstd/sys/windows/mod.rs
src/libstd/sys/windows/path.rs
src/libstd/sys/windows/pipe.rs
src/libstd/sys_common/io.rs
src/libsyntax/attr/mod.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/transcribe.rs
src/libsyntax/feature_gate.rs
src/libsyntax/lib.rs
src/libsyntax/mut_visit.rs
src/libsyntax/parse/diagnostics.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/lexer/unicode_chars.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pp.rs
src/libsyntax/print/pprust.rs
src/libsyntax/ptr.rs
src/libsyntax/test.rs
src/libsyntax/tokenstream.rs
src/libsyntax/util/parser_testing.rs
src/libsyntax_ext/assert.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_ext/deriving/generic/ty.rs
src/libsyntax_ext/lib.rs
src/libsyntax_pos/lib.rs
src/libsyntax_pos/symbol.rs
src/libterm/win.rs
src/libunwind/libunwind.rs
src/stage0.txt
src/test/auxiliary/rust_test_helpers.c
src/test/codegen/pgo-instrumentation.rs
src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs
src/test/incremental/change_add_field/struct_point.rs
src/test/incremental/change_crate_dep_kind.rs
src/test/incremental/change_private_fn/struct_point.rs
src/test/incremental/change_private_fn_cc/struct_point.rs
src/test/incremental/change_private_impl_method/struct_point.rs
src/test/incremental/change_private_impl_method_cc/struct_point.rs
src/test/incremental/change_pub_inherent_method_body/struct_point.rs
src/test/incremental/change_pub_inherent_method_sig/struct_point.rs
src/test/incremental/hashes/call_expressions.rs
src/test/incremental/hashes/closure_expressions.rs
src/test/incremental/hashes/consts.rs
src/test/incremental/hashes/enum_constructors.rs
src/test/incremental/hashes/enum_defs.rs
src/test/incremental/hashes/exported_vs_not.rs
src/test/incremental/hashes/extern_mods.rs
src/test/incremental/hashes/for_loops.rs
src/test/incremental/hashes/function_interfaces.rs
src/test/incremental/hashes/if_expressions.rs
src/test/incremental/hashes/indexing_expressions.rs
src/test/incremental/hashes/inherent_impls.rs
src/test/incremental/hashes/inline_asm.rs
src/test/incremental/hashes/let_expressions.rs
src/test/incremental/hashes/loop_expressions.rs
src/test/incremental/hashes/match_expressions.rs
src/test/incremental/hashes/panic_exprs.rs
src/test/incremental/hashes/statics.rs
src/test/incremental/hashes/struct_constructors.rs
src/test/incremental/hashes/struct_defs.rs
src/test/incremental/hashes/trait_defs.rs
src/test/incremental/hashes/trait_impls.rs
src/test/incremental/hashes/type_defs.rs
src/test/incremental/hashes/unary_and_binary_exprs.rs
src/test/incremental/hashes/while_let_loops.rs
src/test/incremental/hashes/while_loops.rs
src/test/incremental/ich_nested_items.rs
src/test/incremental/incremental_proc_macro.rs
src/test/incremental/issue-42602.rs
src/test/incremental/issue-49595/issue-49595.rs
src/test/incremental/issue-59523-on-implemented-is-not-unused.rs
src/test/incremental/issue-59524-layout-scalar-valid-range-is-not-unused.rs
src/test/incremental/krate-inherent.rs
src/test/incremental/macro_export.rs
src/test/incremental/remove_source_file/main.rs
src/test/incremental/string_constant.rs
src/test/incremental/thinlto/cgu_invalidated_via_import.rs
src/test/incremental/thinlto/independent_cgus_dont_affect_each_other.rs
src/test/incremental/warnings-reemitted.rs
src/test/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile
src/test/run-make-fulldeps/pgo-gen-lto/Makefile
src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile
src/test/run-make-fulldeps/pgo-gen/Makefile
src/test/run-make-fulldeps/pgo-use/Makefile
src/test/run-make-fulldeps/sanitizer-memory/uninit.rs
src/test/run-pass-fulldeps/issue-15778-pass.rs
src/test/run-pass/abi-sysv64-arg-passing.rs
src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs [new file with mode: 0644]
src/test/run-pass/async-await/async-fn-size-moved-locals.rs [new file with mode: 0644]
src/test/run-pass/async-await/async-fn-size.rs
src/test/run-pass/async-await/issue-60709.rs
src/test/run-pass/attr-on-generic-formals.rs [deleted file]
src/test/run-pass/command-uid-gid.rs [new file with mode: 0644]
src/test/run-pass/drop/dynamic-drop-async.rs [new file with mode: 0644]
src/test/run-pass/for-loop-while/for-loop-has-unit-body.rs
src/test/run-pass/generator/size-moved-locals.rs [new file with mode: 0644]
src/test/run-pass/intrinsics/intrinsic-uninit.rs [deleted file]
src/test/run-pass/issues/issue-30530.rs
src/test/run-pass/issues/issue-58212.rs
src/test/run-pass/packed/packed-with-inference-vars-issue-61402.rs [new file with mode: 0644]
src/test/run-pass/panic-uninitialized-zeroed.rs
src/test/run-pass/panics/panic-handler-flail-wildly.rs
src/test/run-pass/rfcs/rfc-2151-raw-identifiers/macros.rs
src/test/run-pass/stack-probes.rs
src/test/run-pass/structs-enums/enum-non-c-like-repr-c-and-int.rs
src/test/run-pass/structs-enums/enum-non-c-like-repr-c.rs
src/test/run-pass/structs-enums/enum-non-c-like-repr-int.rs
src/test/run-pass/type-alias-enum-variants-2.rs [deleted file]
src/test/run-pass/type-alias-enum-variants.rs [deleted file]
src/test/run-pass/uninit-empty-types.rs
src/test/rustdoc-ui/cfg-test.rs
src/test/rustdoc-ui/coverage/basic.rs
src/test/rustdoc-ui/coverage/empty.rs
src/test/rustdoc-ui/coverage/enums.rs
src/test/rustdoc-ui/coverage/exotic.rs
src/test/rustdoc-ui/coverage/private.rs
src/test/rustdoc-ui/coverage/statics-consts.rs
src/test/rustdoc-ui/coverage/traits.rs
src/test/rustdoc-ui/deprecated-attrs.rs
src/test/rustdoc-ui/intra-links-warning-crlf.rs
src/test/rustdoc-ui/intra-links-warning.rs
src/test/rustdoc-ui/invalid-syntax.rs
src/test/rustdoc-ui/issue-58473-2.rs
src/test/rustdoc-ui/issue-58473.rs
src/test/rustdoc-ui/unused.rs
src/test/rustdoc/issue-52873.rs
src/test/rustdoc/process-termination.rs
src/test/ui-fulldeps/auxiliary/lint-tool-test.rs
src/test/ui-fulldeps/internal-lints/default_hash_types.rs
src/test/ui-fulldeps/internal-lints/default_hash_types.stderr
src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs [new file with mode: 0644]
src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr [new file with mode: 0644]
src/test/ui-fulldeps/internal-lints/pass_ty_by_ref.rs
src/test/ui-fulldeps/internal-lints/pass_ty_by_ref.stderr
src/test/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.rs
src/test/ui-fulldeps/internal-lints/qualified_ty_ty_ctxt.stderr
src/test/ui-fulldeps/internal-lints/ty_tykind_usage.rs
src/test/ui-fulldeps/internal-lints/ty_tykind_usage.stderr
src/test/ui/anon-params-deprecated.fixed
src/test/ui/anon-params-deprecated.rs
src/test/ui/associated-const/associated-const-trait-bound.rs
src/test/ui/associated-type-bounds/entails-sized-object-safety.rs
src/test/ui/associated-type-bounds/trait-params.rs
src/test/ui/associated-type-bounds/type-alias.rs
src/test/ui/async-await/async-await.rs
src/test/ui/async-await/async-closure-matches-expr.rs [new file with mode: 0644]
src/test/ui/async-await/async-closure.rs [new file with mode: 0644]
src/test/ui/async-await/async-error-span.rs [new file with mode: 0644]
src/test/ui/async-await/async-error-span.stderr [new file with mode: 0644]
src/test/ui/async-await/async-fn-multiple-lifetimes.rs [deleted file]
src/test/ui/async-await/async-fn-multiple-lifetimes.stderr [deleted file]
src/test/ui/async-await/async-fn-path-elision.rs
src/test/ui/async-await/async-fn-send-uses-nonsend.rs
src/test/ui/async-await/async-matches-expr.rs
src/test/ui/async-await/async-with-closure.rs
src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs
src/test/ui/async-await/await-macro.rs
src/test/ui/async-await/await-unsize.rs [new file with mode: 0644]
src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs
src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs
src/test/ui/async-await/edition-deny-async-fns-2015.rs
src/test/ui/async-await/edition-deny-async-fns-2015.stderr
src/test/ui/async-await/feature-async-closure.rs [new file with mode: 0644]
src/test/ui/async-await/feature-async-closure.stderr [new file with mode: 0644]
src/test/ui/async-await/generics-and-bounds.rs
src/test/ui/async-await/issue-61793.rs
src/test/ui/async-await/issues/issue-53249.rs
src/test/ui/async-await/issues/issue-54974.rs
src/test/ui/async-await/issues/issue-55324.rs
src/test/ui/async-await/issues/issue-58885.rs
src/test/ui/async-await/issues/issue-59001.rs
src/test/ui/async-await/issues/issue-59972.rs
src/test/ui/async-await/issues/issue-60518.rs
src/test/ui/async-await/issues/issue-60655-latebound-regions.rs
src/test/ui/async-await/issues/issue-60674.rs
src/test/ui/async-await/issues/issue-61986.rs
src/test/ui/async-await/issues/issue-62009-1.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-62009-1.stderr [new file with mode: 0644]
src/test/ui/async-await/issues/issue-62009-2.rs [new file with mode: 0644]
src/test/ui/async-await/issues/issue-62009-2.stderr [new file with mode: 0644]
src/test/ui/async-await/issues/issue-62009.rs [deleted file]
src/test/ui/async-await/issues/issue-62009.stderr [deleted file]
src/test/ui/async-await/multiple-lifetimes/elided.rs [new file with mode: 0644]
src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs [new file with mode: 0644]
src/test/ui/async-await/multiple-lifetimes/hrtb.rs [new file with mode: 0644]
src/test/ui/async-await/multiple-lifetimes/named.rs [new file with mode: 0644]
src/test/ui/async-await/multiple-lifetimes/partial-relation.rs [new file with mode: 0644]
src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs [new file with mode: 0644]
src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs [new file with mode: 0644]
src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr [new file with mode: 0644]
src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr [new file with mode: 0644]
src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs [new file with mode: 0644]
src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr [new file with mode: 0644]
src/test/ui/async-await/multiple-lifetimes/ret-ref.rs [new file with mode: 0644]
src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr [new file with mode: 0644]
src/test/ui/async-await/multiple-lifetimes/variance.rs [new file with mode: 0644]
src/test/ui/async-await/no-args-non-move-async-closure.rs
src/test/ui/async-await/no-unsafe-async.rs [new file with mode: 0644]
src/test/ui/async-await/no-unsafe-async.stderr [new file with mode: 0644]
src/test/ui/async-await/recursive-async-impl-trait-type.rs
src/test/ui/async-await/suggest-missing-await-closure.fixed [new file with mode: 0644]
src/test/ui/async-await/suggest-missing-await-closure.rs [new file with mode: 0644]
src/test/ui/async-await/suggest-missing-await-closure.stderr [new file with mode: 0644]
src/test/ui/async-await/suggest-missing-await.fixed
src/test/ui/async-await/suggest-missing-await.rs
src/test/ui/async-await/suggest-missing-await.stderr
src/test/ui/attributes/attr-before-view-item.rs
src/test/ui/attributes/attr-before-view-item2.rs
src/test/ui/attributes/attr-mix-new.rs
src/test/ui/attributes/attrs-with-no-formal-in-generics-1.rs
src/test/ui/attributes/attrs-with-no-formal-in-generics-1.stderr
src/test/ui/attributes/attrs-with-no-formal-in-generics-2.rs
src/test/ui/attributes/attrs-with-no-formal-in-generics-2.stderr
src/test/ui/attributes/class-attributes-1.rs
src/test/ui/attributes/class-attributes-2.rs
src/test/ui/attributes/item-attributes.rs
src/test/ui/attributes/method-attributes.rs
src/test/ui/attributes/variant-attributes.rs
src/test/ui/bastion-of-the-turbofish.rs
src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs
src/test/ui/check_match/issue-43253.rs
src/test/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs
src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs
src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs
src/test/ui/closure-expected-type/issue-24421.rs
src/test/ui/closure_promotion.rs
src/test/ui/codemap_tests/unicode_3.rs
src/test/ui/coercion/coerce-issue-49593-box-never.rs
src/test/ui/coherence/coherence-subtyping.rs
src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs
src/test/ui/conditional-compilation/cfg-attr-multi-false.rs
src/test/ui/conditional-compilation/cfg-attr-multi-true.rs
src/test/ui/const-generics/cannot-infer-type-for-const-param.rs
src/test/ui/const-generics/issue-60818-struct-constructors.rs
src/test/ui/const-generics/issue-61422.rs
src/test/ui/consts/const-block-non-item-statement.rs
src/test/ui/consts/const-eval/const_prop_errors.rs
src/test/ui/consts/const-eval/const_signed_pat.rs
src/test/ui/consts/const-eval/double_check.rs
src/test/ui/consts/const-eval/double_promotion.rs
src/test/ui/consts/const-eval/duration_conversion.rs
src/test/ui/consts/const-eval/extern_fat_pointer.rs
src/test/ui/consts/const-eval/ice-generic-assoc-const.rs
src/test/ui/consts/const-eval/ice-packed.rs
src/test/ui/consts/const-eval/issue-47971.rs
src/test/ui/consts/const-eval/issue-50706.rs
src/test/ui/consts/const-eval/issue-51300.rs
src/test/ui/consts/const-eval/issue-53157.rs
src/test/ui/consts/const-eval/issue-53401.rs
src/test/ui/consts/const-eval/issue-55541.rs
src/test/ui/consts/const-eval/no_lint_for_statically_known_error.rs
src/test/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs
src/test/ui/consts/const-eval/pub_const_err.rs
src/test/ui/consts/const-eval/pub_const_err_bin.rs
src/test/ui/consts/const-eval/simple_with_undef.rs
src/test/ui/consts/const-eval/ub-enum.rs
src/test/ui/consts/const-eval/ub-enum.stderr
src/test/ui/consts/const-eval/ub-nonnull.rs
src/test/ui/consts/const-eval/ub-nonnull.stderr
src/test/ui/consts/const-eval/valid-const.rs
src/test/ui/consts/const-eval/zst_operand_eval.rs
src/test/ui/consts/const-expr-addr-operator.rs
src/test/ui/consts/const-fn-destructuring-arg.rs
src/test/ui/consts/const-nonzero.rs
src/test/ui/consts/const-pattern-not-const-evaluable.rs
src/test/ui/consts/const-validation-fail-55455.rs
src/test/ui/consts/const_fn_return_nested_fn_ptr.rs
src/test/ui/consts/const_let_assign.rs
src/test/ui/consts/const_let_assign2.rs
src/test/ui/consts/const_let_eq_float.rs
src/test/ui/consts/const_let_irrefutable.rs
src/test/ui/consts/drop_none.rs
src/test/ui/consts/int_ptr_for_zst_slices.rs
src/test/ui/consts/invalid_promotion.rs
src/test/ui/consts/issue-62045.rs
src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs
src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr
src/test/ui/consts/min_const_fn/min_const_fn_libstd.rs
src/test/ui/consts/promote_evaluation_unused_result.rs
src/test/ui/consts/promote_fn_calls.rs
src/test/ui/consts/promote_fn_calls_std.rs
src/test/ui/consts/promoted-validation-55454.rs
src/test/ui/consts/promoted_regression.rs
src/test/ui/consts/static_mut_containing_mut_ref.rs
src/test/ui/consts/std/slice.rs
src/test/ui/consts/underscore_const_names.rs
src/test/ui/consts/union_constant.rs
src/test/ui/dead-code-tuple-struct-field.rs
src/test/ui/deprecation/atomic_initializers.fixed
src/test/ui/deprecation/atomic_initializers.rs
src/test/ui/deprecation/derive_on_deprecated.rs
src/test/ui/deprecation/derive_on_deprecated_forbidden.rs
src/test/ui/derive-uninhabited-enum-38885.rs
src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs
src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs
src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs
src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs
src/test/ui/editions/edition-extern-crate-allowed.rs
src/test/ui/editions/edition-feature-ok.rs
src/test/ui/editions/edition-feature-redundant.rs
src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs
src/test/ui/editions/edition-keywords-2015-2015-expansion.rs
src/test/ui/editions/edition-keywords-2018-2015-expansion.rs
src/test/ui/emit-artifact-notifications.rs
src/test/ui/enum-variant-generic-args.rs [deleted file]
src/test/ui/enum-variant-generic-args.stderr [deleted file]
src/test/ui/error-codes/E0705.rs
src/test/ui/existential_types/bound_reduction.rs
src/test/ui/existential_types/cross_crate_ice.rs
src/test/ui/existential_types/cross_crate_ice2.rs
src/test/ui/existential_types/different_defining_uses_never_type2.rs
src/test/ui/existential_types/existential-associated-type.rs
src/test/ui/existential_types/generic_duplicate_param_use10.rs
src/test/ui/existential_types/generic_duplicate_param_use7.rs
src/test/ui/existential_types/generic_lifetime_param.rs
src/test/ui/existential_types/nested_existential_types.rs
src/test/ui/existential_types/private_unused.rs
src/test/ui/explain.rs
src/test/ui/extern-prelude.rs
src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs
src/test/ui/feature-gates/feature-gate-async-await.rs
src/test/ui/feature-gates/feature-gate-async-await.stderr
src/test/ui/feature-gates/feature-gate-const-indexing.rs
src/test/ui/feature-gates/feature-gate-member-constraints.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-member-constraints.stderr [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-rustc-attrs.rs
src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr
src/test/ui/feature-gates/feature-gate-slice-patterns.stderr
src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs [deleted file]
src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr [deleted file]
src/test/ui/fn_must_use.rs
src/test/ui/generator/issue-53548-1.rs
src/test/ui/generator/issue-53548.rs
src/test/ui/generic/generic-param-attrs.rs
src/test/ui/hello_world/main.rs
src/test/ui/hygiene/dollar-crate-modern.rs
src/test/ui/hygiene/local_inner_macros.rs
src/test/ui/hygiene/transparent-basic.rs
src/test/ui/if/if-let.rs
src/test/ui/impl-header-lifetime-elision/inherent-impl.rs
src/test/ui/impl-trait/associated-existential-type-generic-trait.rs
src/test/ui/impl-trait/associated-existential-type-trivial.rs
src/test/ui/impl-trait/associated-existential-type.rs
src/test/ui/impl-trait/can-return-unconstrained-closure.rs
src/test/ui/impl-trait/deprecated_annotation.rs
src/test/ui/impl-trait/existential-minimal.rs
src/test/ui/impl-trait/existential_type_in_fn_body.rs
src/test/ui/impl-trait/issues/issue-42479.rs
src/test/ui/impl-trait/issues/issue-49376.rs
src/test/ui/impl-trait/issues/issue-52128.rs
src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs
src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs
src/test/ui/impl-trait/multiple-lifetimes.rs
src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs [new file with mode: 0644]
src/test/ui/impl-trait/multiple-lifetimes/error-handling.stderr [new file with mode: 0644]
src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs [new file with mode: 0644]
src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.stderr [new file with mode: 0644]
src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs [new file with mode: 0644]
src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-existential.rs [new file with mode: 0644]
src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs [new file with mode: 0644]
src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs [new file with mode: 0644]
src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr [new file with mode: 0644]
src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs [new file with mode: 0644]
src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr [new file with mode: 0644]
src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr [new file with mode: 0644]
src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs [new file with mode: 0644]
src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr [new file with mode: 0644]
src/test/ui/impl-trait/needs_least_region_or_bound.rs
src/test/ui/impl-trait/needs_least_region_or_bound.stderr [deleted file]
src/test/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs
src/test/ui/imports/extern-crate-self/extern-crate-self-pass.rs
src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs
src/test/ui/imports/extern-prelude-extern-crate-cfg.rs
src/test/ui/imports/extern-prelude-extern-crate-pass.rs
src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs
src/test/ui/imports/gensymed.rs
src/test/ui/imports/issue-53140.rs
src/test/ui/imports/issue-55811.rs
src/test/ui/imports/issue-56263.rs
src/test/ui/imports/local-modularized-tricky-pass.rs
src/test/ui/imports/local-modularized.rs
src/test/ui/inference/inference-variable-behind-raw-pointer.rs
src/test/ui/init-unsafe.rs
src/test/ui/init-unsafe.stderr
src/test/ui/issue-53912.rs
src/test/ui/issues/issue-10396.rs
src/test/ui/issues/issue-10456.rs
src/test/ui/issues/issue-10536.rs
src/test/ui/issues/issue-10536.stderr
src/test/ui/issues/issue-10763.rs
src/test/ui/issues/issue-10853.rs
src/test/ui/issues/issue-10902.rs
src/test/ui/issues/issue-11384.rs
src/test/ui/issues/issue-11592.rs
src/test/ui/issues/issue-11612.rs
src/test/ui/issues/issue-11869.rs
src/test/ui/issues/issue-1251.rs
src/test/ui/issues/issue-12729.rs
src/test/ui/issues/issue-13105.rs
src/test/ui/issues/issue-13167.rs
src/test/ui/issues/issue-13214.rs
src/test/ui/issues/issue-13405.rs
src/test/ui/issues/issue-13703.rs
src/test/ui/issues/issue-13775.rs
src/test/ui/issues/issue-13837.rs
src/test/ui/issues/issue-14082.rs
src/test/ui/issues/issue-14254.rs
src/test/ui/issues/issue-14330.rs
src/test/ui/issues/issue-14837.rs
src/test/ui/issues/issue-14901.rs
src/test/ui/issues/issue-14933.rs
src/test/ui/issues/issue-14936.rs
src/test/ui/issues/issue-14959.rs
src/test/ui/issues/issue-15108.rs
src/test/ui/issues/issue-15261.rs
src/test/ui/issues/issue-15689-2.rs
src/test/ui/issues/issue-15735.rs
src/test/ui/issues/issue-16596.rs
src/test/ui/issues/issue-16668.rs
src/test/ui/issues/issue-17121.rs
src/test/ui/issues/issue-17263.rs
src/test/ui/issues/issue-17336.rs
src/test/ui/issues/issue-17450.rs
src/test/ui/issues/issue-17718-const-destructors.rs
src/test/ui/issues/issue-17732.rs
src/test/ui/issues/issue-17746.rs
src/test/ui/issues/issue-17904.rs
src/test/ui/issues/issue-18083.rs
src/test/ui/issues/issue-18088.rs
src/test/ui/issues/issue-18188.rs
src/test/ui/issues/issue-1821.rs
src/test/ui/issues/issue-18446-2.rs
src/test/ui/issues/issue-1866.rs
src/test/ui/issues/issue-18738.rs
src/test/ui/issues/issue-18809.rs
src/test/ui/issues/issue-18906.rs
src/test/ui/issues/issue-18988.rs
src/test/ui/issues/issue-19037.rs
src/test/ui/issues/issue-19081.rs
src/test/ui/issues/issue-19097.rs
src/test/ui/issues/issue-19098.rs
src/test/ui/issues/issue-19102.rs
src/test/ui/issues/issue-19129-1.rs
src/test/ui/issues/issue-19129-2.rs
src/test/ui/issues/issue-19398.rs
src/test/ui/issues/issue-19404.rs
src/test/ui/issues/issue-19479.rs
src/test/ui/issues/issue-19631.rs
src/test/ui/issues/issue-19632.rs
src/test/ui/issues/issue-19850.rs
src/test/ui/issues/issue-19982.rs
src/test/ui/issues/issue-20009.rs
src/test/ui/issues/issue-20091.rs
src/test/ui/issues/issue-20186.rs
src/test/ui/issues/issue-20396.rs
src/test/ui/issues/issue-20414.rs
src/test/ui/issues/issue-20454.rs
src/test/ui/issues/issue-2063-resource.rs
src/test/ui/issues/issue-20644.rs
src/test/ui/issues/issue-20763-1.rs
src/test/ui/issues/issue-20763-2.rs
src/test/ui/issues/issue-20797.rs
src/test/ui/issues/issue-20825-2.rs
src/test/ui/issues/issue-21140.rs
src/test/ui/issues/issue-21174-2.rs
src/test/ui/issues/issue-21245.rs
src/test/ui/issues/issue-21363.rs
src/test/ui/issues/issue-21402.rs
src/test/ui/issues/issue-21520.rs
src/test/ui/issues/issue-21562.rs
src/test/ui/issues/issue-21622.rs
src/test/ui/issues/issue-21634.rs
src/test/ui/issues/issue-21726.rs
src/test/ui/issues/issue-21891.rs
src/test/ui/issues/issue-22066.rs
src/test/ui/issues/issue-22356.rs
src/test/ui/issues/issue-22375.rs
src/test/ui/issues/issue-22471.rs
src/test/ui/issues/issue-22777.rs
src/test/ui/issues/issue-22781.rs
src/test/ui/issues/issue-22814.rs
src/test/ui/issues/issue-22894.rs
src/test/ui/issues/issue-2311-2.rs
src/test/ui/issues/issue-2311.rs
src/test/ui/issues/issue-2312.rs
src/test/ui/issues/issue-23406.rs
src/test/ui/issues/issue-23442.rs
src/test/ui/issues/issue-23477.rs
src/test/ui/issues/issue-23550.rs
src/test/ui/issues/issue-23649-3.rs
src/test/ui/issues/issue-24085.rs
src/test/ui/issues/issue-24161.rs
src/test/ui/issues/issue-24227.rs
src/test/ui/issues/issue-24338.rs
src/test/ui/issues/issue-24389.rs
src/test/ui/issues/issue-24434.rs
src/test/ui/issues/issue-2487-a.rs
src/test/ui/issues/issue-2502.rs
src/test/ui/issues/issue-25180.rs
src/test/ui/issues/issue-25394.rs
src/test/ui/issues/issue-25579.rs
src/test/ui/issues/issue-26095.rs
src/test/ui/issues/issue-2611-3.rs
src/test/ui/issues/issue-26205.rs
src/test/ui/issues/issue-26646.rs
src/test/ui/issues/issue-26997.rs
src/test/ui/issues/issue-27105.rs
src/test/ui/issues/issue-27281.rs
src/test/ui/issues/issue-2748-a.rs
src/test/ui/issues/issue-27583.rs
src/test/ui/issues/issue-27889.rs
src/test/ui/issues/issue-2804-2.rs
src/test/ui/issues/issue-28279.rs
src/test/ui/issues/issue-28561.rs
src/test/ui/issues/issue-28600.rs
src/test/ui/issues/issue-28822.rs
src/test/ui/issues/issue-28871.rs
src/test/ui/issues/issue-28936.rs
src/test/ui/issues/issue-28999.rs
src/test/ui/issues/issue-29030.rs
src/test/ui/issues/issue-29037.rs
src/test/ui/issues/issue-2904.rs
src/test/ui/issues/issue-29048.rs
src/test/ui/issues/issue-29071.rs
src/test/ui/issues/issue-29276.rs
src/test/ui/issues/issue-29516.rs
src/test/ui/issues/issue-29540.rs
src/test/ui/issues/issue-29710.rs
src/test/ui/issues/issue-29740.rs
src/test/ui/issues/issue-29743.rs
src/test/ui/issues/issue-31260.rs
src/test/ui/issues/issue-3149.rs
src/test/ui/issues/issue-31597.rs
src/test/ui/issues/issue-32324.rs
src/test/ui/issues/issue-33140-traitobject-crate.rs
src/test/ui/issues/issue-33264.rs
src/test/ui/issues/issue-33287.rs
src/test/ui/issues/issue-33903.rs
src/test/ui/issues/issue-34194.rs
src/test/ui/issues/issue-3424.rs
src/test/ui/issues/issue-34751.rs
src/test/ui/issues/issue-34780.rs
src/test/ui/issues/issue-35376.rs
src/test/ui/issues/issue-35546.rs
src/test/ui/issues/issue-3563-2.rs
src/test/ui/issues/issue-36075.rs
src/test/ui/issues/issue-3609.rs
src/test/ui/issues/issue-36744-without-calls.rs
src/test/ui/issues/issue-37323.rs
src/test/ui/issues/issue-37598.rs
src/test/ui/issues/issue-37655.rs
src/test/ui/issues/issue-37725.rs
src/test/ui/issues/issue-37733.rs
src/test/ui/issues/issue-38727.rs
src/test/ui/issues/issue-3874.rs
src/test/ui/issues/issue-38875/issue-38875.rs
src/test/ui/issues/issue-3888-2.rs
src/test/ui/issues/issue-39089.rs
src/test/ui/issues/issue-39467.rs
src/test/ui/issues/issue-3979-2.rs
src/test/ui/issues/issue-3991.rs
src/test/ui/issues/issue-39984.rs
src/test/ui/issues/issue-40136.rs
src/test/ui/issues/issue-4025.rs
src/test/ui/issues/issue-40510-2.rs
src/test/ui/issues/issue-40510-4.rs
src/test/ui/issues/issue-40962.rs
src/test/ui/issues/issue-41272.rs
src/test/ui/issues/issue-41298.rs
src/test/ui/issues/issue-41628.rs
src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs
src/test/ui/issues/issue-41998.rs
src/test/ui/issues/issue-42467.rs
src/test/ui/issues/issue-42956.rs
src/test/ui/issues/issue-43057.rs
src/test/ui/issues/issue-43357.rs
src/test/ui/issues/issue-43483.rs
src/test/ui/issues/issue-44005.rs
src/test/ui/issues/issue-44056.rs
src/test/ui/issues/issue-44247.rs
src/test/ui/issues/issue-44373-2.rs
src/test/ui/issues/issue-44402.rs
src/test/ui/issues/issue-4464.rs
src/test/ui/issues/issue-44730.rs
src/test/ui/issues/issue-44851.rs
src/test/ui/issues/issue-45425.rs
src/test/ui/issues/issue-46959.rs
src/test/ui/issues/issue-46964.rs
src/test/ui/issues/issue-47094.rs
src/test/ui/issues/issue-47309.rs
src/test/ui/issues/issue-47673.rs
src/test/ui/issues/issue-47703-1.rs
src/test/ui/issues/issue-47703-tuple.rs
src/test/ui/issues/issue-47703.rs
src/test/ui/issues/issue-47722.rs
src/test/ui/issues/issue-47789.rs
src/test/ui/issues/issue-48131.rs
src/test/ui/issues/issue-48131.stderr
src/test/ui/issues/issue-4830.rs
src/test/ui/issues/issue-48551.rs
src/test/ui/issues/issue-49556.rs
src/test/ui/issues/issue-49579.rs
src/test/ui/issues/issue-49934.rs
src/test/ui/issues/issue-50187.rs
src/test/ui/issues/issue-50411.rs
src/test/ui/issues/issue-50471.rs
src/test/ui/issues/issue-50518.rs
src/test/ui/issues/issue-50761.rs
src/test/ui/issues/issue-50993.rs
src/test/ui/issues/issue-51655.rs
src/test/ui/issues/issue-51947.rs
src/test/ui/issues/issue-52992.rs
src/test/ui/issues/issue-53419.rs
src/test/ui/issues/issue-5353.rs
src/test/ui/issues/issue-53568.rs
src/test/ui/issues/issue-53675-a-test-called-panic.rs
src/test/ui/issues/issue-54387.rs
src/test/ui/issues/issue-54521-1.rs
src/test/ui/issues/issue-54943-1.rs
src/test/ui/issues/issue-54943-2.rs
src/test/ui/issues/issue-54943-3.rs
src/test/ui/issues/issue-5500-1.rs
src/test/ui/issues/issue-5572.rs
src/test/ui/issues/issue-56128.rs
src/test/ui/issues/issue-56202.rs
src/test/ui/issues/issue-56411-aux.rs
src/test/ui/issues/issue-57156.rs
src/test/ui/issues/issue-57162.rs
src/test/ui/issues/issue-57410-1.rs
src/test/ui/issues/issue-57410.rs
src/test/ui/issues/issue-5754.rs
src/test/ui/issues/issue-57866.rs [deleted file]
src/test/ui/issues/issue-58006.rs [deleted file]
src/test/ui/issues/issue-58006.stderr [deleted file]
src/test/ui/issues/issue-5884.rs
src/test/ui/issues/issue-5900.rs
src/test/ui/issues/issue-5950.rs
src/test/ui/issues/issue-60662.rs
src/test/ui/issues/issue-60662.stdout
src/test/ui/issues/issue-6341.rs
src/test/ui/issues/issue-6470.rs
src/test/ui/issues/issue-6557.rs
src/test/ui/issues/issue-6898.rs
src/test/ui/issues/issue-6991.rs
src/test/ui/issues/issue-7268.rs
src/test/ui/issues/issue-7607-2.rs
src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs
src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs
src/test/ui/issues/issue-8398.rs
src/test/ui/issues/issue-8521.rs
src/test/ui/issues/issue-8578.rs
src/test/ui/issues/issue-9110.rs
src/test/ui/issues/issue-9243.rs
src/test/ui/issues/issue-9249.rs
src/test/ui/issues/issue-9719.rs
src/test/ui/lint/command-line-lint-group-allow.rs
src/test/ui/lint/command-line-lint-group-warn.rs
src/test/ui/lint/inclusive-range-pattern-syntax.fixed
src/test/ui/lint/inclusive-range-pattern-syntax.rs
src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs
src/test/ui/lint/issue-54099-camel-case-underscore-types.rs
src/test/ui/lint/issue-54538-unused-parens-lint.rs
src/test/ui/lint/lint-lowercase-static-const-pattern-rename.rs
src/test/ui/lint/lint-non-camel-case-variant.rs
src/test/ui/lint/lint-non-camel-case-with-trailing-underscores.rs
src/test/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs
src/test/ui/lint/lint-nonstandard-style-unicode.rs
src/test/ui/lint/lint-output-format-2.rs
src/test/ui/lint/lint-stability-deprecated.rs
src/test/ui/lint/lint-unknown-feature-default.rs
src/test/ui/lint/lint-unknown-feature.rs
src/test/ui/lint/lints-in-foreign-macros.rs
src/test/ui/lint/must-use-ops.rs
src/test/ui/lint/must_use-array.rs [new file with mode: 0644]
src/test/ui/lint/must_use-array.stderr [new file with mode: 0644]
src/test/ui/lint/must_use-trait.rs
src/test/ui/lint/must_use-trait.stderr
src/test/ui/lint/not_found.rs
src/test/ui/lint/reasons.rs
src/test/ui/lint/type-overflow.rs
src/test/ui/lint/unreachable_pub-pub_crate.rs
src/test/ui/lint/unreachable_pub.rs
src/test/ui/lint/unused_import_warning_issue_45268.rs
src/test/ui/lint/unused_labels.rs
src/test/ui/lint/unused_parens_json_suggestion.rs
src/test/ui/lint/unused_parens_json_suggestion.stderr
src/test/ui/lint/use-redundant.rs
src/test/ui/loops/loop-break-unsize.rs [new file with mode: 0644]
src/test/ui/loops/loops-reject-duplicate-labels-2.rs
src/test/ui/loops/loops-reject-duplicate-labels.rs
src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.rs
src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs
src/test/ui/macros/macro-expanded-include/test.rs
src/test/ui/macros/macro-path-prelude-pass.rs
src/test/ui/macros/macro-shadowing-relaxed.rs
src/test/ui/macros/macro-stmt-matchers.rs
src/test/ui/macros/macro-tt-matchers.rs
src/test/ui/macros/macro-use-scope.rs
src/test/ui/macros/must-use-in-macro-55516.rs
src/test/ui/macros/trace-macro.rs
src/test/ui/malformed/malformed-regressions.rs
src/test/ui/maybe-bounds-where-cpass.rs
src/test/ui/methods/method-call-lifetime-args-subst-index.rs
src/test/ui/methods/method-trait-object-with-hrtb.rs
src/test/ui/missing/missing-semicolon-warning.rs
src/test/ui/never-assign-dead-code.rs
src/test/ui/never_transmute_never.rs
src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs
src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs
src/test/ui/nll/constant.rs
src/test/ui/nll/drop-may-dangle.rs
src/test/ui/nll/empty-type-predicate.rs
src/test/ui/nll/extra-unused-mut.rs
src/test/ui/nll/generator-distinct-lifetime.rs
src/test/ui/nll/issue-16223.rs
src/test/ui/nll/issue-21114-ebfull.rs
src/test/ui/nll/issue-21114-kixunil.rs
src/test/ui/nll/issue-22323-temp-destruction.rs
src/test/ui/nll/issue-30104.rs
src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs
src/test/ui/nll/issue-43058.rs
src/test/ui/nll/issue-47022.rs
src/test/ui/nll/issue-50716-1.rs
src/test/ui/nll/issue-51351.rs
src/test/ui/nll/issue-52078.rs
src/test/ui/nll/issue-53119.rs
src/test/ui/nll/issue-53570.rs
src/test/ui/nll/issue-55344.rs
src/test/ui/nll/issue-55651.rs
src/test/ui/nll/issue-57280-1.rs
src/test/ui/nll/issue-57280.rs
src/test/ui/nll/issue-61311-normalize.rs
src/test/ui/nll/issue-61320-normalize.rs
src/test/ui/nll/maybe-initialized-drop-uninitialized.rs
src/test/ui/nll/projection-return.rs
src/test/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs
src/test/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs
src/test/ui/nll/relate_tys/issue-48071.rs
src/test/ui/nll/ty-outlives/issue-53789-1.rs
src/test/ui/nll/ty-outlives/issue-53789-2.rs
src/test/ui/nll/ty-outlives/issue-55756.rs
src/test/ui/nll/ty-outlives/projection-body.rs
src/test/ui/nll/ty-outlives/projection-implied-bounds.rs
src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr
src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs
src/test/ui/nll/ty-outlives/projection-where-clause-env.rs
src/test/ui/nll/ty-outlives/projection-where-clause-trait.rs
src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs
src/test/ui/nll/user-annotations/downcast-infer.rs
src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs
src/test/ui/no-warn-on-field-replace-issue-34101.rs
src/test/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs
src/test/ui/object-lifetime/object-lifetime-default.stderr
src/test/ui/object-safety/object-safety-by-value-self.rs
src/test/ui/object-safety/object-safety-phantom-fn.rs
src/test/ui/panic_implementation-closures.rs
src/test/ui/parser/bounds-obj-parens.rs
src/test/ui/parser/impl-qpath.rs
src/test/ui/parser/macro-bad-delimiter-ident.rs
src/test/ui/parser/macro-bad-delimiter-ident.stderr
src/test/ui/parser/trailing-plus-in-bounds.rs
src/test/ui/parser/trait-plusequal-splitting.rs
src/test/ui/parser/underscore-suffix-for-string.rs
src/test/ui/pattern/enum-variant-generic-args.rs [deleted file]
src/test/ui/print-fuel/print-fuel.rs
src/test/ui/print_type_sizes/anonymous.rs
src/test/ui/print_type_sizes/generics.rs
src/test/ui/print_type_sizes/multiple_types.rs
src/test/ui/print_type_sizes/niche-filling.rs
src/test/ui/print_type_sizes/no_duplicates.rs
src/test/ui/print_type_sizes/packed.rs
src/test/ui/print_type_sizes/padding.rs
src/test/ui/print_type_sizes/repr-align.rs
src/test/ui/print_type_sizes/repr_int_c.rs
src/test/ui/print_type_sizes/uninhabited.rs
src/test/ui/print_type_sizes/variants.rs
src/test/ui/privacy/issue-57264-1.rs
src/test/ui/privacy/issue-57264-2.rs
src/test/ui/privacy/private-in-public-existential.rs
src/test/ui/privacy/private-in-public-expr-pat.rs
src/test/ui/privacy/restricted/lookup-ignores-private.rs
src/test/ui/proc-macro/attributes-included.rs
src/test/ui/proc-macro/derive-helper-shadowed.rs
src/test/ui/proc-macro/derive-in-mod.rs
src/test/ui/proc-macro/dollar-crate-issue-57089.rs
src/test/ui/proc-macro/edition-imports-2018.rs
src/test/ui/proc-macro/expand-to-unstable-2.rs
src/test/ui/proc-macro/expand-to-unstable-2.stderr
src/test/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs
src/test/ui/proc-macro/helper-attr-blocked-by-import.rs
src/test/ui/proc-macro/issue-53481.rs
src/test/ui/proc-macro/macro-use-attr.rs
src/test/ui/proc-macro/macro-use-bang.rs
src/test/ui/proc-macro/no-missing-docs.rs
src/test/ui/range/range_traits-4.rs
src/test/ui/range/range_traits-5.rs
src/test/ui/range/range_traits-7.rs
src/test/ui/reachable/expr_andand.rs
src/test/ui/reachable/expr_oror.rs
src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
src/test/ui/regions/region-bound-extra-bound-in-inherent-impl.rs
src/test/ui/regions/region-bound-same-bounds-in-trait-and-impl.rs
src/test/ui/regions/region-object-lifetime-1.rs
src/test/ui/regions/region-object-lifetime-3.rs
src/test/ui/regions/regions-implied-bounds-projection-gap-2.rs
src/test/ui/regions/regions-implied-bounds-projection-gap-3.rs
src/test/ui/regions/regions-implied-bounds-projection-gap-4.rs
src/test/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs
src/test/ui/regions/regions-outlives-nominal-type-enum-region.rs
src/test/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs
src/test/ui/regions/regions-outlives-nominal-type-enum-type.rs
src/test/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs
src/test/ui/regions/regions-outlives-nominal-type-struct-region.rs
src/test/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs
src/test/ui/regions/regions-outlives-nominal-type-struct-type.rs
src/test/ui/regions/regions-outlives-projection-hrtype.rs
src/test/ui/regions/regions-outlives-projection-trait-def.rs
src/test/ui/regions/regions-outlives-scalar.rs
src/test/ui/removing-extern-crate.fixed
src/test/ui/removing-extern-crate.rs
src/test/ui/reserved/reserved-attr-on-macro.rs
src/test/ui/reserved/reserved-attr-on-macro.stderr
src/test/ui/resolve/issue-57523.rs
src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs
src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs
src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs
src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs
src/test/ui/rfc-2093-infer-outlives/issue-54467.rs
src/test/ui/rfc-2166-underscore-imports/basic.rs
src/test/ui/rfc-2166-underscore-imports/duplicate.rs
src/test/ui/rfc-2166-underscore-imports/intercrate.rs
src/test/ui/rfc-2306/convert-id-const-with-gate.rs
src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.rs
src/test/ui/rfc-2497-if-let-chains/ast-pretty-check.stdout
src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs
src/test/ui/rfc1598-generic-associated-types/parse/in-trait-impl.rs
src/test/ui/rfc1598-generic-associated-types/parse/in-trait.rs
src/test/ui/rfc1598-generic-associated-types/shadowing.rs
src/test/ui/rmeta-lib-pass.rs
src/test/ui/rmeta-pass.rs
src/test/ui/rmeta-priv-warn.rs
src/test/ui/rust-2018/edition-lint-paths-2018.rs
src/test/ui/rust-2018/edition-lint-uninferable-outlives.rs
src/test/ui/rust-2018/macro-use-warned-against.rs
src/test/ui/rust-2018/proc-macro-crate-in-paths.rs
src/test/ui/rust-2018/remove-extern-crate.fixed
src/test/ui/rust-2018/remove-extern-crate.rs
src/test/ui/rust-2018/suggestions-not-always-applicable.fixed
src/test/ui/rust-2018/suggestions-not-always-applicable.rs
src/test/ui/rust-2018/try-ident.fixed
src/test/ui/rust-2018/try-ident.rs
src/test/ui/rust-2018/try-macro.fixed
src/test/ui/rust-2018/try-macro.rs
src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs
src/test/ui/rust-2018/uniform-paths/from-decl-macro.rs
src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs
src/test/ui/rust-2018/uniform-paths/prelude.rs
src/test/ui/save-analysis/emit-notifications.rs
src/test/ui/self/explicit-self-closures.rs
src/test/ui/self/self-in-typedefs.rs
src/test/ui/self/self-type-param.rs
src/test/ui/single-use-lifetime/one-use-in-fn-return.rs
src/test/ui/single-use-lifetime/one-use-in-struct.rs
src/test/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs
src/test/ui/single-use-lifetime/two-uses-in-fn-arguments.rs
src/test/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs
src/test/ui/single-use-lifetime/two-uses-in-trait-impl.rs
src/test/ui/span/issue-24690.rs
src/test/ui/span/macro-span-replacement.rs
src/test/ui/span/multispan-import-lint.rs
src/test/ui/static/static-extern-type.rs
src/test/ui/static_sized_requirement.rs
src/test/ui/suggestions/attribute-typos.rs
src/test/ui/suggestions/attribute-typos.stderr
src/test/ui/suggestions/issue-57672.rs
src/test/ui/test-on-macro.rs
src/test/ui/test-shadowing/test-cant-be-shadowed.rs
src/test/ui/test-should-panic-attr.rs
src/test/ui/traits/conservative_impl_trait.rs
src/test/ui/traits/trait-alias/trait-alias-maybe-bound.rs
src/test/ui/traits/trait-object-with-self-in-projection-output-good.rs
src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs
src/test/ui/traits/trait-privacy.rs
src/test/ui/traits/trait-with-dst.rs
src/test/ui/traits/traits-issue-23003-overflow.rs
src/test/ui/try-poll.rs
src/test/ui/type-alias-enum-variants-panic.rs [deleted file]
src/test/ui/type-alias-enum-variants-panic.stderr [deleted file]
src/test/ui/type-alias-enum-variants-priority-2.rs [deleted file]
src/test/ui/type-alias-enum-variants-priority-2.stderr [deleted file]
src/test/ui/type-alias-enum-variants-priority-3.rs [deleted file]
src/test/ui/type-alias-enum-variants-priority-3.stderr [deleted file]
src/test/ui/type-alias-enum-variants-priority.rs [deleted file]
src/test/ui/type-alias-enum-variants-priority.stderr [deleted file]
src/test/ui/type-alias-enum-variants.rs [deleted file]
src/test/ui/type-alias-enum-variants.stderr [deleted file]
src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/issue-57866.rs [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs
src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr [new file with mode: 0644]
src/test/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs [new file with mode: 0644]
src/test/ui/type/type-alias-bounds.rs
src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs
src/test/ui/uninhabited/privately-uninhabited-dead-code.rs
src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs
src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
src/test/ui/union/union-const-eval.rs
src/test/ui/unreachable/unreachable-try-pattern.rs
src/test/ui/unrestricted-attribute-tokens.rs
src/test/ui/unsized-locals/unsized-index.rs
src/test/ui/user-defined-macro-rules.rs
src/test/ui/user-defined-macro-rules.stderr [deleted file]
src/test/ui/variance/variance-use-contravariant-struct-2.rs
src/test/ui/variance/variance-use-covariant-struct-2.rs
src/tools/compiletest/src/header.rs
src/tools/miri
src/tools/rls
src/tools/rust-installer

index 8035feeeefb9764137f78223d740226b1450ef3f..2e6c3b7a992af5621184683acbd7a40d080b1659 100644 (file)
@@ -138,9 +138,8 @@ jobs:
         IMAGE: x86_64-gnu-full-bootstrap
       x86_64-gnu-aux:
         IMAGE: x86_64-gnu-aux
-        # FIXME: needs reenabling here rather than Travis
-      # x86_64-gnu-tools:
-      #   IMAGE: x86_64-gnu-tools
+      x86_64-gnu-tools:
+        IMAGE: x86_64-gnu-tools
       x86_64-gnu-debug:
         IMAGE: x86_64-gnu-debug
       x86_64-gnu-nopt:
@@ -252,12 +251,10 @@ jobs:
         RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc
         VCVARS_BAT: vcvars64.bat
       # MSVC tools tests
-      # FIXME: broken on azure right now, need to figure out a cause and
-      # reenable
-      # x86_64-msvc-tools:
-      #   MSYS_BITS: 64
-      #   SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstates.json windows
-      #   RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json --enable-test-miri
+      x86_64-msvc-tools:
+        MSYS_BITS: 64
+        SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstates.json windows
+        RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json --enable-test-miri
 
       # 32/64-bit MinGW builds.
       #
index 271f9d382ff64f87d9c4290e0539d81a30335f55..1ece3ceb088a0a544030d15af62aa483b2541172 100644 (file)
@@ -8,6 +8,13 @@
 
 steps:
 
+# Disable automatic line ending conversion, which is enabled by default on
+# Azure's Windows image. Having the conversion enabled caused regressions both
+# in our test suite (it broke miri tests) and in the ecosystem, since we
+# started shipping install scripts with CRLF endings instead of the old LF.
+- bash: git config --global core.autocrlf false
+  displayName: "Disable git automatic line ending conversion"
+
 - checkout: self
   fetchDepth: 2
 
index 5673cc5cfbc9db3abd85d60332310f6348b7ff5e..c5ecfb54fca52df808b9a523857b47fb93bb2f64 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -167,6 +167,8 @@ Matthijs Hofstra <thiezz@gmail.com>
 Melody Horn <melody@boringcactus.com> <mathphreak@gmail.com>
 Michael Williams <m.t.williams@live.com>
 Michael Woerister <michaelwoerister@posteo> <michaelwoerister@gmail>
+Michael Woerister <michaelwoerister@posteo> <michaelwoerister@users.noreply.github.com>
+Michael Woerister <michaelwoerister@posteo> <michaelwoerister@posteo.net>
 Mickaël Raybaud-Roig <raybaudroigm@gmail.com> m-r-r <raybaudroigm@gmail.com>
 Ms2ger <ms2ger@gmail.com> <Ms2ger@gmail.com>
 Mukilan Thiagarajan <mukilanthiagarajan@gmail.com>
index ec90dd3c8fbcc6d0f507332876345f555f3ea25d..1d35ea0efacc247512c214f8baec0b6cdb0fe1ee 100644 (file)
 language: shell
-sudo: required
-dist: xenial
-services:
-  - docker
-addons:
-  apt:
-    packages:
-      - gdb
+script: echo Travis CI is not used anymore
 
-git:
-  depth: 2
-  submodules: false
-
-env:
-  global:
-    - CI_JOB_NAME=$TRAVIS_JOB_NAME
-
-matrix:
-  fast_finish: true
-  include:
-    - env: IMAGE=x86_64-gnu-tools
-      name: x86_64-gnu-tools
-      if: branch = auto OR (type = pull_request AND commit_message =~ /(?i:^update.*\b(rls|rustfmt|clippy|miri|cargo)\b)/)
-
-before_install:
-  # We'll use the AWS cli to download/upload cached docker layers as well as
-  # push our deployments, so download that here.
-  - pip install --user awscli; export PATH=$PATH:$HOME/.local/bin:$HOME/Library/Python/2.7/bin/
-  - mkdir -p $HOME/rustsrc
-  # FIXME(#46924): these two commands are required to enable IPv6,
-  # they shouldn't exist, please revert once more official solutions appeared.
-  # see https://github.com/travis-ci/travis-ci/issues/8891#issuecomment-353403729
-  - if [ "$TRAVIS_OS_NAME" = linux ]; then
-      echo '{"ipv6":true,"fixed-cidr-v6":"fd9a:8454:6789:13f7::/64"}' | sudo tee /etc/docker/daemon.json;
-      sudo service docker restart;
-    fi
-
-install:
-  - case "$TRAVIS_OS_NAME" in
-        linux)
-          travis_retry curl -fo $HOME/stamp https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2017-03-17-stamp-x86_64-unknown-linux-musl &&
-            chmod +x $HOME/stamp &&
-            export PATH=$PATH:$HOME
-          ;;
-        osx)
-          if [[ "$SCRIPT" == "./x.py dist" ]]; then
-            travis_retry brew update &&
-            travis_retry brew install xz &&
-            travis_retry brew install swig@3 &&
-            brew link --force swig@3;
-          fi &&
-          travis_retry curl -fo /usr/local/bin/sccache https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2018-04-02-sccache-x86_64-apple-darwin &&
-            chmod +x /usr/local/bin/sccache &&
-          travis_retry curl -fo /usr/local/bin/stamp https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2017-03-17-stamp-x86_64-apple-darwin &&
-            chmod +x /usr/local/bin/stamp &&
-          travis_retry curl -f http://releases.llvm.org/7.0.0/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz | tar xJf - &&
-            export CC=`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/bin/clang &&
-            export CXX=`pwd`/clang+llvm-7.0.0-x86_64-apple-darwin/bin/clang++ &&
-            export AR=ar
-          ;;
-    esac
-
-before_script:
-  - >
-      echo "#### Disk usage before running script:";
-      df -h;
-      du . | sort -nr | head -n100
-  - >
-      RUN_SCRIPT="src/ci/init_repo.sh . $HOME/rustsrc";
-      if [ "$TRAVIS_OS_NAME" = "osx" ]; then
-          export RUN_SCRIPT="$RUN_SCRIPT && src/ci/run.sh";
-      else
-          export RUN_SCRIPT="$RUN_SCRIPT && src/ci/docker/run.sh $IMAGE";
-          # Enable core dump on Linux.
-          sudo sh -c 'echo "/checkout/obj/cores/core.%p.%E" > /proc/sys/kernel/core_pattern';
-      fi
-  - >
-      if [ "$IMAGE" = mingw-check ]; then
-        # verify the publish_toolstate script works.
-        git clone --depth=1 https://github.com/rust-lang-nursery/rust-toolstate.git;
-        cd rust-toolstate;
-        python2.7 "$TRAVIS_BUILD_DIR/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "" "";
-        cd ..;
-        rm -rf rust-toolstate;
-      fi
-
-# Log time information from this machine and an external machine for insight into possible
-# clock drift. Timezones don't matter since relative deltas give all the necessary info.
-script:
-  - >
-      date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
-  - stamp sh -x -c "$RUN_SCRIPT"
-  - >
-      date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
-
-after_success:
-  - >
-      echo "#### Build successful; Disk usage after running script:";
-      df -h;
-      du . | sort -nr | head -n100
-  - >
-      if [ "$DEPLOY$DEPLOY_ALT" == "1" ]; then
-        mkdir -p deploy/$TRAVIS_COMMIT;
-        if [ "$TRAVIS_OS_NAME" == "osx" ]; then
-            rm -rf build/dist/doc &&
-            cp -r build/dist/* deploy/$TRAVIS_COMMIT;
-        else
-            rm -rf obj/build/dist/doc &&
-            cp -r obj/build/dist/* deploy/$TRAVIS_COMMIT;
-        fi;
-        ls -la deploy/$TRAVIS_COMMIT;
-        deploy_dir=rustc-builds;
-        if [ "$DEPLOY_ALT" == "1" ]; then
-            deploy_dir=rustc-builds-alt;
-        fi;
-        travis_retry aws s3 cp --no-progress --recursive --acl public-read ./deploy s3://rust-lang-ci2/$deploy_dir
-      fi
-
-after_failure:
-  - >
-      echo "#### Build failed; Disk usage after running script:";
-      df -h;
-      du . | sort -nr | head -n100
-
-  # Random attempt at debugging currently. Just poking around in here to see if
-  # anything shows up.
-
-  # Dump backtrace for macOS
-  - ls -lat $HOME/Library/Logs/DiagnosticReports/
-  - find $HOME/Library/Logs/DiagnosticReports
-      -type f
-      -name '*.crash'
-      -not -name '*.stage2-*.crash'
-      -not -name 'com.apple.CoreSimulator.CoreSimulatorService-*.crash'
-      -exec printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" {} \;
-      -exec head -750 {} \;
-      -exec echo travis_fold":"end:crashlog \; || true
-
-  # Dump backtrace for Linux
-  - ln -s . checkout &&
-    for CORE in obj/cores/core.*; do
-      EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|');
-      if [ -f "$EXE" ]; then
-        printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE";
-        gdb --batch -q -c "$CORE" "$EXE"
-          -iex 'set auto-load off'
-          -iex 'dir src/'
-          -iex 'set sysroot .'
-          -ex bt
-          -ex q;
-        echo travis_fold":"end:crashlog;
-      fi;
-    done || true
-
-  # see #50887
-  - cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
-
-  # attempt to debug anything killed by the oom killer on linux, just to see if
-  # it happened
-  - dmesg | grep -i kill
+branches:
+  only:
+    - auto
+    - try
 
 notifications:
   email: false
index 98dd10955d57d910ca70b7bfae8141dc74731200..d962b134ea2899e309d89d2b4bd8cb83bad8aaf8 100644 (file)
@@ -1272,10 +1272,12 @@ name = "installer"
 version = "0.0.0"
 dependencies = [
  "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1833,7 +1835,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "openssl-src"
-version = "111.1.0+1.1.1a"
+version = "111.3.0+1.1.1c"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1846,7 +1848,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-src 111.1.0+1.1.1a (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-src 111.3.0+1.1.1c (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4382,7 +4384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum opener 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "998c59e83d9474c01127a96e023b7a04bb061dd286bf8bb939d31dc8d31a7448"
 "checksum openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "ec7bd7ca4cce6dbdc77e7c1230682740d307d1218a87fb0349a571272be749f9"
 "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
-"checksum openssl-src 111.1.0+1.1.1a (registry+https://github.com/rust-lang/crates.io-index)" = "26bb632127731bf4ac49bf86a5dde12d2ca0918c2234fc39d79d4da2ccbc6da7"
+"checksum openssl-src 111.3.0+1.1.1c (registry+https://github.com/rust-lang/crates.io-index)" = "53ed5f31d294bdf5f7a4ba0a206c2754b0f60e9a63b7e3076babc5317873c797"
 "checksum openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)" = "33c86834957dd5b915623e94f2f4ab2c70dd8f6b70679824155d5ae21dbd495d"
 "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
 "checksum ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd20eec3dbe4376829cb7d80ae6ac45e0a766831dca50202ff2d40db46a8a024"
index 15d09f4aada3b0090780252a39f96eddb026c7ed..caebdfde8cde1656c0073454da53d7eb1208a587 100644 (file)
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ Read ["Installation"] from [The Book].
 
 _Note: If you wish to contribute to the compiler, you should read
 [this chapter](https://rust-lang.github.io/rustc-guide/how-to-build-and-run.html)
-of the rustc-guide instead._
+of the rustc-guide instead of this section._
 
 ### Building on *nix
 1. Make sure you have installed the dependencies:
index b6e2171f6eef9f75899a4fd8d247191fca55a1e4..5ceeea8d037cbc538199a0803fee386bfc4fb96f 100644 (file)
@@ -309,9 +309,9 @@ Misc
 
 Compatibility Notes
 -------------------
-- [`Command::before_exec` is now deprecated in favor of the
-  unsafe method `Command::pre_exec`.][58059]
-- [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated.][57425] As you
+- [`Command::before_exec` is being replaced by the unsafe method
+  `Command::pre_exec`][58059] and will be deprecated with Rust 1.37.0.
+- [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated][57425] as you
   can now use `const` functions in `static` variables.
 
 [58370]: https://github.com/rust-lang/rust/pull/58370/
index ee1511a0394d4f8dd50935fd29f9d65ddc20bf9e..003de85184c32b3c4ffa35747f01148c24b948d7 100644 (file)
@@ -1,113 +1,8 @@
-environment:
-  # This is required for at least an AArch64 compiler in one image, and is also
-  # going to soon be required for compiling LLVM.
-  APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview
-
-  # By default schannel checks revocation of certificates unlike some other SSL
-  # backends, but we've historically had problems on CI where a revocation
-  # server goes down presumably. See #43333 for more info
-  CARGO_HTTP_CHECK_REVOKE: false
-
-  matrix:
-  # MSVC tools tests
-  - CI_JOB_NAME: x86_64-msvc-tools
-    MSYS_BITS: 64
-    SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstates.json windows
-    RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json --enable-test-miri
-
-matrix:
-  fast_finish: true
-
-clone_depth: 2
+clone_depth: 1
 build: false
 
-install:
-  # Print which AppVeyor agent version we're running on.
-  - appveyor version
-  # If we need to download a custom MinGW, do so here and set the path
-  # appropriately.
-  #
-  # Note that this *also* means that we're not using what is typically
-  # /mingw32/bin/python2.7.exe, which is a "correct" python interpreter where
-  # /usr/bin/python2.7.exe is not. To ensure we use the right interpreter we
-  # move `C:\Python27` ahead in PATH and then also make sure the `python2.7.exe`
-  # file exists in there (which it doesn't by default).
-  - if defined MINGW_URL appveyor-retry appveyor DownloadFile %MINGW_URL%/%MINGW_ARCHIVE%
-  - if defined MINGW_URL 7z x -y %MINGW_ARCHIVE% > nul
-  - if defined MINGW_URL set PATH=%CD%\%MINGW_DIR%\bin;C:\msys64\usr\bin;%PATH%
-
-  # If we're compiling for MSVC then we, like most other distribution builders,
-  # switch to clang as the compiler. This'll allow us eventually to enable LTO
-  # amongst LLVM and rustc. Note that we only do this on MSVC as I don't think
-  # clang has an output mode compatible with MinGW that we need. If it does we
-  # should switch to clang for MinGW as well!
-  #
-  # Note that the LLVM installer is an NSIS installer
-  #
-  # Original downloaded here came from
-  # http://releases.llvm.org/8.0.0/LLVM-8.0.0-win64.exe
-  - if NOT defined MINGW_URL appveyor-retry appveyor DownloadFile https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/LLVM-8.0.0-win64.exe
-  - if NOT defined MINGW_URL .\LLVM-8.0.0-win64.exe /S /NCRC /D=C:\clang-rust
-  - if NOT defined MINGW_URL set RUST_CONFIGURE_ARGS=%RUST_CONFIGURE_ARGS% --set llvm.clang-cl=C:\clang-rust\bin\clang-cl.exe
-
-  # Here we do a pretty heinous thing which is to mangle the MinGW installation
-  # we just had above. Currently, as of this writing, we're using MinGW-w64
-  # builds of gcc, and that's currently at 6.3.0. We use 6.3.0 as it appears to
-  # be the first version which contains a fix for #40546, builds randomly
-  # failing during LLVM due to ar.exe/ranlib.exe failures.
-  #
-  # Unfortunately, though, 6.3.0 *also* is the first version of MinGW-w64 builds
-  # to contain a regression in gdb (#40184). As a result if we were to use the
-  # gdb provided (7.11.1) then we would fail all debuginfo tests.
-  #
-  # In order to fix spurious failures (pretty high priority) we use 6.3.0. To
-  # avoid disabling gdb tests we download an *old* version of gdb, specifically
-  # that found inside the 6.2.0 distribution. We then overwrite the 6.3.0 gdb
-  # with the 6.2.0 gdb to get tests passing.
-  #
-  # Note that we don't literally overwrite the gdb.exe binary because it appears
-  # to just use gdborig.exe, so that's the binary we deal with instead.
-  - if defined MINGW_URL appveyor-retry appveyor DownloadFile %MINGW_URL%/2017-04-20-%MSYS_BITS%bit-gdborig.exe
-  - if defined MINGW_URL mv 2017-04-20-%MSYS_BITS%bit-gdborig.exe %MINGW_DIR%\bin\gdborig.exe
-
-  # Otherwise pull in the MinGW installed on appveyor
-  - if NOT defined MINGW_URL set PATH=C:\msys64\mingw%MSYS_BITS%\bin;C:\msys64\usr\bin;%PATH%
-
-  # Prefer the "native" Python as LLVM has trouble building with MSYS sometimes
-  - copy C:\Python27\python.exe C:\Python27\python2.7.exe
-  - set PATH=C:\Python27;%PATH%
-
-  # Download and install sccache
-  - appveyor-retry appveyor DownloadFile https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2018-04-26-sccache-x86_64-pc-windows-msvc
-  - mv 2018-04-26-sccache-x86_64-pc-windows-msvc sccache.exe
-  - set PATH=%PATH%;%CD%
-
-  # Download and install ninja
-  #
-  # Note that this is originally from the github releases patch of Ninja
-  - appveyor-retry appveyor DownloadFile https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2017-03-15-ninja-win.zip
-  - 7z x 2017-03-15-ninja-win.zip
-  - set RUST_CONFIGURE_ARGS=%RUST_CONFIGURE_ARGS% --enable-ninja
-  # - set PATH=%PATH%;%CD% -- this already happens above for sccache
-
-  # Install InnoSetup to get `iscc` used to produce installers
-  - appveyor-retry appveyor DownloadFile https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2017-08-22-is.exe
-  - 2017-08-22-is.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
-  - set PATH="C:\Program Files (x86)\Inno Setup 5";%PATH%
-
-  # Help debug some handle issues on AppVeyor
-  - appveyor-retry appveyor DownloadFile https://rust-lang-ci2.s3.amazonaws.com/rust-ci-mirror/2017-05-15-Handle.zip
-  - mkdir handle
-  - 7z x -ohandle 2017-05-15-Handle.zip
-  - set PATH=%PATH%;%CD%\handle
-  - handle.exe -accepteula -help
-
 test_script:
-  - if not exist C:\cache\rustsrc\NUL mkdir C:\cache\rustsrc
-  - sh src/ci/init_repo.sh . /c/cache/rustsrc
-  - set SRC=.
-  - set NO_CCACHE=1
-  - sh src/ci/run.sh
+  - echo AppVeyor is not used anymore
 
 branches:
   only:
index 595deb07ec82b56a28bec40c23aa0815621e3425..242074fec7795efea3d986df5a8d49831b9f31c4 100644 (file)
@@ -306,7 +306,20 @@ fn main() {
     }
 
     // This is required for internal lints.
-    cmd.arg("-Zunstable-options");
+    if let Some(crate_name) = args.windows(2).find(|a| &*a[0] == "--crate-name") {
+        let crate_name = crate_name[1].to_string_lossy();
+        if crate_name != "rustc_version"
+            && (crate_name.starts_with("rustc")
+                || crate_name.starts_with("syntax")
+                || crate_name == "arena"
+                || crate_name == "fmt_macros")
+        {
+            cmd.arg("-Zunstable-options");
+            if stage != "0" {
+                cmd.arg("-Wrustc::internal");
+            }
+        }
+    }
 
     // Force all crates compiled by this compiler to (a) be unstable and (b)
     // allow the `rustc_private` feature to link to other unstable crates
index 41235d911c03e52131bc1f6be897140c4c73f152..8e8d8f5e787a7a0effa2488d705a1e7e1871d7ce 100644 (file)
@@ -13,7 +13,7 @@
 use crate::Build;
 
 // The version number
-pub const CFG_RELEASE_NUM: &str = "1.37.0";
+pub const CFG_RELEASE_NUM: &str = "1.38.0";
 
 pub struct GitInfo {
     inner: Option<Info>,
index 66f504ea924e9b880b525ea47409d29db868286e..20d7548df5c654cef9fea62fb96a70b727e4d5fd 100644 (file)
@@ -405,7 +405,7 @@ pub fn parse(args: &[String]) -> Config {
         config.incremental = flags.incremental;
         config.dry_run = flags.dry_run;
         config.keep_stage = flags.keep_stage;
-        if let Some(value) = flags.warnings {
+        if let Some(value) = flags.deny_warnings {
             config.deny_warnings = value;
         }
 
@@ -571,7 +571,7 @@ pub fn parse(args: &[String]) -> Config {
             config.rustc_default_linker = rust.default_linker.clone();
             config.musl_root = rust.musl_root.clone().map(PathBuf::from);
             config.save_toolstates = rust.save_toolstates.clone().map(PathBuf::from);
-            set(&mut config.deny_warnings, rust.deny_warnings.or(flags.warnings));
+            set(&mut config.deny_warnings, flags.deny_warnings.or(rust.deny_warnings));
             set(&mut config.backtrace_on_ice, rust.backtrace_on_ice);
             set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir);
             set(&mut config.rust_remap_debuginfo, rust.remap_debuginfo);
index 179accda0c8b249034899efc1171e1aa255a9e4a..0e171e92b3125f0622d011b0e7471761ad7254b4 100644 (file)
@@ -33,8 +33,11 @@ pub struct Flags {
     pub rustc_error_format: Option<String>,
     pub dry_run: bool,
 
-    // true => deny
-    pub warnings: Option<bool>,
+    // This overrides the deny-warnings configuation option,
+    // which passes -Dwarnings to the compiler invocations.
+    //
+    // true => deny, false => allow
+    pub deny_warnings: Option<bool>,
 }
 
 pub enum Subcommand {
@@ -468,7 +471,7 @@ pub fn parse(args: &[String]) -> Flags {
                 .into_iter()
                 .map(|p| p.into())
                 .collect::<Vec<_>>(),
-            warnings: matches.opt_str("warnings").map(|v| v == "deny"),
+            deny_warnings: parse_deny_warnings(&matches),
         }
     }
 }
@@ -549,3 +552,18 @@ fn split(s: &[String]) -> Vec<String> {
         .map(|s| s.to_string())
         .collect()
 }
+
+fn parse_deny_warnings(matches: &getopts::Matches) -> Option<bool> {
+    match matches.opt_str("warnings").as_ref().map(|v| v.as_str()) {
+        Some("deny") => Some(true),
+        Some("allow") => Some(false),
+        Some(value) => {
+            eprintln!(
+                r#"invalid value for --warnings: {:?}, expected "allow" or "deny""#,
+                value,
+                );
+            process::exit(1);
+        },
+        None => None,
+    }
+}
index abf512fc9cc969dcbea69aa15b44586bbeb13c2d..b5a2b9353c661000378415ecfeb757eb7df42d66 160000 (submodule)
@@ -1 +1 @@
-Subproject commit abf512fc9cc969dcbea69aa15b44586bbeb13c2d
+Subproject commit b5a2b9353c661000378415ecfeb757eb7df42d66
index 34708d1847f6b802e908cc147133a1b0b475642f..3cda8d927973ca64c7210d37ecd750093f838ca7 100644 (file)
@@ -13,5 +13,6 @@
 - [Targets](targets/index.md)
     - [Built-in Targets](targets/built-in.md)
     - [Custom Targets](targets/custom.md)
+- [Profile-guided Optimization](profile-guided-optimization.md)
 - [Linker-plugin based LTO](linker-plugin-lto.md)
 - [Contributing to `rustc`](contributing.md)
index a616409d9a400204b099d20399268e18d03b4258..3773a7783020f8d226b0716e5a9bf9eaf6d78680 100644 (file)
@@ -214,3 +214,20 @@ This option lets you control what happens when the code panics.
 ## incremental
 
 This flag allows you to enable incremental compilation.
+
+## profile-generate
+
+This flag allows for creating instrumented binaries that will collect
+profiling data for use with profile-guided optimization (PGO). The flag takes
+an optional argument which is the path to a directory into which the
+instrumented binary will emit the collected data. See the chapter on
+[profile-guided optimization](profile-guided-optimization.html) for more
+information.
+
+## profile-use
+
+This flag specifies the profiling data file to be used for profile-guided
+optimization (PGO). The flag takes a mandatory argument which is the path
+to a valid `.profdata` file. See the chapter on
+[profile-guided optimization](profile-guided-optimization.html) for more
+information.
diff --git a/src/doc/rustc/src/profile-guided-optimization.md b/src/doc/rustc/src/profile-guided-optimization.md
new file mode 100644 (file)
index 0000000..38be07a
--- /dev/null
@@ -0,0 +1,136 @@
+# Profile Guided Optimization
+
+`rustc` supports doing profile-guided optimization (PGO).
+This chapter describes what PGO is, what it is good for, and how it can be used.
+
+## What Is Profiled-Guided Optimization?
+
+The basic concept of PGO is to collect data about the typical execution of
+a program (e.g. which branches it is likely to take) and then use this data
+to inform optimizations such as inlining, machine-code layout,
+register allocation, etc.
+
+There are different ways of collecting data about a program's execution.
+One is to run the program inside a profiler (such as `perf`) and another
+is to create an instrumented binary, that is, a binary that has data
+collection built into it, and run that.
+The latter usually provides more accurate data and it is also what is
+supported by `rustc`.
+
+## Usage
+
+Generating a PGO-optimized program involves following a workflow with four steps:
+
+1. Compile the program with instrumentation enabled
+   (e.g. `rustc -Cprofile-generate=/tmp/pgo-data main.rs`)
+2. Run the instrumented program (e.g. `./main`) which generates a
+   `default_<id>.profraw` file
+3. Convert the `.profraw` file into a `.profdata` file using
+   LLVM's `llvm-profdata` tool
+4. Compile the program again, this time making use of the profiling data
+   (for example `rustc -Cprofile-use=merged.profdata main.rs`)
+
+An instrumented program will create one or more `.profraw` files, one for each
+instrumented binary. E.g. an instrumented executable that loads two instrumented
+dynamic libraries at runtime will generate three `.profraw` files. Running an
+instrumented binary multiple times, on the other hand, will re-use the
+respective `.profraw` files, updating them in place.
+
+These `.profraw` files have to be post-processed before they can be fed back
+into the compiler. This is done by the `llvm-profdata` tool. This tool
+is most easily installed via
+
+```bash
+rustup component add llvm-tools-preview
+```
+
+Note that installing the `llvm-tools-preview` component won't add
+`llvm-profdata` to the `PATH`. Rather, the tool can be found in:
+
+```bash
+~/.rustup/toolchains/<toolchain>/lib/rustlib/<target-triple>/bin/
+```
+
+Alternatively, an `llvm-profdata` coming with a recent LLVM or Clang
+version usually works too.
+
+The `llvm-profdata` tool merges multiple `.profraw` files into a single
+`.profdata` file that can then be fed back into the compiler via
+`-Cprofile-use`:
+
+```bash
+# STEP 1: Compile the binary with instrumentation
+rustc -Cprofile-generate=/tmp/pgo-data -O ./main.rs
+
+# STEP 2: Run the binary a few times, maybe with common sets of args.
+#         Each run will create or update `.profraw` files in /tmp/pgo-data
+./main mydata1.csv
+./main mydata2.csv
+./main mydata3.csv
+
+# STEP 3: Merge and post-process all the `.profraw` files in /tmp/pgo-data
+llvm-profdata merge -o ./merged.profdata /tmp/pgo-data
+
+# STEP 4: Use the merged `.profdata` file during optimization. All `rustc`
+#         flags have to be the same.
+rustc -Cprofile-use=./merged.profdata -O ./main.rs
+```
+
+### A Complete Cargo Workflow
+
+Using this feature with Cargo works very similar to using it with `rustc`
+directly. Again, we generate an instrumented binary, run it to produce data,
+merge the data, and feed it back into the compiler. Some things of note:
+
+- We use the `RUSTFLAGS` environment variable in order to pass the PGO compiler
+  flags to the compilation of all crates in the program.
+
+- We pass the `--target` flag to Cargo, which prevents the `RUSTFLAGS`
+  arguments to be passed to Cargo build scripts. We don't want the build
+  scripts to generate a bunch of `.profraw` files.
+
+- We pass `--release` to Cargo because that's where PGO makes the most sense.
+  In theory, PGO can also be done on debug builds but there is little reason
+  to do so.
+
+- It is recommended to use *absolute paths* for the argument of
+  `-Cprofile-generate` and `-Cprofile-use`. Cargo can invoke `rustc` with
+  varying working directories, meaning that `rustc` will not be able to find
+  the supplied `.profdata` file. With absolute paths this is not an issue.
+
+- It is good practice to make sure that there is no left-over profiling data
+  from previous compilation sessions. Just deleting the directory is a simple
+  way of doing so (see `STEP 0` below).
+
+This is what the entire workflow looks like:
+
+```bash
+# STEP 0: Make sure there is no left-over profiling data from previous runs
+rm -rf /tmp/pgo-data
+
+# STEP 1: Build the instrumented binaries
+RUSTFLAGS="-Cprofile-generate=/tmp/pgo-data" \
+    cargo build --release --target=x86_64-unknown-linux-gnu
+
+# STEP 2: Run the instrumented binaries with some typical data
+./target/x86_64-unknown-linux-gnu/release/myprogram mydata1.csv
+./target/x86_64-unknown-linux-gnu/release/myprogram mydata2.csv
+./target/x86_64-unknown-linux-gnu/release/myprogram mydata3.csv
+
+# STEP 3: Merge the `.profraw` files into a `.profdata` file
+llvm-profdata merge -o /tmp/pgo-data/merged.profdata /tmp/pgo-data
+
+# STEP 4: Use the `.profdata` file for guiding optimizations
+RUSTFLAGS="-Cprofile-use=/tmp/pgo-data/merged.profdata" \
+    cargo build --release --target=x86_64-unknown-linux-gnu
+```
+
+## Further Reading
+
+`rustc`'s PGO support relies entirely on LLVM's implementation of the feature
+and is equivalent to what Clang offers via the `-fprofile-generate` /
+`-fprofile-use` flags. The [Profile Guided Optimization][clang-pgo] section
+in Clang's documentation is therefore an interesting read for anyone who wants
+to use PGO with Rust.
+
+[clang-pgo]: https://clang.llvm.org/docs/UsersManual.html#profile-guided-optimization
index a896ce819aeb7e389c03d6aa7987e18940727435..c9acd3c307b54690851393d1e5304d78cbcee2ad 100644 (file)
@@ -253,19 +253,6 @@ conversion, so type inference fails because the type is not unique. Please note
 that you must write the `(())` in one sequence without intermediate whitespace
 so that rustdoc understands you want an implicit `Result`-returning function.
 
-As of version 1.37.0, this simplification also works with `Option`s, which can
-be handy to test e.g. iterators or checked arithmetic, for example:
-
-```ignore
-/// ```
-/// let _ = &[].iter().next()?;
-///# Some(())
-/// ```
-```
-
-Note that the result must be a `Some(())` and this has to be written in one go.
-In this case disambiguating the result isn't required.
-
 ## Documenting macros
 
 Here’s an example of documenting a macro:
diff --git a/src/doc/unstable-book/src/language-features/member-constraints.md b/src/doc/unstable-book/src/language-features/member-constraints.md
new file mode 100644 (file)
index 0000000..0d11c31
--- /dev/null
@@ -0,0 +1,29 @@
+# `member_constraints`
+
+The tracking issue for this feature is: [#61977]
+
+[#61977]: https://github.com/rust-lang/rust/issues/61977
+
+------------------------
+
+The `member_constraints` feature gate lets you use `impl Trait` syntax with
+multiple unrelated lifetime parameters.
+
+A simple example is:
+
+```rust
+#![feature(member_constraints)]
+
+trait Trait<'a, 'b> { }
+impl<T> Trait<'_, '_> for T {}
+
+fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> {
+  (x, y)
+}
+
+fn main() { }
+```
+
+Without the `member_constraints` feature gate, the above example is an
+error because both `'a` and `'b` appear in the impl Trait bounds, but
+neither outlives the other.
index 133174268ef93f16fbfc191b9bd405751e81af04..00c81f03ba17394be62146924357395aa5a0d194 100644 (file)
@@ -1,8 +1,8 @@
 # `slice_patterns`
 
-The tracking issue for this feature is: [#23121]
+The tracking issue for this feature is: [#62254]
 
-[#23121]: https://github.com/rust-lang/rust/issues/23121
+[#62254]: https://github.com/rust-lang/rust/issues/62254
 
 ------------------------
 
diff --git a/src/doc/unstable-book/src/language-features/type-alias-enum-variants.md b/src/doc/unstable-book/src/language-features/type-alias-enum-variants.md
deleted file mode 100644 (file)
index bcdeafc..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-# `type_alias_enum_variants`
-
-The tracking issue for this feature is: [#49683]
-
-[#49683]: https://github.com/rust-lang/rust/issues/49683
-
-------------------------
-
-The `type_alias_enum_variants` feature enables the use of variants on type
-aliases that refer to enums, as both a constructor and a pattern. That is,
-it allows for the syntax `EnumAlias::Variant`, which behaves exactly the same
-as `Enum::Variant` (assuming that `EnumAlias` is an alias for some enum type
-`Enum`).
-
-Note that since `Self` exists as a type alias, this feature also enables the
-use of the syntax `Self::Variant` within an impl block for an enum type.
-
-```rust
-#![feature(type_alias_enum_variants)]
-
-enum Foo {
-    Bar(i32),
-    Baz { i: i32 },
-}
-
-type Alias = Foo;
-
-fn main() {
-    let t = Alias::Bar(0);
-    let t = Alias::Baz { i: 0 };
-    match t {
-        Alias::Bar(_i) => {}
-        Alias::Baz { i: _i } => {}
-    }
-}
-```
index 724a21c3fc2697838c3336ca04ecc62955d1b828..0905789079a3e51c072cfcc0c7c621a0cdde7c02 100755 (executable)
@@ -16,7 +16,7 @@
 
 set -ex
 
-bucket=rust-lang-ci-evalazure
+bucket=rust-lang-ci2
 commit=$1
 builder=$2
 
index c551346bb00bfc8c7d8704491f3e7c2647f69df7..fe38c49d2707dcdf9061e2d8fff362c06e62fb3d 100644 (file)
@@ -1,2 +1,3 @@
+import gdb
 import gdb_rust_pretty_printing
 gdb_rust_pretty_printing.register_printers(gdb.current_objfile())
index 755feb849620357dda2d109220b5b5bf2e7536ff..cef2b5eea344acb506f9e382ae01bb998e67bc5d 100644 (file)
@@ -15,8 +15,7 @@
     // them from the `#[global_allocator]` attribute if there is one, or uses the
     // default implementations in libstd (`__rdl_alloc` etc in `src/libstd/alloc.rs`)
     // otherwise.
-    #[cfg_attr(bootstrap, allocator)]
-    #[cfg_attr(not(bootstrap), rustc_allocator)]
+    #[rustc_allocator]
     #[rustc_allocator_nounwind]
     fn __rust_alloc(size: usize, align: usize) -> *mut u8;
     #[rustc_allocator_nounwind]
index 9109a730cce2dd92a269166ef6e295c30191ada8..01dee0a3943373bd2b0f566911d2cd32fe25e240 100644 (file)
@@ -320,7 +320,7 @@ pub fn leak<'a>(b: Box<T>) -> &'a mut T
     /// This conversion does not allocate on the heap and happens in place.
     ///
     /// This is also available via [`From`].
-    #[unstable(feature = "box_into_pin", issue = "0")]
+    #[unstable(feature = "box_into_pin", issue = "62370")]
     pub fn into_pin(boxed: Box<T>) -> Pin<Box<T>> {
         // It's not possible to move or replace the insides of a `Pin<Box<T>>`
         // when `T: !Unpin`,  so it's safe to pin it directly without any
@@ -367,12 +367,19 @@ impl<T: Clone> Clone for Box<T> {
     /// ```
     /// let x = Box::new(5);
     /// let y = x.clone();
+    ///
+    /// // The value is the same
+    /// assert_eq!(x, y);
+    ///
+    /// // But they are unique objects
+    /// assert_ne!(&*x as *const i32, &*y as *const i32);
     /// ```
     #[rustfmt::skip]
     #[inline]
     fn clone(&self) -> Box<T> {
         box { (**self).clone() }
     }
+
     /// Copies `source`'s contents into `self` without creating a new allocation.
     ///
     /// # Examples
@@ -380,10 +387,15 @@ fn clone(&self) -> Box<T> {
     /// ```
     /// let x = Box::new(5);
     /// let mut y = Box::new(10);
+    /// let yp: *const i32 = &*y;
     ///
     /// y.clone_from(&x);
     ///
-    /// assert_eq!(*y, 5);
+    /// // The value is the same
+    /// assert_eq!(x, y);
+    ///
+    /// // And no allocation occurred
+    /// assert_eq!(yp, &*y);
     /// ```
     #[inline]
     fn clone_from(&mut self, source: &Box<T>) {
@@ -716,6 +728,14 @@ fn nth(&mut self, n: usize) -> Option<I::Item> {
         (**self).nth(n)
     }
 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: Iterator + Sized> Iterator for Box<I> {
+    fn last(self) -> Option<I::Item> where I: Sized {
+        (*self).last()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
     fn next_back(&mut self) -> Option<I::Item> {
index c898f064fd09f4fff4bb0e396a4384fe06049b26..9f531f5b83c75d6444b56ba7bb82aec8d1c5a929 100644 (file)
@@ -1035,6 +1035,11 @@ fn next(&mut self) -> Option<&'a T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+
+    #[inline]
+    fn last(self) -> Option<&'a T> {
+        self.iter.last()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
index 6b079fc87cc78905f431a097a2aa8aaee7a33f3b..d466948a0178e18e8d5595dc6110fd776ffd3535 100644 (file)
@@ -770,8 +770,8 @@ pub fn append(&mut self, other: &mut Self) {
         }
 
         // First, we merge `self` and `other` into a sorted sequence in linear time.
-        let self_iter = mem::replace(self, BTreeMap::new()).into_iter();
-        let other_iter = mem::replace(other, BTreeMap::new()).into_iter();
+        let self_iter = mem::take(self).into_iter();
+        let other_iter = mem::take(other).into_iter();
         let iter = MergeIter {
             left: self_iter.peekable(),
             right: other_iter.peekable(),
@@ -1193,6 +1193,10 @@ fn next(&mut self) -> Option<(&'a K, &'a V)> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         (self.length, Some(self.length))
     }
+
+    fn last(mut self) -> Option<(&'a K, &'a V)> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "fused", since = "1.26.0")]
@@ -1253,6 +1257,10 @@ fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         (self.length, Some(self.length))
     }
+
+    fn last(mut self) -> Option<(&'a K, &'a mut V)> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1421,6 +1429,10 @@ fn next(&mut self) -> Option<&'a K> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    fn last(mut self) -> Option<&'a K> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1458,6 +1470,10 @@ fn next(&mut self) -> Option<&'a V> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    fn last(mut self) -> Option<&'a V> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1495,6 +1511,10 @@ fn next(&mut self) -> Option<(&'a K, &'a V)> {
             unsafe { Some(self.next_unchecked()) }
         }
     }
+
+    fn last(mut self) -> Option<(&'a K, &'a V)> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "map_values_mut", since = "1.10.0")]
@@ -1508,6 +1528,10 @@ fn next(&mut self) -> Option<&'a mut V> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    fn last(mut self) -> Option<&'a mut V> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "map_values_mut", since = "1.10.0")]
@@ -1626,6 +1650,10 @@ fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
             unsafe { Some(self.next_unchecked()) }
         }
     }
+
+    fn last(mut self) -> Option<(&'a K, &'a mut V)> {
+        self.next_back()
+    }
 }
 
 impl<'a, K, V> RangeMut<'a, K, V> {
@@ -2004,7 +2032,7 @@ pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
     /// assert_eq!(keys, [1, 2]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
+    pub fn keys(&self) -> Keys<'_, K, V> {
         Keys { inner: self.iter() }
     }
 
@@ -2025,7 +2053,7 @@ pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
     /// assert_eq!(values, ["hello", "goodbye"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn values<'a>(&'a self) -> Values<'a, K, V> {
+    pub fn values(&self) -> Values<'_, K, V> {
         Values { inner: self.iter() }
     }
 
@@ -2529,8 +2557,8 @@ enum UnderflowResult<'a, K, V> {
     Stole(NodeRef<marker::Mut<'a>, K, V, marker::Internal>),
 }
 
-fn handle_underfull_node<'a, K, V>(node: NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>)
-                                   -> UnderflowResult<'a, K, V> {
+fn handle_underfull_node<K, V>(node: NodeRef<marker::Mut<'_>, K, V, marker::LeafOrInternal>)
+                               -> UnderflowResult<'_, K, V> {
     let parent = if let Ok(parent) = node.ascend() {
         parent
     } else {
index 581c66c7086a5b9f0270e3aee54e80e757bda764..7cf077d61d687b1f9ea48932f7611c584704a601 100644 (file)
@@ -394,7 +394,7 @@ pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
     }
 
     /// Temporarily takes out another, immutable reference to the same node.
-    fn reborrow<'a>(&'a self) -> NodeRef<marker::Immut<'a>, K, V, Type> {
+    fn reborrow(&self) -> NodeRef<marker::Immut<'_>, K, V, Type> {
         NodeRef {
             height: self.height,
             node: self.node,
index 16a96ca19b82462b4a99f2e234f3e1c85b630e4f..d3af910a82c27939dab4b03e1190ccad6b842a86 100644 (file)
@@ -1019,6 +1019,9 @@ fn next(&mut self) -> Option<&'a T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+    fn last(mut self) -> Option<&'a T> {
+        self.next_back()
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
@@ -1073,6 +1076,10 @@ impl<'a, T> Iterator for Range<'a, T> {
     fn next(&mut self) -> Option<&'a T> {
         self.iter.next().map(|(k, _)| k)
     }
+
+    fn last(mut self) -> Option<&'a T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "btree_range", since = "1.17.0")]
index 40a82d6feaa98ff5dbdf8856056a58227817c729..db0d6e2f9b9d4ac7246783c97a13555c0d3974be 100644 (file)
@@ -708,7 +708,7 @@ pub fn split_off(&mut self, at: usize) -> LinkedList<T> {
         let len = self.len();
         assert!(at <= len, "Cannot split off at a nonexistent index");
         if at == 0 {
-            return mem::replace(self, Self::new());
+            return mem::take(self);
         } else if at == len {
             return Self::new();
         }
@@ -832,6 +832,11 @@ fn next(&mut self) -> Option<&'a T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         (self.len, Some(self.len))
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -881,6 +886,11 @@ fn next(&mut self) -> Option<&'a mut T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         (self.len, Some(self.len))
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a mut T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
index 71faf672962b3312bd7052ae44c117ca9b321de2..573dd86b23aeb0276f266d9be83777c8e34b7d33 100644 (file)
@@ -2206,6 +2206,11 @@ fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
         self.tail = self.head - iter.len();
         final_res
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2319,6 +2324,11 @@ fn fold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
         accum = front.iter_mut().fold(accum, &mut f);
         back.iter_mut().fold(accum, &mut f)
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a mut T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
index 5fc58c8ab5a7b20672342635a92f7bff79dc8100..0750665c6b4246dd0d5c28419ef226a2d68c9f1d 100644 (file)
@@ -79,7 +79,6 @@
 #![feature(coerce_unsized)]
 #![feature(dispatch_from_dyn)]
 #![feature(core_intrinsics)]
-#![cfg_attr(bootstrap, feature(custom_attribute))]
 #![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
 #![feature(fmt_internals)]
 #![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_array)]
 #![feature(alloc_layout_extra)]
 #![feature(try_trait)]
+#![feature(mem_take)]
 
 // Allow testing this library
 
index 40104554fe574a9caa8d7f5b6a5a19d62e354647..70a93157c9ee26d12e3070d7b411cf0e51c2e05f 100644 (file)
@@ -203,7 +203,7 @@ fn to_owned(&self) -> String {
     }
 
     fn clone_into(&self, target: &mut String) {
-        let mut b = mem::replace(target, String::new()).into_bytes();
+        let mut b = mem::take(target).into_bytes();
         self.as_bytes().clone_into(&mut b);
         *target = unsafe { String::from_utf8_unchecked(b) }
     }
index 7f7722548f581df43deca22d09a91d2950158911..366191e2c85f39f38aa7ad5de472056705b456fd 100644 (file)
@@ -552,7 +552,7 @@ pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
     /// assert_eq!("Hello �World", output);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> {
+    pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> {
         let mut iter = lossy::Utf8Lossy::from_bytes(v).chunks();
 
         let (first_valid, first_broken) = if let Some(chunk) = iter.next() {
@@ -2385,6 +2385,11 @@ fn next(&mut self) -> Option<char> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<char> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "drain", since = "1.6.0")]
index 5ddac673c9ff17fe9b72859dc9748abb3a57cbfa..e0c724f557b9d0d9f84475e68ad5a0a5598d7349 100644 (file)
@@ -761,7 +761,6 @@ fn from_into_inner() {
     it.next().unwrap();
     let vec = it.collect::<Vec<_>>();
     assert_eq!(vec, [2, 3]);
-    #[cfg(not(miri))] // Miri does not support comparing dangling pointers
     assert!(ptr != vec.as_ptr());
 }
 
index 92fe0834dd029bd37225a6ce397bae636f24d7e2..c0544d7469ca76e0f572275e4e6a8e6cb99bbd71 100644 (file)
@@ -1367,6 +1367,40 @@ pub fn resize_with<F>(&mut self, new_len: usize, f: F)
             self.truncate(new_len);
         }
     }
+
+    /// Consumes and leaks the `Vec`, returning a mutable reference to the contents,
+    /// `&'a mut [T]`. Note that the type `T` must outlive the chosen lifetime
+    /// `'a`. If the type has only static references, or none at all, then this
+    /// may be chosen to be `'static`.
+    ///
+    /// This function is similar to the `leak` function on `Box`.
+    ///
+    /// This function is mainly useful for data that lives for the remainder of
+    /// the program's life. Dropping the returned reference will cause a memory
+    /// leak.
+    ///
+    /// # Examples
+    ///
+    /// Simple usage:
+    ///
+    /// ```
+    /// #![feature(vec_leak)]
+    ///
+    /// fn main() {
+    ///     let x = vec![1, 2, 3];
+    ///     let static_ref: &'static mut [usize] = Vec::leak(x);
+    ///     static_ref[0] += 1;
+    ///     assert_eq!(static_ref, &[2, 2, 3]);
+    /// }
+    /// ```
+    #[unstable(feature = "vec_leak", issue = "62195")]
+    #[inline]
+    pub fn leak<'a>(vec: Vec<T>) -> &'a mut [T]
+    where
+        T: 'a // Technically not needed, but kept to be explicit.
+    {
+        Box::leak(vec.into_boxed_slice())
+    }
 }
 
 impl<T: Clone> Vec<T> {
index 3d16e335cd8f11870745d0dadf5e30ea2ad91c2d..a4c6e5b85f9a4313ef43cb61d93d9a3e69196ef2 100644 (file)
@@ -12,7 +12,6 @@
        test(no_crate_inject, attr(deny(warnings))))]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #![feature(core_intrinsics)]
index c0ab364380fbd83d379fe22662e5d4eb20f80598..e6a6fdde540422abac4613b194ae73ae267d3345 100644 (file)
@@ -117,6 +117,7 @@ impl Iterator for EscapeDefault {
     type Item = u8;
     fn next(&mut self) -> Option<u8> { self.range.next().map(|i| self.data[i]) }
     fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
+    fn last(mut self) -> Option<u8> { self.next_back() }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl DoubleEndedIterator for EscapeDefault {
index 722c4c805168ffbb7682da6ab09da72c3a351714..e843303380ad0dfd91d58cce14d828d36556de16 100644 (file)
@@ -337,16 +337,16 @@ pub fn escape_default(self) -> EscapeDefault {
     /// ```
     /// // as chars
     /// let eastern = '東';
-    /// let capitol = '京';
+    /// let capital = '京';
     ///
     /// // both can be represented as three bytes
     /// assert_eq!(3, eastern.len_utf8());
-    /// assert_eq!(3, capitol.len_utf8());
+    /// assert_eq!(3, capital.len_utf8());
     ///
     /// // as a &str, these two are encoded in UTF-8
     /// let tokyo = "東京";
     ///
-    /// let len = eastern.len_utf8() + capitol.len_utf8();
+    /// let len = eastern.len_utf8() + capital.len_utf8();
     ///
     /// // we can see that they take six bytes total...
     /// assert_eq!(6, tokyo.len());
index a697b7bd6e589ca8f7fd97910b4f2307ad0a2c1c..c0de8e2ceb3f38b33802d52d0e1dbf87851e1a7b 100644 (file)
@@ -251,12 +251,12 @@ pub trait AsMut<T: ?Sized> {
 ///
 /// # Examples
 ///
-/// [`String`] implements `Into<Vec<u8>>`:
+/// [`String`] implements [`Into`]`<`[`Vec`]`<`[`u8`]`>>`:
 ///
 /// In order to express that we want a generic function to take all arguments that can be
 /// converted to a specified type `T`, we can use a trait bound of [`Into`]`<T>`.
 /// For example: The function `is_hello` takes all arguments that can be converted into a
-/// `Vec<u8>`.
+/// [`Vec`]`<`[`u8`]`>`.
 ///
 /// ```
 /// fn is_hello<T: Into<Vec<u8>>>(s: T) {
@@ -274,6 +274,7 @@ pub trait AsMut<T: ?Sized> {
 /// [`String`]: ../../std/string/struct.String.html
 /// [`From`]: trait.From.html
 /// [`Into`]: trait.Into.html
+/// [`Vec`]: ../../std/vec/struct.Vec.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Into<T>: Sized {
     /// Performs the conversion.
@@ -410,12 +411,12 @@ pub trait TryInto<T>: Sized {
 ///
 /// This is useful when you are doing a type conversion that may
 /// trivially succeed but may also need special handling.
-/// For example, there is no way to convert an `i64` into an `i32`
-/// using the [`From`] trait, because an `i64` may contain a value
-/// that an `i32` cannot represent and so the conversion would lose data.
-/// This might be handled by truncating the `i64` to an `i32` (essentially
-/// giving the `i64`'s value modulo `i32::MAX`) or by simply returning
-/// `i32::MAX`, or by some other method.  The `From` trait is intended
+/// For example, there is no way to convert an [`i64`] into an [`i32`]
+/// using the [`From`] trait, because an [`i64`] may contain a value
+/// that an [`i32`] cannot represent and so the conversion would lose data.
+/// This might be handled by truncating the [`i64`] to an [`i32`] (essentially
+/// giving the [`i64`]'s value modulo [`i32::MAX`]) or by simply returning
+/// [`i32::MAX`], or by some other method.  The [`From`] trait is intended
 /// for perfect conversions, so the `TryFrom` trait informs the
 /// programmer when a type conversion could go bad and lets them
 /// decide how to handle it.
@@ -425,8 +426,8 @@ pub trait TryInto<T>: Sized {
 /// - `TryFrom<T> for U` implies [`TryInto`]`<U> for T`
 /// - [`try_from`] is reflexive, which means that `TryFrom<T> for T`
 /// is implemented and cannot fail -- the associated `Error` type for
-/// calling `T::try_from()` on a value of type `T` is `Infallible`.
-/// When the `!` type is stablized `Infallible` and `!` will be
+/// calling `T::try_from()` on a value of type `T` is [`Infallible`].
+/// When the [`!`] type is stablized [`Infallible`] and [`!`] will be
 /// equivalent.
 ///
 /// `TryFrom<T>` can be implemented as follows:
@@ -451,7 +452,7 @@ pub trait TryInto<T>: Sized {
 ///
 /// # Examples
 ///
-/// As described, [`i32`] implements `TryFrom<i64>`:
+/// As described, [`i32`] implements `TryFrom<`[`i64`]`>`:
 ///
 /// ```
 /// use std::convert::TryFrom;
@@ -474,6 +475,8 @@ pub trait TryInto<T>: Sized {
 ///
 /// [`try_from`]: trait.TryFrom.html#tymethod.try_from
 /// [`TryInto`]: trait.TryInto.html
+/// [`i32::MAX`]: ../../std/i32/constant.MAX.html
+/// [`!`]: ../../std/primitive.never.html
 #[stable(feature = "try_from", since = "1.34.0")]
 pub trait TryFrom<T>: Sized {
     /// The type returned in the event of a conversion error.
index 49090fb8e43788467855248ce7feae75ec0e0d0d..4f87cc506efae2efc10bfbc1a1964efcba764588 100644 (file)
@@ -302,7 +302,6 @@ impl<T> sealed_trait::VaArgSafe for *const T {}
            reason = "the `c_variadic` feature has not been properly tested on \
                      all supported platforms",
            issue = "44930")]
-#[cfg(not(bootstrap))]
 impl<'f> VaListImpl<'f> {
     /// Advance to the next arg.
     #[inline]
@@ -324,7 +323,6 @@ pub unsafe fn with_copy<F, R>(&self, f: F) -> R
            reason = "the `c_variadic` feature has not been properly tested on \
                      all supported platforms",
            issue = "44930")]
-#[cfg(not(bootstrap))]
 impl<'f> Clone for VaListImpl<'f> {
     #[inline]
     fn clone(&self) -> Self {
@@ -340,7 +338,6 @@ fn clone(&self) -> Self {
            reason = "the `c_variadic` feature has not been properly tested on \
                      all supported platforms",
            issue = "44930")]
-#[cfg(not(bootstrap))]
 impl<'f> Drop for VaListImpl<'f> {
     fn drop(&mut self) {
         // FIXME: this should call `va_end`, but there's no clean way to
@@ -359,15 +356,12 @@ fn drop(&mut self) {
 extern "rust-intrinsic" {
     /// Destroy the arglist `ap` after initialization with `va_start` or
     /// `va_copy`.
-    #[cfg(not(bootstrap))]
     fn va_end(ap: &mut VaListImpl<'_>);
 
     /// Copies the current location of arglist `src` to the arglist `dst`.
-    #[cfg(not(bootstrap))]
     fn va_copy<'f>(dest: *mut VaListImpl<'f>, src: &VaListImpl<'f>);
 
     /// Loads an argument of type `T` from the `va_list` `ap` and increment the
     /// argument `ap` points to.
-    #[cfg(not(bootstrap))]
     fn va_arg<T: sealed_trait::VaArgSafe>(ap: &mut VaListImpl<'_>) -> T;
 }
index acca8d7ba15339e1ddae04985f0fa081d4fd09fb..8bd1601a362133899176df264d1a7373df31f706 100644 (file)
@@ -25,7 +25,7 @@
 #[doc(spotlight)]
 #[must_use = "futures do nothing unless you `.await` or poll them"]
 #[stable(feature = "futures_api", since = "1.36.0")]
-#[cfg_attr(not(bootstrap), lang = "future_trait")]
+#[lang = "future_trait"]
 pub trait Future {
     /// The type of value produced on completion.
     #[stable(feature = "futures_api", since = "1.36.0")]
index b30eff8baa9c87347c605d87382bf0848024cd7c..67430e5bbda4d58df472854ea5ae6cef7d07eb42 100644 (file)
     /// which is unsafe unless `T` is `Copy`. Also, even if T is
     /// `Copy`, an all-zero value may not correspond to any legitimate
     /// state for the type in question.
+    #[unstable(feature = "core_intrinsics",
+               reason = "intrinsics are unlikely to ever be stabilized, instead \
+                         they should be used through stabilized interfaces \
+                         in the rest of the standard library",
+               issue = "0")]
+    #[rustc_deprecated(reason = "no longer used by rustc, will be removed - use MaybeUnint instead",
+                       since = "1.38.0")]
     pub fn init<T>() -> T;
 
-    /// Creates an uninitialized value.
-    ///
-    /// `uninit` is unsafe because there is no guarantee of what its
-    /// contents are. In particular its drop-flag may be set to any
-    /// state, which means it may claim either dropped or
-    /// undropped. In the general case one must use `ptr::write` to
-    /// initialize memory previous set to the result of `uninit`.
-    pub fn uninit<T>() -> T;
-
     /// Moves a value out of scope without running drop glue.
     pub fn forget<T: ?Sized>(_: T);
 
@@ -1052,16 +1050,12 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
     pub fn fabsf64(x: f64) -> f64;
 
     /// Returns the minimum of two `f32` values.
-    #[cfg(not(bootstrap))]
     pub fn minnumf32(x: f32, y: f32) -> f32;
     /// Returns the minimum of two `f64` values.
-    #[cfg(not(bootstrap))]
     pub fn minnumf64(x: f64, y: f64) -> f64;
     /// Returns the maximum of two `f32` values.
-    #[cfg(not(bootstrap))]
     pub fn maxnumf32(x: f32, y: f32) -> f32;
     /// Returns the maximum of two `f64` values.
-    #[cfg(not(bootstrap))]
     pub fn maxnumf64(x: f64, y: f64) -> f64;
 
     /// Copies the sign from `y` to `x` for `f32` values.
@@ -1255,17 +1249,14 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
 
     /// Returns the result of an unchecked addition, resulting in
     /// undefined behavior when `x + y > T::max_value()` or `x + y < T::min_value()`.
-    #[cfg(not(bootstrap))]
     pub fn unchecked_add<T>(x: T, y: T) -> T;
 
     /// Returns the result of an unchecked substraction, resulting in
     /// undefined behavior when `x - y > T::max_value()` or `x - y < T::min_value()`.
-    #[cfg(not(bootstrap))]
     pub fn unchecked_sub<T>(x: T, y: T) -> T;
 
     /// Returns the result of an unchecked multiplication, resulting in
     /// undefined behavior when `x * y > T::max_value()` or `x * y < T::min_value()`.
-    #[cfg(not(bootstrap))]
     pub fn unchecked_mul<T>(x: T, y: T) -> T;
 
     /// Performs rotate left.
@@ -1563,53 +1554,3 @@ pub unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
     }
     write_bytes(dst, val, count)
 }
-
-// Simple bootstrap implementations of minnum/maxnum for stage0 compilation.
-
-/// Returns the minimum of two `f32` values.
-#[cfg(bootstrap)]
-pub fn minnumf32(x: f32, y: f32) -> f32 {
-    // IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the
-    // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
-    // is either x or y, canonicalized (this means results might differ among implementations).
-    // When either x or y is a signaling NaN, then the result is according to 6.2.
-    //
-    // Since we do not support sNaN in Rust yet, we do not need to handle them.
-    // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
-    // multiplying by 1.0. Should switch to the `canonicalize` when it works.
-    (if x < y || y != y { x } else { y }) * 1.0
-}
-
-/// Returns the minimum of two `f64` values.
-#[cfg(bootstrap)]
-pub fn minnumf64(x: f64, y: f64) -> f64 {
-    // Identical to the `f32` case.
-    (if x < y || y != y { x } else { y }) * 1.0
-}
-
-/// Returns the maximum of two `f32` values.
-#[cfg(bootstrap)]
-pub fn maxnumf32(x: f32, y: f32) -> f32 {
-    // IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the
-    // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
-    // is either x or y, canonicalized (this means results might differ among implementations).
-    // When either x or y is a signaling NaN, then the result is according to 6.2.
-    //
-    // Since we do not support sNaN in Rust yet, we do not need to handle them.
-    // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
-    // multiplying by 1.0. Should switch to the `canonicalize` when it works.
-    (if x < y || x != x { y } else { x }) * 1.0
-}
-
-/// Returns the maximum of two `f64` values.
-#[cfg(bootstrap)]
-pub fn maxnumf64(x: f64, y: f64) -> f64 {
-    // Identical to the `f32` case.
-    (if x < y || x != x { y } else { x }) * 1.0
-}
-
-/// For bootstrapping, implement unchecked_sub as just wrapping_sub.
-#[cfg(bootstrap)]
-pub unsafe fn unchecked_sub<T>(x: T, y: T) -> T {
-    sub_with_overflow(x, y).0
-}
index 04c50329de3d01bfecccebb49d136b225a8ee3cf..6ab64a11237003c6567da0149f93332417caaadb 100644 (file)
@@ -74,6 +74,7 @@
 #![feature(concat_idents)]
 #![feature(const_fn)]
 #![feature(const_fn_union)]
+#![feature(custom_inner_attributes)]
 #![feature(doc_cfg)]
 #![feature(doc_spotlight)]
 #![feature(extern_types)]
 #![feature(staged_api)]
 #![feature(std_internals)]
 #![feature(stmt_expr_attributes)]
-#![cfg_attr(not(bootstrap), feature(transparent_unions))]
+#![feature(transparent_unions)]
 #![feature(unboxed_closures)]
 #![feature(unsized_locals)]
 #![feature(untagged_unions)]
 #![feature(adx_target_feature)]
 #![feature(maybe_uninit_slice, maybe_uninit_array)]
 #![feature(external_doc)]
+#![feature(mem_take)]
 
 #[prelude_import]
 #[allow(unused)]
index d9757d78dcebbf34886c9c6b8915e9faf0e9b9ef..39c390b4df6d3d31383dfb4c6839e367004bdee4 100644 (file)
@@ -498,7 +498,7 @@ fn default() -> $t<T> {
 /// #     end: *const T,
 /// #     phantom: PhantomData<&'a T>,
 /// # }
-/// fn borrow_vec<'a, T>(vec: &'a Vec<T>) -> Slice<'a, T> {
+/// fn borrow_vec<T>(vec: &Vec<T>) -> Slice<'_, T> {
 ///     let ptr = vec.as_ptr();
 ///     Slice {
 ///         start: ptr,
index 28e1e22ba7ff298e4800f4c5219b66cc5372442c..407691662d14ee8d80ea02496fd83ee3f639c23e 100644 (file)
 #[allow(missing_debug_implementations)]
 #[stable(feature = "maybe_uninit", since = "1.36.0")]
 #[derive(Copy)]
-#[cfg_attr(not(bootstrap), repr(transparent))]
+#[repr(transparent)]
 pub union MaybeUninit<T> {
     uninit: (),
     value: ManuallyDrop<T>,
index e110e93a95412b73a0b72215a8b1345b86e6dc56..b62d81affddbd61c69d077cf93ce7ca13e85b0f5 100644 (file)
@@ -450,8 +450,7 @@ pub const fn needs_drop<T>() -> bool {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn zeroed<T>() -> T {
-    intrinsics::panic_if_uninhabited::<T>();
-    intrinsics::init()
+    MaybeUninit::zeroed().assume_init()
 }
 
 /// Bypasses Rust's normal memory-initialization checks by pretending to
@@ -476,8 +475,7 @@ pub unsafe fn zeroed<T>() -> T {
 #[rustc_deprecated(since = "1.38.0", reason = "use `mem::MaybeUninit` instead")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn uninitialized<T>() -> T {
-    intrinsics::panic_if_uninhabited::<T>();
-    intrinsics::uninit()
+    MaybeUninit::uninit().assume_init()
 }
 
 /// Swaps the values at two mutable locations, without deinitializing either one.
@@ -552,6 +550,12 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
 ///         mem::take(&mut self.buf)
 ///     }
 /// }
+///
+/// let mut buffer = Buffer { buf: vec![0, 1] };
+/// assert_eq!(buffer.buf.len(), 2);
+///
+/// assert_eq!(buffer.get_and_reset(), vec![0, 1]);
+/// assert_eq!(buffer.buf.len(), 0);
 /// ```
 ///
 /// [`Clone`]: ../../std/clone/trait.Clone.html
@@ -586,17 +590,17 @@ pub fn take<T: Default>(dest: &mut T) -> T {
 /// struct Buffer<T> { buf: Vec<T> }
 ///
 /// impl<T> Buffer<T> {
-///     fn get_and_reset(&mut self) -> Vec<T> {
+///     fn replace_index(&mut self, i: usize, v: T) -> T {
 ///         // error: cannot move out of dereference of `&mut`-pointer
-///         let buf = self.buf;
-///         self.buf = Vec::new();
-///         buf
+///         let t = self.buf[i];
+///         self.buf[i] = v;
+///         t
 ///     }
 /// }
 /// ```
 ///
-/// Note that `T` does not necessarily implement [`Clone`], so it can't even clone and reset
-/// `self.buf`. But `replace` can be used to disassociate the original value of `self.buf` from
+/// Note that `T` does not necessarily implement [`Clone`], so we can't even clone `self.buf[i]` to
+/// avoid the move. But `replace` can be used to disassociate the original value at that index from
 /// `self`, allowing it to be returned:
 ///
 /// ```
@@ -605,10 +609,16 @@ pub fn take<T: Default>(dest: &mut T) -> T {
 ///
 /// # struct Buffer<T> { buf: Vec<T> }
 /// impl<T> Buffer<T> {
-///     fn get_and_reset(&mut self) -> Vec<T> {
-///         mem::replace(&mut self.buf, Vec::new())
+///     fn replace_index(&mut self, i: usize, v: T) -> T {
+///         mem::replace(&mut self.buf[i], v)
 ///     }
 /// }
+///
+/// let mut buffer = Buffer { buf: vec![0, 1] };
+/// assert_eq!(buffer.buf[0], 0);
+///
+/// assert_eq!(buffer.replace_index(0, 2), 0);
+/// assert_eq!(buffer.buf[0], 2);
 /// ```
 ///
 /// [`Clone`]: ../../std/clone/trait.Clone.html
index d70f55670116c9c0c662830d749b6e9763acecc4..72552c5a0b0f06c8e709f6d55b1badd402f659ad 100644 (file)
@@ -50,7 +50,7 @@ macro_rules! nonzero_integers {
                 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
                 #[repr(transparent)]
                 #[rustc_layout_scalar_valid_range_start(1)]
-                #[cfg_attr(not(bootstrap), rustc_nonnull_optimization_guaranteed)]
+                #[rustc_nonnull_optimization_guaranteed]
                 pub struct $Ty($Int);
             }
 
index 3158f58e958068c75d8b108d6846a1a229f80c06..9cff474a760306be8f639270d67b5fed39802cd1 100644 (file)
@@ -105,7 +105,7 @@ pub trait Index<Idx: ?Sized> {
 /// impl Index<Side> for Balance {
 ///     type Output = Weight;
 ///
-///     fn index<'a>(&'a self, index: Side) -> &'a Self::Output {
+///     fn index(&self, index: Side) -> &Self::Output {
 ///         println!("Accessing {:?}-side of balance immutably", index);
 ///         match index {
 ///             Side::Left => &self.left,
@@ -115,7 +115,7 @@ pub trait Index<Idx: ?Sized> {
 /// }
 ///
 /// impl IndexMut<Side> for Balance {
-///     fn index_mut<'a>(&'a mut self, index: Side) -> &'a mut Self::Output {
+///     fn index_mut(&mut self, index: Side) -> &mut Self::Output {
 ///         println!("Accessing {:?}-side of balance mutably", index);
 ///         match index {
 ///             Side::Left => &mut self.left,
index eec4b149ddc7840e78d0dc5f7a5149c806d43fd4..b27fd4098e167f7bca2be9923fa2a9370329f1e8 100644 (file)
@@ -777,15 +777,7 @@ pub fn xor(self, optb: Option<T>) -> Option<T> {
     #[inline]
     #[stable(feature = "option_entry", since = "1.20.0")]
     pub fn get_or_insert(&mut self, v: T) -> &mut T {
-        match *self {
-            None => *self = Some(v),
-            _ => (),
-        }
-
-        match *self {
-            Some(ref mut v) => v,
-            None => unsafe { hint::unreachable_unchecked() },
-        }
+        self.get_or_insert_with(|| v)
     }
 
     /// Inserts a value computed from `f` into the option if it is [`None`], then
@@ -845,7 +837,7 @@ pub fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn take(&mut self) -> Option<T> {
-        mem::replace(self, None)
+        mem::take(self)
     }
 
     /// Replaces the actual value in the option by the value given in parameter,
index fccb00d768cd852f69f35135d68fedcff29c26fc..2a6c2b1331e5c5754e8b7c5e63025a9f9e0d29ef 100644 (file)
 ///   as the compiler doesn't need to prove that it's sound to elide the
 ///   copy.
 ///
+/// Unaligned values cannot be dropped in place, they must be copied to an aligned
+/// location first using [`ptr::read_unaligned`].
+///
 /// [`ptr::read`]: ../ptr/fn.read.html
+/// [`ptr::read_unaligned`]: ../ptr/fn.read_unaligned.html
 ///
 /// # Safety
 ///
 ///
 /// * `to_drop` must be [valid] for reads.
 ///
-/// * `to_drop` must be properly aligned. See the example below for how to drop
-///   an unaligned pointer.
+/// * `to_drop` must be properly aligned.
 ///
 /// Additionally, if `T` is not [`Copy`], using the pointed-to value after
 /// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop =
 /// assert!(weak.upgrade().is_none());
 /// ```
 ///
-/// Unaligned values cannot be dropped in place, they must be copied to an aligned
-/// location first:
-/// ```
-/// use std::ptr;
-/// use std::mem::{self, MaybeUninit};
-///
-/// unsafe fn drop_after_copy<T>(to_drop: *mut T) {
-///     let mut copy: MaybeUninit<T> = MaybeUninit::uninit();
-///     ptr::copy(to_drop, copy.as_mut_ptr(), 1);
-///     drop(copy.assume_init());
-/// }
-///
-/// #[repr(packed, C)]
-/// struct Packed {
-///     _padding: u8,
-///     unaligned: Vec<i32>,
-/// }
-///
-/// let mut p = Packed { _padding: 0, unaligned: vec![42] };
-/// unsafe {
-///     drop_after_copy(&mut p.unaligned as *mut _);
-///     mem::forget(p);
-/// }
-/// ```
-///
 /// Notice that the compiler performs this copy automatically when dropping packed structs,
 /// i.e., you do not usually have to worry about such issues unless you call `drop_in_place`
 /// manually.
@@ -647,42 +625,50 @@ pub unsafe fn read<T>(src: *const T) -> T {
 /// [read-ownership]: ./fn.read.html#ownership-of-the-returned-value
 /// [valid]: ../ptr/index.html#safety
 ///
-/// # Examples
+/// ## On `packed` structs
 ///
-/// Access members of a packed struct by reference:
+/// It is currently impossible to create raw pointers to unaligned fields
+/// of a packed struct.
 ///
-/// ```
-/// use std::ptr;
+/// Attempting to create a raw pointer to an `unaligned` struct field with
+/// an expression such as `&packed.unaligned as *const FieldType` creates an
+/// intermediate unaligned reference before converting that to a raw pointer.
+/// That this reference is temporary and immediately cast is inconsequential
+/// as the compiler always expects references to be properly aligned.
+/// As a result, using `&packed.unaligned as *const FieldType` causes immediate
+/// *undefined behavior* in your program.
 ///
+/// An example of what not to do and how this relates to `read_unaligned` is:
+///
+/// ```no_run
 /// #[repr(packed, C)]
 /// struct Packed {
 ///     _padding: u8,
 ///     unaligned: u32,
 /// }
 ///
-/// let x = Packed {
+/// let packed = Packed {
 ///     _padding: 0x00,
 ///     unaligned: 0x01020304,
 /// };
 ///
 /// let v = unsafe {
-///     // Take the address of a 32-bit integer which is not aligned.
-///     // This must be done as a raw pointer; unaligned references are invalid.
-///     let unaligned = &x.unaligned as *const u32;
-///
-///     // Dereferencing normally will emit an aligned load instruction,
-///     // causing undefined behavior.
-///     // let v = *unaligned; // ERROR
+///     // Here we attempt to take the address of a 32-bit integer which is not aligned.
+///     let unaligned =
+///         // A temporary unaligned reference is created here which results in
+///         // undefined behavior regardless of whether the reference is used or not.
+///         &packed.unaligned
+///         // Casting to a raw pointer doesn't help; the mistake already happened.
+///         as *const u32;
 ///
-///     // Instead, use `read_unaligned` to read improperly aligned values.
-///     let v = ptr::read_unaligned(unaligned);
+///     let v = std::ptr::read_unaligned(unaligned);
 ///
 ///     v
 /// };
-///
-/// // Accessing unaligned values directly is safe.
-/// assert!(x.unaligned == v);
 /// ```
+///
+/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.
+// FIXME: Update docs based on outcome of RFC #2582 and friends.
 #[inline]
 #[stable(feature = "ptr_unaligned", since = "1.17.0")]
 pub unsafe fn read_unaligned<T>(src: *const T) -> T {
@@ -811,38 +797,48 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
 ///
 /// [valid]: ../ptr/index.html#safety
 ///
-/// # Examples
+/// ## On `packed` structs
 ///
-/// Access fields in a packed struct:
+/// It is currently impossible to create raw pointers to unaligned fields
+/// of a packed struct.
 ///
-/// ```
-/// use std::{mem, ptr};
+/// Attempting to create a raw pointer to an `unaligned` struct field with
+/// an expression such as `&packed.unaligned as *const FieldType` creates an
+/// intermediate unaligned reference before converting that to a raw pointer.
+/// That this reference is temporary and immediately cast is inconsequential
+/// as the compiler always expects references to be properly aligned.
+/// As a result, using `&packed.unaligned as *const FieldType` causes immediate
+/// *undefined behavior* in your program.
 ///
+/// An example of what not to do and how this relates to `write_unaligned` is:
+///
+/// ```no_run
 /// #[repr(packed, C)]
-/// #[derive(Default)]
 /// struct Packed {
 ///     _padding: u8,
 ///     unaligned: u32,
 /// }
 ///
 /// let v = 0x01020304;
-/// let mut x: Packed = unsafe { mem::zeroed() };
-///
-/// unsafe {
-///     // Take a reference to a 32-bit integer which is not aligned.
-///     let unaligned = &mut x.unaligned as *mut u32;
+/// let mut packed: Packed = unsafe { std::mem::zeroed() };
 ///
-///     // Dereferencing normally will emit an aligned store instruction,
-///     // causing undefined behavior because the pointer is not aligned.
-///     // *unaligned = v; // ERROR
+/// let v = unsafe {
+///     // Here we attempt to take the address of a 32-bit integer which is not aligned.
+///     let unaligned =
+///         // A temporary unaligned reference is created here which results in
+///         // undefined behavior regardless of whether the reference is used or not.
+///         &mut packed.unaligned
+///         // Casting to a raw pointer doesn't help; the mistake already happened.
+///         as *mut u32;
 ///
-///     // Instead, use `write_unaligned` to write improperly aligned values.
-///     ptr::write_unaligned(unaligned, v);
-/// }
+///     std::ptr::write_unaligned(unaligned, v);
 ///
-/// // Accessing unaligned values directly is safe.
-/// assert!(x.unaligned == v);
+///     v
+/// };
 /// ```
+///
+/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.
+// FIXME: Update docs based on outcome of RFC #2582 and friends.
 #[inline]
 #[stable(feature = "ptr_unaligned", since = "1.17.0")]
 pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
index 46dde7c1da58993cc2c9e65463672e618f69a9b8..ad3d1ce396ab755c70dd1adc709eec93943f9565 100644 (file)
@@ -38,7 +38,7 @@
 #[stable(feature = "nonnull", since = "1.25.0")]
 #[repr(transparent)]
 #[rustc_layout_scalar_valid_range_start(1)]
-#[cfg_attr(not(bootstrap), rustc_nonnull_optimization_guaranteed)]
+#[rustc_nonnull_optimization_guaranteed]
 pub struct NonNull<T: ?Sized> {
     pointer: *const T,
 }
index c6d44324ef5ee16a8eb81464f3420ccc3ece5fc7..fe48e2458cd162e5d9c627ad962b0c45aea8f6e6 100644 (file)
@@ -4453,6 +4453,21 @@ fn next_back(&mut self) -> Option<&'a [T]> {
             Some(snd)
         }
     }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        let len = self.len();
+        if n >= len {
+            self.v = &[];
+            None
+        } else {
+            let start = (len - 1 - n) * self.chunk_size;
+            let end = start + self.chunk_size;
+            let nth_back = &self.v[start..end];
+            self.v = &self.v[..start];
+            Some(nth_back)
+        }
+    }
 }
 
 #[stable(feature = "chunks_exact", since = "1.31.0")]
index 34f2d8917ea472a9f5d25af24e3875448378bedf..b027e6bc051b3abe96d10bc8959460ed2edf2825 100644 (file)
@@ -1333,6 +1333,11 @@ fn next(&mut self) -> Option<&'a str> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.0.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a str> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -3716,10 +3721,10 @@ pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
     ///
     /// # Text directionality
     ///
-    /// A string is a sequence of bytes. 'Left' in this context means the first
-    /// position of that byte string; for a language like Arabic or Hebrew
-    /// which are 'right to left' rather than 'left to right', this will be
-    /// the _right_ side, not the left.
+    /// A string is a sequence of bytes. `start` in this context means the first
+    /// position of that byte string; for a left-to-right language like English or
+    /// Russian, this will be left side, and for right-to-left languages like
+    /// like Arabic or Hebrew, this will be the right side.
     ///
     /// # Examples
     ///
@@ -3755,10 +3760,10 @@ pub fn trim_start_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
     ///
     /// # Text directionality
     ///
-    /// A string is a sequence of bytes. 'Right' in this context means the last
-    /// position of that byte string; for a language like Arabic or Hebrew
-    /// which are 'right to left' rather than 'left to right', this will be
-    /// the _left_ side, not the right.
+    /// A string is a sequence of bytes. `end` in this context means the last
+    /// position of that byte string; for a left-to-right language like English or
+    /// Russian, this will be right side, and for right-to-left languages like
+    /// like Arabic or Hebrew, this will be the left side.
     ///
     /// # Examples
     ///
@@ -3804,10 +3809,10 @@ pub fn trim_end_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
     ///
     /// # Text directionality
     ///
-    /// A string is a sequence of bytes. `start` in this context means the first
-    /// position of that byte string; for a left-to-right language like English or
-    /// Russian, this will be left side, and for right-to-left languages like
-    /// like Arabic or Hebrew, this will be the right side.
+    /// A string is a sequence of bytes. 'Left' in this context means the first
+    /// position of that byte string; for a language like Arabic or Hebrew
+    /// which are 'right to left' rather than 'left to right', this will be
+    /// the _right_ side, not the left.
     ///
     /// # Examples
     ///
@@ -3840,10 +3845,10 @@ pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
     ///
     /// # Text directionality
     ///
-    /// A string is a sequence of bytes. `end` in this context means the last
-    /// position of that byte string; for a left-to-right language like English or
-    /// Russian, this will be right side, and for right-to-left languages like
-    /// like Arabic or Hebrew, this will be the left side.
+    /// A string is a sequence of bytes. 'Right' in this context means the last
+    /// position of that byte string; for a language like Arabic or Hebrew
+    /// which are 'right to left' rather than 'left to right', this will be
+    /// the _left_ side, not the right.
     ///
     /// # Examples
     ///
@@ -4241,6 +4246,11 @@ fn next(&mut self) -> Option<&'a str> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a str> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "split_whitespace", since = "1.1.0")]
@@ -4267,6 +4277,11 @@ fn next(&mut self) -> Option<&'a str> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a str> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
index ec98e0464c9e62c3da991b27e04f21852434dbf8..439ed0c81c8b66e5fdda531c4c9c089b2041185b 100644 (file)
@@ -151,7 +151,7 @@ macro_rules! assert_none {
                            stringify!($what), b);
                 }
             }
-        )*
+        )+
     }};
     ($what:ident, $($str:tt),+,) => (assert_none!($what,$($str),+))
 }
index df1deeaeb97b789c84387f2f69a9d26e06183d31..d86e21cf40b6e7e36da4238066adf742cd887d58 100644 (file)
@@ -3,7 +3,6 @@
 mod num;
 
 #[test]
-#[cfg(not(miri))] // Miri cannot print pointers
 fn test_format_flags() {
     // No residual flags left by pointer formatting
     let p = "".as_ptr();
@@ -13,7 +12,6 @@ fn test_format_flags() {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot print pointers
 fn test_pointer_formats_data_pointer() {
     let b: &[u8] = b"";
     let s: &str = "";
index b78ed0210770f6b71c319f5dc27a5636505b7ede..06c3a78c1698ac831d548abc54fb3a1057ea4e52 100644 (file)
@@ -5,7 +5,7 @@
 macro_rules! search_asserts {
     ($haystack:expr, $needle:expr, $testname:expr, [$($func:ident),*], $result:expr) => {
         let mut searcher = $needle.into_searcher($haystack);
-        let arr = [$( Step::from(searcher.$func()) ),+];
+        let arr = [$( Step::from(searcher.$func()) ),*];
         assert_eq!(&arr[..], &$result, $testname);
     }
 }
index 03fe1fe5a7cf8df93c5c3531c100a65efaa47753..569b3197d09bd64576d7b3fcac10a619071a09c5 100644 (file)
@@ -253,7 +253,6 @@ fn test_unsized_nonnull() {
 
 #[test]
 #[allow(warnings)]
-#[cfg(not(miri))] // Miri cannot hash pointers
 // Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the
 // ABI, or even point to an actual executable code, because the function itself is never invoked.
 #[no_mangle]
@@ -293,7 +292,7 @@ fn drop(&mut self) {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation
+#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
 fn align_offset_zst() {
     // For pointers of stride = 0, the pointer is already aligned or it cannot be aligned at
     // all, because no amount of elements will align the pointer.
@@ -308,7 +307,7 @@ fn align_offset_zst() {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation
+#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
 fn align_offset_stride1() {
     // For pointers of stride = 1, the pointer can always be aligned. The offset is equal to
     // number of bytes.
index 03e65d2fe0b81022ec341bdcfb4f89a54c9af5b1..42ec9d451f7901dfbb9aeb00ebcb6d083b595290 100644 (file)
@@ -275,6 +275,25 @@ fn test_chunks_exact_nth() {
     assert_eq!(c2.next(), None);
 }
 
+#[test]
+fn test_chunks_exact_nth_back() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    let mut c = v.chunks_exact(2);
+    assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
+    assert_eq!(c.next().unwrap(), &[0, 1]);
+    assert_eq!(c.next(), None);
+
+    let v2: &[i32] = &[0, 1, 2, 3, 4];
+    let mut c2 = v2.chunks_exact(3);
+    assert_eq!(c2.nth_back(0).unwrap(), &[0, 1, 2]);
+    assert_eq!(c2.next(), None);
+    assert_eq!(c2.next_back(), None);
+
+    let v3: &[i32] = &[0, 1, 2, 3, 4];
+    let mut c3 = v3.chunks_exact(10);
+    assert_eq!(c3.nth_back(0), None);
+}
+
 #[test]
 fn test_chunks_exact_last() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5];
@@ -1396,7 +1415,7 @@ fn each_alignment_reversed() {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation
+#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
 fn test_align_to_simple() {
     let bytes = [1u8, 2, 3, 4, 5, 6, 7];
     let (prefix, aligned, suffix) = unsafe { bytes.align_to::<u16>() };
@@ -1420,7 +1439,7 @@ fn test_align_to_zst() {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation
+#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
 fn test_align_to_non_trivial() {
     #[repr(align(8))] struct U64(u64, u64);
     #[repr(align(8))] struct U64U64U32(u64, u64, u32);
index f6e9143dd0583e2dd2e9f9e2195d7acbe3c2dea6..39f130b82ed83177cc1a2332ec50f0c12f1634a4 100644 (file)
@@ -9,7 +9,6 @@
        test(attr(deny(warnings))))]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #![feature(nll)]
index 0d8cc552d61ab3cdbd86ec1d39f1d6527ddb3aa9..a51e3a9a33d7b542cd823fdbc315bb1ec76e10b2 100644 (file)
@@ -78,7 +78,7 @@ pub(super) fn clear(&mut self) {
     }
 
     pub(super) fn take(&mut self) -> Self {
-        mem::replace(self, Self::default())
+        mem::take(self)
     }
 
     pub(super) fn extend_from_slice(&mut self, xs: &[T]) {
index 6f7965095b638504873c644ccc7a6804234cd6e4..89fb707001589339874dbf48609ffd63ebeef200 100644 (file)
@@ -74,7 +74,7 @@ fn drop(&mut self) {
     }
 
     /// Sets the value in `self` to `value` while running `f`.
-    pub fn set<'a, R>(&self, value: <T as ApplyL<'a>>::Out, f: impl FnOnce() -> R) -> R {
+    pub fn set<R>(&self, value: <T as ApplyL<'_>>::Out, f: impl FnOnce() -> R) -> R {
         self.replace(value, |_| f())
     }
 }
index 1e0f1ed578aaed4a99016f92b92bf0ba1e377aeb..2c097238b95b24801d6590aa4b60221699bb5cb4 100644 (file)
@@ -25,6 +25,7 @@
 #![feature(extern_types)]
 #![feature(in_band_lifetimes)]
 #![feature(optin_builtin_traits)]
+#![feature(mem_take)]
 #![feature(non_exhaustive)]
 #![feature(specialization)]
 
index a7750edbb6f485f77d89bcc1a463f0c90abba14b..a132575b0c673b8b35848e0a2a29871e55f2009e 100644 (file)
@@ -1,11 +1,11 @@
 use crate::cfg::*;
 use crate::middle::region;
 use rustc_data_structures::graph::implementation as graph;
-use syntax::ptr::P;
 use crate::ty::{self, TyCtxt};
 
 use crate::hir::{self, PatKind};
 use crate::hir::def_id::DefId;
+use crate::hir::ptr::P;
 
 struct CFGBuilder<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -30,7 +30,7 @@ struct LoopScope {
     break_index: CFGIndex,    // where to go on a `break`
 }
 
-pub fn construct<'tcx>(tcx: TyCtxt<'tcx>, body: &hir::Body) -> CFG {
+pub fn construct(tcx: TyCtxt<'_>, body: &hir::Body) -> CFG {
     let mut graph = graph::Graph::new();
     let entry = graph.add_node(CFGNodeData::Entry);
 
index db168d99a08016cad54d0f750ef25d360dc9b520..88fc7fbfad51ff7692481533906bf8bf6c03d03a 100644 (file)
@@ -49,7 +49,7 @@ pub struct CFGEdgeData {
 pub type CFGEdge = graph::Edge<CFGEdgeData>;
 
 impl CFG {
-    pub fn new<'tcx>(tcx: TyCtxt<'tcx>, body: &hir::Body) -> CFG {
+    pub fn new(tcx: TyCtxt<'_>, body: &hir::Body) -> CFG {
         construct::construct(tcx, body)
     }
 
index 94b832bea628ef915287bb3e293191aa27764173..ee22d0b755a097565df5b53cc4db22c2e5da4922 100644 (file)
@@ -55,7 +55,7 @@ impl<M: DepTrackingMapConfig> MemoizationMap for RefCell<DepTrackingMap<M>> {
     ///
     /// ```
     /// fn type_of_item(..., item: &hir::Item) -> Ty<'tcx> {
-    ///     let item_def_id = ccx.tcx.hir().local_def_id(it.id);
+    ///     let item_def_id = ccx.tcx.hir().local_def_id(it.hir_id);
     ///     ccx.tcx.item_types.memoized(item_def_id, || {
     ///         ccx.tcx.dep_graph.read(DepNode::Hir(item_def_id)); // (*)
     ///         compute_type_of_item(ccx, item)
index 93c22c3e713c0a8e8a0cab7df467f9a3be322f62..b8c6c1e3723826a19e070d0bc8c1e254d101da7e 100644 (file)
@@ -841,7 +841,7 @@ pub fn is_green(&self, dep_node: &DepNode) -> bool {
     //
     // This method will only load queries that will end up in the disk cache.
     // Other queries will not be executed.
-    pub fn exec_cache_promotions<'tcx>(&self, tcx: TyCtxt<'tcx>) {
+    pub fn exec_cache_promotions(&self, tcx: TyCtxt<'_>) {
         let data = self.data.as_ref().unwrap();
         for prev_index in data.colors.values.indices() {
             match data.colors.get(prev_index) {
index 4b84d56858cca6afbfa1cf0f759c2b7a1ff1ca39..316ca6424731ce40deda23438bfc2743f58b271a 100644 (file)
@@ -95,7 +95,7 @@ impl CheckAttrVisitor<'tcx> {
     /// Checks any attribute.
     fn check_attributes(&self, item: &hir::Item, target: Target) {
         if target == Target::Fn || target == Target::Const {
-            self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id_from_hir_id(item.hir_id));
+            self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id(item.hir_id));
         } else if let Some(a) = item.attrs.iter().find(|a| a.check_name(sym::target_feature)) {
             self.tcx.sess.struct_span_err(a.span, "attribute should be applied to a function")
                 .span_label(item.span, "not a function")
@@ -347,7 +347,7 @@ fn is_c_like_enum(item: &hir::Item) -> bool {
     }
 }
 
-fn check_mod_attrs<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
+fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: DefId) {
     tcx.hir().visit_item_likes_in_module(
         module_def_id,
         &mut CheckAttrVisitor { tcx }.as_deep_visitor()
index 9c4a208f0f9fc92fb4e193ab508918d06097b3ae..ef05b57fb8f7dd7d23abe0889ddae10796107080 100644 (file)
@@ -39,6 +39,7 @@
 use crate::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
 use crate::hir::def::{Res, DefKind, PartialRes, PerNS};
 use crate::hir::{GenericArg, ConstArg};
+use crate::hir::ptr::P;
 use crate::lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
                     ELIDED_LIFETIMES_IN_PATHS};
 use crate::middle::cstore::CrateStore;
@@ -61,7 +62,6 @@
 use syntax::errors;
 use syntax::ext::hygiene::{Mark, SyntaxContext};
 use syntax::print::pprust;
-use syntax::ptr::P;
 use syntax::source_map::{self, respan, ExpnInfo, CompilerDesugaringKind, Spanned};
 use syntax::source_map::CompilerDesugaringKind::IfTemporary;
 use syntax::std_inject;
@@ -1111,7 +1111,7 @@ fn add_in_band_defs<F, T>(
             },
         );
 
-        lowered_generics.params = lowered_generics
+        let mut lowered_params: Vec<_> = lowered_generics
             .params
             .into_iter()
             .chain(in_band_defs)
@@ -1121,7 +1121,7 @@ fn add_in_band_defs<F, T>(
         // unsorted generic parameters at the moment, so we make sure
         // that they're ordered correctly here for now. (When we chain
         // the `in_band_defs`, we might make the order unsorted.)
-        lowered_generics.params.sort_by_key(|param| {
+        lowered_params.sort_by_key(|param| {
             match param.kind {
                 hir::GenericParamKind::Lifetime { .. } => ParamKindOrd::Lifetime,
                 hir::GenericParamKind::Type { .. } => ParamKindOrd::Type,
@@ -1129,6 +1129,8 @@ fn add_in_band_defs<F, T>(
             }
         });
 
+        lowered_generics.params = lowered_params.into();
+
         (lowered_generics, res)
     }
 
@@ -1155,13 +1157,13 @@ fn make_async_expr(
         &mut self,
         capture_clause: CaptureBy,
         closure_node_id: NodeId,
-        ret_ty: Option<&Ty>,
+        ret_ty: Option<syntax::ptr::P<Ty>>,
         span: Span,
         body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
     ) -> hir::ExprKind {
         let capture_clause = self.lower_capture_clause(capture_clause);
         let output = match ret_ty {
-            Some(ty) => FunctionRetTy::Ty(P(ty.clone())),
+            Some(ty) => FunctionRetTy::Ty(ty),
             None => FunctionRetTy::Default(span),
         };
         let ast_decl = FnDecl {
@@ -1278,8 +1280,8 @@ fn with_new_scopes<T, F>(&mut self, f: F) -> T
         let was_in_loop_condition = self.is_in_loop_condition;
         self.is_in_loop_condition = false;
 
-        let catch_scopes = mem::replace(&mut self.catch_scopes, Vec::new());
-        let loop_scopes = mem::replace(&mut self.loop_scopes, Vec::new());
+        let catch_scopes = mem::take(&mut self.catch_scopes);
+        let loop_scopes = mem::take(&mut self.loop_scopes);
         let ret = f(self);
         self.catch_scopes = catch_scopes;
         self.loop_scopes = loop_scopes;
@@ -2725,7 +2727,7 @@ fn lower_async_fn_output_type_to_future_bound(
 
         // ::std::future::Future<future_params>
         let future_path =
-            self.std_path(span, &[sym::future, sym::Future], Some(future_params), false);
+            P(self.std_path(span, &[sym::future, sym::Future], Some(future_params), false));
 
         hir::GenericBound::Trait(
             hir::PolyTraitRef {
@@ -3094,7 +3096,7 @@ fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
 
     fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext<'_>) -> hir::TraitRef {
         let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
-            hir::QPath::Resolved(None, path) => path.and_then(|path| path),
+            hir::QPath::Resolved(None, path) => path,
             qpath => bug!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
         };
         hir::TraitRef {
@@ -3620,7 +3622,7 @@ fn lower_use_tree(
                             hir::Item {
                                 hir_id: new_id,
                                 ident,
-                                attrs: attrs.clone(),
+                                attrs: attrs.into_iter().cloned().collect(),
                                 node: item,
                                 vis,
                                 span,
@@ -3705,7 +3707,7 @@ fn lower_use_tree(
                             hir::Item {
                                 hir_id: new_hir_id,
                                 ident,
-                                attrs: attrs.clone(),
+                                attrs: attrs.into_iter().cloned().collect(),
                                 node: item,
                                 vis,
                                 span: use_tree.span,
@@ -4567,7 +4569,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                         // `|x: u8| future_from_generator(|| -> X { ... })`.
                         let body_id = this.lower_fn_body(&outer_decl, |this| {
                             let async_ret_ty = if let FunctionRetTy::Ty(ty) = &decl.output {
-                                Some(&**ty)
+                                Some(ty.clone())
                             } else { None };
                             let async_body = this.make_async_expr(
                                 capture_clause, closure_id, async_ret_ty, body.span,
@@ -5577,7 +5579,7 @@ fn ty_path(&mut self, mut hir_id: hir::HirId, span: Span, qpath: hir::QPath) ->
                         let principal = hir::PolyTraitRef {
                             bound_generic_params: hir::HirVec::new(),
                             trait_ref: hir::TraitRef {
-                                path: path.and_then(|path| path),
+                                path,
                                 hir_ref_id: hir_id,
                             },
                             span,
index b4bda36bc8a279036c60ddb10bdbf8c299695ad2..9e7898e10b0112f7c4a584710037e6a56fb2108c 100644 (file)
@@ -371,7 +371,6 @@ pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
         None
     }
 
-    // FIXME(@ljedrz): replace the NodeId variant
     #[inline]
     pub fn as_local_hir_id(&self, def_id: DefId) -> Option<hir::HirId> {
         if def_id.krate == LOCAL_CRATE {
index 60465c04ec62fec2edf925245384d55c08e0c7ab..889659382d060ac5c02b33845389eeae6c4d2412 100644 (file)
@@ -4,13 +4,14 @@
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::{Lock, ParallelIterator, par_iter};
 
-pub fn check_crate<'hir>(hir_map: &hir::map::Map<'hir>) {
+pub fn check_crate(hir_map: &hir::map::Map<'_>) {
     hir_map.dep_graph.assert_ignored();
 
     let errors = Lock::new(Vec::new());
 
     par_iter(&hir_map.krate().modules).for_each(|(module_id, _)| {
-        hir_map.visit_item_likes_in_module(hir_map.local_def_id(*module_id), &mut OuterVisitor {
+        let local_def_id = hir_map.local_def_id_from_node_id(*module_id);
+        hir_map.visit_item_likes_in_module(local_def_id, &mut OuterVisitor {
             hir_map,
             errors: &errors,
         });
@@ -79,7 +80,7 @@ fn check<F: FnOnce(&mut HirIdValidator<'a, 'hir>)>(&mut self,
                                                        hir_id: HirId,
                                                        walk: F) {
         assert!(self.owner_def_index.is_none());
-        let owner_def_index = self.hir_map.local_def_id_from_hir_id(hir_id).index;
+        let owner_def_index = self.hir_map.local_def_id(hir_id).index;
         self.owner_def_index = Some(owner_def_index);
         walk(self);
 
index 3d591c9a1c6bdafb28167b0c04587c4abdc44226..79b343ecfe29a4c1dd68dae3841f4cfea0092661 100644 (file)
@@ -25,7 +25,6 @@
 use crate::util::nodemap::FxHashMap;
 use crate::util::common::time;
 
-use std::io;
 use std::result::Result::Err;
 use crate::ty::query::Providers;
 
@@ -147,7 +146,7 @@ pub fn new(krate: Crate, dep_graph: &DepGraph) -> Forest {
         }
     }
 
-    pub fn krate<'hir>(&'hir self) -> &'hir Crate {
+    pub fn krate(&self) -> &Crate {
         self.dep_graph.read(DepNode::new_no_params(DepKind::Krate));
         &self.krate
     }
@@ -155,7 +154,7 @@ pub fn krate<'hir>(&'hir self) -> &'hir Crate {
     /// This is used internally in the dependency tracking system.
     /// Use the `krate` method to ensure your dependency on the
     /// crate is tracked.
-    pub fn untracked_krate<'hir>(&'hir self) -> &'hir Crate {
+    pub fn untracked_krate(&self) -> &Crate {
         &self.krate
     }
 }
@@ -220,7 +219,7 @@ pub fn def_key(&self, def_id: DefId) -> DefKey {
     }
 
     pub fn def_path_from_hir_id(&self, id: HirId) -> Option<DefPath> {
-        self.opt_local_def_id_from_hir_id(id).map(|def_id| {
+        self.opt_local_def_id(id).map(|def_id| {
             self.def_path(def_id)
         })
     }
@@ -231,32 +230,30 @@ pub fn def_path(&self, def_id: DefId) -> DefPath {
     }
 
     #[inline]
-    pub fn local_def_id(&self, node: NodeId) -> DefId {
-        self.opt_local_def_id(node).unwrap_or_else(|| {
+    pub fn local_def_id_from_node_id(&self, node: NodeId) -> DefId {
+        self.opt_local_def_id_from_node_id(node).unwrap_or_else(|| {
             let hir_id = self.node_to_hir_id(node);
-            bug!("local_def_id: no entry for `{}`, which has a map of `{:?}`",
+            bug!("local_def_id_from_node_id: no entry for `{}`, which has a map of `{:?}`",
                  node, self.find_entry(hir_id))
         })
     }
 
-    // FIXME(@ljedrz): replace the `NodeId` variant.
     #[inline]
-    pub fn local_def_id_from_hir_id(&self, hir_id: HirId) -> DefId {
-        self.opt_local_def_id_from_hir_id(hir_id).unwrap_or_else(|| {
-            bug!("local_def_id_from_hir_id: no entry for `{:?}`, which has a map of `{:?}`",
+    pub fn local_def_id(&self, hir_id: HirId) -> DefId {
+        self.opt_local_def_id(hir_id).unwrap_or_else(|| {
+            bug!("local_def_id: no entry for `{:?}`, which has a map of `{:?}`",
                  hir_id, self.find_entry(hir_id))
         })
     }
 
-    // FIXME(@ljedrz): replace the `NodeId` variant.
     #[inline]
-    pub fn opt_local_def_id_from_hir_id(&self, hir_id: HirId) -> Option<DefId> {
+    pub fn opt_local_def_id(&self, hir_id: HirId) -> Option<DefId> {
         let node_id = self.hir_to_node_id(hir_id);
         self.definitions.opt_local_def_id(node_id)
     }
 
     #[inline]
-    pub fn opt_local_def_id(&self, node: NodeId) -> Option<DefId> {
+    pub fn opt_local_def_id_from_node_id(&self, node: NodeId) -> Option<DefId> {
         self.definitions.opt_local_def_id(node)
     }
 
@@ -265,7 +262,6 @@ pub fn as_local_node_id(&self, def_id: DefId) -> Option<NodeId> {
         self.definitions.as_local_node_id(def_id)
     }
 
-    // FIXME(@ljedrz): replace the `NodeId` variant.
     #[inline]
     pub fn as_local_hir_id(&self, def_id: DefId) -> Option<HirId> {
         self.definitions.as_local_hir_id(def_id)
@@ -430,7 +426,7 @@ pub fn body_owner(&self, BodyId { hir_id }: BodyId) -> HirId {
     }
 
     pub fn body_owner_def_id(&self, id: BodyId) -> DefId {
-        self.local_def_id_from_hir_id(self.body_owner(id))
+        self.local_def_id(self.body_owner(id))
     }
 
     /// Given a `HirId`, returns the `BodyId` associated with it,
@@ -766,7 +762,7 @@ pub fn get_parent_item(&self, hir_id: HirId) -> HirId {
     /// Returns the `DefId` of `id`'s nearest module parent, or `id` itself if no
     /// module parent is in this map.
     pub fn get_module_parent(&self, id: HirId) -> DefId {
-        self.local_def_id_from_hir_id(self.get_module_parent_node(id))
+        self.local_def_id(self.get_module_parent_node(id))
     }
 
     /// Returns the `HirId` of `id`'s nearest module parent, or `id` itself if no
@@ -842,7 +838,7 @@ pub fn get_defining_scope(&self, id: HirId) -> Option<HirId> {
     }
 
     pub fn get_parent_did(&self, id: HirId) -> DefId {
-        self.local_def_id_from_hir_id(self.get_parent_item(id))
+        self.local_def_id(self.get_parent_item(id))
     }
 
     pub fn get_foreign_abi(&self, hir_id: HirId) -> Abi {
@@ -1085,7 +1081,7 @@ fn suffix_matches(&self, parent: HirId) -> bool {
         // If `id` itself is a mod named `m` with parent `p`, then
         // returns `Some(id, m, p)`.  If `id` has no mod in its parent
         // chain, then returns `None`.
-        fn find_first_mod_parent<'a>(map: &'a Map<'_>, mut id: HirId) -> Option<(HirId, Name)> {
+        fn find_first_mod_parent(map: &Map<'_>, mut id: HirId) -> Option<(HirId, Name)> {
             loop {
                 if let Node::Item(item) = map.find(id)? {
                     if item_is_mod(&item) {
@@ -1187,7 +1183,7 @@ pub fn map_crate<'hir>(sess: &crate::session::Session,
 /// Identical to the `PpAnn` implementation for `hir::Crate`,
 /// except it avoids creating a dependency on the whole crate.
 impl<'hir> print::PpAnn for Map<'hir> {
-    fn nested(&self, state: &mut print::State<'_>, nested: print::Nested) -> io::Result<()> {
+    fn nested(&self, state: &mut print::State<'_>, nested: print::Nested) {
         match nested {
             Nested::Item(id) => state.print_item(self.expect_item(id.id)),
             Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
@@ -1199,7 +1195,7 @@ fn nested(&self, state: &mut print::State<'_>, nested: print::Nested) -> io::Res
 }
 
 impl<'a> print::State<'a> {
-    pub fn print_node(&mut self, node: Node<'_>) -> io::Result<()> {
+    pub fn print_node(&mut self, node: Node<'_>) {
         match node {
             Node::Item(a)         => self.print_item(&a),
             Node::ForeignItem(a)  => self.print_foreign_item(&a),
@@ -1219,9 +1215,9 @@ pub fn print_node(&mut self, node: Node<'_>) -> io::Result<()> {
                 use syntax::print::pprust::PrintState;
 
                 // containing cbox, will be closed by print-block at }
-                self.cbox(print::indent_unit)?;
+                self.cbox(print::indent_unit);
                 // head-ibox, will be closed by print-block after {
-                self.ibox(0)?;
+                self.ibox(0);
                 self.print_block(&a)
             }
             Node::Lifetime(a)     => self.print_lifetime(&a),
@@ -1248,7 +1244,7 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
         // the user-friendly path, otherwise fall back to stringifying DefPath.
         crate::ty::tls::with_opt(|tcx| {
             if let Some(tcx) = tcx {
-                let def_id = map.local_def_id_from_hir_id(id);
+                let def_id = map.local_def_id(id);
                 tcx.def_path_str(def_id)
             } else if let Some(path) = map.def_path_from_hir_id(id) {
                 path.data.into_iter().map(|elem| {
index 6df1c2d8c77e5e3a69e7018622165f61b380196e..bfbd8398f99f33334470bd01fcbf1a0b99d3b77b 100644 (file)
@@ -12,6 +12,7 @@
 
 use crate::hir::def::{Res, DefKind};
 use crate::hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
+use crate::hir::ptr::P;
 use crate::util::nodemap::{NodeMap, FxHashSet};
 use crate::mir::mono::Linkage;
 
@@ -23,7 +24,6 @@
 use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
 use syntax::attr::{InlineAttr, OptimizeAttr};
 use syntax::ext::hygiene::SyntaxContext;
-use syntax::ptr::P;
 use syntax::symbol::{Symbol, kw};
 use syntax::tokenstream::TokenStream;
 use syntax::util::parser::ExprPrecedence;
@@ -63,6 +63,7 @@ macro_rules! hir_vec {
 pub mod map;
 pub mod pat_util;
 pub mod print;
+pub mod ptr;
 pub mod upvars;
 
 /// Uniquely identifies a node in the HIR of the current crate. It is
@@ -1979,13 +1980,15 @@ pub struct InlineAsmOutput {
     pub span: Span,
 }
 
+// NOTE(eddyb) This is used within MIR as well, so unlike the rest of the HIR,
+// it needs to be `Clone` and use plain `Vec<T>` instead of `HirVec<T>`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct InlineAsm {
     pub asm: Symbol,
     pub asm_str_style: StrStyle,
-    pub outputs: HirVec<InlineAsmOutput>,
-    pub inputs: HirVec<Symbol>,
-    pub clobbers: HirVec<Symbol>,
+    pub outputs: Vec<InlineAsmOutput>,
+    pub inputs: Vec<Symbol>,
+    pub clobbers: Vec<Symbol>,
     pub volatile: bool,
     pub alignstack: bool,
     pub dialect: AsmDialect,
@@ -2217,7 +2220,7 @@ pub enum UseKind {
 /// within the resolution map.
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct TraitRef {
-    pub path: Path,
+    pub path: P<Path>,
     // Don't hash the ref_id. It is tracked via the thing it is used to access
     #[stable_hasher(ignore)]
     pub hir_ref_id: HirId,
index 8b1984e04f55b596ad2d73207683aae84690f92b..573b9add133ea40a1358e5e1f9460564a273b7e4 100644 (file)
@@ -6,7 +6,6 @@
 use syntax::print::pp::{self, Breaks};
 use syntax::print::pp::Breaks::{Consistent, Inconsistent};
 use syntax::print::pprust::{self, PrintState};
-use syntax::ptr::P;
 use syntax::symbol::kw;
 use syntax::util::parser::{self, AssocOp, Fixity};
 use syntax_pos::{self, BytePos, FileName};
 use crate::hir;
 use crate::hir::{PatKind, GenericBound, TraitBoundModifier, RangeEnd};
 use crate::hir::{GenericParam, GenericParamKind, GenericArg};
+use crate::hir::ptr::P;
 
 use std::borrow::Cow;
 use std::cell::Cell;
-use std::io::{self, Write, Read};
+use std::io::Read;
 use std::vec;
 
 pub enum AnnNode<'a> {
@@ -38,14 +38,11 @@ pub enum Nested {
 }
 
 pub trait PpAnn {
-    fn nested(&self, _state: &mut State<'_>, _nested: Nested) -> io::Result<()> {
-        Ok(())
+    fn nested(&self, _state: &mut State<'_>, _nested: Nested) {
     }
-    fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) -> io::Result<()> {
-        Ok(())
+    fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {
     }
-    fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) -> io::Result<()> {
-        Ok(())
+    fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {
     }
     fn try_fetch_item(&self, _: hir::HirId) -> Option<&hir::Item> {
         None
@@ -60,7 +57,7 @@ impl PpAnn for hir::Crate {
     fn try_fetch_item(&self, item: hir::HirId) -> Option<&hir::Item> {
         Some(self.item(item))
     }
-    fn nested(&self, state: &mut State<'_>, nested: Nested) -> io::Result<()> {
+    fn nested(&self, state: &mut State<'_>, nested: Nested) {
         match nested {
             Nested::Item(id) => state.print_item(self.item(id.id)),
             Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
@@ -101,10 +98,6 @@ fn cur_cmnt(&mut self) -> &mut usize {
 #[allow(non_upper_case_globals)]
 pub const indent_unit: usize = 4;
 
-#[allow(non_upper_case_globals)]
-pub const default_columns: usize = 78;
-
-
 /// Requires you to pass an input filename and reader so that
 /// it can scan the input text for comments to copy forward.
 pub fn print_crate<'a>(cm: &'a SourceMap,
@@ -112,16 +105,16 @@ pub fn print_crate<'a>(cm: &'a SourceMap,
                        krate: &hir::Crate,
                        filename: FileName,
                        input: &mut dyn Read,
-                       out: Box<dyn Write + 'a>,
+                       out: &'a mut String,
                        ann: &'a dyn PpAnn)
-                       -> io::Result<()> {
+                       {
     let mut s = State::new_from_input(cm, sess, filename, input, out, ann);
 
     // When printing the AST, we sometimes need to inject `#[no_std]` here.
     // Since you can't compile the HIR, it's not necessary.
 
-    s.print_mod(&krate.module, &krate.attrs)?;
-    s.print_remaining_comments()?;
+    s.print_mod(&krate.module, &krate.attrs);
+    s.print_remaining_comments();
     s.s.eof()
 }
 
@@ -130,7 +123,7 @@ pub fn new_from_input(cm: &'a SourceMap,
                           sess: &ParseSess,
                           filename: FileName,
                           input: &mut dyn Read,
-                          out: Box<dyn Write + 'a>,
+                          out: &'a mut String,
                           ann: &'a dyn PpAnn)
                           -> State<'a> {
         let comments = comments::gather_comments(sess, filename, input);
@@ -138,12 +131,12 @@ pub fn new_from_input(cm: &'a SourceMap,
     }
 
     pub fn new(cm: &'a SourceMap,
-               out: Box<dyn Write + 'a>,
+               out: &'a mut String,
                ann: &'a dyn PpAnn,
                comments: Option<Vec<comments::Comment>>)
                -> State<'a> {
         State {
-            s: pp::mk_printer(out, default_columns),
+            s: pp::mk_printer(out),
             cm: Some(cm),
             comments,
             cur_cmnt: 0,
@@ -154,65 +147,64 @@ pub fn new(cm: &'a SourceMap,
 }
 
 pub fn to_string<F>(ann: &dyn PpAnn, f: F) -> String
-    where F: FnOnce(&mut State<'_>) -> io::Result<()>
+    where F: FnOnce(&mut State<'_>)
 {
-    let mut wr = Vec::new();
+    let mut wr = String::new();
     {
         let mut printer = State {
-            s: pp::mk_printer(Box::new(&mut wr), default_columns),
+            s: pp::mk_printer(&mut wr),
             cm: None,
             comments: None,
             cur_cmnt: 0,
             boxes: Vec::new(),
             ann,
         };
-        f(&mut printer).unwrap();
-        printer.s.eof().unwrap();
+        f(&mut printer);
+        printer.s.eof();
     }
-    String::from_utf8(wr).unwrap()
+    wr
 }
 
 pub fn visibility_qualified<S: Into<Cow<'static, str>>>(vis: &hir::Visibility, w: S) -> String {
     to_string(NO_ANN, |s| {
-        s.print_visibility(vis)?;
+        s.print_visibility(vis);
         s.s.word(w)
     })
 }
 
 impl<'a> State<'a> {
-    pub fn cbox(&mut self, u: usize) -> io::Result<()> {
+    pub fn cbox(&mut self, u: usize) {
         self.boxes.push(pp::Breaks::Consistent);
-        self.s.cbox(u)
+        self.s.cbox(u);
     }
 
-    pub fn nbsp(&mut self) -> io::Result<()> {
+    pub fn nbsp(&mut self) {
         self.s.word(" ")
     }
 
-    pub fn word_nbsp<S: Into<Cow<'static, str>>>(&mut self, w: S) -> io::Result<()> {
-        self.s.word(w)?;
+    pub fn word_nbsp<S: Into<Cow<'static, str>>>(&mut self, w: S) {
+        self.s.word(w);
         self.nbsp()
     }
 
-    pub fn head<S: Into<Cow<'static, str>>>(&mut self, w: S) -> io::Result<()> {
+    pub fn head<S: Into<Cow<'static, str>>>(&mut self, w: S) {
         let w = w.into();
         // outer-box is consistent
-        self.cbox(indent_unit)?;
+        self.cbox(indent_unit);
         // head-box is inconsistent
-        self.ibox(w.len() + 1)?;
+        self.ibox(w.len() + 1);
         // keyword that starts the head
         if !w.is_empty() {
-            self.word_nbsp(w)?;
+            self.word_nbsp(w);
         }
-        Ok(())
     }
 
-    pub fn bopen(&mut self) -> io::Result<()> {
-        self.s.word("{")?;
-        self.end() // close the head-box
+    pub fn bopen(&mut self) {
+        self.s.word("{");
+        self.end(); // close the head-box
     }
 
-    pub fn bclose_(&mut self, span: syntax_pos::Span, indented: usize) -> io::Result<()> {
+    pub fn bclose_(&mut self, span: syntax_pos::Span, indented: usize) {
         self.bclose_maybe_open(span, indented, true)
     }
 
@@ -220,17 +212,16 @@ pub fn bclose_maybe_open(&mut self,
                              span: syntax_pos::Span,
                              indented: usize,
                              close_box: bool)
-                             -> io::Result<()> {
-        self.maybe_print_comment(span.hi())?;
-        self.break_offset_if_not_bol(1, -(indented as isize))?;
-        self.s.word("}")?;
+                             {
+        self.maybe_print_comment(span.hi());
+        self.break_offset_if_not_bol(1, -(indented as isize));
+        self.s.word("}");
         if close_box {
-            self.end()?; // close the outer-box
+            self.end(); // close the outer-box
         }
-        Ok(())
     }
 
-    pub fn bclose(&mut self, span: syntax_pos::Span) -> io::Result<()> {
+    pub fn bclose(&mut self, span: syntax_pos::Span) {
         self.bclose_(span, indent_unit)
     }
 
@@ -241,14 +232,13 @@ pub fn in_cbox(&self) -> bool {
         }
     }
 
-    pub fn space_if_not_bol(&mut self) -> io::Result<()> {
+    pub fn space_if_not_bol(&mut self) {
         if !self.is_bol() {
-            self.s.space()?;
+            self.s.space();
         }
-        Ok(())
     }
 
-    pub fn break_offset_if_not_bol(&mut self, n: usize, off: isize) -> io::Result<()> {
+    pub fn break_offset_if_not_bol(&mut self, n: usize, off: isize) {
         if !self.is_bol() {
             self.s.break_offset(n, off)
         } else {
@@ -258,17 +248,16 @@ pub fn break_offset_if_not_bol(&mut self, n: usize, off: isize) -> io::Result<()
                 // break into the previous hardbreak.
                 self.s.replace_last_token(pp::Printer::hardbreak_tok_offset(off));
             }
-            Ok(())
         }
     }
 
     // Synthesizes a comment that was not textually present in the original source
     // file.
-    pub fn synth_comment(&mut self, text: String) -> io::Result<()> {
-        self.s.word("/*")?;
-        self.s.space()?;
-        self.s.word(text)?;
-        self.s.space()?;
+    pub fn synth_comment(&mut self, text: String) {
+        self.s.word("/*");
+        self.s.space();
+        self.s.word(text);
+        self.s.space();
         self.s.word("*/")
     }
 
@@ -277,97 +266,93 @@ pub fn commasep_cmnt<T, F, G>(&mut self,
                                   elts: &[T],
                                   mut op: F,
                                   mut get_span: G)
-                                  -> io::Result<()>
-        where F: FnMut(&mut State<'_>, &T) -> io::Result<()>,
+        where F: FnMut(&mut State<'_>, &T),
               G: FnMut(&T) -> syntax_pos::Span
     {
-        self.rbox(0, b)?;
+        self.rbox(0, b);
         let len = elts.len();
         let mut i = 0;
         for elt in elts {
-            self.maybe_print_comment(get_span(elt).hi())?;
-            op(self, elt)?;
+            self.maybe_print_comment(get_span(elt).hi());
+            op(self, elt);
             i += 1;
             if i < len {
-                self.s.word(",")?;
-                self.maybe_print_trailing_comment(get_span(elt), Some(get_span(&elts[i]).hi()))?;
-                self.space_if_not_bol()?;
+                self.s.word(",");
+                self.maybe_print_trailing_comment(get_span(elt), Some(get_span(&elts[i]).hi()));
+                self.space_if_not_bol();
             }
         }
-        self.end()
+        self.end();
     }
 
-    pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[hir::Expr]) -> io::Result<()> {
+    pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[hir::Expr]) {
         self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&e), |e| e.span)
     }
 
-    pub fn print_mod(&mut self, _mod: &hir::Mod, attrs: &[ast::Attribute]) -> io::Result<()> {
-        self.print_inner_attributes(attrs)?;
+    pub fn print_mod(&mut self, _mod: &hir::Mod, attrs: &[ast::Attribute]) {
+        self.print_inner_attributes(attrs);
         for &item_id in &_mod.item_ids {
-            self.ann.nested(self, Nested::Item(item_id))?;
+            self.ann.nested(self, Nested::Item(item_id));
         }
-        Ok(())
     }
 
     pub fn print_foreign_mod(&mut self,
                              nmod: &hir::ForeignMod,
                              attrs: &[ast::Attribute])
-                             -> io::Result<()> {
-        self.print_inner_attributes(attrs)?;
+                             {
+        self.print_inner_attributes(attrs);
         for item in &nmod.items {
-            self.print_foreign_item(item)?;
+            self.print_foreign_item(item);
         }
-        Ok(())
     }
 
-    pub fn print_opt_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> {
+    pub fn print_opt_lifetime(&mut self, lifetime: &hir::Lifetime) {
         if !lifetime.is_elided() {
-            self.print_lifetime(lifetime)?;
-            self.nbsp()?;
+            self.print_lifetime(lifetime);
+            self.nbsp();
         }
-        Ok(())
     }
 
-    pub fn print_type(&mut self, ty: &hir::Ty) -> io::Result<()> {
-        self.maybe_print_comment(ty.span.lo())?;
-        self.ibox(0)?;
+    pub fn print_type(&mut self, ty: &hir::Ty) {
+        self.maybe_print_comment(ty.span.lo());
+        self.ibox(0);
         match ty.node {
             hir::TyKind::Slice(ref ty) => {
-                self.s.word("[")?;
-                self.print_type(&ty)?;
-                self.s.word("]")?;
+                self.s.word("[");
+                self.print_type(&ty);
+                self.s.word("]");
             }
             hir::TyKind::Ptr(ref mt) => {
-                self.s.word("*")?;
+                self.s.word("*");
                 match mt.mutbl {
-                    hir::MutMutable => self.word_nbsp("mut")?,
-                    hir::MutImmutable => self.word_nbsp("const")?,
+                    hir::MutMutable => self.word_nbsp("mut"),
+                    hir::MutImmutable => self.word_nbsp("const"),
                 }
-                self.print_type(&mt.ty)?;
+                self.print_type(&mt.ty);
             }
             hir::TyKind::Rptr(ref lifetime, ref mt) => {
-                self.s.word("&")?;
-                self.print_opt_lifetime(lifetime)?;
-                self.print_mt(mt)?;
+                self.s.word("&");
+                self.print_opt_lifetime(lifetime);
+                self.print_mt(mt);
             }
             hir::TyKind::Never => {
-                self.s.word("!")?;
+                self.s.word("!");
             },
             hir::TyKind::Tup(ref elts) => {
-                self.popen()?;
-                self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(&ty))?;
+                self.popen();
+                self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(&ty));
                 if elts.len() == 1 {
-                    self.s.word(",")?;
+                    self.s.word(",");
                 }
-                self.pclose()?;
+                self.pclose();
             }
             hir::TyKind::BareFn(ref f) => {
                 self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, &f.generic_params,
-                                 &f.arg_names[..])?;
+                                 &f.arg_names[..]);
             }
             hir::TyKind::Def(..) => {},
             hir::TyKind::Path(ref qpath) => {
-                self.print_qpath(qpath, false)?
+                self.print_qpath(qpath, false)
             }
             hir::TyKind::TraitObject(ref bounds, ref lifetime) => {
                 let mut first = true;
@@ -375,51 +360,51 @@ pub fn print_type(&mut self, ty: &hir::Ty) -> io::Result<()> {
                     if first {
                         first = false;
                     } else {
-                        self.nbsp()?;
-                        self.word_space("+")?;
+                        self.nbsp();
+                        self.word_space("+");
                     }
-                    self.print_poly_trait_ref(bound)?;
+                    self.print_poly_trait_ref(bound);
                 }
                 if !lifetime.is_elided() {
-                    self.nbsp()?;
-                    self.word_space("+")?;
-                    self.print_lifetime(lifetime)?;
+                    self.nbsp();
+                    self.word_space("+");
+                    self.print_lifetime(lifetime);
                 }
             }
             hir::TyKind::Array(ref ty, ref length) => {
-                self.s.word("[")?;
-                self.print_type(&ty)?;
-                self.s.word("; ")?;
-                self.print_anon_const(length)?;
-                self.s.word("]")?;
+                self.s.word("[");
+                self.print_type(&ty);
+                self.s.word("; ");
+                self.print_anon_const(length);
+                self.s.word("]");
             }
             hir::TyKind::Typeof(ref e) => {
-                self.s.word("typeof(")?;
-                self.print_anon_const(e)?;
-                self.s.word(")")?;
+                self.s.word("typeof(");
+                self.print_anon_const(e);
+                self.s.word(")");
             }
             hir::TyKind::Infer => {
-                self.s.word("_")?;
+                self.s.word("_");
             }
             hir::TyKind::Err => {
-                self.popen()?;
-                self.s.word("/*ERROR*/")?;
-                self.pclose()?;
+                self.popen();
+                self.s.word("/*ERROR*/");
+                self.pclose();
             }
             hir::TyKind::CVarArgs(_) => {
-                self.s.word("...")?;
+                self.s.word("...");
             }
         }
         self.end()
     }
 
-    pub fn print_foreign_item(&mut self, item: &hir::ForeignItem) -> io::Result<()> {
-        self.hardbreak_if_not_bol()?;
-        self.maybe_print_comment(item.span.lo())?;
-        self.print_outer_attributes(&item.attrs)?;
+    pub fn print_foreign_item(&mut self, item: &hir::ForeignItem) {
+        self.hardbreak_if_not_bol();
+        self.maybe_print_comment(item.span.lo());
+        self.print_outer_attributes(&item.attrs);
         match item.node {
             hir::ForeignItemKind::Fn(ref decl, ref arg_names, ref generics) => {
-                self.head("")?;
+                self.head("");
                 self.print_fn(decl,
                               hir::FnHeader {
                                   unsafety: hir::Unsafety::Normal,
@@ -431,28 +416,28 @@ pub fn print_foreign_item(&mut self, item: &hir::ForeignItem) -> io::Result<()>
                               generics,
                               &item.vis,
                               arg_names,
-                              None)?;
-                self.end()?; // end head-ibox
-                self.s.word(";")?;
+                              None);
+                self.end(); // end head-ibox
+                self.s.word(";");
                 self.end() // end the outer fn box
             }
             hir::ForeignItemKind::Static(ref t, m) => {
-                self.head(visibility_qualified(&item.vis, "static"))?;
+                self.head(visibility_qualified(&item.vis, "static"));
                 if m == hir::MutMutable {
-                    self.word_space("mut")?;
+                    self.word_space("mut");
                 }
-                self.print_ident(item.ident)?;
-                self.word_space(":")?;
-                self.print_type(&t)?;
-                self.s.word(";")?;
-                self.end()?; // end the head-ibox
+                self.print_ident(item.ident);
+                self.word_space(":");
+                self.print_type(&t);
+                self.s.word(";");
+                self.end(); // end the head-ibox
                 self.end() // end the outer cbox
             }
             hir::ForeignItemKind::Type => {
-                self.head(visibility_qualified(&item.vis, "type"))?;
-                self.print_ident(item.ident)?;
-                self.s.word(";")?;
-                self.end()?; // end the head-ibox
+                self.head(visibility_qualified(&item.vis, "type"));
+                self.print_ident(item.ident);
+                self.s.word(";");
+                self.end(); // end the head-ibox
                 self.end() // end the outer cbox
             }
         }
@@ -463,16 +448,16 @@ fn print_associated_const(&mut self,
                               ty: &hir::Ty,
                               default: Option<hir::BodyId>,
                               vis: &hir::Visibility)
-                              -> io::Result<()> {
-        self.s.word(visibility_qualified(vis, ""))?;
-        self.word_space("const")?;
-        self.print_ident(ident)?;
-        self.word_space(":")?;
-        self.print_type(ty)?;
+                              {
+        self.s.word(visibility_qualified(vis, ""));
+        self.word_space("const");
+        self.print_ident(ident);
+        self.word_space(":");
+        self.print_type(ty);
         if let Some(expr) = default {
-            self.s.space()?;
-            self.word_space("=")?;
-            self.ann.nested(self, Nested::Body(expr))?;
+            self.s.space();
+            self.word_space("=");
+            self.ann.nested(self, Nested::Body(expr));
         }
         self.s.word(";")
     }
@@ -481,168 +466,168 @@ fn print_associated_type(&mut self,
                              ident: ast::Ident,
                              bounds: Option<&hir::GenericBounds>,
                              ty: Option<&hir::Ty>)
-                             -> io::Result<()> {
-        self.word_space("type")?;
-        self.print_ident(ident)?;
+                             {
+        self.word_space("type");
+        self.print_ident(ident);
         if let Some(bounds) = bounds {
-            self.print_bounds(":", bounds)?;
+            self.print_bounds(":", bounds);
         }
         if let Some(ty) = ty {
-            self.s.space()?;
-            self.word_space("=")?;
-            self.print_type(ty)?;
+            self.s.space();
+            self.word_space("=");
+            self.print_type(ty);
         }
         self.s.word(";")
     }
 
     /// Pretty-print an item
-    pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
-        self.hardbreak_if_not_bol()?;
-        self.maybe_print_comment(item.span.lo())?;
-        self.print_outer_attributes(&item.attrs)?;
-        self.ann.pre(self, AnnNode::Item(item))?;
+    pub fn print_item(&mut self, item: &hir::Item) {
+        self.hardbreak_if_not_bol();
+        self.maybe_print_comment(item.span.lo());
+        self.print_outer_attributes(&item.attrs);
+        self.ann.pre(self, AnnNode::Item(item));
         match item.node {
             hir::ItemKind::ExternCrate(orig_name) => {
-                self.head(visibility_qualified(&item.vis, "extern crate"))?;
+                self.head(visibility_qualified(&item.vis, "extern crate"));
                 if let Some(orig_name) = orig_name {
-                    self.print_name(orig_name)?;
-                    self.s.space()?;
-                    self.s.word("as")?;
-                    self.s.space()?;
+                    self.print_name(orig_name);
+                    self.s.space();
+                    self.s.word("as");
+                    self.s.space();
                 }
-                self.print_ident(item.ident)?;
-                self.s.word(";")?;
-                self.end()?; // end inner head-block
-                self.end()?; // end outer head-block
+                self.print_ident(item.ident);
+                self.s.word(";");
+                self.end(); // end inner head-block
+                self.end(); // end outer head-block
             }
             hir::ItemKind::Use(ref path, kind) => {
-                self.head(visibility_qualified(&item.vis, "use"))?;
-                self.print_path(path, false)?;
+                self.head(visibility_qualified(&item.vis, "use"));
+                self.print_path(path, false);
 
                 match kind {
                     hir::UseKind::Single => {
                         if path.segments.last().unwrap().ident != item.ident {
-                            self.s.space()?;
-                            self.word_space("as")?;
-                            self.print_ident(item.ident)?;
+                            self.s.space();
+                            self.word_space("as");
+                            self.print_ident(item.ident);
                         }
-                        self.s.word(";")?;
+                        self.s.word(";");
                     }
-                    hir::UseKind::Glob => self.s.word("::*;")?,
-                    hir::UseKind::ListStem => self.s.word("::{};")?
+                    hir::UseKind::Glob => self.s.word("::*;"),
+                    hir::UseKind::ListStem => self.s.word("::{};")
                 }
-                self.end()?; // end inner head-block
-                self.end()?; // end outer head-block
+                self.end(); // end inner head-block
+                self.end(); // end outer head-block
             }
             hir::ItemKind::Static(ref ty, m, expr) => {
-                self.head(visibility_qualified(&item.vis, "static"))?;
+                self.head(visibility_qualified(&item.vis, "static"));
                 if m == hir::MutMutable {
-                    self.word_space("mut")?;
+                    self.word_space("mut");
                 }
-                self.print_ident(item.ident)?;
-                self.word_space(":")?;
-                self.print_type(&ty)?;
-                self.s.space()?;
-                self.end()?; // end the head-ibox
+                self.print_ident(item.ident);
+                self.word_space(":");
+                self.print_type(&ty);
+                self.s.space();
+                self.end(); // end the head-ibox
 
-                self.word_space("=")?;
-                self.ann.nested(self, Nested::Body(expr))?;
-                self.s.word(";")?;
-                self.end()?; // end the outer cbox
+                self.word_space("=");
+                self.ann.nested(self, Nested::Body(expr));
+                self.s.word(";");
+                self.end(); // end the outer cbox
             }
             hir::ItemKind::Const(ref ty, expr) => {
-                self.head(visibility_qualified(&item.vis, "const"))?;
-                self.print_ident(item.ident)?;
-                self.word_space(":")?;
-                self.print_type(&ty)?;
-                self.s.space()?;
-                self.end()?; // end the head-ibox
-
-                self.word_space("=")?;
-                self.ann.nested(self, Nested::Body(expr))?;
-                self.s.word(";")?;
-                self.end()?; // end the outer cbox
+                self.head(visibility_qualified(&item.vis, "const"));
+                self.print_ident(item.ident);
+                self.word_space(":");
+                self.print_type(&ty);
+                self.s.space();
+                self.end(); // end the head-ibox
+
+                self.word_space("=");
+                self.ann.nested(self, Nested::Body(expr));
+                self.s.word(";");
+                self.end(); // end the outer cbox
             }
             hir::ItemKind::Fn(ref decl, header, ref param_names, body) => {
-                self.head("")?;
+                self.head("");
                 self.print_fn(decl,
                               header,
                               Some(item.ident.name),
                               param_names,
                               &item.vis,
                               &[],
-                              Some(body))?;
-                self.s.word(" ")?;
-                self.end()?; // need to close a box
-                self.end()?; // need to close a box
-                self.ann.nested(self, Nested::Body(body))?;
+                              Some(body));
+                self.s.word(" ");
+                self.end(); // need to close a box
+                self.end(); // need to close a box
+                self.ann.nested(self, Nested::Body(body));
             }
             hir::ItemKind::Mod(ref _mod) => {
-                self.head(visibility_qualified(&item.vis, "mod"))?;
-                self.print_ident(item.ident)?;
-                self.nbsp()?;
-                self.bopen()?;
-                self.print_mod(_mod, &item.attrs)?;
-                self.bclose(item.span)?;
+                self.head(visibility_qualified(&item.vis, "mod"));
+                self.print_ident(item.ident);
+                self.nbsp();
+                self.bopen();
+                self.print_mod(_mod, &item.attrs);
+                self.bclose(item.span);
             }
             hir::ItemKind::ForeignMod(ref nmod) => {
-                self.head("extern")?;
-                self.word_nbsp(nmod.abi.to_string())?;
-                self.bopen()?;
-                self.print_foreign_mod(nmod, &item.attrs)?;
-                self.bclose(item.span)?;
+                self.head("extern");
+                self.word_nbsp(nmod.abi.to_string());
+                self.bopen();
+                self.print_foreign_mod(nmod, &item.attrs);
+                self.bclose(item.span);
             }
             hir::ItemKind::GlobalAsm(ref ga) => {
-                self.head(visibility_qualified(&item.vis, "global asm"))?;
-                self.s.word(ga.asm.as_str().to_string())?;
-                self.end()?
+                self.head(visibility_qualified(&item.vis, "global asm"));
+                self.s.word(ga.asm.as_str().to_string());
+                self.end()
             }
             hir::ItemKind::Ty(ref ty, ref generics) => {
-                self.head(visibility_qualified(&item.vis, "type"))?;
-                self.print_ident(item.ident)?;
-                self.print_generic_params(&generics.params)?;
-                self.end()?; // end the inner ibox
-
-                self.print_where_clause(&generics.where_clause)?;
-                self.s.space()?;
-                self.word_space("=")?;
-                self.print_type(&ty)?;
-                self.s.word(";")?;
-                self.end()?; // end the outer ibox
+                self.head(visibility_qualified(&item.vis, "type"));
+                self.print_ident(item.ident);
+                self.print_generic_params(&generics.params);
+                self.end(); // end the inner ibox
+
+                self.print_where_clause(&generics.where_clause);
+                self.s.space();
+                self.word_space("=");
+                self.print_type(&ty);
+                self.s.word(";");
+                self.end(); // end the outer ibox
             }
             hir::ItemKind::Existential(ref exist) => {
-                self.head(visibility_qualified(&item.vis, "existential type"))?;
-                self.print_ident(item.ident)?;
-                self.print_generic_params(&exist.generics.params)?;
-                self.end()?; // end the inner ibox
+                self.head(visibility_qualified(&item.vis, "existential type"));
+                self.print_ident(item.ident);
+                self.print_generic_params(&exist.generics.params);
+                self.end(); // end the inner ibox
 
-                self.print_where_clause(&exist.generics.where_clause)?;
-                self.s.space()?;
+                self.print_where_clause(&exist.generics.where_clause);
+                self.s.space();
                 let mut real_bounds = Vec::with_capacity(exist.bounds.len());
                 for b in exist.bounds.iter() {
                     if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
-                        self.s.space()?;
-                        self.word_space("for ?")?;
-                        self.print_trait_ref(&ptr.trait_ref)?;
+                        self.s.space();
+                        self.word_space("for ?");
+                        self.print_trait_ref(&ptr.trait_ref);
                     } else {
                         real_bounds.push(b);
                     }
                 }
-                self.print_bounds(":", real_bounds)?;
-                self.s.word(";")?;
-                self.end()?; // end the outer ibox
+                self.print_bounds(":", real_bounds);
+                self.s.word(";");
+                self.end(); // end the outer ibox
             }
             hir::ItemKind::Enum(ref enum_definition, ref params) => {
                 self.print_enum_def(enum_definition, params, item.ident.name, item.span,
-                                    &item.vis)?;
+                                    &item.vis);
             }
             hir::ItemKind::Struct(ref struct_def, ref generics) => {
-                self.head(visibility_qualified(&item.vis, "struct"))?;
-                self.print_struct(struct_def, generics, item.ident.name, item.span, true)?;
+                self.head(visibility_qualified(&item.vis, "struct"));
+                self.print_struct(struct_def, generics, item.ident.name, item.span, true);
             }
             hir::ItemKind::Union(ref struct_def, ref generics) => {
-                self.head(visibility_qualified(&item.vis, "union"))?;
-                self.print_struct(struct_def, generics, item.ident.name, item.span, true)?;
+                self.head(visibility_qualified(&item.vis, "union"));
+                self.print_struct(struct_def, generics, item.ident.name, item.span, true);
             }
             hir::ItemKind::Impl(unsafety,
                           polarity,
@@ -651,109 +636,108 @@ pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
                           ref opt_trait,
                           ref ty,
                           ref impl_items) => {
-                self.head("")?;
-                self.print_visibility(&item.vis)?;
-                self.print_defaultness(defaultness)?;
-                self.print_unsafety(unsafety)?;
-                self.word_nbsp("impl")?;
+                self.head("");
+                self.print_visibility(&item.vis);
+                self.print_defaultness(defaultness);
+                self.print_unsafety(unsafety);
+                self.word_nbsp("impl");
 
                 if !generics.params.is_empty() {
-                    self.print_generic_params(&generics.params)?;
-                    self.s.space()?;
+                    self.print_generic_params(&generics.params);
+                    self.s.space();
                 }
 
                 if let hir::ImplPolarity::Negative = polarity {
-                    self.s.word("!")?;
+                    self.s.word("!");
                 }
 
                 if let Some(ref t) = opt_trait {
-                    self.print_trait_ref(t)?;
-                    self.s.space()?;
-                    self.word_space("for")?;
+                    self.print_trait_ref(t);
+                    self.s.space();
+                    self.word_space("for");
                 }
 
-                self.print_type(&ty)?;
-                self.print_where_clause(&generics.where_clause)?;
+                self.print_type(&ty);
+                self.print_where_clause(&generics.where_clause);
 
-                self.s.space()?;
-                self.bopen()?;
-                self.print_inner_attributes(&item.attrs)?;
+                self.s.space();
+                self.bopen();
+                self.print_inner_attributes(&item.attrs);
                 for impl_item in impl_items {
-                    self.ann.nested(self, Nested::ImplItem(impl_item.id))?;
+                    self.ann.nested(self, Nested::ImplItem(impl_item.id));
                 }
-                self.bclose(item.span)?;
+                self.bclose(item.span);
             }
             hir::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref trait_items) => {
-                self.head("")?;
-                self.print_visibility(&item.vis)?;
-                self.print_is_auto(is_auto)?;
-                self.print_unsafety(unsafety)?;
-                self.word_nbsp("trait")?;
-                self.print_ident(item.ident)?;
-                self.print_generic_params(&generics.params)?;
+                self.head("");
+                self.print_visibility(&item.vis);
+                self.print_is_auto(is_auto);
+                self.print_unsafety(unsafety);
+                self.word_nbsp("trait");
+                self.print_ident(item.ident);
+                self.print_generic_params(&generics.params);
                 let mut real_bounds = Vec::with_capacity(bounds.len());
                 for b in bounds.iter() {
                     if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
-                        self.s.space()?;
-                        self.word_space("for ?")?;
-                        self.print_trait_ref(&ptr.trait_ref)?;
+                        self.s.space();
+                        self.word_space("for ?");
+                        self.print_trait_ref(&ptr.trait_ref);
                     } else {
                         real_bounds.push(b);
                     }
                 }
-                self.print_bounds(":", real_bounds)?;
-                self.print_where_clause(&generics.where_clause)?;
-                self.s.word(" ")?;
-                self.bopen()?;
+                self.print_bounds(":", real_bounds);
+                self.print_where_clause(&generics.where_clause);
+                self.s.word(" ");
+                self.bopen();
                 for trait_item in trait_items {
-                    self.ann.nested(self, Nested::TraitItem(trait_item.id))?;
+                    self.ann.nested(self, Nested::TraitItem(trait_item.id));
                 }
-                self.bclose(item.span)?;
+                self.bclose(item.span);
             }
             hir::ItemKind::TraitAlias(ref generics, ref bounds) => {
-                self.head("")?;
-                self.print_visibility(&item.vis)?;
-                self.word_nbsp("trait")?;
-                self.print_ident(item.ident)?;
-                self.print_generic_params(&generics.params)?;
+                self.head("");
+                self.print_visibility(&item.vis);
+                self.word_nbsp("trait");
+                self.print_ident(item.ident);
+                self.print_generic_params(&generics.params);
                 let mut real_bounds = Vec::with_capacity(bounds.len());
                 // FIXME(durka) this seems to be some quite outdated syntax
                 for b in bounds.iter() {
                     if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
-                        self.s.space()?;
-                        self.word_space("for ?")?;
-                        self.print_trait_ref(&ptr.trait_ref)?;
+                        self.s.space();
+                        self.word_space("for ?");
+                        self.print_trait_ref(&ptr.trait_ref);
                     } else {
                         real_bounds.push(b);
                     }
                 }
-                self.nbsp()?;
-                self.print_bounds("=", real_bounds)?;
-                self.print_where_clause(&generics.where_clause)?;
-                self.s.word(";")?;
+                self.nbsp();
+                self.print_bounds("=", real_bounds);
+                self.print_where_clause(&generics.where_clause);
+                self.s.word(";");
             }
         }
         self.ann.post(self, AnnNode::Item(item))
     }
 
-    pub fn print_trait_ref(&mut self, t: &hir::TraitRef) -> io::Result<()> {
+    pub fn print_trait_ref(&mut self, t: &hir::TraitRef) {
         self.print_path(&t.path, false)
     }
 
     fn print_formal_generic_params(
         &mut self,
         generic_params: &[hir::GenericParam]
-    ) -> io::Result<()> {
+    ) {
         if !generic_params.is_empty() {
-            self.s.word("for")?;
-            self.print_generic_params(generic_params)?;
-            self.nbsp()?;
+            self.s.word("for");
+            self.print_generic_params(generic_params);
+            self.nbsp();
         }
-        Ok(())
     }
 
-    fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef) -> io::Result<()> {
-        self.print_formal_generic_params(&t.bound_generic_params)?;
+    fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef) {
+        self.print_formal_generic_params(&t.bound_generic_params);
         self.print_trait_ref(&t.trait_ref)
     }
 
@@ -763,63 +747,60 @@ pub fn print_enum_def(&mut self,
                           name: ast::Name,
                           span: syntax_pos::Span,
                           visibility: &hir::Visibility)
-                          -> io::Result<()> {
-        self.head(visibility_qualified(visibility, "enum"))?;
-        self.print_name(name)?;
-        self.print_generic_params(&generics.params)?;
-        self.print_where_clause(&generics.where_clause)?;
-        self.s.space()?;
+                          {
+        self.head(visibility_qualified(visibility, "enum"));
+        self.print_name(name);
+        self.print_generic_params(&generics.params);
+        self.print_where_clause(&generics.where_clause);
+        self.s.space();
         self.print_variants(&enum_definition.variants, span)
     }
 
     pub fn print_variants(&mut self,
                           variants: &[hir::Variant],
                           span: syntax_pos::Span)
-                          -> io::Result<()> {
-        self.bopen()?;
+                          {
+        self.bopen();
         for v in variants {
-            self.space_if_not_bol()?;
-            self.maybe_print_comment(v.span.lo())?;
-            self.print_outer_attributes(&v.node.attrs)?;
-            self.ibox(indent_unit)?;
-            self.print_variant(v)?;
-            self.s.word(",")?;
-            self.end()?;
-            self.maybe_print_trailing_comment(v.span, None)?;
+            self.space_if_not_bol();
+            self.maybe_print_comment(v.span.lo());
+            self.print_outer_attributes(&v.node.attrs);
+            self.ibox(indent_unit);
+            self.print_variant(v);
+            self.s.word(",");
+            self.end();
+            self.maybe_print_trailing_comment(v.span, None);
         }
         self.bclose(span)
     }
 
-    pub fn print_visibility(&mut self, vis: &hir::Visibility) -> io::Result<()> {
+    pub fn print_visibility(&mut self, vis: &hir::Visibility) {
         match vis.node {
-            hir::VisibilityKind::Public => self.word_nbsp("pub")?,
-            hir::VisibilityKind::Crate(ast::CrateSugar::JustCrate) => self.word_nbsp("crate")?,
-            hir::VisibilityKind::Crate(ast::CrateSugar::PubCrate) => self.word_nbsp("pub(crate)")?,
+            hir::VisibilityKind::Public => self.word_nbsp("pub"),
+            hir::VisibilityKind::Crate(ast::CrateSugar::JustCrate) => self.word_nbsp("crate"),
+            hir::VisibilityKind::Crate(ast::CrateSugar::PubCrate) => self.word_nbsp("pub(crate)"),
             hir::VisibilityKind::Restricted { ref path, .. } => {
-                self.s.word("pub(")?;
+                self.s.word("pub(");
                 if path.segments.len() == 1 &&
                    path.segments[0].ident.name == kw::Super {
                     // Special case: `super` can print like `pub(super)`.
-                    self.s.word("super")?;
+                    self.s.word("super");
                 } else {
                     // Everything else requires `in` at present.
-                    self.word_nbsp("in")?;
-                    self.print_path(path, false)?;
+                    self.word_nbsp("in");
+                    self.print_path(path, false);
                 }
-                self.word_nbsp(")")?;
+                self.word_nbsp(")");
             }
             hir::VisibilityKind::Inherited => ()
         }
-
-        Ok(())
     }
 
-    pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) -> io::Result<()> {
+    pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) {
         match defaultness {
-            hir::Defaultness::Default { .. } => self.word_nbsp("default")?,
+            hir::Defaultness::Default { .. } => self.word_nbsp("default"),
             hir::Defaultness::Final => (),
         }
-        Ok(())
     }
 
     pub fn print_struct(&mut self,
@@ -828,43 +809,43 @@ pub fn print_struct(&mut self,
                         name: ast::Name,
                         span: syntax_pos::Span,
                         print_finalizer: bool)
-                        -> io::Result<()> {
-        self.print_name(name)?;
-        self.print_generic_params(&generics.params)?;
+                        {
+        self.print_name(name);
+        self.print_generic_params(&generics.params);
         match struct_def {
             hir::VariantData::Tuple(..) | hir::VariantData::Unit(..) => {
                 if let hir::VariantData::Tuple(..) = struct_def {
-                    self.popen()?;
+                    self.popen();
                     self.commasep(Inconsistent, struct_def.fields(), |s, field| {
-                        s.maybe_print_comment(field.span.lo())?;
-                        s.print_outer_attributes(&field.attrs)?;
-                        s.print_visibility(&field.vis)?;
+                        s.maybe_print_comment(field.span.lo());
+                        s.print_outer_attributes(&field.attrs);
+                        s.print_visibility(&field.vis);
                         s.print_type(&field.ty)
-                    })?;
-                    self.pclose()?;
+                    });
+                    self.pclose();
                 }
-                self.print_where_clause(&generics.where_clause)?;
+                self.print_where_clause(&generics.where_clause);
                 if print_finalizer {
-                    self.s.word(";")?;
+                    self.s.word(";");
                 }
-                self.end()?;
+                self.end();
                 self.end() // close the outer-box
             }
             hir::VariantData::Struct(..) => {
-                self.print_where_clause(&generics.where_clause)?;
-                self.nbsp()?;
-                self.bopen()?;
-                self.hardbreak_if_not_bol()?;
+                self.print_where_clause(&generics.where_clause);
+                self.nbsp();
+                self.bopen();
+                self.hardbreak_if_not_bol();
 
                 for field in struct_def.fields() {
-                    self.hardbreak_if_not_bol()?;
-                    self.maybe_print_comment(field.span.lo())?;
-                    self.print_outer_attributes(&field.attrs)?;
-                    self.print_visibility(&field.vis)?;
-                    self.print_ident(field.ident)?;
-                    self.word_nbsp(":")?;
-                    self.print_type(&field.ty)?;
-                    self.s.word(",")?;
+                    self.hardbreak_if_not_bol();
+                    self.maybe_print_comment(field.span.lo());
+                    self.print_outer_attributes(&field.attrs);
+                    self.print_visibility(&field.vis);
+                    self.print_ident(field.ident);
+                    self.word_nbsp(":");
+                    self.print_type(&field.ty);
+                    self.s.word(",");
                 }
 
                 self.bclose(span)
@@ -872,16 +853,15 @@ pub fn print_struct(&mut self,
         }
     }
 
-    pub fn print_variant(&mut self, v: &hir::Variant) -> io::Result<()> {
-        self.head("")?;
+    pub fn print_variant(&mut self, v: &hir::Variant) {
+        self.head("");
         let generics = hir::Generics::empty();
-        self.print_struct(&v.node.data, &generics, v.node.ident.name, v.span, false)?;
+        self.print_struct(&v.node.data, &generics, v.node.ident.name, v.span, false);
         if let Some(ref d) = v.node.disr_expr {
-            self.s.space()?;
-            self.word_space("=")?;
-            self.print_anon_const(d)?;
+            self.s.space();
+            self.word_space("=");
+            self.print_anon_const(d);
         }
-        Ok(())
     }
     pub fn print_method_sig(&mut self,
                             ident: ast::Ident,
@@ -890,7 +870,7 @@ pub fn print_method_sig(&mut self,
                             vis: &hir::Visibility,
                             arg_names: &[ast::Ident],
                             body_id: Option<hir::BodyId>)
-                            -> io::Result<()> {
+                            {
         self.print_fn(&m.decl,
                       m.header,
                       Some(ident.name),
@@ -900,67 +880,67 @@ pub fn print_method_sig(&mut self,
                       body_id)
     }
 
-    pub fn print_trait_item(&mut self, ti: &hir::TraitItem) -> io::Result<()> {
-        self.ann.pre(self, AnnNode::SubItem(ti.hir_id))?;
-        self.hardbreak_if_not_bol()?;
-        self.maybe_print_comment(ti.span.lo())?;
-        self.print_outer_attributes(&ti.attrs)?;
+    pub fn print_trait_item(&mut self, ti: &hir::TraitItem) {
+        self.ann.pre(self, AnnNode::SubItem(ti.hir_id));
+        self.hardbreak_if_not_bol();
+        self.maybe_print_comment(ti.span.lo());
+        self.print_outer_attributes(&ti.attrs);
         match ti.node {
             hir::TraitItemKind::Const(ref ty, default) => {
                 let vis = Spanned { span: syntax_pos::DUMMY_SP,
                                     node: hir::VisibilityKind::Inherited };
-                self.print_associated_const(ti.ident, &ty, default, &vis)?;
+                self.print_associated_const(ti.ident, &ty, default, &vis);
             }
             hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref arg_names)) => {
                 let vis = Spanned { span: syntax_pos::DUMMY_SP,
                                     node: hir::VisibilityKind::Inherited };
-                self.print_method_sig(ti.ident, sig, &ti.generics, &vis, arg_names, None)?;
-                self.s.word(";")?;
+                self.print_method_sig(ti.ident, sig, &ti.generics, &vis, arg_names, None);
+                self.s.word(";");
             }
             hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
                 let vis = Spanned { span: syntax_pos::DUMMY_SP,
                                     node: hir::VisibilityKind::Inherited };
-                self.head("")?;
-                self.print_method_sig(ti.ident, sig, &ti.generics, &vis, &[], Some(body))?;
-                self.nbsp()?;
-                self.end()?; // need to close a box
-                self.end()?; // need to close a box
-                self.ann.nested(self, Nested::Body(body))?;
+                self.head("");
+                self.print_method_sig(ti.ident, sig, &ti.generics, &vis, &[], Some(body));
+                self.nbsp();
+                self.end(); // need to close a box
+                self.end(); // need to close a box
+                self.ann.nested(self, Nested::Body(body));
             }
             hir::TraitItemKind::Type(ref bounds, ref default) => {
                 self.print_associated_type(ti.ident,
                                            Some(bounds),
-                                           default.as_ref().map(|ty| &**ty))?;
+                                           default.as_ref().map(|ty| &**ty));
             }
         }
         self.ann.post(self, AnnNode::SubItem(ti.hir_id))
     }
 
-    pub fn print_impl_item(&mut self, ii: &hir::ImplItem) -> io::Result<()> {
-        self.ann.pre(self, AnnNode::SubItem(ii.hir_id))?;
-        self.hardbreak_if_not_bol()?;
-        self.maybe_print_comment(ii.span.lo())?;
-        self.print_outer_attributes(&ii.attrs)?;
-        self.print_defaultness(ii.defaultness)?;
+    pub fn print_impl_item(&mut self, ii: &hir::ImplItem) {
+        self.ann.pre(self, AnnNode::SubItem(ii.hir_id));
+        self.hardbreak_if_not_bol();
+        self.maybe_print_comment(ii.span.lo());
+        self.print_outer_attributes(&ii.attrs);
+        self.print_defaultness(ii.defaultness);
 
         match ii.node {
             hir::ImplItemKind::Const(ref ty, expr) => {
-                self.print_associated_const(ii.ident, &ty, Some(expr), &ii.vis)?;
+                self.print_associated_const(ii.ident, &ty, Some(expr), &ii.vis);
             }
             hir::ImplItemKind::Method(ref sig, body) => {
-                self.head("")?;
-                self.print_method_sig(ii.ident, sig, &ii.generics, &ii.vis, &[], Some(body))?;
-                self.nbsp()?;
-                self.end()?; // need to close a box
-                self.end()?; // need to close a box
-                self.ann.nested(self, Nested::Body(body))?;
+                self.head("");
+                self.print_method_sig(ii.ident, sig, &ii.generics, &ii.vis, &[], Some(body));
+                self.nbsp();
+                self.end(); // need to close a box
+                self.end(); // need to close a box
+                self.ann.nested(self, Nested::Body(body));
             }
             hir::ImplItemKind::Type(ref ty) => {
-                self.print_associated_type(ii.ident, None, Some(ty))?;
+                self.print_associated_type(ii.ident, None, Some(ty));
             }
             hir::ImplItemKind::Existential(ref bounds) => {
-                self.word_space("existential")?;
-                self.print_associated_type(ii.ident, Some(bounds), None)?;
+                self.word_space("existential");
+                self.print_associated_type(ii.ident, Some(bounds), None);
             }
         }
         self.ann.post(self, AnnNode::SubItem(ii.hir_id))
@@ -969,68 +949,68 @@ pub fn print_impl_item(&mut self, ii: &hir::ImplItem) -> io::Result<()> {
     pub fn print_local(
         &mut self,
         init: Option<&hir::Expr>,
-        decl: impl Fn(&mut Self) -> io::Result<()>
-    ) -> io::Result<()> {
-        self.space_if_not_bol()?;
-        self.ibox(indent_unit)?;
-        self.word_nbsp("let")?;
+        decl: impl Fn(&mut Self)
+    ) {
+        self.space_if_not_bol();
+        self.ibox(indent_unit);
+        self.word_nbsp("let");
 
-        self.ibox(indent_unit)?;
-        decl(self)?;
-        self.end()?;
+        self.ibox(indent_unit);
+        decl(self);
+        self.end();
 
         if let Some(ref init) = init {
-            self.nbsp()?;
-            self.word_space("=")?;
-            self.print_expr(&init)?;
+            self.nbsp();
+            self.word_space("=");
+            self.print_expr(&init);
         }
         self.end()
     }
 
-    pub fn print_stmt(&mut self, st: &hir::Stmt) -> io::Result<()> {
-        self.maybe_print_comment(st.span.lo())?;
+    pub fn print_stmt(&mut self, st: &hir::Stmt) {
+        self.maybe_print_comment(st.span.lo());
         match st.node {
             hir::StmtKind::Local(ref loc) => {
-                self.print_local(loc.init.deref(), |this| this.print_local_decl(&loc))?;
+                self.print_local(loc.init.deref(), |this| this.print_local_decl(&loc));
             }
             hir::StmtKind::Item(item) => {
-                self.ann.nested(self, Nested::Item(item))?
+                self.ann.nested(self, Nested::Item(item))
             }
             hir::StmtKind::Expr(ref expr) => {
-                self.space_if_not_bol()?;
-                self.print_expr(&expr)?;
+                self.space_if_not_bol();
+                self.print_expr(&expr);
             }
             hir::StmtKind::Semi(ref expr) => {
-                self.space_if_not_bol()?;
-                self.print_expr(&expr)?;
-                self.s.word(";")?;
+                self.space_if_not_bol();
+                self.print_expr(&expr);
+                self.s.word(";");
             }
         }
         if stmt_ends_with_semi(&st.node) {
-            self.s.word(";")?;
+            self.s.word(";");
         }
         self.maybe_print_trailing_comment(st.span, None)
     }
 
-    pub fn print_block(&mut self, blk: &hir::Block) -> io::Result<()> {
+    pub fn print_block(&mut self, blk: &hir::Block) {
         self.print_block_with_attrs(blk, &[])
     }
 
-    pub fn print_block_unclosed(&mut self, blk: &hir::Block) -> io::Result<()> {
+    pub fn print_block_unclosed(&mut self, blk: &hir::Block) {
         self.print_block_unclosed_indent(blk, indent_unit)
     }
 
     pub fn print_block_unclosed_indent(&mut self,
                                        blk: &hir::Block,
                                        indented: usize)
-                                       -> io::Result<()> {
+                                       {
         self.print_block_maybe_unclosed(blk, indented, &[], false)
     }
 
     pub fn print_block_with_attrs(&mut self,
                                   blk: &hir::Block,
                                   attrs: &[ast::Attribute])
-                                  -> io::Result<()> {
+                                  {
         self.print_block_maybe_unclosed(blk, indent_unit, attrs, true)
     }
 
@@ -1039,56 +1019,55 @@ pub fn print_block_maybe_unclosed(&mut self,
                                       indented: usize,
                                       attrs: &[ast::Attribute],
                                       close_box: bool)
-                                      -> io::Result<()> {
+                                      {
         match blk.rules {
-            hir::UnsafeBlock(..) => self.word_space("unsafe")?,
-            hir::PushUnsafeBlock(..) => self.word_space("push_unsafe")?,
-            hir::PopUnsafeBlock(..) => self.word_space("pop_unsafe")?,
+            hir::UnsafeBlock(..) => self.word_space("unsafe"),
+            hir::PushUnsafeBlock(..) => self.word_space("push_unsafe"),
+            hir::PopUnsafeBlock(..) => self.word_space("pop_unsafe"),
             hir::DefaultBlock => (),
         }
-        self.maybe_print_comment(blk.span.lo())?;
-        self.ann.pre(self, AnnNode::Block(blk))?;
-        self.bopen()?;
+        self.maybe_print_comment(blk.span.lo());
+        self.ann.pre(self, AnnNode::Block(blk));
+        self.bopen();
 
-        self.print_inner_attributes(attrs)?;
+        self.print_inner_attributes(attrs);
 
         for st in &blk.stmts {
-            self.print_stmt(st)?;
+            self.print_stmt(st);
         }
         if let Some(ref expr) = blk.expr {
-            self.space_if_not_bol()?;
-            self.print_expr(&expr)?;
-            self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi()))?;
+            self.space_if_not_bol();
+            self.print_expr(&expr);
+            self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi()));
         }
-        self.bclose_maybe_open(blk.span, indented, close_box)?;
+        self.bclose_maybe_open(blk.span, indented, close_box);
         self.ann.post(self, AnnNode::Block(blk))
     }
 
-    pub fn print_anon_const(&mut self, constant: &hir::AnonConst) -> io::Result<()> {
+    pub fn print_anon_const(&mut self, constant: &hir::AnonConst) {
         self.ann.nested(self, Nested::Body(constant.body))
     }
 
-    fn print_call_post(&mut self, args: &[hir::Expr]) -> io::Result<()> {
-        self.popen()?;
-        self.commasep_exprs(Inconsistent, args)?;
+    fn print_call_post(&mut self, args: &[hir::Expr]) {
+        self.popen();
+        self.commasep_exprs(Inconsistent, args);
         self.pclose()
     }
 
-    pub fn print_expr_maybe_paren(&mut self, expr: &hir::Expr, prec: i8) -> io::Result<()> {
+    pub fn print_expr_maybe_paren(&mut self, expr: &hir::Expr, prec: i8) {
         let needs_par = expr.precedence().order() < prec;
         if needs_par {
-            self.popen()?;
+            self.popen();
         }
-        self.print_expr(expr)?;
+        self.print_expr(expr);
         if needs_par {
-            self.pclose()?;
+            self.pclose();
         }
-        Ok(())
     }
 
     /// Print an expr using syntax that's acceptable in a condition position, such as the `cond` in
     /// `if cond { ... }`.
-    pub fn print_expr_as_cond(&mut self, expr: &hir::Expr) -> io::Result<()> {
+    pub fn print_expr_as_cond(&mut self, expr: &hir::Expr) {
         let needs_par = match expr.node {
             // These cases need parens due to the parse error observed in #26461: `if return {}`
             // parses as the erroneous construct `if (return {})`, not `if (return) {}`.
@@ -1100,30 +1079,29 @@ pub fn print_expr_as_cond(&mut self, expr: &hir::Expr) -> io::Result<()> {
         };
 
         if needs_par {
-            self.popen()?;
+            self.popen();
         }
-        self.print_expr(expr)?;
+        self.print_expr(expr);
         if needs_par {
-            self.pclose()?;
+            self.pclose();
         }
-        Ok(())
     }
 
-    fn print_expr_vec(&mut self, exprs: &[hir::Expr]) -> io::Result<()> {
-        self.ibox(indent_unit)?;
-        self.s.word("[")?;
-        self.commasep_exprs(Inconsistent, exprs)?;
-        self.s.word("]")?;
+    fn print_expr_vec(&mut self, exprs: &[hir::Expr]) {
+        self.ibox(indent_unit);
+        self.s.word("[");
+        self.commasep_exprs(Inconsistent, exprs);
+        self.s.word("]");
         self.end()
     }
 
-    fn print_expr_repeat(&mut self, element: &hir::Expr, count: &hir::AnonConst) -> io::Result<()> {
-        self.ibox(indent_unit)?;
-        self.s.word("[")?;
-        self.print_expr(element)?;
-        self.word_space(";")?;
-        self.print_anon_const(count)?;
-        self.s.word("]")?;
+    fn print_expr_repeat(&mut self, element: &hir::Expr, count: &hir::AnonConst) {
+        self.ibox(indent_unit);
+        self.s.word("[");
+        self.print_expr(element);
+        self.word_space(";");
+        self.print_anon_const(count);
+        self.s.word("]");
         self.end()
     }
 
@@ -1131,72 +1109,71 @@ fn print_expr_struct(&mut self,
                          qpath: &hir::QPath,
                          fields: &[hir::Field],
                          wth: &Option<P<hir::Expr>>)
-                         -> io::Result<()> {
-        self.print_qpath(qpath, true)?;
-        self.s.word("{")?;
+                         {
+        self.print_qpath(qpath, true);
+        self.s.word("{");
         self.commasep_cmnt(Consistent,
                            &fields[..],
                            |s, field| {
-                               s.ibox(indent_unit)?;
+                               s.ibox(indent_unit);
                                if !field.is_shorthand {
-                                    s.print_ident(field.ident)?;
-                                    s.word_space(":")?;
+                                    s.print_ident(field.ident);
+                                    s.word_space(":");
                                }
-                               s.print_expr(&field.expr)?;
+                               s.print_expr(&field.expr);
                                s.end()
                            },
-                           |f| f.span)?;
+                           |f| f.span);
         match *wth {
             Some(ref expr) => {
-                self.ibox(indent_unit)?;
+                self.ibox(indent_unit);
                 if !fields.is_empty() {
-                    self.s.word(",")?;
-                    self.s.space()?;
+                    self.s.word(",");
+                    self.s.space();
                 }
-                self.s.word("..")?;
-                self.print_expr(&expr)?;
-                self.end()?;
+                self.s.word("..");
+                self.print_expr(&expr);
+                self.end();
             }
             _ => if !fields.is_empty() {
-                self.s.word(",")?
+                self.s.word(",")
             },
         }
-        self.s.word("}")?;
-        Ok(())
+        self.s.word("}");
     }
 
-    fn print_expr_tup(&mut self, exprs: &[hir::Expr]) -> io::Result<()> {
-        self.popen()?;
-        self.commasep_exprs(Inconsistent, exprs)?;
+    fn print_expr_tup(&mut self, exprs: &[hir::Expr]) {
+        self.popen();
+        self.commasep_exprs(Inconsistent, exprs);
         if exprs.len() == 1 {
-            self.s.word(",")?;
+            self.s.word(",");
         }
         self.pclose()
     }
 
-    fn print_expr_call(&mut self, func: &hir::Expr, args: &[hir::Expr]) -> io::Result<()> {
+    fn print_expr_call(&mut self, func: &hir::Expr, args: &[hir::Expr]) {
         let prec =
             match func.node {
                 hir::ExprKind::Field(..) => parser::PREC_FORCE_PAREN,
                 _ => parser::PREC_POSTFIX,
             };
 
-        self.print_expr_maybe_paren(func, prec)?;
+        self.print_expr_maybe_paren(func, prec);
         self.print_call_post(args)
     }
 
     fn print_expr_method_call(&mut self,
                               segment: &hir::PathSegment,
                               args: &[hir::Expr])
-                              -> io::Result<()> {
+                              {
         let base_args = &args[1..];
-        self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX)?;
-        self.s.word(".")?;
-        self.print_ident(segment.ident)?;
+        self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX);
+        self.s.word(".");
+        self.print_ident(segment.ident);
 
         let generic_args = segment.generic_args();
         if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() {
-            self.print_generic_args(generic_args, segment.infer_args, true)?;
+            self.print_generic_args(generic_args, segment.infer_args, true);
         }
 
         self.print_call_post(base_args)
@@ -1206,7 +1183,7 @@ fn print_expr_binary(&mut self,
                          op: hir::BinOp,
                          lhs: &hir::Expr,
                          rhs: &hir::Expr)
-                         -> io::Result<()> {
+                         {
         let assoc_op = bin_op_to_assoc_op(op.node);
         let prec = assoc_op.precedence() as i8;
         let fixity = assoc_op.fixity();
@@ -1226,220 +1203,220 @@ fn print_expr_binary(&mut self,
             _ => left_prec,
         };
 
-        self.print_expr_maybe_paren(lhs, left_prec)?;
-        self.s.space()?;
-        self.word_space(op.node.as_str())?;
+        self.print_expr_maybe_paren(lhs, left_prec);
+        self.s.space();
+        self.word_space(op.node.as_str());
         self.print_expr_maybe_paren(rhs, right_prec)
     }
 
-    fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr) -> io::Result<()> {
-        self.s.word(op.as_str())?;
+    fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr) {
+        self.s.word(op.as_str());
         self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
     }
 
     fn print_expr_addr_of(&mut self,
                           mutability: hir::Mutability,
                           expr: &hir::Expr)
-                          -> io::Result<()> {
-        self.s.word("&")?;
-        self.print_mutability(mutability)?;
+                          {
+        self.s.word("&");
+        self.print_mutability(mutability);
         self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
     }
 
-    fn print_literal(&mut self, lit: &hir::Lit) -> io::Result<()> {
-        self.maybe_print_comment(lit.span.lo())?;
+    fn print_literal(&mut self, lit: &hir::Lit) {
+        self.maybe_print_comment(lit.span.lo());
         self.writer().word(pprust::literal_to_string(lit.node.to_lit_token()))
     }
 
-    pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> {
-        self.maybe_print_comment(expr.span.lo())?;
-        self.print_outer_attributes(&expr.attrs)?;
-        self.ibox(indent_unit)?;
-        self.ann.pre(self, AnnNode::Expr(expr))?;
+    pub fn print_expr(&mut self, expr: &hir::Expr) {
+        self.maybe_print_comment(expr.span.lo());
+        self.print_outer_attributes(&expr.attrs);
+        self.ibox(indent_unit);
+        self.ann.pre(self, AnnNode::Expr(expr));
         match expr.node {
             hir::ExprKind::Box(ref expr) => {
-                self.word_space("box")?;
-                self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)?;
+                self.word_space("box");
+                self.print_expr_maybe_paren(expr, parser::PREC_PREFIX);
             }
             hir::ExprKind::Array(ref exprs) => {
-                self.print_expr_vec(exprs)?;
+                self.print_expr_vec(exprs);
             }
             hir::ExprKind::Repeat(ref element, ref count) => {
-                self.print_expr_repeat(&element, count)?;
+                self.print_expr_repeat(&element, count);
             }
             hir::ExprKind::Struct(ref qpath, ref fields, ref wth) => {
-                self.print_expr_struct(qpath, &fields[..], wth)?;
+                self.print_expr_struct(qpath, &fields[..], wth);
             }
             hir::ExprKind::Tup(ref exprs) => {
-                self.print_expr_tup(exprs)?;
+                self.print_expr_tup(exprs);
             }
             hir::ExprKind::Call(ref func, ref args) => {
-                self.print_expr_call(&func, args)?;
+                self.print_expr_call(&func, args);
             }
             hir::ExprKind::MethodCall(ref segment, _, ref args) => {
-                self.print_expr_method_call(segment, args)?;
+                self.print_expr_method_call(segment, args);
             }
             hir::ExprKind::Binary(op, ref lhs, ref rhs) => {
-                self.print_expr_binary(op, &lhs, &rhs)?;
+                self.print_expr_binary(op, &lhs, &rhs);
             }
             hir::ExprKind::Unary(op, ref expr) => {
-                self.print_expr_unary(op, &expr)?;
+                self.print_expr_unary(op, &expr);
             }
             hir::ExprKind::AddrOf(m, ref expr) => {
-                self.print_expr_addr_of(m, &expr)?;
+                self.print_expr_addr_of(m, &expr);
             }
             hir::ExprKind::Lit(ref lit) => {
-                self.print_literal(&lit)?;
+                self.print_literal(&lit);
             }
             hir::ExprKind::Cast(ref expr, ref ty) => {
                 let prec = AssocOp::As.precedence() as i8;
-                self.print_expr_maybe_paren(&expr, prec)?;
-                self.s.space()?;
-                self.word_space("as")?;
-                self.print_type(&ty)?;
+                self.print_expr_maybe_paren(&expr, prec);
+                self.s.space();
+                self.word_space("as");
+                self.print_type(&ty);
             }
             hir::ExprKind::Type(ref expr, ref ty) => {
                 let prec = AssocOp::Colon.precedence() as i8;
-                self.print_expr_maybe_paren(&expr, prec)?;
-                self.word_space(":")?;
-                self.print_type(&ty)?;
+                self.print_expr_maybe_paren(&expr, prec);
+                self.word_space(":");
+                self.print_type(&ty);
             }
             hir::ExprKind::DropTemps(ref init) => {
                 // Print `{`:
-                self.cbox(indent_unit)?;
-                self.ibox(0)?;
-                self.bopen()?;
+                self.cbox(indent_unit);
+                self.ibox(0);
+                self.bopen();
 
                 // Print `let _t = $init;`:
                 let temp = ast::Ident::from_str("_t");
-                self.print_local(Some(init), |this| this.print_ident(temp))?;
-                self.s.word(";")?;
+                self.print_local(Some(init), |this| this.print_ident(temp));
+                self.s.word(";");
 
                 // Print `_t`:
-                self.space_if_not_bol()?;
-                self.print_ident(temp)?;
+                self.space_if_not_bol();
+                self.print_ident(temp);
 
                 // Print `}`:
-                self.bclose_maybe_open(expr.span, indent_unit, true)?;
+                self.bclose_maybe_open(expr.span, indent_unit, true);
             }
             hir::ExprKind::While(ref test, ref blk, opt_label) => {
                 if let Some(label) = opt_label {
-                    self.print_ident(label.ident)?;
-                    self.word_space(":")?;
+                    self.print_ident(label.ident);
+                    self.word_space(":");
                 }
-                self.head("while")?;
-                self.print_expr_as_cond(&test)?;
-                self.s.space()?;
-                self.print_block(&blk)?;
+                self.head("while");
+                self.print_expr_as_cond(&test);
+                self.s.space();
+                self.print_block(&blk);
             }
             hir::ExprKind::Loop(ref blk, opt_label, _) => {
                 if let Some(label) = opt_label {
-                    self.print_ident(label.ident)?;
-                    self.word_space(":")?;
+                    self.print_ident(label.ident);
+                    self.word_space(":");
                 }
-                self.head("loop")?;
-                self.s.space()?;
-                self.print_block(&blk)?;
+                self.head("loop");
+                self.s.space();
+                self.print_block(&blk);
             }
             hir::ExprKind::Match(ref expr, ref arms, _) => {
-                self.cbox(indent_unit)?;
-                self.ibox(4)?;
-                self.word_nbsp("match")?;
-                self.print_expr_as_cond(&expr)?;
-                self.s.space()?;
-                self.bopen()?;
+                self.cbox(indent_unit);
+                self.ibox(4);
+                self.word_nbsp("match");
+                self.print_expr_as_cond(&expr);
+                self.s.space();
+                self.bopen();
                 for arm in arms {
-                    self.print_arm(arm)?;
+                    self.print_arm(arm);
                 }
-                self.bclose_(expr.span, indent_unit)?;
+                self.bclose_(expr.span, indent_unit);
             }
             hir::ExprKind::Closure(capture_clause, ref decl, body, _fn_decl_span, _gen) => {
-                self.print_capture_clause(capture_clause)?;
+                self.print_capture_clause(capture_clause);
 
-                self.print_closure_args(&decl, body)?;
-                self.s.space()?;
+                self.print_closure_args(&decl, body);
+                self.s.space();
 
                 // this is a bare expression
-                self.ann.nested(self, Nested::Body(body))?;
-                self.end()?; // need to close a box
+                self.ann.nested(self, Nested::Body(body));
+                self.end(); // need to close a box
 
                 // a box will be closed by print_expr, but we didn't want an overall
                 // wrapper so we closed the corresponding opening. so create an
                 // empty box to satisfy the close.
-                self.ibox(0)?;
+                self.ibox(0);
             }
             hir::ExprKind::Block(ref blk, opt_label) => {
                 if let Some(label) = opt_label {
-                    self.print_ident(label.ident)?;
-                    self.word_space(":")?;
+                    self.print_ident(label.ident);
+                    self.word_space(":");
                 }
                 // containing cbox, will be closed by print-block at }
-                self.cbox(indent_unit)?;
+                self.cbox(indent_unit);
                 // head-box, will be closed by print-block after {
-                self.ibox(0)?;
-                self.print_block(&blk)?;
+                self.ibox(0);
+                self.print_block(&blk);
             }
             hir::ExprKind::Assign(ref lhs, ref rhs) => {
                 let prec = AssocOp::Assign.precedence() as i8;
-                self.print_expr_maybe_paren(&lhs, prec + 1)?;
-                self.s.space()?;
-                self.word_space("=")?;
-                self.print_expr_maybe_paren(&rhs, prec)?;
+                self.print_expr_maybe_paren(&lhs, prec + 1);
+                self.s.space();
+                self.word_space("=");
+                self.print_expr_maybe_paren(&rhs, prec);
             }
             hir::ExprKind::AssignOp(op, ref lhs, ref rhs) => {
                 let prec = AssocOp::Assign.precedence() as i8;
-                self.print_expr_maybe_paren(&lhs, prec + 1)?;
-                self.s.space()?;
-                self.s.word(op.node.as_str())?;
-                self.word_space("=")?;
-                self.print_expr_maybe_paren(&rhs, prec)?;
+                self.print_expr_maybe_paren(&lhs, prec + 1);
+                self.s.space();
+                self.s.word(op.node.as_str());
+                self.word_space("=");
+                self.print_expr_maybe_paren(&rhs, prec);
             }
             hir::ExprKind::Field(ref expr, ident) => {
-                self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX)?;
-                self.s.word(".")?;
-                self.print_ident(ident)?;
+                self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
+                self.s.word(".");
+                self.print_ident(ident);
             }
             hir::ExprKind::Index(ref expr, ref index) => {
-                self.print_expr_maybe_paren(&expr, parser::PREC_POSTFIX)?;
-                self.s.word("[")?;
-                self.print_expr(&index)?;
-                self.s.word("]")?;
+                self.print_expr_maybe_paren(&expr, parser::PREC_POSTFIX);
+                self.s.word("[");
+                self.print_expr(&index);
+                self.s.word("]");
             }
             hir::ExprKind::Path(ref qpath) => {
-                self.print_qpath(qpath, true)?
+                self.print_qpath(qpath, true)
             }
             hir::ExprKind::Break(destination, ref opt_expr) => {
-                self.s.word("break")?;
-                self.s.space()?;
+                self.s.word("break");
+                self.s.space();
                 if let Some(label) = destination.label {
-                    self.print_ident(label.ident)?;
-                    self.s.space()?;
+                    self.print_ident(label.ident);
+                    self.s.space();
                 }
                 if let Some(ref expr) = *opt_expr {
-                    self.print_expr_maybe_paren(expr, parser::PREC_JUMP)?;
-                    self.s.space()?;
+                    self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
+                    self.s.space();
                 }
             }
             hir::ExprKind::Continue(destination) => {
-                self.s.word("continue")?;
-                self.s.space()?;
+                self.s.word("continue");
+                self.s.space();
                 if let Some(label) = destination.label {
-                    self.print_ident(label.ident)?;
-                    self.s.space()?
+                    self.print_ident(label.ident);
+                    self.s.space()
                 }
             }
             hir::ExprKind::Ret(ref result) => {
-                self.s.word("return")?;
+                self.s.word("return");
                 if let Some(ref expr) = *result {
-                    self.s.word(" ")?;
-                    self.print_expr_maybe_paren(&expr, parser::PREC_JUMP)?;
+                    self.s.word(" ");
+                    self.print_expr_maybe_paren(&expr, parser::PREC_JUMP);
                 }
             }
             hir::ExprKind::InlineAsm(ref a, ref outputs, ref inputs) => {
-                self.s.word("asm!")?;
-                self.popen()?;
-                self.print_string(&a.asm.as_str(), a.asm_str_style)?;
-                self.word_space(":")?;
+                self.s.word("asm!");
+                self.popen();
+                self.print_string(&a.asm.as_str(), a.asm_str_style);
+                self.word_space(":");
 
                 let mut out_idx = 0;
                 self.commasep(Inconsistent, &a.outputs, |s, out| {
@@ -1448,35 +1425,32 @@ pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> {
                     match ch.next() {
                         Some('=') if out.is_rw => {
                             s.print_string(&format!("+{}", ch.as_str()),
-                                           ast::StrStyle::Cooked)?
+                                           ast::StrStyle::Cooked)
                         }
-                        _ => s.print_string(&constraint, ast::StrStyle::Cooked)?,
+                        _ => s.print_string(&constraint, ast::StrStyle::Cooked),
                     }
-                    s.popen()?;
-                    s.print_expr(&outputs[out_idx])?;
-                    s.pclose()?;
+                    s.popen();
+                    s.print_expr(&outputs[out_idx]);
+                    s.pclose();
                     out_idx += 1;
-                    Ok(())
-                })?;
-                self.s.space()?;
-                self.word_space(":")?;
+                });
+                self.s.space();
+                self.word_space(":");
 
                 let mut in_idx = 0;
                 self.commasep(Inconsistent, &a.inputs, |s, co| {
-                    s.print_string(&co.as_str(), ast::StrStyle::Cooked)?;
-                    s.popen()?;
-                    s.print_expr(&inputs[in_idx])?;
-                    s.pclose()?;
+                    s.print_string(&co.as_str(), ast::StrStyle::Cooked);
+                    s.popen();
+                    s.print_expr(&inputs[in_idx]);
+                    s.pclose();
                     in_idx += 1;
-                    Ok(())
-                })?;
-                self.s.space()?;
-                self.word_space(":")?;
+                });
+                self.s.space();
+                self.word_space(":");
 
                 self.commasep(Inconsistent, &a.clobbers, |s, co| {
-                    s.print_string(&co.as_str(), ast::StrStyle::Cooked)?;
-                    Ok(())
-                })?;
+                    s.print_string(&co.as_str(), ast::StrStyle::Cooked);
+                });
 
                 let mut options = vec![];
                 if a.volatile {
@@ -1490,131 +1464,126 @@ pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> {
                 }
 
                 if !options.is_empty() {
-                    self.s.space()?;
-                    self.word_space(":")?;
+                    self.s.space();
+                    self.word_space(":");
                     self.commasep(Inconsistent, &options, |s, &co| {
-                        s.print_string(co, ast::StrStyle::Cooked)?;
-                        Ok(())
-                    })?;
+                        s.print_string(co, ast::StrStyle::Cooked);
+                    });
                 }
 
-                self.pclose()?;
+                self.pclose();
             }
             hir::ExprKind::Yield(ref expr, _) => {
-                self.word_space("yield")?;
-                self.print_expr_maybe_paren(&expr, parser::PREC_JUMP)?;
+                self.word_space("yield");
+                self.print_expr_maybe_paren(&expr, parser::PREC_JUMP);
             }
             hir::ExprKind::Err => {
-                self.popen()?;
-                self.s.word("/*ERROR*/")?;
-                self.pclose()?;
+                self.popen();
+                self.s.word("/*ERROR*/");
+                self.pclose();
             }
         }
-        self.ann.post(self, AnnNode::Expr(expr))?;
+        self.ann.post(self, AnnNode::Expr(expr));
         self.end()
     }
 
-    pub fn print_local_decl(&mut self, loc: &hir::Local) -> io::Result<()> {
-        self.print_pat(&loc.pat)?;
+    pub fn print_local_decl(&mut self, loc: &hir::Local) {
+        self.print_pat(&loc.pat);
         if let Some(ref ty) = loc.ty {
-            self.word_space(":")?;
-            self.print_type(&ty)?;
+            self.word_space(":");
+            self.print_type(&ty);
         }
-        Ok(())
     }
 
-    pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
+    pub fn print_usize(&mut self, i: usize) {
         self.s.word(i.to_string())
     }
 
-    pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
+    pub fn print_ident(&mut self, ident: ast::Ident) {
         if ident.is_raw_guess() {
-            self.s.word(format!("r#{}", ident.name))?;
+            self.s.word(format!("r#{}", ident.name));
         } else {
-            self.s.word(ident.as_str().to_string())?;
+            self.s.word(ident.as_str().to_string());
         }
         self.ann.post(self, AnnNode::Name(&ident.name))
     }
 
-    pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
+    pub fn print_name(&mut self, name: ast::Name) {
         self.print_ident(ast::Ident::with_empty_ctxt(name))
     }
 
-    pub fn print_for_decl(&mut self, loc: &hir::Local, coll: &hir::Expr) -> io::Result<()> {
-        self.print_local_decl(loc)?;
-        self.s.space()?;
-        self.word_space("in")?;
+    pub fn print_for_decl(&mut self, loc: &hir::Local, coll: &hir::Expr) {
+        self.print_local_decl(loc);
+        self.s.space();
+        self.word_space("in");
         self.print_expr(coll)
     }
 
     pub fn print_path(&mut self,
                       path: &hir::Path,
                       colons_before_params: bool)
-                      -> io::Result<()> {
-        self.maybe_print_comment(path.span.lo())?;
+                      {
+        self.maybe_print_comment(path.span.lo());
 
         for (i, segment) in path.segments.iter().enumerate() {
             if i > 0 {
-                self.s.word("::")?
+                self.s.word("::")
             }
             if segment.ident.name != kw::PathRoot {
-                self.print_ident(segment.ident)?;
+                self.print_ident(segment.ident);
                 self.print_generic_args(segment.generic_args(), segment.infer_args,
-                                        colons_before_params)?;
+                                        colons_before_params);
             }
         }
-
-        Ok(())
     }
 
-    pub fn print_path_segment(&mut self, segment: &hir::PathSegment) -> io::Result<()> {
+    pub fn print_path_segment(&mut self, segment: &hir::PathSegment) {
         if segment.ident.name != kw::PathRoot {
-            self.print_ident(segment.ident)?;
-            self.print_generic_args(segment.generic_args(), segment.infer_args, false)?;
+            self.print_ident(segment.ident);
+            self.print_generic_args(segment.generic_args(), segment.infer_args, false);
         }
-        Ok(())
     }
 
     pub fn print_qpath(&mut self,
                        qpath: &hir::QPath,
                        colons_before_params: bool)
-                       -> io::Result<()> {
+                       {
         match *qpath {
             hir::QPath::Resolved(None, ref path) => {
                 self.print_path(path, colons_before_params)
             }
             hir::QPath::Resolved(Some(ref qself), ref path) => {
-                self.s.word("<")?;
-                self.print_type(qself)?;
-                self.s.space()?;
-                self.word_space("as")?;
+                self.s.word("<");
+                self.print_type(qself);
+                self.s.space();
+                self.word_space("as");
 
                 for (i, segment) in path.segments[..path.segments.len() - 1].iter().enumerate() {
                     if i > 0 {
-                        self.s.word("::")?
+                        self.s.word("::")
                     }
                     if segment.ident.name != kw::PathRoot {
-                        self.print_ident(segment.ident)?;
+                        self.print_ident(segment.ident);
                         self.print_generic_args(segment.generic_args(),
                                                 segment.infer_args,
-                                                colons_before_params)?;
+                                                colons_before_params);
                     }
                 }
 
-                self.s.word(">")?;
-                self.s.word("::")?;
+                self.s.word(">");
+                self.s.word("::");
                 let item_segment = path.segments.last().unwrap();
-                self.print_ident(item_segment.ident)?;
+                self.print_ident(item_segment.ident);
                 self.print_generic_args(item_segment.generic_args(),
                                         item_segment.infer_args,
                                         colons_before_params)
             }
             hir::QPath::TypeRelative(ref qself, ref item_segment) => {
-                self.s.word("<")?;
-                self.print_type(qself)?;
-                self.s.word(">")?;
-                self.s.word("::")?;
-                self.print_ident(item_segment.ident)?;
+                self.s.word("<");
+                self.print_type(qself);
+                self.s.word(">");
+                self.s.word("::");
+                self.print_ident(item_segment.ident);
                 self.print_generic_args(item_segment.generic_args(),
                                         item_segment.infer_args,
                                         colons_before_params)
@@ -1626,15 +1595,15 @@ fn print_generic_args(&mut self,
                              generic_args: &hir::GenericArgs,
                              infer_args: bool,
                              colons_before_params: bool)
-                             -> io::Result<()> {
+                             {
         if generic_args.parenthesized {
-            self.s.word("(")?;
-            self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(&ty))?;
-            self.s.word(")")?;
+            self.s.word("(");
+            self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(&ty));
+            self.s.word(")");
 
-            self.space_if_not_bol()?;
-            self.word_space("->")?;
-            self.print_type(generic_args.bindings[0].ty())?;
+            self.space_if_not_bol();
+            self.word_space("->");
+            self.print_type(generic_args.bindings[0].ty());
         } else {
             let start = if colons_before_params { "::<" } else { "<" };
             let empty = Cell::new(true);
@@ -1657,153 +1626,151 @@ fn print_generic_args(&mut self,
             });
 
             if nonelided_generic_args {
-                start_or_comma(self)?;
+                start_or_comma(self);
                 self.commasep(Inconsistent, &generic_args.args, |s, generic_arg| {
                     match generic_arg {
                         GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt),
-                        GenericArg::Lifetime(_) => Ok(()),
+                        GenericArg::Lifetime(_) => {},
                         GenericArg::Type(ty) => s.print_type(ty),
                         GenericArg::Const(ct) => s.print_anon_const(&ct.value),
                     }
-                })?;
+                });
             }
 
             // FIXME(eddyb): this would leak into error messages (e.g.,
             // "non-exhaustive patterns: `Some::<..>(_)` not covered").
             if infer_args && false {
-                start_or_comma(self)?;
-                self.s.word("..")?;
+                start_or_comma(self);
+                self.s.word("..");
             }
 
             for binding in generic_args.bindings.iter() {
-                start_or_comma(self)?;
-                self.print_ident(binding.ident)?;
-                self.s.space()?;
+                start_or_comma(self);
+                self.print_ident(binding.ident);
+                self.s.space();
                 match generic_args.bindings[0].kind {
                     hir::TypeBindingKind::Equality { ref ty } => {
-                        self.word_space("=")?;
-                        self.print_type(ty)?;
+                        self.word_space("=");
+                        self.print_type(ty);
                     }
                     hir::TypeBindingKind::Constraint { ref bounds } => {
-                        self.print_bounds(":", bounds)?;
+                        self.print_bounds(":", bounds);
                     }
                 }
             }
 
             if !empty.get() {
-                self.s.word(">")?
+                self.s.word(">")
             }
         }
-
-        Ok(())
     }
 
-    pub fn print_pat(&mut self, pat: &hir::Pat) -> io::Result<()> {
-        self.maybe_print_comment(pat.span.lo())?;
-        self.ann.pre(self, AnnNode::Pat(pat))?;
+    pub fn print_pat(&mut self, pat: &hir::Pat) {
+        self.maybe_print_comment(pat.span.lo());
+        self.ann.pre(self, AnnNode::Pat(pat));
         // Pat isn't normalized, but the beauty of it
         // is that it doesn't matter
         match pat.node {
-            PatKind::Wild => self.s.word("_")?,
+            PatKind::Wild => self.s.word("_"),
             PatKind::Binding(binding_mode, _, ident, ref sub) => {
                 match binding_mode {
                     hir::BindingAnnotation::Ref => {
-                        self.word_nbsp("ref")?;
-                        self.print_mutability(hir::MutImmutable)?;
+                        self.word_nbsp("ref");
+                        self.print_mutability(hir::MutImmutable);
                     }
                     hir::BindingAnnotation::RefMut => {
-                        self.word_nbsp("ref")?;
-                        self.print_mutability(hir::MutMutable)?;
+                        self.word_nbsp("ref");
+                        self.print_mutability(hir::MutMutable);
                     }
                     hir::BindingAnnotation::Unannotated => {}
                     hir::BindingAnnotation::Mutable => {
-                        self.word_nbsp("mut")?;
+                        self.word_nbsp("mut");
                     }
                 }
-                self.print_ident(ident)?;
+                self.print_ident(ident);
                 if let Some(ref p) = *sub {
-                    self.s.word("@")?;
-                    self.print_pat(&p)?;
+                    self.s.word("@");
+                    self.print_pat(&p);
                 }
             }
             PatKind::TupleStruct(ref qpath, ref elts, ddpos) => {
-                self.print_qpath(qpath, true)?;
-                self.popen()?;
+                self.print_qpath(qpath, true);
+                self.popen();
                 if let Some(ddpos) = ddpos {
-                    self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))?;
+                    self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p));
                     if ddpos != 0 {
-                        self.word_space(",")?;
+                        self.word_space(",");
                     }
-                    self.s.word("..")?;
+                    self.s.word("..");
                     if ddpos != elts.len() {
-                        self.s.word(",")?;
-                        self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))?;
+                        self.s.word(",");
+                        self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p));
                     }
                 } else {
-                    self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?;
+                    self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p));
                 }
-                self.pclose()?;
+                self.pclose();
             }
             PatKind::Path(ref qpath) => {
-                self.print_qpath(qpath, true)?;
+                self.print_qpath(qpath, true);
             }
             PatKind::Struct(ref qpath, ref fields, etc) => {
-                self.print_qpath(qpath, true)?;
-                self.nbsp()?;
-                self.word_space("{")?;
+                self.print_qpath(qpath, true);
+                self.nbsp();
+                self.word_space("{");
                 self.commasep_cmnt(Consistent,
                                    &fields[..],
                                    |s, f| {
-                                       s.cbox(indent_unit)?;
+                                       s.cbox(indent_unit);
                                        if !f.node.is_shorthand {
-                                           s.print_ident(f.node.ident)?;
-                                           s.word_nbsp(":")?;
+                                           s.print_ident(f.node.ident);
+                                           s.word_nbsp(":");
                                        }
-                                       s.print_pat(&f.node.pat)?;
+                                       s.print_pat(&f.node.pat);
                                        s.end()
                                    },
-                                   |f| f.node.pat.span)?;
+                                   |f| f.node.pat.span);
                 if etc {
                     if !fields.is_empty() {
-                        self.word_space(",")?;
+                        self.word_space(",");
                     }
-                    self.s.word("..")?;
+                    self.s.word("..");
                 }
-                self.s.space()?;
-                self.s.word("}")?;
+                self.s.space();
+                self.s.word("}");
             }
             PatKind::Tuple(ref elts, ddpos) => {
-                self.popen()?;
+                self.popen();
                 if let Some(ddpos) = ddpos {
-                    self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))?;
+                    self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p));
                     if ddpos != 0 {
-                        self.word_space(",")?;
+                        self.word_space(",");
                     }
-                    self.s.word("..")?;
+                    self.s.word("..");
                     if ddpos != elts.len() {
-                        self.s.word(",")?;
-                        self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))?;
+                        self.s.word(",");
+                        self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p));
                     }
                 } else {
-                    self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?;
+                    self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p));
                     if elts.len() == 1 {
-                        self.s.word(",")?;
+                        self.s.word(",");
                     }
                 }
-                self.pclose()?;
+                self.pclose();
             }
             PatKind::Box(ref inner) => {
                 let is_range_inner = match inner.node {
                     PatKind::Range(..) => true,
                     _ => false,
                 };
-                self.s.word("box ")?;
+                self.s.word("box ");
                 if is_range_inner {
-                    self.popen()?;
+                    self.popen();
                 }
-                self.print_pat(&inner)?;
+                self.print_pat(&inner);
                 if is_range_inner {
-                    self.pclose()?;
+                    self.pclose();
                 }
             }
             PatKind::Ref(ref inner, mutbl) => {
@@ -1811,101 +1778,101 @@ pub fn print_pat(&mut self, pat: &hir::Pat) -> io::Result<()> {
                     PatKind::Range(..) => true,
                     _ => false,
                 };
-                self.s.word("&")?;
+                self.s.word("&");
                 if mutbl == hir::MutMutable {
-                    self.s.word("mut ")?;
+                    self.s.word("mut ");
                 }
                 if is_range_inner {
-                    self.popen()?;
+                    self.popen();
                 }
-                self.print_pat(&inner)?;
+                self.print_pat(&inner);
                 if is_range_inner {
-                    self.pclose()?;
+                    self.pclose();
                 }
             }
-            PatKind::Lit(ref e) => self.print_expr(&e)?,
+            PatKind::Lit(ref e) => self.print_expr(&e),
             PatKind::Range(ref begin, ref end, ref end_kind) => {
-                self.print_expr(&begin)?;
-                self.s.space()?;
+                self.print_expr(&begin);
+                self.s.space();
                 match *end_kind {
-                    RangeEnd::Included => self.s.word("...")?,
-                    RangeEnd::Excluded => self.s.word("..")?,
+                    RangeEnd::Included => self.s.word("..."),
+                    RangeEnd::Excluded => self.s.word(".."),
                 }
-                self.print_expr(&end)?;
+                self.print_expr(&end);
             }
             PatKind::Slice(ref before, ref slice, ref after) => {
-                self.s.word("[")?;
-                self.commasep(Inconsistent, &before[..], |s, p| s.print_pat(&p))?;
+                self.s.word("[");
+                self.commasep(Inconsistent, &before[..], |s, p| s.print_pat(&p));
                 if let Some(ref p) = *slice {
                     if !before.is_empty() {
-                        self.word_space(",")?;
+                        self.word_space(",");
                     }
                     if let PatKind::Wild = p.node {
                         // Print nothing
                     } else {
-                        self.print_pat(&p)?;
+                        self.print_pat(&p);
                     }
-                    self.s.word("..")?;
+                    self.s.word("..");
                     if !after.is_empty() {
-                        self.word_space(",")?;
+                        self.word_space(",");
                     }
                 }
-                self.commasep(Inconsistent, &after[..], |s, p| s.print_pat(&p))?;
-                self.s.word("]")?;
+                self.commasep(Inconsistent, &after[..], |s, p| s.print_pat(&p));
+                self.s.word("]");
             }
         }
         self.ann.post(self, AnnNode::Pat(pat))
     }
 
-    pub fn print_arm(&mut self, arm: &hir::Arm) -> io::Result<()> {
+    pub fn print_arm(&mut self, arm: &hir::Arm) {
         // I have no idea why this check is necessary, but here it
         // is :(
         if arm.attrs.is_empty() {
-            self.s.space()?;
+            self.s.space();
         }
-        self.cbox(indent_unit)?;
-        self.ibox(0)?;
-        self.print_outer_attributes(&arm.attrs)?;
+        self.cbox(indent_unit);
+        self.ibox(0);
+        self.print_outer_attributes(&arm.attrs);
         let mut first = true;
         for p in &arm.pats {
             if first {
                 first = false;
             } else {
-                self.s.space()?;
-                self.word_space("|")?;
+                self.s.space();
+                self.word_space("|");
             }
-            self.print_pat(&p)?;
+            self.print_pat(&p);
         }
-        self.s.space()?;
+        self.s.space();
         if let Some(ref g) = arm.guard {
             match g {
                 hir::Guard::If(e) => {
-                    self.word_space("if")?;
-                    self.print_expr(&e)?;
-                    self.s.space()?;
+                    self.word_space("if");
+                    self.print_expr(&e);
+                    self.s.space();
                 }
             }
         }
-        self.word_space("=>")?;
+        self.word_space("=>");
 
         match arm.body.node {
             hir::ExprKind::Block(ref blk, opt_label) => {
                 if let Some(label) = opt_label {
-                    self.print_ident(label.ident)?;
-                    self.word_space(":")?;
+                    self.print_ident(label.ident);
+                    self.word_space(":");
                 }
                 // the block will close the pattern's ibox
-                self.print_block_unclosed_indent(&blk, indent_unit)?;
+                self.print_block_unclosed_indent(&blk, indent_unit);
 
                 // If it is a user-provided unsafe block, print a comma after it
                 if let hir::UnsafeBlock(hir::UserProvided) = blk.rules {
-                    self.s.word(",")?;
+                    self.s.word(",");
                 }
             }
             _ => {
-                self.end()?; // close the ibox for the pattern
-                self.print_expr(&arm.body)?;
-                self.s.word(",")?;
+                self.end(); // close the ibox for the pattern
+                self.print_expr(&arm.body);
+                self.s.word(",");
             }
         }
         self.end() // close enclosing cbox
@@ -1919,82 +1886,82 @@ pub fn print_fn(&mut self,
                     vis: &hir::Visibility,
                     arg_names: &[ast::Ident],
                     body_id: Option<hir::BodyId>)
-                    -> io::Result<()> {
-        self.print_fn_header_info(header, vis)?;
+                    {
+        self.print_fn_header_info(header, vis);
 
         if let Some(name) = name {
-            self.nbsp()?;
-            self.print_name(name)?;
+            self.nbsp();
+            self.print_name(name);
         }
-        self.print_generic_params(&generics.params)?;
+        self.print_generic_params(&generics.params);
 
-        self.popen()?;
+        self.popen();
         let mut i = 0;
         // Make sure we aren't supplied *both* `arg_names` and `body_id`.
         assert!(arg_names.is_empty() || body_id.is_none());
         self.commasep(Inconsistent, &decl.inputs, |s, ty| {
-            s.ibox(indent_unit)?;
+            s.ibox(indent_unit);
             if let Some(arg_name) = arg_names.get(i) {
-                s.s.word(arg_name.as_str().to_string())?;
-                s.s.word(":")?;
-                s.s.space()?;
+                s.s.word(arg_name.as_str().to_string());
+                s.s.word(":");
+                s.s.space();
             } else if let Some(body_id) = body_id {
-                s.ann.nested(s, Nested::BodyArgPat(body_id, i))?;
-                s.s.word(":")?;
-                s.s.space()?;
+                s.ann.nested(s, Nested::BodyArgPat(body_id, i));
+                s.s.word(":");
+                s.s.space();
             }
             i += 1;
-            s.print_type(ty)?;
+            s.print_type(ty);
             s.end()
-        })?;
+        });
         if decl.c_variadic {
-            self.s.word(", ...")?;
+            self.s.word(", ...");
         }
-        self.pclose()?;
+        self.pclose();
 
-        self.print_fn_output(decl)?;
+        self.print_fn_output(decl);
         self.print_where_clause(&generics.where_clause)
     }
 
-    fn print_closure_args(&mut self, decl: &hir::FnDecl, body_id: hir::BodyId) -> io::Result<()> {
-        self.s.word("|")?;
+    fn print_closure_args(&mut self, decl: &hir::FnDecl, body_id: hir::BodyId) {
+        self.s.word("|");
         let mut i = 0;
         self.commasep(Inconsistent, &decl.inputs, |s, ty| {
-            s.ibox(indent_unit)?;
+            s.ibox(indent_unit);
 
-            s.ann.nested(s, Nested::BodyArgPat(body_id, i))?;
+            s.ann.nested(s, Nested::BodyArgPat(body_id, i));
             i += 1;
 
             if let hir::TyKind::Infer = ty.node {
                 // Print nothing
             } else {
-                s.s.word(":")?;
-                s.s.space()?;
-                s.print_type(ty)?;
+                s.s.word(":");
+                s.s.space();
+                s.print_type(ty);
             }
-            s.end()
-        })?;
-        self.s.word("|")?;
+            s.end();
+        });
+        self.s.word("|");
 
         if let hir::DefaultReturn(..) = decl.output {
-            return Ok(());
+            return;
         }
 
-        self.space_if_not_bol()?;
-        self.word_space("->")?;
+        self.space_if_not_bol();
+        self.word_space("->");
         match decl.output {
             hir::Return(ref ty) => {
-                self.print_type(&ty)?;
+                self.print_type(&ty);
                 self.maybe_print_comment(ty.span.lo())
             }
             hir::DefaultReturn(..) => unreachable!(),
         }
     }
 
-    pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureClause) -> io::Result<()> {
+    pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureClause) {
         match capture_clause {
             hir::CaptureByValue => self.word_space("move"),
-            hir::CaptureByRef => Ok(()),
+            hir::CaptureByRef => {},
         }
     }
 
@@ -2002,55 +1969,53 @@ pub fn print_bounds<'b>(
         &mut self,
         prefix: &'static str,
         bounds: impl IntoIterator<Item = &'b hir::GenericBound>,
-    ) -> io::Result<()> {
+    ) {
         let mut first = true;
         for bound in bounds {
             if first {
-                self.s.word(prefix)?;
+                self.s.word(prefix);
             }
             if !(first && prefix.is_empty()) {
-                self.nbsp()?;
+                self.nbsp();
             }
             if first {
                 first = false;
             } else {
-                self.word_space("+")?;
+                self.word_space("+");
             }
 
             match bound {
                 GenericBound::Trait(tref, modifier) => {
                     if modifier == &TraitBoundModifier::Maybe {
-                        self.s.word("?")?;
+                        self.s.word("?");
                     }
-                    self.print_poly_trait_ref(tref)?;
+                    self.print_poly_trait_ref(tref);
                 }
                 GenericBound::Outlives(lt) => {
-                    self.print_lifetime(lt)?;
+                    self.print_lifetime(lt);
                 }
             }
         }
-        Ok(())
     }
 
-    pub fn print_generic_params(&mut self, generic_params: &[GenericParam]) -> io::Result<()> {
+    pub fn print_generic_params(&mut self, generic_params: &[GenericParam]) {
         if !generic_params.is_empty() {
-            self.s.word("<")?;
+            self.s.word("<");
 
             self.commasep(Inconsistent, generic_params, |s, param| {
                 s.print_generic_param(param)
-            })?;
+            });
 
-            self.s.word(">")?;
+            self.s.word(">");
         }
-        Ok(())
     }
 
-    pub fn print_generic_param(&mut self, param: &GenericParam) -> io::Result<()> {
+    pub fn print_generic_param(&mut self, param: &GenericParam) {
         if let GenericParamKind::Const { .. } = param.kind {
-            self.word_space("const")?;
+            self.word_space("const");
         }
 
-        self.print_ident(param.name.ident())?;
+        self.print_ident(param.name.ident());
 
         match param.kind {
             GenericParamKind::Lifetime { .. } => {
@@ -2058,48 +2023,47 @@ pub fn print_generic_param(&mut self, param: &GenericParam) -> io::Result<()> {
                 for bound in &param.bounds {
                     match bound {
                         GenericBound::Outlives(lt) => {
-                            self.s.word(sep)?;
-                            self.print_lifetime(lt)?;
+                            self.s.word(sep);
+                            self.print_lifetime(lt);
                             sep = "+";
                         }
                         _ => bug!(),
                     }
                 }
-                Ok(())
             }
             GenericParamKind::Type { ref default, .. } => {
-                self.print_bounds(":", &param.bounds)?;
+                self.print_bounds(":", &param.bounds);
                 match default {
                     Some(default) => {
-                        self.s.space()?;
-                        self.word_space("=")?;
+                        self.s.space();
+                        self.word_space("=");
                         self.print_type(&default)
                     }
-                    _ => Ok(()),
+                    _ => {}
                 }
             }
             GenericParamKind::Const { ref ty } => {
-                self.word_space(":")?;
+                self.word_space(":");
                 self.print_type(ty)
             }
         }
     }
 
-    pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> {
+    pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) {
         self.print_ident(lifetime.name.ident())
     }
 
-    pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause) -> io::Result<()> {
+    pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause) {
         if where_clause.predicates.is_empty() {
-            return Ok(());
+            return;
         }
 
-        self.s.space()?;
-        self.word_space("where")?;
+        self.s.space();
+        self.word_space("where");
 
         for (i, predicate) in where_clause.predicates.iter().enumerate() {
             if i != 0 {
-                self.word_space(",")?;
+                self.word_space(",");
             }
 
             match predicate {
@@ -2109,72 +2073,70 @@ pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause) -> io::Res
                     ref bounds,
                     ..
                 }) => {
-                    self.print_formal_generic_params(bound_generic_params)?;
-                    self.print_type(&bounded_ty)?;
-                    self.print_bounds(":", bounds)?;
+                    self.print_formal_generic_params(bound_generic_params);
+                    self.print_type(&bounded_ty);
+                    self.print_bounds(":", bounds);
                 }
                 &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime,
                                                                                 ref bounds,
                                                                                 ..}) => {
-                    self.print_lifetime(lifetime)?;
-                    self.s.word(":")?;
+                    self.print_lifetime(lifetime);
+                    self.s.word(":");
 
                     for (i, bound) in bounds.iter().enumerate() {
                         match bound {
                             GenericBound::Outlives(lt) => {
-                                self.print_lifetime(lt)?;
+                                self.print_lifetime(lt);
                             }
                             _ => bug!(),
                         }
 
                         if i != 0 {
-                            self.s.word(":")?;
+                            self.s.word(":");
                         }
                     }
                 }
                 &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ref lhs_ty,
                                                                         ref rhs_ty,
                                                                         ..}) => {
-                    self.print_type(lhs_ty)?;
-                    self.s.space()?;
-                    self.word_space("=")?;
-                    self.print_type(rhs_ty)?;
+                    self.print_type(lhs_ty);
+                    self.s.space();
+                    self.word_space("=");
+                    self.print_type(rhs_ty);
                 }
             }
         }
-
-        Ok(())
     }
 
-    pub fn print_mutability(&mut self, mutbl: hir::Mutability) -> io::Result<()> {
+    pub fn print_mutability(&mut self, mutbl: hir::Mutability) {
         match mutbl {
             hir::MutMutable => self.word_nbsp("mut"),
-            hir::MutImmutable => Ok(()),
+            hir::MutImmutable => {},
         }
     }
 
-    pub fn print_mt(&mut self, mt: &hir::MutTy) -> io::Result<()> {
-        self.print_mutability(mt.mutbl)?;
+    pub fn print_mt(&mut self, mt: &hir::MutTy) {
+        self.print_mutability(mt.mutbl);
         self.print_type(&mt.ty)
     }
 
-    pub fn print_fn_output(&mut self, decl: &hir::FnDecl) -> io::Result<()> {
+    pub fn print_fn_output(&mut self, decl: &hir::FnDecl) {
         if let hir::DefaultReturn(..) = decl.output {
-            return Ok(());
+            return;
         }
 
-        self.space_if_not_bol()?;
-        self.ibox(indent_unit)?;
-        self.word_space("->")?;
+        self.space_if_not_bol();
+        self.ibox(indent_unit);
+        self.word_space("->");
         match decl.output {
             hir::DefaultReturn(..) => unreachable!(),
-            hir::Return(ref ty) => self.print_type(&ty)?,
+            hir::Return(ref ty) => self.print_type(&ty),
         }
-        self.end()?;
+        self.end();
 
         match decl.output {
             hir::Return(ref output) => self.maybe_print_comment(output.span.lo()),
-            _ => Ok(()),
+            _ => {},
         }
     }
 
@@ -2185,11 +2147,11 @@ pub fn print_ty_fn(&mut self,
                        name: Option<ast::Name>,
                        generic_params: &[hir::GenericParam],
                        arg_names: &[ast::Ident])
-                       -> io::Result<()> {
-        self.ibox(indent_unit)?;
+                       {
+        self.ibox(indent_unit);
         if !generic_params.is_empty() {
-            self.s.word("for")?;
-            self.print_generic_params(generic_params)?;
+            self.s.word("for");
+            self.print_generic_params(generic_params);
         }
         let generics = hir::Generics {
             params: hir::HirVec::new(),
@@ -2211,21 +2173,21 @@ pub fn print_ty_fn(&mut self,
                       &Spanned { span: syntax_pos::DUMMY_SP,
                                  node: hir::VisibilityKind::Inherited },
                       arg_names,
-                      None)?;
-        self.end()
+                      None);
+        self.end();
     }
 
     pub fn maybe_print_trailing_comment(&mut self,
                                         span: syntax_pos::Span,
                                         next_pos: Option<BytePos>)
-                                        -> io::Result<()> {
+                                        {
         let cm = match self.cm {
             Some(cm) => cm,
-            _ => return Ok(()),
+            _ => return,
         };
         if let Some(ref cmnt) = self.next_comment() {
             if (*cmnt).style != comments::Trailing {
-                return Ok(());
+                return;
             }
             let span_line = cm.lookup_char_pos(span.hi());
             let comment_line = cm.lookup_char_pos((*cmnt).pos);
@@ -2235,84 +2197,82 @@ pub fn maybe_print_trailing_comment(&mut self,
             }
             if span.hi() < (*cmnt).pos && (*cmnt).pos < next &&
                span_line.line == comment_line.line {
-                self.print_comment(cmnt)?;
+                self.print_comment(cmnt);
             }
         }
-        Ok(())
     }
 
-    pub fn print_remaining_comments(&mut self) -> io::Result<()> {
+    pub fn print_remaining_comments(&mut self) {
         // If there aren't any remaining comments, then we need to manually
         // make sure there is a line break at the end.
         if self.next_comment().is_none() {
-            self.s.hardbreak()?;
+            self.s.hardbreak();
         }
         while let Some(ref cmnt) = self.next_comment() {
-            self.print_comment(cmnt)?
+            self.print_comment(cmnt)
         }
-        Ok(())
     }
 
     pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
                                                   opt_abi: Option<Abi>)
-                                                  -> io::Result<()> {
+                                                  {
         match opt_abi {
-            Some(Abi::Rust) => Ok(()),
+            Some(Abi::Rust) => {},
             Some(abi) => {
-                self.word_nbsp("extern")?;
+                self.word_nbsp("extern");
                 self.word_nbsp(abi.to_string())
             }
-            None => Ok(()),
+            None => {},
         }
     }
 
-    pub fn print_extern_opt_abi(&mut self, opt_abi: Option<Abi>) -> io::Result<()> {
+    pub fn print_extern_opt_abi(&mut self, opt_abi: Option<Abi>) {
         match opt_abi {
             Some(abi) => {
-                self.word_nbsp("extern")?;
+                self.word_nbsp("extern");
                 self.word_nbsp(abi.to_string())
             }
-            None => Ok(()),
+            None => {},
         }
     }
 
     pub fn print_fn_header_info(&mut self,
                                 header: hir::FnHeader,
                                 vis: &hir::Visibility)
-                                -> io::Result<()> {
-        self.s.word(visibility_qualified(vis, ""))?;
+                                {
+        self.s.word(visibility_qualified(vis, ""));
 
         match header.constness {
             hir::Constness::NotConst => {}
-            hir::Constness::Const => self.word_nbsp("const")?,
+            hir::Constness::Const => self.word_nbsp("const"),
         }
 
         match header.asyncness {
             hir::IsAsync::NotAsync => {}
-            hir::IsAsync::Async => self.word_nbsp("async")?,
+            hir::IsAsync::Async => self.word_nbsp("async"),
         }
 
-        self.print_unsafety(header.unsafety)?;
+        self.print_unsafety(header.unsafety);
 
         if header.abi != Abi::Rust {
-            self.word_nbsp("extern")?;
-            self.word_nbsp(header.abi.to_string())?;
+            self.word_nbsp("extern");
+            self.word_nbsp(header.abi.to_string());
         }
 
         self.s.word("fn")
     }
 
-    pub fn print_unsafety(&mut self, s: hir::Unsafety) -> io::Result<()> {
+    pub fn print_unsafety(&mut self, s: hir::Unsafety) {
         match s {
-            hir::Unsafety::Normal => Ok(()),
+            hir::Unsafety::Normal => {}
             hir::Unsafety::Unsafe => self.word_nbsp("unsafe"),
         }
     }
 
-    pub fn print_is_auto(&mut self, s: hir::IsAuto) -> io::Result<()> {
+    pub fn print_is_auto(&mut self, s: hir::IsAuto) {
         match s {
             hir::IsAuto::Yes => self.word_nbsp("auto"),
-            hir::IsAuto::No => Ok(()),
+            hir::IsAuto::No => {},
         }
     }
 }
diff --git a/src/librustc/hir/ptr.rs b/src/librustc/hir/ptr.rs
new file mode 100644 (file)
index 0000000..3a87b36
--- /dev/null
@@ -0,0 +1,141 @@
+// HACK(eddyb) this is a copy of `syntax::ptr`, minus the mutation (the HIR is
+// frozen anyway). The only reason for doing this instead of replacing `P<T>`
+// with `Box<T>` in HIR, is that `&Box<[T]>` doesn't implement `IntoIterator`.
+
+use std::fmt::{self, Display, Debug};
+use std::iter::FromIterator;
+use std::ops::Deref;
+use std::{slice, vec};
+
+use serialize::{Encodable, Decodable, Encoder, Decoder};
+
+use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
+                                           HashStable};
+/// An owned smart pointer.
+#[derive(Hash, PartialEq, Eq)]
+pub struct P<T: ?Sized> {
+    ptr: Box<T>
+}
+
+/// Construct a `P<T>` from a `T` value.
+#[allow(non_snake_case)]
+pub fn P<T: 'static>(value: T) -> P<T> {
+    P {
+        ptr: box value
+    }
+}
+
+impl<T: 'static> P<T> {
+    // HACK(eddyb) used by HIR lowering in a few places still.
+    // NOTE: do not make this more public than `pub(super)`.
+    pub(super) fn into_inner(self) -> T {
+        *self.ptr
+    }
+}
+
+impl<T: ?Sized> Deref for P<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &self.ptr
+    }
+}
+
+impl<T: ?Sized + Debug> Debug for P<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        Debug::fmt(&self.ptr, f)
+    }
+}
+
+impl<T: Display> Display for P<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        Display::fmt(&**self, f)
+    }
+}
+
+impl<T: 'static + Decodable> Decodable for P<T> {
+    fn decode<D: Decoder>(d: &mut D) -> Result<P<T>, D::Error> {
+        Decodable::decode(d).map(P)
+    }
+}
+
+impl<T: Encodable> Encodable for P<T> {
+    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+        (**self).encode(s)
+    }
+}
+
+impl<T> P<[T]> {
+    pub const fn new() -> P<[T]> {
+        // HACK(eddyb) bypass the lack of a `const fn` to create an empty `Box<[T]>`
+        // (as trait methods, `default` in this case, can't be `const fn` yet).
+        P {
+            ptr: unsafe {
+                use std::ptr::NonNull;
+                std::mem::transmute(NonNull::<[T; 0]>::dangling() as NonNull<[T]>)
+            },
+        }
+    }
+
+    #[inline(never)]
+    pub fn from_vec(v: Vec<T>) -> P<[T]> {
+        P { ptr: v.into_boxed_slice() }
+    }
+
+    // HACK(eddyb) used by HIR lowering in a few places still.
+    // NOTE: do not make this more public than `pub(super)`,
+    // and do not make this into an `IntoIterator` impl.
+    pub(super) fn into_iter(self) -> vec::IntoIter<T> {
+        self.ptr.into_vec().into_iter()
+    }
+}
+
+
+impl<T> Default for P<[T]> {
+    /// Creates an empty `P<[T]>`.
+    fn default() -> P<[T]> {
+        P::new()
+    }
+}
+
+impl<T> From<Vec<T>> for P<[T]> {
+    fn from(v: Vec<T>) -> Self {
+        P::from_vec(v)
+    }
+}
+
+impl<T> FromIterator<T> for P<[T]> {
+    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> P<[T]> {
+        P::from_vec(iter.into_iter().collect())
+    }
+}
+
+impl<'a, T> IntoIterator for &'a P<[T]> {
+    type Item = &'a T;
+    type IntoIter = slice::Iter<'a, T>;
+    fn into_iter(self) -> Self::IntoIter {
+        self.ptr.into_iter()
+    }
+}
+
+impl<T: Encodable> Encodable for P<[T]> {
+    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+        Encodable::encode(&**self, s)
+    }
+}
+
+impl<T: Decodable> Decodable for P<[T]> {
+    fn decode<D: Decoder>(d: &mut D) -> Result<P<[T]>, D::Error> {
+        Ok(P::from_vec(Decodable::decode(d)?))
+    }
+}
+
+impl<CTX, T> HashStable<CTX> for P<T>
+    where T: ?Sized + HashStable<CTX>
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        (**self).hash_stable(hcx, hasher);
+    }
+}
index 54b4435573baac2171577065d9355d78581986dd..cc532cb064ebe3139953ae91eb6b643bfe5b8b2c 100644 (file)
@@ -83,7 +83,7 @@ fn visit_path(&mut self, path: &'tcx hir::Path, _: hir::HirId) {
 
     fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
         if let hir::ExprKind::Closure(..) = expr.node {
-            let closure_def_id = self.tcx.hir().local_def_id_from_hir_id(expr.hir_id);
+            let closure_def_id = self.tcx.hir().local_def_id(expr.hir_id);
             if let Some(upvars) = self.tcx.upvars(closure_def_id) {
                 // Every capture of a closure expression is a local in scope,
                 // that is moved/copied/borrowed into the closure value, and
index b2c7bd73b6812833d0aa3d95521894ffe6fb6533..b508f91e01ebb22905053676a4c7ba5a33419547 100644 (file)
@@ -23,6 +23,7 @@
 
 use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind};
+use crate::infer::region_constraints::MemberConstraint;
 use crate::mir::interpret::ConstValue;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_macros::HashStable;
@@ -189,11 +190,25 @@ pub enum CanonicalTyVarKind {
 #[derive(Clone, Debug, HashStable)]
 pub struct QueryResponse<'tcx, R> {
     pub var_values: CanonicalVarValues<'tcx>,
-    pub region_constraints: Vec<QueryRegionConstraint<'tcx>>,
+    pub region_constraints: QueryRegionConstraints<'tcx>,
     pub certainty: Certainty,
     pub value: R,
 }
 
+#[derive(Clone, Debug, Default, HashStable)]
+pub struct QueryRegionConstraints<'tcx> {
+    pub outlives: Vec<QueryOutlivesConstraint<'tcx>>,
+    pub member_constraints: Vec<MemberConstraint<'tcx>>,
+}
+
+impl QueryRegionConstraints<'_> {
+    /// Represents an empty (trivially true) set of region
+    /// constraints.
+    pub fn is_empty(&self) -> bool {
+        self.outlives.is_empty() && self.member_constraints.is_empty()
+    }
+}
+
 pub type Canonicalized<'tcx, V> = Canonical<'tcx, V>;
 
 pub type CanonicalizedQueryResponse<'tcx, T> =
@@ -292,7 +307,8 @@ pub fn unchecked_map<W>(self, map_op: impl FnOnce(V) -> W) -> Canonical<'tcx, W>
     }
 }
 
-pub type QueryRegionConstraint<'tcx> = ty::Binder<ty::OutlivesPredicate<Kind<'tcx>, Region<'tcx>>>;
+pub type QueryOutlivesConstraint<'tcx> =
+    ty::Binder<ty::OutlivesPredicate<Kind<'tcx>, Region<'tcx>>>;
 
 impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
     /// Creates a substitution S for the canonical value with fresh
@@ -540,6 +556,19 @@ impl<'a, 'tcx, R> Lift<'tcx> for QueryResponse<'a, R> {
     } where R: Lift<'tcx>
 }
 
+BraceStructTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for QueryRegionConstraints<'tcx> {
+        outlives, member_constraints
+    }
+}
+
+BraceStructLiftImpl! {
+    impl<'a, 'tcx> Lift<'tcx> for QueryRegionConstraints<'a> {
+        type Lifted = QueryRegionConstraints<'tcx>;
+        outlives, member_constraints
+    }
+}
+
 impl<'tcx> Index<BoundVar> for CanonicalVarValues<'tcx> {
     type Output = Kind<'tcx>;
 
index 3e92fed005cd1f141c4d66c341ac71648395733c..79c5538626be191f80eba1c5671db8b8f56892fd 100644 (file)
@@ -11,7 +11,7 @@
 use crate::infer::canonical::substitute::substitute_value;
 use crate::infer::canonical::{
     Canonical, CanonicalVarValues, CanonicalizedQueryResponse, Certainty,
-    OriginalQueryValues, QueryRegionConstraint, QueryResponse,
+    OriginalQueryValues, QueryRegionConstraints, QueryOutlivesConstraint, QueryResponse,
 };
 use crate::infer::region_constraints::{Constraint, RegionConstraintData};
 use crate::infer::InferCtxtBuilder;
@@ -132,7 +132,7 @@ pub fn make_query_response_ignoring_pending_obligations<T>(
     {
         self.canonicalize_response(&QueryResponse {
             var_values: inference_vars,
-            region_constraints: vec![],
+            region_constraints: QueryRegionConstraints::default(),
             certainty: Certainty::Proven, // Ambiguities are OK!
             value: answer,
         })
@@ -174,7 +174,7 @@ fn make_query_response<T>(
 
         let region_obligations = self.take_registered_region_obligations();
         let region_constraints = self.with_region_constraints(|region_constraints| {
-            make_query_outlives(
+            make_query_region_constraints(
                 tcx,
                 region_obligations
                     .iter()
@@ -222,10 +222,10 @@ pub fn instantiate_query_response_and_region_obligations<R>(
             mut obligations,
         } = self.query_response_substitution(cause, param_env, original_values, query_response)?;
 
-        obligations.extend(self.query_region_constraints_into_obligations(
+        obligations.extend(self.query_outlives_constraints_into_obligations(
             cause,
             param_env,
-            &query_response.value.region_constraints,
+            &query_response.value.region_constraints.outlives,
             &result_subst,
         ));
 
@@ -248,9 +248,9 @@ pub fn instantiate_query_response_and_region_obligations<R>(
     /// that come out of these queries, which it wants to convert into
     /// MIR-based constraints and solve. Therefore, it is most
     /// convenient for the NLL Type Checker to **directly consume**
-    /// the `QueryRegionConstraint` values that arise from doing a
+    /// the `QueryOutlivesConstraint` values that arise from doing a
     /// query. This is contrast to other parts of the compiler, which
-    /// would prefer for those `QueryRegionConstraint` to be converted
+    /// would prefer for those `QueryOutlivesConstraint` to be converted
     /// into the older infcx-style constraints (e.g., calls to
     /// `sub_regions` or `register_region_obligation`).
     ///
@@ -263,7 +263,7 @@ pub fn instantiate_query_response_and_region_obligations<R>(
     ///   result. If any errors arise, they are propagated back as an
     ///   `Err` result.
     /// - In the case of a successful substitution, we will append
-    ///   `QueryRegionConstraint` values onto the
+    ///   `QueryOutlivesConstraint` values onto the
     ///   `output_query_region_constraints` vector for the solver to
     ///   use (if an error arises, some values may also be pushed, but
     ///   they should be ignored).
@@ -279,7 +279,7 @@ pub fn instantiate_nll_query_response_and_region_obligations<R>(
         param_env: ty::ParamEnv<'tcx>,
         original_values: &OriginalQueryValues<'tcx>,
         query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
-        output_query_region_constraints: &mut Vec<QueryRegionConstraint<'tcx>>,
+        output_query_region_constraints: &mut QueryRegionConstraints<'tcx>,
     ) -> InferResult<'tcx, R>
     where
         R: Debug + TypeFoldable<'tcx>,
@@ -287,7 +287,7 @@ pub fn instantiate_nll_query_response_and_region_obligations<R>(
         let result_subst =
             self.query_response_substitution_guess(cause, original_values, query_response);
 
-        // Compute `QueryRegionConstraint` values that unify each of
+        // Compute `QueryOutlivesConstraint` values that unify each of
         // the original values `v_o` that was canonicalized into a
         // variable...
         let mut obligations = vec![];
@@ -306,8 +306,10 @@ pub fn instantiate_nll_query_response_and_region_obligations<R>(
                     // To make `v_o = v_r`, we emit `v_o: v_r` and `v_r: v_o`.
                     if v_o != v_r {
                         output_query_region_constraints
+                            .outlives
                             .push(ty::Binder::dummy(ty::OutlivesPredicate(v_o.into(), v_r)));
                         output_query_region_constraints
+                            .outlives
                             .push(ty::Binder::dummy(ty::OutlivesPredicate(v_r.into(), v_o)));
                     }
                 }
@@ -333,12 +335,12 @@ pub fn instantiate_nll_query_response_and_region_obligations<R>(
         }
 
         // ...also include the other query region constraints from the query.
-        output_query_region_constraints.extend(
-            query_response.value.region_constraints.iter().filter_map(|r_c| {
+        output_query_region_constraints.outlives.extend(
+            query_response.value.region_constraints.outlives.iter().filter_map(|r_c| {
                 let r_c = substitute_value(self.tcx, &result_subst, r_c);
 
                 // Screen out `'a: 'a` cases -- we skip the binder here but
-                // only care the inner values to one another, so they are still at
+                // only compare the inner values to one another, so they are still at
                 // consistent binding levels.
                 let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder();
                 if k1 != r2.into() {
@@ -349,6 +351,13 @@ pub fn instantiate_nll_query_response_and_region_obligations<R>(
             })
         );
 
+        // ...also include the query member constraints.
+        output_query_region_constraints.member_constraints.extend(
+            query_response.value.region_constraints.member_constraints.iter().map(|p_c| {
+                substitute_value(self.tcx, &result_subst, p_c)
+            })
+        );
+
         let user_result: R =
             query_response.substitute_projected(self.tcx, &result_subst, |q_r| &q_r.value);
 
@@ -560,11 +569,11 @@ fn unify_query_response_substitution_guess<R>(
 
     /// Converts the region constraints resulting from a query into an
     /// iterator of obligations.
-    fn query_region_constraints_into_obligations<'a>(
+    fn query_outlives_constraints_into_obligations<'a>(
         &'a self,
         cause: &'a ObligationCause<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
-        unsubstituted_region_constraints: &'a [QueryRegionConstraint<'tcx>],
+        unsubstituted_region_constraints: &'a [QueryOutlivesConstraint<'tcx>],
         result_subst: &'a CanonicalVarValues<'tcx>,
     ) -> impl Iterator<Item = PredicateObligation<'tcx>> + 'a + Captures<'tcx> {
         unsubstituted_region_constraints
@@ -645,15 +654,16 @@ fn unify_canonical_vars(
 
 /// Given the region obligations and constraints scraped from the infcx,
 /// creates query region constraints.
-pub fn make_query_outlives<'tcx>(
+pub fn make_query_region_constraints<'tcx>(
     tcx: TyCtxt<'tcx>,
     outlives_obligations: impl Iterator<Item = (Ty<'tcx>, ty::Region<'tcx>)>,
     region_constraints: &RegionConstraintData<'tcx>,
-) -> Vec<QueryRegionConstraint<'tcx>> {
+) -> QueryRegionConstraints<'tcx> {
     let RegionConstraintData {
         constraints,
         verifys,
         givens,
+        member_constraints,
     } = region_constraints;
 
     assert!(verifys.is_empty());
@@ -684,5 +694,5 @@ pub fn make_query_outlives<'tcx>(
         )
         .collect();
 
-    outlives
+    QueryRegionConstraints { outlives, member_constraints: member_constraints.clone() }
 }
index 65225163a25a47111160a511f6c8374e2686d92b..cbfb048c064a2c2e4d3b91d72c632bf1cfb9f402 100644 (file)
@@ -53,6 +53,7 @@
 use crate::hir;
 use crate::hir::def_id::DefId;
 use crate::hir::Node;
+use crate::infer::opaque_types;
 use crate::middle::region;
 use crate::traits::{ObligationCause, ObligationCauseCode};
 use crate::ty::error::TypeError;
@@ -375,6 +376,23 @@ pub fn report_region_errors(
                             );
                         }
                     }
+
+                    RegionResolutionError::MemberConstraintFailure {
+                        opaque_type_def_id,
+                        hidden_ty,
+                        member_region,
+                        span: _,
+                        choice_regions: _,
+                    } => {
+                        let hidden_ty = self.resolve_vars_if_possible(&hidden_ty);
+                        opaque_types::unexpected_hidden_region_diagnostic(
+                            self.tcx,
+                            Some(region_scope_tree),
+                            opaque_type_def_id,
+                            hidden_ty,
+                            member_region,
+                        ).emit();
+                    }
                 }
             }
         }
@@ -411,7 +429,8 @@ fn process_errors(
         let is_bound_failure = |e: &RegionResolutionError<'tcx>| match *e {
             RegionResolutionError::GenericBoundFailure(..) => true,
             RegionResolutionError::ConcreteFailure(..)
-            | RegionResolutionError::SubSupConflict(..) => false,
+                | RegionResolutionError::SubSupConflict(..)
+                | RegionResolutionError::MemberConstraintFailure { .. } => false,
         };
 
         let mut errors = if errors.iter().all(|e| is_bound_failure(e)) {
@@ -429,6 +448,7 @@ fn process_errors(
             RegionResolutionError::ConcreteFailure(ref sro, _, _) => sro.span(),
             RegionResolutionError::GenericBoundFailure(ref sro, _, _) => sro.span(),
             RegionResolutionError::SubSupConflict(_, ref rvo, _, _, _, _) => rvo.span(),
+            RegionResolutionError::MemberConstraintFailure { span, .. } => span,
         });
         errors
     }
index 283af94b89b4841604bfdd19bdbcbae273f5e6bf..34f3b8a2c720586ceeddba74cb867633be1b8cfd 100644 (file)
@@ -139,12 +139,7 @@ fn visit_ty(&mut self, arg: &'tcx hir::Ty) {
                     // error. We will then search the function parameters for a bound
                     // region at the right depth with the same index
                     (Some(rl::Region::EarlyBound(_, id, _)), ty::BrNamed(def_id, _)) => {
-                        debug!(
-                            "EarlyBound self.infcx.tcx.hir().local_def_id(id)={:?} \
-                             def_id={:?}",
-                            id,
-                            def_id
-                        );
+                        debug!("EarlyBound id={:?} def_id={:?}", id, def_id);
                         if id == def_id {
                             self.found_type = Some(arg);
                             return; // we can stop visiting now
@@ -162,8 +157,7 @@ fn visit_ty(&mut self, arg: &'tcx hir::Ty) {
                             "FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}",
                             debruijn_index
                         );
-                        debug!("self.infcx.tcx.hir().local_def_id(id)={:?}", id);
-                        debug!("def_id={:?}", def_id);
+                        debug!("LateBound id={:?} def_id={:?}", id, def_id);
                         if debruijn_index == self.current_index && id == def_id {
                             self.found_type = Some(arg);
                             return; // we can stop visiting now
@@ -231,12 +225,7 @@ fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) {
             }
 
             (Some(rl::Region::EarlyBound(_, id, _)), ty::BrNamed(def_id, _)) => {
-                debug!(
-                    "EarlyBound self.infcx.tcx.hir().local_def_id(id)={:?} \
-                     def_id={:?}",
-                    id,
-                    def_id
-                );
+                debug!("EarlyBound id={:?} def_id={:?}", id, def_id);
                 if id == def_id {
                     self.found_it = true;
                     return; // we can stop visiting now
index 2613f4c7c2ae3bc2d8c855d470a4af5c9cdc09d6..d06c4434b3aaf8d4a1b5c9eb003ce63e188dd97c 100644 (file)
@@ -1,13 +1,20 @@
 //! Lexical region resolution.
 
+use crate::hir::def_id::DefId;
 use crate::infer::region_constraints::Constraint;
 use crate::infer::region_constraints::GenericKind;
+use crate::infer::region_constraints::MemberConstraint;
 use crate::infer::region_constraints::RegionConstraintData;
 use crate::infer::region_constraints::VarInfos;
 use crate::infer::region_constraints::VerifyBound;
 use crate::infer::RegionVariableOrigin;
 use crate::infer::SubregionOrigin;
 use crate::middle::free_region::RegionRelations;
+use crate::ty::fold::TypeFoldable;
+use crate::ty::{self, Ty, TyCtxt};
+use crate::ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic};
+use crate::ty::{ReLateBound, RePlaceholder, ReScope, ReVar};
+use crate::ty::{Region, RegionVid};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::graph::implementation::{
     Direction, Graph, NodeIndex, INCOMING, OUTGOING,
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 use smallvec::SmallVec;
 use std::fmt;
-use std::u32;
-use crate::ty::fold::TypeFoldable;
-use crate::ty::{self, Ty, TyCtxt};
-use crate::ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic};
-use crate::ty::{ReLateBound, ReScope, RePlaceholder, ReVar};
-use crate::ty::{Region, RegionVid};
+use syntax_pos::Span;
 
 mod graphviz;
 
@@ -36,11 +38,7 @@ pub fn resolve<'tcx>(
 ) -> (LexicalRegionResolutions<'tcx>, Vec<RegionResolutionError<'tcx>>) {
     debug!("RegionConstraintData: resolve_regions()");
     let mut errors = vec![];
-    let mut resolver = LexicalResolver {
-        region_rels,
-        var_infos,
-        data,
-    };
+    let mut resolver = LexicalResolver { region_rels, var_infos, data };
     let values = resolver.infer_variable_values(&mut errors);
     (values, errors)
 }
@@ -84,6 +82,17 @@ pub enum RegionResolutionError<'tcx> {
         SubregionOrigin<'tcx>,
         Region<'tcx>,
     ),
+
+    /// Indicates a failure of a `MemberConstraint`. These arise during
+    /// impl trait processing explicitly -- basically, the impl trait's hidden type
+    /// included some region that it was not supposed to.
+    MemberConstraintFailure {
+        span: Span,
+        opaque_type_def_id: DefId,
+        hidden_ty: Ty<'tcx>,
+        member_region: Region<'tcx>,
+        choice_regions: Vec<Region<'tcx>>,
+    },
 }
 
 struct RegionAndOrigin<'tcx> {
@@ -121,7 +130,12 @@ fn infer_variable_values(
 
         let graph = self.construct_graph();
         self.expand_givens(&graph);
-        self.expansion(&mut var_data);
+        loop {
+            self.expansion(&mut var_data);
+            if !self.enforce_member_constraints(&graph, &mut var_data) {
+                break;
+            }
+        }
         self.collect_errors(&mut var_data, errors);
         self.collect_var_errors(&var_data, &graph, errors);
         var_data
@@ -136,7 +150,7 @@ fn num_vars(&self) -> usize {
     fn construct_var_data(&self, tcx: TyCtxt<'tcx>) -> LexicalRegionResolutions<'tcx> {
         LexicalRegionResolutions {
             error_region: tcx.lifetimes.re_static,
-            values: IndexVec::from_elem_n(VarValue::Value(tcx.lifetimes.re_empty), self.num_vars())
+            values: IndexVec::from_elem_n(VarValue::Value(tcx.lifetimes.re_empty), self.num_vars()),
         }
     }
 
@@ -182,6 +196,113 @@ fn expand_givens(&mut self, graph: &RegionGraph<'_>) {
         }
     }
 
+    /// Enforce all member constraints and return true if anything
+    /// changed. See `enforce_member_constraint` for more details.
+    fn enforce_member_constraints(
+        &self,
+        graph: &RegionGraph<'tcx>,
+        var_values: &mut LexicalRegionResolutions<'tcx>,
+    ) -> bool {
+        // Note: we don't use the `any` combinator because we don't
+        // want to stop at the first constraint that makes a change.
+        let mut any_changed = false;
+        for member_constraint in &self.data.member_constraints {
+            if self.enforce_member_constraint(graph, member_constraint, var_values) {
+                any_changed = true;
+            }
+        }
+        any_changed
+    }
+
+    /// Enforce a constraint like
+    ///
+    /// ```
+    /// 'r member of ['c...]
+    /// ```
+    ///
+    /// We look for all choice regions from the list `'c...` that:
+    ///
+    /// (a) are greater than the current value of `'r` (which is a lower bound)
+    ///
+    /// and
+    ///
+    /// (b) are compatible with the upper bounds of `'r` that we can
+    /// find by traversing the graph.
+    ///
+    /// From that list, we look for a *minimal* option `'c_min`. If we
+    /// find one, then we can enforce that `'r: 'c_min`.
+    fn enforce_member_constraint(
+        &self,
+        graph: &RegionGraph<'tcx>,
+        member_constraint: &MemberConstraint<'tcx>,
+        var_values: &mut LexicalRegionResolutions<'tcx>,
+    ) -> bool {
+        debug!("enforce_member_constraint(member_constraint={:#?})", member_constraint);
+
+        // The constraint is some inference variable (`vid`) which
+        // must be equal to one of the options.
+        let member_vid = match member_constraint.member_region {
+            ty::ReVar(vid) => *vid,
+            _ => return false,
+        };
+
+        // The current value of `vid` is a lower bound LB -- i.e., we
+        // know that `LB <= vid` must be true.
+        let member_lower_bound: ty::Region<'tcx> = match var_values.value(member_vid) {
+            VarValue::ErrorValue => return false,
+            VarValue::Value(r) => r,
+        };
+
+        // Find all the "upper bounds" -- that is, each region `b` such that
+        // `r0 <= b` must hold.
+        let (member_upper_bounds, _) = self.collect_concrete_regions(
+            graph,
+            member_vid,
+            OUTGOING,
+            None,
+        );
+
+        // Get an iterator over the *available choice* -- that is,
+        // each choice region `c` where `lb <= c` and `c <= ub` for all the
+        // upper bounds `ub`.
+        debug!("enforce_member_constraint: upper_bounds={:#?}", member_upper_bounds);
+        let mut options = member_constraint.choice_regions.iter().filter(|option| {
+            self.sub_concrete_regions(member_lower_bound, option)
+                && member_upper_bounds
+                    .iter()
+                    .all(|upper_bound| self.sub_concrete_regions(option, upper_bound.region))
+        });
+
+        // If there is more than one option, we only make a choice if
+        // there is a single *least* choice -- i.e., some available
+        // region that is `<=` all the others.
+        let mut least_choice: ty::Region<'tcx> = match options.next() {
+            Some(&r) => r,
+            None => return false,
+        };
+        debug!("enforce_member_constraint: least_choice={:?}", least_choice);
+        for &option in options {
+            debug!("enforce_member_constraint: option={:?}", option);
+            if !self.sub_concrete_regions(least_choice, option) {
+                if self.sub_concrete_regions(option, least_choice) {
+                    debug!("enforce_member_constraint: new least choice");
+                    least_choice = option;
+                } else {
+                    debug!("enforce_member_constraint: no least choice");
+                    return false;
+                }
+            }
+        }
+
+        debug!("enforce_member_constraint: final least choice = {:?}", least_choice);
+        if least_choice != member_lower_bound {
+            *var_values.value_mut(member_vid) = VarValue::Value(least_choice);
+            true
+        } else {
+            false
+        }
+    }
+
     fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
         self.iterate_until_fixed_point("Expansion", |constraint| {
             debug!("expansion: constraint={:?}", constraint);
@@ -196,7 +317,7 @@ fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
                         let b_data = var_values.value_mut(b_vid);
                         let retain = match *b_data {
                             VarValue::Value(ReStatic) | VarValue::ErrorValue => false,
-                            _ => true
+                            _ => true,
                         };
                         (a_region, b_vid, b_data, retain)
                     }
@@ -204,7 +325,7 @@ fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
                 Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => {
                     // These constraints are checked after expansion
                     // is done, in `collect_errors`.
-                    return (false, false)
+                    return (false, false);
                 }
             };
 
@@ -226,16 +347,16 @@ fn expand_node(
 
         match *a_region {
             // Check if this relationship is implied by a given.
-            ty::ReEarlyBound(_) | ty::ReFree(_) => if self.data.givens.contains(&(a_region, b_vid))
-            {
-                debug!("given");
-                return false;
-            },
+            ty::ReEarlyBound(_) | ty::ReFree(_) => {
+                if self.data.givens.contains(&(a_region, b_vid)) {
+                    debug!("given");
+                    return false;
+                }
+            }
 
             _ => {}
         }
 
-
         match *b_data {
             VarValue::Value(cur_region) => {
                 // Identical scopes can show up quite often, if the fixed point
@@ -267,10 +388,7 @@ fn expand_node(
                     }
                 }
 
-                debug!(
-                    "Expanding value of {:?} from {:?} to {:?}",
-                    b_vid, cur_region, lub
-                );
+                debug!("Expanding value of {:?} from {:?} to {:?}", b_vid, cur_region, lub);
 
                 *b_data = VarValue::Value(lub);
                 return true;
@@ -282,6 +400,12 @@ fn expand_node(
         }
     }
 
+    /// True if `a <= b`, but not defined over inference variables.
+    fn sub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> bool {
+        self.lub_concrete_regions(a, b) == b
+    }
+
+    /// Returns the smallest region `c` such that `a <= c` and `b <= c`.
     fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
         let tcx = self.tcx();
 
@@ -321,17 +445,16 @@ fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx>
                 // at least as big as fr.scope".  So, we can
                 // reasonably compare free regions and scopes:
                 let fr_scope = match (a, b) {
-                    (&ReEarlyBound(ref br), _) | (_, &ReEarlyBound(ref br)) => self.region_rels
-                        .region_scope_tree
-                        .early_free_scope(self.tcx(), br),
-                    (&ReFree(ref fr), _) | (_, &ReFree(ref fr)) => self.region_rels
-                        .region_scope_tree
-                        .free_scope(self.tcx(), fr),
+                    (&ReEarlyBound(ref br), _) | (_, &ReEarlyBound(ref br)) => {
+                        self.region_rels.region_scope_tree.early_free_scope(self.tcx(), br)
+                    }
+                    (&ReFree(ref fr), _) | (_, &ReFree(ref fr)) => {
+                        self.region_rels.region_scope_tree.free_scope(self.tcx(), fr)
+                    }
                     _ => bug!(),
                 };
-                let r_id = self.region_rels
-                    .region_scope_tree
-                    .nearest_common_ancestor(fr_scope, s_id);
+                let r_id =
+                    self.region_rels.region_scope_tree.nearest_common_ancestor(fr_scope, s_id);
                 if r_id == fr_scope {
                     // if the free region's scope `fr.scope` is bigger than
                     // the scope region `s_id`, then the LUB is the free
@@ -352,9 +475,7 @@ fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx>
                 // The region corresponding to an outer block is a
                 // subtype of the region corresponding to an inner
                 // block.
-                let lub = self.region_rels
-                    .region_scope_tree
-                    .nearest_common_ancestor(a_id, b_id);
+                let lub = self.region_rels.region_scope_tree.nearest_common_ancestor(a_id, b_id);
                 tcx.mk_region(ReScope(lub))
             }
 
@@ -365,11 +486,13 @@ fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx>
 
             // For these types, we cannot define any additional
             // relationship:
-            (&RePlaceholder(..), _) | (_, &RePlaceholder(..)) => if a == b {
-                a
-            } else {
-                tcx.lifetimes.re_static
-            },
+            (&RePlaceholder(..), _) | (_, &RePlaceholder(..)) => {
+                if a == b {
+                    a
+                } else {
+                    tcx.lifetimes.re_static
+                }
+            }
         }
     }
 
@@ -382,10 +505,7 @@ fn collect_errors(
         errors: &mut Vec<RegionResolutionError<'tcx>>,
     ) {
         for (constraint, origin) in &self.data.constraints {
-            debug!(
-                "collect_errors: constraint={:?} origin={:?}",
-                constraint, origin
-            );
+            debug!("collect_errors: constraint={:?} origin={:?}", constraint, origin);
             match *constraint {
                 Constraint::RegSubVar(..) | Constraint::VarSubVar(..) => {
                     // Expansion will ensure that these constraints hold. Ignore.
@@ -433,6 +553,25 @@ fn collect_errors(
             }
         }
 
+        // Check that all member constraints are satisfied.
+        for member_constraint in &self.data.member_constraints {
+            let member_region = var_data.normalize(self.tcx(), member_constraint.member_region);
+            let choice_regions = member_constraint
+                .choice_regions
+                .iter()
+                .map(|&choice_region| var_data.normalize(self.tcx(), choice_region));
+            if !choice_regions.clone().any(|choice_region| member_region == choice_region) {
+                let span = self.tcx().def_span(member_constraint.opaque_type_def_id);
+                errors.push(RegionResolutionError::MemberConstraintFailure {
+                    span,
+                    opaque_type_def_id: member_constraint.opaque_type_def_id,
+                    hidden_ty: member_constraint.hidden_ty,
+                    member_region,
+                    choice_regions: choice_regions.collect(),
+                });
+            }
+        }
+
         for verify in &self.data.verifys {
             debug!("collect_errors: verify={:?}", verify);
             let sub = var_data.normalize(self.tcx(), verify.region);
@@ -483,34 +622,35 @@ fn collect_var_errors(
         // idea is to report errors that derive from independent
         // regions of the graph, but not those that derive from
         // overlapping locations.
-        let mut dup_vec = vec![u32::MAX; self.num_vars()];
+        let mut dup_vec = IndexVec::from_elem_n(None, self.num_vars());
 
         for (node_vid, value) in var_data.values.iter_enumerated() {
             match *value {
                 VarValue::Value(_) => { /* Inference successful */ }
                 VarValue::ErrorValue => {
-                    /* Inference impossible: this value contains
-                       inconsistent constraints.
-
-                       I think that in this case we should report an
-                       error now -- unlike the case above, we can't
-                       wait to see whether the user needs the result
-                       of this variable. The reason is that the mere
-                       existence of this variable implies that the
-                       region graph is inconsistent, whether or not it
-                       is used.
-
-                       For example, we may have created a region
-                       variable that is the GLB of two other regions
-                       which do not have a GLB. Even if that variable
-                       is not used, it implies that those two regions
-                       *should* have a GLB.
-
-                       At least I think this is true. It may be that
-                       the mere existence of a conflict in a region variable
-                       that is not used is not a problem, so if this rule
-                       starts to create problems we'll have to revisit
-                       this portion of the code and think hard about it. =) */
+                    // Inference impossible: this value contains
+                    // inconsistent constraints.
+                    //
+                    // I think that in this case we should report an
+                    // error now -- unlike the case above, we can't
+                    // wait to see whether the user needs the result
+                    // of this variable. The reason is that the mere
+                    // existence of this variable implies that the
+                    // region graph is inconsistent, whether or not it
+                    // is used.
+                    //
+                    // For example, we may have created a region
+                    // variable that is the GLB of two other regions
+                    // which do not have a GLB. Even if that variable
+                    // is not used, it implies that those two regions
+                    // *should* have a GLB.
+                    //
+                    // At least I think this is true. It may be that
+                    // the mere existence of a conflict in a region
+                    // variable that is not used is not a problem, so
+                    // if this rule starts to create problems we'll
+                    // have to revisit this portion of the code and
+                    // think hard about it. =) -- nikomatsakis
                     self.collect_error_for_expanding_node(graph, &mut dup_vec, node_vid, errors);
                 }
             }
@@ -562,16 +702,16 @@ fn construct_graph(&self) -> RegionGraph<'tcx> {
     fn collect_error_for_expanding_node(
         &self,
         graph: &RegionGraph<'tcx>,
-        dup_vec: &mut [u32],
+        dup_vec: &mut IndexVec<RegionVid, Option<RegionVid>>,
         node_idx: RegionVid,
         errors: &mut Vec<RegionResolutionError<'tcx>>,
     ) {
         // Errors in expanding nodes result from a lower-bound that is
         // not contained by an upper-bound.
         let (mut lower_bounds, lower_dup) =
-            self.collect_concrete_regions(graph, node_idx, INCOMING, dup_vec);
+            self.collect_concrete_regions(graph, node_idx, INCOMING, Some(dup_vec));
         let (mut upper_bounds, upper_dup) =
-            self.collect_concrete_regions(graph, node_idx, OUTGOING, dup_vec);
+            self.collect_concrete_regions(graph, node_idx, OUTGOING, Some(dup_vec));
 
         if lower_dup || upper_dup {
             return;
@@ -604,9 +744,7 @@ fn region_order_key(x: &RegionAndOrigin<'_>) -> u8 {
             };
 
             for upper_bound in &upper_bounds {
-                if !self.region_rels
-                    .is_subregion_of(effective_lower_bound, upper_bound.region)
-                {
+                if !self.region_rels.is_subregion_of(effective_lower_bound, upper_bound.region) {
                     let origin = self.var_infos[node_idx].origin.clone();
                     debug!(
                         "region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \
@@ -643,7 +781,7 @@ fn collect_concrete_regions(
         graph: &RegionGraph<'tcx>,
         orig_node_idx: RegionVid,
         dir: Direction,
-        dup_vec: &mut [u32],
+        mut dup_vec: Option<&mut IndexVec<RegionVid, Option<RegionVid>>>,
     ) -> (Vec<RegionAndOrigin<'tcx>>, bool) {
         struct WalkState<'tcx> {
             set: FxHashSet<RegionVid>,
@@ -667,23 +805,23 @@ struct WalkState<'tcx> {
             let node_idx = state.stack.pop().unwrap();
 
             // check whether we've visited this node on some previous walk
-            if dup_vec[node_idx.index() as usize] == u32::MAX {
-                dup_vec[node_idx.index() as usize] = orig_node_idx.index() as u32;
-            } else if dup_vec[node_idx.index() as usize] != orig_node_idx.index() as u32 {
-                state.dup_found = true;
-            }
+            if let Some(dup_vec) = &mut dup_vec {
+                if dup_vec[node_idx].is_none() {
+                    dup_vec[node_idx] = Some(orig_node_idx);
+                } else if dup_vec[node_idx] != Some(orig_node_idx) {
+                    state.dup_found = true;
+                }
 
-            debug!(
-                "collect_concrete_regions(orig_node_idx={:?}, node_idx={:?})",
-                orig_node_idx, node_idx
-            );
+                debug!(
+                    "collect_concrete_regions(orig_node_idx={:?}, node_idx={:?})",
+                    orig_node_idx, node_idx
+                );
+            }
 
             process_edges(&self.data, &mut state, graph, node_idx, dir);
         }
 
-        let WalkState {
-            result, dup_found, ..
-        } = state;
+        let WalkState { result, dup_found, .. } = state;
         return (result, dup_found);
 
         fn process_edges<'tcx>(
@@ -699,11 +837,7 @@ fn process_edges<'tcx>(
             for (_, edge) in graph.adjacent_edges(source_node_index, dir) {
                 match edge.data {
                     Constraint::VarSubVar(from_vid, to_vid) => {
-                        let opp_vid = if from_vid == source_vid {
-                            to_vid
-                        } else {
-                            from_vid
-                        };
+                        let opp_vid = if from_vid == source_vid { to_vid } else { from_vid };
                         if state.set.insert(opp_vid) {
                             state.stack.push(opp_vid);
                         }
@@ -726,7 +860,8 @@ fn process_edges<'tcx>(
     }
 
     fn iterate_until_fixed_point<F>(&self, tag: &str, mut body: F)
-        where F: FnMut(&Constraint<'tcx>) -> (bool, bool),
+    where
+        F: FnMut(&Constraint<'tcx>) -> (bool, bool),
     {
         let mut constraints: SmallVec<[_; 16]> = self.data.constraints.keys().collect();
         let mut iteration = 0;
@@ -760,17 +895,17 @@ fn bound_is_met(
                     && self.bound_is_met(b, var_values, generic_ty, min)
             }
 
-            VerifyBound::OutlivedBy(r) =>
-                self.region_rels.is_subregion_of(
-                    min,
-                    var_values.normalize(self.tcx(), r),
-                ),
+            VerifyBound::OutlivedBy(r) => {
+                self.region_rels.is_subregion_of(min, var_values.normalize(self.tcx(), r))
+            }
 
-            VerifyBound::AnyBound(bs) => bs.iter()
-                .any(|b| self.bound_is_met(b, var_values, generic_ty, min)),
+            VerifyBound::AnyBound(bs) => {
+                bs.iter().any(|b| self.bound_is_met(b, var_values, generic_ty, min))
+            }
 
-            VerifyBound::AllBounds(bs) => bs.iter()
-                .all(|b| self.bound_is_met(b, var_values, generic_ty, min)),
+            VerifyBound::AllBounds(bs) => {
+                bs.iter().all(|b| self.bound_is_met(b, var_values, generic_ty, min))
+            }
         }
     }
 }
index 9a5c726901fe87ea235f70ba28edd9dac60c6b74..663acd67dcd839b147f5e4b3a7fc263a70e0a0af 100644 (file)
@@ -26,6 +26,7 @@
 use crate::util::nodemap::FxHashMap;
 
 use errors::DiagnosticBuilder;
+use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::unify as ut;
 use std::cell::{Cell, Ref, RefCell, RefMut};
 use std::collections::BTreeMap;
@@ -904,6 +905,21 @@ pub fn sub_regions(
             .make_subregion(origin, a, b);
     }
 
+    /// Require that the region `r` be equal to one of the regions in
+    /// the set `regions`.
+    pub fn member_constraint(
+        &self,
+        opaque_type_def_id: DefId,
+        definition_span: Span,
+        hidden_ty: Ty<'tcx>,
+        region: ty::Region<'tcx>,
+        in_regions: &Lrc<Vec<ty::Region<'tcx>>>,
+    ) {
+        debug!("member_constraint({:?} <: {:?})", region, in_regions);
+        self.borrow_region_constraints()
+            .member_constraint(opaque_type_def_id, definition_span, hidden_ty, region, in_regions);
+    }
+
     pub fn subtype_predicate(
         &self,
         cause: &ObligationCause<'tcx>,
@@ -1456,7 +1472,7 @@ pub fn type_is_copy_modulo_regions(
         // Even if the type may have no inference variables, during
         // type-checking closure types are in local tables only.
         if !self.in_progress_tables.is_some() || !ty.has_closure_types() {
-            if let Some((param_env, ty)) = self.tcx.lift_to_global(&(param_env, ty)) {
+            if !(param_env, ty).has_local_value() {
                 return ty.is_copy_modulo_regions(self.tcx.global_tcx(), param_env, span);
             }
         }
index a1a93eb5521387ee03fcbd30c2f1371e3a6d80ee..a0621af053783865d46f234fea1e9aff97b8a0c2 100644 (file)
@@ -364,7 +364,7 @@ fn relate_ty_var<PAIR: VidValuePair<'tcx>>(
         // been fully instantiated and hence the set of scopes we have
         // doesn't matter -- just to be sure, put an empty vector
         // in there.
-        let old_a_scopes = ::std::mem::replace(pair.vid_scopes(self), vec![]);
+        let old_a_scopes = ::std::mem::take(pair.vid_scopes(self));
 
         // Relate the generalized kind to the original one.
         let result = pair.relate_generalized_ty(self, generalized_ty);
index 6b6dbd43167fa3fadad4d89583a6a48a770295f6..c127e667ce9e95f73b4da61bb19b658de2569273 100644 (file)
@@ -1,16 +1,19 @@
-use rustc_data_structures::fx::FxHashMap;
-use syntax_pos::Span;
-
-use crate::hir::def_id::DefId;
 use crate::hir;
+use crate::hir::def_id::DefId;
 use crate::hir::Node;
-use crate::infer::{self, InferCtxt, InferOk, TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::outlives::free_region_map::FreeRegionRelations;
+use crate::infer::{self, InferCtxt, InferOk, TypeVariableOrigin, TypeVariableOriginKind};
+use crate::middle::region;
 use crate::traits::{self, PredicateObligation};
-use crate::ty::{self, Ty, TyCtxt, GenericParamDefKind};
 use crate::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor};
-use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, UnpackedKind};
+use crate::ty::subst::{InternalSubsts, Kind, SubstsRef, UnpackedKind};
+use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt};
 use crate::util::nodemap::DefIdMap;
+use errors::DiagnosticBuilder;
+use rustc::session::config::nightly_options;
+use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::sync::Lrc;
+use syntax_pos::Span;
 
 pub type OpaqueTypeMap<'tcx> = DefIdMap<OpaqueTypeDecl<'tcx>>;
 
@@ -32,6 +35,20 @@ pub struct OpaqueTypeDecl<'tcx> {
     /// then `substs` would be `['a, T]`.
     pub substs: SubstsRef<'tcx>,
 
+    /// The span of this particular definition of the opaque type.  So
+    /// for example:
+    ///
+    /// ```
+    /// existential type Foo;
+    /// fn bar() -> Foo {
+    ///             ^^^ This is the span we are looking for!
+    /// ```
+    ///
+    /// In cases where the fn returns `(impl Trait, impl Trait)` or
+    /// other such combinations, the result is currently
+    /// over-approximated, but better than nothing.
+    pub definition_span: Span,
+
     /// The type variable that represents the value of the abstract type
     /// that we require. In other words, after we compile this function,
     /// we will be created a constraint like:
@@ -98,30 +115,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     /// - `param_env` -- the in-scope parameter environment to be used for
     ///   obligations
     /// - `value` -- the value within which we are instantiating opaque types
+    /// - `value_span` -- the span where the value came from, used in error reporting
     pub fn instantiate_opaque_types<T: TypeFoldable<'tcx>>(
         &self,
         parent_def_id: DefId,
         body_id: hir::HirId,
         param_env: ty::ParamEnv<'tcx>,
         value: &T,
+        value_span: Span,
     ) -> InferOk<'tcx, (T, OpaqueTypeMap<'tcx>)> {
-        debug!("instantiate_opaque_types(value={:?}, parent_def_id={:?}, body_id={:?}, \
-                param_env={:?})",
-               value, parent_def_id, body_id, param_env,
+        debug!(
+            "instantiate_opaque_types(value={:?}, parent_def_id={:?}, body_id={:?}, \
+             param_env={:?})",
+            value, parent_def_id, body_id, param_env,
         );
         let mut instantiator = Instantiator {
             infcx: self,
             parent_def_id,
             body_id,
             param_env,
+            value_span,
             opaque_types: Default::default(),
             obligations: vec![],
         };
         let value = instantiator.instantiate_opaque_types_in_map(value);
-        InferOk {
-            value: (value, instantiator.opaque_types),
-            obligations: instantiator.obligations,
-        }
+        InferOk { value: (value, instantiator.opaque_types), obligations: instantiator.obligations }
     }
 
     /// Given the map `opaque_types` containing the existential `impl
@@ -216,13 +234,13 @@ pub fn instantiate_opaque_types<T: TypeFoldable<'tcx>>(
     ///
     /// # The Solution
     ///
-    /// We make use of the constraint that we *do* have in the `<=`
-    /// relation. To do that, we find the "minimum" of all the
-    /// arguments that appear in the substs: that is, some region
-    /// which is less than all the others. In the case of `Foo1<'a>`,
-    /// that would be `'a` (it's the only choice, after all). Then we
-    /// apply that as a least bound to the variables (e.g., `'a <=
-    /// '0`).
+    /// We generally prefer to make `<=` constraints, since they
+    /// integrate best into the region solver. To do that, we find the
+    /// "minimum" of all the arguments that appear in the substs: that
+    /// is, some region which is less than all the others. In the case
+    /// of `Foo1<'a>`, that would be `'a` (it's the only choice, after
+    /// all). Then we apply that as a least bound to the variables
+    /// (e.g., `'a <= '0`).
     ///
     /// In some cases, there is no minimum. Consider this example:
     ///
@@ -230,8 +248,32 @@ pub fn instantiate_opaque_types<T: TypeFoldable<'tcx>>(
     /// fn baz<'a, 'b>() -> impl Trait<'a, 'b> { ... }
     /// ```
     ///
-    /// Here we would report an error, because `'a` and `'b` have no
-    /// relation to one another.
+    /// Here we would report a more complex "in constraint", like `'r
+    /// in ['a, 'b, 'static]` (where `'r` is some regon appearing in
+    /// the hidden type).
+    ///
+    /// # Constrain regions, not the hidden concrete type
+    ///
+    /// Note that generating constraints on each region `Rc` is *not*
+    /// the same as generating an outlives constraint on `Tc` iself.
+    /// For example, if we had a function like this:
+    ///
+    /// ```rust
+    /// fn foo<'a, T>(x: &'a u32, y: T) -> impl Foo<'a> {
+    ///   (x, y)
+    /// }
+    ///
+    /// // Equivalent to:
+    /// existential type FooReturn<'a, T>: Foo<'a>;
+    /// fn foo<'a, T>(..) -> FooReturn<'a, T> { .. }
+    /// ```
+    ///
+    /// then the hidden type `Tc` would be `(&'0 u32, T)` (where `'0`
+    /// is an inference variable). If we generated a constraint that
+    /// `Tc: 'a`, then this would incorrectly require that `T: 'a` --
+    /// but this is not necessary, because the existential type we
+    /// create will be allowed to reference `T`. So we only generate a
+    /// constraint that `'0: 'a`.
     ///
     /// # The `free_region_relations` parameter
     ///
@@ -274,6 +316,7 @@ pub fn constrain_opaque_types<FRR: FreeRegionRelations<'tcx>>(
         }
     }
 
+    /// See `constrain_opaque_types` for documentation.
     pub fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
         &self,
         def_id: DefId,
@@ -290,32 +333,25 @@ pub fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
 
         debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty);
 
-        let abstract_type_generics = tcx.generics_of(def_id);
+        let opaque_type_generics = tcx.generics_of(def_id);
 
         let span = tcx.def_span(def_id);
 
         // If there are required region bounds, we can use them.
         if opaque_defn.has_required_region_bounds {
             let predicates_of = tcx.predicates_of(def_id);
-            debug!(
-                "constrain_opaque_type: predicates: {:#?}",
-                predicates_of,
-            );
+            debug!("constrain_opaque_type: predicates: {:#?}", predicates_of,);
             let bounds = predicates_of.instantiate(tcx, opaque_defn.substs);
             debug!("constrain_opaque_type: bounds={:#?}", bounds);
             let opaque_type = tcx.mk_opaque(def_id, opaque_defn.substs);
 
-            let required_region_bounds = tcx.required_region_bounds(
-                opaque_type,
-                bounds.predicates,
-            );
+            let required_region_bounds = tcx.required_region_bounds(opaque_type, bounds.predicates);
             debug_assert!(!required_region_bounds.is_empty());
 
-            for region in required_region_bounds {
-                concrete_ty.visit_with(&mut OpaqueTypeOutlivesVisitor {
-                    infcx: self,
-                    least_region: region,
-                    span,
+            for required_region in required_region_bounds {
+                concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
+                    tcx: self.tcx,
+                    op: |r| self.sub_regions(infer::CallReturn(span), required_region, r),
                 });
             }
             return;
@@ -329,11 +365,12 @@ pub fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
         // `['a]` for the first impl trait and `'b` for the
         // second.
         let mut least_region = None;
-        for param in &abstract_type_generics.params {
+        for param in &opaque_type_generics.params {
             match param.kind {
                 GenericParamDefKind::Lifetime => {}
-                _ => continue
+                _ => continue,
             }
+
             // Get the value supplied for this region from the substs.
             let subst_arg = opaque_defn.substs.region_at(param.index as usize);
 
@@ -350,44 +387,21 @@ pub fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
                         least_region = Some(subst_arg);
                     } else {
                         // There are two regions (`lr` and
-                        // `subst_arg`) which are not relatable. We can't
-                        // find a best choice.
-                        let context_name = match opaque_defn.origin {
-                            hir::ExistTyOrigin::ExistentialType => "existential type",
-                            hir::ExistTyOrigin::ReturnImplTrait => "impl Trait",
-                            hir::ExistTyOrigin::AsyncFn => "async fn",
-                        };
-                        let msg = format!("ambiguous lifetime bound in `{}`", context_name);
-                        let mut err = self.tcx
-                            .sess
-                            .struct_span_err(span, &msg);
-
-                        let lr_name = lr.to_string();
-                        let subst_arg_name = subst_arg.to_string();
-                        let label_owned;
-                        let label = match (&*lr_name, &*subst_arg_name) {
-                            ("'_", "'_") => "the elided lifetimes here do not outlive one another",
-                            _ => {
-                                label_owned = format!(
-                                    "neither `{}` nor `{}` outlives the other",
-                                    lr_name,
-                                    subst_arg_name,
-                                );
-                                &label_owned
-                            }
-                        };
-                        err.span_label(span, label);
-
-                        if let hir::ExistTyOrigin::AsyncFn = opaque_defn.origin {
-                            err.note("multiple unrelated lifetimes are not allowed in \
-                                     `async fn`.");
-                            err.note("if you're using argument-position elided lifetimes, consider \
-                                switching to a single named lifetime.");
-                        }
-                        err.emit();
-
-                        least_region = Some(self.tcx.mk_region(ty::ReEmpty));
-                        break;
+                        // `subst_arg`) which are not relatable. We
+                        // can't find a best choice. Therefore,
+                        // instead of creating a single bound like
+                        // `'r: 'a` (which is our preferred choice),
+                        // we will create a "in bound" like `'r in
+                        // ['a, 'b, 'c]`, where `'a..'c` are the
+                        // regions that appear in the impl trait.
+                        return self.generate_member_constraint(
+                            concrete_ty,
+                            opaque_type_generics,
+                            opaque_defn,
+                            def_id,
+                            lr,
+                            subst_arg,
+                        );
                     }
                 }
             }
@@ -396,13 +410,121 @@ pub fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
         let least_region = least_region.unwrap_or(tcx.lifetimes.re_static);
         debug!("constrain_opaque_types: least_region={:?}", least_region);
 
-        concrete_ty.visit_with(&mut OpaqueTypeOutlivesVisitor {
-            infcx: self,
-            least_region,
-            span,
+        concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
+            tcx: self.tcx,
+            op: |r| self.sub_regions(infer::CallReturn(span), least_region, r),
         });
     }
 
+    /// As a fallback, we sometimes generate an "in constraint". For
+    /// a case like `impl Foo<'a, 'b>`, where `'a` and `'b` cannot be
+    /// related, we would generate a constraint `'r in ['a, 'b,
+    /// 'static]` for each region `'r` that appears in the hidden type
+    /// (i.e., it must be equal to `'a`, `'b`, or `'static`).
+    ///
+    /// `conflict1` and `conflict2` are the two region bounds that we
+    /// detected which were unrelated. They are used for diagnostics.
+    fn generate_member_constraint(
+        &self,
+        concrete_ty: Ty<'tcx>,
+        opaque_type_generics: &ty::Generics,
+        opaque_defn: &OpaqueTypeDecl<'tcx>,
+        opaque_type_def_id: DefId,
+        conflict1: ty::Region<'tcx>,
+        conflict2: ty::Region<'tcx>,
+    ) {
+        // For now, enforce a feature gate outside of async functions.
+        if self.member_constraint_feature_gate(
+            opaque_defn,
+            opaque_type_def_id,
+            conflict1,
+            conflict2,
+        ) {
+            return;
+        }
+
+        // Create the set of choice regions: each region in the hidden
+        // type can be equal to any of the region parameters of the
+        // opaque type definition.
+        let choice_regions: Lrc<Vec<ty::Region<'tcx>>> = Lrc::new(
+            opaque_type_generics
+                .params
+                .iter()
+                .filter(|param| match param.kind {
+                    GenericParamDefKind::Lifetime => true,
+                    GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => false,
+                })
+                .map(|param| opaque_defn.substs.region_at(param.index as usize))
+                .chain(std::iter::once(self.tcx.lifetimes.re_static))
+                .collect(),
+        );
+
+        concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
+            tcx: self.tcx,
+            op: |r| self.member_constraint(
+                opaque_type_def_id,
+                opaque_defn.definition_span,
+                concrete_ty,
+                r,
+                &choice_regions,
+            ),
+        });
+    }
+
+    /// Member constraints are presently feature-gated except for
+    /// async-await. We expect to lift this once we've had a bit more
+    /// time.
+    fn member_constraint_feature_gate(
+        &self,
+        opaque_defn: &OpaqueTypeDecl<'tcx>,
+        opaque_type_def_id: DefId,
+        conflict1: ty::Region<'tcx>,
+        conflict2: ty::Region<'tcx>,
+    ) -> bool {
+        // If we have `#![feature(member_constraints)]`, no problems.
+        if self.tcx.features().member_constraints {
+            return false;
+        }
+
+        let span = self.tcx.def_span(opaque_type_def_id);
+
+        // Without a feature-gate, we only generate member-constraints for async-await.
+        let context_name = match opaque_defn.origin {
+            // No feature-gate required for `async fn`.
+            hir::ExistTyOrigin::AsyncFn => return false,
+
+            // Otherwise, generate the label we'll use in the error message.
+            hir::ExistTyOrigin::ExistentialType => "existential type",
+            hir::ExistTyOrigin::ReturnImplTrait => "impl Trait",
+        };
+        let msg = format!("ambiguous lifetime bound in `{}`", context_name);
+        let mut err = self.tcx.sess.struct_span_err(span, &msg);
+
+        let conflict1_name = conflict1.to_string();
+        let conflict2_name = conflict2.to_string();
+        let label_owned;
+        let label = match (&*conflict1_name, &*conflict2_name) {
+            ("'_", "'_") => "the elided lifetimes here do not outlive one another",
+            _ => {
+                label_owned = format!(
+                    "neither `{}` nor `{}` outlives the other",
+                    conflict1_name, conflict2_name,
+                );
+                &label_owned
+            }
+        };
+        err.span_label(span, label);
+
+        if nightly_options::is_nightly_build() {
+            help!(err,
+                  "add #![feature(member_constraints)] to the crate attributes \
+                   to enable");
+        }
+
+        err.emit();
+        true
+    }
+
     /// Given the fully resolved, instantiated type for an opaque
     /// type, i.e., the value of an inference variable like C1 or C2
     /// (*), computes the "definition type" for an abstract type
@@ -456,23 +578,98 @@ pub fn infer_opaque_definition_from_instantiation(
         // Convert the type from the function into a type valid outside
         // the function, by replacing invalid regions with 'static,
         // after producing an error for each of them.
-        let definition_ty =
-            instantiated_ty.fold_with(&mut ReverseMapper::new(
-                self.tcx,
-                self.is_tainted_by_errors(),
-                def_id,
-                map,
-                instantiated_ty,
-            ));
-        debug!(
-            "infer_opaque_definition_from_instantiation: definition_ty={:?}",
-            definition_ty
-        );
+        let definition_ty = instantiated_ty.fold_with(&mut ReverseMapper::new(
+            self.tcx,
+            self.is_tainted_by_errors(),
+            def_id,
+            map,
+            instantiated_ty,
+        ));
+        debug!("infer_opaque_definition_from_instantiation: definition_ty={:?}", definition_ty);
 
         definition_ty
     }
 }
 
+pub fn unexpected_hidden_region_diagnostic(
+    tcx: TyCtxt<'tcx>,
+    region_scope_tree: Option<&region::ScopeTree>,
+    opaque_type_def_id: DefId,
+    hidden_ty: Ty<'tcx>,
+    hidden_region: ty::Region<'tcx>,
+) -> DiagnosticBuilder<'tcx> {
+    let span = tcx.def_span(opaque_type_def_id);
+    let mut err = struct_span_err!(
+        tcx.sess,
+        span,
+        E0700,
+        "hidden type for `impl Trait` captures lifetime that does not appear in bounds",
+    );
+
+    // Explain the region we are capturing.
+    if let ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic | ty::ReEmpty = hidden_region {
+        // Assuming regionck succeeded (*), we ought to always be
+        // capturing *some* region from the fn header, and hence it
+        // ought to be free. So under normal circumstances, we will go
+        // down this path which gives a decent human readable
+        // explanation.
+        //
+        // (*) if not, the `tainted_by_errors` flag would be set to
+        // true in any case, so we wouldn't be here at all.
+        tcx.note_and_explain_free_region(
+            &mut err,
+            &format!("hidden type `{}` captures ", hidden_ty),
+            hidden_region,
+            "",
+        );
+    } else {
+        // Ugh. This is a painful case: the hidden region is not one
+        // that we can easily summarize or explain. This can happen
+        // in a case like
+        // `src/test/ui/multiple-lifetimes/ordinary-bounds-unsuited.rs`:
+        //
+        // ```
+        // fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> {
+        //   if condition() { a } else { b }
+        // }
+        // ```
+        //
+        // Here the captured lifetime is the intersection of `'a` and
+        // `'b`, which we can't quite express.
+
+        if let Some(region_scope_tree) = region_scope_tree {
+            // If the `region_scope_tree` is available, this is being
+            // invoked from the "region inferencer error". We can at
+            // least report a really cryptic error for now.
+            tcx.note_and_explain_region(
+                region_scope_tree,
+                &mut err,
+                &format!("hidden type `{}` captures ", hidden_ty),
+                hidden_region,
+                "",
+            );
+        } else {
+            // If the `region_scope_tree` is *unavailable*, this is
+            // being invoked by the code that comes *after* region
+            // inferencing. This is a bug, as the region inferencer
+            // ought to have noticed the failed constraint and invoked
+            // error reporting, which in turn should have prevented us
+            // from getting trying to infer the hidden type
+            // completely.
+            tcx.sess.delay_span_bug(
+                span,
+                &format!(
+                    "hidden type captures unexpected lifetime `{:?}` \
+                     but no region inference failure",
+                    hidden_region,
+                ),
+            );
+        }
+    }
+
+    err
+}
+
 // Visitor that requires that (almost) all regions in the type visited outlive
 // `least_region`. We cannot use `push_outlives_components` because regions in
 // closure signatures are not included in their outlives components. We need to
@@ -486,13 +683,18 @@ pub fn infer_opaque_definition_from_instantiation(
 //
 // We ignore any type parameters because impl trait values are assumed to
 // capture all the in-scope type parameters.
-struct OpaqueTypeOutlivesVisitor<'a, 'tcx> {
-    infcx: &'a InferCtxt<'a, 'tcx>,
-    least_region: ty::Region<'tcx>,
-    span: Span,
+struct ConstrainOpaqueTypeRegionVisitor<'tcx, OP>
+where
+    OP: FnMut(ty::Region<'tcx>),
+{
+    tcx: TyCtxt<'tcx>,
+    op: OP,
 }
 
-impl<'tcx> TypeVisitor<'tcx> for OpaqueTypeOutlivesVisitor<'_, 'tcx> {
+impl<'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor<'tcx, OP>
+where
+    OP: FnMut(ty::Region<'tcx>),
+{
     fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> bool {
         t.skip_binder().visit_with(self);
         false // keep visiting
@@ -503,7 +705,7 @@ fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
             // ignore bound regions, keep visiting
             ty::ReLateBound(_, _) => false,
             _ => {
-                self.infcx.sub_regions(infer::CallReturn(self.span), self.least_region, r);
+                (self.op)(r);
                 false
             }
         }
@@ -519,23 +721,23 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
             ty::Closure(def_id, ref substs) => {
                 // Skip lifetime parameters of the enclosing item(s)
 
-                for upvar_ty in substs.upvar_tys(def_id, self.infcx.tcx) {
+                for upvar_ty in substs.upvar_tys(def_id, self.tcx) {
                     upvar_ty.visit_with(self);
                 }
 
-                substs.closure_sig_ty(def_id, self.infcx.tcx).visit_with(self);
+                substs.closure_sig_ty(def_id, self.tcx).visit_with(self);
             }
 
             ty::Generator(def_id, ref substs, _) => {
                 // Skip lifetime parameters of the enclosing item(s)
                 // Also skip the witness type, because that has no free regions.
 
-                for upvar_ty in substs.upvar_tys(def_id, self.infcx.tcx) {
+                for upvar_ty in substs.upvar_tys(def_id, self.tcx) {
                     upvar_ty.visit_with(self);
                 }
 
-                substs.return_ty(def_id, self.infcx.tcx).visit_with(self);
-                substs.yield_ty(def_id, self.infcx.tcx).visit_with(self);
+                substs.return_ty(def_id, self.tcx).visit_with(self);
+                substs.yield_ty(def_id, self.tcx).visit_with(self);
             }
             _ => {
                 ty.super_visit_with(self);
@@ -616,40 +818,17 @@ fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
             None => {
                 if !self.map_missing_regions_to_empty && !self.tainted_by_errors {
                     if let Some(hidden_ty) = self.hidden_ty.take() {
-                        let span = self.tcx.def_span(self.opaque_type_def_id);
-                        let mut err = struct_span_err!(
-                            self.tcx.sess,
-                            span,
-                            E0700,
-                            "hidden type for `impl Trait` captures lifetime that \
-                             does not appear in bounds",
-                        );
-
-                        // Assuming regionck succeeded, then we must
-                        // be capturing *some* region from the fn
-                        // header, and hence it must be free, so it's
-                        // ok to invoke this fn (which doesn't accept
-                        // all regions, and would ICE if an
-                        // inappropriate region is given). We check
-                        // `is_tainted_by_errors` by errors above, so
-                        // we don't get in here unless regionck
-                        // succeeded. (Note also that if regionck
-                        // failed, then the regions we are attempting
-                        // to map here may well be giving errors
-                        // *because* the constraints were not
-                        // satisfiable.)
-                        self.tcx.note_and_explain_free_region(
-                            &mut err,
-                            &format!("hidden type `{}` captures ", hidden_ty),
+                        unexpected_hidden_region_diagnostic(
+                            self.tcx,
+                            None,
+                            self.opaque_type_def_id,
+                            hidden_ty,
                             r,
-                            ""
-                        );
-
-                        err.emit();
+                        ).emit();
                     }
                 }
                 self.tcx.lifetimes.re_empty
-            },
+            }
         }
     }
 
@@ -681,8 +860,8 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                 // during codegen.
 
                 let generics = self.tcx.generics_of(def_id);
-                let substs = self.tcx.mk_substs(substs.substs.iter().enumerate().map(
-                    |(index, &kind)| {
+                let substs =
+                    self.tcx.mk_substs(substs.substs.iter().enumerate().map(|(index, &kind)| {
                         if index < generics.parent_count {
                             // Accommodate missing regions in the parent kinds...
                             self.fold_kind_mapping_missing_regions_to_empty(kind)
@@ -690,16 +869,15 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                             // ...but not elsewhere.
                             self.fold_kind_normally(kind)
                         }
-                    },
-                ));
+                    }));
 
                 self.tcx.mk_closure(def_id, ty::ClosureSubsts { substs })
             }
 
             ty::Generator(def_id, substs, movability) => {
                 let generics = self.tcx.generics_of(def_id);
-                let substs = self.tcx.mk_substs(substs.substs.iter().enumerate().map(
-                    |(index, &kind)| {
+                let substs =
+                    self.tcx.mk_substs(substs.substs.iter().enumerate().map(|(index, &kind)| {
                         if index < generics.parent_count {
                             // Accommodate missing regions in the parent kinds...
                             self.fold_kind_mapping_missing_regions_to_empty(kind)
@@ -707,8 +885,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                             // ...but not elsewhere.
                             self.fold_kind_normally(kind)
                         }
-                    },
-                ));
+                    }));
 
                 self.tcx.mk_generator(def_id, ty::GeneratorSubsts { substs }, movability)
             }
@@ -723,6 +900,7 @@ struct Instantiator<'a, 'tcx> {
     parent_def_id: DefId,
     body_id: hir::HirId,
     param_env: ty::ParamEnv<'tcx>,
+    value_span: Span,
     opaque_types: OpaqueTypeMap<'tcx>,
     obligations: Vec<PredicateObligation<'tcx>>,
 }
@@ -774,11 +952,9 @@ fn instantiate_opaque_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: &T)
                         let def_scope_default = || {
                             let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id);
                             parent_def_id == tcx.hir()
-                                                .local_def_id_from_hir_id(opaque_parent_hir_id)
+                                                .local_def_id(opaque_parent_hir_id)
                         };
-                        let (in_definition_scope, origin) =
-                            match tcx.hir().find(opaque_hir_id)
-                        {
+                        let (in_definition_scope, origin) = match tcx.hir().find(opaque_hir_id) {
                             Some(Node::Item(item)) => match item.node {
                                 // Anonymous `impl Trait`
                                 hir::ItemKind::Existential(hir::ExistTy {
@@ -847,10 +1023,7 @@ fn fold_opaque_ty(
         let infcx = self.infcx;
         let tcx = infcx.tcx;
 
-        debug!(
-            "instantiate_opaque_types: Opaque(def_id={:?}, substs={:?})",
-            def_id, substs
-        );
+        debug!("instantiate_opaque_types: Opaque(def_id={:?}, substs={:?})", def_id, substs);
 
         // Use the same type variable if the exact same opaque type appears more
         // than once in the return type (e.g., if it's passed to a type alias).
@@ -858,41 +1031,35 @@ fn fold_opaque_ty(
             return opaque_defn.concrete_ty;
         }
         let span = tcx.def_span(def_id);
-        let ty_var = infcx.next_ty_var(TypeVariableOrigin {
-            kind: TypeVariableOriginKind::TypeInference,
-            span,
-        });
+        let ty_var = infcx
+            .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
 
         let predicates_of = tcx.predicates_of(def_id);
-        debug!(
-            "instantiate_opaque_types: predicates={:#?}",
-            predicates_of,
-        );
+        debug!("instantiate_opaque_types: predicates={:#?}", predicates_of,);
         let bounds = predicates_of.instantiate(tcx, substs);
         debug!("instantiate_opaque_types: bounds={:?}", bounds);
 
         let required_region_bounds = tcx.required_region_bounds(ty, bounds.predicates.clone());
-        debug!(
-            "instantiate_opaque_types: required_region_bounds={:?}",
-            required_region_bounds
-        );
+        debug!("instantiate_opaque_types: required_region_bounds={:?}", required_region_bounds);
 
         // Make sure that we are in fact defining the *entire* type
         // (e.g., `existential type Foo<T: Bound>: Bar;` needs to be
         // defined by a function like `fn foo<T: Bound>() -> Foo<T>`).
-        debug!(
-            "instantiate_opaque_types: param_env={:#?}",
-            self.param_env,
-        );
-        debug!(
-            "instantiate_opaque_types: generics={:#?}",
-            tcx.generics_of(def_id),
-        );
+        debug!("instantiate_opaque_types: param_env={:#?}", self.param_env,);
+        debug!("instantiate_opaque_types: generics={:#?}", tcx.generics_of(def_id),);
+
+        // Ideally, we'd get the span where *this specific `ty` came
+        // from*, but right now we just use the span from the overall
+        // value being folded. In simple cases like `-> impl Foo`,
+        // these are the same span, but not in cases like `-> (impl
+        // Foo, impl Bar)`.
+        let definition_span = self.value_span;
 
         self.opaque_types.insert(
             def_id,
             OpaqueTypeDecl {
                 substs,
+                definition_span,
                 concrete_ty: ty_var,
                 has_required_region_bounds: !required_region_bounds.is_empty(),
                 origin,
@@ -911,8 +1078,7 @@ fn fold_opaque_ty(
 
             // Require that the predicate holds for the concrete type.
             debug!("instantiate_opaque_types: predicate={:?}", predicate);
-            self.obligations
-                .push(traits::Obligation::new(cause, self.param_env, predicate));
+            self.obligations.push(traits::Obligation::new(cause, self.param_env, predicate));
         }
 
         ty_var
@@ -950,9 +1116,7 @@ pub fn may_define_existential_type(
     );
 
     // Named existential types can be defined by any siblings or children of siblings.
-    let scope = tcx.hir()
-        .get_defining_scope(opaque_hir_id)
-        .expect("could not get defining scope");
+    let scope = tcx.hir().get_defining_scope(opaque_hir_id).expect("could not get defining scope");
     // We walk up the node tree until we hit the root or the scope of the opaque type.
     while hir_id != scope && hir_id != hir::CRATE_HIR_ID {
         hir_id = tcx.hir().get_parent_item(hir_id);
index 1250995a59c106787707c905d08c192387d23241..c085df6a6e7ab6536a99192c8db0232fdfe1e83d 100644 (file)
@@ -11,6 +11,10 @@ pub struct FreeRegionMap<'tcx> {
 }
 
 impl<'tcx> FreeRegionMap<'tcx> {
+    pub fn elements(&self) -> impl Iterator<Item=&Region<'tcx>> {
+        self.relation.elements()
+    }
+
     pub fn is_empty(&self) -> bool {
         self.relation.is_empty()
     }
index 0ae4446ee63faf5044938b5a9d2bf554cbc54cad..e1470e4ef0232318468feb298536a639fe47fda7 100644 (file)
@@ -112,7 +112,7 @@ pub fn register_region_obligation_with_cause(
 
     /// Trait queries just want to pass back type obligations "as is"
     pub fn take_registered_region_obligations(&self) -> Vec<(hir::HirId, RegionObligation<'tcx>)> {
-        ::std::mem::replace(&mut *self.region_obligations.borrow_mut(), vec![])
+        ::std::mem::take(&mut *self.region_obligations.borrow_mut())
     }
 
     /// Process the region obligations that must be proven (during
index f2235fe8d6d1245868a8167a6d83499f05250b40..21904edb309cb4b2efe6de2899465f6c9c9ec843 100644 (file)
@@ -8,11 +8,14 @@
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::indexed_vec::IndexVec;
+use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::unify as ut;
+use crate::hir::def_id::DefId;
 use crate::ty::ReStatic;
 use crate::ty::{self, Ty, TyCtxt};
 use crate::ty::{ReLateBound, ReVar};
 use crate::ty::{Region, RegionVid};
+use syntax_pos::Span;
 
 use std::collections::BTreeMap;
 use std::{cmp, fmt, mem};
@@ -78,6 +81,11 @@ pub struct RegionConstraintData<'tcx> {
     /// be a region variable (or neither, as it happens).
     pub constraints: BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
 
+    /// Constraints of the form `R0 member of [R1, ..., Rn]`, meaning that
+    /// `R0` must be equal to one of the regions `R1..Rn`. These occur
+    /// with `impl Trait` quite frequently.
+    pub member_constraints: Vec<MemberConstraint<'tcx>>,
+
     /// A "verify" is something that we need to verify after inference
     /// is done, but which does not directly affect inference in any
     /// way.
@@ -137,6 +145,43 @@ pub fn involves_placeholders(&self) -> bool {
     }
 }
 
+/// Requires that `region` must be equal to one of the regions in `choice_regions`.
+/// We often denote this using the syntax:
+///
+/// ```
+/// R0 member of [O1..On]
+/// ```
+#[derive(Debug, Clone, HashStable)]
+pub struct MemberConstraint<'tcx> {
+    /// The `DefId` of the opaque type causing this constraint: used for error reporting.
+    pub opaque_type_def_id: DefId,
+
+    /// The span where the hidden type was instantiated.
+    pub definition_span: Span,
+
+    /// The hidden type in which `member_region` appears: used for error reporting.
+    pub hidden_ty: Ty<'tcx>,
+
+    /// The region `R0`.
+    pub member_region: Region<'tcx>,
+
+    /// The options `O1..On`.
+    pub choice_regions: Lrc<Vec<Region<'tcx>>>,
+}
+
+BraceStructTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for MemberConstraint<'tcx> {
+        opaque_type_def_id, definition_span, hidden_ty, member_region, choice_regions
+    }
+}
+
+BraceStructLiftImpl! {
+    impl<'a, 'tcx> Lift<'tcx> for MemberConstraint<'a> {
+        type Lifted = MemberConstraint<'tcx>;
+        opaque_type_def_id, definition_span, hidden_ty, member_region, choice_regions
+    }
+}
+
 /// `VerifyGenericBound(T, _, R, RS)`: the parameter type `T` (or
 /// associated type) must outlive the region `R`. `T` is known to
 /// outlive `RS`. Therefore, verify that `R <= RS[i]` for some
@@ -410,7 +455,7 @@ pub fn take_and_reset_data(&mut self) -> RegionConstraintData<'tcx> {
             *any_unifications = false;
         }
 
-        mem::replace(data, RegionConstraintData::default())
+        mem::take(data)
     }
 
     pub fn data(&self) -> &RegionConstraintData<'tcx> {
@@ -643,6 +688,30 @@ pub fn make_eqregion(
         }
     }
 
+    pub fn member_constraint(
+        &mut self,
+        opaque_type_def_id: DefId,
+        definition_span: Span,
+        hidden_ty: Ty<'tcx>,
+        member_region: ty::Region<'tcx>,
+        choice_regions: &Lrc<Vec<ty::Region<'tcx>>>,
+    ) {
+        debug!("member_constraint({:?} in {:#?})", member_region, choice_regions);
+
+        if choice_regions.iter().any(|&r| r == member_region) {
+            return;
+        }
+
+        self.data.member_constraints.push(MemberConstraint {
+            opaque_type_def_id,
+            definition_span,
+            hidden_ty,
+            member_region,
+            choice_regions: choice_regions.clone()
+        });
+
+    }
+
     pub fn make_subregion(
         &mut self,
         origin: SubregionOrigin<'tcx>,
@@ -906,9 +975,13 @@ impl<'tcx> RegionConstraintData<'tcx> {
     pub fn is_empty(&self) -> bool {
         let RegionConstraintData {
             constraints,
+            member_constraints,
             verifys,
             givens,
         } = self;
-        constraints.is_empty() && verifys.is_empty() && givens.is_empty()
+        constraints.is_empty() &&
+            member_constraints.is_empty() &&
+            verifys.is_empty() &&
+            givens.is_empty()
     }
 }
index dcafb0f3976ff639de1e6ac69b64569bd02bacf0..e30e86998a8c6f16bde7f8c1d8e932edb1380f31 100644 (file)
@@ -115,7 +115,7 @@ pub fn new() -> TypeVariableTable<'tcx> {
     ///
     /// Note that this function does not return care whether
     /// `vid` has been unified with something else or not.
-    pub fn var_diverges<'a>(&'a self, vid: ty::TyVid) -> bool {
+    pub fn var_diverges(&self, vid: ty::TyVid) -> bool {
         self.values.get(vid.index as usize).diverging
     }
 
index 257d5159f113195128fc4db2f3c935342bbe45df..b20f7120bbfa2e9ea7ca7189b52c47017019da96 100644 (file)
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #![feature(arbitrary_self_types)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
+#![feature(const_fn)]
+#![feature(const_transmute)]
 #![feature(core_intrinsics)]
 #![feature(drain_filter)]
 #![feature(inner_deref)]
@@ -65,6 +66,7 @@
 #![feature(crate_visibility_modifier)]
 #![feature(proc_macro_hygiene)]
 #![feature(log_syntax)]
+#![feature(mem_take)]
 
 #![recursion_limit="512"]
 
index 7f09120bbdd5eac48618102eb20bafe5bb6f2509..2930f7690dd8ed8c4dc39ef1499c295ec8c96f5a 100644 (file)
@@ -926,7 +926,7 @@ fn with_param_env<F>(&mut self, id: hir::HirId, f: F)
     {
         let old_param_env = self.context.param_env;
         self.context.param_env = self.context.tcx.param_env(
-            self.context.tcx.hir().local_def_id_from_hir_id(id)
+            self.context.tcx.hir().local_def_id(id)
         );
         f(self);
         self.context.param_env = old_param_env;
@@ -1341,6 +1341,7 @@ struct LateLintPassObjects<'a> {
     lints: &'a mut [LateLintPassObject],
 }
 
+#[cfg_attr(not(bootstrap), allow(rustc::lint_pass_impl_without_macro))]
 impl LintPass for LateLintPassObjects<'_> {
     fn name(&self) -> &'static str {
         panic!()
@@ -1500,7 +1501,7 @@ pub fn check_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
         time(tcx.sess, "module lints", || {
             // Run per-module lints
             par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| {
-                tcx.ensure().lint_mod(tcx.hir().local_def_id(module));
+                tcx.ensure().lint_mod(tcx.hir().local_def_id_from_node_id(module));
             });
         });
     });
@@ -1510,6 +1511,7 @@ struct EarlyLintPassObjects<'a> {
     lints: &'a mut [EarlyLintPassObject],
 }
 
+#[cfg_attr(not(bootstrap), allow(rustc::lint_pass_impl_without_macro))]
 impl LintPass for EarlyLintPassObjects<'_> {
     fn name(&self) -> &'static str {
         panic!()
index 86dae579ca753d859b3dc04a320a503b53f9e2c5..34899736949675cd2142cd4967fa30bc37ccacaa 100644 (file)
@@ -7,11 +7,12 @@
 };
 use errors::Applicability;
 use rustc_data_structures::fx::FxHashMap;
-use syntax::ast::Ident;
+use syntax::ast::{Ident, Item, ItemKind};
 use syntax::symbol::{sym, Symbol};
+use syntax_pos::ExpnInfo;
 
-declare_lint! {
-    pub DEFAULT_HASH_TYPES,
+declare_tool_lint! {
+    pub rustc::DEFAULT_HASH_TYPES,
     Allow,
     "forbid HashMap and HashSet and suggest the FxHash* variants"
 }
@@ -22,7 +23,7 @@ pub struct DefaultHashTypes {
 
 impl DefaultHashTypes {
     // we are allowed to use `HashMap` and `HashSet` as identifiers for implementing the lint itself
-    #[allow(internal)]
+    #[cfg_attr(not(bootstrap), allow(rustc::default_hash_types))]
     pub fn new() -> Self {
         let mut map = FxHashMap::default();
         map.insert(sym::HashMap, sym::FxHashMap);
@@ -36,10 +37,7 @@ pub fn new() -> Self {
 impl EarlyLintPass for DefaultHashTypes {
     fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
         if let Some(replace) = self.map.get(&ident.name) {
-            let msg = format!(
-                "Prefer {} over {}, it has better performance",
-                replace, ident
-            );
+            let msg = format!("Prefer {} over {}, it has better performance", replace, ident);
             let mut db = cx.struct_span_lint(DEFAULT_HASH_TYPES, ident.span, &msg);
             db.span_suggestion(
                 ident.span,
@@ -47,29 +45,26 @@ fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
                 replace.to_string(),
                 Applicability::MaybeIncorrect, // FxHashMap, ... needs another import
             );
-            db.note(&format!(
-                "a `use rustc_data_structures::fx::{}` may be necessary",
-                replace
-            ))
-            .emit();
+            db.note(&format!("a `use rustc_data_structures::fx::{}` may be necessary", replace))
+                .emit();
         }
     }
 }
 
-declare_lint! {
-    pub USAGE_OF_TY_TYKIND,
+declare_tool_lint! {
+    pub rustc::USAGE_OF_TY_TYKIND,
     Allow,
     "usage of `ty::TyKind` outside of the `ty::sty` module"
 }
 
-declare_lint! {
-    pub TY_PASS_BY_REFERENCE,
+declare_tool_lint! {
+    pub rustc::TY_PASS_BY_REFERENCE,
     Allow,
     "passing `Ty` or `TyCtxt` by reference"
 }
 
-declare_lint! {
-    pub USAGE_OF_QUALIFIED_TY,
+declare_tool_lint! {
+    pub rustc::USAGE_OF_QUALIFIED_TY,
     Allow,
     "using `ty::{Ty,TyCtxt}` instead of importing it"
 }
@@ -137,13 +132,7 @@ fn check_ty(&mut self, cx: &LateContext<'_, '_>, ty: &'tcx Ty) {
                     }
                 }
             }
-            TyKind::Rptr(
-                _,
-                MutTy {
-                    ty: inner_ty,
-                    mutbl: Mutability::MutImmutable,
-                },
-            ) => {
+            TyKind::Rptr(_, MutTy { ty: inner_ty, mutbl: Mutability::MutImmutable }) => {
                 if let Some(impl_did) = cx.tcx.impl_of_method(ty.hir_id.owner_def_id()) {
                     if cx.tcx.impl_trait_ref(impl_did).is_some() {
                         return;
@@ -225,3 +214,44 @@ fn gen_args(segment: &PathSegment) -> String {
 
     String::new()
 }
+
+declare_tool_lint! {
+    pub rustc::LINT_PASS_IMPL_WITHOUT_MACRO,
+    Allow,
+    "`impl LintPass` without the `declare_lint_pass!` or `impl_lint_pass!` macros"
+}
+
+declare_lint_pass!(LintPassImpl => [LINT_PASS_IMPL_WITHOUT_MACRO]);
+
+impl EarlyLintPass for LintPassImpl {
+    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
+        if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.node {
+            if let Some(last) = lint_pass.path.segments.last() {
+                if last.ident.name == sym::LintPass {
+                    match &lint_pass.path.span.ctxt().outer_expn_info() {
+                        Some(info) if is_lint_pass_expansion(info) => {}
+                        _ => {
+                            cx.struct_span_lint(
+                                LINT_PASS_IMPL_WITHOUT_MACRO,
+                                lint_pass.path.span,
+                                "implementing `LintPass` by hand",
+                            )
+                            .help("try using `declare_lint_pass!` or `impl_lint_pass!` instead")
+                            .emit();
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+fn is_lint_pass_expansion(expn_info: &ExpnInfo) -> bool {
+    if expn_info.format.name() == sym::impl_lint_pass {
+        true
+    } else if let Some(info) = expn_info.call_site.ctxt().outer_expn_info() {
+        info.format.name() == sym::declare_lint_pass
+    } else {
+        false
+    }
+}
index 309af4b72c1271e88bc9809b46e0c1984316c2ab..59b08b832d27275fe0f210cc883c414b35d6c900 100644 (file)
@@ -765,7 +765,7 @@ pub fn maybe_lint_level_root(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
     attrs.iter().any(|attr| Level::from_symbol(attr.name_or_empty()).is_some())
 }
 
-fn lint_levels<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> &'tcx LintLevelMap {
+fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap {
     assert_eq!(cnum, LOCAL_CRATE);
     let mut builder = LintLevelMapBuilder {
         levels: LintLevelSets::builder(tcx.sess),
index 2e9e1ac582f812e8169c09b1b95d2dae983d3280..5a580dfa420b3f22d5a3b33fabf39d7e2c0383ea 100644 (file)
@@ -211,7 +211,7 @@ pub trait CrateStore {
     fn crates_untracked(&self) -> Vec<CrateNum>;
 
     // utility functions
-    fn encode_metadata<'tcx>(&self, tcx: TyCtxt<'tcx>) -> EncodedMetadata;
+    fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata;
     fn metadata_encoding_version(&self) -> &[u8];
 }
 
index e02ee8943603a6372cc113f9687c0d0b5d75cb1e..4c27318c3e19bd62be99587cbc05855b07c86d07 100644 (file)
@@ -26,7 +26,7 @@
 // explored. For example, if it's a live Node::Item that is a
 // function, then we should explore its block to check for codes that
 // may need to be marked as live.
-fn should_explore<'tcx>(tcx: TyCtxt<'tcx>, hir_id: hir::HirId) -> bool {
+fn should_explore(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
     match tcx.hir().find(hir_id) {
         Some(Node::Item(..)) |
         Some(Node::ImplItem(..)) |
@@ -161,7 +161,7 @@ fn visit_node(&mut self, node: Node<'tcx>) {
             Node::Item(item) => {
                 match item.node {
                     hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
-                        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+                        let def_id = self.tcx.hir().local_def_id(item.hir_id);
                         let def = self.tcx.adt_def(def_id);
                         self.repr_has_repr_c = def.repr.c();
 
@@ -325,7 +325,7 @@ fn has_allow_dead_code_or_lang_attr(
         return true;
     }
 
-    let def_id = tcx.hir().local_def_id_from_hir_id(id);
+    let def_id = tcx.hir().local_def_id(id);
     let cg_attrs = tcx.codegen_fn_attrs(def_id);
 
     // #[used], #[no_mangle], #[export_name], etc also keeps the item alive
@@ -494,7 +494,7 @@ fn should_warn_about_item(&mut self, item: &hir::Item) -> bool {
     }
 
     fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool {
-        let field_type = self.tcx.type_of(self.tcx.hir().local_def_id_from_hir_id(field.hir_id));
+        let field_type = self.tcx.type_of(self.tcx.hir().local_def_id(field.hir_id));
         !field.is_positional()
             && !self.symbol_is_live(field.hir_id)
             && !field_type.is_phantom_data()
@@ -525,7 +525,7 @@ fn symbol_is_live(
         // This is done to handle the case where, for example, the static
         // method of a private type is used, but the type itself is never
         // called directly.
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(id);
+        let def_id = self.tcx.hir().local_def_id(id);
         let inherent_impls = self.tcx.inherent_impls(def_id);
         for &impl_did in inherent_impls.iter() {
             for &item_did in &self.tcx.associated_item_def_ids(impl_did)[..] {
@@ -662,7 +662,7 @@ fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
     }
 }
 
-pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn check_crate(tcx: TyCtxt<'_>) {
     let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
     let krate = tcx.hir().krate();
     let live_symbols = find_live(tcx, access_levels, krate);
index 879da6413e28a9f9cc8a400bcbe60c8fa5565faa..96b99fe4cdce2c01ca4716a4ba60be190907f59f 100644 (file)
@@ -81,7 +81,7 @@ pub enum Linkage {
     Dynamic,
 }
 
-pub fn calculate<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn calculate(tcx: TyCtxt<'_>) {
     let sess = &tcx.sess;
     let fmts = sess.crate_types.borrow().iter().map(|&ty| {
         let linkage = calculate_type(tcx, ty);
@@ -92,7 +92,7 @@ pub fn calculate<'tcx>(tcx: TyCtxt<'tcx>) {
     sess.dependency_formats.set(fmts);
 }
 
-fn calculate_type<'tcx>(tcx: TyCtxt<'tcx>, ty: config::CrateType) -> DependencyList {
+fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList {
     let sess = &tcx.sess;
 
     if !sess.opts.output_types.should_codegen() {
@@ -267,7 +267,7 @@ fn add_library(
     }
 }
 
-fn attempt_static<'tcx>(tcx: TyCtxt<'tcx>) -> Option<DependencyList> {
+fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> {
     let sess = &tcx.sess;
     let crates = cstore::used_crates(tcx, RequireStatic);
     if !crates.iter().by_ref().all(|&(_, ref p)| p.is_some()) {
@@ -324,7 +324,7 @@ fn activate_injected_dep(injected: Option<CrateNum>,
 
 // After the linkage for a crate has been determined we need to verify that
 // there's only going to be one allocator in the output.
-fn verify_ok<'tcx>(tcx: TyCtxt<'tcx>, list: &[Linkage]) {
+fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
     let sess = &tcx.sess;
     if list.len() == 0 {
         return
index d1867e8fa36b25d6c252795b1c7faddadf329b3a..cba4d0f1598c4436335da9dcd0c54c1251f0764b 100644 (file)
@@ -32,7 +32,7 @@ struct EntryContext<'a, 'tcx> {
 
 impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
     fn visit_item(&mut self, item: &'tcx Item) {
-        let def_id = self.map.local_def_id_from_hir_id(item.hir_id);
+        let def_id = self.map.local_def_id(item.hir_id);
         let def_key = self.map.def_key(def_id);
         let at_root = def_key.parent == Some(CRATE_DEF_INDEX);
         find_item(item, self, at_root);
@@ -142,11 +142,11 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
 
 fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(DefId, EntryFnType)> {
     if let Some((hir_id, _)) = visitor.start_fn {
-        Some((tcx.hir().local_def_id_from_hir_id(hir_id), EntryFnType::Start))
+        Some((tcx.hir().local_def_id(hir_id), EntryFnType::Start))
     } else if let Some((hir_id, _)) = visitor.attr_main_fn {
-        Some((tcx.hir().local_def_id_from_hir_id(hir_id), EntryFnType::Main))
+        Some((tcx.hir().local_def_id(hir_id), EntryFnType::Main))
     } else if let Some((hir_id, _)) = visitor.main_fn {
-        Some((tcx.hir().local_def_id_from_hir_id(hir_id), EntryFnType::Main))
+        Some((tcx.hir().local_def_id(hir_id), EntryFnType::Main))
     } else {
         // No main function
         let mut err = struct_err!(tcx.sess, E0601,
index 086ddfd7e33bfc996b41735fc479ac9e363983c0..77094604edacf63cb7e51c728ff6f6325cdfbe92 100644 (file)
@@ -11,6 +11,7 @@
 
 use crate::hir::def::{CtorOf, Res, DefKind};
 use crate::hir::def_id::DefId;
+use crate::hir::ptr::P;
 use crate::infer::InferCtxt;
 use crate::middle::mem_categorization as mc;
 use crate::middle::region;
@@ -18,7 +19,6 @@
 
 use crate::hir::{self, PatKind};
 use std::rc::Rc;
-use syntax::ptr::P;
 use syntax_pos::Span;
 use crate::util::nodemap::ItemLocalSet;
 
@@ -930,7 +930,7 @@ fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: Mat
     fn walk_captures(&mut self, closure_expr: &hir::Expr, fn_decl_span: Span) {
         debug!("walk_captures({:?})", closure_expr);
 
-        let closure_def_id = self.tcx().hir().local_def_id_from_hir_id(closure_expr.hir_id);
+        let closure_def_id = self.tcx().hir().local_def_id(closure_expr.hir_id);
         if let Some(upvars) = self.tcx().upvars(closure_def_id) {
             for (&var_id, upvar) in upvars.iter() {
                 let upvar_id = ty::UpvarId {
index e8d68e0b7a7aa409948c4293cbee35a8b20f0c7e..1cc96c549e7243c943d8629bcfecc3e8f91e76f1 100644 (file)
@@ -10,7 +10,7 @@
 use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use crate::hir;
 
-fn check_mod_intrinsics<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
+fn check_mod_intrinsics(tcx: TyCtxt<'_>, module_def_id: DefId) {
     tcx.hir().visit_item_likes_in_module(
         module_def_id,
         &mut ItemVisitor { tcx }.as_deep_visitor()
index a6e5bd275ae19008442a28c90751be2cb7905afe..7c15f2ef94d1b4e259d106583e83392482239f5c 100644 (file)
@@ -118,7 +118,7 @@ fn visit_item(&mut self, item: &hir::Item) {
             match self.item_refs.get(&*value.as_str()).cloned() {
                 // Known lang item with attribute on correct target.
                 Some((item_index, expected_target)) if actual_target == expected_target => {
-                    let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+                    let def_id = self.tcx.hir().local_def_id(item.hir_id);
                     self.collect_item(item_index, def_id);
                 },
                 // Known lang item with attribute on incorrect target.
index 9c131ce63428b3845dffc7e0970e7c8dc3029705..694b0a986296065b3d005a3d26aa63b5b9ba8f6b 100644 (file)
@@ -142,7 +142,7 @@ fn visit_attribute(&mut self, attr: &'tcx Attribute) {
     }
 }
 
-pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> LibFeatures {
+pub fn collect(tcx: TyCtxt<'_>) -> LibFeatures {
     let mut collector = LibFeatureCollector::new(tcx);
     intravisit::walk_crate(&mut collector, tcx.hir().krate());
     collector.lib_features
index 7b69fe394fb2c552bc702ecbd588595ccdc7418d..c4d60b676b2798131acbbe63fa4b58f1f52ab885 100644 (file)
@@ -99,6 +99,7 @@
 
 use crate::hir::def::*;
 use crate::hir::Node;
+use crate::hir::ptr::P;
 use crate::ty::{self, TyCtxt};
 use crate::ty::query::Providers;
 use crate::lint;
 use std::io;
 use std::rc::Rc;
 use syntax::ast;
-use syntax::ptr::P;
 use syntax::symbol::{kw, sym};
 use syntax_pos::Span;
 
@@ -181,7 +181,7 @@ fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
     fn visit_arm(&mut self, a: &'tcx hir::Arm) { visit_arm(self, a); }
 }
 
-fn check_mod_liveness<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
+fn check_mod_liveness(tcx: TyCtxt<'_>, module_def_id: DefId) {
     tcx.hir().visit_item_likes_in_module(
         module_def_id,
         &mut IrMaps::new(tcx, module_def_id).as_deep_visitor(),
@@ -363,7 +363,7 @@ fn visit_fn<'tcx>(
     debug!("visit_fn");
 
     // swap in a new set of IR maps for this function body:
-    let def_id = ir.tcx.hir().local_def_id_from_hir_id(id);
+    let def_id = ir.tcx.hir().local_def_id(id);
     let mut fn_maps = IrMaps::new(ir.tcx, def_id);
 
     // Don't run unused pass for #[derive()]
@@ -494,7 +494,7 @@ fn visit_expr<'tcx>(ir: &mut IrMaps<'tcx>, expr: &'tcx Expr) {
         // in better error messages than just pointing at the closure
         // construction site.
         let mut call_caps = Vec::new();
-        let closure_def_id = ir.tcx.hir().local_def_id_from_hir_id(expr.hir_id);
+        let closure_def_id = ir.tcx.hir().local_def_id(expr.hir_id);
         if let Some(upvars) = ir.tcx.upvars(closure_def_id) {
             let parent_upvars = ir.tcx.upvars(ir.body_owner);
             call_caps.extend(upvars.iter().filter_map(|(&var_id, upvar)| {
index e7253a73bd4180a4469c85d203be2a1c85fc2309..088c862dcb8796974e452f74a733f3f84bf9e717 100644 (file)
@@ -465,9 +465,11 @@ pub fn type_is_copy_modulo_regions(
     ) -> bool {
         self.infcx.map(|infcx| infcx.type_is_copy_modulo_regions(param_env, ty, span))
             .or_else(|| {
-                self.tcx.lift_to_global(&(param_env, ty)).map(|(param_env, ty)| {
-                    ty.is_copy_modulo_regions(self.tcx.global_tcx(), param_env, span)
-                })
+                if (param_env, ty).has_local_value() {
+                    None
+                } else {
+                    Some(ty.is_copy_modulo_regions(self.tcx, param_env, span))
+                }
             })
             .unwrap_or(true)
     }
index d607c35f8762bb746f1f07f00f83835279a15600..b9a95219d3146be6525e8e0866d1cf8acf69ffa6 100644 (file)
@@ -35,20 +35,20 @@ fn item_might_be_inlined(tcx: TyCtxt<'tcx>, item: &hir::Item, attrs: CodegenFnAt
     match item.node {
         hir::ItemKind::Impl(..) |
         hir::ItemKind::Fn(..) => {
-            let generics = tcx.generics_of(tcx.hir().local_def_id_from_hir_id(item.hir_id));
+            let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
             generics.requires_monomorphization(tcx)
         }
         _ => false,
     }
 }
 
-fn method_might_be_inlined<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn method_might_be_inlined(
+    tcx: TyCtxt<'_>,
     impl_item: &hir::ImplItem,
     impl_src: DefId,
 ) -> bool {
     let codegen_fn_attrs = tcx.codegen_fn_attrs(impl_item.hir_id.owner_def_id());
-    let generics = tcx.generics_of(tcx.hir().local_def_id_from_hir_id(impl_item.hir_id));
+    let generics = tcx.generics_of(tcx.hir().local_def_id(impl_item.hir_id));
     if codegen_fn_attrs.requests_inline() || generics.requires_monomorphization(tcx) {
         return true
     }
@@ -222,7 +222,7 @@ fn propagate_node(&mut self, node: &Node<'tcx>,
                 } else {
                     false
                 };
-                let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+                let def_id = self.tcx.hir().local_def_id(item.hir_id);
                 let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
                 let is_extern = codegen_attrs.contains_extern_indicator();
                 let std_internal = codegen_attrs.flags.contains(
@@ -243,7 +243,7 @@ fn propagate_node(&mut self, node: &Node<'tcx>,
             Node::Item(item) => {
                 match item.node {
                     hir::ItemKind::Fn(.., body) => {
-                        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+                        let def_id = self.tcx.hir().local_def_id(item.hir_id);
                         if item_might_be_inlined(self.tcx,
                                                  &item,
                                                  self.tcx.codegen_fn_attrs(def_id)) {
@@ -345,7 +345,7 @@ fn visit_item(&mut self, item: &hir::Item) {
         // Anything which has custom linkage gets thrown on the worklist no
         // matter where it is in the crate, along with "special std symbols"
         // which are currently akin to allocator symbols.
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let def_id = self.tcx.hir().local_def_id(item.hir_id);
         let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
         if codegen_attrs.contains_extern_indicator() ||
             codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
@@ -391,7 +391,7 @@ fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
 #[derive(Clone, HashStable)]
 pub struct ReachableSet(pub Lrc<HirIdSet>);
 
-fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> ReachableSet {
+fn reachable_set(tcx: TyCtxt<'_>, crate_num: CrateNum) -> ReachableSet {
     debug_assert!(crate_num == LOCAL_CRATE);
 
     let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
index 114684b15240279badb11c6241fe448c607016e8..26ac1275bb992045a920ab3346a9df27c4ddb81b 100644 (file)
@@ -675,7 +675,7 @@ pub fn early_free_scope(&self, tcx: TyCtxt<'tcx>, br: &ty::EarlyBoundRegion) ->
                     &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_parent.map(|id| tcx.hir().local_def_id(id)),
                              self.root_body.map(|hir_id| DefId::local(hir_id.owner))));
             }
 
@@ -1375,7 +1375,7 @@ fn visit_body(&mut self, body: &'tcx hir::Body) {
 
         let outer_ec = mem::replace(&mut self.expr_and_pat_count, 0);
         let outer_cx = self.cx;
-        let outer_ts = mem::replace(&mut self.terminating_scopes, FxHashSet::default());
+        let outer_ts = mem::take(&mut self.terminating_scopes);
         self.terminating_scopes.insert(body.value.hir_id.local_id);
 
         if let Some(root_id) = self.cx.root_id {
@@ -1446,7 +1446,7 @@ fn visit_local(&mut self, l: &'tcx Local) {
     }
 }
 
-fn region_scope_tree<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ScopeTree {
+fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree {
     let closure_base_def_id = tcx.closure_base_def_id(def_id);
     if closure_base_def_id != def_id {
         return tcx.region_scope_tree(closure_base_def_id);
index 412346bab257e6b4b7c25906291ed58fe0d649cc..0839a2b435ae81920db2748bcd2a7f8ccd921be1 100644 (file)
@@ -8,6 +8,7 @@
 use crate::hir::def::{Res, DefKind};
 use crate::hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
 use crate::hir::map::Map;
+use crate::hir::ptr::P;
 use crate::hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, Node, ParamName};
 use crate::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
 
 use rustc_macros::HashStable;
 use std::borrow::Cow;
 use std::cell::Cell;
-use std::mem::replace;
+use std::mem::{replace, take};
 use syntax::ast;
 use syntax::attr;
-use syntax::ptr::P;
 use syntax::symbol::{kw, sym};
 use syntax_pos::Span;
 
@@ -83,7 +83,7 @@ impl Region {
     fn early(hir_map: &Map<'_>, index: &mut u32, param: &GenericParam) -> (ParamName, Region) {
         let i = *index;
         *index += 1;
-        let def_id = hir_map.local_def_id_from_hir_id(param.hir_id);
+        let def_id = hir_map.local_def_id(param.hir_id);
         let origin = LifetimeDefOrigin::from_param(param);
         debug!("Region::early: index={} def_id={:?}", i, def_id);
         (param.name.modern(), Region::EarlyBound(i, def_id, origin))
@@ -91,7 +91,7 @@ fn early(hir_map: &Map<'_>, index: &mut u32, param: &GenericParam) -> (ParamName
 
     fn late(hir_map: &Map<'_>, param: &GenericParam) -> (ParamName, Region) {
         let depth = ty::INNERMOST;
-        let def_id = hir_map.local_def_id_from_hir_id(param.hir_id);
+        let def_id = hir_map.local_def_id(param.hir_id);
         let origin = LifetimeDefOrigin::from_param(param);
         debug!(
             "Region::late: param={:?} depth={:?} def_id={:?} origin={:?}",
@@ -368,7 +368,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
 /// entire crate. You should not read the result of this query
 /// directly, but rather use `named_region_map`, `is_late_bound_map`,
 /// etc.
-fn resolve_lifetimes<'tcx>(tcx: TyCtxt<'tcx>, for_krate: CrateNum) -> &'tcx ResolveLifetimes {
+fn resolve_lifetimes(tcx: TyCtxt<'_>, for_krate: CrateNum) -> &ResolveLifetimes {
     assert_eq!(for_krate, LOCAL_CRATE);
 
     let named_region_map = krate(tcx);
@@ -395,7 +395,7 @@ fn resolve_lifetimes<'tcx>(tcx: TyCtxt<'tcx>, for_krate: CrateNum) -> &'tcx Reso
     tcx.arena.alloc(rl)
 }
 
-fn krate<'tcx>(tcx: TyCtxt<'tcx>) -> NamedRegionMap {
+fn krate(tcx: TyCtxt<'_>) -> NamedRegionMap {
     let krate = tcx.hir().krate();
     let mut map = NamedRegionMap {
         defs: Default::default(),
@@ -441,7 +441,7 @@ fn visit_nested_item(&mut self, _: hir::ItemId) {}
 
     fn visit_nested_body(&mut self, body: hir::BodyId) {
         // Each body has their own set of labels, save labels.
-        let saved = replace(&mut self.labels_in_fn, vec![]);
+        let saved = take(&mut self.labels_in_fn);
         let body = self.tcx.hir().body(body);
         extract_labels(self, body);
         self.with(
@@ -1326,7 +1326,7 @@ fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::GenericBound]) {
 
                 add_bounds(&mut set, &param.bounds);
 
-                let param_def_id = tcx.hir().local_def_id_from_hir_id(param.hir_id);
+                let param_def_id = tcx.hir().local_def_id(param.hir_id);
                 for predicate in &generics.where_clause.predicates {
                     // Look for `type: ...` where clauses.
                     let data = match *predicate {
@@ -1370,7 +1370,7 @@ fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::GenericBound]) {
                                 .enumerate()
                                 .find(|&(_, (_, lt_name, _))| lt_name == name)
                                 .map_or(Set1::Many, |(i, (id, _, origin))| {
-                                    let def_id = tcx.hir().local_def_id_from_hir_id(id);
+                                    let def_id = tcx.hir().local_def_id(id);
                                     Set1::One(Region::EarlyBound(i as u32, def_id, origin))
                                 })
                         }
@@ -1405,9 +1405,8 @@ fn with<F>(&mut self, wrap_scope: Scope<'_>, f: F)
             lifetime_uses,
             ..
         } = self;
-        let labels_in_fn = replace(&mut self.labels_in_fn, vec![]);
-        let xcrate_object_lifetime_defaults =
-            replace(&mut self.xcrate_object_lifetime_defaults, DefIdMap::default());
+        let labels_in_fn = take(&mut self.labels_in_fn);
+        let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults);
         let mut this = LifetimeContext {
             tcx: *tcx,
             map: map,
@@ -1836,7 +1835,7 @@ fn resolve_lifetime_ref(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
                         node: hir::ImplItemKind::Method(..),
                         ..
                     }) => {
-                        let scope = self.tcx.hir().local_def_id_from_hir_id(fn_id);
+                        let scope = self.tcx.hir().local_def_id(fn_id);
                         def = Region::Free(scope, def.id().unwrap());
                     }
                     _ => {}
index 38df4060652b7c6b799bfaa4ed08ee1f06f64b2d..7757336cf9c366a02c77c78241a4315a26169a77 100644 (file)
@@ -361,7 +361,7 @@ fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
     }
 
     fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
-        let impl_def_id = self.tcx.hir().local_def_id_from_hir_id(
+        let impl_def_id = self.tcx.hir().local_def_id(
             self.tcx.hir().get_parent_item(ii.hir_id));
         if self.tcx.impl_trait_ref(impl_def_id).is_none() {
             self.check_missing_stability(ii.hir_id, ii.span, "item");
@@ -466,7 +466,7 @@ pub fn local_deprecation_entry(&self, id: HirId) -> Option<DeprecationEntry> {
 
 /// Cross-references the feature names of unstable APIs with enabled
 /// features and possibly prints errors.
-fn check_mod_unstable_api_usage<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
+fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: DefId) {
     tcx.hir().visit_item_likes_in_module(module_def_id, &mut Checker { tcx }.as_deep_visitor());
 }
 
@@ -598,7 +598,7 @@ pub fn eval_stability(self, def_id: DefId, id: Option<HirId>, span: Span) -> Eva
         // Deprecated attributes apply in-crate and cross-crate.
         if let Some(id) = id {
             if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
-                let parent_def_id = self.hir().local_def_id_from_hir_id(
+                let parent_def_id = self.hir().local_def_id(
                     self.hir().get_parent_item(id));
                 let skip = self.lookup_deprecation_entry(parent_def_id)
                                .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
@@ -766,7 +766,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                 // compiler-generated `extern crate` items have a dummy span.
                 if item.span.is_dummy() { return }
 
-                let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+                let def_id = self.tcx.hir().local_def_id(item.hir_id);
                 let cnum = match self.tcx.extern_mod_stmt_cnum(def_id) {
                     Some(cnum) => cnum,
                     None => return,
@@ -796,7 +796,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
             // There's no good place to insert stability check for non-Copy unions,
             // so semi-randomly perform it here in stability.rs
             hir::ItemKind::Union(..) if !self.tcx.features().untagged_unions => {
-                let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+                let def_id = self.tcx.hir().local_def_id(item.hir_id);
                 let adt_def = self.tcx.adt_def(def_id);
                 let ty = self.tcx.type_of(def_id);
 
@@ -836,7 +836,7 @@ pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {
 /// Given the list of enabled features that were not language features (i.e., that
 /// were expected to be library features), and the list of features used from
 /// libraries, identify activated features that don't exist and error about them.
-pub fn check_unused_or_stable_features<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
     let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
 
     if tcx.stability().staged_api[&LOCAL_CRATE] {
@@ -920,8 +920,8 @@ pub fn check_unused_or_stable_features<'tcx>(tcx: TyCtxt<'tcx>) {
     // don't lint about unused features. We should reenable this one day!
 }
 
-fn unnecessary_stable_feature_lint<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn unnecessary_stable_feature_lint(
+    tcx: TyCtxt<'_>,
     span: Span,
     feature: Symbol,
     since: Symbol,
index 256b3f1015093f2038938c3e4a90a4a23ff31c1c..c8f42b1c604a587b2315e135ae6b51b6eb0d0676 100644 (file)
@@ -37,6 +37,10 @@ pub fn assert_reported(self) {
     }
 }
 
+CloneTypeFoldableImpls! {
+    ErrorHandled,
+}
+
 pub type ConstEvalRawResult<'tcx> = Result<RawConst<'tcx>, ErrorHandled>;
 pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
 
@@ -178,7 +182,7 @@ pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'
 /// up with a Rust-level backtrace of where the error occured.
 /// Thsese should always be constructed by calling `.into()` on
 /// a `InterpError`. In `librustc_mir::interpret`, we have the `err!`
-/// macro for this
+/// macro for this.
 #[derive(Debug, Clone)]
 pub struct InterpErrorInfo<'tcx> {
     pub kind: InterpError<'tcx, u64>,
index 388c549324268452183254b523635654ffdb40ba..867565d5e0922bec9359ea8d1369dfcb7ca35abb 100644 (file)
@@ -275,17 +275,6 @@ pub fn get_ptr_offset(self, cx: &impl HasDataLayout) -> Size {
         }
     }
 
-    #[inline]
-    pub fn is_null_ptr(self, cx: &impl HasDataLayout) -> bool {
-        match self {
-            Scalar::Raw { data, size } => {
-                assert_eq!(size as u64, cx.data_layout().pointer_size.bytes());
-                data == 0
-            },
-            Scalar::Ptr(_) => false,
-        }
-    }
-
     #[inline]
     pub fn from_bool(b: bool) -> Self {
         Scalar::Raw { data: b as u128, size: 1 }
index 9b1808c585ce7f605b72bea27f06f77266555780..59a032d53cfd67991da6d32ac16d5d41707b6597 100644 (file)
@@ -2867,19 +2867,19 @@ fn start_node(&self) -> Self::Node {
 }
 
 impl<'tcx> graph::WithPredecessors for Body<'tcx> {
-    fn predecessors<'graph>(
-        &'graph self,
+    fn predecessors(
+        &self,
         node: Self::Node,
-    ) -> <Self as GraphPredecessors<'graph>>::Iter {
+    ) -> <Self as GraphPredecessors<'_>>::Iter {
         self.predecessors_for(node).clone().into_iter()
     }
 }
 
 impl<'tcx> graph::WithSuccessors for Body<'tcx> {
-    fn successors<'graph>(
-        &'graph self,
+    fn successors(
+        &self,
         node: Self::Node,
-    ) -> <Self as GraphSuccessors<'graph>>::Iter {
+    ) -> <Self as GraphSuccessors<'_>>::Iter {
         self.basic_blocks[node].terminator().successors().cloned()
     }
 }
index 432a61de6cb984cc46ae500c4bd520d53d3877fb..a061e6f48f4c0bc554751c55d0ed77778d5febd6 100644 (file)
@@ -79,7 +79,7 @@ pub fn symbol_name(&self, tcx: TyCtxt<'tcx>) -> SymbolName {
                 tcx.symbol_name(Instance::mono(tcx, def_id))
             }
             MonoItem::GlobalAsm(hir_id) => {
-                let def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
+                let def_id = tcx.hir().local_def_id(hir_id);
                 SymbolName {
                     name: InternedString::intern(&format!("global_asm_{:?}", def_id))
                 }
index d2082ab87e738c6acd1ebdbbd27ed17b6781a970..442a90ab3f845b8a666aefa1882f0e286076ad03 100644 (file)
                 "const-evaluating `{}`",
                 tcx.def_path_str(key.value.instance.def.def_id())
             }
-            cache_on_disk_if(_, opt_result) {
-                // Only store results without errors
-                // FIXME: We never store these
-                opt_result.map_or(true, |r| r.is_ok())
-            }
         }
 
         /// Results of evaluating const items or constants embedded in
index 895f9c6d8fb8510661dae5a14aa034448854c5d4..82c53be3ec70ff15316d2fa9d5f34d9333a23090 100644 (file)
@@ -269,11 +269,11 @@ pub fn contains_key(&self, key: &OutputType) -> bool {
         self.0.contains_key(key)
     }
 
-    pub fn keys<'a>(&'a self) -> BTreeMapKeysIter<'a, OutputType, Option<PathBuf>> {
+    pub fn keys(&self) -> BTreeMapKeysIter<'_, OutputType, Option<PathBuf>> {
         self.0.keys()
     }
 
-    pub fn values<'a>(&'a self) -> BTreeMapValuesIter<'a, OutputType, Option<PathBuf>> {
+    pub fn values(&self) -> BTreeMapValuesIter<'_, OutputType, Option<PathBuf>> {
         self.0.values()
     }
 
@@ -316,7 +316,7 @@ pub fn get(&self, key: &str) -> Option<&ExternEntry> {
         self.0.get(key)
     }
 
-    pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, ExternEntry> {
+    pub fn iter(&self) -> BTreeMapIter<'_, String, ExternEntry> {
         self.0.iter()
     }
 }
@@ -1207,7 +1207,11 @@ fn parse_symbol_mangling_version(
     linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled,
         parse_linker_plugin_lto, [TRACKED],
         "generate build artifacts that are compatible with linker-based LTO."),
-
+    profile_generate: SwitchWithOptPath = (SwitchWithOptPath::Disabled,
+        parse_switch_with_opt_path, [TRACKED],
+        "compile the program with profiling instrumentation"),
+    profile_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
+        "use the given `.profdata` file for profile-guided optimization"),
 }
 
 options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
@@ -1379,11 +1383,6 @@ fn parse_symbol_mangling_version(
         "extra arguments to prepend to the linker invocation (space separated)"),
     profile: bool = (false, parse_bool, [TRACKED],
                      "insert profiling code"),
-    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: 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."),
     relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED],
@@ -2036,13 +2035,6 @@ pub fn build_session_options_and_crate_config(
         }
     }
 
-    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",
-        );
-    }
-
     let mut output_types = BTreeMap::new();
     if !debugging_opts.parse_only {
         for list in matches.opt_strs("emit") {
@@ -2154,6 +2146,13 @@ pub fn build_session_options_and_crate_config(
         );
     }
 
+    if cg.profile_generate.enabled() && cg.profile_use.is_some() {
+        early_error(
+            error_format,
+            "options `-C profile-generate` and `-C profile-use` are exclusive",
+        );
+    }
+
     let mut prints = Vec::<PrintRequest>::new();
     if cg.target_cpu.as_ref().map_or(false, |s| s == "help") {
         prints.push(PrintRequest::TargetCPUs);
index b8477f8dd178956ed298452c12fc3d8d44757fbc..3d6312548a47bcf58b13688c0905092402bbd7fa 100644 (file)
@@ -519,11 +519,11 @@ fn test_codegen_options_tracking_hash() {
     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
     opts = reference.clone();
-    opts.debugging_opts.pgo_gen = SwitchWithOptPath::Enabled(None);
+    opts.cg.profile_generate = SwitchWithOptPath::Enabled(None);
     assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
 
     opts = reference.clone();
-    opts.debugging_opts.pgo_use = Some(PathBuf::from("abc"));
+    opts.cg.profile_use = Some(PathBuf::from("abc"));
     assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
 
     opts = reference.clone();
index bb4ef2d7bd4268cf63b027f22559ea6190297970..3cbf0ee213ae371891821890de7a2086d3e61bc8 100644 (file)
@@ -215,66 +215,66 @@ pub fn local_crate_disambiguator(&self) -> CrateDisambiguator {
         *self.crate_disambiguator.get()
     }
 
-    pub fn struct_span_warn<'a, S: Into<MultiSpan>>(
-        &'a self,
+    pub fn struct_span_warn<S: Into<MultiSpan>>(
+        &self,
         sp: S,
         msg: &str,
-    ) -> DiagnosticBuilder<'a> {
+    ) -> DiagnosticBuilder<'_> {
         self.diagnostic().struct_span_warn(sp, msg)
     }
-    pub fn struct_span_warn_with_code<'a, S: Into<MultiSpan>>(
-        &'a self,
+    pub fn struct_span_warn_with_code<S: Into<MultiSpan>>(
+        &self,
         sp: S,
         msg: &str,
         code: DiagnosticId,
-    ) -> DiagnosticBuilder<'a> {
+    ) -> DiagnosticBuilder<'_> {
         self.diagnostic().struct_span_warn_with_code(sp, msg, code)
     }
-    pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
+    pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> {
         self.diagnostic().struct_warn(msg)
     }
-    pub fn struct_span_err<'a, S: Into<MultiSpan>>(
-        &'a self,
+    pub fn struct_span_err<S: Into<MultiSpan>>(
+        &self,
         sp: S,
         msg: &str,
-    ) -> DiagnosticBuilder<'a> {
+    ) -> DiagnosticBuilder<'_> {
         self.diagnostic().struct_span_err(sp, msg)
     }
-    pub fn struct_span_err_with_code<'a, S: Into<MultiSpan>>(
-        &'a self,
+    pub fn struct_span_err_with_code<S: Into<MultiSpan>>(
+        &self,
         sp: S,
         msg: &str,
         code: DiagnosticId,
-    ) -> DiagnosticBuilder<'a> {
+    ) -> DiagnosticBuilder<'_> {
         self.diagnostic().struct_span_err_with_code(sp, msg, code)
     }
     // FIXME: This method should be removed (every error should have an associated error code).
-    pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
+    pub fn struct_err(&self, msg: &str) -> DiagnosticBuilder<'_> {
         self.diagnostic().struct_err(msg)
     }
-    pub fn struct_err_with_code<'a>(
-        &'a self,
+    pub fn struct_err_with_code(
+        &self,
         msg: &str,
         code: DiagnosticId,
-    ) -> DiagnosticBuilder<'a> {
+    ) -> DiagnosticBuilder<'_> {
         self.diagnostic().struct_err_with_code(msg, code)
     }
-    pub fn struct_span_fatal<'a, S: Into<MultiSpan>>(
-        &'a self,
+    pub fn struct_span_fatal<S: Into<MultiSpan>>(
+        &self,
         sp: S,
         msg: &str,
-    ) -> DiagnosticBuilder<'a> {
+    ) -> DiagnosticBuilder<'_> {
         self.diagnostic().struct_span_fatal(sp, msg)
     }
-    pub fn struct_span_fatal_with_code<'a, S: Into<MultiSpan>>(
-        &'a self,
+    pub fn struct_span_fatal_with_code<S: Into<MultiSpan>>(
+        &self,
         sp: S,
         msg: &str,
         code: DiagnosticId,
-    ) -> DiagnosticBuilder<'a> {
+    ) -> DiagnosticBuilder<'_> {
         self.diagnostic().struct_span_fatal_with_code(sp, msg, code)
     }
-    pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
+    pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_> {
         self.diagnostic().struct_fatal(msg)
     }
 
@@ -416,7 +416,7 @@ pub fn reserve_node_ids(&self, count: usize) -> ast::NodeId {
     pub fn next_node_id(&self) -> NodeId {
         self.reserve_node_ids(1)
     }
-    pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler {
+    pub fn diagnostic(&self) -> &errors::Handler {
         &self.parse_sess.span_diagnostic
     }
 
@@ -504,7 +504,7 @@ pub fn diag_span_suggestion_once<'a, 'b>(
         );
     }
 
-    pub fn source_map<'a>(&'a self) -> &'a source_map::SourceMap {
+    pub fn source_map(&self) -> &source_map::SourceMap {
         self.parse_sess.source_map()
     }
     pub fn verbose(&self) -> bool {
@@ -1295,9 +1295,9 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
 
     // 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 let Some(ref path) = sess.opts.cg.profile_use {
         if !path.exists() {
-            sess.err(&format!("File `{}` passed to `-Zpgo-use` does not exist.",
+            sess.err(&format!("File `{}` passed to `-C profile-use` does not exist.",
                               path.display()));
         }
     }
@@ -1306,7 +1306,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
     // an error to combine the two for now. It always runs into an assertions
     // if LLVM is built with assertions, but without assertions it sometimes
     // does not crash and will probably generate a corrupted binary.
-    if sess.opts.debugging_opts.pgo_gen.enabled() &&
+    if sess.opts.cg.profile_generate.enabled() &&
        sess.target.target.options.is_like_msvc &&
        sess.panic_strategy() == PanicStrategy::Unwind {
         sess.err("Profile-guided optimization does not yet work in conjunction \
index d8087af60acdf3abe8be2523ff50822434cde0d4..b6f0addd77107216c344fefa999de768462d56ba 100644 (file)
@@ -48,8 +48,8 @@ pub fn add_placeholder_note(err: &mut errors::DiagnosticBuilder<'_>) {
 /// If there are types that satisfy both impls, invokes `on_overlap`
 /// with a suitably-freshened `ImplHeader` with those types
 /// substituted. Otherwise, invokes `no_overlap`.
-pub fn overlapping_impls<'tcx, F1, F2, R>(
-    tcx: TyCtxt<'tcx>,
+pub fn overlapping_impls<F1, F2, R>(
+    tcx: TyCtxt<'_>,
     impl1_def_id: DefId,
     impl2_def_id: DefId,
     intercrate_mode: IntercrateMode,
@@ -247,10 +247,10 @@ pub enum OrphanCheckErr<'tcx> {
 ///
 /// 1. All type parameters in `Self` must be "covered" by some local type constructor.
 /// 2. Some local type must appear in `Self`.
-pub fn orphan_check<'tcx>(
-    tcx: TyCtxt<'tcx>,
+pub fn orphan_check(
+    tcx: TyCtxt<'_>,
     impl_def_id: DefId,
-) -> Result<(), OrphanCheckErr<'tcx>> {
+) -> Result<(), OrphanCheckErr<'_>> {
     debug!("orphan_check({:?})", impl_def_id);
 
     // We only except this routine to be invoked on implementations
index f54575ff8fc1dcb87047c2bf8482a55537afec47..d6cc68bcdab468c19c68a709bbcf5fb4457a47ff 100644 (file)
@@ -247,7 +247,7 @@ fn report_projection_error(&self,
     fn fuzzy_match_tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
         /// returns the fuzzy category of a given type, or None
         /// if the type can be equated to any type.
-        fn type_category<'tcx>(t: Ty<'tcx>) -> Option<u32> {
+        fn type_category(t: Ty<'_>) -> Option<u32> {
             match t.sty {
                 ty::Bool => Some(0),
                 ty::Char => Some(1),
index f106458c7676a93068c890ae8268848408df767c..99b5ef3894b9ce02c2c39f396530274a06fbd0c7 100644 (file)
@@ -461,41 +461,35 @@ fn process_obligation(&mut self,
             }
 
             ty::Predicate::ConstEvaluatable(def_id, substs) => {
-                match self.selcx.tcx().lift_to_global(&obligation.param_env) {
-                    None => {
+                if obligation.param_env.has_local_value() {
                         ProcessResult::Unchanged
-                    }
-                    Some(param_env) => {
-                        match self.selcx.tcx().lift_to_global(&substs) {
-                            Some(substs) => {
-                                let instance = ty::Instance::resolve(
-                                    self.selcx.tcx().global_tcx(),
-                                    param_env,
-                                    def_id,
-                                    substs,
-                                );
-                                if let Some(instance) = instance {
-                                    let cid = GlobalId {
-                                        instance,
-                                        promoted: None,
-                                    };
-                                    match self.selcx.tcx().at(obligation.cause.span)
-                                                          .const_eval(param_env.and(cid)) {
-                                        Ok(_) => ProcessResult::Changed(vec![]),
-                                        Err(err) => ProcessResult::Error(
-                                            CodeSelectionError(ConstEvalFailure(err)))
-                                    }
-                                } else {
-                                    ProcessResult::Error(CodeSelectionError(
-                                        ConstEvalFailure(ErrorHandled::TooGeneric)
-                                    ))
-                                }
-                            },
-                            None => {
-                                pending_obligation.stalled_on = substs.types().collect();
-                                ProcessResult::Unchanged
+                } else {
+                    if !substs.has_local_value() {
+                        let instance = ty::Instance::resolve(
+                            self.selcx.tcx().global_tcx(),
+                            obligation.param_env,
+                            def_id,
+                            substs,
+                        );
+                        if let Some(instance) = instance {
+                            let cid = GlobalId {
+                                instance,
+                                promoted: None,
+                            };
+                            match self.selcx.tcx().at(obligation.cause.span)
+                                                    .const_eval(obligation.param_env.and(cid)) {
+                                Ok(_) => ProcessResult::Changed(vec![]),
+                                Err(err) => ProcessResult::Error(
+                                    CodeSelectionError(ConstEvalFailure(err)))
                             }
+                        } else {
+                            ProcessResult::Error(CodeSelectionError(
+                                ConstEvalFailure(ErrorHandled::TooGeneric)
+                            ))
                         }
+                    } else {
+                        pending_obligation.stalled_on = substs.types().collect();
+                        ProcessResult::Unchanged
                     }
                 }
             }
index 8d17df1e61055ab3183412856a6a687e36b73985..1ca92d79fa5f66bc5293cfd6dd2b7fd89e9e1fe9 100644 (file)
@@ -457,6 +457,16 @@ pub enum SelectionError<'tcx> {
     Overflow,
 }
 
+EnumTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for SelectionError<'tcx> {
+        (SelectionError::Unimplemented),
+        (SelectionError::OutputTypeParameterMismatch)(a, b, c),
+        (SelectionError::TraitNotObjectSafe)(a),
+        (SelectionError::ConstEvalFailure)(a),
+        (SelectionError::Overflow),
+    }
+}
+
 pub struct FulfillmentError<'tcx> {
     pub obligation: PredicateObligation<'tcx>,
     pub code: FulfillmentErrorCode<'tcx>
@@ -782,13 +792,11 @@ fn do_normalize_predicates<'tcx>(
                 return Err(ErrorReported)
             }
         };
-
-        match tcx.lift_to_global(&predicates) {
-            Some(predicates) => Ok(predicates),
-            None => {
-                // FIXME: shouldn't we, you know, actually report an error here? or an ICE?
-                Err(ErrorReported)
-            }
+        if predicates.has_local_value() {
+            // FIXME: shouldn't we, you know, actually report an error here? or an ICE?
+            Err(ErrorReported)
+        } else {
+            Ok(predicates)
         }
     })
 }
index cfd5cfa897daf23ce4f8be6318dd30310a000f48..37eff852abd01de8b5c485e7fcc4be4cb7c50cdc 100644 (file)
@@ -702,6 +702,6 @@ fn contains_illegal_self_type_reference(self,
     }
 }
 
-pub(super) fn is_object_safe_provider<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> bool {
+pub(super) fn is_object_safe_provider(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
     tcx.object_safety_violations(trait_def_id).is_empty()
 }
index 0f4b7aff82bce82cb1646be85f7145f00f7381e9..20acf443406908baccd56ddeec2db744e3e73d18 100644 (file)
@@ -399,7 +399,8 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
     fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
         if let ConstValue::Unevaluated(def_id, substs) = constant.val {
             let tcx = self.selcx.tcx().global_tcx();
-            if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
+            let param_env = self.param_env;
+            if !param_env.has_local_value() {
                 if substs.needs_infer() || substs.has_placeholders() {
                     let identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
                     let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
@@ -414,7 +415,7 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc
                         }
                     }
                 } else {
-                    if let Some(substs) = self.tcx().lift_to_global(&substs) {
+                    if !substs.has_local_value() {
                         let instance = ty::Instance::resolve(tcx, param_env, def_id, substs);
                         if let Some(instance) = instance {
                             let cid = GlobalId {
@@ -1508,8 +1509,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
 ///
 /// Based on the "projection mode", this lookup may in fact only examine the
 /// topmost impl. See the comments for `Reveal` for more details.
-fn assoc_ty_def<'cx, 'tcx>(
-    selcx: &SelectionContext<'cx, 'tcx>,
+fn assoc_ty_def(
+    selcx: &SelectionContext<'_, '_>,
     impl_def_id: DefId,
     assoc_ty_def_id: DefId,
 ) -> specialization_graph::NodeItem<ty::AssocItem> {
index 5dd1b9e3d53f3a6db5d9e7b2ad831c6527ae7af4..55e622e46b966f80aec79911845b13fbd80f2bd7 100644 (file)
@@ -193,7 +193,8 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
     fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
         if let ConstValue::Unevaluated(def_id, substs) = constant.val {
             let tcx = self.infcx.tcx.global_tcx();
-            if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
+            let param_env = self.param_env;
+            if !param_env.has_local_value() {
                 if substs.needs_infer() || substs.has_placeholders() {
                     let identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
                     let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
@@ -208,7 +209,7 @@ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tc
                         }
                     }
                 } else {
-                    if let Some(substs) = self.tcx().lift_to_global(&substs) {
+                    if !substs.has_local_value() {
                         let instance = ty::Instance::resolve(tcx, param_env, def_id, substs);
                         if let Some(instance) = instance {
                             let cid = GlobalId {
index 72550e23460e65ed805d80143caeeeeee4301484..a2a5f3f950c7ac022186769fc0406f77f558d654 100644 (file)
@@ -3,7 +3,7 @@
 use crate::traits::query::Fallible;
 
 use crate::infer::canonical::query_response;
-use crate::infer::canonical::QueryRegionConstraint;
+use crate::infer::canonical::QueryRegionConstraints;
 use std::rc::Rc;
 use syntax::source_map::DUMMY_SP;
 use crate::traits::{ObligationCause, TraitEngine, TraitEngineExt};
@@ -39,7 +39,7 @@ impl<'tcx, F, R, G> super::TypeOp<'tcx> for CustomTypeOp<F, G>
     fn fully_perform(
         self,
         infcx: &InferCtxt<'_, 'tcx>,
-    ) -> Fallible<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)> {
+    ) -> Fallible<(Self::Output, Option<Rc<QueryRegionConstraints<'tcx>>>)> {
         if cfg!(debug_assertions) {
             info!("fully_perform({:?})", self);
         }
@@ -62,7 +62,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 fn scrape_region_constraints<'tcx, R>(
     infcx: &InferCtxt<'_, 'tcx>,
     op: impl FnOnce() -> Fallible<InferOk<'tcx, R>>,
-) -> Fallible<(R, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)> {
+) -> Fallible<(R, Option<Rc<QueryRegionConstraints<'tcx>>>)> {
     let mut fulfill_cx = TraitEngine::new(infcx.tcx);
     let dummy_body_id = ObligationCause::dummy().body_id;
 
@@ -92,7 +92,7 @@ fn scrape_region_constraints<'tcx, R>(
 
     let region_constraint_data = infcx.take_and_reset_region_constraints();
 
-    let outlives = query_response::make_query_outlives(
+    let region_constraints = query_response::make_query_region_constraints(
         infcx.tcx,
         region_obligations
             .iter()
@@ -101,9 +101,9 @@ fn scrape_region_constraints<'tcx, R>(
         &region_constraint_data,
     );
 
-    if outlives.is_empty() {
+    if region_constraints.is_empty() {
         Ok((value, None))
     } else {
-        Ok((value, Some(Rc::new(outlives))))
+        Ok((value, Some(Rc::new(region_constraints))))
     }
 }
index 4a07a3120f3e83b61409caf691e7cdf72f29a64f..e2a5cd9670e0c50d889eb56a733c089e092aeb1a 100644 (file)
@@ -1,6 +1,6 @@
 use crate::infer::canonical::{
     Canonical, Canonicalized, CanonicalizedQueryResponse, OriginalQueryValues,
-    QueryRegionConstraint, QueryResponse,
+    QueryRegionConstraints, QueryResponse,
 };
 use crate::infer::{InferCtxt, InferOk};
 use std::fmt;
@@ -32,7 +32,7 @@ pub trait TypeOp<'tcx>: Sized + fmt::Debug {
     fn fully_perform(
         self,
         infcx: &InferCtxt<'_, 'tcx>,
-    ) -> Fallible<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)>;
+    ) -> Fallible<(Self::Output, Option<Rc<QueryRegionConstraints<'tcx>>>)>;
 }
 
 /// "Query type ops" are type ops that are implemented using a
@@ -85,7 +85,7 @@ fn shrink_to_tcx_lifetime(
     fn fully_perform_into(
         query_key: ParamEnvAnd<'tcx, Self>,
         infcx: &InferCtxt<'_, 'tcx>,
-        output_query_region_constraints: &mut Vec<QueryRegionConstraint<'tcx>>,
+        output_query_region_constraints: &mut QueryRegionConstraints<'tcx>,
     ) -> Fallible<Self::QueryResponse> {
         if let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key) {
             return Ok(result);
@@ -140,16 +140,16 @@ impl<'tcx, Q> TypeOp<'tcx> for ParamEnvAnd<'tcx, Q>
     fn fully_perform(
         self,
         infcx: &InferCtxt<'_, 'tcx>,
-    ) -> Fallible<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)> {
-        let mut qrc = vec![];
-        let r = Q::fully_perform_into(self, infcx, &mut qrc)?;
+    ) -> Fallible<(Self::Output, Option<Rc<QueryRegionConstraints<'tcx>>>)> {
+        let mut region_constraints = QueryRegionConstraints::default();
+        let r = Q::fully_perform_into(self, infcx, &mut region_constraints)?;
 
         // Promote the final query-region-constraints into a
         // (optional) ref-counted vector:
-        let opt_qrc = if qrc.is_empty() {
+        let opt_qrc = if region_constraints.is_empty() {
             None
         } else {
-            Some(Rc::new(qrc))
+            Some(Rc::new(region_constraints))
         };
 
         Ok((r, opt_qrc))
index 7c4742259ac161cae85c08cb00fb93e66010d910..798a25fe7b1bc0d7be18935c9b0f21b574929bf3 100644 (file)
@@ -328,6 +328,23 @@ fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
     }
 }
 
+EnumTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for SelectionCandidate<'tcx> {
+        (SelectionCandidate::BuiltinCandidate) { has_nested },
+        (SelectionCandidate::ParamCandidate)(poly_trait_ref),
+        (SelectionCandidate::ImplCandidate)(def_id),
+        (SelectionCandidate::AutoImplCandidate)(def_id),
+        (SelectionCandidate::ProjectionCandidate),
+        (SelectionCandidate::ClosureCandidate),
+        (SelectionCandidate::GeneratorCandidate),
+        (SelectionCandidate::FnPointerCandidate),
+        (SelectionCandidate::TraitAliasCandidate)(def_id),
+        (SelectionCandidate::ObjectCandidate),
+        (SelectionCandidate::BuiltinObjectCandidate),
+        (SelectionCandidate::BuiltinUnsizeCandidate),
+    }
+}
+
 struct SelectionCandidateSet<'tcx> {
     // a list of candidates that definitely apply to the current
     // obligation (meaning: types unify).
@@ -818,27 +835,25 @@ fn evaluate_predicate_recursively<'o>(
 
             ty::Predicate::ConstEvaluatable(def_id, substs) => {
                 let tcx = self.tcx();
-                match tcx.lift_to_global(&(obligation.param_env, substs)) {
-                    Some((param_env, substs)) => {
-                        let instance =
-                            ty::Instance::resolve(tcx.global_tcx(), param_env, def_id, substs);
-                        if let Some(instance) = instance {
-                            let cid = GlobalId {
-                                instance,
-                                promoted: None,
-                            };
-                            match self.tcx().const_eval(param_env.and(cid)) {
-                                Ok(_) => Ok(EvaluatedToOk),
-                                Err(_) => Ok(EvaluatedToErr),
-                            }
-                        } else {
-                            Ok(EvaluatedToErr)
+                if !(obligation.param_env, substs).has_local_value() {
+                    let param_env = obligation.param_env;
+                    let instance =
+                        ty::Instance::resolve(tcx, param_env, def_id, substs);
+                    if let Some(instance) = instance {
+                        let cid = GlobalId {
+                            instance,
+                            promoted: None,
+                        };
+                        match self.tcx().const_eval(param_env.and(cid)) {
+                            Ok(_) => Ok(EvaluatedToOk),
+                            Err(_) => Ok(EvaluatedToErr),
                         }
+                    } else {
+                        Ok(EvaluatedToErr)
                     }
-                    None => {
-                        // Inference variables still left in param_env or substs.
-                        Ok(EvaluatedToAmbig)
-                    }
+                } else {
+                    // Inference variables still left in param_env or substs.
+                    Ok(EvaluatedToAmbig)
                 }
             }
         }
@@ -1172,7 +1187,7 @@ fn insert_evaluation_cache(
         }
 
         if self.can_use_global_caches(param_env) {
-            if let Some(trait_ref) = self.tcx().lift_to_global(&trait_ref) {
+            if !trait_ref.has_local_value() {
                 debug!(
                     "insert_evaluation_cache(trait_ref={:?}, candidate={:?}) global",
                     trait_ref, result,
@@ -1645,8 +1660,8 @@ fn insert_candidate_cache(
             if let Err(Overflow) = candidate {
                 // Don't cache overflow globally; we only produce this
                 // in certain modes.
-            } else if let Some(trait_ref) = tcx.lift_to_global(&trait_ref) {
-                if let Some(candidate) = tcx.lift_to_global(&candidate) {
+            } else if !trait_ref.has_local_value() {
+                if !candidate.has_local_value() {
                     debug!(
                         "insert_candidate_cache(trait_ref={:?}, candidate={:?}) global",
                         trait_ref, candidate,
index 43bb4edd9b27d8e75d1501e9915cc93289a0a838..f0389bb037ac5b827aeb4e1e5bcc8e07f1d29d5a 100644 (file)
@@ -145,8 +145,8 @@ pub fn find_associated_item<'tcx>(
 /// Specialization is determined by the sets of types to which the impls apply;
 /// `impl1` specializes `impl2` if it applies to a subset of the types `impl2` applies
 /// to.
-pub(super) fn specializes<'tcx>(
-    tcx: TyCtxt<'tcx>,
+pub(super) fn specializes(
+    tcx: TyCtxt<'_>,
     (impl1_def_id, impl2_def_id): (DefId, DefId),
 ) -> bool {
     debug!("specializes({:?}, {:?})", impl1_def_id, impl2_def_id);
@@ -282,10 +282,10 @@ fn fulfill_implication<'a, 'tcx>(
 }
 
 // Query provider for `specialization_graph_of`.
-pub(super) fn specialization_graph_provider<'tcx>(
-    tcx: TyCtxt<'tcx>,
+pub(super) fn specialization_graph_provider(
+    tcx: TyCtxt<'_>,
     trait_id: DefId,
-) -> &'tcx specialization_graph::Graph {
+) -> &specialization_graph::Graph {
     let mut sg = specialization_graph::Graph::new();
 
     let mut trait_impls = tcx.all_impls(trait_id);
index 2d295679be32406c2eac5c67dc8b418d8d8045cf..07d6f633143a2c29b8b99e76ca0a55ef2cd062e7 100644 (file)
@@ -417,7 +417,7 @@ pub struct SupertraitDefIds<'tcx> {
     visited: FxHashSet<DefId>,
 }
 
-pub fn supertrait_def_ids<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> SupertraitDefIds<'tcx> {
+pub fn supertrait_def_ids(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SupertraitDefIds<'_> {
     SupertraitDefIds {
         tcx,
         stack: vec![trait_def_id],
index 224f7d5f28dc359bfcf1ed2bfe47ca2a10ff32a7..26e7cc9004d4ee4d5032a1af0999a42ac51c316a 100644 (file)
@@ -27,6 +27,7 @@ pub trait EncodableWithShorthand: Clone + Eq + Hash {
     fn variant(&self) -> &Self::Variant;
 }
 
+#[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))]
 impl<'tcx> EncodableWithShorthand for Ty<'tcx> {
     type Variant = ty::TyKind<'tcx>;
     fn variant(&self) -> &Self::Variant {
@@ -159,6 +160,7 @@ pub fn decode_cnum<D>(decoder: &mut D) -> Result<CrateNum, D::Error>
     Ok(decoder.map_encoded_cnum_to_current(cnum))
 }
 
+#[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))]
 #[inline]
 pub fn decode_ty<D>(decoder: &mut D) -> Result<Ty<'tcx>, D::Error>
 where
index 4710d611d99df0a3b2bc63cfa274aeddc443ff59..16fc46b66d9f45df66e7517f45a37d5dcbceac4d 100644 (file)
@@ -1,5 +1,3 @@
-// ignore-tidy-filelength
-
 //! Type context book-keeping.
 
 use crate::arena::Arena;
@@ -67,7 +65,6 @@
 use std::iter;
 use std::sync::mpsc;
 use std::sync::Arc;
-use std::marker::PhantomData;
 use rustc_target::spec::abi;
 use rustc_macros::HashStable;
 use syntax::ast;
 
 pub struct AllArenas {
     pub interner: SyncDroplessArena,
-    pub local_interner: SyncDroplessArena,
 }
 
 impl AllArenas {
     pub fn new() -> Self {
         AllArenas {
             interner: SyncDroplessArena::default(),
-            local_interner: SyncDroplessArena::default(),
         }
     }
 }
@@ -135,58 +130,23 @@ fn new(arena: &'tcx SyncDroplessArena) -> CtxtInterners<'tcx> {
     }
 
     /// Intern a type
+    #[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))]
     #[inline(never)]
-    fn intern_ty(
-        local: &CtxtInterners<'tcx>,
-        global: &CtxtInterners<'tcx>,
-        st: TyKind<'tcx>,
+    fn intern_ty(&self,
+        st: TyKind<'tcx>
     ) -> Ty<'tcx> {
-        let flags = super::flags::FlagComputation::for_sty(&st);
-
-        // HACK(eddyb) Depend on flags being accurate to
-        // determine that all contents are in the global tcx.
-        // See comments on Lift for why we can't use that.
-        if flags.flags.intersects(ty::TypeFlags::KEEP_IN_LOCAL_TCX) {
-            local.type_.borrow_mut().intern(st, |st| {
-                let ty_struct = TyS {
-                    sty: st,
-                    flags: flags.flags,
-                    outer_exclusive_binder: flags.outer_exclusive_binder,
-                };
+        self.type_.borrow_mut().intern(st, |st| {
+            let flags = super::flags::FlagComputation::for_sty(&st);
 
-                // Make sure we don't end up with inference
-                // types/regions in the global interner
-                if ptr_eq(local, global) {
-                    bug!("Attempted to intern `{:?}` which contains \
-                        inference types/regions in the global type context",
-                        &ty_struct);
-                }
-
-                // This is safe because all the types the ty_struct can point to
-                // already is in the local arena or the global arena
-                let ty_struct: TyS<'tcx> = unsafe {
-                    mem::transmute(ty_struct)
-                };
-
-                Interned(local.arena.alloc(ty_struct))
-            }).0
-        } else {
-            global.type_.borrow_mut().intern(st, |st| {
-                let ty_struct = TyS {
-                    sty: st,
-                    flags: flags.flags,
-                    outer_exclusive_binder: flags.outer_exclusive_binder,
-                };
+            let ty_struct = TyS {
+                sty: st,
+                flags: flags.flags,
+                outer_exclusive_binder: flags.outer_exclusive_binder,
+            };
 
-                // This is safe because all the types the ty_struct can point to
-                // already is in the global arena
-                let ty_struct: TyS<'tcx> = unsafe {
-                    mem::transmute(ty_struct)
-                };
 
-                Interned(global.arena.alloc(ty_struct))
-            }).0
-        }
+            Interned(self.arena.alloc(ty_struct))
+        }).0
     }
 }
 
@@ -933,7 +893,7 @@ impl<'a, 'tcx> Lift<'tcx> for UserType<'a> {
 
 impl<'tcx> CommonTypes<'tcx> {
     fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
-        let mk = |sty| CtxtInterners::intern_ty(interners, interners, sty);
+        let mk = |sty| interners.intern_ty(sty);
 
         CommonTypes {
             unit: mk(Tuple(List::empty())),
@@ -1015,8 +975,6 @@ pub struct FreeRegionInfo {
 #[derive(Copy, Clone)]
 pub struct TyCtxt<'tcx> {
     gcx: &'tcx GlobalCtxt<'tcx>,
-    interners: &'tcx CtxtInterners<'tcx>,
-    dummy: PhantomData<&'tcx ()>,
 }
 
 impl<'tcx> Deref for TyCtxt<'tcx> {
@@ -1030,8 +988,7 @@ fn deref(&self) -> &Self::Target {
 pub struct GlobalCtxt<'tcx> {
     pub arena: WorkerLocal<Arena<'tcx>>,
 
-    global_interners: CtxtInterners<'tcx>,
-    local_interners: CtxtInterners<'tcx>,
+    interners: CtxtInterners<'tcx>,
 
     cstore: &'tcx CrateStoreDyn,
 
@@ -1122,8 +1079,6 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn global_tcx(self) -> TyCtxt<'tcx> {
         TyCtxt {
             gcx: self.gcx,
-            interners: &self.gcx.global_interners,
-            dummy: PhantomData,
         }
     }
 
@@ -1203,11 +1158,6 @@ pub fn lift_to_global<T: ?Sized + Lift<'tcx>>(self, value: &T) -> Option<T::Lift
         value.lift_to_tcx(self.global_tcx())
     }
 
-    /// Returns `true` if self is the same as self.global_tcx().
-    fn is_global(self) -> bool {
-        ptr_eq(self.interners, &self.global_interners)
-    }
-
     /// Creates a type context and call the closure with a `TyCtxt` reference
     /// to the context. The closure enforces that the type context and any interned
     /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
@@ -1229,7 +1179,6 @@ pub fn create_global_ctxt(
             s.fatal(&err);
         });
         let interners = CtxtInterners::new(&arenas.interner);
-        let local_interners = CtxtInterners::new(&arenas.local_interner);
         let common = Common {
             empty_predicates: ty::GenericPredicates {
                 parent: None,
@@ -1287,8 +1236,7 @@ pub fn create_global_ctxt(
             sess: s,
             cstore,
             arena: WorkerLocal::new(|_| Arena::default()),
-            global_interners: interners,
-            local_interners: local_interners,
+            interners,
             dep_graph,
             common,
             types: common_types,
@@ -1304,15 +1252,15 @@ pub fn create_global_ctxt(
             maybe_unused_trait_imports:
                 resolutions.maybe_unused_trait_imports
                     .into_iter()
-                    .map(|id| hir.local_def_id(id))
+                    .map(|id| hir.local_def_id_from_node_id(id))
                     .collect(),
             maybe_unused_extern_crates:
                 resolutions.maybe_unused_extern_crates
                     .into_iter()
-                    .map(|(id, sp)| (hir.local_def_id(id), sp))
+                    .map(|(id, sp)| (hir.local_def_id_from_node_id(id), sp))
                     .collect(),
             glob_map: resolutions.glob_map.into_iter().map(|(id, names)| {
-                (hir.local_def_id(id), names)
+                (hir.local_def_id_from_node_id(id), names)
             }).collect(),
             extern_prelude: resolutions.extern_prelude,
             hir_map: hir,
@@ -1682,8 +1630,6 @@ pub fn enter_local<F, R>(&'tcx self, f: F) -> R
     {
         let tcx = TyCtxt {
             gcx: self,
-            interners: &self.local_interners,
-            dummy: PhantomData,
         };
         ty::tls::with_related_context(tcx.global_tcx(), |icx| {
             let new_icx = ty::tls::ImplicitCtxt {
@@ -1729,11 +1675,7 @@ impl<'a, 'tcx> Lift<'tcx> for $ty {
                     type Lifted = $lifted;
                     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
                         if tcx.interners.arena.in_arena(*self as *const _) {
-                            return Some(unsafe { mem::transmute(*self) });
-                        }
-                        // Also try in the global tcx if we're not that.
-                        if !tcx.is_global() {
-                            self.lift_to_tcx(tcx.global_tcx())
+                            Some(unsafe { mem::transmute(*self) })
                         } else {
                             None
                         }
@@ -1751,11 +1693,7 @@ fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
                             return Some(List::empty());
                         }
                         if tcx.interners.arena.in_arena(*self as *const _) {
-                            return Some(unsafe { mem::transmute(*self) });
-                        }
-                        // Also try in the global tcx if we're not that.
-                        if !tcx.is_global() {
-                            self.lift_to_tcx(tcx.global_tcx())
+                            Some(unsafe { mem::transmute(*self) })
                         } else {
                             None
                         }
@@ -1785,7 +1723,6 @@ pub mod tls {
 
     use std::fmt;
     use std::mem;
-    use std::marker::PhantomData;
     use syntax_pos;
     use crate::ty::query;
     use errors::{Diagnostic, TRACK_DIAGNOSTICS};
@@ -1949,8 +1886,6 @@ pub fn enter_global<'tcx, F, R>(gcx: &'tcx GlobalCtxt<'tcx>, f: F) -> R
 
         let tcx = TyCtxt {
             gcx,
-            interners: &gcx.global_interners,
-            dummy: PhantomData,
         };
         let icx = ImplicitCtxt {
             tcx,
@@ -1981,8 +1916,6 @@ pub unsafe fn with_global<F, R>(f: F) -> R
         let gcx = &*(gcx as *const GlobalCtxt<'_>);
         let tcx = TyCtxt {
             gcx,
-            interners: &gcx.global_interners,
-            dummy: PhantomData,
         };
         let icx = ImplicitCtxt {
             query: None,
@@ -2041,26 +1974,6 @@ pub fn with_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
         })
     }
 
-    /// Allows access to the current ImplicitCtxt whose tcx field has the same global
-    /// interner and local interner as the tcx argument passed in. This means the closure
-    /// is given an ImplicitCtxt with the same 'tcx and 'tcx lifetimes as the TyCtxt passed in.
-    /// This will panic if you pass it a TyCtxt which has a different global interner or
-    /// a different local interner from the current ImplicitCtxt's tcx field.
-    #[inline]
-    pub fn with_fully_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
-    where
-        F: for<'b> FnOnce(&ImplicitCtxt<'b, 'tcx>) -> R,
-    {
-        with_context(|context| {
-            unsafe {
-                assert!(ptr_eq(context.tcx.gcx, tcx.gcx));
-                assert!(ptr_eq(context.tcx.interners, tcx.interners));
-                let context: &ImplicitCtxt<'_, '_> = mem::transmute(context);
-                f(context)
-            }
-        })
-    }
-
     /// Allows access to the TyCtxt in the current ImplicitCtxt.
     /// Panics if there is no ImplicitCtxt available
     #[inline]
@@ -2195,6 +2108,7 @@ fn hash<H: Hasher>(&self, s: &mut H) {
     }
 }
 
+#[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))]
 impl<'tcx> Borrow<TyKind<'tcx>> for Interned<'tcx, TyS<'tcx>> {
     fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> {
         &self.0.sty
@@ -2288,39 +2202,22 @@ fn borrow<'a>(&'a self) -> &'a [Goal<'tcx>] {
 macro_rules! intern_method {
     ($lt_tcx:tt, $name:ident: $method:ident($alloc:ty,
                                             $alloc_method:expr,
-                                            $alloc_to_key:expr,
-                                            $keep_in_local_tcx:expr) -> $ty:ty) => {
+                                            $alloc_to_key:expr) -> $ty:ty) => {
         impl<$lt_tcx> TyCtxt<$lt_tcx> {
             pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
                 let key = ($alloc_to_key)(&v);
 
-                // HACK(eddyb) Depend on flags being accurate to
-                // determine that all contents are in the global tcx.
-                // See comments on Lift for why we can't use that.
-                if ($keep_in_local_tcx)(&v) {
-                    self.interners.$name.borrow_mut().intern_ref(key, || {
-                        // Make sure we don't end up with inference
-                        // types/regions in the global tcx.
-                        if self.is_global() {
-                            bug!("Attempted to intern `{:?}` which contains \
-                                inference types/regions in the global type context",
-                                v);
-                        }
+                self.interners.$name.borrow_mut().intern_ref(key, || {
+                    Interned($alloc_method(&self.interners.arena, v))
 
-                        Interned($alloc_method(&self.interners.arena, v))
-                    }).0
-                } else {
-                    self.global_interners.$name.borrow_mut().intern_ref(key, || {
-                        Interned($alloc_method(&self.global_interners.arena, v))
-                    }).0
-                }
+                }).0
             }
         }
     }
 }
 
 macro_rules! direct_interners {
-    ($lt_tcx:tt, $($name:ident: $method:ident($keep_in_local_tcx:expr) -> $ty:ty),+) => {
+    ($lt_tcx:tt, $($name:ident: $method:ident($ty:ty)),+) => {
         $(impl<$lt_tcx> PartialEq for Interned<$lt_tcx, $ty> {
             fn eq(&self, other: &Self) -> bool {
                 self.0 == other.0
@@ -2339,8 +2236,7 @@ fn hash<H: Hasher>(&self, s: &mut H) {
             $lt_tcx,
             $name: $method($ty,
                            |a: &$lt_tcx SyncDroplessArena, v| -> &$lt_tcx $ty { a.alloc(v) },
-                           |x| x,
-                           $keep_in_local_tcx) -> $ty);)+
+                           |x| x) -> $ty);)+
     }
 }
 
@@ -2349,9 +2245,9 @@ pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
 }
 
 direct_interners!('tcx,
-    region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind,
-    goal: mk_goal(|c: &GoalKind<'_>| keep_local(c)) -> GoalKind<'tcx>,
-    const_: mk_const(|c: &Const<'_>| keep_local(&c)) -> Const<'tcx>
+    region: mk_region(RegionKind),
+    goal: mk_goal(GoalKind<'tcx>),
+    const_: mk_const(Const<'tcx>)
 );
 
 macro_rules! slice_interners {
@@ -2359,8 +2255,7 @@ macro_rules! slice_interners {
         $(intern_method!( 'tcx, $field: $method(
             &[$ty],
             |a, v| List::from_arena(a, v),
-            Deref::deref,
-            |xs: &[$ty]| xs.iter().any(keep_local)) -> List<$ty>);)+
+            Deref::deref) -> List<$ty>);)+
     );
 }
 
@@ -2384,8 +2279,7 @@ macro_rules! slice_interners {
     canonical_var_infos: _intern_canonical_var_infos(
         &[CanonicalVarInfo],
         |a, v| List::from_arena(a, v),
-        Deref::deref,
-        |_xs: &[CanonicalVarInfo]| -> bool { false }
+        Deref::deref
     ) -> List<CanonicalVarInfo>
 }
 
@@ -2429,9 +2323,10 @@ pub fn coerce_closure_fn_ty(self, sig: PolyFnSig<'tcx>, unsafety: hir::Unsafety)
         self.mk_fn_ptr(converted_sig)
     }
 
+    #[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))]
     #[inline]
     pub fn mk_ty(&self, st: TyKind<'tcx>) -> Ty<'tcx> {
-        CtxtInterners::intern_ty(&self.interners, &self.global_interners, st)
+        self.interners.intern_ty(st)
     }
 
     pub fn mk_mach_int(self, tm: ast::IntTy) -> Ty<'tcx> {
index 999b4eff85697ef1abb85ca799555a94dc41af57..3dd1fd100f2a4658a476818a7629654a8352bc5e 100644 (file)
@@ -42,10 +42,10 @@ fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
     }
 
     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        if let Some(ty_lifted) = self.tcx.lift_to_global(&ty) {
-            self.tcx.erase_regions_ty(ty_lifted)
-        } else {
+        if ty.has_local_value() {
             ty.super_fold_with(self)
+        } else {
+            self.tcx.erase_regions_ty(ty)
         }
     }
 
index 8d7e7e16e85cb738fc102c4d0e76c3b39c4f90da..411b18e043a203a36dd5e3a575e3c9564b86c235 100644 (file)
@@ -18,6 +18,7 @@ fn new() -> FlagComputation {
         }
     }
 
+    #[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))]
     pub fn for_sty(st: &ty::TyKind<'_>) -> FlagComputation {
         let mut result = FlagComputation::new();
         result.add_sty(st);
@@ -61,6 +62,7 @@ fn add_bound_computation(&mut self, computation: &FlagComputation) {
         } // otherwise, this binder captures nothing
     }
 
+    #[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))]
     fn add_sty(&mut self, st: &ty::TyKind<'_>) {
         match st {
             &ty::Bool |
index 8b98a2916a76693b13c6de3042a714023f73c621..ab7df8e4e845b25a045880068e17c814766ba154 100644 (file)
@@ -91,6 +91,9 @@ fn has_self_ty(&self) -> bool {
     fn has_infer_types(&self) -> bool {
         self.has_type_flags(TypeFlags::HAS_TY_INFER)
     }
+    fn has_local_value(&self) -> bool {
+        self.has_type_flags(TypeFlags::KEEP_IN_LOCAL_TCX)
+    }
     fn needs_infer(&self) -> bool {
         self.has_type_flags(
             TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER | TypeFlags::HAS_CT_INFER
@@ -922,6 +925,7 @@ fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> bool {
     }
 }
 
+// FIXME: Optimize for checking for infer flags
 struct HasTypeFlagsVisitor {
     flags: ty::TypeFlags,
 }
index af8dedfc8812e389874fb9bed343766c38520f45..4453624fa4502334a58a9d8e118ed70dd3fa6f28 100644 (file)
@@ -33,7 +33,7 @@ pub fn empty() -> DefIdForest {
     /// crate.
     #[inline]
     pub fn full(tcx: TyCtxt<'tcx>) -> DefIdForest {
-        let crate_id = tcx.hir().local_def_id_from_hir_id(CRATE_HIR_ID);
+        let crate_id = tcx.hir().local_def_id(CRATE_HIR_ID);
         DefIdForest::from_id(crate_id)
     }
 
index ad9880725128f0156af94de039c9aaf1d70c313c..6701c20b0a3660e43e659bb125938244e0c1de9a 100644 (file)
@@ -1,7 +1,5 @@
 // ignore-tidy-filelength
 
-#![allow(usage_of_ty_tykind)]
-
 pub use self::Variance::*;
 pub use self::AssocItemContainer::*;
 pub use self::BorrowKind::*;
@@ -484,6 +482,7 @@ pub struct TypeFlags: u32 {
     }
 }
 
+#[cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))]
 pub struct TyS<'tcx> {
     pub sty: TyKind<'tcx>,
     pub flags: TypeFlags,
@@ -541,29 +540,29 @@ fn hash<H: Hasher>(&self, s: &mut H) {
 impl<'tcx> TyS<'tcx> {
     pub fn is_primitive_ty(&self) -> bool {
         match self.sty {
-            TyKind::Bool |
-            TyKind::Char |
-            TyKind::Int(_) |
-            TyKind::Uint(_) |
-            TyKind::Float(_) |
-            TyKind::Infer(InferTy::IntVar(_)) |
-            TyKind::Infer(InferTy::FloatVar(_)) |
-            TyKind::Infer(InferTy::FreshIntTy(_)) |
-            TyKind::Infer(InferTy::FreshFloatTy(_)) => true,
-            TyKind::Ref(_, x, _) => x.is_primitive_ty(),
+            Bool |
+            Char |
+            Int(_) |
+            Uint(_) |
+            Float(_) |
+            Infer(InferTy::IntVar(_)) |
+            Infer(InferTy::FloatVar(_)) |
+            Infer(InferTy::FreshIntTy(_)) |
+            Infer(InferTy::FreshFloatTy(_)) => true,
+            Ref(_, x, _) => x.is_primitive_ty(),
             _ => false,
         }
     }
 
     pub fn is_suggestable(&self) -> bool {
         match self.sty {
-            TyKind::Opaque(..) |
-            TyKind::FnDef(..) |
-            TyKind::FnPtr(..) |
-            TyKind::Dynamic(..) |
-            TyKind::Closure(..) |
-            TyKind::Infer(..) |
-            TyKind::Projection(..) => false,
+            Opaque(..) |
+            FnDef(..) |
+            FnPtr(..) |
+            Dynamic(..) |
+            Closure(..) |
+            Infer(..) |
+            Projection(..) => false,
             _ => true,
         }
     }
@@ -2816,7 +2815,7 @@ fn associated_item_from_trait_item_ref(self,
                                            parent_vis: &hir::Visibility,
                                            trait_item_ref: &hir::TraitItemRef)
                                            -> AssocItem {
-        let def_id = self.hir().local_def_id_from_hir_id(trait_item_ref.id.hir_id);
+        let def_id = self.hir().local_def_id(trait_item_ref.id.hir_id);
         let (kind, has_self) = match trait_item_ref.kind {
             hir::AssocItemKind::Const => (ty::AssocKind::Const, false),
             hir::AssocItemKind::Method { has_self } => {
@@ -2842,7 +2841,7 @@ fn associated_item_from_impl_item_ref(self,
                                           parent_def_id: DefId,
                                           impl_item_ref: &hir::ImplItemRef)
                                           -> AssocItem {
-        let def_id = self.hir().local_def_id_from_hir_id(impl_item_ref.id.hir_id);
+        let def_id = self.hir().local_def_id(impl_item_ref.id.hir_id);
         let (kind, has_self) = match impl_item_ref.kind {
             hir::AssocItemKind::Const => (ty::AssocKind::Const, false),
             hir::AssocItemKind::Method { has_self } => {
@@ -3114,7 +3113,7 @@ fn next(&mut self) -> Option<AssocItem> {
 fn associated_item(tcx: TyCtxt<'_>, 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);
+    let parent_def_id = tcx.hir().local_def_id(parent_id);
     let parent_item = tcx.hir().expect_item(parent_id);
     match parent_item.node {
         hir::ItemKind::Impl(.., ref impl_item_refs) => {
@@ -3178,14 +3177,14 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] {
             tcx.arena.alloc_from_iter(
                 trait_item_refs.iter()
                                .map(|trait_item_ref| trait_item_ref.id)
-                               .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
+                               .map(|id| tcx.hir().local_def_id(id.hir_id))
             )
         }
         hir::ItemKind::Impl(.., ref impl_item_refs) => {
             tcx.arena.alloc_from_iter(
                 impl_item_refs.iter()
                               .map(|impl_item_ref| impl_item_ref.id)
-                              .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
+                              .map(|id| tcx.hir().local_def_id(id.hir_id))
             )
         }
         hir::ItemKind::TraitAlias(..) => &[],
index 8b2183c42efd46cb6ee636df61f4af43bcc419a0..56c9474170cad0ca533675f6d853240bcc404dd2 100644 (file)
@@ -201,28 +201,22 @@ pub fn serialize<'tcx, E>(&self, tcx: TyCtxt<'tcx>, encoder: &mut E) -> Result<(
             let mut query_result_index = EncodedQueryResultIndex::new();
 
             time(tcx.sess, "encode query results", || {
-                use crate::ty::query::queries::*;
                 let enc = &mut encoder;
                 let qri = &mut query_result_index;
 
-                encode_query_results::<type_of<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<generics_of<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<predicates_of<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<used_trait_imports<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<typeck_tables_of<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<codegen_fulfill_obligation<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<optimized_mir<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<unsafety_check_result<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<borrowck<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<mir_borrowck<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<mir_const_qualif<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<const_is_rvalue_promotable_to_static<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<symbol_name<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<check_match<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<codegen_fn_attrs<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<specialization_graph_of<'_>, _>(tcx, enc, qri)?;
-                encode_query_results::<const_eval<'_>, _>(tcx, enc, qri)?;
-                // FIXME: Include const_eval_raw?
+                macro_rules! encode_queries {
+                    ($($query:ident,)*) => {
+                        $(
+                            encode_query_results::<ty::query::queries::$query<'_>, _>(
+                                tcx,
+                                enc,
+                                qri
+                            )?;
+                        )*
+                    }
+                }
+
+                rustc_cached_queries!(encode_queries!);
 
                 Ok(())
             })?;
@@ -306,9 +300,9 @@ fn sorted_cnums_including_local_crate(tcx: TyCtxt<'_>) -> Vec<CrateNum> {
     }
 
     /// Loads a diagnostic emitted during the previous compilation session.
-    pub fn load_diagnostics<'tcx>(
+    pub fn load_diagnostics(
         &self,
-        tcx: TyCtxt<'tcx>,
+        tcx: TyCtxt<'_>,
         dep_node_index: SerializedDepNodeIndex,
     ) -> Vec<Diagnostic> {
         let diagnostics: Option<EncodedDiagnostics> = self.load_indexed(
@@ -335,9 +329,9 @@ pub fn store_diagnostics(&self,
 
     /// Returns the cached query result if there is something in the cache for
     /// the given `SerializedDepNodeIndex`; otherwise returns `None`.
-    pub fn try_load_query_result<'tcx, T>(
+    pub fn try_load_query_result<T>(
         &self,
-        tcx: TyCtxt<'tcx>,
+        tcx: TyCtxt<'_>,
         dep_node_index: SerializedDepNodeIndex,
     ) -> Option<T>
     where
index 5a7d106700af282d5b331723e48a2da753a9b2e5..0c9e31e1ff28e9c7b8bd87167e13f701dfcd7900 100644 (file)
@@ -1166,7 +1166,7 @@ fn default() -> Self {
 /// then `force_from_dep_node()` should not fail for it. Otherwise, you can just
 /// add it to the "We don't have enough information to reconstruct..." group in
 /// the match below.
-pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool {
+pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool {
     use crate::dep_graph::RecoverKey;
 
     // We must avoid ever having to call force_from_dep_node() for a
index 46adb7eb2a47642d8b61214c7791b7d7f5407ce1..a6bfc2dee613b0ce04bb8e997f1cd4550cd390ff 100644 (file)
@@ -550,7 +550,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
         if let ConstValue::Unevaluated(def_id, substs) = x.val {
             // FIXME(eddyb) get the right param_env.
             let param_env = ty::ParamEnv::empty();
-            if let Some(substs) = tcx.lift_to_global(&substs) {
+            if !substs.has_local_value() {
                 let instance = ty::Instance::resolve(
                     tcx.global_tcx(),
                     param_env,
index 3d8170586c47f9248e97b3d73e0f057e3c84eb9d..28b52dcea80f1126896e75fe02ab5c9027ebb1e9 100644 (file)
@@ -15,6 +15,7 @@
 
 use std::fmt;
 use std::rc::Rc;
+use std::sync::Arc;
 
 impl fmt::Debug for ty::GenericParamDef {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -348,7 +349,7 @@ fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.0).and_then(|a| {
             tcx.lift(&self.1).and_then(|b| tcx.lift(&self.2).map(|c| (a, b, c)))
         })
-    }
+   }
 }
 
 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
@@ -378,6 +379,20 @@ fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
     }
 }
 
+impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Rc<T> {
+    type Lifted = Rc<T::Lifted>;
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
+        tcx.lift(&**self).map(Rc::new)
+    }
+}
+
+impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Arc<T> {
+    type Lifted = Arc<T::Lifted>;
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
+        tcx.lift(&**self).map(Arc::new)
+    }
+}
+
 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
     type Lifted = Vec<T::Lifted>;
     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
@@ -821,6 +836,13 @@ impl<'tcx, T> TypeFoldable<'tcx> for Option<T> {
     } where T: TypeFoldable<'tcx>
 }
 
+EnumTypeFoldableImpl! {
+    impl<'tcx, T, E> TypeFoldable<'tcx> for Result<T, E> {
+        (Ok)(a),
+        (Err)(a),
+    } where T: TypeFoldable<'tcx>, E: TypeFoldable<'tcx>,
+}
+
 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         Rc::new((**self).fold_with(folder))
@@ -831,6 +853,16 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
     }
 }
 
+impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
+        Arc::new((**self).fold_with(folder))
+    }
+
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+        (**self).visit_with(visitor)
+    }
+}
+
 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         let content: T = (**self).fold_with(folder);
index 8bfbd8b854b03589506ff74ba39a709086a3bd58..5d17080a9b2bce0c30de8ca16264a3668c105f3e 100644 (file)
@@ -1,5 +1,7 @@
 //! This module contains `TyKind` and its major components.
 
+#![cfg_attr(not(bootstrap), allow(rustc::usage_of_ty_tykind))]
+
 use crate::hir;
 use crate::hir::def_id::DefId;
 use crate::infer::canonical::Canonical;
index a7ade875bf11b25d61368a5298d061218d5c37fe..2bb9c258f8b67b14fb2af647de32ebd61513d30d 100644 (file)
@@ -186,7 +186,7 @@ pub(super) fn trait_impls_of_provider(
         }
 
         for &hir_id in tcx.hir().trait_impls(trait_id) {
-            add_impl(tcx.hir().local_def_id_from_hir_id(hir_id));
+            add_impl(tcx.hir().local_def_id(hir_id));
         }
     }
 
index 2140018223c34cbfc48e443b27e80ab35a1b49ee..8e7936dae0976ca7563923d9531c427d6d193521 100644 (file)
@@ -170,7 +170,7 @@ pub fn time_ext<T, F>(do_it: bool, sess: Option<&Session>, what: &str, f: F) ->
         }
     }
 
-    print_time_passes_entry_internal(what, dur);
+    print_time_passes_entry(true, what, dur);
 
     TIME_DEPTH.with(|slot| slot.set(old));
 
@@ -182,18 +182,6 @@ pub fn print_time_passes_entry(do_it: bool, what: &str, dur: Duration) {
         return
     }
 
-    let old = TIME_DEPTH.with(|slot| {
-        let r = slot.get();
-        slot.set(r + 1);
-        r
-    });
-
-    print_time_passes_entry_internal(what, dur);
-
-    TIME_DEPTH.with(|slot| slot.set(old));
-}
-
-fn print_time_passes_entry_internal(what: &str, dur: Duration) {
     let indentation = TIME_DEPTH.with(|slot| slot.get());
 
     let mem_string = match get_resident() {
index e7a70895a3023c884c91fd95a9bb16ef2d4065aa..8d380c47bc4a371360b12198f7901b82dd9cd860 100644 (file)
@@ -2,7 +2,6 @@
 #![feature(rustc_private)]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 pub mod expand;
index 714b7c27200e3ebe0215dbd1c12522930079fff7..a098cd1761236f3171d7a1872b5e7013ccf4c566 100644 (file)
@@ -354,7 +354,7 @@ pub fn check_for_loans_across_yields(&self,
                                          cmt: &mc::cmt_<'tcx>,
                                          loan_region: ty::Region<'tcx>,
                                          borrow_span: Span) {
-        pub fn borrow_of_local_data<'tcx>(cmt: &mc::cmt_<'tcx>) -> bool {
+        pub fn borrow_of_local_data(cmt: &mc::cmt_<'_>) -> bool {
             match cmt.cat {
                 // Borrows of static items is allowed
                 Categorization::StaticItem => false,
index 3c7f19f7fbf4fb0d772e3462cacde24be6841a5d..34db080ef66332e6607d53d774bdb5008a549e55 100644 (file)
@@ -53,7 +53,7 @@
 
 pub type LoanDataFlow<'tcx> = DataFlowContext<'tcx, LoanDataFlowOperator>;
 
-pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn check_crate(tcx: TyCtxt<'_>) {
     tcx.par_body_owners(|body_owner_def_id| {
         tcx.ensure().borrowck(body_owner_def_id);
     });
@@ -73,7 +73,7 @@ pub struct AnalysisData<'tcx> {
     pub move_data: move_data::FlowedMoveData<'tcx>,
 }
 
-fn borrowck<'tcx>(tcx: TyCtxt<'tcx>, owner_def_id: DefId) -> &'tcx BorrowCheckResult {
+fn borrowck(tcx: TyCtxt<'_>, owner_def_id: DefId) -> &BorrowCheckResult {
     assert!(tcx.use_ast_borrowck() || tcx.migrate_borrowck());
 
     debug!("borrowck(body_owner_def_id={:?})", owner_def_id);
@@ -198,7 +198,7 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
     cfg: &cfg::CFG,
 ) -> (BorrowckCtxt<'a, 'tcx>, AnalysisData<'tcx>) {
     let owner_id = tcx.hir().body_owner(body_id);
-    let owner_def_id = tcx.hir().local_def_id_from_hir_id(owner_id);
+    let owner_def_id = tcx.hir().local_def_id(owner_id);
     let tables = tcx.typeck_tables_of(owner_def_id);
     let region_scope_tree = tcx.region_scope_tree(owner_def_id);
     let body = tcx.hir().body(body_id);
index f5d311b35d738987b3205fdd4fa90518721232b7..95580952ffb95ee204d084a61df63b484d1363f5 100644 (file)
@@ -6,7 +6,6 @@
 use rustc::cfg;
 use rustc::cfg::CFGIndex;
 use rustc::ty::TyCtxt;
-use std::io;
 use std::mem;
 use std::usize;
 use syntax::print::pprust::PrintState;
@@ -84,9 +83,9 @@ struct PropagationContext<'a, 'tcx, O> {
     changed: bool,
 }
 
-fn get_cfg_indices<'a>(id: hir::ItemLocalId,
-                       index: &'a FxHashMap<hir::ItemLocalId, Vec<CFGIndex>>)
-                       -> &'a [CFGIndex] {
+fn get_cfg_indices(id: hir::ItemLocalId,
+                   index: &FxHashMap<hir::ItemLocalId, Vec<CFGIndex>>)
+                   -> &[CFGIndex] {
     index.get(&id).map_or(&[], |v| &v[..])
 }
 
@@ -98,23 +97,23 @@ fn has_bitset_for_local_id(&self, n: hir::ItemLocalId) -> bool {
 }
 
 impl<'tcx, O: DataFlowOperator> pprust::PpAnn for DataFlowContext<'tcx, O> {
-    fn nested(&self, state: &mut pprust::State<'_>, nested: pprust::Nested) -> io::Result<()> {
+    fn nested(&self, state: &mut pprust::State<'_>, nested: pprust::Nested) {
         pprust::PpAnn::nested(self.tcx.hir(), state, nested)
     }
     fn pre(&self,
            ps: &mut pprust::State<'_>,
-           node: pprust::AnnNode<'_>) -> io::Result<()> {
+           node: pprust::AnnNode<'_>) {
         let id = match node {
-            pprust::AnnNode::Name(_) => return Ok(()),
+            pprust::AnnNode::Name(_) => return,
             pprust::AnnNode::Expr(expr) => expr.hir_id.local_id,
             pprust::AnnNode::Block(blk) => blk.hir_id.local_id,
             pprust::AnnNode::Item(_) |
-            pprust::AnnNode::SubItem(_) => return Ok(()),
+            pprust::AnnNode::SubItem(_) => return,
             pprust::AnnNode::Pat(pat) => pat.hir_id.local_id
         };
 
         if !self.has_bitset_for_local_id(id) {
-            return Ok(());
+            return;
         }
 
         assert!(self.bits_per_id > 0);
@@ -147,10 +146,9 @@ fn pre(&self,
 
             ps.synth_comment(
                 format!("id {}: {}{}{}{}", id.as_usize(), entry_str,
-                        gens_str, action_kills_str, scope_kills_str))?;
-            ps.s.space()?;
+                        gens_str, action_kills_str, scope_kills_str));
+            ps.s.space();
         }
-        Ok(())
     }
 }
 
@@ -531,8 +529,8 @@ pub fn propagate(&mut self, cfg: &cfg::CFG, body: &hir::Body) {
 
         debug!("Dataflow result for {}:", self.analysis_name);
         debug!("{}", pprust::to_string(self, |s| {
-            s.cbox(pprust::indent_unit)?;
-            s.ibox(0)?;
+            s.cbox(pprust::indent_unit);
+            s.ibox(0);
             s.print_expr(&body.value)
         }));
     }
index 98e629ce046bbfd3d62c19d7d8e19c08fbf7df6f..b857c625ec2e76c8b0d4cca48928f53b07453985 100644 (file)
@@ -2,7 +2,6 @@
 
 #![allow(non_camel_case_types)]
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #![feature(in_band_lifetimes)]
index 4735588f29a02507df33b38fa48753b3526b2636..94abf1796d3665f4dd1b904fbd0a97d1f162fdef 100644 (file)
@@ -102,8 +102,8 @@ pub fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
         return
     }
 
-    // probestack doesn't play nice either with pgo-gen.
-    if cx.sess().opts.debugging_opts.pgo_gen.enabled() {
+    // probestack doesn't play nice either with `-C profile-generate`.
+    if cx.sess().opts.cg.profile_generate.enabled() {
         return;
     }
 
index e0e26e9af2537796bdb37428eb82076f4cc34196..ca3b2b84655e2939857df0bb775d9e950eb2baef 100644 (file)
@@ -205,8 +205,8 @@ fn llvm_archive_kind(&self) -> Result<ArchiveKind, &str> {
     }
 
     fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> {
-        let removals = mem::replace(&mut self.removals, Vec::new());
-        let mut additions = mem::replace(&mut self.additions, Vec::new());
+        let removals = mem::take(&mut self.removals);
+        let mut additions = mem::take(&mut self.additions);
         let mut strings = Vec::new();
         let mut members = Vec::new();
 
index 3638730707f3f6046f573f363cbb8844203c703f..b135605cf02d765ab38bf780816a838c2cdcc99b 100644 (file)
@@ -239,9 +239,9 @@ fn drop(&mut self) {
     }
 }
 
-unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext<LlvmCodegenBackend>,
-                                               msg: &'b str,
-                                               cookie: c_uint) {
+unsafe extern "C" fn report_inline_asm(cgcx: &CodegenContext<LlvmCodegenBackend>,
+                                       msg: &str,
+                                       cookie: c_uint) {
     cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_owned());
 }
 
index 04645dacfec58c7d9795e7da2f2c2a3588a8ffd4..21c19e167cfbe9299570d8fd652adbdc83d626d2 100644 (file)
@@ -123,8 +123,8 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'tcx>, cgu_name: InternedString) {
 
     submit_codegened_module_to_llvm(&LlvmCodegenBackend(()), tcx, module, cost);
 
-    fn module_codegen<'tcx>(
-        tcx: TyCtxt<'tcx>,
+    fn module_codegen(
+        tcx: TyCtxt<'_>,
         cgu_name: InternedString,
     ) -> ModuleCodegen<ModuleLlvm> {
         let cgu = tcx.codegen_unit(cgu_name);
index 0709368ad860ef973792a951cd7f16f180e5ab70..f67c740b777488423bcce75cc8b3ce715c99967b 100644 (file)
@@ -144,7 +144,7 @@ fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
         }
     }
 
-    fn build_sibling_block<'b>(&self, name: &'b str) -> Self {
+    fn build_sibling_block(&self, name: &str) -> Self {
         Builder::new_block(self.cx, self.llfn(), name)
     }
 
index f21f203fcc99f0abea1f89e242014445b3dc37a5..9fdc93c3ff0f3e01ce3586347f1c30d7a6494bc4 100644 (file)
@@ -170,6 +170,7 @@ pub fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value {
     pub fn const_get_real(&self, v: &'ll Value) -> Option<(f64, bool)> {
         unsafe {
             if self.is_const_real(v) {
+                #[allow(deprecated)]
                 let mut loses_info: llvm::Bool = ::std::mem::uninitialized();
                 let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info);
                 let loses_info = if loses_info == 1 { true } else { false };
index 7831c200114a5d2254f648ed43a06245dca61960..69f8356f66920be0bc29b5fcbe154b0ac95ab056 100644 (file)
@@ -234,7 +234,7 @@ fn codegen_intrinsic_call(
                 return;
             }
             // Effectively no-ops
-            "uninit" | "forget" => {
+            "forget" => {
                 return;
             }
             "needs_drop" => {
index 7283aa95b3027e7d9182d596bd9cd0a6bbda3331..dbcb20315520bb24fbc1e72d402c5e96fbde963b 100644 (file)
@@ -21,8 +21,8 @@
 #![feature(link_args)]
 #![feature(static_nobundle)]
 #![feature(trusted_len)]
+#![feature(mem_take)]
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 use back::write::{create_target_machine, create_informational_target_machine};
@@ -124,7 +124,7 @@ fn codegen_allocator<'tcx>(
     ) {
         unsafe { allocator::codegen(tcx, mods, kind) }
     }
-    fn compile_codegen_unit<'tcx>(&self, tcx: TyCtxt<'tcx>, cgu_name: InternedString) {
+    fn compile_codegen_unit(&self, tcx: TyCtxt<'_>, cgu_name: InternedString) {
         base::compile_codegen_unit(tcx, cgu_name);
     }
     fn target_machine_factory(
index 78570cce57dd9ea9d88ea6ddd73aa4dda8d2b382..d610805b5bbd0e1a8575bd95e0d5a0ac65afc172 100644 (file)
@@ -110,7 +110,7 @@ pub fn get_args(&self) -> &[OsString] {
     }
 
     pub fn take_args(&mut self) -> Vec<OsString> {
-        mem::replace(&mut self.args, Vec::new())
+        mem::take(&mut self.args)
     }
 
     /// Returns a `true` if we're pretty sure that this'll blow OS spawn limits,
index 618e8b8699fcc9713cd1ad550353ed71160f5341..707b7cae16ce73f1d58fa79a05d3dbd1e0dc6b02 100644 (file)
@@ -653,10 +653,14 @@ fn escape_string(s: &[u8]) -> String {
             linker_error.emit();
 
             if sess.target.target.options.is_like_msvc && linker_not_found {
-                sess.note_without_error("the msvc targets depend on the msvc linker \
-                    but `link.exe` was not found");
-                sess.note_without_error("please ensure that VS 2013, VS 2015 or VS 2017 \
-                    was installed with the Visual C++ option");
+                sess.note_without_error(
+                    "the msvc targets depend on the msvc linker \
+                     but `link.exe` was not found",
+                );
+                sess.note_without_error(
+                    "please ensure that VS 2013, VS 2015, VS 2017 or VS 2019 \
+                     was installed with the Visual C++ option",
+                );
             }
             sess.abort_if_errors();
         }
@@ -1179,7 +1183,7 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker,
         cmd.build_static_executable();
     }
 
-    if sess.opts.debugging_opts.pgo_gen.enabled() {
+    if sess.opts.cg.profile_generate.enabled() {
         cmd.pgo_gen();
     }
 
index b9ee82f108ae34a50dcacb12918609efcc359e0c..c5553fa93cf67c2c5ce650c486533ceb04b6782c 100644 (file)
@@ -46,10 +46,10 @@ pub fn crates_export_threshold(crate_types: &[config::CrateType]) -> SymbolExpor
     }
 }
 
-fn reachable_non_generics_provider<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn reachable_non_generics_provider(
+    tcx: TyCtxt<'_>,
     cnum: CrateNum,
-) -> &'tcx DefIdMap<SymbolExportLevel> {
+) -> &DefIdMap<SymbolExportLevel> {
     assert_eq!(cnum, LOCAL_CRATE);
 
     if !tcx.sess.opts.output_types.should_codegen() {
@@ -84,7 +84,7 @@ fn reachable_non_generics_provider<'tcx>(
             // let it through if it's included statically.
             match tcx.hir().get(hir_id) {
                 Node::ForeignItem(..) => {
-                    let def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
+                    let def_id = tcx.hir().local_def_id(hir_id);
                     if tcx.is_statically_included_foreign_item(def_id) {
                         Some(def_id)
                     } else {
@@ -104,7 +104,7 @@ fn reachable_non_generics_provider<'tcx>(
                     node: hir::ImplItemKind::Method(..),
                     ..
                 }) => {
-                    let def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
+                    let def_id = tcx.hir().local_def_id(hir_id);
                     let generics = tcx.generics_of(def_id);
                     if !generics.requires_monomorphization(tcx) &&
                         // Functions marked with #[inline] are only ever codegened
@@ -157,7 +157,7 @@ fn reachable_non_generics_provider<'tcx>(
     tcx.arena.alloc(reachable_non_generics)
 }
 
-fn is_reachable_non_generic_provider_local<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
+fn is_reachable_non_generic_provider_local(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     let export_threshold = threshold(tcx);
 
     if let Some(&level) = tcx.reachable_non_generics(def_id.krate).get(&def_id) {
@@ -167,14 +167,14 @@ fn is_reachable_non_generic_provider_local<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefI
     }
 }
 
-fn is_reachable_non_generic_provider_extern<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
+fn is_reachable_non_generic_provider_extern(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     tcx.reachable_non_generics(def_id.krate).contains_key(&def_id)
 }
 
-fn exported_symbols_provider_local<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn exported_symbols_provider_local(
+    tcx: TyCtxt<'_>,
     cnum: CrateNum,
-) -> Arc<Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)>> {
+) -> Arc<Vec<(ExportedSymbol<'_>, SymbolExportLevel)>> {
     assert_eq!(cnum, LOCAL_CRATE);
 
     if !tcx.sess.opts.output_types.should_codegen() {
@@ -203,7 +203,7 @@ fn exported_symbols_provider_local<'tcx>(
         }
     }
 
-    if tcx.sess.opts.debugging_opts.pgo_gen.enabled() {
+    if tcx.sess.opts.cg.profile_generate.enabled() {
         // These are weak symbols that point to the profile version and the
         // profile name, which need to be treated as exported so LTO doesn't nix
         // them.
@@ -273,10 +273,10 @@ fn exported_symbols_provider_local<'tcx>(
     Arc::new(symbols)
 }
 
-fn upstream_monomorphizations_provider<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn upstream_monomorphizations_provider(
+    tcx: TyCtxt<'_>,
     cnum: CrateNum,
-) -> &'tcx DefIdMap<FxHashMap<SubstsRef<'tcx>, CrateNum>> {
+) -> &DefIdMap<FxHashMap<SubstsRef<'_>, CrateNum>> {
     debug_assert!(cnum == LOCAL_CRATE);
 
     let cnums = tcx.all_crate_nums(LOCAL_CRATE);
@@ -322,10 +322,10 @@ fn upstream_monomorphizations_provider<'tcx>(
     tcx.arena.alloc(instances)
 }
 
-fn upstream_monomorphizations_for_provider<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn upstream_monomorphizations_for_provider(
+    tcx: TyCtxt<'_>,
     def_id: DefId,
-) -> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>> {
+) -> Option<&FxHashMap<SubstsRef<'_>, CrateNum>> {
     debug_assert!(!def_id.is_local());
     tcx.upstream_monomorphizations(LOCAL_CRATE).get(&def_id)
 }
index 309187ca2eaa3e14244967044e31df5dbe1a9ff0..7bb2cc7c08977c0a03dd05a1f7e6225cf591437c 100644 (file)
@@ -423,8 +423,8 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
         modules_config.passes.push("insert-gcov-profiling".to_owned())
     }
 
-    modules_config.pgo_gen = sess.opts.debugging_opts.pgo_gen.clone();
-    modules_config.pgo_use = sess.opts.debugging_opts.pgo_use.clone();
+    modules_config.pgo_gen = sess.opts.cg.profile_generate.clone();
+    modules_config.pgo_use = sess.opts.cg.profile_use.clone();
 
     modules_config.opt_level = Some(sess.opts.optimize);
     modules_config.opt_size = Some(sess.opts.optimize);
@@ -1345,12 +1345,9 @@ fn start_executing_work<B: ExtraBackendMethods>(
                     assert!(!started_lto);
                     started_lto = true;
 
-                    let needs_fat_lto =
-                        mem::replace(&mut needs_fat_lto, Vec::new());
-                    let needs_thin_lto =
-                        mem::replace(&mut needs_thin_lto, Vec::new());
-                    let import_only_modules =
-                        mem::replace(&mut lto_import_only_modules, Vec::new());
+                    let needs_fat_lto = mem::take(&mut needs_fat_lto);
+                    let needs_thin_lto = mem::take(&mut needs_thin_lto);
+                    let import_only_modules = mem::take(&mut lto_import_only_modules);
 
                     for (work, cost) in generate_lto_work(&cgcx, needs_fat_lto,
                                                           needs_thin_lto, import_only_modules) {
@@ -1557,7 +1554,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
             let total_llvm_time = Instant::now().duration_since(llvm_start_time);
             // This is the top-level timing for all of LLVM, set the time-depth
             // to zero.
-            set_time_depth(0);
+            set_time_depth(1);
             print_time_passes_entry(cgcx.time_passes,
                                     "LLVM passes",
                                     total_llvm_time);
index 47b383fddbc31ca9acddcc30ca0888cfbc827dee..a554bf7761c93cbfeeac7732c1b54447e231f037 100644 (file)
@@ -25,7 +25,7 @@
 use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt};
 use rustc::ty::query::Providers;
 use rustc::middle::cstore::{self, LinkagePreference};
-use rustc::util::common::{time, print_time_passes_entry};
+use rustc::util::common::{time, print_time_passes_entry, set_time_depth, time_depth};
 use rustc::session::config::{self, EntryFnType, Lto};
 use rustc::session::Session;
 use rustc::util::nodemap::FxHashMap;
@@ -639,9 +639,12 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
 
     // Since the main thread is sometimes blocked during codegen, we keep track
     // -Ztime-passes output manually.
+    let time_depth = time_depth();
+    set_time_depth(time_depth + 1);
     print_time_passes_entry(tcx.sess.time_passes(),
                             "codegen to LLVM IR",
                             total_codegen_time);
+    set_time_depth(time_depth);
 
     ::rustc_incremental::assert_module_sources::assert_module_sources(tcx);
 
@@ -700,7 +703,7 @@ fn drop(&mut self) {
     }
 }
 
-fn assert_and_save_dep_graph<'tcx>(tcx: TyCtxt<'tcx>) {
+fn assert_and_save_dep_graph(tcx: TyCtxt<'_>) {
     time(tcx.sess,
          "assert dep graph",
          || ::rustc_incremental::assert_dep_graph(tcx));
index d60a2e0cb1358e0f67ad22722ff89f87215a2364..c9b1c0260e8c36e54b2821e3ac95e1de6b2854d9 100644 (file)
@@ -10,7 +10,7 @@ pub enum FunctionDebugContext<D> {
 }
 
 impl<D> FunctionDebugContext<D> {
-    pub fn get_ref<'a>(&'a self, span: Span) -> &'a FunctionDebugContextData<D> {
+    pub fn get_ref(&self, span: Span) -> &FunctionDebugContextData<D> {
         match *self {
             FunctionDebugContext::RegularContext(ref data) => data,
             FunctionDebugContext::DebugInfoDisabled => {
index b76f098773f0b6a26b6758dca781c1f669433537..d0f4b0a870b5ab0a6cfca6202be00ff41c183380 100644 (file)
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
 #![feature(trusted_len)]
+#![feature(mem_take)]
 #![allow(unused_attributes)]
 #![allow(dead_code)]
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #![recursion_limit="256"]
index 0289150a5e42a40305175859c3cf9762cfc67b6c..2af9b448ef1eb03cc57c6733477f1b45a608750b 100644 (file)
@@ -273,7 +273,7 @@ pub fn funclet_bb(self, for_bb: mir::BasicBlock) -> Option<mir::BasicBlock> {
     }
 }
 
-pub fn cleanup_kinds<'tcx>(mir: &mir::Body<'tcx>) -> IndexVec<mir::BasicBlock, CleanupKind> {
+pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKind> {
     fn discover_masters<'tcx>(result: &mut IndexVec<mir::BasicBlock, CleanupKind>,
                               mir: &mir::Body<'tcx>) {
         for (bb, data) in mir.basic_blocks().iter_enumerated() {
index 414871be6116eeabc7259be6b90e6b0b5e6d6b12..9d5aaa7655db88161ee2994755cfa1d071419b4b 100644 (file)
@@ -44,7 +44,7 @@ fn codegen_allocator<'tcx>(
         mods: &mut Self::Module,
         kind: AllocatorKind,
     );
-    fn compile_codegen_unit<'tcx>(&self, tcx: TyCtxt<'tcx>, cgu_name: InternedString);
+    fn compile_codegen_unit(&self, tcx: TyCtxt<'_>, cgu_name: InternedString);
     // If find_features is true this won't access `sess.crate_types` by assuming
     // that `is_pie_binary` is false. When we discover LLVM target features
     // `sess.crate_types` is uninitialized so we cannot access it.
index 1c80e614db8d5b710f519bc2261dcc4c69e625bd..3a144f0b0e0aa0a879bb5b69188abc4700bdc0fb 100644 (file)
@@ -36,7 +36,7 @@ pub trait BuilderMethods<'a, 'tcx>:
 {
     fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self;
     fn with_cx(cx: &'a Self::CodegenCx) -> Self;
-    fn build_sibling_block<'b>(&self, name: &'b str) -> Self;
+    fn build_sibling_block(&self, name: &str) -> Self;
     fn cx(&self) -> &Self::CodegenCx;
     fn llbb(&self) -> Self::BasicBlock;
 
index 942c2d13fac8752457defab49c26ca0127026277..f38b672afd939ac61c57719185e5c0003ecdf162 100644 (file)
@@ -17,7 +17,6 @@
 #![recursion_limit="256"]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #[macro_use]
index f48d1f2853c52598b10a18644355f4e575bf0650..f562744dbe753a3a53bba338551b608c9ef47b85 100644 (file)
@@ -11,7 +11,7 @@
 const SYMBOL_NAME: Symbol = sym::rustc_symbol_name;
 const DEF_PATH: Symbol = sym::rustc_def_path;
 
-pub fn report_symbol_names<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn report_symbol_names(tcx: TyCtxt<'_>) {
     // if the `rustc_attrs` feature is not enabled, then the
     // attributes we are interested in cannot be present anyway, so
     // skip the walk.
@@ -33,7 +33,7 @@ impl SymbolNamesTest<'tcx> {
     fn process_attrs(&mut self,
                      hir_id: hir::HirId) {
         let tcx = self.tcx;
-        let def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
+        let def_id = tcx.hir().local_def_id(hir_id);
         for attr in tcx.get_attrs(def_id).iter() {
             if attr.check_name(SYMBOL_NAME) {
                 // for now, can only use on monomorphic names
diff --git a/src/librustc_data_structures/binary_search_util/mod.rs b/src/librustc_data_structures/binary_search_util/mod.rs
new file mode 100644 (file)
index 0000000..32aa1cb
--- /dev/null
@@ -0,0 +1,49 @@
+#[cfg(test)]
+mod test;
+
+/// Uses a sorted slice `data: &[E]` as a kind of "multi-map". The
+/// `key_fn` extracts a key of type `K` from the data, and this
+/// function finds the range of elements that match the key. `data`
+/// must have been sorted as if by a call to `sort_by_key` for this to
+/// work.
+pub fn binary_search_slice<E, K>(data: &'d [E], key_fn: impl Fn(&E) -> K, key: &K) -> &'d [E]
+where
+    K: Ord,
+{
+    let mid = match data.binary_search_by_key(key, &key_fn) {
+        Ok(mid) => mid,
+        Err(_) => return &[],
+    };
+
+    // We get back *some* element with the given key -- so
+    // search backwards to find the *first* one.
+    //
+    // (It'd be more efficient to use a "galloping" search
+    // here, but it's not really worth it for small-ish
+    // amounts of data.)
+    let mut start = mid;
+    while start > 0 {
+        if key_fn(&data[start - 1]) == *key {
+            start -= 1;
+        } else {
+            break;
+        }
+    }
+
+    // Now search forward to find the *last* one.
+    //
+    // (It'd be more efficient to use a "galloping" search
+    // here, but it's not really worth it for small-ish
+    // amounts of data.)
+    let mut end = mid + 1;
+    let max = data.len();
+    while end < max {
+        if key_fn(&data[end]) == *key {
+            end += 1;
+        } else {
+            break;
+        }
+    }
+
+    &data[start..end]
+}
diff --git a/src/librustc_data_structures/binary_search_util/test.rs b/src/librustc_data_structures/binary_search_util/test.rs
new file mode 100644 (file)
index 0000000..d74febb
--- /dev/null
@@ -0,0 +1,23 @@
+use super::*;
+
+type Element = (usize, &'static str);
+
+fn test_map() -> Vec<Element> {
+    let mut data = vec![(3, "three-a"), (0, "zero"), (3, "three-b"), (22, "twenty-two")];
+    data.sort_by_key(get_key);
+    data
+}
+
+fn get_key(data: &Element) -> usize {
+    data.0
+}
+
+#[test]
+fn binary_search_slice_test() {
+    let map = test_map();
+    assert_eq!(binary_search_slice(&map, get_key, &0), &[(0, "zero")]);
+    assert_eq!(binary_search_slice(&map, get_key, &1), &[]);
+    assert_eq!(binary_search_slice(&map, get_key, &3), &[(3, "three-a"), (3, "three-b")]);
+    assert_eq!(binary_search_slice(&map, get_key, &22), &[(22, "twenty-two")]);
+    assert_eq!(binary_search_slice(&map, get_key, &23), &[]);
+}
index 5d8388d89f5b3097a17b2ff9ab7a02aa28545cd8..1eb28bccbe382cd4663e853d3aaf62b959849da2 100644 (file)
@@ -168,7 +168,7 @@ pub fn words(&self) -> &[Word] {
 
     /// Iterates over the indices of set bits in a sorted order.
     #[inline]
-    pub fn iter<'a>(&'a self) -> BitIter<'a, T> {
+    pub fn iter(&self) -> BitIter<'_, T> {
         BitIter {
             cur: None,
             iter: self.words.iter().enumerate(),
@@ -849,7 +849,7 @@ pub fn words(&self) -> &[Word] {
 
     /// Iterates through all the columns set to true in a given row of
     /// the matrix.
-    pub fn iter<'a>(&'a self, row: R) -> BitIter<'a, C> {
+    pub fn iter(&self, row: R) -> BitIter<'_, C> {
         assert!(row.index() < self.num_rows);
         let (start, end) = self.range(row);
         BitIter {
index 7975c62b90fb6fa8c3cd005725a2c2c0938e3f60..3bea965ef30411ce3dff6852b0101033a837434b 100644 (file)
@@ -58,7 +58,7 @@ pub fn encode_opaque(&self, encoder: &mut Encoder) -> EncodeResult {
         Ok(())
     }
 
-    pub fn decode_opaque<'a>(decoder: &mut Decoder<'a>) -> Result<Fingerprint, String> {
+    pub fn decode_opaque(decoder: &mut Decoder<'_>) -> Result<Fingerprint, String> {
         let mut bytes = [0; 16];
 
         decoder.read_raw_bytes(&mut bytes)?;
index de4b1bcd0c2a191f1df095ccf2b476ccaac680f1..d2699004c81d8f9952d9ebd65952142d2ee39d73 100644 (file)
@@ -247,11 +247,11 @@ pub fn predecessor_nodes<'a>(
         self.incoming_edges(target).sources()
     }
 
-    pub fn depth_traverse<'a>(
-        &'a self,
+    pub fn depth_traverse(
+        &self,
         start: NodeIndex,
         direction: Direction,
-    ) -> DepthFirstTraversal<'a, N, E> {
+    ) -> DepthFirstTraversal<'_, N, E> {
         DepthFirstTraversal::with_start_node(self, start, direction)
     }
 
index c09364b0a5395f70c03958a8812e419f867496d6..5612778ce07ed1075b89c257745daacad3b4107b 100644 (file)
@@ -1,5 +1,6 @@
 use super::super::indexed_vec::IndexVec;
-use super::{DirectedGraph, WithSuccessors, WithNumNodes};
+use super::{DirectedGraph, WithNumNodes, WithSuccessors};
+use crate::bit_set::BitSet;
 
 #[cfg(test)]
 mod test;
@@ -51,3 +52,36 @@ pub fn reverse_post_order<G: DirectedGraph + WithSuccessors + WithNumNodes>(
     vec.reverse();
     vec
 }
+
+/// A "depth-first search" iterator for a directed graph.
+pub struct DepthFirstSearch<'graph, G>
+where
+    G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
+{
+    graph: &'graph G,
+    stack: Vec<G::Node>,
+    visited: BitSet<G::Node>,
+}
+
+impl<G> DepthFirstSearch<'graph, G>
+where
+    G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
+{
+    pub fn new(graph: &'graph G, start_node: G::Node) -> Self {
+        Self { graph, stack: vec![start_node], visited: BitSet::new_empty(graph.num_nodes()) }
+    }
+}
+
+impl<G> Iterator for DepthFirstSearch<'_, G>
+where
+    G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
+{
+    type Item = G::Node;
+
+    fn next(&mut self) -> Option<G::Node> {
+        let DepthFirstSearch { stack, visited, graph } = self;
+        let n = stack.pop()?;
+        stack.extend(graph.successors(n).filter(|&m| visited.insert(m)));
+        Some(n)
+    }
+}
index 3d47b7d49fb96947fd87a61652756abdd0cc0218..e59085a9e3a95e3ea8fd8a7eb2cbe830e410aed7 100644 (file)
@@ -5,6 +5,7 @@
 pub mod iterate;
 mod reference;
 pub mod scc;
+pub mod vec_graph;
 
 #[cfg(test)]
 mod test;
@@ -17,14 +18,25 @@ pub trait WithNumNodes: DirectedGraph {
     fn num_nodes(&self) -> usize;
 }
 
+pub trait WithNumEdges: DirectedGraph {
+    fn num_edges(&self) -> usize;
+}
+
 pub trait WithSuccessors: DirectedGraph
 where
     Self: for<'graph> GraphSuccessors<'graph, Item = <Self as DirectedGraph>::Node>,
 {
-    fn successors<'graph>(
-        &'graph self,
+    fn successors(
+        &self,
         node: Self::Node,
-    ) -> <Self as GraphSuccessors<'graph>>::Iter;
+    ) -> <Self as GraphSuccessors<'_>>::Iter;
+
+    fn depth_first_search(&self, from: Self::Node) -> iterate::DepthFirstSearch<'_, Self>
+    where
+        Self: WithNumNodes,
+    {
+        iterate::DepthFirstSearch::new(self, from)
+    }
 }
 
 pub trait GraphSuccessors<'graph> {
@@ -36,10 +48,10 @@ pub trait WithPredecessors: DirectedGraph
 where
     Self: for<'graph> GraphPredecessors<'graph, Item = <Self as DirectedGraph>::Node>,
 {
-    fn predecessors<'graph>(
-        &'graph self,
+    fn predecessors(
+        &self,
         node: Self::Node,
-    ) -> <Self as GraphPredecessors<'graph>>::Iter;
+    ) -> <Self as GraphPredecessors<'_>>::Iter;
 }
 
 pub trait GraphPredecessors<'graph> {
index 5ad2a71e1d7323c424ac42a7192c72d8a52e4e62..9442bb3cdec3b8a11cf73122535d98c569a7f011 100644 (file)
@@ -17,15 +17,15 @@ fn start_node(&self) -> Self::Node {
 }
 
 impl<'graph, G: WithSuccessors> WithSuccessors for &'graph G {
-    fn successors<'iter>(&'iter self, node: Self::Node) -> <Self as GraphSuccessors<'iter>>::Iter {
+    fn successors(&self, node: Self::Node) -> <Self as GraphSuccessors<'_>>::Iter {
         (**self).successors(node)
     }
 }
 
 impl<'graph, G: WithPredecessors> WithPredecessors for &'graph G {
-    fn predecessors<'iter>(&'iter self,
-                           node: Self::Node)
-                           -> <Self as GraphPredecessors<'iter>>::Iter {
+    fn predecessors(&self,
+                    node: Self::Node)
+                    -> <Self as GraphPredecessors<'_>>::Iter {
         (**self).predecessors(node)
     }
 }
index 24c5448639e7d7db911414abb7a1d248b8aab166..78554cda77b44b2a8710e37667af151043b20d84 100644 (file)
@@ -4,7 +4,8 @@
 //! O(n) time.
 
 use crate::fx::FxHashSet;
-use crate::graph::{DirectedGraph, WithNumNodes, WithSuccessors};
+use crate::graph::{DirectedGraph, WithNumNodes, WithNumEdges, WithSuccessors, GraphSuccessors};
+use crate::graph::vec_graph::VecGraph;
 use crate::indexed_vec::{Idx, IndexVec};
 use std::ops::Range;
 
@@ -58,6 +59,49 @@ pub fn scc(&self, r: N) -> S {
     pub fn successors(&self, scc: S) -> &[S] {
         self.scc_data.successors(scc)
     }
+
+    /// Construct the reverse graph of the SCC graph.
+    pub fn reverse(&self) -> VecGraph<S> {
+        VecGraph::new(
+            self.num_sccs(),
+            self.all_sccs()
+                .flat_map(|source| self.successors(source).iter().map(move |&target| {
+                    (target, source)
+                }))
+                .collect(),
+        )
+    }
+}
+
+impl<N: Idx, S: Idx> DirectedGraph for Sccs<N, S> {
+    type Node = S;
+}
+
+impl<N: Idx, S: Idx> WithNumNodes for Sccs<N, S> {
+    fn num_nodes(&self) -> usize {
+        self.num_sccs()
+    }
+}
+
+impl<N: Idx, S: Idx> WithNumEdges for Sccs<N, S> {
+    fn num_edges(&self) -> usize {
+        self.scc_data.all_successors.len()
+    }
+}
+
+impl<N: Idx, S: Idx> GraphSuccessors<'graph> for Sccs<N, S> {
+    type Item = S;
+
+    type Iter = std::iter::Cloned<std::slice::Iter<'graph, S>>;
+}
+
+impl<N: Idx, S: Idx> WithSuccessors for Sccs<N, S> {
+    fn successors<'graph>(
+        &'graph self,
+        node: S
+    ) -> <Self as GraphSuccessors<'graph>>::Iter {
+        self.successors(node).iter().cloned()
+    }
 }
 
 impl<S: Idx> SccData<S> {
index b390c4195729429b5903c8e933ef0056e77b5703..bc142144e930f24e8790df0d40e4b13dc1c8fff3 100644 (file)
@@ -51,15 +51,15 @@ fn num_nodes(&self) -> usize {
 }
 
 impl WithPredecessors for TestGraph {
-    fn predecessors<'graph>(&'graph self,
-                            node: usize)
-                            -> <Self as GraphPredecessors<'graph>>::Iter {
+    fn predecessors(&self,
+                    node: usize)
+                    -> <Self as GraphPredecessors<'_>>::Iter {
         self.predecessors[&node].iter().cloned()
     }
 }
 
 impl WithSuccessors for TestGraph {
-    fn successors<'graph>(&'graph self, node: usize) -> <Self as GraphSuccessors<'graph>>::Iter {
+    fn successors(&self, node: usize) -> <Self as GraphSuccessors<'_>>::Iter {
         self.successors[&node].iter().cloned()
     }
 }
diff --git a/src/librustc_data_structures/graph/vec_graph/mod.rs b/src/librustc_data_structures/graph/vec_graph/mod.rs
new file mode 100644 (file)
index 0000000..6fb1bb4
--- /dev/null
@@ -0,0 +1,113 @@
+use crate::indexed_vec::{Idx, IndexVec};
+use crate::graph::{DirectedGraph, WithNumNodes, WithNumEdges, WithSuccessors, GraphSuccessors};
+
+#[cfg(test)]
+mod test;
+
+pub struct VecGraph<N: Idx> {
+    /// Maps from a given node to an index where the set of successors
+    /// for that node starts. The index indexes into the `edges`
+    /// vector. To find the range for a given node, we look up the
+    /// start for that node and then the start for the next node
+    /// (i.e., with an index 1 higher) and get the range between the
+    /// two. This vector always has an extra entry so that this works
+    /// even for the max element.
+    node_starts: IndexVec<N, usize>,
+
+    edge_targets: Vec<N>,
+}
+
+impl<N: Idx> VecGraph<N> {
+    pub fn new(
+        num_nodes: usize,
+        mut edge_pairs: Vec<(N, N)>,
+    ) -> Self {
+        // Sort the edges by the source -- this is important.
+        edge_pairs.sort();
+
+        let num_edges = edge_pairs.len();
+
+        // Store the *target* of each edge into `edge_targets`.
+        let edge_targets: Vec<N> = edge_pairs.iter().map(|&(_, target)| target).collect();
+
+        // Create the *edge starts* array. We are iterating over over
+        // the (sorted) edge pairs. We maintain the invariant that the
+        // length of the `node_starts` arary is enough to store the
+        // current source node -- so when we see that the source node
+        // for an edge is greater than the current length, we grow the
+        // edge-starts array by just enough.
+        let mut node_starts = IndexVec::with_capacity(num_edges);
+        for (index, &(source, _)) in edge_pairs.iter().enumerate() {
+            // If we have a list like `[(0, x), (2, y)]`:
+            //
+            // - Start out with `node_starts` of `[]`
+            // - Iterate to `(0, x)` at index 0:
+            //   - Push one entry because `node_starts.len()` (0) is <= the source (0)
+            //   - Leaving us with `node_starts` of `[0]`
+            // - Iterate to `(2, y)` at index 1:
+            //   - Push one entry because `node_starts.len()` (1) is <= the source (2)
+            //   - Push one entry because `node_starts.len()` (2) is <= the source (2)
+            //   - Leaving us with `node_starts` of `[0, 1, 1]`
+            // - Loop terminates
+            while node_starts.len() <= source.index() {
+                node_starts.push(index);
+            }
+        }
+
+        // Pad out the `node_starts` array so that it has `num_nodes +
+        // 1` entries. Continuing our example above, if `num_nodes` is
+        // be `3`, we would push one more index: `[0, 1, 1, 2]`.
+        //
+        // Interpretation of that vector:
+        //
+        // [0, 1, 1, 2]
+        //        ---- range for N=2
+        //     ---- range for N=1
+        //  ---- range for N=0
+        while node_starts.len() <= num_nodes {
+            node_starts.push(edge_targets.len());
+        }
+
+        assert_eq!(node_starts.len(), num_nodes + 1);
+
+        Self { node_starts, edge_targets }
+    }
+
+    /// Gets the successors for `source` as a slice.
+    pub fn successors(&self, source: N) -> &[N] {
+        let start_index = self.node_starts[source];
+        let end_index = self.node_starts[source.plus(1)];
+        &self.edge_targets[start_index..end_index]
+    }
+}
+
+impl<N: Idx> DirectedGraph for VecGraph<N> {
+    type Node = N;
+}
+
+impl<N: Idx> WithNumNodes for VecGraph<N> {
+    fn num_nodes(&self) -> usize {
+        self.node_starts.len() - 1
+    }
+}
+
+impl<N: Idx> WithNumEdges for VecGraph<N> {
+    fn num_edges(&self) -> usize {
+        self.edge_targets.len()
+    }
+}
+
+impl<N: Idx> GraphSuccessors<'graph> for VecGraph<N> {
+    type Item = N;
+
+    type Iter = std::iter::Cloned<std::slice::Iter<'graph, N>>;
+}
+
+impl<N: Idx> WithSuccessors for VecGraph<N> {
+    fn successors<'graph>(
+        &'graph self,
+        node: N
+    ) -> <Self as GraphSuccessors<'graph>>::Iter {
+        self.successors(node).iter().cloned()
+    }
+}
diff --git a/src/librustc_data_structures/graph/vec_graph/test.rs b/src/librustc_data_structures/graph/vec_graph/test.rs
new file mode 100644 (file)
index 0000000..97a9bd2
--- /dev/null
@@ -0,0 +1,51 @@
+use super::*;
+
+fn create_graph() -> VecGraph<usize> {
+    // Create a simple graph
+    //
+    //          5
+    //          |
+    //          V
+    //    0 --> 1 --> 2
+    //          |
+    //          v
+    //          3 --> 4
+    //
+    //    6
+
+    VecGraph::new(
+        7,
+        vec![
+            (0, 1),
+            (1, 2),
+            (1, 3),
+            (3, 4),
+            (5, 1),
+        ],
+    )
+}
+
+#[test]
+fn num_nodes() {
+    let graph = create_graph();
+    assert_eq!(graph.num_nodes(), 7);
+}
+
+#[test]
+fn succesors() {
+    let graph = create_graph();
+    assert_eq!(graph.successors(0), &[1]);
+    assert_eq!(graph.successors(1), &[2, 3]);
+    assert_eq!(graph.successors(2), &[]);
+    assert_eq!(graph.successors(3), &[4]);
+    assert_eq!(graph.successors(4), &[]);
+    assert_eq!(graph.successors(5), &[1]);
+    assert_eq!(graph.successors(6), &[]);
+}
+
+#[test]
+fn dfs() {
+    let graph = create_graph();
+    let dfs: Vec<_> = graph.depth_first_search(0).collect();
+    assert_eq!(dfs, vec![0, 1, 3, 4, 2]);
+}
index 635edbb927e5c4c1e86cdc6c02e88c057474682f..b3a810a622d03dbdf7b2dd7479b1f21e83feeff2 100644 (file)
@@ -19,8 +19,11 @@ pub trait Idx: Copy + 'static + Ord + Debug + Hash {
     fn index(self) -> usize;
 
     fn increment_by(&mut self, amount: usize) {
-        let v = self.index() + amount;
-        *self = Self::new(v);
+        *self = self.plus(amount);
+    }
+
+    fn plus(self, amount: usize) -> Self {
+        Self::new(self.index() + amount)
     }
 }
 
@@ -167,6 +170,14 @@ impl $type {
             }
         }
 
+        impl std::ops::Add<usize> for $type {
+            type Output = Self;
+
+            fn add(self, other: usize) -> Self {
+                Self::new(self.index() + other)
+            }
+        }
+
         impl Idx for $type {
             #[inline]
             fn new(value: usize) -> Self {
index a1d7ab8856daa4606e023dcabb62b136737a3511..38dfb675237b5d256c378b1da81fe1f5cf3a44db 100644 (file)
@@ -27,6 +27,7 @@
 #![cfg_attr(test, feature(test))]
 
 #![deny(rust_2018_idioms)]
+#![cfg_attr(not(bootstrap), allow(rustc::default_hash_types))]
 
 #[macro_use]
 extern crate log;
@@ -72,6 +73,7 @@ macro_rules! unlikely {
 pub mod macros;
 pub mod svh;
 pub mod base_n;
+pub mod binary_search_util;
 pub mod bit_set;
 pub mod box_region;
 pub mod const_cstr;
index 6e7a8e98853c02f520939c4c5588b11991983eea..3f75523a81584a7bc62330d01ab267200f68ec75 100644 (file)
@@ -1,7 +1,6 @@
 /// A simple static assertion macro.
 #[macro_export]
-#[cfg_attr(bootstrap, allow_internal_unstable(type_ascription, underscore_const_names))]
-#[cfg_attr(not(bootstrap), allow_internal_unstable(type_ascription))]
+#[allow_internal_unstable(type_ascription)]
 macro_rules! static_assert {
     ($test:expr) => {
         // Use the bool to access an array such that if the bool is false, the access
@@ -13,7 +12,6 @@ macro_rules! static_assert {
 
 /// Type size assertion. The first argument is a type and the second argument is its expected size.
 #[macro_export]
-#[cfg_attr(bootstrap, allow_internal_unstable(underscore_const_names))]
 macro_rules! static_assert_size {
     ($ty:ty, $size:expr) => {
         const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()];
index 0974607fabea8f1caaa69961205f8bef50295087..d7cbd1e2e4b476e28a2b87727388997c6b9b4f46 100644 (file)
@@ -58,6 +58,10 @@ pub fn is_empty(&self) -> bool {
         self.edges.is_empty()
     }
 
+    pub fn elements(&self) -> impl Iterator<Item=&T> {
+        self.elements.iter()
+    }
+
     fn index(&self, a: &T) -> Option<Index> {
         self.map.get(a).cloned()
     }
index 5fb6ed31b0693df2d469866ff3c39b8c4054affe..e615f8a4846920915940dbbdd53e9863ffecba4c 100644 (file)
@@ -17,7 +17,6 @@
 #![recursion_limit="256"]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 pub extern crate getopts;
@@ -38,7 +37,8 @@
 use rustc::lint::Lint;
 use rustc::lint;
 use rustc::hir::def_id::LOCAL_CRATE;
-use rustc::util::common::{time, ErrorReported, install_panic_hook};
+use rustc::util::common::{ErrorReported, install_panic_hook, print_time_passes_entry};
+use rustc::util::common::{set_time_depth, time};
 use rustc_metadata::locator;
 use rustc_metadata::cstore::CStore;
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
 use std::env;
 use std::ffi::OsString;
 use std::io::{self, Read, Write};
+use std::mem;
 use std::panic::{self, catch_unwind};
 use std::path::PathBuf;
 use std::process::{self, Command, Stdio};
 use std::str;
-use std::mem;
+use std::time::Instant;
 
 use syntax::ast;
 use syntax::source_map::FileLoader;
@@ -72,7 +73,7 @@
 /// Exit status code used for successful compilation and help output.
 pub const EXIT_SUCCESS: i32 = 0;
 
-/// Exit status code used for compilation failures and  invalid flags.
+/// Exit status code used for compilation failures and invalid flags.
 pub const EXIT_FAILURE: i32 = 1;
 
 const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\
@@ -118,6 +119,18 @@ fn after_analysis(&mut self, _compiler: &interface::Compiler) -> bool {
 
 impl Callbacks for DefaultCallbacks {}
 
+#[derive(Default)]
+pub struct TimePassesCallbacks {
+    time_passes: bool,
+}
+
+impl Callbacks for TimePassesCallbacks {
+    fn config(&mut self, config: &mut interface::Config) {
+        self.time_passes =
+            config.opts.debugging_opts.time_passes || config.opts.debugging_opts.time;
+    }
+}
+
 // Parse args and run the compiler. This is the primary entry point for rustc.
 // See comments on CompilerCalls below for details about the callbacks argument.
 // The FileLoader provides a way to load files from sources other than the file system.
@@ -1169,7 +1182,9 @@ pub fn init_rustc_env_logger() {
 }
 
 pub fn main() {
+    let start = Instant::now();
     init_rustc_env_logger();
+    let mut callbacks = TimePassesCallbacks::default();
     let result = report_ices_to_stderr_if_any(|| {
         let args = env::args_os().enumerate()
             .map(|(i, arg)| arg.into_string().unwrap_or_else(|arg| {
@@ -1177,10 +1192,14 @@ pub fn main() {
                             &format!("Argument {} is not valid Unicode: {:?}", i, arg))
             }))
             .collect::<Vec<_>>();
-        run_compiler(&args, &mut DefaultCallbacks, None, None)
+        run_compiler(&args, &mut callbacks, None, None)
     }).and_then(|result| result);
-    process::exit(match result {
+    let exit_code = match result {
         Ok(_) => EXIT_SUCCESS,
         Err(_) => EXIT_FAILURE,
-    });
+    };
+    // The extra `\t` is necessary to align this label with the others.
+    set_time_depth(0);
+    print_time_passes_entry(callbacks.time_passes, "\ttotal", start.elapsed());
+    process::exit(exit_code);
 }
index d92f3aafa1c7e3dbfdc8f059861843729676f4dd..f314af43f99a431bcaf25987c8b9f7ce48bcda35 100644 (file)
@@ -188,7 +188,7 @@ fn call_with_pp_support<'tcx, A, F>(
             _ => panic!("Should use call_with_pp_support_hir"),
         }
     }
-    fn call_with_pp_support_hir<'tcx, A, F>(&self, tcx: TyCtxt<'tcx>, f: F) -> A
+    fn call_with_pp_support_hir<A, F>(&self, tcx: TyCtxt<'_>, f: F) -> A
     where
         F: FnOnce(&dyn HirPrinterSupport<'_>, &hir::Crate) -> A,
     {
@@ -228,7 +228,7 @@ fn call_with_pp_support_hir<'tcx, A, F>(&self, tcx: TyCtxt<'tcx>, f: F) -> A
 trait PrinterSupport: pprust::PpAnn {
     /// Provides a uniform interface for re-extracting a reference to a
     /// `Session` from a value that now owns it.
-    fn sess<'a>(&'a self) -> &'a Session;
+    fn sess(&self) -> &Session;
 
     /// Produces the pretty-print annotation object.
     ///
@@ -240,7 +240,7 @@ trait PrinterSupport: pprust::PpAnn {
 trait HirPrinterSupport<'hir>: pprust_hir::PpAnn {
     /// Provides a uniform interface for re-extracting a reference to a
     /// `Session` from a value that now owns it.
-    fn sess<'a>(&'a self) -> &'a Session;
+    fn sess(&self) -> &Session;
 
     /// Provides a uniform interface for re-extracting a reference to an
     /// `hir_map::Map` from a value that now owns it.
@@ -272,7 +272,7 @@ struct NoAnn<'hir> {
 }
 
 impl<'hir> PrinterSupport for NoAnn<'hir> {
-    fn sess<'a>(&'a self) -> &'a Session {
+    fn sess(&self) -> &Session {
         self.sess
     }
 
@@ -282,7 +282,7 @@ fn pp_ann<'a>(&'a self) -> &'a dyn pprust::PpAnn {
 }
 
 impl<'hir> HirPrinterSupport<'hir> for NoAnn<'hir> {
-    fn sess<'a>(&'a self) -> &'a Session {
+    fn sess(&self) -> &Session {
         self.sess
     }
 
@@ -297,12 +297,9 @@ fn pp_ann<'a>(&'a self) -> &'a dyn pprust_hir::PpAnn {
 
 impl<'hir> pprust::PpAnn for NoAnn<'hir> {}
 impl<'hir> pprust_hir::PpAnn for NoAnn<'hir> {
-    fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested)
-              -> io::Result<()> {
+    fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) {
         if let Some(tcx) = self.tcx {
             pprust_hir::PpAnn::nested(tcx.hir(), state, nested)
-        } else {
-            Ok(())
         }
     }
 }
@@ -313,7 +310,7 @@ struct IdentifiedAnnotation<'hir> {
 }
 
 impl<'hir> PrinterSupport for IdentifiedAnnotation<'hir> {
-    fn sess<'a>(&'a self) -> &'a Session {
+    fn sess(&self) -> &Session {
         self.sess
     }
 
@@ -323,44 +320,44 @@ fn pp_ann<'a>(&'a self) -> &'a dyn pprust::PpAnn {
 }
 
 impl<'hir> pprust::PpAnn for IdentifiedAnnotation<'hir> {
-    fn pre(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) -> io::Result<()> {
+    fn pre(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) {
         match node {
             pprust::AnnNode::Expr(_) => s.popen(),
-            _ => Ok(()),
+            _ => {}
         }
     }
-    fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) -> io::Result<()> {
+    fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) {
         match node {
             pprust::AnnNode::Ident(_) |
-            pprust::AnnNode::Name(_) => Ok(()),
+            pprust::AnnNode::Name(_) => {},
 
             pprust::AnnNode::Item(item) => {
-                s.s.space()?;
+                s.s.space();
                 s.synth_comment(item.id.to_string())
             }
             pprust::AnnNode::SubItem(id) => {
-                s.s.space()?;
+                s.s.space();
                 s.synth_comment(id.to_string())
             }
             pprust::AnnNode::Block(blk) => {
-                s.s.space()?;
+                s.s.space();
                 s.synth_comment(format!("block {}", blk.id))
             }
             pprust::AnnNode::Expr(expr) => {
-                s.s.space()?;
-                s.synth_comment(expr.id.to_string())?;
+                s.s.space();
+                s.synth_comment(expr.id.to_string());
                 s.pclose()
             }
             pprust::AnnNode::Pat(pat) => {
-                s.s.space()?;
-                s.synth_comment(format!("pat {}", pat.id))
+                s.s.space();
+                s.synth_comment(format!("pat {}", pat.id));
             }
         }
     }
 }
 
 impl<'hir> HirPrinterSupport<'hir> for IdentifiedAnnotation<'hir> {
-    fn sess<'a>(&'a self) -> &'a Session {
+    fn sess(&self) -> &Session {
         self.sess
     }
 
@@ -374,45 +371,42 @@ fn pp_ann<'a>(&'a self) -> &'a dyn pprust_hir::PpAnn {
 }
 
 impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> {
-    fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested)
-              -> io::Result<()> {
+    fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) {
         if let Some(ref tcx) = self.tcx {
             pprust_hir::PpAnn::nested(tcx.hir(), state, nested)
-        } else {
-            Ok(())
         }
     }
-    fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) -> io::Result<()> {
+    fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) {
         match node {
             pprust_hir::AnnNode::Expr(_) => s.popen(),
-            _ => Ok(()),
+            _ => {}
         }
     }
-    fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) -> io::Result<()> {
+    fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) {
         match node {
-            pprust_hir::AnnNode::Name(_) => Ok(()),
+            pprust_hir::AnnNode::Name(_) => {},
             pprust_hir::AnnNode::Item(item) => {
-                s.s.space()?;
+                s.s.space();
                 s.synth_comment(format!("hir_id: {} hir local_id: {}",
                                         item.hir_id, item.hir_id.local_id.as_u32()))
             }
             pprust_hir::AnnNode::SubItem(id) => {
-                s.s.space()?;
+                s.s.space();
                 s.synth_comment(id.to_string())
             }
             pprust_hir::AnnNode::Block(blk) => {
-                s.s.space()?;
+                s.s.space();
                 s.synth_comment(format!("block hir_id: {} hir local_id: {}",
                                         blk.hir_id, blk.hir_id.local_id.as_u32()))
             }
             pprust_hir::AnnNode::Expr(expr) => {
-                s.s.space()?;
+                s.s.space();
                 s.synth_comment(format!("expr hir_id: {} hir local_id: {}",
-                                        expr.hir_id, expr.hir_id.local_id.as_u32()))?;
+                                        expr.hir_id, expr.hir_id.local_id.as_u32()));
                 s.pclose()
             }
             pprust_hir::AnnNode::Pat(pat) => {
-                s.s.space()?;
+                s.s.space();
                 s.synth_comment(format!("pat hir_id: {} hir local_id: {}",
                                         pat.hir_id, pat.hir_id.local_id.as_u32()))
             }
@@ -435,19 +429,19 @@ fn pp_ann(&self) -> &dyn pprust::PpAnn {
 }
 
 impl<'a> pprust::PpAnn for HygieneAnnotation<'a> {
-    fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) -> io::Result<()> {
+    fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) {
         match node {
             pprust::AnnNode::Ident(&ast::Ident { name, span }) => {
-                s.s.space()?;
+                s.s.space();
                 // FIXME #16420: this doesn't display the connections
                 // between syntax contexts
                 s.synth_comment(format!("{}{:?}", name.as_u32(), span.ctxt()))
             }
             pprust::AnnNode::Name(&name) => {
-                s.s.space()?;
+                s.s.space();
                 s.synth_comment(name.as_u32().to_string())
             }
-            _ => Ok(()),
+            _ => {}
         }
     }
 }
@@ -458,7 +452,7 @@ struct TypedAnnotation<'a, 'tcx> {
 }
 
 impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> {
-    fn sess<'a>(&'a self) -> &'a Session {
+    fn sess(&self) -> &Session {
         &self.tcx.sess
     }
 
@@ -471,37 +465,35 @@ fn pp_ann<'a>(&'a self) -> &'a dyn pprust_hir::PpAnn {
     }
 
     fn node_path(&self, id: hir::HirId) -> Option<String> {
-        Some(self.tcx.def_path_str(self.tcx.hir().local_def_id_from_hir_id(id)))
+        Some(self.tcx.def_path_str(self.tcx.hir().local_def_id(id)))
     }
 }
 
 impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> {
-    fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested)
-              -> io::Result<()> {
+    fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) {
         let old_tables = self.tables.get();
         if let pprust_hir::Nested::Body(id) = nested {
             self.tables.set(self.tcx.body_tables(id));
         }
-        pprust_hir::PpAnn::nested(self.tcx.hir(), state, nested)?;
+        pprust_hir::PpAnn::nested(self.tcx.hir(), state, nested);
         self.tables.set(old_tables);
-        Ok(())
     }
-    fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) -> io::Result<()> {
+    fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) {
         match node {
             pprust_hir::AnnNode::Expr(_) => s.popen(),
-            _ => Ok(()),
+            _ => {}
         }
     }
-    fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) -> io::Result<()> {
+    fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) {
         match node {
             pprust_hir::AnnNode::Expr(expr) => {
-                s.s.space()?;
-                s.s.word("as")?;
-                s.s.space()?;
-                s.s.word(self.tables.get().expr_ty(expr).to_string())?;
-                s.pclose()
+                s.s.space();
+                s.s.word("as");
+                s.s.space();
+                s.s.word(self.tables.get().expr_ty(expr).to_string());
+                s.pclose();
             }
-            _ => Ok(()),
+            _ => {},
         }
     }
 }
@@ -728,11 +720,11 @@ pub fn print_after_parsing(sess: &Session,
     let (src, src_name) = get_source(input, sess);
 
     let mut rdr = &*src;
-    let mut out = Vec::new();
+    let mut out = String::new();
 
     if let PpmSource(s) = ppm {
         // Silently ignores an identified node.
-        let out: &mut dyn Write = &mut out;
+        let out = &mut out;
         s.call_with_pp_support(sess, None, move |annotation| {
             debug!("pretty printing source code {:?}", s);
             let sess = annotation.sess();
@@ -741,15 +733,15 @@ pub fn print_after_parsing(sess: &Session,
                                 krate,
                                 src_name,
                                 &mut rdr,
-                                box out,
+                                out,
                                 annotation.pp_ann(),
                                 false)
-        }).unwrap()
+        })
     } else {
         unreachable!();
     };
 
-    write_output(out, ofile);
+    write_output(out.into_bytes(), ofile);
 }
 
 pub fn print_after_hir_lowering<'tcx>(
@@ -773,12 +765,12 @@ pub fn print_after_hir_lowering<'tcx>(
     let (src, src_name) = get_source(input, tcx.sess);
 
     let mut rdr = &src[..];
-    let mut out = Vec::new();
+    let mut out = String::new();
 
     match (ppm, opt_uii) {
             (PpmSource(s), _) => {
                 // Silently ignores an identified node.
-                let out: &mut dyn Write = &mut out;
+                let out = &mut out;
                 s.call_with_pp_support(tcx.sess, Some(tcx), move |annotation| {
                     debug!("pretty printing source code {:?}", s);
                     let sess = annotation.sess();
@@ -787,14 +779,14 @@ pub fn print_after_hir_lowering<'tcx>(
                                         krate,
                                         src_name,
                                         &mut rdr,
-                                        box out,
+                                        out,
                                         annotation.pp_ann(),
                                         true)
                 })
             }
 
             (PpmHir(s), None) => {
-                let out: &mut dyn Write = &mut out;
+                let out = &mut out;
                 s.call_with_pp_support_hir(tcx, move |annotation, krate| {
                     debug!("pretty printing source code {:?}", s);
                     let sess = annotation.sess();
@@ -803,21 +795,21 @@ pub fn print_after_hir_lowering<'tcx>(
                                             krate,
                                             src_name,
                                             &mut rdr,
-                                            box out,
+                                            out,
                                             annotation.pp_ann())
                 })
             }
 
             (PpmHirTree(s), None) => {
-                let out: &mut dyn Write = &mut out;
+                let out = &mut out;
                 s.call_with_pp_support_hir(tcx, move |_annotation, krate| {
                     debug!("pretty printing source code {:?}", s);
-                    write!(out, "{:#?}", krate)
-                })
+                    *out = format!("{:#?}", krate);
+                });
             }
 
             (PpmHir(s), Some(uii)) => {
-                let out: &mut dyn Write = &mut out;
+                let out = &mut out;
                 s.call_with_pp_support_hir(tcx, move |annotation, _| {
                     debug!("pretty printing source code {:?}", s);
                     let sess = annotation.sess();
@@ -826,48 +818,46 @@ pub fn print_after_hir_lowering<'tcx>(
                                                                          &sess.parse_sess,
                                                                          src_name,
                                                                          &mut rdr,
-                                                                         box out,
+                                                                         out,
                                                                          annotation.pp_ann());
                     for node_id in uii.all_matching_node_ids(hir_map) {
                         let hir_id = tcx.hir().node_to_hir_id(node_id);
                         let node = hir_map.get(hir_id);
-                        pp_state.print_node(node)?;
-                        pp_state.s.space()?;
+                        pp_state.print_node(node);
+                        pp_state.s.space();
                         let path = annotation.node_path(hir_id)
                             .expect("-Z unpretty missing node paths");
-                        pp_state.synth_comment(path)?;
-                        pp_state.s.hardbreak()?;
+                        pp_state.synth_comment(path);
+                        pp_state.s.hardbreak();
                     }
-                    pp_state.s.eof()
+                    pp_state.s.eof();
                 })
             }
 
             (PpmHirTree(s), Some(uii)) => {
-                let out: &mut dyn Write = &mut out;
+                let out = &mut out;
                 s.call_with_pp_support_hir(tcx, move |_annotation, _krate| {
                     debug!("pretty printing source code {:?}", s);
                     for node_id in uii.all_matching_node_ids(tcx.hir()) {
                         let hir_id = tcx.hir().node_to_hir_id(node_id);
                         let node = tcx.hir().get(hir_id);
-                        write!(out, "{:#?}", node)?;
+                        out.push_str(&format!("{:#?}", node));
                     }
-                    Ok(())
                 })
             }
 
             _ => unreachable!(),
         }
-        .unwrap();
 
-    write_output(out, ofile);
+    write_output(out.into_bytes(), ofile);
 }
 
 // In an ideal world, this would be a public function called by the driver after
 // analysis is performed. However, we want to call `phase_3_run_analysis_passes`
 // with a different callback than the standard driver, so that isn't easy.
 // Instead, we call that function ourselves.
-fn print_with_analysis<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn print_with_analysis(
+    tcx: TyCtxt<'_>,
     ppm: PpMode,
     uii: Option<UserIdentifiedItem>,
     ofile: Option<&Path>,
@@ -887,7 +877,7 @@ fn print_with_analysis<'tcx>(
     let mut print = || match ppm {
         PpmMir | PpmMirCFG => {
             if let Some(nodeid) = nodeid {
-                let def_id = tcx.hir().local_def_id(nodeid);
+                let def_id = tcx.hir().local_def_id_from_node_id(nodeid);
                 match ppm {
                     PpmMir => write_mir_pretty(tcx, Some(def_id), &mut out),
                     PpmMirCFG => write_mir_graphviz(tcx, Some(def_id), &mut out),
index a2717ab7ad8a9000f06217a691ef533258fda152..83a0fb486fd9a34c728910a571f74c00b5ea790d 100644 (file)
@@ -1635,7 +1635,7 @@ fn from_stderr(color: ColorConfig) -> Destination {
         }
     }
 
-    fn writable<'a>(&'a mut self) -> WritableDst<'a> {
+    fn writable(&mut self) -> WritableDst<'_> {
         match *self {
             Destination::Terminal(ref mut t) => WritableDst::Terminal(t),
             Destination::Buffered(ref mut t) => {
index 70bd25a9d5772cfdb04714b0d50a93846c2af704..3269b85d0dd13243c39a69b3e314e26e89fe9d5f 100644 (file)
@@ -10,7 +10,6 @@
 #![feature(nll)]
 #![feature(optin_builtin_traits)]
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #[allow(unused_extern_crates)]
@@ -438,14 +437,14 @@ pub fn reset_err_count(&self) {
         self.err_count.store(0, SeqCst);
     }
 
-    pub fn struct_dummy<'a>(&'a self) -> DiagnosticBuilder<'a> {
+    pub fn struct_dummy(&self) -> DiagnosticBuilder<'_> {
         DiagnosticBuilder::new(self, Level::Cancelled, "")
     }
 
-    pub fn struct_span_warn<'a, S: Into<MultiSpan>>(&'a self,
-                                                    sp: S,
-                                                    msg: &str)
-                                                    -> DiagnosticBuilder<'a> {
+    pub fn struct_span_warn<S: Into<MultiSpan>>(&self,
+                                                sp: S,
+                                                msg: &str)
+                                                -> DiagnosticBuilder<'_> {
         let mut result = DiagnosticBuilder::new(self, Level::Warning, msg);
         result.set_span(sp);
         if !self.flags.can_emit_warnings {
@@ -453,11 +452,11 @@ pub fn struct_span_warn<'a, S: Into<MultiSpan>>(&'a self,
         }
         result
     }
-    pub fn struct_span_warn_with_code<'a, S: Into<MultiSpan>>(&'a self,
-                                                              sp: S,
-                                                              msg: &str,
-                                                              code: DiagnosticId)
-                                                              -> DiagnosticBuilder<'a> {
+    pub fn struct_span_warn_with_code<S: Into<MultiSpan>>(&self,
+                                                          sp: S,
+                                                          msg: &str,
+                                                          code: DiagnosticId)
+                                                          -> DiagnosticBuilder<'_> {
         let mut result = DiagnosticBuilder::new(self, Level::Warning, msg);
         result.set_span(sp);
         result.code(code);
@@ -466,63 +465,63 @@ pub fn struct_span_warn_with_code<'a, S: Into<MultiSpan>>(&'a self,
         }
         result
     }
-    pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
+    pub fn struct_warn(&self, msg: &str) -> DiagnosticBuilder<'_> {
         let mut result = DiagnosticBuilder::new(self, Level::Warning, msg);
         if !self.flags.can_emit_warnings {
             result.cancel();
         }
         result
     }
-    pub fn struct_span_err<'a, S: Into<MultiSpan>>(&'a self,
-                                                   sp: S,
-                                                   msg: &str)
-                                                   -> DiagnosticBuilder<'a> {
+    pub fn struct_span_err<S: Into<MultiSpan>>(&self,
+                                               sp: S,
+                                               msg: &str)
+                                               -> DiagnosticBuilder<'_> {
         let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
         result.set_span(sp);
         result
     }
-    pub fn struct_span_err_with_code<'a, S: Into<MultiSpan>>(&'a self,
-                                                             sp: S,
-                                                             msg: &str,
-                                                             code: DiagnosticId)
-                                                             -> DiagnosticBuilder<'a> {
+    pub fn struct_span_err_with_code<S: Into<MultiSpan>>(&self,
+                                                         sp: S,
+                                                         msg: &str,
+                                                         code: DiagnosticId)
+                                                         -> DiagnosticBuilder<'_> {
         let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
         result.set_span(sp);
         result.code(code);
         result
     }
     // FIXME: This method should be removed (every error should have an associated error code).
-    pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
+    pub fn struct_err(&self, msg: &str) -> DiagnosticBuilder<'_> {
         DiagnosticBuilder::new(self, Level::Error, msg)
     }
-    pub fn struct_err_with_code<'a>(
-        &'a self,
+    pub fn struct_err_with_code(
+        &self,
         msg: &str,
         code: DiagnosticId,
-    ) -> DiagnosticBuilder<'a> {
+    ) -> DiagnosticBuilder<'_> {
         let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
         result.code(code);
         result
     }
-    pub fn struct_span_fatal<'a, S: Into<MultiSpan>>(&'a self,
-                                                     sp: S,
-                                                     msg: &str)
-                                                     -> DiagnosticBuilder<'a> {
+    pub fn struct_span_fatal<S: Into<MultiSpan>>(&self,
+                                                 sp: S,
+                                                 msg: &str)
+                                                 -> DiagnosticBuilder<'_> {
         let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg);
         result.set_span(sp);
         result
     }
-    pub fn struct_span_fatal_with_code<'a, S: Into<MultiSpan>>(&'a self,
-                                                               sp: S,
-                                                               msg: &str,
-                                                               code: DiagnosticId)
-                                                               -> DiagnosticBuilder<'a> {
+    pub fn struct_span_fatal_with_code<S: Into<MultiSpan>>(&self,
+                                                           sp: S,
+                                                           msg: &str,
+                                                           code: DiagnosticId)
+                                                           -> DiagnosticBuilder<'_> {
         let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg);
         result.set_span(sp);
         result.code(code);
         result
     }
-    pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
+    pub fn struct_fatal(&self, msg: &str) -> DiagnosticBuilder<'_> {
         DiagnosticBuilder::new(self, Level::Fatal, msg)
     }
 
@@ -563,10 +562,10 @@ pub fn span_fatal_with_code<S: Into<MultiSpan>>(&self,
     pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
         self.emit(&sp.into(), msg, Error);
     }
-    pub fn mut_span_err<'a, S: Into<MultiSpan>>(&'a self,
-                                                sp: S,
-                                                msg: &str)
-                                                -> DiagnosticBuilder<'a> {
+    pub fn mut_span_err<S: Into<MultiSpan>>(&self,
+                                            sp: S,
+                                            msg: &str)
+                                            -> DiagnosticBuilder<'_> {
         let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
         result.set_span(sp);
         result
@@ -605,10 +604,10 @@ pub fn span_bug_no_panic<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
     pub fn span_note_without_error<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
         self.emit(&sp.into(), msg, Note);
     }
-    pub fn span_note_diag<'a>(&'a self,
-                              sp: Span,
-                              msg: &str)
-                              -> DiagnosticBuilder<'a> {
+    pub fn span_note_diag(&self,
+                          sp: Span,
+                          msg: &str)
+                          -> DiagnosticBuilder<'_> {
         let mut db = DiagnosticBuilder::new(self, Note, msg);
         db.set_span(sp);
         db
index a43347a2197c3735d055bd260dca268aeddbe259..ba893f5f9369161374f9609c7b6ba1da677103bb 100644 (file)
@@ -51,7 +51,7 @@
 use syntax::ast;
 use syntax_pos::Span;
 
-pub fn assert_dep_graph<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn assert_dep_graph(tcx: TyCtxt<'_>) {
     tcx.dep_graph.with_ignore(|| {
         if tcx.sess.opts.debugging_opts.dump_dep_graph {
             dump_graph(tcx);
@@ -111,7 +111,7 @@ fn argument(&self, attr: &ast::Attribute) -> Option<ast::Name> {
     }
 
     fn process_attrs(&mut self, hir_id: hir::HirId, attrs: &[ast::Attribute]) {
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(hir_id);
+        let def_id = self.tcx.hir().local_def_id(hir_id);
         let def_path_hash = self.tcx.def_path_hash(def_id);
         for attr in attrs {
             if attr.check_name(ATTR_IF_THIS_CHANGED) {
index f502d0475460e04803c65112dffe40c50b93b05c..046fdc72270dbb5cb48568b760189846c602e169 100644 (file)
@@ -35,7 +35,7 @@
 const CFG: Symbol = sym::cfg;
 const KIND: Symbol = sym::kind;
 
-pub fn assert_module_sources<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn assert_module_sources(tcx: TyCtxt<'_>) {
     tcx.dep_graph.with_ignore(|| {
         if tcx.sess.opts.incremental.is_none() {
             return;
index ffea495d3ebdb3c0857cf23c2525539fd1127889..569aa78c9d4b3f0df6d0da39cd4a4791692f9de1 100644 (file)
@@ -9,7 +9,6 @@
 #![recursion_limit="256"]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #[macro_use] extern crate rustc;
index 5296ed0ffd0b818bfa46b554c729f558f4407e78..c23bb6b47f49080b925903cce1425e87c6891f92 100644 (file)
@@ -206,7 +206,7 @@ fn from_dirty_labels(labels: Labels) -> Assertion {
     }
 }
 
-pub fn check_dirty_clean_annotations<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
     // can't add `#[rustc_dirty]` etc without opting in to this feature
     if !tcx.features().rustc_attrs {
         return;
@@ -500,7 +500,7 @@ fn assert_clean(&self, item_span: Span, dep_node: DepNode) {
     }
 
     fn check_item(&mut self, item_id: hir::HirId, item_span: Span) {
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(item_id);
+        let def_id = self.tcx.hir().local_def_id(item_id);
         for attr in self.tcx.get_attrs(def_id).iter() {
             let assertion = match self.assertion_maybe(item_id, attr) {
                 Some(a) => a,
index d9bcc0b2a83c7c1530a091ce7657dbff2fa16b55..90aefb0f32416f8bf56358ba695fb78df55ddb41 100644 (file)
@@ -15,7 +15,7 @@
 use super::file_format;
 use super::work_product;
 
-pub fn dep_graph_tcx_init<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn dep_graph_tcx_init(tcx: TyCtxt<'_>) {
     if !tcx.dep_graph.is_fully_enabled() {
         return
     }
@@ -192,7 +192,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
     }))
 }
 
-pub fn load_query_result_cache<'sess>(sess: &'sess Session) -> OnDiskCache<'sess> {
+pub fn load_query_result_cache(sess: &Session) -> OnDiskCache<'_> {
     if sess.opts.incremental.is_none() ||
        !sess.opts.debugging_opts.incremental_queries {
         return OnDiskCache::new_empty(sess.source_map());
index 49c79ec09f5e2c29b6a7a716572f1e6d28f84ff0..13e2c5d1c574d6aaccf819798681b8ed19638f89 100644 (file)
@@ -15,7 +15,7 @@
 use super::file_format;
 use super::work_product;
 
-pub fn save_dep_graph<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn save_dep_graph(tcx: TyCtxt<'_>) {
     debug!("save_dep_graph()");
     tcx.dep_graph.with_ignore(|| {
         let sess = tcx.sess;
index 7fc311d40c3d09fb2c3870655678d7b7855a434d..4bc50c24e817c216889e7ce06b4d63625f312b87 100644 (file)
@@ -7,7 +7,6 @@
 #![cfg_attr(unix, feature(libc))]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #![allow(unused_imports)]
index c1b6e3409c9159f1918d9c79088e094b893817e4..9a5eb2b93d574f0330f196c8e81cce978cdf669c 100644 (file)
@@ -878,7 +878,7 @@ pub fn create_global_ctxt(
 
 /// Runs the resolution, type-checking, region checking and other
 /// miscellaneous analysis passes on the crate.
-fn analysis<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Result<()> {
+fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {
     assert_eq!(cnum, LOCAL_CRATE);
 
     let sess = tcx.sess;
@@ -899,9 +899,10 @@ fn analysis<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Result<()> {
             });
         }, {
             par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| {
-                tcx.ensure().check_mod_loops(tcx.hir().local_def_id(module));
-                tcx.ensure().check_mod_attrs(tcx.hir().local_def_id(module));
-                tcx.ensure().check_mod_unstable_api_usage(tcx.hir().local_def_id(module));
+                tcx.ensure().check_mod_loops(tcx.hir().local_def_id_from_node_id(module));
+                tcx.ensure().check_mod_attrs(tcx.hir().local_def_id_from_node_id(module));
+                tcx.ensure().check_mod_unstable_api_usage(
+                    tcx.hir().local_def_id_from_node_id(module));
             });
         });
     });
@@ -924,9 +925,9 @@ fn analysis<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Result<()> {
                     // "not all control paths return a value" is reported here.
                     //
                     // maybe move the check to a MIR pass?
-                    tcx.ensure().check_mod_liveness(tcx.hir().local_def_id(module));
+                    tcx.ensure().check_mod_liveness(tcx.hir().local_def_id_from_node_id(module));
 
-                    tcx.ensure().check_mod_intrinsics(tcx.hir().local_def_id(module));
+                    tcx.ensure().check_mod_intrinsics(tcx.hir().local_def_id_from_node_id(module));
                 });
             });
         });
@@ -986,7 +987,7 @@ fn analysis<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Result<()> {
         }, {
             time(sess, "privacy checking modules", || {
                 par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| {
-                    tcx.ensure().check_mod_privacy(tcx.hir().local_def_id(module));
+                    tcx.ensure().check_mod_privacy(tcx.hir().local_def_id_from_node_id(module));
                 });
             });
         });
@@ -995,8 +996,8 @@ fn analysis<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Result<()> {
     Ok(())
 }
 
-fn encode_and_write_metadata<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn encode_and_write_metadata(
+    tcx: TyCtxt<'_>,
     outputs: &OutputFilenames,
 ) -> (middle::cstore::EncodedMetadata, bool) {
     #[derive(PartialEq, Eq, PartialOrd, Ord)]
index 9e1ef6b022d9b9d46e686c3efce4878f3b09c4c5..56180bcad06d33d4a11073f00864e020f198cb13 100644 (file)
@@ -6,17 +6,17 @@
 use syntax::attr;
 use syntax::symbol::sym;
 
-pub fn find<'tcx>(tcx: TyCtxt<'tcx>) -> Option<DefId> {
+pub fn find(tcx: TyCtxt<'_>) -> Option<DefId> {
     tcx.proc_macro_decls_static(LOCAL_CRATE)
 }
 
-fn proc_macro_decls_static<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Option<DefId> {
+fn proc_macro_decls_static(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<DefId> {
     assert_eq!(cnum, LOCAL_CRATE);
 
     let mut finder = Finder { decls: None };
     tcx.hir().krate().visit_all_item_likes(&mut finder);
 
-    finder.decls.map(|id| tcx.hir().local_def_id_from_hir_id(id))
+    finder.decls.map(|id| tcx.hir().local_def_id(id))
 }
 
 struct Finder {
index a86d3cc43948d50a4a6865ad9e009559206f4ac0..6ae5e94b11af389d9afc90388c08642785500bda 100644 (file)
@@ -642,14 +642,14 @@ pub fn build_output_filenames(
                 );
                 None
             } else {
+                if !sess.opts.cg.extra_filename.is_empty() {
+                    sess.warn("ignoring -C extra-filename flag due to -o flag");
+                }
                 Some(out_file.clone())
             };
             if *odir != None {
                 sess.warn("ignoring --out-dir flag due to -o flag");
             }
-            if !sess.opts.cg.extra_filename.is_empty() {
-                sess.warn("ignoring -C extra-filename flag due to -o flag");
-            }
 
             OutputFilenames {
                 out_directory: out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(),
index 12719c3b9d303bc627101f861ce8c53a79b34e4a..267b09bae35e427604ce0ae16f2d1ca737685ff9 100644 (file)
@@ -114,7 +114,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
             hir::ItemKind::Enum(..) |
             hir::ItemKind::Struct(..) |
             hir::ItemKind::Union(..) => {
-                let def_id = cx.tcx.hir().local_def_id_from_hir_id(it.hir_id);
+                let def_id = cx.tcx.hir().local_def_id(it.hir_id);
                 self.check_heap_type(cx, it.span, cx.tcx.type_of(def_id))
             }
             _ => ()
@@ -125,7 +125,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
             hir::ItemKind::Struct(ref struct_def, _) |
             hir::ItemKind::Union(ref struct_def, _) => {
                 for struct_field in struct_def.fields() {
-                    let def_id = cx.tcx.hir().local_def_id_from_hir_id(struct_field.hir_id);
+                    let def_id = cx.tcx.hir().local_def_id(struct_field.hir_id);
                     self.check_heap_type(cx, struct_field.span,
                                          cx.tcx.type_of(def_id));
                 }
@@ -500,21 +500,21 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
-                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id_from_hir_id(item.hir_id));
+                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.hir_id));
                 (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
             }
             hir::ItemKind::Union(_, ref ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
-                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id_from_hir_id(item.hir_id));
+                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.hir_id));
                 (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
             }
             hir::ItemKind::Enum(_, ref ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
-                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id_from_hir_id(item.hir_id));
+                let def = cx.tcx.adt_def(cx.tcx.hir().local_def_id(item.hir_id));
                 (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
             }
             _ => return,
@@ -792,7 +792,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
             _ => return,
         };
 
-        let def_id = cx.tcx.hir().local_def_id_from_hir_id(it.hir_id);
+        let def_id = cx.tcx.hir().local_def_id(it.hir_id);
         let prfn = match cx.tcx.extern_mod_stmt_cnum(def_id) {
             Some(cnum) => cx.tcx.plugin_registrar_fn(cnum),
             None => {
@@ -973,7 +973,7 @@ fn check_item(&mut self, ctx: &LateContext<'_, '_>, item: &hir::Item) {
         if let hir::ItemKind::Union(ref vdata, _) = item.node {
             for field in vdata.fields() {
                 let field_ty = ctx.tcx.type_of(
-                    ctx.tcx.hir().local_def_id_from_hir_id(field.hir_id));
+                    ctx.tcx.hir().local_def_id(field.hir_id));
                 if field_ty.needs_drop(ctx.tcx, ctx.param_env) {
                     ctx.span_lint(UNIONS_WITH_DROP_FIELDS,
                                   field.span,
@@ -1216,7 +1216,7 @@ fn check_item(
         use rustc::ty::Predicate::*;
 
         if cx.tcx.features().trivial_bounds {
-            let def_id = cx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+            let def_id = cx.tcx.hir().local_def_id(item.hir_id);
             let predicates = cx.tcx.predicates_of(def_id);
             for &(predicate, span) in &predicates.predicates {
                 let predicate_kind_name = match predicate {
@@ -1541,7 +1541,7 @@ fn collect_outlived_lifetimes<'tcx>(
         ty_generics: &'tcx ty::Generics,
     ) -> Vec<ty::Region<'tcx>> {
         let index = ty_generics.param_def_id_to_index[
-            &tcx.hir().local_def_id_from_hir_id(param.hir_id)];
+            &tcx.hir().local_def_id(param.hir_id)];
 
         match param.kind {
             hir::GenericParamKind::Lifetime { .. } => {
@@ -1659,7 +1659,7 @@ fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item) {
         use rustc::middle::resolve_lifetime::Region;
 
         let infer_static = cx.tcx.features().infer_static_outlives_requirements;
-        let def_id = cx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let def_id = cx.tcx.hir().local_def_id(item.hir_id);
         if let hir::ItemKind::Struct(_, ref hir_generics)
             | hir::ItemKind::Enum(_, ref hir_generics)
             | hir::ItemKind::Union(_, ref hir_generics) = item.node
index d808a15982e37fc34a260e3c6888609f3ce34b9d..fb02782e6d3200fca67125d7dc978ca5bd3aa765 100644 (file)
@@ -20,7 +20,6 @@
 #![recursion_limit="256"]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #[macro_use]
@@ -74,7 +73,7 @@ pub fn provide(providers: &mut Providers<'_>) {
     };
 }
 
-fn lint_mod<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
+fn lint_mod(tcx: TyCtxt<'_>, module_def_id: DefId) {
     lint::late_lint_mod(tcx, module_def_id, BuiltinCombinedModuleLateLintPass::new());
 }
 
@@ -487,15 +486,17 @@ macro_rules! register_passes {
 
 pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) {
     store.register_early_pass(sess, false, false, box DefaultHashTypes::new());
+    store.register_early_pass(sess, false, false, box LintPassImpl);
     store.register_late_pass(sess, false, false, false, box TyTyKind);
     store.register_group(
         sess,
         false,
-        "internal",
+        "rustc::internal",
         None,
         vec![
             LintId::of(DEFAULT_HASH_TYPES),
             LintId::of(USAGE_OF_TY_TYKIND),
+            LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO),
             LintId::of(TY_PASS_BY_REFERENCE),
             LintId::of(USAGE_OF_QUALIFIED_TY),
         ],
index b221b8ed30c59dc8c2a314636e4ad29fc501b6c4..84f068ab50a22c5f792420c65b5a7195aca2861c 100644 (file)
@@ -20,7 +20,7 @@ pub enum MethodLateContext {
 }
 
 pub fn method_context(cx: &LateContext<'_, '_>, id: hir::HirId) -> MethodLateContext {
-    let def_id = cx.tcx.hir().local_def_id_from_hir_id(id);
+    let def_id = cx.tcx.hir().local_def_id(id);
     let item = cx.tcx.associated_item(def_id);
     match item.container {
         ty::TraitContainer(..) => MethodLateContext::TraitAutoImpl,
index d0258ca30c507d8b589b59b2e82d1ae346f2248a..fdfc6f68590a4b308abf99a4a2bbdb1257f2a5b5 100644 (file)
@@ -888,7 +888,7 @@ fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
     }
 
     fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl) {
-        let def_id = self.cx.tcx.hir().local_def_id_from_hir_id(id);
+        let def_id = self.cx.tcx.hir().local_def_id(id);
         let sig = self.cx.tcx.fn_sig(def_id);
         let sig = self.cx.tcx.erase_late_bound_regions(&sig);
         let inputs = if sig.c_variadic {
@@ -912,7 +912,7 @@ fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl) {
     }
 
     fn check_foreign_static(&mut self, id: hir::HirId, span: Span) {
-        let def_id = self.cx.tcx.hir().local_def_id_from_hir_id(id);
+        let def_id = self.cx.tcx.hir().local_def_id(id);
         let ty = self.cx.tcx.type_of(def_id);
         self.check_type_for_ffi_and_report_errors(span, ty);
     }
@@ -941,7 +941,7 @@ fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
     fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
         if let hir::ItemKind::Enum(ref enum_definition, _) = it.node {
-            let item_def_id = cx.tcx.hir().local_def_id_from_hir_id(it.hir_id);
+            let item_def_id = cx.tcx.hir().local_def_id(it.hir_id);
             let t = cx.tcx.type_of(item_def_id);
             let ty = cx.tcx.erase_regions(&t);
             let layout = match cx.layout_of(ty) {
index b5c5fc0608b950c5bf75065b5f5252c83706c014..2db2e0bc0da96b5b0100e41ce5526556bdfd455f 100644 (file)
@@ -48,7 +48,7 @@ fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt) {
         }
 
         let ty = cx.tables.expr_ty(&expr);
-        let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "");
+        let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", false);
 
         let mut fn_warned = false;
         let mut op_warned = false;
@@ -133,7 +133,9 @@ fn check_must_use_ty<'tcx>(
             ty: Ty<'tcx>,
             expr: &hir::Expr,
             span: Span,
-            descr_post_path: &str,
+            descr_pre: &str,
+            descr_post: &str,
+            plural: bool,
         ) -> bool {
             if ty.is_unit() || cx.tcx.is_ty_uninhabited_from(
                 cx.tcx.hir().get_module_parent(expr.hir_id), ty)
@@ -141,15 +143,29 @@ fn check_must_use_ty<'tcx>(
                 return true;
             }
 
+            let plural_suffix = if plural { "s" } else { "" };
+
             match ty.sty {
-                ty::Adt(def, _) => check_must_use_def(cx, def.did, span, "", descr_post_path),
+                ty::Adt(..) if ty.is_box() => {
+                    let boxed_ty = ty.boxed_ty();
+                    let descr_pre = &format!("{}boxed ", descr_pre);
+                    check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural)
+                }
+                ty::Adt(def, _) => {
+                    check_must_use_def(cx, def.did, span, descr_pre, descr_post)
+                }
                 ty::Opaque(def, _) => {
                     let mut has_emitted = false;
                     for (predicate, _) in &cx.tcx.predicates_of(def).predicates {
                         if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate {
                             let trait_ref = poly_trait_predicate.skip_binder().trait_ref;
                             let def_id = trait_ref.def_id;
-                            if check_must_use_def(cx, def_id, span, "implementer of ", "") {
+                            let descr_pre = &format!(
+                                "{}implementer{} of ",
+                                descr_pre,
+                                plural_suffix,
+                            );
+                            if check_must_use_def(cx, def_id, span, descr_pre, descr_post) {
                                 has_emitted = true;
                                 break;
                             }
@@ -162,7 +178,12 @@ fn check_must_use_ty<'tcx>(
                     for predicate in binder.skip_binder().iter() {
                         if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate {
                             let def_id = trait_ref.def_id;
-                            if check_must_use_def(cx, def_id, span, "", " trait object") {
+                            let descr_post = &format!(
+                                " trait object{}{}",
+                                plural_suffix,
+                                descr_post,
+                            );
+                            if check_must_use_def(cx, def_id, span, descr_pre, descr_post) {
                                 has_emitted = true;
                                 break;
                             }
@@ -179,14 +200,27 @@ fn check_must_use_ty<'tcx>(
                         vec![]
                     };
                     for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() {
-                        let descr_post_path = &format!(" in tuple element {}", i);
+                        let descr_post = &format!(" in tuple element {}", i);
                         let span = *spans.get(i).unwrap_or(&span);
-                        if check_must_use_ty(cx, ty, expr, span, descr_post_path) {
+                        if check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, plural) {
                             has_emitted = true;
                         }
                     }
                     has_emitted
                 }
+                ty::Array(ty, len) => match len.assert_usize(cx.tcx) {
+                    // If the array is definitely non-empty, we can do `#[must_use]` checking.
+                    Some(n) if n != 0 => {
+                        let descr_pre = &format!(
+                            "{}array{} of ",
+                            descr_pre,
+                            plural_suffix,
+                        );
+                        check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, true)
+                    }
+                    // Otherwise, we don't lint, to avoid false positives.
+                    _ => false,
+                }
                 _ => false,
             }
         }
index e9cf7bca25c4bb27c20b0e945508c684357d8ffa..53bbecd0e6a1d242ac127d544253f06b1d1c1ddc 100644 (file)
@@ -1,5 +1,6 @@
 #![feature(proc_macro_hygiene)]
 #![deny(rust_2018_idioms)]
+#![cfg_attr(not(bootstrap), allow(rustc::default_hash_types))]
 
 #![recursion_limit="128"]
 
index d47bd0580d6cab8c5c5db56428e661e401ecccf5..a8df7e197a8c9f069cc8526b9b27e4cc2291a4fc 100644 (file)
@@ -414,6 +414,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
     let mut dep_node_force_stream = quote! {};
     let mut try_load_from_on_disk_cache_stream = quote! {};
     let mut no_force_queries = Vec::new();
+    let mut cached_queries = quote! {};
 
     for group in groups.0 {
         let mut group_stream = quote! {};
@@ -427,6 +428,12 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
                 _ => quote! { #result_full },
             };
 
+            if modifiers.cache.is_some() {
+                cached_queries.extend(quote! {
+                    #name,
+                });
+            }
+
             if modifiers.cache.is_some() && !modifiers.no_force {
                 try_load_from_on_disk_cache_stream.extend(quote! {
                     DepKind::#name => {
@@ -549,6 +556,12 @@ macro_rules! rustc_dep_node_force {
                 }
             }
         }
+        macro_rules! rustc_cached_queries {
+            ($($macro:tt)*) => {
+                $($macro)*(#cached_queries);
+            }
+        }
+
         #query_description_stream
 
         impl DepNode {
index df0957254cc093fc2340954b3916ee98ff529e2c..2073b317939d78acea4e30e8b64071d1fc09c0df 100644 (file)
@@ -868,7 +868,7 @@ fn inject_sanitizer_runtime(&mut self) {
 
     fn inject_profiler_runtime(&mut self) {
         if self.sess.opts.debugging_opts.profile ||
-            self.sess.opts.debugging_opts.pgo_gen.enabled()
+           self.sess.opts.cg.profile_generate.enabled()
         {
             info!("loading profiler");
 
index 04a9c4e9a1a11c1083f8d50778965b80c65f6521..914084d7e9ece4f489ef6dc9ee62a71c8a201b4e 100644 (file)
@@ -250,7 +250,7 @@ fn into_args(self) -> (DefId, DefId) { (self.0.as_def_id(), self.1) }
     exported_symbols => { Arc::new(cdata.exported_symbols(tcx)) }
 }
 
-pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
+pub fn provide(providers: &mut Providers<'_>) {
     // FIXME(#44234) - almost all of these queries have no sub-queries and
     // therefore no actual inputs, they're just reading tables calculated in
     // resolve! Does this work? Unsure! That's what the issue is about
@@ -550,7 +550,7 @@ fn postorder_cnums_untracked(&self) -> Vec<CrateNum> {
         self.do_postorder_cnums_untracked()
     }
 
-    fn encode_metadata<'tcx>(&self, tcx: TyCtxt<'tcx>) -> EncodedMetadata {
+    fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata {
         encoder::encode_metadata(tcx)
     }
 
index b52b6dfbb5e1229f7f5a9fed2fe59530afbc7826..c7f57be642618c1ef9be5c2ec908bc4803a1c398 100644 (file)
@@ -667,7 +667,7 @@ fn encode_info_for_mod(
         (id, md, attrs, vis): (hir::HirId, &hir::Mod, &[ast::Attribute], &hir::Visibility),
     ) -> Entry<'tcx> {
         let tcx = self.tcx;
-        let def_id = tcx.hir().local_def_id_from_hir_id(id);
+        let def_id = tcx.hir().local_def_id(id);
         debug!("EncodeContext::encode_info_for_mod({:?})", def_id);
 
         let data = ModData {
@@ -683,7 +683,7 @@ fn encode_info_for_mod(
             span: self.lazy(&tcx.def_span(def_id)),
             attributes: self.encode_attributes(attrs),
             children: self.lazy_seq(md.item_ids.iter().map(|item_id| {
-                tcx.hir().local_def_id_from_hir_id(item_id.id).index
+                tcx.hir().local_def_id(item_id.id).index
             })),
             stability: self.encode_stability(def_id),
             deprecation: self.encode_deprecation(def_id),
@@ -1105,7 +1105,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                 // for methods, write all the stuff get_trait_method
                 // needs to know
                 let ctor = struct_def.ctor_hir_id()
-                    .map(|ctor_hir_id| tcx.hir().local_def_id_from_hir_id(ctor_hir_id).index);
+                    .map(|ctor_hir_id| tcx.hir().local_def_id(ctor_hir_id).index);
 
                 let repr_options = get_repr_options(tcx, def_id);
 
@@ -1194,7 +1194,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                 hir::ItemKind::ForeignMod(ref fm) => {
                     self.lazy_seq(fm.items
                         .iter()
-                        .map(|foreign_item| tcx.hir().local_def_id_from_hir_id(
+                        .map(|foreign_item| tcx.hir().local_def_id(
                             foreign_item.hir_id).index))
                 }
                 hir::ItemKind::Enum(..) => {
@@ -1313,7 +1313,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
     /// Serialize the text of exported macros
     fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef) -> Entry<'tcx> {
         use syntax::print::pprust;
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(macro_def.hir_id);
+        let def_id = self.tcx.hir().local_def_id(macro_def.hir_id);
         Entry {
             kind: EntryKind::MacroDef(self.lazy(&MacroDef {
                 body: pprust::tts_to_string(&macro_def.body.trees().collect::<Vec<_>>()),
@@ -1656,7 +1656,7 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
     }
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         intravisit::walk_item(self, item);
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let def_id = self.tcx.hir().local_def_id(item.hir_id);
         match item.node {
             hir::ItemKind::ExternCrate(_) |
             hir::ItemKind::Use(..) => {} // ignore these
@@ -1666,7 +1666,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
     }
     fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) {
         intravisit::walk_foreign_item(self, ni);
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(ni.hir_id);
+        let def_id = self.tcx.hir().local_def_id(ni.hir_id);
         self.record(def_id,
                           EncodeContext::encode_info_for_foreign_item,
                           (def_id, ni));
@@ -1678,7 +1678,7 @@ fn visit_variant(&mut self,
         intravisit::walk_variant(self, v, g, id);
 
         if let Some(ref discr) = v.node.disr_expr {
-            let def_id = self.tcx.hir().local_def_id_from_hir_id(discr.hir_id);
+            let def_id = self.tcx.hir().local_def_id(discr.hir_id);
             self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id);
         }
     }
@@ -1691,7 +1691,7 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
         self.encode_info_for_ty(ty);
     }
     fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef) {
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(macro_def.hir_id);
+        let def_id = self.tcx.hir().local_def_id(macro_def.hir_id);
         self.record(def_id, EncodeContext::encode_info_for_macro_def, macro_def);
     }
 }
@@ -1710,7 +1710,7 @@ fn encode_fields(&mut self, adt_def_id: DefId) {
 
     fn encode_info_for_generics(&mut self, generics: &hir::Generics) {
         for param in &generics.params {
-            let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id);
+            let def_id = self.tcx.hir().local_def_id(param.hir_id);
             match param.kind {
                 GenericParamKind::Lifetime { .. } => continue,
                 GenericParamKind::Type { ref default, .. } => {
@@ -1730,7 +1730,7 @@ fn encode_info_for_generics(&mut self, generics: &hir::Generics) {
     fn encode_info_for_ty(&mut self, ty: &hir::Ty) {
         match ty.node {
             hir::TyKind::Array(_, ref length) => {
-                let def_id = self.tcx.hir().local_def_id_from_hir_id(length.hir_id);
+                let def_id = self.tcx.hir().local_def_id(length.hir_id);
                 self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id);
             }
             _ => {}
@@ -1740,7 +1740,7 @@ fn encode_info_for_ty(&mut self, ty: &hir::Ty) {
     fn encode_info_for_expr(&mut self, expr: &hir::Expr) {
         match expr.node {
             hir::ExprKind::Closure(..) => {
-                let def_id = self.tcx.hir().local_def_id_from_hir_id(expr.hir_id);
+                let def_id = self.tcx.hir().local_def_id(expr.hir_id);
                 self.record(def_id, EncodeContext::encode_info_for_closure, def_id);
             }
             _ => {}
@@ -1752,7 +1752,7 @@ fn encode_info_for_expr(&mut self, expr: &hir::Expr) {
     /// so it's easier to do that here then to wait until we would encounter
     /// normally in the visitor walk.
     fn encode_addl_info_for_item(&mut self, item: &hir::Item) {
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let def_id = self.tcx.hir().local_def_id(item.hir_id);
         match item.node {
             hir::ItemKind::Static(..) |
             hir::ItemKind::Const(..) |
@@ -1788,7 +1788,7 @@ fn encode_addl_info_for_item(&mut self, item: &hir::Item) {
 
                 // If the struct has a constructor, encode it.
                 if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
-                    let ctor_def_id = self.tcx.hir().local_def_id_from_hir_id(ctor_hir_id);
+                    let ctor_def_id = self.tcx.hir().local_def_id(ctor_hir_id);
                     self.record(ctor_def_id,
                                 EncodeContext::encode_struct_ctor,
                                 (def_id, ctor_def_id));
@@ -1823,7 +1823,7 @@ struct ImplVisitor<'tcx> {
 impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
         if let hir::ItemKind::Impl(..) = item.node {
-            let impl_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+            let impl_id = self.tcx.hir().local_def_id(item.hir_id);
             if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) {
                 self.impls
                     .entry(trait_ref.def_id)
@@ -1863,7 +1863,7 @@ fn visit_impl_item(&mut self, _impl_item: &'v hir::ImplItem) {
 // will allow us to slice the metadata to the precise length that we just
 // generated regardless of trailing bytes that end up in it.
 
-pub fn encode_metadata<'tcx>(tcx: TyCtxt<'tcx>) -> EncodedMetadata {
+pub fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
     let mut encoder = opaque::Encoder::new(vec![]);
     encoder.emit_raw_bytes(METADATA_HEADER);
 
@@ -1905,7 +1905,7 @@ pub fn encode_metadata<'tcx>(tcx: TyCtxt<'tcx>) -> EncodedMetadata {
     EncodedMetadata { raw_data: result }
 }
 
-pub fn get_repr_options<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> ReprOptions {
+pub fn get_repr_options(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions {
     let ty = tcx.type_of(did);
     match ty.sty {
         ty::Adt(ref def, _) => return def.repr,
index 0ce103cfa40dc63b506c4ec4deb70265f0a8d26d..b2e40282d93323a04654b04ec5ed1bb249ca382b 100644 (file)
@@ -3,7 +3,7 @@
 use rustc::middle::cstore::ForeignModule;
 use rustc::ty::TyCtxt;
 
-pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> Vec<ForeignModule> {
+pub fn collect(tcx: TyCtxt<'_>) -> Vec<ForeignModule> {
     let mut collector = Collector {
         tcx,
         modules: Vec::new(),
@@ -25,11 +25,11 @@ fn visit_item(&mut self, it: &'tcx hir::Item) {
         };
 
         let foreign_items = fm.items.iter()
-            .map(|it| self.tcx.hir().local_def_id_from_hir_id(it.hir_id))
+            .map(|it| self.tcx.hir().local_def_id(it.hir_id))
             .collect();
         self.modules.push(ForeignModule {
             foreign_items,
-            def_id: self.tcx.hir().local_def_id_from_hir_id(it.hir_id),
+            def_id: self.tcx.hir().local_def_id(it.hir_id),
         });
     }
 
index e49ca8acf6702e579ba10a0e60744eb2798b59b9..826349362db2500556cbfee242377c088aaecf3d 100644 (file)
@@ -15,7 +15,6 @@
 #![recursion_limit="256"]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 extern crate libc;
index cd6270046faabe18094a583e097ff76cdb1d03b2..728fd004fcb693a2ce8b71b88b6746a9bcb65212 100644 (file)
@@ -4,7 +4,7 @@
 use rustc_target::spec::abi::Abi;
 use syntax::symbol::sym;
 
-pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> Vec<String> {
+pub fn collect(tcx: TyCtxt<'_>) -> Vec<String> {
     let mut collector = Collector {
         args: Vec::new(),
     };
index 7b335b3b4832d65566b0218b887f31870b356e1a..5da5384f8aaa792a8ada31b192c73e815aeebe48 100644 (file)
@@ -11,7 +11,7 @@
 use syntax::symbol::{Symbol, sym};
 use syntax::{span_err, struct_span_err};
 
-pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> Vec<NativeLibrary> {
+pub fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLibrary> {
     let mut collector = Collector {
         tcx,
         libs: Vec::new(),
@@ -56,7 +56,7 @@ fn visit_item(&mut self, it: &'tcx hir::Item) {
                 name: None,
                 kind: cstore::NativeUnknown,
                 cfg: None,
-                foreign_module: Some(self.tcx.hir().local_def_id_from_hir_id(it.hir_id)),
+                foreign_module: Some(self.tcx.hir().local_def_id(it.hir_id)),
                 wasm_import_module: None,
             };
             let mut kind_specified = false;
index 4872440f5bd4ae371b7a7eb37ee87e0498557179..25ac93cc2422c1559b4dcc551cf2beda2e321e42 100644 (file)
@@ -87,7 +87,7 @@ pub fn provide(providers: &mut Providers<'_>) {
     };
 }
 
-fn mir_borrowck<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BorrowCheckResult<'tcx> {
+fn mir_borrowck(tcx: TyCtxt<'_>, def_id: DefId) -> BorrowCheckResult<'_> {
     let input_body = tcx.mir_validated(def_id);
     debug!("run query mir_borrowck: {}", tcx.def_path_str(def_id));
 
@@ -275,7 +275,7 @@ fn do_mir_borrowck<'a, 'tcx>(
     mbcx.analyze_results(&mut state); // entry point for DataflowResultsConsumer
 
     // Convert any reservation warnings into lints.
-    let reservation_warnings = mem::replace(&mut mbcx.reservation_warnings, Default::default());
+    let reservation_warnings = mem::take(&mut mbcx.reservation_warnings);
     for (_, (place, span, location, bk, borrow)) in reservation_warnings {
         let mut initial_diag =
             mbcx.report_conflicting_borrow(location, (&place, span), bk, &borrow);
index c4b2a5daef89ab50c8ed4a1e7fd78fedeeac8e78..b5630251e5830942b194ebc3edcc61c8b3d71a8a 100644 (file)
@@ -1,6 +1,6 @@
 use crate::borrow_check::nll::type_check::Locations;
-use crate::borrow_check::nll::constraints::ConstraintIndex;
-use crate::borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
+use crate::borrow_check::nll::constraints::OutlivesConstraintIndex;
+use crate::borrow_check::nll::constraints::{OutlivesConstraintSet, OutlivesConstraint};
 use rustc::mir::ConstraintCategory;
 use rustc::ty::RegionVid;
 use rustc_data_structures::graph;
@@ -12,8 +12,8 @@
 /// -> R2` or `R2 -> R1` depending on the direction type `D`.
 crate struct ConstraintGraph<D: ConstraintGraphDirecton> {
     _direction: D,
-    first_constraints: IndexVec<RegionVid, Option<ConstraintIndex>>,
-    next_constraints: IndexVec<ConstraintIndex, Option<ConstraintIndex>>,
+    first_constraints: IndexVec<RegionVid, Option<OutlivesConstraintIndex>>,
+    next_constraints: IndexVec<OutlivesConstraintIndex, Option<OutlivesConstraintIndex>>,
 }
 
 crate type NormalConstraintGraph = ConstraintGraph<Normal>;
@@ -77,13 +77,13 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
     /// reporting.
     crate fn new(
         direction: D,
-        set: &ConstraintSet,
+        set: &OutlivesConstraintSet,
         num_region_vars: usize,
     ) -> Self {
         let mut first_constraints = IndexVec::from_elem_n(None, num_region_vars);
-        let mut next_constraints = IndexVec::from_elem(None, &set.constraints);
+        let mut next_constraints = IndexVec::from_elem(None, &set.outlives);
 
-        for (idx, constraint) in set.constraints.iter_enumerated().rev() {
+        for (idx, constraint) in set.outlives.iter_enumerated().rev() {
             let head = &mut first_constraints[D::start_region(constraint)];
             let next = &mut next_constraints[idx];
             debug_assert!(next.is_none());
@@ -103,7 +103,7 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
     /// and not constraints.
     crate fn region_graph<'rg>(
         &'rg self,
-        set: &'rg ConstraintSet,
+        set: &'rg OutlivesConstraintSet,
         static_region: RegionVid,
     ) -> RegionGraph<'rg, D> {
         RegionGraph::new(set, self, static_region)
@@ -113,7 +113,7 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
     crate fn outgoing_edges<'a>(
         &'a self,
         region_sup: RegionVid,
-        constraints: &'a ConstraintSet,
+        constraints: &'a OutlivesConstraintSet,
         static_region: RegionVid,
     ) -> Edges<'a, D> {
         //if this is the `'static` region and the graph's direction is normal,
@@ -142,8 +142,8 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
 
 crate struct Edges<'s, D: ConstraintGraphDirecton> {
     graph: &'s ConstraintGraph<D>,
-    constraints: &'s ConstraintSet,
-    pointer: Option<ConstraintIndex>,
+    constraints: &'s OutlivesConstraintSet,
+    pointer: Option<OutlivesConstraintIndex>,
     next_static_idx: Option<usize>,
     static_region: RegionVid,
 }
@@ -180,7 +180,7 @@ fn next(&mut self) -> Option<Self::Item> {
 /// reverse) constraint graph. It implements the graph traits and is
 /// usd for doing the SCC computation.
 crate struct RegionGraph<'s, D: ConstraintGraphDirecton> {
-    set: &'s ConstraintSet,
+    set: &'s OutlivesConstraintSet,
     constraint_graph: &'s ConstraintGraph<D>,
     static_region: RegionVid,
 }
@@ -191,7 +191,7 @@ impl<'s, D: ConstraintGraphDirecton> RegionGraph<'s, D> {
     /// construct SCCs for region inference but also for error
     /// reporting.
     crate fn new(
-        set: &'s ConstraintSet,
+        set: &'s OutlivesConstraintSet,
         constraint_graph: &'s ConstraintGraph<D>,
         static_region: RegionVid,
     ) -> Self {
@@ -234,10 +234,10 @@ fn num_nodes(&self) -> usize {
 }
 
 impl<'s, D: ConstraintGraphDirecton> graph::WithSuccessors for RegionGraph<'s, D> {
-    fn successors<'graph>(
-        &'graph self,
+    fn successors(
+        &self,
         node: Self::Node,
-    ) -> <Self as graph::GraphSuccessors<'graph>>::Iter {
+    ) -> <Self as graph::GraphSuccessors<'_>>::Iter {
         self.outgoing_regions(node)
     }
 }
index b1091eb5ac81f8578225f187cdc73ce9b6ac0f02..6121ed0cf0d1c3282b87dc813de3f85b294e8407 100644 (file)
@@ -1,37 +1,40 @@
+use crate::borrow_check::nll::type_check::Locations;
 use rustc::mir::ConstraintCategory;
 use rustc::ty::RegionVid;
 use rustc_data_structures::graph::scc::Sccs;
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
-use crate::borrow_check::nll::type_check::Locations;
-
 use std::fmt;
-use std::ops::Deref;
+use std::ops::Index;
 
 crate mod graph;
 
+/// A set of NLL region constraints. These include "outlives"
+/// constraints of the form `R1: R2`. Each constraint is identified by
+/// a unique `OutlivesConstraintIndex` and you can index into the set
+/// (`constraint_set[i]`) to access the constraint details.
 #[derive(Clone, Default)]
-crate struct ConstraintSet {
-    constraints: IndexVec<ConstraintIndex, OutlivesConstraint>,
+crate struct OutlivesConstraintSet {
+    outlives: IndexVec<OutlivesConstraintIndex, OutlivesConstraint>,
 }
 
-impl ConstraintSet {
+impl OutlivesConstraintSet {
     crate fn push(&mut self, constraint: OutlivesConstraint) {
         debug!(
-            "ConstraintSet::push({:?}: {:?} @ {:?}",
+            "OutlivesConstraintSet::push({:?}: {:?} @ {:?}",
             constraint.sup, constraint.sub, constraint.locations
         );
         if constraint.sup == constraint.sub {
             // 'a: 'a is pretty uninteresting
             return;
         }
-        self.constraints.push(constraint);
+        self.outlives.push(constraint);
     }
 
     /// Constructs a "normal" graph from the constraint set; the graph makes it
     /// easy to find the constraints affecting a particular region.
     ///
     /// N.B., this graph contains a "frozen" view of the current
-    /// constraints. Any new constraints added to the `ConstraintSet`
+    /// constraints. Any new constraints added to the `OutlivesConstraintSet`
     /// after the graph is built will not be present in the graph.
     crate fn graph(&self, num_region_vars: usize) -> graph::NormalConstraintGraph {
         graph::ConstraintGraph::new(graph::Normal, self, num_region_vars)
@@ -54,13 +57,17 @@ impl ConstraintSet {
         let region_graph = &constraint_graph.region_graph(self, static_region);
         Sccs::new(region_graph)
     }
+
+    crate fn outlives(&self) -> &IndexVec<OutlivesConstraintIndex, OutlivesConstraint> {
+        &self.outlives
+    }
 }
 
-impl Deref for ConstraintSet {
-    type Target = IndexVec<ConstraintIndex, OutlivesConstraint>;
+impl Index<OutlivesConstraintIndex> for OutlivesConstraintSet {
+    type Output = OutlivesConstraint;
 
-    fn deref(&self) -> &Self::Target {
-        &self.constraints
+    fn index(&self, i: OutlivesConstraintIndex) -> &Self::Output {
+        &self.outlives[i]
     }
 }
 
@@ -94,8 +101,8 @@ fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
 }
 
 newtype_index! {
-    pub struct ConstraintIndex {
-        DEBUG_FORMAT = "ConstraintIndex({})"
+    pub struct OutlivesConstraintIndex {
+        DEBUG_FORMAT = "OutlivesConstraintIndex({})"
     }
 }
 
diff --git a/src/librustc_mir/borrow_check/nll/member_constraints.rs b/src/librustc_mir/borrow_check/nll/member_constraints.rs
new file mode 100644 (file)
index 0000000..b5e2e11
--- /dev/null
@@ -0,0 +1,235 @@
+use crate::rustc::ty::{self, Ty};
+use rustc::hir::def_id::DefId;
+use rustc::infer::region_constraints::MemberConstraint;
+use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::indexed_vec::{Idx, IndexVec};
+use std::hash::Hash;
+use std::ops::Index;
+use syntax_pos::Span;
+
+/// Compactly stores a set of `R0 member of [R1...Rn]` constraints,
+/// indexed by the region `R0`.
+crate struct MemberConstraintSet<'tcx, R>
+where
+    R: Copy + Hash + Eq,
+{
+    /// Stores the first "member" constraint for a given `R0`. This is an
+    /// index into the `constraints` vector below.
+    first_constraints: FxHashMap<R, NllMemberConstraintIndex>,
+
+    /// Stores the data about each `R0 member of [R1..Rn]` constraint.
+    /// These are organized into a linked list, so each constraint
+    /// contains the index of the next constraint with the same `R0`.
+    constraints: IndexVec<NllMemberConstraintIndex, NllMemberConstraint<'tcx>>,
+
+    /// Stores the `R1..Rn` regions for *all* sets. For any given
+    /// constraint, we keep two indices so that we can pull out a
+    /// slice.
+    choice_regions: Vec<ty::RegionVid>,
+}
+
+/// Represents a `R0 member of [R1..Rn]` constraint
+crate struct NllMemberConstraint<'tcx> {
+    next_constraint: Option<NllMemberConstraintIndex>,
+
+    /// The opaque type whose hidden type is being inferred. (Used in error reporting.)
+    crate opaque_type_def_id: DefId,
+
+    /// The span where the hidden type was instantiated.
+    crate definition_span: Span,
+
+    /// The hidden type in which `R0` appears. (Used in error reporting.)
+    crate hidden_ty: Ty<'tcx>,
+
+    /// The region `R0`.
+    crate member_region_vid: ty::RegionVid,
+
+    /// Index of `R1` in `choice_regions` vector from `MemberConstraintSet`.
+    start_index: usize,
+
+    /// Index of `Rn` in `choice_regions` vector from `MemberConstraintSet`.
+    end_index: usize,
+}
+
+newtype_index! {
+    crate struct NllMemberConstraintIndex {
+        DEBUG_FORMAT = "MemberConstraintIndex({})"
+    }
+}
+
+impl Default for MemberConstraintSet<'tcx, ty::RegionVid> {
+    fn default() -> Self {
+        Self {
+            first_constraints: Default::default(),
+            constraints: Default::default(),
+            choice_regions: Default::default(),
+        }
+    }
+}
+
+impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> {
+    /// Pushes a member constraint into the set.
+    ///
+    /// The input member constraint `m_c` is in the form produced by
+    /// the the `rustc::infer` code.
+    ///
+    /// The `to_region_vid` callback fn is used to convert the regions
+    /// within into `RegionVid` format -- it typically consults the
+    /// `UniversalRegions` data structure that is known to the caller
+    /// (but which this code is unaware of).
+    crate fn push_constraint(
+        &mut self,
+        m_c: &MemberConstraint<'tcx>,
+        mut to_region_vid: impl FnMut(ty::Region<'tcx>) -> ty::RegionVid,
+    ) {
+        debug!("push_constraint(m_c={:?})", m_c);
+        let member_region_vid: ty::RegionVid = to_region_vid(m_c.member_region);
+        let next_constraint = self.first_constraints.get(&member_region_vid).cloned();
+        let start_index = self.choice_regions.len();
+        let end_index = start_index + m_c.choice_regions.len();
+        debug!("push_constraint: member_region_vid={:?}", member_region_vid);
+        let constraint_index = self.constraints.push(NllMemberConstraint {
+            next_constraint,
+            member_region_vid,
+            opaque_type_def_id: m_c.opaque_type_def_id,
+            definition_span: m_c.definition_span,
+            hidden_ty: m_c.hidden_ty,
+            start_index,
+            end_index,
+        });
+        self.first_constraints.insert(member_region_vid, constraint_index);
+        self.choice_regions.extend(m_c.choice_regions.iter().map(|&r| to_region_vid(r)));
+    }
+}
+
+impl<R1> MemberConstraintSet<'tcx, R1>
+where
+    R1: Copy + Hash + Eq,
+{
+    /// Remap the "member region" key using `map_fn`, producing a new
+    /// member constraint set.  This is used in the NLL code to map from
+    /// the original `RegionVid` to an scc index. In some cases, we
+    /// may have multiple `R1` values mapping to the same `R2` key -- that
+    /// is ok, the two sets will be merged.
+    crate fn into_mapped<R2>(
+        self,
+        mut map_fn: impl FnMut(R1) -> R2,
+    ) -> MemberConstraintSet<'tcx, R2>
+    where
+        R2: Copy + Hash + Eq,
+    {
+        // We can re-use most of the original data, just tweaking the
+        // linked list links a bit.
+        //
+        // For example if we had two keys `Ra` and `Rb` that both now
+        // wind up mapped to the same key `S`, we would append the
+        // linked list for `Ra` onto the end of the linked list for
+        // `Rb` (or vice versa) -- this basically just requires
+        // rewriting the final link from one list to point at the othe
+        // other (see `append_list`).
+
+        let MemberConstraintSet { first_constraints, mut constraints, choice_regions } = self;
+
+        let mut first_constraints2 = FxHashMap::default();
+        first_constraints2.reserve(first_constraints.len());
+
+        for (r1, start1) in first_constraints {
+            let r2 = map_fn(r1);
+            if let Some(&start2) = first_constraints2.get(&r2) {
+                append_list(&mut constraints, start1, start2);
+            }
+            first_constraints2.insert(r2, start1);
+        }
+
+        MemberConstraintSet {
+            first_constraints: first_constraints2,
+            constraints,
+            choice_regions,
+        }
+    }
+}
+
+impl<R> MemberConstraintSet<'tcx, R>
+where
+    R: Copy + Hash + Eq,
+{
+    crate fn all_indices(
+        &self,
+    ) -> impl Iterator<Item = NllMemberConstraintIndex> {
+        self.constraints.indices()
+    }
+
+    /// Iterate down the constraint indices associated with a given
+    /// peek-region.  You can then use `choice_regions` and other
+    /// methods to access data.
+    crate fn indices(
+        &self,
+        member_region_vid: R,
+    ) -> impl Iterator<Item = NllMemberConstraintIndex> + '_ {
+        let mut next = self.first_constraints.get(&member_region_vid).cloned();
+        std::iter::from_fn(move || -> Option<NllMemberConstraintIndex> {
+            if let Some(current) = next {
+                next = self.constraints[current].next_constraint;
+                Some(current)
+            } else {
+                None
+            }
+        })
+    }
+
+    /// Returns the "choice regions" for a given member
+    /// constraint. This is the `R1..Rn` from a constraint like:
+    ///
+    /// ```
+    /// R0 member of [R1..Rn]
+    /// ```
+    crate fn choice_regions(&self, pci: NllMemberConstraintIndex) -> &[ty::RegionVid] {
+        let NllMemberConstraint { start_index, end_index, .. } = &self.constraints[pci];
+        &self.choice_regions[*start_index..*end_index]
+    }
+}
+
+impl<'tcx, R> Index<NllMemberConstraintIndex> for MemberConstraintSet<'tcx, R>
+where
+    R: Copy + Hash + Eq,
+{
+    type Output = NllMemberConstraint<'tcx>;
+
+    fn index(&self, i: NllMemberConstraintIndex) -> &NllMemberConstraint<'tcx> {
+        &self.constraints[i]
+    }
+}
+
+/// Given a linked list starting at `source_list` and another linked
+/// list starting at `target_list`, modify `target_list` so that it is
+/// followed by `source_list`.
+///
+/// Before:
+///
+/// ```
+/// target_list: A -> B -> C -> (None)
+/// source_list: D -> E -> F -> (None)
+/// ```
+///
+/// After:
+///
+/// ```
+/// target_list: A -> B -> C -> D -> E -> F -> (None)
+/// ```
+fn append_list(
+    constraints: &mut IndexVec<NllMemberConstraintIndex, NllMemberConstraint<'_>>,
+    target_list: NllMemberConstraintIndex,
+    source_list: NllMemberConstraintIndex,
+) {
+    let mut p = target_list;
+    loop {
+        let mut r = &mut constraints[p];
+        match r.next_constraint {
+            Some(q) => p = q,
+            None => {
+                r.next_constraint = Some(source_list);
+                return;
+            }
+        }
+    }
+}
index 5dd7b7452733cf654692c199548448baff2935bc..eb63e0de195e5d6692d56ad9e94d9edb4514ab3e 100644 (file)
@@ -37,6 +37,7 @@
 mod universal_regions;
 
 mod constraints;
+mod member_constraints;
 
 use self::facts::AllFacts;
 use self::region_infer::RegionInferenceContext;
@@ -129,6 +130,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
         placeholder_index_to_region: _,
         mut liveness_constraints,
         outlives_constraints,
+        member_constraints,
         closure_bounds_mapping,
         type_tests,
     } = constraints;
@@ -150,6 +152,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
         universal_region_relations,
         body,
         outlives_constraints,
+        member_constraints,
         closure_bounds_mapping,
         type_tests,
         liveness_constraints,
index 4931005a4547a0c836d4e86c85a93b45b782e4ce..d4f6ce8801e63689639e3949c20cadca1a1d619b 100644 (file)
@@ -71,7 +71,7 @@ fn for_each_constraint(
             }
         }
 
-        let mut constraints: Vec<_> = self.constraints.iter().collect();
+        let mut constraints: Vec<_> = self.constraints.outlives().iter().collect();
         constraints.sort();
         for constraint in &constraints {
             let OutlivesConstraint {
index 04ff54e9a5e452871e5e8e79d969635645a7b847..9e08961f440f2ab42ae1c05eac54047e31c53228 100644 (file)
@@ -1,4 +1,5 @@
 use crate::borrow_check::nll::constraints::OutlivesConstraint;
+use crate::borrow_check::nll::region_infer::AppliedMemberConstraint;
 use crate::borrow_check::nll::region_infer::RegionInferenceContext;
 use crate::borrow_check::nll::type_check::Locations;
 use crate::borrow_check::nll::universal_regions::DefiningTy;
@@ -195,6 +196,7 @@ fn find_constraint_paths_between_regions(
                         Trace::NotVisited => {
                             bug!("found unvisited region {:?} on path to {:?}", p, r)
                         }
+
                         Trace::FromOutlivesConstraint(c) => {
                             result.push(c);
                             p = c.sup;
@@ -211,10 +213,30 @@ fn find_constraint_paths_between_regions(
             // Otherwise, walk over the outgoing constraints and
             // enqueue any regions we find, keeping track of how we
             // reached them.
+
+            // A constraint like `'r: 'x` can come from our constraint
+            // graph.
             let fr_static = self.universal_regions.fr_static;
-            for constraint in self.constraint_graph
-                .outgoing_edges(r, &self.constraints, fr_static)
-            {
+            let outgoing_edges_from_graph = self.constraint_graph
+                .outgoing_edges(r, &self.constraints, fr_static);
+
+
+            // But member constraints can also give rise to `'r: 'x`
+            // edges that were not part of the graph initially, so
+            // watch out for those.
+            let outgoing_edges_from_picks = self.applied_member_constraints(r)
+                .iter()
+                .map(|&AppliedMemberConstraint { min_choice, member_constraint_index, .. }| {
+                    let p_c = &self.member_constraints[member_constraint_index];
+                    OutlivesConstraint {
+                        sup: r,
+                        sub: min_choice,
+                        locations: Locations::All(p_c.definition_span),
+                        category: ConstraintCategory::OpaqueType,
+                    }
+                });
+
+            for constraint in outgoing_edges_from_graph.chain(outgoing_edges_from_picks) {
                 debug_assert_eq!(constraint.sup, r);
                 let sub_region = constraint.sub;
                 if let Trace::NotVisited = context[sub_region] {
@@ -687,7 +709,11 @@ fn add_static_impl_trait_suggestion(
 
     // Finds some region R such that `fr1: R` and `R` is live at
     // `elem`.
-    crate fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid {
+    crate fn find_sub_region_live_at(
+        &self,
+        fr1: RegionVid,
+        elem: Location,
+    ) -> RegionVid {
         debug!("find_sub_region_live_at(fr1={:?}, elem={:?})", fr1, elem);
         self.find_constraint_paths_between_regions(fr1, |r| {
             // First look for some `r` such that `fr1: r` and `r` is live at `elem`
@@ -729,8 +755,11 @@ fn add_static_impl_trait_suggestion(
         fr1: RegionVid,
         fr2: RegionVid,
     ) -> (ConstraintCategory, Span) {
-        let (category, _, span) =
-            self.best_blame_constraint(body, fr1, |r| self.provides_universal_region(r, fr1, fr2));
+        let (category, _, span) = self.best_blame_constraint(
+            body,
+            fr1,
+            |r| self.provides_universal_region(r, fr1, fr2),
+        );
         (category, span)
     }
 
index 0cf8a0d16f622ba317dc68fea2c76e8b1b24cf46..fdf2af9f44ebcae25a6825d8753f5611a01f0ac1 100644 (file)
@@ -63,7 +63,7 @@ fn nodes(&'this self) -> dot::Nodes<'this, RegionVid> {
         vids.into()
     }
     fn edges(&'this self) -> dot::Edges<'this, OutlivesConstraint> {
-        (&self.regioncx.constraints.raw[..]).into()
+        (&self.regioncx.constraints.outlives().raw[..]).into()
     }
 
     // Render `a: b` as `a -> b`, indicating the flow
index 41ed564d0f0e1a91ca73b798ae4464b8ca2b5293..40388722bcac933aeb2006b0b5dbc9c333e0bc50 100644 (file)
@@ -1,25 +1,32 @@
 use super::universal_regions::UniversalRegions;
 use crate::borrow_check::nll::constraints::graph::NormalConstraintGraph;
-use crate::borrow_check::nll::constraints::{ConstraintSccIndex, ConstraintSet, OutlivesConstraint};
+use crate::borrow_check::nll::constraints::{
+    ConstraintSccIndex, OutlivesConstraint, OutlivesConstraintSet,
+};
+use crate::borrow_check::nll::member_constraints::{MemberConstraintSet, NllMemberConstraintIndex};
 use crate::borrow_check::nll::region_infer::values::{
-    PlaceholderIndices, RegionElement, ToElementIndex
+    PlaceholderIndices, RegionElement, ToElementIndex,
 };
-use crate::borrow_check::Upvar;
 use crate::borrow_check::nll::type_check::free_region_relations::UniversalRegionRelations;
 use crate::borrow_check::nll::type_check::Locations;
+use crate::borrow_check::Upvar;
 use rustc::hir::def_id::DefId;
-use rustc::infer::canonical::QueryRegionConstraint;
+use rustc::infer::canonical::QueryOutlivesConstraint;
+use rustc::infer::opaque_types;
 use rustc::infer::region_constraints::{GenericKind, VarInfos, VerifyBound};
 use rustc::infer::{InferCtxt, NLLRegionVariableOrigin, RegionVariableOrigin};
 use rustc::mir::{
-    ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements,
-    ConstraintCategory, Local, Location, Body,
+    Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements,
+    ConstraintCategory, Local, Location,
 };
 use rustc::ty::{self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable};
-use rustc::util::common::{self, ErrorReported};
+use rustc::util::common::ErrorReported;
+use rustc_data_structures::binary_search_util;
 use rustc_data_structures::bit_set::BitSet;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::graph::WithSuccessors;
 use rustc_data_structures::graph::scc::Sccs;
+use rustc_data_structures::graph::vec_graph::VecGraph;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_errors::{Diagnostic, DiagnosticBuilder};
 use syntax_pos::Span;
@@ -49,17 +56,31 @@ pub struct RegionInferenceContext<'tcx> {
     liveness_constraints: LivenessValues<RegionVid>,
 
     /// The outlives constraints computed by the type-check.
-    constraints: Rc<ConstraintSet>,
+    constraints: Rc<OutlivesConstraintSet>,
 
     /// The constraint-set, but in graph form, making it easy to traverse
     /// the constraints adjacent to a particular region. Used to construct
     /// the SCC (see `constraint_sccs`) and for error reporting.
     constraint_graph: Rc<NormalConstraintGraph>,
 
-    /// The SCC computed from `constraints` and the constraint graph. Used to
+    /// The SCC computed from `constraints` and the constraint
+    /// graph. We have an edge from SCC A to SCC B if `A: B`. Used to
     /// compute the values of each region.
     constraint_sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>,
 
+    /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B`
+    /// exists if `B: A`. Computed lazilly.
+    rev_constraint_graph: Option<Rc<VecGraph<ConstraintSccIndex>>>,
+
+    /// The "R0 member of [R1..Rn]" constraints, indexed by SCC.
+    member_constraints: Rc<MemberConstraintSet<'tcx, ConstraintSccIndex>>,
+
+    /// Records the member constraints that we applied to each scc.
+    /// This is useful for error reporting. Once constraint
+    /// propagation is done, this vector is sorted according to
+    /// `member_region_scc`.
+    member_constraints_applied: Vec<AppliedMemberConstraint>,
+
     /// Map closure bounds to a `Span` that should be used for error reporting.
     closure_bounds_mapping:
         FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
@@ -95,6 +116,32 @@ pub struct RegionInferenceContext<'tcx> {
     universal_region_relations: Rc<UniversalRegionRelations<'tcx>>,
 }
 
+/// Each time that `apply_member_constraint` is successful, it appends
+/// one of these structs to the `member_constraints_applied` field.
+/// This is used in error reporting to trace out what happened.
+///
+/// The way that `apply_member_constraint` works is that it effectively
+/// adds a new lower bound to the SCC it is analyzing: so you wind up
+/// with `'R: 'O` where `'R` is the pick-region and `'O` is the
+/// minimal viable option.
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
+struct AppliedMemberConstraint {
+    /// The SCC that was affected. (The "member region".)
+    ///
+    /// The vector if `AppliedMemberConstraint` elements is kept sorted
+    /// by this field.
+    member_region_scc: ConstraintSccIndex,
+
+    /// The "best option" that `apply_member_constraint` found -- this was
+    /// added as an "ad-hoc" lower-bound to `member_region_scc`.
+    min_choice: ty::RegionVid,
+
+    /// The "member constraint index" -- we can find out details about
+    /// the constraint from
+    /// `set.member_constraints[member_constraint_index]`.
+    member_constraint_index: NllMemberConstraintIndex,
+}
+
 struct RegionDefinition<'tcx> {
     /// What kind of variable is this -- a free region? existential
     /// variable? etc. (See the `NLLRegionVariableOrigin` for more
@@ -186,7 +233,8 @@ pub(crate) fn new(
         placeholder_indices: Rc<PlaceholderIndices>,
         universal_region_relations: Rc<UniversalRegionRelations<'tcx>>,
         _body: &Body<'tcx>,
-        outlives_constraints: ConstraintSet,
+        outlives_constraints: OutlivesConstraintSet,
+        member_constraints_in: MemberConstraintSet<'tcx, RegionVid>,
         closure_bounds_mapping: FxHashMap<
             Location,
             FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>,
@@ -218,12 +266,18 @@ pub(crate) fn new(
 
         let scc_representatives = Self::compute_scc_representatives(&constraint_sccs, &definitions);
 
+        let member_constraints =
+            Rc::new(member_constraints_in.into_mapped(|r| constraint_sccs.scc(r)));
+
         let mut result = Self {
             definitions,
             liveness_constraints,
             constraints,
             constraint_graph,
             constraint_sccs,
+            rev_constraint_graph: None,
+            member_constraints,
+            member_constraints_applied: Vec::new(),
             closure_bounds_mapping,
             scc_universes,
             scc_representatives,
@@ -341,9 +395,7 @@ fn init_free_and_bound_regions(&mut self) {
                         debug!(
                             "init_free_and_bound_regions: placeholder {:?} is \
                              not compatible with universe {:?} of its SCC {:?}",
-                            placeholder,
-                            scc_universe,
-                            scc,
+                            placeholder, scc_universe, scc,
                         );
                         self.add_incompatible_universe(scc);
                     }
@@ -394,6 +446,18 @@ pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
         self.scc_universes[scc]
     }
 
+    /// Once region solving has completed, this function will return
+    /// the member constraints that were applied to the value of a given
+    /// region `r`. See `AppliedMemberConstraint`.
+    fn applied_member_constraints(&self, r: impl ToRegionVid) -> &[AppliedMemberConstraint] {
+        let scc = self.constraint_sccs.scc(r.to_region_vid());
+        binary_search_util::binary_search_slice(
+            &self.member_constraints_applied,
+            |applied| applied.member_region_scc,
+            &scc,
+        )
+    }
+
     /// Performs region inference and report errors if we see any
     /// unsatisfiable constraints. If this is a closure, returns the
     /// region requirements to propagate to our creator, if any.
@@ -404,22 +468,6 @@ pub(super) fn solve(
         upvars: &[Upvar],
         mir_def_id: DefId,
         errors_buffer: &mut Vec<Diagnostic>,
-    ) -> Option<ClosureRegionRequirements<'tcx>> {
-        common::time_ext(
-            infcx.tcx.sess.time_extended(),
-            Some(infcx.tcx.sess),
-            &format!("solve_nll_region_constraints({:?})", mir_def_id),
-            || self.solve_inner(infcx, body, upvars, mir_def_id, errors_buffer),
-        )
-    }
-
-    fn solve_inner(
-        &mut self,
-        infcx: &InferCtxt<'_, 'tcx>,
-        body: &Body<'tcx>,
-        upvars: &[Upvar],
-        mir_def_id: DefId,
-        errors_buffer: &mut Vec<Diagnostic>,
     ) -> Option<ClosureRegionRequirements<'tcx>> {
         self.propagate_constraints(body);
 
@@ -428,11 +476,8 @@ fn solve_inner(
         // to store those. Otherwise, we'll pass in `None` to the
         // functions below, which will trigger them to report errors
         // eagerly.
-        let mut outlives_requirements = if infcx.tcx.is_closure(mir_def_id) {
-            Some(vec![])
-        } else {
-            None
-        };
+        let mut outlives_requirements =
+            if infcx.tcx.is_closure(mir_def_id) { Some(vec![]) } else { None };
 
         self.check_type_tests(
             infcx,
@@ -451,16 +496,15 @@ fn solve_inner(
             errors_buffer,
         );
 
+        self.check_member_constraints(infcx, mir_def_id, errors_buffer);
+
         let outlives_requirements = outlives_requirements.unwrap_or(vec![]);
 
         if outlives_requirements.is_empty() {
             None
         } else {
             let num_external_vids = self.universal_regions.num_global_and_external_regions();
-            Some(ClosureRegionRequirements {
-                num_external_vids,
-                outlives_requirements,
-            })
+            Some(ClosureRegionRequirements { num_external_vids, outlives_requirements })
         }
     }
 
@@ -472,7 +516,7 @@ fn propagate_constraints(&mut self, _body: &Body<'tcx>) {
         debug!("propagate_constraints()");
 
         debug!("propagate_constraints: constraints={:#?}", {
-            let mut constraints: Vec<_> = self.constraints.iter().collect();
+            let mut constraints: Vec<_> = self.constraints.outlives().iter().collect();
             constraints.sort();
             constraints
                 .into_iter()
@@ -488,8 +532,14 @@ fn propagate_constraints(&mut self, _body: &Body<'tcx>) {
         for scc_index in self.constraint_sccs.all_sccs() {
             self.propagate_constraint_sccs_if_new(scc_index, visited);
         }
+
+        // Sort the applied member constraints so we can binary search
+        // through them later.
+        self.member_constraints_applied.sort_by_key(|applied| applied.member_region_scc);
     }
 
+    /// Computes the value of the SCC `scc_a` if it has not already
+    /// been computed. The `visited` parameter is a bitset
     #[inline]
     fn propagate_constraint_sccs_if_new(
         &mut self,
@@ -501,6 +551,10 @@ fn propagate_constraint_sccs_if_new(
         }
     }
 
+    /// Computes the value of the SCC `scc_a`, which has not yet been
+    /// computed. This works by first computing all successors of the
+    /// SCC (if they haven't been computed already) and then unioning
+    /// together their elements.
     fn propagate_constraint_sccs_new(
         &mut self,
         scc_a: ConstraintSccIndex,
@@ -510,10 +564,7 @@ fn propagate_constraint_sccs_new(
 
         // Walk each SCC `B` such that `A: B`...
         for &scc_b in constraint_sccs.successors(scc_a) {
-            debug!(
-                "propagate_constraint_sccs: scc_a = {:?} scc_b = {:?}",
-                scc_a, scc_b
-            );
+            debug!("propagate_constraint_sccs: scc_a = {:?} scc_b = {:?}", scc_a, scc_b);
 
             // ...compute the value of `B`...
             self.propagate_constraint_sccs_if_new(scc_b, visited);
@@ -531,6 +582,16 @@ fn propagate_constraint_sccs_new(
             }
         }
 
+        // Now take member constraints into account.
+        let member_constraints = self.member_constraints.clone();
+        for m_c_i in member_constraints.indices(scc_a) {
+            self.apply_member_constraint(
+                scc_a,
+                m_c_i,
+                member_constraints.choice_regions(m_c_i),
+            );
+        }
+
         debug!(
             "propagate_constraint_sccs: scc_a = {:?} has value {:?}",
             scc_a,
@@ -538,6 +599,167 @@ fn propagate_constraint_sccs_new(
         );
     }
 
+    /// Invoked for each `R0 member of [R1..Rn]` constraint.
+    ///
+    /// `scc` is the SCC containing R0, and `choice_regions` are the
+    /// `R1..Rn` regions -- they are always known to be universal
+    /// regions (and if that's not true, we just don't attempt to
+    /// enforce the constraint).
+    ///
+    /// The current value of `scc` at the time the method is invoked
+    /// is considered a *lower bound*.  If possible, we will modify
+    /// the constraint to set it equal to one of the option regions.
+    /// If we make any changes, returns true, else false.
+    fn apply_member_constraint(
+        &mut self,
+        scc: ConstraintSccIndex,
+        member_constraint_index: NllMemberConstraintIndex,
+        choice_regions: &[ty::RegionVid],
+    ) -> bool {
+        debug!("apply_member_constraint(scc={:?}, choice_regions={:#?})", scc, choice_regions,);
+
+        if let Some(uh_oh) =
+            choice_regions.iter().find(|&&r| !self.universal_regions.is_universal_region(r))
+        {
+            // FIXME(#61773): This case can only occur with
+            // `impl_trait_in_bindings`, I believe, and we are just
+            // opting not to handle it for now. See #61773 for
+            // details.
+            bug!(
+                "member constraint for `{:?}` has an option region `{:?}` \
+                 that is not a universal region",
+                self.member_constraints[member_constraint_index].opaque_type_def_id,
+                uh_oh,
+            );
+        }
+
+        // Create a mutable vector of the options. We'll try to winnow
+        // them down.
+        let mut choice_regions: Vec<ty::RegionVid> = choice_regions.to_vec();
+
+        // The 'member region' in a member constraint is part of the
+        // hidden type, which must be in the root universe. Therefore,
+        // it cannot have any placeholders in its value.
+        assert!(self.scc_universes[scc] == ty::UniverseIndex::ROOT);
+        debug_assert!(
+            self.scc_values.placeholders_contained_in(scc).next().is_none(),
+            "scc {:?} in a member constraint has placeholder value: {:?}",
+            scc,
+            self.scc_values.region_value_str(scc),
+        );
+
+        // The existing value for `scc` is a lower-bound. This will
+        // consist of some set `{P} + {LB}` of points `{P}` and
+        // lower-bound free regions `{LB}`. As each choice region `O`
+        // is a free region, it will outlive the points. But we can
+        // only consider the option `O` if `O: LB`.
+        choice_regions.retain(|&o_r| {
+            self.scc_values
+                .universal_regions_outlived_by(scc)
+                .all(|lb| self.universal_region_relations.outlives(o_r, lb))
+        });
+        debug!("apply_member_constraint: after lb, choice_regions={:?}", choice_regions);
+
+        // Now find all the *upper bounds* -- that is, each UB is a
+        // free region that must outlive the member region `R0` (`UB:
+        // R0`). Therefore, we need only keep an option `O` if `UB: O`
+        // for all UB.
+        if choice_regions.len() > 1 {
+            let universal_region_relations = self.universal_region_relations.clone();
+            let rev_constraint_graph = self.rev_constraint_graph();
+            for ub in self.upper_bounds(scc, &rev_constraint_graph) {
+                debug!("apply_member_constraint: ub={:?}", ub);
+                choice_regions.retain(|&o_r| universal_region_relations.outlives(ub, o_r));
+            }
+            debug!("apply_member_constraint: after ub, choice_regions={:?}", choice_regions);
+        }
+
+        // If we ruled everything out, we're done.
+        if choice_regions.is_empty() {
+            return false;
+        }
+
+        // Otherwise, we need to find the minimum remaining choice, if
+        // any, and take that.
+        debug!("apply_member_constraint: choice_regions remaining are {:#?}", choice_regions);
+        let min = |r1: ty::RegionVid, r2: ty::RegionVid| -> Option<ty::RegionVid> {
+            let r1_outlives_r2 = self.universal_region_relations.outlives(r1, r2);
+            let r2_outlives_r1 = self.universal_region_relations.outlives(r2, r1);
+            if r1_outlives_r2 && r2_outlives_r1 {
+                Some(r1.min(r2))
+            } else if r1_outlives_r2 {
+                Some(r2)
+            } else if r2_outlives_r1 {
+                Some(r1)
+            } else {
+                None
+            }
+        };
+        let mut min_choice = choice_regions[0];
+        for &other_option in &choice_regions[1..] {
+            debug!(
+                "apply_member_constraint: min_choice={:?} other_option={:?}",
+                min_choice, other_option,
+            );
+            match min(min_choice, other_option) {
+                Some(m) => min_choice = m,
+                None => {
+                    debug!(
+                        "apply_member_constraint: {:?} and {:?} are incomparable; no min choice",
+                        min_choice, other_option,
+                    );
+                    return false;
+                }
+            }
+        }
+
+        let min_choice_scc = self.constraint_sccs.scc(min_choice);
+        debug!(
+            "apply_member_constraint: min_choice={:?} best_choice_scc={:?}",
+            min_choice,
+            min_choice_scc,
+        );
+        if self.scc_values.add_region(scc, min_choice_scc) {
+            self.member_constraints_applied.push(AppliedMemberConstraint {
+                member_region_scc: scc,
+                min_choice,
+                member_constraint_index,
+            });
+
+            true
+        } else {
+            false
+        }
+    }
+
+    /// Compute and return the reverse SCC-based constraint graph (lazilly).
+    fn upper_bounds(
+        &'a mut self,
+        scc0: ConstraintSccIndex,
+        rev_constraint_graph: &'a VecGraph<ConstraintSccIndex>,
+    ) -> impl Iterator<Item = RegionVid> + 'a {
+        let scc_values = &self.scc_values;
+        let mut duplicates = FxHashSet::default();
+        rev_constraint_graph
+            .depth_first_search(scc0)
+            .skip(1)
+            .flat_map(move |scc1| scc_values.universal_regions_outlived_by(scc1))
+            .filter(move |&r| duplicates.insert(r))
+    }
+
+    /// Compute and return the reverse SCC-based constraint graph (lazilly).
+    fn rev_constraint_graph(
+        &mut self,
+    ) -> Rc<VecGraph<ConstraintSccIndex>> {
+        if let Some(g) = &self.rev_constraint_graph {
+            return g.clone();
+        }
+
+        let rev_graph = Rc::new(self.constraint_sccs.reverse());
+        self.rev_constraint_graph = Some(rev_graph.clone());
+        rev_graph
+    }
+
     /// Returns `true` if all the elements in the value of `scc_b` are nameable
     /// in `scc_a`. Used during constraint propagation, and only once
     /// the value of `scc_b` has been computed.
@@ -554,9 +776,7 @@ fn universe_compatible(&self, scc_b: ConstraintSccIndex, scc_a: ConstraintSccInd
         // Otherwise, we have to iterate over the universe elements in
         // B's value, and check whether all of them are nameable
         // from universe_a
-        self.scc_values
-            .placeholders_contained_in(scc_b)
-            .all(|p| universe_a.can_name(p.universe))
+        self.scc_values.placeholders_contained_in(scc_b).all(|p| universe_a.can_name(p.universe))
     }
 
     /// Extend `scc` so that it can outlive some placeholder region
@@ -731,12 +951,7 @@ fn try_promote_type_test(
     ) -> bool {
         let tcx = infcx.tcx;
 
-        let TypeTest {
-            generic_kind,
-            lower_bound,
-            locations,
-            verify_bound: _,
-        } = type_test;
+        let TypeTest { generic_kind, lower_bound, locations, verify_bound: _ } = type_test;
 
         let generic_ty = generic_kind.to_ty(tcx);
         let subject = match self.try_promote_type_test_subject(infcx, generic_ty) {
@@ -809,7 +1024,6 @@ fn try_promote_type_test_subject(
         ty: Ty<'tcx>,
     ) -> Option<ClosureOutlivesSubject<'tcx>> {
         let tcx = infcx.tcx;
-        let gcx = tcx.global_tcx();
 
         debug!("try_promote_type_test_subject(ty = {:?})", ty);
 
@@ -863,8 +1077,10 @@ fn try_promote_type_test_subject(
         });
         debug!("try_promote_type_test_subject: folded ty = {:?}", ty);
 
-        // `lift_to_global` will only fail if we failed to promote some region.
-        gcx.lift_to_global(&ty)?;
+        // `has_local_value` will only be true if we failed to promote some region.
+        if ty.has_local_value() {
+            return None;
+        }
 
         Some(ClosureOutlivesSubject::Ty(ty))
     }
@@ -885,11 +1101,7 @@ fn try_promote_type_test_subject(
     /// except that it converts further takes the non-local upper
     /// bound of `'y`, so that the final result is non-local.
     fn non_local_universal_upper_bound(&self, r: RegionVid) -> RegionVid {
-        debug!(
-            "non_local_universal_upper_bound(r={:?}={})",
-            r,
-            self.region_value_str(r)
-        );
+        debug!("non_local_universal_upper_bound(r={:?}={})", r, self.region_value_str(r));
 
         let lub = self.universal_upper_bound(r);
 
@@ -897,10 +1109,7 @@ fn non_local_universal_upper_bound(&self, r: RegionVid) -> RegionVid {
         // creator.
         let non_local_lub = self.universal_region_relations.non_local_upper_bound(lub);
 
-        debug!(
-            "non_local_universal_upper_bound: non_local_lub={:?}",
-            non_local_lub
-        );
+        debug!("non_local_universal_upper_bound: non_local_lub={:?}", non_local_lub);
 
         non_local_lub
     }
@@ -920,11 +1129,7 @@ fn non_local_universal_upper_bound(&self, r: RegionVid) -> RegionVid {
     /// - For each `end('x)` element in `'r`, compute the mutual LUB, yielding
     ///   a result `'y`.
     fn universal_upper_bound(&self, r: RegionVid) -> RegionVid {
-        debug!(
-            "universal_upper_bound(r={:?}={})",
-            r,
-            self.region_value_str(r)
-        );
+        debug!("universal_upper_bound(r={:?}={})", r, self.region_value_str(r));
 
         // Find the smallest universal region that contains all other
         // universal regions within `region`.
@@ -949,10 +1154,7 @@ fn eval_verify_bound(
         lower_bound: RegionVid,
         verify_bound: &VerifyBound<'tcx>,
     ) -> bool {
-        debug!(
-            "eval_verify_bound(lower_bound={:?}, verify_bound={:?})",
-            lower_bound, verify_bound
-        );
+        debug!("eval_verify_bound(lower_bound={:?}, verify_bound={:?})", lower_bound, verify_bound);
 
         match verify_bound {
             VerifyBound::IfEq(test_ty, verify_bound1) => {
@@ -961,7 +1163,7 @@ fn eval_verify_bound(
 
             VerifyBound::OutlivedBy(r) => {
                 let r_vid = self.to_region_vid(r);
-                self.eval_outlives(body, r_vid, lower_bound)
+                self.eval_outlives(r_vid, lower_bound)
             }
 
             VerifyBound::AnyBound(verify_bounds) => verify_bounds.iter().any(|verify_bound| {
@@ -1034,22 +1236,24 @@ fn normalize_to_scc_representatives<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
         })
     }
 
-    // Evaluate whether `sup_region: sub_region @ point`.
-    fn eval_outlives(
-        &self,
-        _body: &Body<'tcx>,
-        sup_region: RegionVid,
-        sub_region: RegionVid,
-    ) -> bool {
+    // Evaluate whether `sup_region == sub_region`.
+    fn eval_equal(&self, r1: RegionVid, r2: RegionVid) -> bool {
+        self.eval_outlives(r1, r2) && self.eval_outlives(r2, r1)
+    }
+
+    // Evaluate whether `sup_region: sub_region`.
+    fn eval_outlives(&self, sup_region: RegionVid, sub_region: RegionVid) -> bool {
         debug!("eval_outlives({:?}: {:?})", sup_region, sub_region);
 
         debug!(
-            "eval_outlives: sup_region's value = {:?}",
+            "eval_outlives: sup_region's value = {:?} universal={:?}",
             self.region_value_str(sup_region),
+            self.universal_regions.is_universal_region(sup_region),
         );
         debug!(
-            "eval_outlives: sub_region's value = {:?}",
+            "eval_outlives: sub_region's value = {:?} universal={:?}",
             self.region_value_str(sub_region),
+            self.universal_regions.is_universal_region(sub_region),
         );
 
         let sub_region_scc = self.constraint_sccs.scc(sub_region);
@@ -1061,9 +1265,8 @@ fn eval_outlives(
         // now). Therefore, the sup-region outlives the sub-region if,
         // for each universal region R1 in the sub-region, there
         // exists some region R2 in the sup-region that outlives R1.
-        let universal_outlives = self.scc_values
-            .universal_regions_outlived_by(sub_region_scc)
-            .all(|r1| {
+        let universal_outlives =
+            self.scc_values.universal_regions_outlived_by(sub_region_scc).all(|r1| {
                 self.scc_values
                     .universal_regions_outlived_by(sup_region_scc)
                     .any(|r2| self.universal_region_relations.outlives(r2, r1))
@@ -1081,8 +1284,7 @@ fn eval_outlives(
             return true;
         }
 
-        self.scc_values
-            .contains_points(sup_region_scc, sub_region_scc)
+        self.scc_values.contains_points(sup_region_scc, sub_region_scc)
     }
 
     /// Once regions have been propagated, this method is used to see
@@ -1164,12 +1366,7 @@ fn check_universal_region(
         // Because this free region must be in the ROOT universe, we
         // know it cannot contain any bound universes.
         assert!(self.scc_universes[longer_fr_scc] == ty::UniverseIndex::ROOT);
-        debug_assert!(
-            self.scc_values
-                .placeholders_contained_in(longer_fr_scc)
-                .next()
-                .is_none()
-        );
+        debug_assert!(self.scc_values.placeholders_contained_in(longer_fr_scc).next().is_none());
 
         // Only check all of the relations for the main representative of each
         // SCC, otherwise just check that we outlive said representative. This
@@ -1223,9 +1420,7 @@ fn check_universal_region_relation(
         errors_buffer: &mut Vec<Diagnostic>,
     ) -> Option<ErrorReported> {
         // If it is known that `fr: o`, carry on.
-        if self.universal_region_relations
-            .outlives(longer_fr, shorter_fr)
-        {
+        if self.universal_region_relations.outlives(longer_fr, shorter_fr) {
             return None;
         }
 
@@ -1239,9 +1434,7 @@ fn check_universal_region_relation(
             // We'll call it `fr-` -- it's ever so slightly smaller than
             // `longer_fr`.
 
-            if let Some(fr_minus) = self
-                .universal_region_relations
-                .non_local_lower_bound(longer_fr)
+            if let Some(fr_minus) = self.universal_region_relations.non_local_lower_bound(longer_fr)
             {
                 debug!("check_universal_region: fr_minus={:?}", fr_minus);
 
@@ -1251,12 +1444,9 @@ fn check_universal_region_relation(
                 // Grow `shorter_fr` until we find some non-local regions. (We
                 // always will.)  We'll call them `shorter_fr+` -- they're ever
                 // so slightly larger than `shorter_fr`.
-                let shorter_fr_plus = self.universal_region_relations
-                    .non_local_upper_bounds(&shorter_fr);
-                debug!(
-                    "check_universal_region: shorter_fr_plus={:?}",
-                    shorter_fr_plus
-                );
+                let shorter_fr_plus =
+                    self.universal_region_relations.non_local_upper_bounds(&shorter_fr);
+                debug!("check_universal_region: shorter_fr_plus={:?}", shorter_fr_plus);
                 for &&fr in &shorter_fr_plus {
                     // Push the constraint `fr-: shorter_fr+`
                     propagated_outlives_requirements.push(ClosureOutlivesRequirement {
@@ -1288,28 +1478,20 @@ fn check_bound_universal_region(
         longer_fr: RegionVid,
         placeholder: ty::PlaceholderRegion,
     ) {
-        debug!(
-            "check_bound_universal_region(fr={:?}, placeholder={:?})",
-            longer_fr, placeholder,
-        );
+        debug!("check_bound_universal_region(fr={:?}, placeholder={:?})", longer_fr, placeholder,);
 
         let longer_fr_scc = self.constraint_sccs.scc(longer_fr);
-        debug!(
-            "check_bound_universal_region: longer_fr_scc={:?}",
-            longer_fr_scc,
-        );
+        debug!("check_bound_universal_region: longer_fr_scc={:?}", longer_fr_scc,);
 
         // If we have some bound universal region `'a`, then the only
         // elements it can contain is itself -- we don't know anything
         // else about it!
         let error_element = match {
-            self.scc_values
-                .elements_contained_in(longer_fr_scc)
-                .find(|element| match element {
-                    RegionElement::Location(_) => true,
-                    RegionElement::RootUniversalRegion(_) => true,
-                    RegionElement::PlaceholderRegion(placeholder1) => placeholder != *placeholder1,
-                })
+            self.scc_values.elements_contained_in(longer_fr_scc).find(|element| match element {
+                RegionElement::Location(_) => true,
+                RegionElement::RootUniversalRegion(_) => true,
+                RegionElement::PlaceholderRegion(placeholder1) => placeholder != *placeholder1,
+            })
         } {
             Some(v) => v,
             None => return,
@@ -1320,7 +1502,8 @@ fn check_bound_universal_region(
         let error_region = match error_element {
             RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l),
             RegionElement::RootUniversalRegion(r) => r,
-            RegionElement::PlaceholderRegion(error_placeholder) => self.definitions
+            RegionElement::PlaceholderRegion(error_placeholder) => self
+                .definitions
                 .iter_enumerated()
                 .filter_map(|(r, definition)| match definition.origin {
                     NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r),
@@ -1338,12 +1521,50 @@ fn check_bound_universal_region(
         // the AST-based checker uses a more conservative check,
         // so to even see this error, one must pass in a special
         // flag.
-        let mut diag = infcx
-            .tcx
-            .sess
-            .struct_span_err(span, "higher-ranked subtype error");
+        let mut diag = infcx.tcx.sess.struct_span_err(span, "higher-ranked subtype error");
         diag.emit();
     }
+
+    fn check_member_constraints(
+        &self,
+        infcx: &InferCtxt<'_, 'tcx>,
+        mir_def_id: DefId,
+        errors_buffer: &mut Vec<Diagnostic>,
+    ) {
+        let member_constraints = self.member_constraints.clone();
+        for m_c_i in member_constraints.all_indices() {
+            debug!("check_member_constraint(m_c_i={:?})", m_c_i);
+            let m_c = &member_constraints[m_c_i];
+            let member_region_vid = m_c.member_region_vid;
+            debug!(
+                "check_member_constraint: member_region_vid={:?} with value {}",
+                member_region_vid,
+                self.region_value_str(member_region_vid),
+            );
+            let choice_regions = member_constraints.choice_regions(m_c_i);
+            debug!("check_member_constraint: choice_regions={:?}", choice_regions);
+
+            // Did the member region wind up equal to any of the option regions?
+            if let Some(o) = choice_regions.iter().find(|&&o_r| {
+                self.eval_equal(o_r, m_c.member_region_vid)
+            }) {
+                debug!("check_member_constraint: evaluated as equal to {:?}", o);
+                continue;
+            }
+
+            // If not, report an error.
+            let region_scope_tree = &infcx.tcx.region_scope_tree(mir_def_id);
+            let member_region = infcx.tcx.mk_region(ty::ReVar(member_region_vid));
+            opaque_types::unexpected_hidden_region_diagnostic(
+                infcx.tcx,
+                Some(region_scope_tree),
+                m_c.opaque_type_def_id,
+                m_c.hidden_ty,
+                member_region,
+            )
+            .buffer(errors_buffer);
+        }
+    }
 }
 
 impl<'tcx> RegionDefinition<'tcx> {
@@ -1357,11 +1578,7 @@ fn new(universe: ty::UniverseIndex, rv_origin: RegionVariableOrigin) -> Self {
             _ => NLLRegionVariableOrigin::Existential,
         };
 
-        Self {
-            origin,
-            universe,
-            external_name: None,
-        }
+        Self { origin, universe, external_name: None }
     }
 }
 
@@ -1371,7 +1588,7 @@ fn apply_requirements(
         tcx: TyCtxt<'tcx>,
         closure_def_id: DefId,
         closure_substs: SubstsRef<'tcx>,
-    ) -> Vec<QueryRegionConstraint<'tcx>>;
+    ) -> Vec<QueryOutlivesConstraint<'tcx>>;
 
     fn subst_closure_mapping<T>(
         &self,
@@ -1401,7 +1618,7 @@ fn apply_requirements(
         tcx: TyCtxt<'tcx>,
         closure_def_id: DefId,
         closure_substs: SubstsRef<'tcx>,
-    ) -> Vec<QueryRegionConstraint<'tcx>> {
+    ) -> Vec<QueryOutlivesConstraint<'tcx>> {
         debug!(
             "apply_requirements(closure_def_id={:?}, closure_substs={:?})",
             closure_def_id, closure_substs
@@ -1464,10 +1681,7 @@ fn subst_closure_mapping<T>(
             if let ty::ReClosureBound(vid) = r {
                 closure_mapping[*vid]
             } else {
-                bug!(
-                    "subst_closure_mapping: encountered non-closure bound free region {:?}",
-                    r
-                )
+                bug!("subst_closure_mapping: encountered non-closure bound free region {:?}", r)
             }
         })
     }
index cfd80cecca510865849ec3829d0a7e208dce6d36..6f9f5707935baa75ef782903d642681a23279e41 100644 (file)
@@ -162,7 +162,7 @@ impl<N: Idx> LivenessValues<N> {
     }
 
     /// Iterate through each region that has a value in this set.
-    crate fn rows<'a>(&'a self) -> impl Iterator<Item = N> {
+    crate fn rows(&self) -> impl Iterator<Item=N> {
         self.points.rows()
     }
 
index 77a4d2699fff72eff1cb1d2a16ca26c969605e1b..8de014522dea76ed302922d7f77baf84da1fc47e 100644 (file)
@@ -3,7 +3,8 @@
 use crate::borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints};
 use crate::borrow_check::nll::universal_regions::UniversalRegions;
 use crate::borrow_check::nll::ToRegionVid;
-use rustc::infer::canonical::QueryRegionConstraint;
+use rustc::infer::canonical::QueryRegionConstraints;
+use rustc::infer::canonical::QueryOutlivesConstraint;
 use rustc::infer::outlives::env::RegionBoundPairs;
 use rustc::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
 use rustc::infer::region_constraints::{GenericKind, VerifyBound};
@@ -49,13 +50,33 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
         }
     }
 
-    pub(super) fn convert_all(&mut self, query_constraints: &[QueryRegionConstraint<'tcx>]) {
-        for query_constraint in query_constraints {
+    pub(super) fn convert_all(&mut self, query_constraints: &QueryRegionConstraints<'tcx>) {
+        debug!("convert_all(query_constraints={:#?})", query_constraints);
+
+        let QueryRegionConstraints { outlives, member_constraints } = query_constraints;
+
+        // Annoying: to invoke `self.to_region_vid`, we need access to
+        // `self.constraints`, but we also want to be mutating
+        // `self.member_constraints`. For now, just swap out the value
+        // we want and replace at the end.
+        let mut tmp = std::mem::replace(
+            &mut self.constraints.member_constraints,
+            Default::default(),
+        );
+        for member_constraint in member_constraints {
+            tmp.push_constraint(
+                member_constraint,
+                |r| self.to_region_vid(r),
+            );
+        }
+        self.constraints.member_constraints = tmp;
+
+        for query_constraint in outlives {
             self.convert(query_constraint);
         }
     }
 
-    pub(super) fn convert(&mut self, query_constraint: &QueryRegionConstraint<'tcx>) {
+    pub(super) fn convert(&mut self, query_constraint: &QueryOutlivesConstraint<'tcx>) {
         debug!("generate: constraints at: {:#?}", self.locations);
 
         // Extract out various useful fields we'll need below.
index 1bb3acc28f0c8d97628fb2b6fa70529a43449062..d18a8e87453a54e6788fc9eec352390b0588fa6e 100644 (file)
@@ -2,7 +2,7 @@
 use crate::borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints};
 use crate::borrow_check::nll::universal_regions::UniversalRegions;
 use crate::borrow_check::nll::ToRegionVid;
-use rustc::infer::canonical::QueryRegionConstraint;
+use rustc::infer::canonical::QueryRegionConstraints;
 use rustc::infer::outlives::free_region_map::FreeRegionRelations;
 use rustc::infer::region_constraints::GenericKind;
 use rustc::infer::InferCtxt;
@@ -287,7 +287,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
             self.relations.relate_universal_regions(fr, fr_fn_body);
         }
 
-        for data in constraint_sets {
+        for data in &constraint_sets {
             constraint_conversion::ConstraintConversion::new(
                 self.infcx,
                 &self.universal_regions,
@@ -297,7 +297,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
                 Locations::All(DUMMY_SP),
                 ConstraintCategory::Internal,
                 &mut self.constraints,
-            ).convert_all(&data);
+            ).convert_all(data);
         }
 
         CreateResult {
@@ -311,7 +311,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
     /// either the return type of the MIR or one of its arguments. At
     /// the same time, compute and add any implied bounds that come
     /// from this local.
-    fn add_implied_bounds(&mut self, ty: Ty<'tcx>) -> Option<Rc<Vec<QueryRegionConstraint<'tcx>>>> {
+    fn add_implied_bounds(&mut self, ty: Ty<'tcx>) -> Option<Rc<QueryRegionConstraints<'tcx>>> {
         debug!("add_implied_bounds(ty={:?})", ty);
         let (bounds, constraints) =
             self.param_env
index 3b138bc1262575f419dad609fe45569b55c035fd..4af78fa5e0f42e4dd64979434aeb0384ff7ebb94 100644 (file)
@@ -1,5 +1,5 @@
 use crate::borrow_check::location::LocationTable;
-use crate::borrow_check::nll::constraints::ConstraintSet;
+use crate::borrow_check::nll::constraints::OutlivesConstraintSet;
 use crate::borrow_check::nll::facts::{AllFacts, AllFactsExt};
 use crate::borrow_check::nll::region_infer::values::RegionValueElements;
 use crate::borrow_check::nll::universal_regions::UniversalRegions;
@@ -107,7 +107,7 @@ fn compute_live_locals(
 fn regions_that_outlive_free_regions(
     num_region_vars: usize,
     universal_regions: &UniversalRegions<'tcx>,
-    constraint_set: &ConstraintSet,
+    constraint_set: &OutlivesConstraintSet,
 ) -> FxHashSet<RegionVid> {
     // Build a graph of the outlives constraints thus far. This is
     // a reverse graph, so for each constraint `R1: R2` we have an
index f1d568f0cf24c85a29e57c5c2080a6f9e9a0fa5f..f160f658f557640e68731c9b211cf29e19e6025d 100644 (file)
@@ -6,7 +6,7 @@
 use crate::dataflow::indexes::MovePathIndex;
 use crate::dataflow::move_paths::MoveData;
 use crate::dataflow::{FlowAtLocation, FlowsAtLocation, MaybeInitializedPlaces};
-use rustc::infer::canonical::QueryRegionConstraint;
+use rustc::infer::canonical::QueryRegionConstraints;
 use rustc::mir::{BasicBlock, ConstraintCategory, Local, Location, Body};
 use rustc::traits::query::dropck_outlives::DropckOutlivesResult;
 use rustc::traits::query::type_op::outlives::DropckOutlives;
@@ -88,7 +88,7 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> {
 
 struct DropData<'tcx> {
     dropck_result: DropckOutlivesResult<'tcx>,
-    region_constraint_data: Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>,
+    region_constraint_data: Option<Rc<QueryRegionConstraints<'tcx>>>,
 }
 
 struct LivenessResults<'me, 'typeck, 'flow, 'tcx> {
index 9409fefb6bde7d5d2d519762b02fb4b7238de059..cdbbe1d02bd92edd54450409dd9ae907ef6b6a08 100644 (file)
@@ -4,7 +4,8 @@
 
 use crate::borrow_check::borrow_set::BorrowSet;
 use crate::borrow_check::location::LocationTable;
-use crate::borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
+use crate::borrow_check::nll::constraints::{OutlivesConstraintSet, OutlivesConstraint};
+use crate::borrow_check::nll::member_constraints::MemberConstraintSet;
 use crate::borrow_check::nll::facts::AllFacts;
 use crate::borrow_check::nll::region_infer::values::LivenessValues;
 use crate::borrow_check::nll::region_infer::values::PlaceholderIndex;
@@ -23,7 +24,7 @@
 use either::Either;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
-use rustc::infer::canonical::QueryRegionConstraint;
+use rustc::infer::canonical::QueryRegionConstraints;
 use rustc::infer::outlives::env::RegionBoundPairs;
 use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin};
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -127,7 +128,8 @@ pub(crate) fn type_check<'tcx>(
         placeholder_indices: PlaceholderIndices::default(),
         placeholder_index_to_region: IndexVec::default(),
         liveness_constraints: LivenessValues::new(elements.clone()),
-        outlives_constraints: ConstraintSet::default(),
+        outlives_constraints: OutlivesConstraintSet::default(),
+        member_constraints: MemberConstraintSet::default(),
         closure_bounds_mapping: Default::default(),
         type_tests: Vec::default(),
     };
@@ -215,7 +217,7 @@ fn translate_outlives_facts(cx: &mut BorrowCheckContext<'_, '_>) {
         let location_table = cx.location_table;
         facts
             .outlives
-            .extend(cx.constraints.outlives_constraints.iter().flat_map(
+            .extend(cx.constraints.outlives_constraints.outlives().iter().flat_map(
                 |constraint: &OutlivesConstraint| {
                     if let Some(from_location) = constraint.locations.from_location() {
                         Either::Left(iter::once((
@@ -582,7 +584,7 @@ fn sanitize_promoted(&mut self, promoted_body: &'b Body<'tcx>, location: Locatio
         );
 
         let locations = location.to_locations();
-        for constraint in constraints.iter() {
+        for constraint in constraints.outlives().iter() {
             let mut constraint = *constraint;
             constraint.locations = locations;
             if let ConstraintCategory::Return
@@ -834,6 +836,7 @@ struct TypeChecker<'a, 'tcx> {
     infcx: &'a InferCtxt<'a, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     last_span: Span,
+    body: &'a Body<'tcx>,
     /// User type annotations are shared between the main MIR and the MIR of
     /// all of the promoted items.
     user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
@@ -884,7 +887,9 @@ struct BorrowCheckContext<'a, 'tcx> {
     /// hence it must report on their liveness constraints.
     crate liveness_constraints: LivenessValues<RegionVid>,
 
-    crate outlives_constraints: ConstraintSet,
+    crate outlives_constraints: OutlivesConstraintSet,
+
+    crate member_constraints: MemberConstraintSet<'tcx, RegionVid>,
 
     crate closure_bounds_mapping:
         FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
@@ -992,6 +997,7 @@ fn new(
             infcx,
             last_span: DUMMY_SP,
             mir_def_id,
+            body,
             user_type_annotations: &body.user_type_annotations,
             param_env,
             region_bound_pairs,
@@ -1093,7 +1099,7 @@ fn push_region_constraints(
         &mut self,
         locations: Locations,
         category: ConstraintCategory,
-        data: &[QueryRegionConstraint<'tcx>],
+        data: &QueryRegionConstraints<'tcx>,
     ) {
         debug!(
             "push_region_constraints: constraints generated at {:?} are {:#?}",
@@ -1109,7 +1115,7 @@ fn push_region_constraints(
             locations,
             category,
             &mut self.borrowck_context.constraints,
-        ).convert_all(&data);
+        ).convert_all(data);
     }
 
     /// Convenient wrapper around `relate_tys::relate_types` -- see
@@ -1229,6 +1235,7 @@ fn eq_opaque_type_and_type(
         let infcx = self.infcx;
         let tcx = infcx.tcx;
         let param_env = self.param_env;
+        let body = self.body;
         debug!("eq_opaque_type_and_type: mir_def_id={:?}", self.mir_def_id);
         let opaque_type_map = self.fully_perform_op(
             locations,
@@ -1244,6 +1251,7 @@ fn eq_opaque_type_and_type(
                             dummy_body_id,
                             param_env,
                             &anon_ty,
+                            locations.span(body),
                         ));
                     debug!(
                         "eq_opaque_type_and_type: \
@@ -2508,10 +2516,20 @@ fn prove_closure_bounds(
         location: Location,
     ) -> ty::InstantiatedPredicates<'tcx> {
         if let Some(closure_region_requirements) = tcx.mir_borrowck(def_id).closure_requirements {
-            let closure_constraints =
-                closure_region_requirements.apply_requirements(tcx, def_id, substs);
+            let closure_constraints = QueryRegionConstraints {
+                outlives: closure_region_requirements.apply_requirements(tcx, def_id, substs),
+
+                // Presently, closures never propagate member
+                // constraints to their parents -- they are enforced
+                // locally.  This is largely a non-issue as member
+                // constraints only come from `-> impl Trait` and
+                // friends which don't appear (thus far...) in
+                // closures.
+                member_constraints: vec![],
+            };
 
             let bounds_mapping = closure_constraints
+                .outlives
                 .iter()
                 .enumerate()
                 .filter_map(|(idx, constraint)| {
index a85f4776a8bee2638def80071668c35cb35cb875..3e090aed5227006bcd8cdc7bdabd73a71f282834 100644 (file)
@@ -768,7 +768,7 @@ fn for_each_late_bound_region_defined_on<'tcx>(
                 local_id: *late_bound,
             };
             let name = tcx.hir().name(hir_id).as_interned_str();
-            let region_def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
+            let region_def_id = tcx.hir().local_def_id(hir_id);
             let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
                 scope: fn_def_id,
                 bound_region: ty::BoundRegion::BrNamed(region_def_id, name),
index aa2b177e54ed8607a211089b776fd48990702d6e..538ac6881d90ab8d98b8f72c19cebaa4cc2bebb3 100644 (file)
@@ -130,7 +130,7 @@ 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 {
+pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool {
     place.iterate(|place_base, place_projection| {
         match place_base {
             PlaceBase::Static(..) => return false,
index 222ce6d1c968eaaf716c5bc2b3543a8539b76f9d..f679a00035d76ebfbb37b4ad30975958bf14c837 100644 (file)
@@ -31,7 +31,7 @@ pub enum RvalueFunc {
 /// Determines the category for a given expression. Note that scope
 /// and paren expressions have no category.
 impl Category {
-    pub fn of<'tcx>(ek: &ExprKind<'tcx>) -> Option<Category> {
+    pub fn of(ek: &ExprKind<'_>) -> Option<Category> {
         match *ek {
             ExprKind::Scope { .. } => None,
 
index f831f5105a4686d368ff694b8c34d3b399a07ac0..75c64bb2644c1611809dd00dfe9a56221c862f50 100644 (file)
@@ -228,10 +228,12 @@ pub fn match_expr(
         };
 
         // Step 5. Create everything else: the guards and the arms.
+        let match_scope = self.scopes.topmost();
+
         let arm_end_blocks: Vec<_> = arm_candidates.into_iter().map(|(arm, mut candidates)| {
             let arm_source_info = self.source_info(arm.span);
-            let region_scope = (arm.scope, arm_source_info);
-            self.in_scope(region_scope, arm.lint_level, |this| {
+            let arm_scope = (arm.scope, arm_source_info);
+            self.in_scope(arm_scope, arm.lint_level, |this| {
                 let body = this.hir.mirror(arm.body.clone());
                 let scope = this.declare_bindings(
                     None,
@@ -248,7 +250,7 @@ pub fn match_expr(
                         arm.guard.clone(),
                         &fake_borrow_temps,
                         scrutinee_span,
-                        region_scope,
+                        match_scope,
                     );
                 } else {
                     arm_block = this.cfg.start_new_block();
@@ -259,7 +261,7 @@ pub fn match_expr(
                             arm.guard.clone(),
                             &fake_borrow_temps,
                             scrutinee_span,
-                            region_scope,
+                            match_scope,
                         );
                         this.cfg.terminate(
                             binding_end,
@@ -1339,7 +1341,7 @@ fn bind_and_guard_matched_candidate<'pat>(
         guard: Option<Guard<'tcx>>,
         fake_borrows: &Vec<(&Place<'tcx>, Local)>,
         scrutinee_span: Span,
-        region_scope: (region::Scope, SourceInfo),
+        region_scope: region::Scope,
     ) -> BasicBlock {
         debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate);
 
index b1b5233fbc8750962318244e112f546c545a58a3..7125eb6850bb6c6f7639362b28406ea61d299fdd 100644 (file)
@@ -28,7 +28,7 @@ pub fn simplify_candidate<'pat>(&mut self,
                                     candidate: &mut Candidate<'pat, 'tcx>) {
         // repeatedly simplify match pairs until fixed point is reached
         loop {
-            let match_pairs = mem::replace(&mut candidate.match_pairs, vec![]);
+            let match_pairs = mem::take(&mut candidate.match_pairs);
             let mut changed = false;
             for match_pair in match_pairs {
                 match self.simplify_match_pair(match_pair, candidate) {
index 95e2e52092a91c138e1866944c3d96b3443ec414..528dfbef6946a3d5546582bb77da17ae7cd8546e 100644 (file)
@@ -826,6 +826,6 @@ pub(super) fn targets(&self) -> usize {
     }
 }
 
-fn is_switch_ty<'tcx>(ty: Ty<'tcx>) -> bool {
+fn is_switch_ty(ty: Ty<'_>) -> bool {
     ty.is_integral() || ty.is_char() || ty.is_bool()
 }
index ad970de466cfdf16baba62ffdbe2645ec9d9ad91..8948d1c4b3663db2e3740850577df43c2e0d9664 100644 (file)
@@ -22,7 +22,7 @@
 use super::lints;
 
 /// Construct the MIR for a given `DefId`.
-pub fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Body<'tcx> {
+pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {
     let id = tcx.hir().as_local_hir_id(def_id).unwrap();
 
     // Figure out what primary body this item has.
@@ -69,7 +69,7 @@ pub fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Body<'tcx> {
             // fetch the fully liberated fn signature (that is, all bound
             // types/lifetimes replaced)
             let fn_sig = cx.tables().liberated_fn_sigs()[id].clone();
-            let fn_def_id = tcx.hir().local_def_id_from_hir_id(id);
+            let fn_def_id = tcx.hir().local_def_id(id);
 
             let ty = tcx.type_of(fn_def_id);
             let mut abi = fn_sig.abi;
@@ -171,11 +171,11 @@ pub fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Body<'tcx> {
 ///////////////////////////////////////////////////////////////////////////
 // BuildMir -- walks a crate, looking for fn items and methods to build MIR from
 
-fn liberated_closure_env_ty<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn liberated_closure_env_ty(
+    tcx: TyCtxt<'_>,
     closure_expr_id: hir::HirId,
     body_id: hir::BodyId,
-) -> Ty<'tcx> {
+) -> Ty<'_> {
     let closure_ty = tcx.body_tables(body_id).node_type(closure_expr_id);
 
     let (closure_def_id, closure_substs) = match closure_ty.sty {
@@ -485,7 +485,7 @@ macro_rules! unpack {
     };
 }
 
-fn should_abort_on_panic<'tcx>(tcx: TyCtxt<'tcx>, fn_def_id: DefId, abi: Abi) -> bool {
+fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, abi: Abi) -> bool {
     // Not callable from C, so we can safely unwind through these
     if abi == Abi::Rust || abi == Abi::RustCall { return false; }
 
@@ -534,7 +534,7 @@ fn construct_fn<'a, 'tcx, A>(
     let span = tcx_hir.span(fn_id);
 
     let hir_tables = hir.tables();
-    let fn_def_id = tcx_hir.local_def_id_from_hir_id(fn_id);
+    let fn_def_id = tcx_hir.local_def_id(fn_id);
 
     // Gather the upvars of a closure, if any.
     let mut upvar_mutbls = vec![];
@@ -604,9 +604,18 @@ fn construct_fn<'a, 'tcx, A>(
         }
 
         let arg_scope_s = (arg_scope, source_info);
-        unpack!(block = builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
-            builder.args_and_body(block, &arguments, arg_scope, &body.value)
-        }));
+        // `return_block` is called when we evaluate a `return` expression, so
+        // we just use `START_BLOCK` here.
+        unpack!(block = builder.in_breakable_scope(
+            None,
+            START_BLOCK,
+            Place::RETURN_PLACE,
+            |builder| {
+                builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
+                    builder.args_and_body(block, &arguments, arg_scope, &body.value)
+                })
+            },
+        ));
         // Attribute epilogue to function's closing brace
         let fn_end = span.shrink_to_hi();
         let source_info = builder.source_info(fn_end);
@@ -860,11 +869,7 @@ fn args_and_body(&mut self,
         }
 
         let body = self.hir.mirror(ast_body);
-        // `return_block` is called when we evaluate a `return` expression, so
-        // we just use `START_BLOCK` here.
-        self.in_breakable_scope(None, START_BLOCK, Place::RETURN_PLACE, |this| {
-            this.into(&Place::RETURN_PLACE, block, body)
-        })
+        self.into(&Place::RETURN_PLACE, block, body)
     }
 
     fn get_unit_temp(&mut self) -> Place<'tcx> {
index 1b5fa1c9770f168d37de3a4e2fb6885075b69e83..a74d5d7ab2de3347ac8a6251cdb8a2655e072617 100644 (file)
@@ -332,9 +332,9 @@ fn find_breakable_scope(
         }
     }
 
-    fn num_scopes_to(&self, region_scope: (region::Scope, SourceInfo), span: Span) -> usize {
-        let scope_count = 1 + self.scopes.iter().rev()
-            .position(|scope| scope.region_scope == region_scope.0)
+    fn num_scopes_above(&self, region_scope: region::Scope, span: Span) -> usize {
+        let scope_count = self.scopes.iter().rev()
+            .position(|scope| scope.region_scope == region_scope)
             .unwrap_or_else(|| {
                 span_bug!(span, "region_scope {:?} does not enclose", region_scope)
             });
@@ -354,7 +354,7 @@ fn top_scopes(&mut self, count: usize) -> impl DoubleEndedIterator<Item=&mut Sco
 
     /// Returns the topmost active scope, which is known to be alive until
     /// the next scope expression.
-    fn topmost(&self) -> region::Scope {
+    pub(super) fn topmost(&self) -> region::Scope {
         self.scopes.last().expect("topmost_scope: no scopes present").region_scope
     }
 
@@ -514,7 +514,7 @@ pub fn break_scope(
         } else {
             assert!(value.is_none(), "`return` and `break` should have a destination");
         }
-        self.exit_scope(source_info.span, (region_scope, source_info), block, target_block);
+        self.exit_scope(source_info.span, region_scope, block, target_block);
         self.cfg.start_new_block().unit()
     }
 
@@ -523,12 +523,12 @@ pub fn break_scope(
     /// needed. See module comment for details.
     pub fn exit_scope(&mut self,
                       span: Span,
-                      region_scope: (region::Scope, SourceInfo),
+                      region_scope: region::Scope,
                       mut block: BasicBlock,
                       target: BasicBlock) {
         debug!("exit_scope(region_scope={:?}, block={:?}, target={:?})",
                region_scope, block, target);
-        let scope_count = self.scopes.num_scopes_to(region_scope, span);
+        let scope_count = self.scopes.num_scopes_above(region_scope, span);
 
         // If we are emitting a `drop` statement, we need to have the cached
         // diverge cleanup pads ready in case that drop panics.
@@ -545,7 +545,7 @@ pub fn exit_scope(&mut self,
                 continue;
             }
             let source_info = scope.source_info(span);
-            block = match scope.cached_exits.entry((target, region_scope.0)) {
+            block = match scope.cached_exits.entry((target, region_scope)) {
                 Entry::Occupied(e) => {
                     self.cfg.terminate(block, source_info,
                                     TerminatorKind::Goto { target: *e.get() });
index 887ef4b520ea38110c3c4c8a656ceb15f7dfdb07..49a42955d8dd6032bfa4b21e4ffcdd5eaa20b393 100644 (file)
@@ -22,7 +22,7 @@
 use crate::interpret::{self,
     PlaceTy, MPlaceTy, OpTy, ImmTy, Immediate, Scalar,
     RawConst, ConstValue,
-    InterpResult, InterpErrorInfo, InterpError, GlobalId, InterpretCx, StackPopCleanup,
+    InterpResult, InterpErrorInfo, InterpError, GlobalId, InterpCx, StackPopCleanup,
     Allocation, AllocId, MemoryKind, Memory,
     snapshot, RefTracking, intern_const_alloc_recursive,
 };
@@ -34,7 +34,7 @@
 /// Should be a power of two for performance reasons.
 const DETECTOR_SNAPSHOT_PERIOD: isize = 256;
 
-/// The `InterpretCx` is only meant to be used to do field and index projections into constants for
+/// The `InterpCx` is only meant to be used to do field and index projections into constants for
 /// `simd_shuffle` and const patterns in match arms.
 ///
 /// The function containing the `match` that is currently being analyzed may have generic bounds
@@ -47,7 +47,7 @@ pub(crate) fn mk_eval_cx<'mir, 'tcx>(
     param_env: ty::ParamEnv<'tcx>,
 ) -> CompileTimeEvalContext<'mir, 'tcx> {
     debug!("mk_eval_cx: {:?}", param_env);
-    InterpretCx::new(tcx.at(span), param_env, CompileTimeInterpreter::new())
+    InterpCx::new(tcx.at(span), param_env, CompileTimeInterpreter::new(), Default::default())
 }
 
 pub(crate) fn eval_promoted<'mir, 'tcx>(
@@ -303,7 +303,7 @@ fn get_mut_or<E>(
 }
 
 crate type CompileTimeEvalContext<'mir, 'tcx> =
-    InterpretCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>;
+    InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>;
 
 impl interpret::MayLeak for ! {
     #[inline(always)]
@@ -316,6 +316,7 @@ fn may_leak(self) -> bool {
 impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, 'tcx> {
     type MemoryKinds = !;
     type PointerTag = ();
+    type ExtraFnVal = !;
 
     type FrameExtra = ();
     type MemoryExtra = ();
@@ -326,12 +327,12 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
     const STATIC_KIND: Option<!> = None; // no copying of statics allowed
 
     #[inline(always)]
-    fn enforce_validity(_ecx: &InterpretCx<'mir, 'tcx, Self>) -> bool {
+    fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
         false // for now, we don't enforce validity
     }
 
     fn find_fn(
-        ecx: &mut InterpretCx<'mir, 'tcx, Self>,
+        ecx: &mut InterpCx<'mir, 'tcx, Self>,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx>],
         dest: Option<PlaceTy<'tcx>>,
@@ -370,8 +371,18 @@ fn find_fn(
         }))
     }
 
+    fn call_extra_fn(
+        _ecx: &mut InterpCx<'mir, 'tcx, Self>,
+        fn_val: !,
+        _args: &[OpTy<'tcx>],
+        _dest: Option<PlaceTy<'tcx>>,
+        _ret: Option<mir::BasicBlock>,
+    ) -> InterpResult<'tcx> {
+        match fn_val {}
+    }
+
     fn call_intrinsic(
-        ecx: &mut InterpretCx<'mir, 'tcx, Self>,
+        ecx: &mut InterpCx<'mir, 'tcx, Self>,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx>],
         dest: PlaceTy<'tcx>,
@@ -387,7 +398,7 @@ fn call_intrinsic(
     }
 
     fn ptr_op(
-        _ecx: &InterpretCx<'mir, 'tcx, Self>,
+        _ecx: &InterpCx<'mir, 'tcx, Self>,
         _bin_op: mir::BinOp,
         _left: ImmTy<'tcx>,
         _right: ImmTy<'tcx>,
@@ -424,7 +435,7 @@ fn tag_static_base_pointer(
     }
 
     fn box_alloc(
-        _ecx: &mut InterpretCx<'mir, 'tcx, Self>,
+        _ecx: &mut InterpCx<'mir, 'tcx, Self>,
         _dest: PlaceTy<'tcx>,
     ) -> InterpResult<'tcx> {
         Err(
@@ -432,7 +443,7 @@ fn box_alloc(
         )
     }
 
-    fn before_terminator(ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
+    fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
         {
             let steps = &mut ecx.machine.steps_since_detector_enabled;
 
@@ -457,13 +468,13 @@ fn before_terminator(ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'t
     }
 
     #[inline(always)]
-    fn stack_push(_ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
+    fn stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
         Ok(())
     }
 
     /// Called immediately before a stack frame gets popped.
     #[inline(always)]
-    fn stack_pop(_ecx: &mut InterpretCx<'mir, 'tcx, Self>, _extra: ()) -> InterpResult<'tcx> {
+    fn stack_pop(_ecx: &mut InterpCx<'mir, 'tcx, Self>, _extra: ()) -> InterpResult<'tcx> {
         Ok(())
     }
 }
@@ -508,7 +519,7 @@ pub fn const_variant_index<'tcx>(
 }
 
 pub fn error_to_const_error<'mir, 'tcx>(
-    ecx: &InterpretCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
+    ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
     mut error: InterpErrorInfo<'tcx>,
 ) -> ConstEvalErr<'tcx> {
     error.print_backtrace();
@@ -632,7 +643,12 @@ pub fn const_eval_raw_provider<'tcx>(
     }
 
     let span = tcx.def_span(cid.instance.def_id());
-    let mut ecx = InterpretCx::new(tcx.at(span), key.param_env, CompileTimeInterpreter::new());
+    let mut ecx = InterpCx::new(
+        tcx.at(span),
+        key.param_env,
+        CompileTimeInterpreter::new(),
+        Default::default()
+    );
 
     let res = ecx.load_mir(cid.instance.def);
     res.map(|body| {
index 7735528d8f8e06aeb99577ee35239398650d17ab..f0014602e2d6b161089727ccbcf901fcf80c8362 100644 (file)
@@ -8,6 +8,7 @@
 use crate::dataflow::move_paths::{HasMoveData, MovePathIndex};
 
 use std::iter;
+use std::borrow::Borrow;
 
 /// A trait for "cartesian products" of multiple FlowAtLocation.
 ///
@@ -60,18 +61,20 @@ pub trait FlowsAtLocation {
 /// (e.g., via `reconstruct_statement_effect` and
 /// `reconstruct_terminator_effect`; don't forget to call
 /// `apply_local_effect`).
-pub struct FlowAtLocation<'tcx, BD>
+pub struct FlowAtLocation<'tcx, BD, DR = DataflowResults<'tcx, BD>>
 where
     BD: BitDenotation<'tcx>,
+    DR: Borrow<DataflowResults<'tcx, BD>>,
 {
-    base_results: DataflowResults<'tcx, BD>,
+    base_results: DR,
     curr_state: BitSet<BD::Idx>,
     stmt_trans: GenKillSet<BD::Idx>,
 }
 
-impl<'tcx, BD> FlowAtLocation<'tcx, BD>
+impl<'tcx, BD, DR> FlowAtLocation<'tcx, BD, DR>
 where
     BD: BitDenotation<'tcx>,
+    DR: Borrow<DataflowResults<'tcx, BD>>,
 {
     /// Iterate over each bit set in the current state.
     pub fn each_state_bit<F>(&self, f: F)
@@ -91,8 +94,8 @@ pub fn each_gen_bit<F>(&self, f: F)
         self.stmt_trans.gen_set.iter().for_each(f)
     }
 
-    pub fn new(results: DataflowResults<'tcx, BD>) -> Self {
-        let bits_per_block = results.sets().bits_per_block();
+    pub fn new(results: DR) -> Self {
+        let bits_per_block = results.borrow().sets().bits_per_block();
         let curr_state = BitSet::new_empty(bits_per_block);
         let stmt_trans = GenKillSet::from_elem(HybridBitSet::new_empty(bits_per_block));
         FlowAtLocation {
@@ -104,7 +107,7 @@ pub fn new(results: DataflowResults<'tcx, BD>) -> Self {
 
     /// Access the underlying operator.
     pub fn operator(&self) -> &BD {
-        self.base_results.operator()
+        self.base_results.borrow().operator()
     }
 
     pub fn contains(&self, x: BD::Idx) -> bool {
@@ -134,27 +137,31 @@ pub fn as_dense(&self) -> &BitSet<BD::Idx> {
     }
 }
 
-impl<'tcx, BD> FlowsAtLocation for FlowAtLocation<'tcx, BD>
-    where BD: BitDenotation<'tcx>
+impl<'tcx, BD, DR> FlowsAtLocation for FlowAtLocation<'tcx, BD, DR>
+where
+    BD: BitDenotation<'tcx>,
+    DR: Borrow<DataflowResults<'tcx, BD>>,
 {
     fn reset_to_entry_of(&mut self, bb: BasicBlock) {
-        self.curr_state.overwrite(self.base_results.sets().entry_set_for(bb.index()));
+        self.curr_state.overwrite(self.base_results.borrow().sets().entry_set_for(bb.index()));
     }
 
     fn reset_to_exit_of(&mut self, bb: BasicBlock) {
         self.reset_to_entry_of(bb);
-        let trans = self.base_results.sets().trans_for(bb.index());
+        let trans = self.base_results.borrow().sets().trans_for(bb.index());
         trans.apply(&mut self.curr_state)
     }
 
     fn reconstruct_statement_effect(&mut self, loc: Location) {
         self.stmt_trans.clear();
         self.base_results
+            .borrow()
             .operator()
             .before_statement_effect(&mut self.stmt_trans, loc);
         self.stmt_trans.apply(&mut self.curr_state);
 
         self.base_results
+            .borrow()
             .operator()
             .statement_effect(&mut self.stmt_trans, loc);
     }
@@ -162,11 +169,13 @@ fn reconstruct_statement_effect(&mut self, loc: Location) {
     fn reconstruct_terminator_effect(&mut self, loc: Location) {
         self.stmt_trans.clear();
         self.base_results
+            .borrow()
             .operator()
             .before_terminator_effect(&mut self.stmt_trans, loc);
         self.stmt_trans.apply(&mut self.curr_state);
 
         self.base_results
+            .borrow()
             .operator()
             .terminator_effect(&mut self.stmt_trans, loc);
     }
@@ -177,9 +186,10 @@ fn apply_local_effect(&mut self, _loc: Location) {
 }
 
 
-impl<'tcx, T> FlowAtLocation<'tcx, T>
+impl<'tcx, T, DR> FlowAtLocation<'tcx, T, DR>
 where
     T: HasMoveData<'tcx> + BitDenotation<'tcx, Idx = MovePathIndex>,
+    DR: Borrow<DataflowResults<'tcx, T>>,
 {
     pub fn has_any_child_of(&self, mpi: T::Idx) -> Option<T::Idx> {
         // We process `mpi` before the loop below, for two reasons:
index 0f7f37f2db8b47b10de129eae036b792750fabd0..d94ebdbae24ae9f68d3a9468a431b1cdfd9f84c0 100644 (file)
@@ -92,7 +92,7 @@ struct BorrowedLocalsVisitor<'gk> {
     trans: &'gk mut GenKillSet<Local>,
 }
 
-fn find_local<'tcx>(place: &Place<'tcx>) -> Option<Local> {
+fn find_local(place: &Place<'_>) -> Option<Local> {
     place.iterate(|place_base, place_projection| {
         for proj in place_projection {
             if proj.elem == ProjectionElem::Deref {
index d2003993d45063f1f014b347412ec623dcddb984..7fa950cb98d344886fa6b94698647d5fecab2f2b 100644 (file)
@@ -1,7 +1,13 @@
 pub use super::*;
 
 use rustc::mir::*;
+use rustc::mir::visit::{
+    PlaceContext, Visitor, NonMutatingUseContext,
+};
+use std::cell::RefCell;
 use crate::dataflow::BitDenotation;
+use crate::dataflow::HaveBeenBorrowedLocals;
+use crate::dataflow::{DataflowResults, DataflowResultsCursor, DataflowResultsRefCursor};
 
 #[derive(Copy, Clone)]
 pub struct MaybeStorageLive<'a, 'tcx> {
@@ -27,7 +33,9 @@ fn bits_per_block(&self) -> usize {
     }
 
     fn start_block_effect(&self, _on_entry: &mut BitSet<Local>) {
-        // Nothing is live on function entry
+        // Nothing is live on function entry (generators only have a self
+        // argument, and we don't care about that)
+        assert_eq!(1, self.body.arg_count);
     }
 
     fn statement_effect(&self,
@@ -63,3 +71,123 @@ impl<'a, 'tcx> BottomValue for MaybeStorageLive<'a, 'tcx> {
     /// bottom = dead
     const BOTTOM_VALUE: bool = false;
 }
+
+/// Dataflow analysis that determines whether each local requires storage at a
+/// given location; i.e. whether its storage can go away without being observed.
+pub struct RequiresStorage<'mir, 'tcx> {
+    body: &'mir Body<'tcx>,
+    borrowed_locals:
+        RefCell<DataflowResultsRefCursor<'mir, 'tcx, HaveBeenBorrowedLocals<'mir, 'tcx>>>,
+}
+
+impl<'mir, 'tcx: 'mir> RequiresStorage<'mir, 'tcx> {
+    pub fn new(
+        body: &'mir Body<'tcx>,
+        borrowed_locals: &'mir DataflowResults<'tcx, HaveBeenBorrowedLocals<'mir, 'tcx>>,
+    ) -> Self {
+        RequiresStorage {
+            body,
+            borrowed_locals: RefCell::new(DataflowResultsCursor::new(borrowed_locals, body)),
+        }
+    }
+
+    pub fn body(&self) -> &Body<'tcx> {
+        self.body
+    }
+}
+
+impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
+    type Idx = Local;
+    fn name() -> &'static str { "requires_storage" }
+    fn bits_per_block(&self) -> usize {
+        self.body.local_decls.len()
+    }
+
+    fn start_block_effect(&self, _sets: &mut BitSet<Local>) {
+        // Nothing is live on function entry (generators only have a self
+        // argument, and we don't care about that)
+        assert_eq!(1, self.body.arg_count);
+    }
+
+    fn statement_effect(&self,
+                        sets: &mut GenKillSet<Local>,
+                        loc: Location) {
+        self.check_for_move(sets, loc);
+        self.check_for_borrow(sets, loc);
+
+        let stmt = &self.body[loc.block].statements[loc.statement_index];
+        match stmt.kind {
+            StatementKind::StorageLive(l) => sets.gen(l),
+            StatementKind::StorageDead(l) => sets.kill(l),
+            StatementKind::Assign(ref place, _)
+            | StatementKind::SetDiscriminant { ref place, .. } => {
+                place.base_local().map(|l| sets.gen(l));
+            }
+            StatementKind::InlineAsm(box InlineAsm { ref outputs, .. }) => {
+                for p in &**outputs {
+                    p.base_local().map(|l| sets.gen(l));
+                }
+            }
+            _ => (),
+        }
+    }
+
+    fn terminator_effect(&self,
+                         sets: &mut GenKillSet<Local>,
+                         loc: Location) {
+        self.check_for_move(sets, loc);
+        self.check_for_borrow(sets, loc);
+    }
+
+    fn propagate_call_return(
+        &self,
+        in_out: &mut BitSet<Local>,
+        _call_bb: mir::BasicBlock,
+        _dest_bb: mir::BasicBlock,
+        dest_place: &mir::Place<'tcx>,
+    ) {
+        dest_place.base_local().map(|l| in_out.insert(l));
+    }
+}
+
+impl<'mir, 'tcx> RequiresStorage<'mir, 'tcx> {
+    /// Kill locals that are fully moved and have not been borrowed.
+    fn check_for_move(&self, sets: &mut GenKillSet<Local>, loc: Location) {
+        let mut visitor = MoveVisitor {
+            sets,
+            borrowed_locals: &self.borrowed_locals,
+        };
+        visitor.visit_location(self.body, loc);
+    }
+
+    /// Gen locals that are newly borrowed. This includes borrowing any part of
+    /// a local (we rely on this behavior of `HaveBeenBorrowedLocals`).
+    fn check_for_borrow(&self, sets: &mut GenKillSet<Local>, loc: Location) {
+        let mut borrowed_locals = self.borrowed_locals.borrow_mut();
+        borrowed_locals.seek(loc);
+        borrowed_locals.each_gen_bit(|l| sets.gen(l));
+    }
+}
+
+impl<'mir, 'tcx> BottomValue for RequiresStorage<'mir, 'tcx> {
+    /// bottom = dead
+    const BOTTOM_VALUE: bool = false;
+}
+
+struct MoveVisitor<'a, 'mir, 'tcx> {
+    borrowed_locals:
+        &'a RefCell<DataflowResultsRefCursor<'mir, 'tcx, HaveBeenBorrowedLocals<'mir, 'tcx>>>,
+    sets: &'a mut GenKillSet<Local>,
+}
+
+impl<'a, 'mir: 'a, 'tcx> Visitor<'tcx> for MoveVisitor<'a, 'mir, 'tcx> {
+    fn visit_local(&mut self, local: &Local, context: PlaceContext, loc: Location) {
+        if PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) == context {
+            let mut borrowed_locals = self.borrowed_locals.borrow_mut();
+            borrowed_locals.seek(loc);
+            if !borrowed_locals.contains(*local) {
+                self.sets.kill(*local);
+            }
+        }
+    }
+}
index 80f65a9c8d04e513ccf41a42d8c9d641caa29547..5433a9013aa851d2c7dfcd7c2ba6aac3b8ae406d 100644 (file)
@@ -17,7 +17,7 @@
 use std::path::PathBuf;
 use std::usize;
 
-pub use self::impls::{MaybeStorageLive};
+pub use self::impls::{MaybeStorageLive, RequiresStorage};
 pub use self::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
 pub use self::impls::DefinitelyInitializedPlaces;
 pub use self::impls::EverInitializedPlaces;
@@ -228,9 +228,25 @@ impl<'b, 'a, 'tcx, BD> PropagationContext<'b, 'a, 'tcx, BD>
     BD: BitDenotation<'tcx>,
 {
     fn walk_cfg(&mut self, in_out: &mut BitSet<BD::Idx>) {
-        let mut dirty_queue: WorkQueue<mir::BasicBlock> =
-            WorkQueue::with_all(self.builder.body.basic_blocks().len());
         let body = self.builder.body;
+
+        // Initialize the dirty queue in reverse post-order. This makes it more likely that the
+        // entry state for each basic block will have the effects of its predecessors applied
+        // before it is processed. In fact, for CFGs without back edges, this guarantees that
+        // dataflow will converge in exactly `N` iterations, where `N` is the number of basic
+        // blocks.
+        let mut dirty_queue: WorkQueue<mir::BasicBlock> =
+            WorkQueue::with_none(body.basic_blocks().len());
+        for (bb, _) in traversal::reverse_postorder(body) {
+            dirty_queue.insert(bb);
+        }
+
+        // Add blocks which are not reachable from START_BLOCK to the work queue. These blocks will
+        // be processed after the ones added above.
+        for bb in body.basic_blocks().indices() {
+            dirty_queue.insert(bb);
+        }
+
         while let Some(bb) = dirty_queue.pop() {
             let (on_entry, trans) = self.builder.flow_state.sets.get_mut(bb.index());
             debug_assert!(in_out.words().len() == on_entry.words().len());
@@ -344,6 +360,99 @@ fn process_basic_block(&mut self, bb: BasicBlock, flow_state: &mut Self::FlowSta
     fn body(&self) -> &'a Body<'tcx>;
 }
 
+/// Allows iterating dataflow results in a flexible and reasonably fast way.
+pub struct DataflowResultsCursor<'mir, 'tcx, BD, DR = DataflowResults<'tcx, BD>>
+where
+    BD: BitDenotation<'tcx>,
+    DR: Borrow<DataflowResults<'tcx, BD>>,
+{
+    flow_state: FlowAtLocation<'tcx, BD, DR>,
+
+    // The statement (or terminator) whose effect has been reconstructed in
+    // flow_state.
+    curr_loc: Option<Location>,
+
+    body: &'mir Body<'tcx>,
+}
+
+pub type DataflowResultsRefCursor<'mir, 'tcx, BD> =
+    DataflowResultsCursor<'mir, 'tcx, BD, &'mir DataflowResults<'tcx, BD>>;
+
+impl<'mir, 'tcx, BD, DR> DataflowResultsCursor<'mir, 'tcx, BD, DR>
+where
+    BD: BitDenotation<'tcx>,
+    DR: Borrow<DataflowResults<'tcx, BD>>,
+{
+    pub fn new(result: DR, body: &'mir Body<'tcx>) -> Self {
+        DataflowResultsCursor {
+            flow_state: FlowAtLocation::new(result),
+            curr_loc: None,
+            body,
+        }
+    }
+
+    /// Seek to the given location in MIR. This method is fast if you are
+    /// traversing your MIR statements in order.
+    ///
+    /// After calling `seek`, the current state will reflect all effects up to
+    /// and including the `before_statement_effect` of the statement at location
+    /// `loc`. The `statement_effect` of the statement at `loc` will be
+    /// available as the current effect (see e.g. `each_gen_bit`).
+    ///
+    /// If `loc.statement_index` equals the number of statements in the block,
+    /// we will reconstruct the terminator effect in the same way as described
+    /// above.
+    pub fn seek(&mut self, loc: Location) {
+        if self.curr_loc.map(|cur| loc == cur).unwrap_or(false) {
+            return;
+        }
+
+        let start_index;
+        let should_reset = match self.curr_loc {
+            None => true,
+            Some(cur)
+                if loc.block != cur.block || loc.statement_index < cur.statement_index => true,
+            _ => false,
+        };
+        if should_reset {
+            self.flow_state.reset_to_entry_of(loc.block);
+            start_index = 0;
+        } else {
+            let curr_loc = self.curr_loc.unwrap();
+            start_index = curr_loc.statement_index;
+            // Apply the effect from the last seek to the current state.
+            self.flow_state.apply_local_effect(curr_loc);
+        }
+
+        for stmt in start_index..loc.statement_index {
+            let mut stmt_loc = loc;
+            stmt_loc.statement_index = stmt;
+            self.flow_state.reconstruct_statement_effect(stmt_loc);
+            self.flow_state.apply_local_effect(stmt_loc);
+        }
+
+        if loc.statement_index == self.body[loc.block].statements.len() {
+            self.flow_state.reconstruct_terminator_effect(loc);
+        } else {
+            self.flow_state.reconstruct_statement_effect(loc);
+        }
+        self.curr_loc = Some(loc);
+    }
+
+    /// Return whether the current state contains bit `x`.
+    pub fn contains(&self, x: BD::Idx) -> bool {
+        self.flow_state.contains(x)
+    }
+
+    /// Iterate over each `gen` bit in the current effect (invoke `seek` first).
+    pub fn each_gen_bit<F>(&self, f: F)
+    where
+        F: FnMut(BD::Idx),
+    {
+        self.flow_state.each_gen_bit(f)
+    }
+}
+
 pub fn state_for_location<'tcx, T: BitDenotation<'tcx>>(loc: Location,
                                                         analysis: &T,
                                                         result: &DataflowResults<'tcx, T>,
index 4807782c66347e55b8321b84b695be61ba6de47e..618c047e77359122d214aebf0e331d595105d377 100644 (file)
@@ -331,7 +331,7 @@ struct X { x: (), }
 match was successful. If the match is irrefutable (when it cannot fail to
 match), use a regular `let`-binding instead. For instance:
 
-```compile_pass
+```
 struct Irrefutable(i32);
 let irr = Irrefutable(0);
 
@@ -360,7 +360,7 @@ struct X { x: (), }
 match was successful. If the match is irrefutable (when it cannot fail to
 match), use a regular `let`-binding inside a `loop` instead. For instance:
 
-```compile_pass,no_run
+```no_run
 struct Irrefutable(i32);
 let irr = Irrefutable(0);
 
index 94b4f6e8dd1c5cf26fcb2b8fe2542dd657336aa9..e7663ddaa9879e1726c6fb5329b70c680b0dd7d0 100644 (file)
@@ -542,7 +542,7 @@ fn make_mirror_unadjusted<'a, 'tcx>(
 
         // Now comes the rote stuff:
         hir::ExprKind::Repeat(ref v, ref count) => {
-            let def_id = cx.tcx.hir().local_def_id_from_hir_id(count.hir_id);
+            let def_id = cx.tcx.hir().local_def_id(count.hir_id);
             let substs = InternalSubsts::identity_for_item(cx.tcx.global_tcx(), def_id);
             let instance = ty::Instance::resolve(
                 cx.tcx.global_tcx(),
@@ -910,9 +910,9 @@ fn convert_path_expr<'a, 'tcx>(
         Res::Def(DefKind::ConstParam, def_id) => {
             let hir_id = cx.tcx.hir().as_local_hir_id(def_id).unwrap();
             let item_id = cx.tcx.hir().get_parent_node(hir_id);
-            let item_def_id = cx.tcx.hir().local_def_id_from_hir_id(item_id);
+            let item_def_id = cx.tcx.hir().local_def_id(item_id);
             let generics = cx.tcx.generics_of(item_def_id);
-            let local_def_id = cx.tcx.hir().local_def_id_from_hir_id(hir_id);
+            let local_def_id = cx.tcx.hir().local_def_id(hir_id);
             let index = generics.param_def_id_to_index[&local_def_id];
             let name = cx.tcx.hir().name(hir_id).as_interned_str();
             let val = ConstValue::Param(ty::ParamConst::new(index, name));
@@ -1191,7 +1191,7 @@ fn capture_upvar<'tcx>(
 ) -> ExprRef<'tcx> {
     let upvar_id = ty::UpvarId {
         var_path: ty::UpvarPath { hir_id: var_hir_id },
-        closure_expr_id: cx.tcx.hir().local_def_id_from_hir_id(closure_expr.hir_id).to_local(),
+        closure_expr_id: cx.tcx.hir().local_def_id(closure_expr.hir_id).to_local(),
     };
     let upvar_capture = cx.tables().upvar_capture(upvar_id);
     let temp_lifetime = cx.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id);
index a21d900cf5e5e2344e21bdfd95b213a4b2957adb..3d9349df5bedb3d490b4307394018180cc05be91 100644 (file)
@@ -54,7 +54,7 @@ pub struct Cx<'a, 'tcx> {
 impl<'a, 'tcx> Cx<'a, 'tcx> {
     pub fn new(infcx: &'a InferCtxt<'a, 'tcx>, src_id: hir::HirId) -> Cx<'a, 'tcx> {
         let tcx = infcx.tcx;
-        let src_def_id = tcx.hir().local_def_id_from_hir_id(src_id);
+        let src_def_id = tcx.hir().local_def_id(src_id);
         let tables = tcx.typeck_tables_of(src_def_id);
         let body_owner_kind = tcx.hir().body_owner_kind(src_id);
 
index 946d66fc91d7d21b53fd4e05a419b471b4dacc7e..c365cc2ad854416640bfbe8829e871ddbe914c60 100644 (file)
@@ -1,7 +1,7 @@
 use crate::hair::*;
 
 use rustc::hir;
-use syntax::ptr::P;
+use rustc::hir::ptr::P;
 
 pub trait ToRef {
     type Output;
index fc2951895f3fe9bd1cc2bd96cd7e8876005780b6..d356194c0034323b0c70ddca7466f8450b0fb870 100644 (file)
@@ -835,7 +835,7 @@ impl<'tcx> IntRange<'tcx> {
     fn from_ctor(tcx: TyCtxt<'tcx>, ctor: &Constructor<'tcx>) -> Option<IntRange<'tcx>> {
         // Floating-point ranges are permitted and we don't want
         // to consider them when constructing integer ranges.
-        fn is_integral<'tcx>(ty: Ty<'tcx>) -> bool {
+        fn is_integral(ty: Ty<'_>) -> bool {
             match ty.sty {
                 ty::Char | ty::Int(_) | ty::Uint(_) => true,
                 _ => false,
index ed850379af60b49a9d9faed48181bb343788aedd..915ce9f20d07d161f867616de07f81cc5b6c92e4 100644 (file)
 use rustc::hir::def::*;
 use rustc::hir::def_id::DefId;
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
+use rustc::hir::ptr::P;
 use rustc::hir::{self, Pat, PatKind};
 
 use smallvec::smallvec;
 use std::slice;
 
-use syntax::ptr::P;
 use syntax_pos::{Span, DUMMY_SP, MultiSpan};
 
-pub(crate) fn check_match<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
+pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
     let body_id = if let Some(id) = tcx.hir().as_local_hir_id(def_id) {
         tcx.hir().body_owned_by(id)
     } else {
@@ -43,7 +43,7 @@ pub(crate) fn check_match<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
     }.visit_body(tcx.hir().body(body_id));
 }
 
-fn create_e0004<'a>(sess: &'a Session, sp: Span, error_message: String) -> DiagnosticBuilder<'a> {
+fn create_e0004(sess: &Session, sp: Span, error_message: String) -> DiagnosticBuilder<'_> {
     struct_span_err!(sess, sp, E0004, "{}", &error_message)
 }
 
index cf597ce0b6319b2aca2b75ef524adbd955135e04..6ba2f587768497bf9b89e29e32569ee47227dbcb 100644 (file)
 use rustc::hir::{self, PatKind, RangeEnd};
 use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
+use rustc::hir::ptr::P;
 
 use rustc_data_structures::indexed_vec::Idx;
 
 use std::cmp::Ordering;
 use std::fmt;
 use syntax::ast;
-use syntax::ptr::P;
 use syntax::symbol::sym;
 use syntax_pos::Span;
 
index fbacdf6cd93bbf80629c9206df2a9db05788a85b..3ef525979f8c9ecce2f61480797957cc8557d081 100644 (file)
@@ -1,7 +1,7 @@
 use rustc::ty::{self, Ty, TypeAndMut};
 use rustc::ty::layout::{self, TyLayout, Size};
 use rustc::ty::adjustment::{PointerCast};
-use syntax::ast::{FloatTy, IntTy, UintTy};
+use syntax::ast::FloatTy;
 use syntax::symbol::sym;
 
 use rustc_apfloat::ieee::{Single, Double};
@@ -11,9 +11,9 @@
 };
 use rustc::mir::CastKind;
 
-use super::{InterpretCx, Machine, PlaceTy, OpTy, Immediate};
+use super::{InterpCx, Machine, PlaceTy, OpTy, Immediate, FnVal};
 
-impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
+impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     fn type_is_fat_ptr(&self, ty: Ty<'tcx>) -> bool {
         match ty.sty {
             ty::RawPtr(ty::TypeAndMut { ty, .. }) |
@@ -86,7 +86,7 @@ pub fn cast(
                             def_id,
                             substs,
                         ).ok_or_else(|| InterpError::TooGeneric.into());
-                        let fn_ptr = self.memory.create_fn_alloc(instance?);
+                        let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance?));
                         self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?;
                     }
                     _ => bug!("reify fn pointer on {:?}", src.layout.ty),
@@ -115,7 +115,7 @@ pub fn cast(
                             substs,
                             ty::ClosureKind::FnOnce,
                         );
-                        let fn_ptr = self.memory.create_fn_alloc(instance);
+                        let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance));
                         let val = Immediate::Scalar(Scalar::Ptr(fn_ptr.into()).into());
                         self.write_immediate(val, dest)?;
                     }
@@ -151,7 +151,7 @@ fn cast_scalar(
                     "Unexpected cast from type {:?}", src_layout.ty
                 );
                 match val.to_bits_or_ptr(src_layout.size, self) {
-                    Err(ptr) => self.cast_from_ptr(ptr, dest_layout.ty),
+                    Err(ptr) => self.cast_from_ptr(ptr, src_layout, dest_layout),
                     Ok(data) => self.cast_from_int(data, src_layout, dest_layout),
                 }
             }
@@ -239,17 +239,25 @@ fn cast_from_float<F>(
     fn cast_from_ptr(
         &self,
         ptr: Pointer<M::PointerTag>,
-        ty: Ty<'tcx>
+        src_layout: TyLayout<'tcx>,
+        dest_layout: TyLayout<'tcx>,
     ) -> InterpResult<'tcx, Scalar<M::PointerTag>> {
         use rustc::ty::TyKind::*;
-        match ty.sty {
+
+        match dest_layout.ty.sty {
             // Casting to a reference or fn pointer is not permitted by rustc,
             // no need to support it here.
-            RawPtr(_) |
-            Int(IntTy::Isize) |
-            Uint(UintTy::Usize) => Ok(ptr.into()),
-            Int(_) | Uint(_) => err!(ReadPointerAsBytes),
-            _ => err!(Unimplemented(format!("ptr to {:?} cast", ty))),
+            RawPtr(_) => Ok(ptr.into()),
+            Int(_) | Uint(_) => {
+                let size = self.memory.pointer_size();
+
+                match self.force_bits(Scalar::Ptr(ptr), size) {
+                    Ok(bits) => self.cast_from_int(bits, src_layout, dest_layout),
+                    Err(_) if dest_layout.size == size => Ok(ptr.into()),
+                    Err(e) => Err(e),
+                }
+            }
+            _ => bug!("invalid MIR: ptr to {:?} cast", dest_layout.ty)
         }
     }
 
index c6e762bddd4d940f169affb8dfcf01749db54002..fd5290ee0400c52f467171a4f97241d8a8fa3594 100644 (file)
@@ -26,7 +26,7 @@
     Memory, Machine
 };
 
-pub struct InterpretCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
+pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
     /// Stores the `Machine` instance.
     pub machine: M,
 
@@ -158,14 +158,14 @@ pub fn access_mut(
     }
 }
 
-impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for InterpretCx<'mir, 'tcx, M> {
+impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for InterpCx<'mir, 'tcx, M> {
     #[inline]
     fn data_layout(&self) -> &layout::TargetDataLayout {
         &self.tcx.data_layout
     }
 }
 
-impl<'mir, 'tcx, M> layout::HasTyCtxt<'tcx> for InterpretCx<'mir, 'tcx, M>
+impl<'mir, 'tcx, M> layout::HasTyCtxt<'tcx> for InterpCx<'mir, 'tcx, M>
 where
     M: Machine<'mir, 'tcx>,
 {
@@ -175,7 +175,7 @@ fn tcx(&self) -> TyCtxt<'tcx> {
     }
 }
 
-impl<'mir, 'tcx, M> layout::HasParamEnv<'tcx> for InterpretCx<'mir, 'tcx, M>
+impl<'mir, 'tcx, M> layout::HasParamEnv<'tcx> for InterpCx<'mir, 'tcx, M>
 where
     M: Machine<'mir, 'tcx>,
 {
@@ -184,7 +184,7 @@ fn param_env(&self) -> ty::ParamEnv<'tcx> {
     }
 }
 
-impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpretCx<'mir, 'tcx, M> {
+impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> {
     type Ty = Ty<'tcx>;
     type TyLayout = InterpResult<'tcx, TyLayout<'tcx>>;
 
@@ -195,13 +195,18 @@ fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
     }
 }
 
-impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
-    pub fn new(tcx: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>, machine: M) -> Self {
-        InterpretCx {
+impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
+    pub fn new(
+        tcx: TyCtxtAt<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        machine: M,
+        memory_extra: M::MemoryExtra,
+    ) -> Self {
+        InterpCx {
             machine,
             tcx,
             param_env,
-            memory: Memory::new(tcx),
+            memory: Memory::new(tcx, memory_extra),
             stack: Vec::new(),
             vtables: FxHashMap::default(),
         }
index beb5049307117c0325145a7adefde39426d8916d..cf36c10a614e5a3fa06512be1149a2017933fe26 100644 (file)
@@ -11,7 +11,7 @@
 };
 
 use super::{
-    Machine, PlaceTy, OpTy, InterpretCx, Immediate,
+    Machine, PlaceTy, OpTy, InterpCx, Immediate,
 };
 
 mod type_name;
@@ -39,7 +39,7 @@ fn numeric_intrinsic<'tcx, Tag>(
     Ok(Scalar::from_uint(bits_out, size))
 }
 
-impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
+impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Returns `true` if emulation happened.
     pub fn emulate_intrinsic(
         &mut self,
index 4eb95f20d935449e610426d1c88ef571a4edfa99..922b5e0676a194c44933eefcd8c81af01709eccb 100644 (file)
@@ -11,7 +11,7 @@
 
 use super::{
     Allocation, AllocId, InterpResult, Scalar, AllocationExtra,
-    InterpretCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory
+    InterpCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory
 };
 
 /// Whether this kind of memory is allowed to leak
@@ -67,13 +67,18 @@ pub trait Machine<'mir, 'tcx>: Sized {
     /// The `default()` is used for pointers to consts, statics, vtables and functions.
     type PointerTag: ::std::fmt::Debug + Copy + Eq + Hash + 'static;
 
+    /// Machines can define extra (non-instance) things that represent values of function pointers.
+    /// For example, Miri uses this to return a fucntion pointer from `dlsym`
+    /// that can later be called to execute the right thing.
+    type ExtraFnVal: ::std::fmt::Debug + Copy;
+
     /// Extra data stored in every call frame.
     type FrameExtra;
 
     /// Extra data stored in memory. A reference to this is available when `AllocExtra`
     /// gets initialized, so you can e.g., have an `Rc` here if there is global state you
     /// need access to in the `AllocExtra` hooks.
-    type MemoryExtra: Default;
+    type MemoryExtra;
 
     /// Extra data stored in every allocation.
     type AllocExtra: AllocationExtra<Self::PointerTag> + 'static;
@@ -95,11 +100,11 @@ pub trait Machine<'mir, 'tcx>: Sized {
     const STATIC_KIND: Option<Self::MemoryKinds>;
 
     /// Whether to enforce the validity invariant
-    fn enforce_validity(ecx: &InterpretCx<'mir, 'tcx, Self>) -> bool;
+    fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
 
     /// Called before a basic block terminator is executed.
     /// You can use this to detect endlessly running programs.
-    fn before_terminator(ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx>;
+    fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx>;
 
     /// Entry point to all function calls.
     ///
@@ -112,17 +117,27 @@ pub trait Machine<'mir, 'tcx>: Sized {
     /// Passing `dest`and `ret` in the same `Option` proved very annoying when only one of them
     /// was used.
     fn find_fn(
-        ecx: &mut InterpretCx<'mir, 'tcx, Self>,
+        ecx: &mut InterpCx<'mir, 'tcx, Self>,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx, Self::PointerTag>],
         dest: Option<PlaceTy<'tcx, Self::PointerTag>>,
         ret: Option<mir::BasicBlock>,
     ) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>>;
 
+    /// Execute `fn_val`.  it is the hook's responsibility to advance the instruction
+    /// pointer as appropriate.
+    fn call_extra_fn(
+        ecx: &mut InterpCx<'mir, 'tcx, Self>,
+        fn_val: Self::ExtraFnVal,
+        args: &[OpTy<'tcx, Self::PointerTag>],
+        dest: Option<PlaceTy<'tcx, Self::PointerTag>>,
+        ret: Option<mir::BasicBlock>,
+    ) -> InterpResult<'tcx>;
+
     /// Directly process an intrinsic without pushing a stack frame.
     /// If this returns successfully, the engine will take care of jumping to the next block.
     fn call_intrinsic(
-        ecx: &mut InterpretCx<'mir, 'tcx, Self>,
+        ecx: &mut InterpCx<'mir, 'tcx, Self>,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx, Self::PointerTag>],
         dest: PlaceTy<'tcx, Self::PointerTag>,
@@ -145,7 +160,7 @@ fn find_foreign_static(
     ///
     /// Returns a (value, overflowed) pair if the operation succeeded
     fn ptr_op(
-        ecx: &InterpretCx<'mir, 'tcx, Self>,
+        ecx: &InterpCx<'mir, 'tcx, Self>,
         bin_op: mir::BinOp,
         left: ImmTy<'tcx, Self::PointerTag>,
         right: ImmTy<'tcx, Self::PointerTag>,
@@ -153,7 +168,7 @@ fn ptr_op(
 
     /// Heap allocations via the `box` keyword.
     fn box_alloc(
-        ecx: &mut InterpretCx<'mir, 'tcx, Self>,
+        ecx: &mut InterpCx<'mir, 'tcx, Self>,
         dest: PlaceTy<'tcx, Self::PointerTag>,
     ) -> InterpResult<'tcx>;
 
@@ -193,7 +208,7 @@ fn tag_static_base_pointer(
     /// Executes a retagging operation
     #[inline]
     fn retag(
-        _ecx: &mut InterpretCx<'mir, 'tcx, Self>,
+        _ecx: &mut InterpCx<'mir, 'tcx, Self>,
         _kind: mir::RetagKind,
         _place: PlaceTy<'tcx, Self::PointerTag>,
     ) -> InterpResult<'tcx> {
@@ -201,11 +216,11 @@ fn retag(
     }
 
     /// Called immediately before a new stack frame got pushed
-    fn stack_push(ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx, Self::FrameExtra>;
+    fn stack_push(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx, Self::FrameExtra>;
 
     /// Called immediately after a stack frame gets popped
     fn stack_pop(
-        ecx: &mut InterpretCx<'mir, 'tcx, Self>,
+        ecx: &mut InterpCx<'mir, 'tcx, Self>,
         extra: Self::FrameExtra,
     ) -> InterpResult<'tcx>;
 
index f76107078807e300c0b4f136ad2bf73bc7b0780c..8607a7c3f1ec3568c695a7c9aec32615021a26d1 100644 (file)
@@ -54,6 +54,26 @@ pub enum AllocCheck {
     MaybeDead,
 }
 
+/// The value of a function pointer.
+#[derive(Debug, Copy, Clone)]
+pub enum FnVal<'tcx, Other> {
+    Instance(Instance<'tcx>),
+    Other(Other),
+}
+
+impl<'tcx, Other> FnVal<'tcx, Other> {
+    pub fn as_instance(self) -> InterpResult<'tcx, Instance<'tcx>> {
+        match self {
+            FnVal::Instance(instance) =>
+                Ok(instance),
+            FnVal::Other(_) =>
+                err!(MachineError(
+                    format!("Expected instance function pointer, got 'other' pointer")
+                )),
+        }
+    }
+}
+
 // `Memory` has to depend on the `Machine` because some of its operations
 // (e.g., `get`) call a `Machine` hook.
 pub struct Memory<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
@@ -69,16 +89,20 @@ pub struct Memory<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
     // FIXME: this should not be public, but interning currently needs access to it
     pub(super) alloc_map: M::MemoryMap,
 
+    /// Map for "extra" function pointers.
+    extra_fn_ptr_map: FxHashMap<AllocId, M::ExtraFnVal>,
+
     /// To be able to compare pointers with NULL, and to check alignment for accesses
     /// to ZSTs (where pointers may dangle), we keep track of the size even for allocations
     /// that do not exist any more.
+    // FIXME: this should not be public, but interning currently needs access to it
     pub(super) dead_alloc_map: FxHashMap<AllocId, (Size, Align)>,
 
     /// Extra data added by the machine.
     pub extra: M::MemoryExtra,
 
     /// Lets us implement `HasDataLayout`, which is awfully convenient.
-    pub(super) tcx: TyCtxtAt<'tcx>,
+    pub tcx: TyCtxtAt<'tcx>,
 }
 
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for Memory<'mir, 'tcx, M> {
@@ -98,6 +122,7 @@ impl<'mir, 'tcx, M> Clone for Memory<'mir, 'tcx, M>
     fn clone(&self) -> Self {
         Memory {
             alloc_map: self.alloc_map.clone(),
+            extra_fn_ptr_map: self.extra_fn_ptr_map.clone(),
             dead_alloc_map: self.dead_alloc_map.clone(),
             extra: (),
             tcx: self.tcx,
@@ -106,11 +131,12 @@ fn clone(&self) -> Self {
 }
 
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
-    pub fn new(tcx: TyCtxtAt<'tcx>) -> Self {
+    pub fn new(tcx: TyCtxtAt<'tcx>, extra: M::MemoryExtra) -> Self {
         Memory {
             alloc_map: M::MemoryMap::default(),
+            extra_fn_ptr_map: FxHashMap::default(),
             dead_alloc_map: FxHashMap::default(),
-            extra: M::MemoryExtra::default(),
+            extra,
             tcx,
         }
     }
@@ -120,8 +146,21 @@ pub fn tag_static_base_pointer(&self, ptr: Pointer) -> Pointer<M::PointerTag> {
         ptr.with_tag(M::tag_static_base_pointer(ptr.alloc_id, &self))
     }
 
-    pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> Pointer<M::PointerTag> {
-        let id = self.tcx.alloc_map.lock().create_fn_alloc(instance);
+    pub fn create_fn_alloc(
+        &mut self,
+        fn_val: FnVal<'tcx, M::ExtraFnVal>,
+    ) -> Pointer<M::PointerTag>
+    {
+        let id = match fn_val {
+            FnVal::Instance(instance) => self.tcx.alloc_map.lock().create_fn_alloc(instance),
+            FnVal::Other(extra) => {
+                // FIXME(RalfJung): Should we have a cache here?
+                let id = self.tcx.alloc_map.lock().reserve();
+                let old = self.extra_fn_ptr_map.insert(id, extra);
+                assert!(old.is_none());
+                id
+            }
+        };
         self.tag_static_base_pointer(Pointer::from(id))
     }
 
@@ -158,8 +197,7 @@ pub fn allocate_with(
     pub fn reallocate(
         &mut self,
         ptr: Pointer<M::PointerTag>,
-        old_size: Size,
-        old_align: Align,
+        old_size_and_align: Option<(Size, Align)>,
         new_size: Size,
         new_align: Align,
         kind: MemoryKind<M::MemoryKinds>,
@@ -171,15 +209,19 @@ pub fn reallocate(
         // For simplicities' sake, we implement reallocate as "alloc, copy, dealloc".
         // This happens so rarely, the perf advantage is outweighed by the maintenance cost.
         let new_ptr = self.allocate(new_size, new_align, kind);
+        let old_size = match old_size_and_align {
+            Some((size, _align)) => size,
+            None => Size::from_bytes(self.get(ptr.alloc_id)?.bytes.len() as u64),
+        };
         self.copy(
             ptr.into(),
-            old_align,
+            Align::from_bytes(1).unwrap(), // old_align anyway gets checked below by `deallocate`
             new_ptr.into(),
             new_align,
             old_size.min(new_size),
             /*nonoverlapping*/ true,
         )?;
-        self.deallocate(ptr, Some((old_size, old_align)), kind)?;
+        self.deallocate(ptr, old_size_and_align, kind)?;
 
         Ok(new_ptr)
     }
@@ -198,7 +240,7 @@ pub fn deallocate_local(&mut self, ptr: Pointer<M::PointerTag>) -> InterpResult<
     pub fn deallocate(
         &mut self,
         ptr: Pointer<M::PointerTag>,
-        size_and_align: Option<(Size, Align)>,
+        old_size_and_align: Option<(Size, Align)>,
         kind: MemoryKind<M::MemoryKinds>,
     ) -> InterpResult<'tcx> {
         trace!("deallocating: {}", ptr.alloc_id);
@@ -232,7 +274,7 @@ pub fn deallocate(
                 format!("{:?}", kind),
             ));
         }
-        if let Some((size, align)) = size_and_align {
+        if let Some((size, align)) = old_size_and_align {
             if size.bytes() != alloc.bytes.len() as u64 || align != alloc.align {
                 let bytes = Size::from_bytes(alloc.bytes.len() as u64);
                 return err!(IncorrectAllocationInformation(size,
@@ -492,56 +534,65 @@ pub fn get_size_and_align(
         id: AllocId,
         liveness: AllocCheck,
     ) -> InterpResult<'static, (Size, Align)> {
+        // Regular allocations.
         if let Ok(alloc) = self.get(id) {
             return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align));
         }
-        // can't do this in the match argument, we may get cycle errors since the lock would get
-        // dropped after the match.
+        // Function pointers.
+        if let Ok(_) = self.get_fn_alloc(id) {
+            return if let AllocCheck::Dereferencable = liveness {
+                // The caller requested no function pointers.
+                err!(DerefFunctionPointer)
+            } else {
+                Ok((Size::ZERO, Align::from_bytes(1).unwrap()))
+            };
+        }
+        // Foreign statics.
+        // Can't do this in the match argument, we may get cycle errors since the lock would
+        // be held throughout the match.
         let alloc = self.tcx.alloc_map.lock().get(id);
-        // Could also be a fn ptr or extern static
         match alloc {
-            Some(GlobalAlloc::Function(..)) => {
-                if let AllocCheck::Dereferencable = liveness {
-                    // The caller requested no function pointers.
-                    err!(DerefFunctionPointer)
-                } else {
-                    Ok((Size::ZERO, Align::from_bytes(1).unwrap()))
-                }
-            }
-            // `self.get` would also work, but can cause cycles if a static refers to itself
             Some(GlobalAlloc::Static(did)) => {
-                // The only way `get` couldn't have worked here is if this is an extern static
                 assert!(self.tcx.is_foreign_item(did));
                 // Use size and align of the type
                 let ty = self.tcx.type_of(did);
                 let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
-                Ok((layout.size, layout.align.abi))
+                return Ok((layout.size, layout.align.abi));
             }
-            _ => {
-                if let Ok(alloc) = self.get(id) {
-                    Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align))
-                }
-                else if let AllocCheck::MaybeDead = liveness {
-                    // Deallocated pointers are allowed, we should be able to find
-                    // them in the map.
-                    Ok(*self.dead_alloc_map.get(&id)
-                        .expect("deallocated pointers should all be recorded in `dead_alloc_map`"))
-                } else {
-                    err!(DanglingPointerDeref)
-                }
-            },
+            _ => {}
+        }
+        // The rest must be dead.
+        if let AllocCheck::MaybeDead = liveness {
+            // Deallocated pointers are allowed, we should be able to find
+            // them in the map.
+            Ok(*self.dead_alloc_map.get(&id)
+                .expect("deallocated pointers should all be recorded in `dead_alloc_map`"))
+        } else {
+            err!(DanglingPointerDeref)
         }
     }
 
-    pub fn get_fn(&self, ptr: Pointer<M::PointerTag>) -> InterpResult<'tcx, Instance<'tcx>> {
+    fn get_fn_alloc(&self, id: AllocId) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> {
+        trace!("reading fn ptr: {}", id);
+        if let Some(extra) = self.extra_fn_ptr_map.get(&id) {
+            Ok(FnVal::Other(*extra))
+        } else {
+            match self.tcx.alloc_map.lock().get(id) {
+                Some(GlobalAlloc::Function(instance)) => Ok(FnVal::Instance(instance)),
+                _ => Err(InterpError::ExecuteMemory.into()),
+            }
+        }
+    }
+
+    pub fn get_fn(
+        &self,
+        ptr: Scalar<M::PointerTag>,
+    ) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> {
+        let ptr = self.force_ptr(ptr)?; // We definitely need a pointer value.
         if ptr.offset.bytes() != 0 {
             return err!(InvalidFunctionPointer);
         }
-        trace!("reading fn ptr: {}", ptr.alloc_id);
-        match self.tcx.alloc_map.lock().get(ptr.alloc_id) {
-            Some(GlobalAlloc::Function(instance)) => Ok(instance),
-            _ => Err(InterpError::ExecuteMemory.into()),
-        }
+        self.get_fn_alloc(ptr.alloc_id)
     }
 
     pub fn mark_immutable(&mut self, id: AllocId) -> InterpResult<'tcx> {
index 259bd6af0d5d4fe68181f01402b457fe172c839f..45d24347e4efd45618c3a5ff2eb41b80beefc01c 100644 (file)
 pub use rustc::mir::interpret::*; // have all the `interpret` symbols in one place: here
 
 pub use self::eval_context::{
-    InterpretCx, Frame, StackPopCleanup, LocalState, LocalValue,
+    InterpCx, Frame, StackPopCleanup, LocalState, LocalValue,
 };
 
 pub use self::place::{Place, PlaceTy, MemPlace, MPlaceTy};
 
-pub use self::memory::{Memory, MemoryKind, AllocCheck};
+pub use self::memory::{Memory, MemoryKind, AllocCheck, FnVal};
 
 pub use self::machine::{Machine, AllocMap, MayLeak};
 
index c72078fa89cd27e07bf0ec8c6a2bf265696b1138..68c9047f7b70842758c4b0484ac805532818e929 100644 (file)
@@ -15,7 +15,7 @@
     sign_extend, truncate,
 };
 use super::{
-    InterpretCx, Machine,
+    InterpCx, Machine,
     MemPlace, MPlaceTy, PlaceTy, Place,
 };
 pub use rustc::mir::interpret::ScalarMaybeUndef;
@@ -213,7 +213,7 @@ pub(super) fn from_known_layout<'tcx>(
     }
 }
 
-impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
+impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Try reading an immediate in memory; this is interesting particularly for `ScalarPair`.
     /// Returns `None` if the layout does not permit loading this as a value.
     fn try_read_immediate_from_mplace(
index 029a440f34e7270c41da05c3b97d0643427b2427..20180c9cba542423aeaa53acc00b77e23c245692 100644 (file)
@@ -4,10 +4,10 @@
 use rustc_apfloat::Float;
 use rustc::mir::interpret::{InterpResult, Scalar};
 
-use super::{InterpretCx, PlaceTy, Immediate, Machine, ImmTy};
+use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy};
 
 
-impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
+impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Applies the binary operation `op` to the two operands and writes a tuple of the result
     /// and a boolean signifying the potential overflow to the destination.
     pub fn binop_with_overflow(
@@ -36,7 +36,7 @@ pub fn binop_ignore_overflow(
     }
 }
 
-impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
+impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     fn binary_char_op(
         &self,
         bin_op: mir::BinOp,
index 1351b5bb8bd88a6684ca967e69559cd7ba588111..4f3727fbd8d9af00feeedb6f0a30b2eb28f0881d 100644 (file)
@@ -13,7 +13,7 @@
 
 use super::{
     GlobalId, AllocId, Allocation, Scalar, InterpResult, Pointer, PointerArithmetic,
-    InterpretCx, Machine, AllocMap, AllocationExtra,
+    InterpCx, Machine, AllocMap, AllocationExtra,
     RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue
 };
 
@@ -290,7 +290,7 @@ pub fn to_mem_place(self) -> MPlaceTy<'tcx, Tag> {
 }
 
 // separating the pointer tag for `impl Trait`, see https://github.com/rust-lang/rust/issues/54385
-impl<'mir, 'tcx, Tag, M> InterpretCx<'mir, 'tcx, M>
+impl<'mir, 'tcx, Tag, M> InterpCx<'mir, 'tcx, M>
 where
     // FIXME: Working around https://github.com/rust-lang/rust/issues/54385
     Tag: ::std::fmt::Debug + Copy + Eq + Hash + 'static,
@@ -583,7 +583,7 @@ pub(super) fn eval_static_to_mplace(
                 // global table but not in its local memory: It calls back into tcx through
                 // a query, triggering the CTFE machinery to actually turn this lazy reference
                 // into a bunch of bytes.  IOW, statics are evaluated with CTFE even when
-                // this InterpretCx uses another Machine (e.g., in miri).  This is what we
+                // this InterpCx uses another Machine (e.g., in miri).  This is what we
                 // want!  This way, computing statics works consistently between codegen
                 // and miri: They use the same query to eventually obtain a `ty::Const`
                 // and use that for further computation.
index 2f99973b90d4a784331004d697de927a9a9c1a02..dc5302eb18fc4b2d1ac407b9afd805a55edfc37c 100644 (file)
@@ -1,4 +1,4 @@
-//! This module contains the `InterpretCx` methods for executing a single step of the interpreter.
+//! This module contains the `InterpCx` methods for executing a single step of the interpreter.
 //!
 //! The main entry point is the `step` method.
 
@@ -6,7 +6,7 @@
 use rustc::ty::layout::LayoutOf;
 use rustc::mir::interpret::{InterpResult, Scalar, PointerArithmetic};
 
-use super::{InterpretCx, Machine};
+use super::{InterpCx, Machine};
 
 /// Classify whether an operator is "left-homogeneous", i.e., the LHS has the
 /// same type as the result.
@@ -35,7 +35,7 @@ fn binop_right_homogeneous(op: mir::BinOp) -> bool {
     }
 }
 
-impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
+impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     pub fn run(&mut self) -> InterpResult<'tcx> {
         while self.step()? {}
         Ok(())
index 13baf245d10fbeb865097e86e39419978a0823e3..0ab428628de688d12ee78c08ee383225453ad839 100644 (file)
@@ -6,12 +6,12 @@
 use syntax::source_map::Span;
 use rustc_target::spec::abi::Abi;
 
-use rustc::mir::interpret::{InterpResult, PointerArithmetic, InterpError, Scalar};
 use super::{
-    InterpretCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup
+    InterpResult, PointerArithmetic, InterpError, Scalar,
+    InterpCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal,
 };
 
-impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
+impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     #[inline]
     pub fn goto_block(&mut self, target: Option<mir::BasicBlock>) -> InterpResult<'tcx> {
         if let Some(target) = target {
@@ -76,16 +76,16 @@ pub(super) fn eval_terminator(
                 };
 
                 let func = self.eval_operand(func, None)?;
-                let (fn_def, abi) = match func.layout.ty.sty {
+                let (fn_val, abi) = match func.layout.ty.sty {
                     ty::FnPtr(sig) => {
                         let caller_abi = sig.abi();
-                        let fn_ptr = self.force_ptr(self.read_scalar(func)?.not_undef()?)?;
-                        let instance = self.memory.get_fn(fn_ptr)?;
-                        (instance, caller_abi)
+                        let fn_ptr = self.read_scalar(func)?.not_undef()?;
+                        let fn_val = self.memory.get_fn(fn_ptr)?;
+                        (fn_val, caller_abi)
                     }
                     ty::FnDef(def_id, substs) => {
                         let sig = func.layout.ty.fn_sig(*self.tcx);
-                        (self.resolve(def_id, substs)?, sig.abi())
+                        (FnVal::Instance(self.resolve(def_id, substs)?), sig.abi())
                     },
                     _ => {
                         let msg = format!("can't handle callee of type {:?}", func.layout.ty);
@@ -94,7 +94,7 @@ pub(super) fn eval_terminator(
                 };
                 let args = self.eval_operands(args)?;
                 self.eval_fn_call(
-                    fn_def,
+                    fn_val,
                     terminator.source_info.span,
                     abi,
                     &args[..],
@@ -228,14 +228,21 @@ fn pass_argument(
     /// Call this function -- pushing the stack frame and initializing the arguments.
     fn eval_fn_call(
         &mut self,
-        instance: ty::Instance<'tcx>,
+        fn_val: FnVal<'tcx, M::ExtraFnVal>,
         span: Span,
         caller_abi: Abi,
         args: &[OpTy<'tcx, M::PointerTag>],
         dest: Option<PlaceTy<'tcx, M::PointerTag>>,
         ret: Option<mir::BasicBlock>,
     ) -> InterpResult<'tcx> {
-        trace!("eval_fn_call: {:#?}", instance);
+        trace!("eval_fn_call: {:#?}", fn_val);
+
+        let instance = match fn_val {
+            FnVal::Instance(instance) => instance,
+            FnVal::Other(extra) => {
+                return M::call_extra_fn(self, extra, args, dest, ret);
+            }
+        };
 
         match instance.def {
             ty::InstanceDef::Intrinsic(..) => {
@@ -431,8 +438,8 @@ fn eval_fn_call(
                     self.tcx.data_layout.pointer_align.abi,
                 )?.expect("cannot be a ZST");
                 let fn_ptr = self.memory.get(vtable_slot.alloc_id)?
-                    .read_ptr_sized(self, vtable_slot)?.to_ptr()?;
-                let instance = self.memory.get_fn(fn_ptr)?;
+                    .read_ptr_sized(self, vtable_slot)?.not_undef()?;
+                let drop_fn = self.memory.get_fn(fn_ptr)?;
 
                 // `*mut receiver_place.layout.ty` is almost the layout that we
                 // want for args[0]: We have to project to field 0 because we want
@@ -447,7 +454,7 @@ fn eval_fn_call(
                 });
                 trace!("Patched self operand to {:#?}", args[0]);
                 // recurse with concrete function
-                self.eval_fn_call(instance, span, caller_abi, &args, dest, ret)
+                self.eval_fn_call(drop_fn, span, caller_abi, &args, dest, ret)
             }
         }
     }
@@ -482,7 +489,7 @@ fn drop_in_place(
         let dest = MPlaceTy::dangling(self.layout_of(ty)?, self);
 
         self.eval_fn_call(
-            instance,
+            FnVal::Instance(instance),
             span,
             Abi::Rust,
             &[arg.into()],
index 5d2f268d2663915efb2ce318e6a9b97ded635ea4..e7363f6876c28ce7abeb9a2370d4eeb60fb685e0 100644 (file)
@@ -2,9 +2,9 @@
 use rustc::ty::layout::{Size, Align, LayoutOf};
 use rustc::mir::interpret::{Scalar, Pointer, InterpResult, PointerArithmetic};
 
-use super::{InterpretCx, InterpError, Machine, MemoryKind};
+use super::{InterpCx, InterpError, Machine, MemoryKind, FnVal};
 
-impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
+impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Creates a dynamic vtable for the given type and vtable origin. This is used only for
     /// objects.
     ///
@@ -56,7 +56,7 @@ pub fn get_vtable(
         let tcx = &*self.tcx;
 
         let drop = Instance::resolve_drop_in_place(*tcx, ty);
-        let drop = self.memory.create_fn_alloc(drop);
+        let drop = self.memory.create_fn_alloc(FnVal::Instance(drop));
 
         // no need to do any alignment checks on the memory accesses below, because we know the
         // allocation is correctly aligned as we created it above. Also we're only offsetting by
@@ -84,7 +84,7 @@ pub fn get_vtable(
                     def_id,
                     substs,
                 ).ok_or_else(|| InterpError::TooGeneric)?;
-                let fn_ptr = self.memory.create_fn_alloc(instance);
+                let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance));
                 let method_ptr = vtable.offset(ptr_size * (3 + i as u64), self)?;
                 self.memory
                     .get_mut(method_ptr.alloc_id)?
@@ -112,8 +112,10 @@ pub fn read_drop_type_from_vtable(
         let drop_fn = self.memory
             .get(vtable.alloc_id)?
             .read_ptr_sized(self, vtable)?
-            .to_ptr()?;
-        let drop_instance = self.memory.get_fn(drop_fn)?;
+            .not_undef()?;
+        // We *need* an instance here, no other kind of function value, to be able
+        // to determine the type.
+        let drop_instance = self.memory.get_fn(drop_fn)?.as_instance()?;
         trace!("Found drop fn: {:?}", drop_instance);
         let fn_sig = drop_instance.ty(*self.tcx).fn_sig(*self.tcx);
         let fn_sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, &fn_sig);
index b2a159fef59c616341ca6a7e850edd638237664f..34892f5b8ca01bda2f702e94523609fdf6e423f5 100644 (file)
@@ -6,14 +6,12 @@
 use rustc::ty::layout::{self, TyLayout, LayoutOf, VariantIdx};
 use rustc::ty;
 use rustc_data_structures::fx::FxHashSet;
-use rustc::mir::interpret::{
-    GlobalAlloc, InterpResult, InterpError,
-};
 
 use std::hash::Hash;
 
 use super::{
-    OpTy, Machine, InterpretCx, ValueVisitor, MPlaceTy,
+    GlobalAlloc, InterpResult, InterpError,
+    OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy,
 };
 
 macro_rules! validation_failure {
@@ -153,15 +151,16 @@ fn wrapping_range_format(r: &RangeInclusive<u128>, max_hi: u128) -> String {
     debug_assert!(hi <= max_hi);
     if lo > hi {
         format!("less or equal to {}, or greater or equal to {}", hi, lo)
+    } else if lo == hi {
+        format!("equal to {}", lo)
+    } else if lo == 0 {
+        debug_assert!(hi < max_hi, "should not be printing if the range covers everything");
+        format!("less or equal to {}", hi)
+    } else if hi == max_hi {
+        debug_assert!(lo > 0, "should not be printing if the range covers everything");
+        format!("greater or equal to {}", lo)
     } else {
-        if lo == 0 {
-            debug_assert!(hi < max_hi, "should not be printing if the range covers everything");
-            format!("less or equal to {}", hi)
-        } else if hi == max_hi {
-            format!("greater or equal to {}", lo)
-        } else {
-            format!("in the range {:?}", r)
-        }
+        format!("in the range {:?}", r)
     }
 }
 
@@ -174,7 +173,7 @@ struct ValidityVisitor<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> {
         MPlaceTy<'tcx, M::PointerTag>,
         Vec<PathElem>,
     >>,
-    ecx: &'rt InterpretCx<'mir, 'tcx, M>,
+    ecx: &'rt InterpCx<'mir, 'tcx, M>,
 }
 
 impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M> {
@@ -259,7 +258,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
     type V = OpTy<'tcx, M::PointerTag>;
 
     #[inline(always)]
-    fn ecx(&self) -> &InterpretCx<'mir, 'tcx, M> {
+    fn ecx(&self) -> &InterpCx<'mir, 'tcx, M> {
         &self.ecx
     }
 
@@ -457,10 +456,10 @@ fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> InterpResult<
             }
             ty::FnPtr(_sig) => {
                 let value = value.to_scalar_or_undef();
-                let ptr = try_validation!(value.to_ptr(),
-                    value, self.path, "a pointer");
-                let _fn = try_validation!(self.ecx.memory.get_fn(ptr),
-                    value, self.path, "a function pointer");
+                let _fn = try_validation!(
+                    value.not_undef().and_then(|ptr| self.ecx.memory.get_fn(ptr)),
+                    value, self.path, "a function pointer"
+                );
                 // FIXME: Check if the signature matches
             }
             // This should be all the primitive types
@@ -504,20 +503,18 @@ fn visit_scalar(
                 if lo == 1 && hi == max_hi {
                     // Only NULL is the niche.  So make sure the ptr is NOT NULL.
                     if self.ecx.memory.ptr_may_be_null(ptr) {
-                        // These conditions are just here to improve the diagnostics so we can
-                        // differentiate between null pointers and dangling pointers
-                        if self.ref_tracking_for_consts.is_some() &&
-                            self.ecx.memory.get(ptr.alloc_id).is_err() &&
-                            self.ecx.memory.get_fn(ptr).is_err() {
-                            return validation_failure!(
-                                "encountered dangling pointer", self.path
-                            );
-                        }
-                        return validation_failure!("a potentially NULL pointer", self.path);
+                        return validation_failure!(
+                            "a potentially NULL pointer",
+                            self.path,
+                            format!(
+                                "something that cannot possibly fail to be {}",
+                                wrapping_range_format(&layout.valid_range, max_hi)
+                            )
+                        );
                     }
                     return Ok(());
                 } else {
-                    // Conservatively, we reject, because the pointer *could* have this
+                    // Conservatively, we reject, because the pointer *could* have a bad
                     // value.
                     return validation_failure!(
                         "a pointer",
@@ -628,7 +625,7 @@ fn visit_aggregate(
     }
 }
 
-impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
+impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// This function checks the data at `op`. `op` is assumed to cover valid memory if it
     /// is an indirect operand.
     /// It will error if the bits at the destination do not match the ones described by the layout.
index d04dc3ab37ed3e4b83bbfed8d3b35ad887c82c18..783d2522637352977299bba19f493ff3a9b105f7 100644 (file)
@@ -8,7 +8,7 @@
 };
 
 use super::{
-    Machine, InterpretCx, MPlaceTy, OpTy,
+    Machine, InterpCx, MPlaceTy, OpTy,
 };
 
 // A thing that we can project into, and that has a layout.
@@ -21,7 +21,7 @@ pub trait Value<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Copy {
     /// Makes this into an `OpTy`.
     fn to_op(
         self,
-        ecx: &InterpretCx<'mir, 'tcx, M>,
+        ecx: &InterpCx<'mir, 'tcx, M>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>>;
 
     /// Creates this from an `MPlaceTy`.
@@ -30,14 +30,14 @@ fn to_op(
     /// Projects to the given enum variant.
     fn project_downcast(
         self,
-        ecx: &InterpretCx<'mir, 'tcx, M>,
+        ecx: &InterpCx<'mir, 'tcx, M>,
         variant: VariantIdx,
     ) -> InterpResult<'tcx, Self>;
 
     /// Projects to the n-th field.
     fn project_field(
         self,
-        ecx: &InterpretCx<'mir, 'tcx, M>,
+        ecx: &InterpCx<'mir, 'tcx, M>,
         field: u64,
     ) -> InterpResult<'tcx, Self>;
 }
@@ -53,7 +53,7 @@ fn layout(&self) -> TyLayout<'tcx> {
     #[inline(always)]
     fn to_op(
         self,
-        _ecx: &InterpretCx<'mir, 'tcx, M>,
+        _ecx: &InterpCx<'mir, 'tcx, M>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
         Ok(self)
     }
@@ -66,7 +66,7 @@ fn from_mem_place(mplace: MPlaceTy<'tcx, M::PointerTag>) -> Self {
     #[inline(always)]
     fn project_downcast(
         self,
-        ecx: &InterpretCx<'mir, 'tcx, M>,
+        ecx: &InterpCx<'mir, 'tcx, M>,
         variant: VariantIdx,
     ) -> InterpResult<'tcx, Self> {
         ecx.operand_downcast(self, variant)
@@ -75,7 +75,7 @@ fn project_downcast(
     #[inline(always)]
     fn project_field(
         self,
-        ecx: &InterpretCx<'mir, 'tcx, M>,
+        ecx: &InterpCx<'mir, 'tcx, M>,
         field: u64,
     ) -> InterpResult<'tcx, Self> {
         ecx.operand_field(self, field)
@@ -91,7 +91,7 @@ fn layout(&self) -> TyLayout<'tcx> {
     #[inline(always)]
     fn to_op(
         self,
-        _ecx: &InterpretCx<'mir, 'tcx, M>,
+        _ecx: &InterpCx<'mir, 'tcx, M>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
         Ok(self.into())
     }
@@ -104,7 +104,7 @@ fn from_mem_place(mplace: MPlaceTy<'tcx, M::PointerTag>) -> Self {
     #[inline(always)]
     fn project_downcast(
         self,
-        ecx: &InterpretCx<'mir, 'tcx, M>,
+        ecx: &InterpCx<'mir, 'tcx, M>,
         variant: VariantIdx,
     ) -> InterpResult<'tcx, Self> {
         ecx.mplace_downcast(self, variant)
@@ -113,7 +113,7 @@ fn project_downcast(
     #[inline(always)]
     fn project_field(
         self,
-        ecx: &InterpretCx<'mir, 'tcx, M>,
+        ecx: &InterpCx<'mir, 'tcx, M>,
         field: u64,
     ) -> InterpResult<'tcx, Self> {
         ecx.mplace_field(self, field)
@@ -126,9 +126,9 @@ macro_rules! make_value_visitor {
         pub trait $visitor_trait_name<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>: Sized {
             type V: Value<'mir, 'tcx, M>;
 
-            /// The visitor must have an `InterpretCx` in it.
+            /// The visitor must have an `InterpCx` in it.
             fn ecx(&$($mutability)? self)
-                -> &$($mutability)? InterpretCx<'mir, 'tcx, M>;
+                -> &$($mutability)? InterpCx<'mir, 'tcx, M>;
 
             // Recursive actions, ready to be overloaded.
             /// Visits the given value, dispatching as appropriate to more specialized visitors.
index cb02e1a778c93af78f38da3bc6ed78d3db92564e..4a80534503a5d017bb00b435f0b8b82f2035114e 100644 (file)
 #![feature(slice_concat_ext)]
 #![feature(trusted_len)]
 #![feature(try_blocks)]
+#![feature(mem_take)]
 
 #![recursion_limit="256"]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #[macro_use] extern crate log;
index bb2738d5aa4a32437ff4898e99b7109d2a7a4a54..da8fdb5082a8c21d15f43c9e9368248983a67caa 100644 (file)
@@ -281,10 +281,10 @@ pub fn iter_accesses<F>(&self, mut f: F)
     }
 }
 
-pub fn collect_crate_mono_items<'tcx>(
-    tcx: TyCtxt<'tcx>,
+pub fn collect_crate_mono_items(
+    tcx: TyCtxt<'_>,
     mode: MonoItemCollectionMode,
-) -> (FxHashSet<MonoItem<'tcx>>, InliningMap<'tcx>) {
+) -> (FxHashSet<MonoItem<'_>>, InliningMap<'_>) {
     let roots = time(tcx.sess, "collecting roots", || {
         collect_roots(tcx, mode)
     });
@@ -315,7 +315,7 @@ pub fn collect_crate_mono_items<'tcx>(
 
 // Find all non-generic items by walking the HIR. These items serve as roots to
 // start monomorphizing from.
-fn collect_roots<'tcx>(tcx: TyCtxt<'tcx>, mode: MonoItemCollectionMode) -> Vec<MonoItem<'tcx>> {
+fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec<MonoItem<'_>> {
     debug!("Collecting roots");
     let mut roots = Vec::new();
 
@@ -912,7 +912,7 @@ fn find_vtable_types_for_unsizing<'tcx>(
     }
 }
 
-fn create_fn_mono_item<'tcx>(instance: Instance<'tcx>) -> MonoItem<'tcx> {
+fn create_fn_mono_item(instance: Instance<'_>) -> MonoItem<'_> {
     debug!("create_fn_mono_item(instance={})", instance);
     MonoItem::Fn(instance)
 }
@@ -989,7 +989,7 @@ fn visit_item(&mut self, item: &'v hir::Item) {
             hir::ItemKind::Union(_, ref generics) => {
                 if generics.params.is_empty() {
                     if self.mode == MonoItemCollectionMode::Eager {
-                        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+                        let def_id = self.tcx.hir().local_def_id(item.hir_id);
                         debug!("RootCollector: ADT drop-glue for {}",
                                def_id_to_string(self.tcx, def_id));
 
@@ -1001,11 +1001,11 @@ fn visit_item(&mut self, item: &'v hir::Item) {
             hir::ItemKind::GlobalAsm(..) => {
                 debug!("RootCollector: ItemKind::GlobalAsm({})",
                        def_id_to_string(self.tcx,
-                                        self.tcx.hir().local_def_id_from_hir_id(item.hir_id)));
+                                        self.tcx.hir().local_def_id(item.hir_id)));
                 self.output.push(MonoItem::GlobalAsm(item.hir_id));
             }
             hir::ItemKind::Static(..) => {
-                let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+                let def_id = self.tcx.hir().local_def_id(item.hir_id);
                 debug!("RootCollector: ItemKind::Static({})",
                        def_id_to_string(self.tcx, def_id));
                 self.output.push(MonoItem::Static(def_id));
@@ -1015,7 +1015,7 @@ fn visit_item(&mut self, item: &'v hir::Item) {
                 // actually used somewhere. Just declaring them is insufficient.
 
                 // but even just declaring them must collect the items they refer to
-                let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+                let def_id = self.tcx.hir().local_def_id(item.hir_id);
 
                 let instance = Instance::mono(self.tcx, def_id);
                 let cid = GlobalId {
@@ -1029,7 +1029,7 @@ fn visit_item(&mut self, item: &'v hir::Item) {
                 }
             }
             hir::ItemKind::Fn(..) => {
-                let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+                let def_id = self.tcx.hir().local_def_id(item.hir_id);
                 self.push_if_root(def_id);
             }
         }
@@ -1043,7 +1043,7 @@ fn visit_trait_item(&mut self, _: &'v hir::TraitItem) {
     fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) {
         match ii.node {
             hir::ImplItemKind::Method(hir::MethodSig { .. }, _) => {
-                let def_id = self.tcx.hir().local_def_id_from_hir_id(ii.hir_id);
+                let def_id = self.tcx.hir().local_def_id(ii.hir_id);
                 self.push_if_root(def_id);
             }
             _ => { /* Nothing to do here */ }
@@ -1114,7 +1114,7 @@ fn push_extra_entry_roots(&mut self) {
     }
 }
 
-fn item_requires_monomorphization<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
+fn item_requires_monomorphization(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     let generics = tcx.generics_of(def_id);
     generics.requires_monomorphization(tcx)
 }
@@ -1136,7 +1136,7 @@ fn create_mono_items_for_default_impls<'tcx>(
                 }
             }
 
-            let impl_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id);
+            let impl_def_id = tcx.hir().local_def_id(item.hir_id);
 
             debug!("create_mono_items_for_default_impls(item={})",
                    def_id_to_string(tcx, impl_def_id));
@@ -1243,7 +1243,7 @@ fn collect_neighbours<'tcx>(
     }
 }
 
-fn def_id_to_string<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> String {
+fn def_id_to_string(tcx: TyCtxt<'_>, def_id: DefId) -> String {
     let mut output = String::new();
     let printer = DefPathBasedNames::new(tcx, false, false);
     printer.push_def_path(def_id, &mut output);
index 2bcf058ad7c35c8335766c56749bd0d18b46ddfb..e63426281bf21fea294ffd71ecac399254a366a5 100644 (file)
@@ -55,7 +55,7 @@ fn symbol_name(&self, tcx: TyCtxt<'tcx>) -> ty::SymbolName {
                 tcx.symbol_name(Instance::mono(tcx, def_id))
             }
             MonoItem::GlobalAsm(hir_id) => {
-                let def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
+                let def_id = tcx.hir().local_def_id(hir_id);
                 ty::SymbolName {
                     name: InternedString::intern(&format!("global_asm_{:?}", def_id))
                 }
index 32e4d4f437a7884605833461241ca0734c0f9bad..ad9db4e0aa8d84f59507cd2a11d805e0805d1350 100644 (file)
@@ -314,7 +314,7 @@ fn mono_item_visibility(
             };
         }
         MonoItem::GlobalAsm(hir_id) => {
-            let def_id = tcx.hir().local_def_id_from_hir_id(*hir_id);
+            let def_id = tcx.hir().local_def_id(*hir_id);
             return if tcx.is_reachable_non_generic(def_id) {
                 *can_be_internalized = false;
                 default_visibility(tcx, def_id, false)
@@ -698,7 +698,7 @@ fn characteristic_def_id_of_mono_item<'tcx>(
             Some(def_id)
         }
         MonoItem::Static(def_id) => Some(def_id),
-        MonoItem::GlobalAsm(hir_id) => Some(tcx.hir().local_def_id_from_hir_id(hir_id)),
+        MonoItem::GlobalAsm(hir_id) => Some(tcx.hir().local_def_id(hir_id)),
     }
 }
 
@@ -839,10 +839,10 @@ fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'tcx>, mono_items: I)
     }
 }
 
-fn collect_and_partition_mono_items<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn collect_and_partition_mono_items(
+    tcx: TyCtxt<'_>,
     cnum: CrateNum,
-) -> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>) {
+) -> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'_>>>>) {
     assert_eq!(cnum, LOCAL_CRATE);
 
     let collection_mode = match tcx.sess.opts.debugging_opts.print_mono_items {
index 7987095a33401ee437fb77a1e7db8297beebc7ac..32b964dbadfa92ac3dcf5e4a5d0dab9f6844db46 100644 (file)
@@ -829,7 +829,7 @@ fn build_call_shim<'tcx>(
     body
 }
 
-pub fn build_adt_ctor<'tcx>(tcx: TyCtxt<'tcx>, ctor_id: DefId) -> &'tcx Body<'tcx> {
+pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> {
     debug_assert!(tcx.is_constructor(ctor_id));
 
     let span = tcx.hir().span_if_local(ctor_id)
index e01017d7c9bdbe513a8b849116cedace25de0f5f..de5af0a46b534935102c2de6e231ad2d28fbccfe 100644 (file)
@@ -14,8 +14,8 @@
 /// after the assignment, we can be sure to obtain the same place value.
 /// (Concurrent accesses by other threads are no problem as these are anyway non-atomic
 /// copies.  Data races are UB.)
-fn is_stable<'tcx>(
-    place: &Place<'tcx>,
+fn is_stable(
+    place: &Place<'_>,
 ) -> bool {
     use rustc::mir::Place::*;
 
index 24df3549be48136c9d8a4e481b0c0364765a75c9..9898ba897734d7f74deb56476bea127caf3506ce 100644 (file)
@@ -480,11 +480,11 @@ fn visit_block(&mut self, block: &'tcx hir::Block) {
     }
 }
 
-fn check_unused_unsafe<'a, 'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn check_unused_unsafe(
+    tcx: TyCtxt<'_>,
     def_id: DefId,
     used_unsafe: &FxHashSet<hir::HirId>,
-    unsafe_blocks: &'a mut Vec<(hir::HirId, bool)>,
+    unsafe_blocks: &mut Vec<(hir::HirId, bool)>,
 ) {
     let body_id =
         tcx.hir().as_local_hir_id(def_id).and_then(|hir_id| {
@@ -506,7 +506,7 @@ fn check_unused_unsafe<'a, 'tcx>(
     hir::intravisit::Visitor::visit_body(&mut visitor, body);
 }
 
-fn unsafety_check_result<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> UnsafetyCheckResult {
+fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult {
     debug!("unsafety_violations({:?})", def_id);
 
     // N.B., this borrow is valid because all the consumers of
@@ -545,7 +545,7 @@ fn unsafety_check_result<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> UnsafetyChec
     }
 }
 
-fn unsafe_derive_on_repr_packed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
+fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: DefId) {
     let lint_hir_id = tcx.hir().as_local_hir_id(def_id).unwrap_or_else(||
         bug!("checking unsafety for non-local def id {:?}", def_id));
 
@@ -602,7 +602,7 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, used_unsafe: &FxHashSet<hir::HirId>, id
     db.emit();
 }
 
-fn builtin_derive_def_id<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<DefId> {
+fn builtin_derive_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
     debug!("builtin_derive_def_id({:?})", def_id);
     if let Some(impl_def_id) = tcx.impl_of_method(def_id) {
         if tcx.has_attr(impl_def_id, sym::automatically_derived) {
@@ -618,7 +618,7 @@ fn builtin_derive_def_id<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<DefId
     }
 }
 
-pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
+pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) {
     debug!("check_unsafety({:?})", def_id);
 
     // closures are handled by their parent fn.
index c7a2fdd93830f64c166e956308e0059757a097e7..29480f88fcedc421e291fa5026cd5352907de848 100644 (file)
@@ -23,7 +23,7 @@
 };
 
 use crate::interpret::{
-    self, InterpretCx, ScalarMaybeUndef, Immediate, OpTy,
+    self, InterpCx, ScalarMaybeUndef, Immediate, OpTy,
     ImmTy, MemoryKind, StackPopCleanup, LocalValue, LocalState,
 };
 use crate::const_eval::{
@@ -117,7 +117,7 @@ fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut
 
 /// Finds optimization opportunities on the MIR.
 struct ConstPropagator<'mir, 'tcx> {
-    ecx: InterpretCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
+    ecx: InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
     tcx: TyCtxt<'tcx>,
     source: MirSource<'tcx>,
     can_const_prop: IndexVec<Local, bool>,
@@ -202,7 +202,7 @@ fn get_const(&self, local: Local) -> Option<Const<'tcx>> {
 
         // If the local is `Unitialized` or `Dead` then we haven't propagated a value into it.
         //
-        // `InterpretCx::access_local()` mostly takes care of this for us however, for ZSTs,
+        // `InterpCx::access_local()` mostly takes care of this for us however, for ZSTs,
         // it will synthesize a value for us. In doing so, that will cause the
         // `get_const(l).is_empty()` assert right before we call `set_const()` in `visit_statement`
         // to fail.
index 243820ba7d0278cd4ce347e227999e55d886c873..a6fb555f20bd023cddbf7d14aaa3902d4f82148c 100644 (file)
@@ -14,7 +14,7 @@
 pub struct Marker(pub &'static str);
 
 impl MirPass for Marker {
-    fn name<'a>(&'a self) -> Cow<'a, str> {
+    fn name(&self) -> Cow<'_, str> {
         Cow::Borrowed(self.0)
     }
 
@@ -52,7 +52,7 @@ pub fn on_mir_pass<'tcx>(
     }
 }
 
-pub fn emit_mir<'tcx>(tcx: TyCtxt<'tcx>, outputs: &OutputFilenames) -> io::Result<()> {
+pub fn emit_mir(tcx: TyCtxt<'_>, outputs: &OutputFilenames) -> io::Result<()> {
     let path = outputs.path(OutputType::Mir);
     let mut f = File::create(&path)?;
     mir_util::write_mir_pretty(tcx, None, &mut f)?;
index 7b961e97a10de580f0f7a340055e2409a3f58991..2ed3f7d5c26e28c852e4dd45a30c153c43754c20 100644 (file)
@@ -68,7 +68,7 @@
 use crate::transform::no_landing_pads::no_landing_pads;
 use crate::dataflow::{DataflowResults, DataflowResultsConsumer, FlowAtLocation};
 use crate::dataflow::{do_dataflow, DebugFormatted, state_for_location};
-use crate::dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals};
+use crate::dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals, RequiresStorage};
 use crate::util::dump_mir;
 use crate::util::liveness;
 
@@ -437,16 +437,18 @@ fn locals_live_across_suspend_points(
 
     // Calculate the MIR locals which have been previously
     // borrowed (even if they are still active).
-    // This is only used for immovable generators.
-    let borrowed_locals = if !movable {
-        let analysis = HaveBeenBorrowedLocals::new(body);
-        let result =
-            do_dataflow(tcx, body, def_id, &[], &dead_unwinds, analysis,
-                        |bd, p| DebugFormatted::new(&bd.body().local_decls[p]));
-        Some((analysis, result))
-    } else {
-        None
-    };
+    let borrowed_locals_analysis = HaveBeenBorrowedLocals::new(body);
+    let borrowed_locals_result =
+        do_dataflow(tcx, body, def_id, &[], &dead_unwinds, borrowed_locals_analysis,
+                    |bd, p| DebugFormatted::new(&bd.body().local_decls[p]));
+
+    // Calculate the MIR locals that we actually need to keep storage around
+    // for.
+    let requires_storage_analysis = RequiresStorage::new(body, &borrowed_locals_result);
+    let requires_storage =
+        do_dataflow(tcx, body, def_id, &[], &dead_unwinds, requires_storage_analysis,
+                    |bd, p| DebugFormatted::new(&bd.body().local_decls[p]));
+    let requires_storage_analysis = RequiresStorage::new(body, &borrowed_locals_result);
 
     // Calculate the liveness of MIR locals ignoring borrows.
     let mut live_locals = liveness::LiveVarSet::new_empty(body.local_decls.len());
@@ -471,10 +473,10 @@ fn locals_live_across_suspend_points(
                 statement_index: data.statements.len(),
             };
 
-            if let Some((ref analysis, ref result)) = borrowed_locals {
+            if !movable {
                 let borrowed_locals = state_for_location(loc,
-                                                         analysis,
-                                                         result,
+                                                         &borrowed_locals_analysis,
+                                                         &borrowed_locals_result,
                                                          body);
                 // The `liveness` variable contains the liveness of MIR locals ignoring borrows.
                 // This is correct for movable generators since borrows cannot live across
@@ -489,27 +491,34 @@ fn locals_live_across_suspend_points(
                 liveness.outs[block].union(&borrowed_locals);
             }
 
-            let mut storage_liveness = state_for_location(loc,
-                                                          &storage_live_analysis,
-                                                          &storage_live,
-                                                          body);
+            let storage_liveness = state_for_location(loc,
+                                                      &storage_live_analysis,
+                                                      &storage_live,
+                                                      body);
 
             // Store the storage liveness for later use so we can restore the state
             // after a suspension point
             storage_liveness_map.insert(block, storage_liveness.clone());
 
-            // Mark locals without storage statements as always having live storage
-            storage_liveness.union(&ignored.0);
+            let mut storage_required = state_for_location(loc,
+                                                          &requires_storage_analysis,
+                                                          &requires_storage,
+                                                          body);
+
+            // Mark locals without storage statements as always requiring storage
+            storage_required.union(&ignored.0);
 
             // Locals live are live at this point only if they are used across
             // suspension points (the `liveness` variable)
-            // and their storage is live (the `storage_liveness` variable)
-            let mut live_locals_here = storage_liveness;
+            // and their storage is required (the `storage_required` variable)
+            let mut live_locals_here = storage_required;
             live_locals_here.intersect(&liveness.outs[block]);
 
             // The generator argument is ignored
             live_locals_here.remove(self_arg());
 
+            debug!("loc = {:?}, live_locals_here = {:?}", loc, live_locals_here);
+
             // Add the locals live at this suspension point to the set of locals which live across
             // any suspension points
             live_locals.union(&live_locals_here);
@@ -517,6 +526,7 @@ fn locals_live_across_suspend_points(
             live_locals_at_suspension_points.push(live_locals_here);
         }
     }
+    debug!("live_locals = {:?}", live_locals);
 
     // Renumber our liveness_map bitsets to include only the locals we are
     // saving.
@@ -529,8 +539,8 @@ fn locals_live_across_suspend_points(
         body,
         &live_locals,
         &ignored,
-        storage_live,
-        storage_live_analysis);
+        requires_storage,
+        requires_storage_analysis);
 
     LivenessInfo {
         live_locals,
@@ -567,8 +577,8 @@ fn compute_storage_conflicts(
     body: &'mir Body<'tcx>,
     stored_locals: &liveness::LiveVarSet,
     ignored: &StorageIgnored,
-    storage_live: DataflowResults<'tcx, MaybeStorageLive<'mir, 'tcx>>,
-    _storage_live_analysis: MaybeStorageLive<'mir, 'tcx>,
+    requires_storage: DataflowResults<'tcx, RequiresStorage<'mir, 'tcx>>,
+    _requires_storage_analysis: RequiresStorage<'mir, 'tcx>,
 ) -> BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal> {
     assert_eq!(body.local_decls.len(), ignored.0.domain_size());
     assert_eq!(body.local_decls.len(), stored_locals.domain_size());
@@ -584,9 +594,9 @@ fn compute_storage_conflicts(
     let mut visitor = StorageConflictVisitor {
         body,
         stored_locals: &stored_locals,
-        local_conflicts: BitMatrix::from_row_n(&ineligible_locals, body.local_decls.len())
+        local_conflicts: BitMatrix::from_row_n(&ineligible_locals, body.local_decls.len()),
     };
-    let mut state = FlowAtLocation::new(storage_live);
+    let mut state = FlowAtLocation::new(requires_storage);
     visitor.analyze_results(&mut state);
     let local_conflicts = visitor.local_conflicts;
 
@@ -627,7 +637,7 @@ struct StorageConflictVisitor<'body, 'tcx, 's> {
 impl<'body, 'tcx, 's> DataflowResultsConsumer<'body, 'tcx>
     for StorageConflictVisitor<'body, 'tcx, 's>
 {
-    type FlowState = FlowAtLocation<'tcx, MaybeStorageLive<'body, 'tcx>>;
+    type FlowState = FlowAtLocation<'tcx, RequiresStorage<'body, 'tcx>>;
 
     fn body(&self) -> &'body Body<'tcx> {
         self.body
@@ -657,7 +667,7 @@ fn visit_terminator_entry(&mut self,
 
 impl<'body, 'tcx, 's> StorageConflictVisitor<'body, 'tcx, 's> {
     fn apply_state(&mut self,
-                   flow_state: &FlowAtLocation<'tcx, MaybeStorageLive<'body, 'tcx>>,
+                   flow_state: &FlowAtLocation<'tcx, RequiresStorage<'body, 'tcx>>,
                    loc: Location) {
         // Ignore unreachable blocks.
         match self.body.basic_blocks()[loc.block].terminator().kind {
@@ -1018,14 +1028,14 @@ fn create_generator_resume_function<'tcx>(
     dump_mir(tcx, None, "generator_resume", &0, source, body, |_, _| Ok(()) );
 }
 
-fn source_info<'tcx>(body: &Body<'tcx>) -> SourceInfo {
+fn source_info(body: &Body<'_>) -> SourceInfo {
     SourceInfo {
         span: body.span,
         scope: OUTERMOST_SOURCE_SCOPE,
     }
 }
 
-fn insert_clean_drop<'tcx>(body: &mut Body<'tcx>) -> BasicBlock {
+fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock {
     let return_block = insert_term_block(body, TerminatorKind::Return);
 
     // Create a block to destroy an unresumed generators. This can only destroy upvars.
index 81d91dcd0a95f58f66d6bd173832cae477f94b96..15e2dc3261d98ecbb9223ac7ea301a7a97264524 100644 (file)
@@ -50,13 +50,13 @@ pub(crate) fn provide(providers: &mut Providers<'_>) {
     };
 }
 
-fn is_mir_available<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
+fn is_mir_available(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     tcx.mir_keys(def_id.krate).contains(&def_id)
 }
 
 /// Finds the full set of `DefId`s within the current crate that have
 /// MIR associated with them.
-fn mir_keys<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) -> &'tcx DefIdSet {
+fn mir_keys(tcx: TyCtxt<'_>, krate: CrateNum) -> &DefIdSet {
     assert_eq!(krate, LOCAL_CRATE);
 
     let mut set = DefIdSet::default();
@@ -78,7 +78,7 @@ fn visit_variant_data(&mut self,
                               _: hir::HirId,
                               _: Span) {
             if let hir::VariantData::Tuple(_, hir_id) = *v {
-                self.set.insert(self.tcx.hir().local_def_id_from_hir_id(hir_id));
+                self.set.insert(self.tcx.hir().local_def_id(hir_id));
             }
             intravisit::walk_struct_def(self, v)
         }
@@ -94,7 +94,7 @@ fn nested_visit_map<'b>(&'b mut self) -> NestedVisitorMap<'b, 'tcx> {
     tcx.arena.alloc(set)
 }
 
-fn mir_built<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Steal<Body<'tcx>> {
+fn mir_built(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal<Body<'_>> {
     let mir = build::mir_build(tcx, def_id);
     tcx.alloc_steal_mir(mir)
 }
@@ -137,7 +137,7 @@ pub fn default_name<T: ?Sized>() -> Cow<'static, str> {
 /// pass will be named after the type, and it will consist of a main
 /// loop that goes over each available MIR and applies `run_pass`.
 pub trait MirPass {
-    fn name<'a>(&'a self) -> Cow<'a, str> {
+    fn name(&self) -> Cow<'_, str> {
         default_name::<Self>()
     }
 
@@ -192,7 +192,7 @@ pub fn run_passes(
     }
 }
 
-fn mir_const<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Steal<Body<'tcx>> {
+fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal<Body<'_>> {
     // Unsafety check uses the raw mir, so make sure it is run
     let _ = tcx.unsafety_check_result(def_id);
 
@@ -223,7 +223,7 @@ fn mir_validated(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Steal<Body<'tcx>> {
     tcx.alloc_steal_mir(body)
 }
 
-fn optimized_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Body<'tcx> {
+fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> {
     if tcx.is_constructor(def_id) {
         // There's no reason to run all of the MIR passes on constructors when
         // we can just output the MIR we want directly. This also saves const
index f082b5e5a046cfedd7a0dde7c5cdf93ad9a47cf1..3e52d3ee9bbdff021d4d8d56ea2501bd037e1d26 100644 (file)
@@ -1473,7 +1473,7 @@ pub fn provide(providers: &mut Providers<'_>) {
     };
 }
 
-fn mir_const_qualif<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> (u8, &'tcx BitSet<Local>) {
+fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> (u8, &BitSet<Local>) {
     // N.B., this `borrow()` is guaranteed to be valid (i.e., the value
     // cannot yet be stolen), because `mir_validated()`, which steals
     // from `mir_const(), forces this query to execute before
index f226f15c0096f2fcabaefab6ed4555298186b54e..2eed9d453f23363fded6deb3aa19d811e6e04cbf 100644 (file)
@@ -53,7 +53,7 @@ pub fn simplify_cfg(body: &mut Body<'_>) {
 }
 
 impl MirPass for SimplifyCfg {
-    fn name<'a>(&'a self) -> Cow<'a, str> {
+    fn name(&self) -> Cow<'_, str> {
         Cow::Borrowed(&self.label)
     }
 
index 0c63a8d9c96b1ad2446fed71ec0178563c48f796..f39c71ef42d71559c70bc6a04a5bd008ceb3ef03 100644 (file)
@@ -15,7 +15,7 @@ pub fn new(label: &str) -> Self {
 }
 
 impl MirPass for SimplifyBranches {
-    fn name<'a>(&'a self) -> Cow<'a, str> {
+    fn name(&self) -> Cow<'_, str> {
         Cow::Borrowed(&self.label)
     }
 
index fac752dbf023e9675fd7231f39b35bc7a90b2c65..59821440c6619cfb2edded3d832b1a19281201a4 100644 (file)
@@ -31,7 +31,7 @@ pub fn analyze(&mut self, body: &Body<'_>) {
         self.clear();
 
         let mut finder = DefUseFinder {
-            info: mem::replace(&mut self.info, IndexVec::new()),
+            info: mem::take(&mut self.info),
         };
         finder.visit_body(body);
         self.info = finder.info
index 1d876d7bddb5300b8488ecbf5ae82cff88aac028..9d142d9b700b63498f26f180c88c03233be4258d 100644 (file)
@@ -8,8 +8,8 @@
 use super::pretty::dump_mir_def_ids;
 
 /// Write a graphviz DOT graph of a list of MIRs.
-pub fn write_mir_graphviz<'tcx, W>(
-    tcx: TyCtxt<'tcx>,
+pub fn write_mir_graphviz<W>(
+    tcx: TyCtxt<'_>,
     single: Option<DefId>,
     w: &mut W,
 ) -> io::Result<()>
index cf0fc09472b6c520fc5c0805334e7a9189a6863a..b42eebc7ee3be28dfc0cd3d1cf544b7623535a1b 100644 (file)
@@ -56,8 +56,8 @@ pub struct LivenessResult {
 
 /// Computes which local variables are live within the given function
 /// `mir`, including drops.
-pub fn liveness_of_locals<'tcx>(
-    body: &Body<'tcx>,
+pub fn liveness_of_locals(
+    body: &Body<'_>,
 ) -> LivenessResult {
     let num_live_vars = body.local_decls.len();
 
@@ -75,9 +75,24 @@ pub fn liveness_of_locals<'tcx>(
 
     let mut bits = LiveVarSet::new_empty(num_live_vars);
 
-    // queue of things that need to be re-processed, and a set containing
-    // the things currently in the queue
-    let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_all(body.basic_blocks().len());
+    // The dirty queue contains the set of basic blocks whose entry sets have changed since they
+    // were last processed. At the start of the analysis, we initialize the queue in post-order to
+    // make it more likely that the entry set for a given basic block will have the effects of all
+    // its successors in the CFG applied before it is processed.
+    //
+    // FIXME(ecstaticmorse): Reverse post-order on the reverse CFG may generate a better iteration
+    // order when cycles are present, but the overhead of computing the reverse CFG may outweigh
+    // any benefits. Benchmark this and find out.
+    let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_none(body.basic_blocks().len());
+    for (bb, _) in traversal::postorder(body) {
+        dirty_queue.insert(bb);
+    }
+
+    // Add blocks which are not reachable from START_BLOCK to the work queue. These blocks will
+    // be processed after the ones added above.
+    for bb in body.basic_blocks().indices() {
+        dirty_queue.insert(bb);
+    }
 
     let predecessors = body.predecessors();
 
@@ -228,8 +243,8 @@ fn visit_local(&mut self, &local: &Local, context: PlaceContext, _: Location) {
     }
 }
 
-fn block<'tcx>(
-    b: &BasicBlockData<'tcx>,
+fn block(
+    b: &BasicBlockData<'_>,
     locals: usize,
 ) -> DefsUses {
     let mut visitor = DefsUsesVisitor {
index 719029dbaac77bfdf339a2b161527f96e8ed03a6..fd2a5e452ce4b481d5ae2dc94b2170da0c96798b 100644 (file)
@@ -21,7 +21,7 @@
 pub use self::graphviz::write_node_label as write_graphviz_node_label;
 
 /// If possible, suggest replacing `ref` with `ref mut`.
-pub fn suggest_ref_mut<'tcx>(tcx: TyCtxt<'tcx>, binding_span: Span) -> Option<(String)> {
+pub fn suggest_ref_mut(tcx: TyCtxt<'_>, binding_span: Span) -> Option<(String)> {
     let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).unwrap();
     if hi_src.starts_with("ref")
         && hi_src["ref".len()..].starts_with(Pattern_White_Space)
index 2da9c5adf9baf7a24fd96bed15978cccd37375a0..560635962995cb268263db3023691c631fa12f6b 100644 (file)
@@ -837,13 +837,6 @@ fn visit_mac(&mut self, mac: &Spanned<Mac_>) {
                                  the relevant `fold_*()` method in `PlaceholderExpander`?");
     }
 
-    fn visit_fn_header(&mut self, header: &'a FnHeader) {
-        if header.asyncness.node.is_async() && self.session.rust_2015() {
-            struct_span_err!(self.session, header.asyncness.span, E0670,
-                             "`async fn` is not permitted in the 2015 edition").emit();
-        }
-    }
-
     fn visit_impl_item(&mut self, ii: &'a ImplItem) {
         match ii.node {
             ImplItemKind::Method(ref sig, _) => {
index 6936aedb9de80d48f93482a3423dd8b60961bc28..e7f6abc410a32f90e945347af9089453dc77ac32 100644 (file)
@@ -38,7 +38,7 @@ pub fn print_hir_stats(krate: &hir::Crate) {
     collector.print("HIR STATS");
 }
 
-pub fn print_ast_stats<'v>(krate: &'v ast::Crate, title: &str) {
+pub fn print_ast_stats(krate: &ast::Crate, title: &str) {
     let mut collector = StatCollector {
         krate: None,
         data: FxHashMap::default(),
index 8f790d1328572d6e84be6deb59f83d785fe5f19f..95cb8de70675d12c604572560870fe51fb006c9f 100644 (file)
@@ -14,7 +14,7 @@
 use syntax::ast::Attribute;
 use syntax::symbol::sym;
 
-pub fn test_layout<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn test_layout(tcx: TyCtxt<'_>) {
     if tcx.features().rustc_attrs {
         // if the `rustc_attrs` feature is not enabled, don't bother testing layout
         tcx.hir()
@@ -29,7 +29,7 @@ struct VarianceTest<'tcx> {
 
 impl ItemLikeVisitor<'tcx> for VarianceTest<'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
-        let item_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let item_def_id = self.tcx.hir().local_def_id(item.hir_id);
 
         if let ItemKind::Ty(..) = item.node {
             for attr in self.tcx.get_attrs(item_def_id).iter() {
index 5f3d7159be6ce88fc8bc5c9707842bb19007de53..0a96ad3e3445e7bc59becea63d2779586bd39e3f 100644 (file)
@@ -14,7 +14,6 @@
 #![recursion_limit="256"]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #[macro_use]
index ed0a78b46527659bd7aea3eff19f639f50f74681..616e6974110e680b5cec399a15de685b8024dcd1 100644 (file)
@@ -45,7 +45,7 @@ struct CheckLoopVisitor<'a, 'hir> {
     cx: Context,
 }
 
-fn check_mod_loops<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
+fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: DefId) {
     tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckLoopVisitor {
         sess: &tcx.sess,
         hir_map: &tcx.hir(),
index bc1151974bb70bd4367ffd2c40288e5780892f04..daa64478bca8303ee20112c574db6b2ed4925aa2 100644 (file)
@@ -39,7 +39,7 @@ pub fn provide(providers: &mut Providers<'_>) {
     };
 }
 
-fn const_is_rvalue_promotable_to_static<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
+fn const_is_rvalue_promotable_to_static(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     assert!(def_id.is_local());
 
     let hir_id = tcx.hir().as_local_hir_id(def_id)
@@ -48,7 +48,7 @@ fn const_is_rvalue_promotable_to_static<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId)
     tcx.rvalue_promotable_map(def_id).contains(&body_id.hir_id.local_id)
 }
 
-fn rvalue_promotable_map<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ItemLocalSet {
+fn rvalue_promotable_map(tcx: TyCtxt<'_>, def_id: DefId) -> &ItemLocalSet {
     let outer_def_id = tcx.closure_base_def_id(def_id);
     if outer_def_id != def_id {
         return tcx.rvalue_promotable_map(outer_def_id);
@@ -165,7 +165,7 @@ fn remove_mut_rvalue_borrow(&mut self, pat: &hir::Pat) -> bool {
 impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
     fn check_nested_body(&mut self, body_id: hir::BodyId) -> Promotability {
         let item_id = self.tcx.hir().body_owner(body_id);
-        let item_def_id = self.tcx.hir().local_def_id_from_hir_id(item_id);
+        let item_def_id = self.tcx.hir().local_def_id(item_id);
 
         let outer_in_fn = self.in_fn;
         let outer_tables = self.tables;
@@ -451,7 +451,7 @@ fn check_expr_kind<'a, 'tcx>(
             let nested_body_promotable = v.check_nested_body(body_id);
             // Paths in constant contexts cannot refer to local variables,
             // as there are none, and thus closures can't have upvars there.
-            let closure_def_id = v.tcx.hir().local_def_id_from_hir_id(e.hir_id);
+            let closure_def_id = v.tcx.hir().local_def_id(e.hir_id);
             if !v.tcx.upvars(closure_def_id).map_or(true, |v| v.is_empty()) {
                 NotPromotable
             } else {
index d3ac597160fd63464d54b568b6581c1f3548405a..f1bf1111cf700d0ea3b43725721b4e0f3abe9a92 100644 (file)
@@ -30,11 +30,11 @@ fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
 }
 
 /// Finds the function marked with `#[plugin_registrar]`, if any.
-pub fn find_plugin_registrar<'tcx>(tcx: TyCtxt<'tcx>) -> Option<DefId> {
+pub fn find_plugin_registrar(tcx: TyCtxt<'_>) -> Option<DefId> {
     tcx.plugin_registrar_fn(LOCAL_CRATE)
 }
 
-fn plugin_registrar_fn<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Option<DefId> {
+fn plugin_registrar_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<DefId> {
     assert_eq!(cnum, LOCAL_CRATE);
 
     let mut finder = RegistrarFinder { registrars: Vec::new() };
@@ -44,7 +44,7 @@ fn plugin_registrar_fn<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> Option<DefId>
         0 => None,
         1 => {
             let (hir_id, _) = finder.registrars.pop().unwrap();
-            Some(tcx.hir().local_def_id_from_hir_id(hir_id))
+            Some(tcx.hir().local_def_id(hir_id))
         },
         _ => {
             let diagnostic = tcx.sess.diagnostic();
index 16d484e2a98f2e699edc0078c41c61bdd1972544..ec2855f826a46cc9a0a458f828da5e6d2c35a561 100644 (file)
@@ -6,7 +6,7 @@
 
 use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExtension};
 use syntax::ext::base::MacroExpanderFn;
-use syntax::symbol::{Symbol, sym};
+use syntax::symbol::Symbol;
 use syntax::ast;
 use syntax::feature_gate::AttributeType;
 use syntax_pos::Span;
@@ -77,7 +77,7 @@ pub fn new(sess: &'a Session, krate_span: Span) -> Registry<'a> {
     ///
     /// Returns empty slice in case the plugin was loaded
     /// with `--extra-plugins`
-    pub fn args<'b>(&'b self) -> &'b [ast::NestedMetaItem] {
+    pub fn args(&self) -> &[ast::NestedMetaItem] {
         self.args_hidden.as_ref().map(|v| &v[..]).unwrap_or(&[])
     }
 
@@ -85,9 +85,6 @@ pub fn args<'b>(&'b self) -> &'b [ast::NestedMetaItem] {
     ///
     /// This is the most general hook into `libsyntax`'s expansion behavior.
     pub fn register_syntax_extension(&mut self, name: ast::Name, mut extension: SyntaxExtension) {
-        if name == sym::macro_rules {
-            panic!("user-defined macros may not be named `macro_rules`");
-        }
         if extension.def_info.is_none() {
             extension.def_info = Some((ast::CRATE_NODE_ID, self.krate_span));
         }
index 3e98200e5327466e5d7cdf8ea5988cf4c8785f94..052f1526f0cc8bc077a931d915266c03988deef5 100644 (file)
@@ -1,7 +1,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #![feature(in_band_lifetimes)]
@@ -250,13 +249,13 @@ fn def_id_visibility<'tcx>(
                     let parent_hir_id = tcx.hir().get_parent_node(hir_id);
                     match tcx.hir().get(parent_hir_id) {
                         Node::Variant(..) => {
-                            let parent_did = tcx.hir().local_def_id_from_hir_id(parent_hir_id);
+                            let parent_did = tcx.hir().local_def_id(parent_hir_id);
                             let (mut ctor_vis, mut span, mut descr) = def_id_visibility(
                                 tcx, parent_did,
                             );
 
                             let adt_def = tcx.adt_def(tcx.hir().get_parent_did(hir_id));
-                            let ctor_did = tcx.hir().local_def_id_from_hir_id(
+                            let ctor_did = tcx.hir().local_def_id(
                                 vdata.ctor_hir_id().unwrap());
                             let variant = adt_def.variant_with_ctor_id(ctor_did);
 
@@ -333,11 +332,11 @@ fn item_tables<'a, 'tcx>(
     hir_id: hir::HirId,
     empty_tables: &'a ty::TypeckTables<'tcx>,
 ) -> &'a ty::TypeckTables<'tcx> {
-    let def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
+    let def_id = tcx.hir().local_def_id(hir_id);
     if tcx.has_typeck_tables(def_id) { tcx.typeck_tables_of(def_id) } else { empty_tables }
 }
 
-fn min<'tcx>(vis1: ty::Visibility, vis2: ty::Visibility, tcx: TyCtxt<'tcx>) -> ty::Visibility {
+fn min(vis1: ty::Visibility, vis2: ty::Visibility, tcx: TyCtxt<'_>) -> ty::Visibility {
     if vis1.is_at_least(vis2, tcx) { vis2 } else { vis1 }
 }
 
@@ -384,17 +383,17 @@ fn visit_def_id(&mut self, def_id: DefId, _kind: &str, _descr: &dyn fmt::Display
 trait VisibilityLike: Sized {
     const MAX: Self;
     const SHALLOW: bool = false;
-    fn new_min<'a, 'tcx>(find: &FindMin<'a, 'tcx, Self>, def_id: DefId) -> Self;
+    fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self;
 
     // Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to
     // associated types for which we can't determine visibility precisely.
-    fn of_impl<'a, 'tcx>(
+    fn of_impl(
         hir_id: hir::HirId,
-        tcx: TyCtxt<'tcx>,
-        access_levels: &'a AccessLevels,
+        tcx: TyCtxt<'_>,
+        access_levels: &AccessLevels,
     ) -> Self {
         let mut find = FindMin { tcx, access_levels, min: Self::MAX };
-        let def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
+        let def_id = tcx.hir().local_def_id(hir_id);
         find.visit(tcx.type_of(def_id));
         if let Some(trait_ref) = tcx.impl_trait_ref(def_id) {
             find.visit_trait(trait_ref);
@@ -404,7 +403,7 @@ fn of_impl<'a, 'tcx>(
 }
 impl VisibilityLike for ty::Visibility {
     const MAX: Self = ty::Visibility::Public;
-    fn new_min<'a, 'tcx>(find: &FindMin<'a, 'tcx, Self>, def_id: DefId) -> Self {
+    fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self {
         min(def_id_visibility(find.tcx, def_id).0, find.min, find.tcx)
     }
 }
@@ -420,7 +419,7 @@ impl VisibilityLike for Option<AccessLevel> {
     // both "shallow" version of its self type and "shallow" version of its trait if it exists
     // (which require reaching the `DefId`s in them).
     const SHALLOW: bool = true;
-    fn new_min<'a, 'tcx>(find: &FindMin<'a, 'tcx, Self>, def_id: DefId) -> Self {
+    fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self {
         cmp::min(if let Some(hir_id) = find.tcx.hir().as_local_hir_id(def_id) {
             find.access_levels.map.get(&hir_id).cloned()
         } else {
@@ -475,7 +474,7 @@ fn reach(
     ) -> ReachEverythingInTheInterfaceVisitor<'_, 'tcx> {
         ReachEverythingInTheInterfaceVisitor {
             access_level: cmp::min(access_level, Some(AccessLevel::Reachable)),
-            item_def_id: self.tcx.hir().local_def_id_from_hir_id(item_id),
+            item_def_id: self.tcx.hir().local_def_id(item_id),
             ev: self,
         }
     }
@@ -506,7 +505,7 @@ fn update_visibility_of_intermediate_use_statements(&mut self, segments: &[hir::
                 if let hir::ItemKind::Mod(m) = &item.node {
                     for item_id in m.item_ids.as_ref() {
                         let item = self.tcx.hir().expect_item(item_id.id);
-                        let def_id = self.tcx.hir().local_def_id_from_hir_id(item_id.id);
+                        let def_id = self.tcx.hir().local_def_id(item_id.id);
                         if !self.tcx.hygienic_eq(segment.ident, item.ident, def_id) { continue; }
                         if let hir::ItemKind::Use(..) = item.node {
                             self.update(item.hir_id, Some(AccessLevel::Exported));
@@ -726,7 +725,7 @@ fn visit_mod(&mut self, m: &'tcx hir::Mod, _sp: Span, id: hir::HirId) {
         // This code is here instead of in visit_item so that the
         // crate module gets processed as well.
         if self.prev_level.is_some() {
-            let def_id = self.tcx.hir().local_def_id_from_hir_id(id);
+            let def_id = self.tcx.hir().local_def_id(id);
             if let Some(exports) = self.tcx.module_exports(def_id) {
                 for export in exports.iter() {
                     if export.vis == ty::Visibility::Public {
@@ -751,7 +750,7 @@ fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
 
         let module_did = ty::DefIdTree::parent(
             self.tcx,
-            self.tcx.hir().local_def_id_from_hir_id(md.hir_id)
+            self.tcx.hir().local_def_id(md.hir_id)
         ).unwrap();
         let mut module_id = self.tcx.hir().as_local_hir_id(module_did).unwrap();
         let level = if md.vis.node.is_pub() { self.get(module_id) } else { None };
@@ -772,7 +771,7 @@ fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
             for id in &module.item_ids {
                 self.update(id.id, level);
             }
-            let def_id = self.tcx.hir().local_def_id_from_hir_id(module_id);
+            let def_id = self.tcx.hir().local_def_id(module_id);
             if let Some(exports) = self.tcx.module_exports(def_id) {
                 for export in exports.iter() {
                     if let Some(hir_id) = self.tcx.hir().as_local_hir_id(export.res.def_id()) {
@@ -1163,7 +1162,7 @@ fn visit_local(&mut self, local: &'tcx hir::Local) {
     // Check types in item interfaces.
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         let orig_current_item = mem::replace(&mut self.current_item,
-            self.tcx.hir().local_def_id_from_hir_id(item.hir_id));
+            self.tcx.hir().local_def_id(item.hir_id));
         let orig_in_body = mem::replace(&mut self.in_body, false);
         let orig_tables =
             mem::replace(&mut self.tables, item_tables(self.tcx, item.hir_id, self.empty_tables));
@@ -1689,7 +1688,7 @@ fn check(
         SearchInterfaceForPrivateItemsVisitor {
             tcx: self.tcx,
             item_id,
-            item_def_id: self.tcx.hir().local_def_id_from_hir_id(item_id),
+            item_def_id: self.tcx.hir().local_def_id(item_id),
             span: self.tcx.hir().span(item_id),
             required_visibility,
             has_pub_restricted: self.has_pub_restricted,
@@ -1828,7 +1827,7 @@ pub fn provide(providers: &mut Providers<'_>) {
     };
 }
 
-fn check_mod_privacy<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
+fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: DefId) {
     let empty_tables = ty::TypeckTables::empty(None);
 
     // Check privacy of names not checked in previous compilation stages.
@@ -1855,7 +1854,7 @@ fn check_mod_privacy<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
     intravisit::walk_mod(&mut visitor, module, hir_id);
 }
 
-fn privacy_access_levels<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) -> &'tcx AccessLevels {
+fn privacy_access_levels(tcx: TyCtxt<'_>, krate: CrateNum) -> &AccessLevels {
     assert_eq!(krate, LOCAL_CRATE);
 
     // Build up a set of all exported items in the AST. This is a set of all
@@ -1879,7 +1878,7 @@ fn privacy_access_levels<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) -> &'tcx Acce
     tcx.arena.alloc(visitor.access_levels)
 }
 
-fn check_private_in_public<'tcx>(tcx: TyCtxt<'tcx>, krate: CrateNum) {
+fn check_private_in_public(tcx: TyCtxt<'_>, krate: CrateNum) {
     assert_eq!(krate, LOCAL_CRATE);
 
     let access_levels = tcx.privacy_access_levels(LOCAL_CRATE);
index 81adfac0a291aa3647c76a41c9a7107fe00f5f1a..13b9855dbd71a77b18d24c38291ec68fda3ef1a2 100644 (file)
@@ -4,14 +4,13 @@
 
 #![feature(crate_visibility_modifier)]
 #![feature(label_break_value)]
+#![feature(mem_take)]
 #![feature(nll)]
 #![feature(rustc_diagnostic_macros)]
-#![feature(type_alias_enum_variants)]
 
 #![recursion_limit="256"]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 pub use rustc::hir::def::{Namespace, PerNS};
@@ -198,9 +197,9 @@ enum ResolutionError<'a> {
 ///
 /// This takes the error provided, combines it with the span and any additional spans inside the
 /// error and emits it.
-fn resolve_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
-                            span: Span,
-                            resolution_error: ResolutionError<'a>) {
+fn resolve_error(resolver: &Resolver<'_>,
+                 span: Span,
+                 resolution_error: ResolutionError<'_>) {
     resolve_struct_error(resolver, span, resolution_error).emit();
 }
 
index 392a46a262f5038c2b59e0dcfebf7c1f137678ef..dd0beee2104e8cf07a28af3d18d4a527b7824692 100644 (file)
@@ -19,9 +19,8 @@
 use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
 use syntax::ext::hygiene::Mark;
 use syntax::ext::tt::macro_rules;
-use syntax::feature_gate::{
-    feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES,
-};
+use syntax::feature_gate::{feature_err, emit_feature_err, is_builtin_attr_name};
+use syntax::feature_gate::{AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES};
 use syntax::symbol::{Symbol, kw, sym};
 use syntax::visit::Visitor;
 use syntax::util::lev_distance::find_best_match_for_name;
@@ -298,12 +297,25 @@ fn resolve_macro_to_res(
         let res = self.resolve_macro_to_res_inner(path, kind, parent_scope, trace, force);
 
         // Report errors and enforce feature gates for the resolved macro.
+        let features = self.session.features_untracked();
         if res != Err(Determinacy::Undetermined) {
             // Do not report duplicated errors on every undetermined resolution.
             for segment in &path.segments {
                 if let Some(args) = &segment.args {
                     self.session.span_err(args.span(), "generic arguments in macro path");
                 }
+                if kind == MacroKind::Attr && !features.rustc_attrs &&
+                   segment.ident.as_str().starts_with("rustc") {
+                    let msg = "attributes starting with `rustc` are \
+                               reserved for use by the `rustc` compiler";
+                    emit_feature_err(
+                        &self.session.parse_sess,
+                        sym::rustc_attrs,
+                        segment.ident.span,
+                        GateIssue::Language,
+                        msg,
+                    );
+                }
             }
         }
 
@@ -320,24 +332,15 @@ fn resolve_macro_to_res(
             }
             Res::NonMacroAttr(attr_kind) => {
                 if kind == MacroKind::Attr {
-                    let features = self.session.features_untracked();
                     if attr_kind == NonMacroAttrKind::Custom {
                         assert!(path.segments.len() == 1);
-                        let name = path.segments[0].ident.as_str();
-                        if name.starts_with("rustc_") {
-                            if !features.rustc_attrs {
-                                let msg = "unless otherwise specified, attributes with the prefix \
-                                           `rustc_` are reserved for internal compiler diagnostics";
-                                self.report_unknown_attribute(path.span, &name, msg,
-                                                              sym::rustc_attrs);
-                            }
-                        } else if !features.custom_attribute {
+                        if !features.custom_attribute {
                             let msg = format!("The attribute `{}` is currently unknown to the \
                                                compiler and may have meaning added to it in the \
                                                future", path);
                             self.report_unknown_attribute(
                                 path.span,
-                                &name,
+                                &path.segments[0].ident.as_str(),
                                 &msg,
                                 sym::custom_attribute,
                             );
@@ -946,7 +949,7 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
         };
 
         let macro_resolutions =
-            mem::replace(&mut *module.multi_segment_macro_resolutions.borrow_mut(), Vec::new());
+            mem::take(&mut *module.multi_segment_macro_resolutions.borrow_mut());
         for (mut path, path_span, kind, parent_scope, initial_res) in macro_resolutions {
             // FIXME: Path resolution will ICE if segment IDs present.
             for seg in &mut path { seg.id = None; }
@@ -973,7 +976,7 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
         }
 
         let macro_resolutions =
-            mem::replace(&mut *module.single_segment_macro_resolutions.borrow_mut(), Vec::new());
+            mem::take(&mut *module.single_segment_macro_resolutions.borrow_mut());
         for (ident, kind, parent_scope, initial_binding) in macro_resolutions {
             match self.early_resolve_ident_in_lexical_scope(ident, ScopeSet::Macro(kind),
                                                             &parent_scope, true, true, ident.span) {
@@ -998,7 +1001,7 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
             }
         }
 
-        let builtin_attrs = mem::replace(&mut *module.builtin_attrs.borrow_mut(), Vec::new());
+        let builtin_attrs = mem::take(&mut *module.builtin_attrs.borrow_mut());
         for (ident, parent_scope) in builtin_attrs {
             let _ = self.early_resolve_ident_in_lexical_scope(
                 ident, ScopeSet::Macro(MacroKind::Attr), &parent_scope, true, true, ident.span
@@ -1109,9 +1112,6 @@ pub fn define_macro(&mut self,
                         current_legacy_scope: &mut LegacyScope<'a>) {
         self.local_macro_def_scopes.insert(item.id, self.current_module);
         let ident = item.ident;
-        if ident.name == sym::macro_rules {
-            self.session.span_err(item.span, "user-defined macros may not be named `macro_rules`");
-        }
 
         let def_id = self.definitions.local_def_id(item.id);
         let ext = Lrc::new(macro_rules::compile(&self.session.parse_sess,
index f69849bb4a9ee8d8bd843f755e0d302ee5ed18cc..404d728d8808ce5cd54fe8e448a3ee86ea8924b2 100644 (file)
@@ -682,7 +682,7 @@ pub fn resolve_imports(&mut self) {
         let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1;
         while self.indeterminate_imports.len() < prev_num_indeterminates {
             prev_num_indeterminates = self.indeterminate_imports.len();
-            for import in mem::replace(&mut self.indeterminate_imports, Vec::new()) {
+            for import in mem::take(&mut self.indeterminate_imports) {
                 match self.resolve_import(&import) {
                     true => self.determined_imports.push(import),
                     false => self.indeterminate_imports.push(import),
index beef9f151cf008846252f61ebddcaffdad41ecb9..dfdf560d419060a39ef922a31d3a5ba0cc192a93 100644 (file)
@@ -123,7 +123,7 @@ fn nest_tables<F>(&mut self, item_id: NodeId, f: F)
     where
         F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll, O>),
     {
-        let item_def_id = self.tcx.hir().local_def_id(item_id);
+        let item_def_id = self.tcx.hir().local_def_id_from_node_id(item_id);
         if self.tcx.has_typeck_tables(item_def_id) {
             let tables = self.tcx.typeck_tables_of(item_def_id);
             let old_tables = self.save_ctxt.tables;
@@ -436,7 +436,7 @@ fn process_assoc_const(
         attrs: &'l [Attribute],
     ) {
         let qualname = format!("::{}",
-            self.tcx.def_path_str(self.tcx.hir().local_def_id(id)));
+            self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(id)));
 
         if !self.span.filter_generated(ident.span) {
             let sig = sig::assoc_const_signature(id, ident.name, typ, expr, &self.save_ctxt);
@@ -481,7 +481,7 @@ fn process_struct(
         debug!("process_struct {:?} {:?}", item, item.span);
         let name = item.ident.to_string();
         let qualname = format!("::{}",
-            self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
+            self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
 
         let kind = match item.node {
             ast::ItemKind::Struct(_, _) => DefKind::Struct,
@@ -683,7 +683,7 @@ fn process_impl(
         self.process_generic_params(generics, "", item.id);
         for impl_item in impl_items {
             let map = &self.tcx.hir();
-            self.process_impl_item(impl_item, map.local_def_id(item.id));
+            self.process_impl_item(impl_item, map.local_def_id_from_node_id(item.id));
         }
     }
 
@@ -696,7 +696,7 @@ fn process_trait(
     ) {
         let name = item.ident.to_string();
         let qualname = format!("::{}",
-            self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
+            self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
         let mut val = name.clone();
         if !generics.params.is_empty() {
             val.push_str(&generic_params_to_string(&generics.params));
@@ -764,7 +764,7 @@ fn process_trait(
         self.process_generic_params(generics, &qualname, item.id);
         for method in methods {
             let map = &self.tcx.hir();
-            self.process_trait_item(method, map.local_def_id(item.id))
+            self.process_trait_item(method, map.local_def_id_from_node_id(item.id))
         }
     }
 
@@ -1109,7 +1109,7 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId
                 // FIXME do something with _bounds (for type refs)
                 let name = trait_item.ident.name.to_string();
                 let qualname = format!("::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id(trait_item.id)));
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(trait_item.id)));
 
                 if !self.span.filter_generated(trait_item.ident.span) {
                     let span = self.span_from_span(trait_item.ident.span);
@@ -1217,7 +1217,7 @@ fn process_use_tree(&mut self,
         let access = access_from!(self.save_ctxt, root_item, hir_id);
 
         // The parent `DefId` of a given use tree is always the enclosing item.
-        let parent = self.save_ctxt.tcx.hir().opt_local_def_id(id)
+        let parent = self.save_ctxt.tcx.hir().opt_local_def_id_from_node_id(id)
             .and_then(|id| self.save_ctxt.tcx.parent(id))
             .map(id_from_def_id);
 
@@ -1261,7 +1261,7 @@ fn process_use_tree(&mut self,
                 };
 
                 // Make a comma-separated list of names of imported modules.
-                let def_id = self.tcx.hir().local_def_id(id);
+                let def_id = self.tcx.hir().local_def_id_from_node_id(id);
                 let names = self.tcx.names_imported_by_glob_use(def_id);
                 let names: Vec<_> = names.iter().map(|n| n.to_string()).collect();
 
@@ -1318,7 +1318,7 @@ fn visit_mod(&mut self, m: &'l ast::Mod, span: Span, attrs: &[ast::Attribute], i
         assert_eq!(id, ast::CRATE_NODE_ID);
 
         let qualname = format!("::{}",
-            self.tcx.def_path_str(self.tcx.hir().local_def_id(id)));
+            self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(id)));
 
         let cm = self.tcx.sess.source_map();
         let filename = cm.span_to_filename(span);
@@ -1367,7 +1367,7 @@ fn visit_item(&mut self, item: &'l ast::Item) {
                 let name_span = item.ident.span;
                 if !self.span.filter_generated(name_span) {
                     let span = self.span_from_span(name_span);
-                    let parent = self.save_ctxt.tcx.hir().opt_local_def_id(item.id)
+                    let parent = self.save_ctxt.tcx.hir().opt_local_def_id_from_node_id(item.id)
                         .and_then(|id| self.save_ctxt.tcx.parent(id))
                         .map(id_from_def_id);
                     self.dumper.import(
@@ -1408,7 +1408,7 @@ fn visit_item(&mut self, item: &'l ast::Item) {
             }
             Ty(ref ty, ref ty_params) => {
                 let qualname = format!("::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
                 let value = ty_to_string(&ty);
                 if !self.span.filter_generated(item.ident.span) {
                     let span = self.span_from_span(item.ident.span);
@@ -1439,7 +1439,7 @@ fn visit_item(&mut self, item: &'l ast::Item) {
             }
             Existential(ref _bounds, ref ty_params) => {
                 let qualname = format!("::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
                 // FIXME do something with _bounds
                 let value = String::new();
                 if !self.span.filter_generated(item.ident.span) {
index ab82f75f74f4b26e3083c23de3c5c2de62e43b7f..effd69dc61ddc6660d1ac2fe30c685a3f50f402f 100644 (file)
@@ -1,7 +1,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 #![feature(nll)]
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 #![allow(unused_attributes)]
 
@@ -135,7 +134,7 @@ pub fn get_external_crates(&self) -> Vec<ExternalCrateData> {
 
     pub fn get_extern_item_data(&self, item: &ast::ForeignItem) -> Option<Data> {
         let qualname = format!("::{}",
-            self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
+            self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
         match item.node {
             ast::ForeignItemKind::Fn(ref decl, ref generics) => {
                 filter!(self.span_utils, item.ident.span);
@@ -186,7 +185,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
         match item.node {
             ast::ItemKind::Fn(ref decl, .., ref generics, _) => {
                 let qualname = format!("::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
                 filter!(self.span_utils, item.ident.span);
                 Some(Data::DefData(Def {
                     kind: DefKind::Function,
@@ -205,7 +204,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
             }
             ast::ItemKind::Static(ref typ, ..) => {
                 let qualname = format!("::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
 
                 filter!(self.span_utils, item.ident.span);
 
@@ -229,7 +228,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
             }
             ast::ItemKind::Const(ref typ, _) => {
                 let qualname = format!("::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
                 filter!(self.span_utils, item.ident.span);
 
                 let id = id_from_node_id(item.id, self);
@@ -252,7 +251,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
             }
             ast::ItemKind::Mod(ref m) => {
                 let qualname = format!("::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
 
                 let cm = self.tcx.sess.source_map();
                 let filename = cm.span_to_filename(m.inner);
@@ -280,7 +279,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
             ast::ItemKind::Enum(ref def, _) => {
                 let name = item.ident.to_string();
                 let qualname = format!("::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id(item.id)));
+                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
                 filter!(self.span_utils, item.ident.span);
                 let variants_str = def.variants
                     .iter()
@@ -365,10 +364,10 @@ pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option<
         if let Some(ident) = field.ident {
             let name = ident.to_string();
             let qualname = format!("::{}::{}",
-                self.tcx.def_path_str(self.tcx.hir().local_def_id(scope)),
+                self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(scope)),
                 ident);
             filter!(self.span_utils, ident.span);
-            let def_id = self.tcx.hir().local_def_id(field.id);
+            let def_id = self.tcx.hir().local_def_id_from_node_id(field.id);
             let typ = self.tcx.type_of(def_id).to_string();
 
 
@@ -400,7 +399,7 @@ pub fn get_method_data(&self, id: ast::NodeId, ident: ast::Ident, span: Span) ->
         // The qualname for a method is the trait name or name of the struct in an impl in
         // which the method is declared in, followed by the method's name.
         let (qualname, parent_scope, decl_id, docs, attributes) =
-            match self.tcx.impl_of_method(self.tcx.hir().local_def_id(id)) {
+            match self.tcx.impl_of_method(self.tcx.hir().local_def_id_from_node_id(id)) {
                 Some(impl_id) => match self.tcx.hir().get_if_local(impl_id) {
                     Some(Node::Item(item)) => match item.node {
                         hir::ItemKind::Impl(.., ref ty, _) => {
@@ -451,7 +450,7 @@ pub fn get_method_data(&self, id: ast::NodeId, ident: ast::Ident, span: Span) ->
                         );
                     }
                 },
-                None => match self.tcx.trait_of_item(self.tcx.hir().local_def_id(id)) {
+                None => match self.tcx.trait_of_item(self.tcx.hir().local_def_id_from_node_id(id)) {
                     Some(def_id) => {
                         let mut docs = String::new();
                         let mut attrs = vec![];
@@ -1193,7 +1192,7 @@ fn id_from_def_id(id: DefId) -> rls_data::Id {
 }
 
 fn id_from_node_id(id: NodeId, scx: &SaveContext<'_, '_>) -> rls_data::Id {
-    let def_id = scx.tcx.hir().opt_local_def_id(id);
+    let def_id = scx.tcx.hir().opt_local_def_id_from_node_id(id);
     def_id.map(|id| id_from_def_id(id)).unwrap_or_else(|| {
         // Create a *fake* `DefId` out of a `NodeId` by subtracting the `NodeId`
         // out of the maximum u32 value. This will work unless you have *billions*
index b68c70224c95e7a05263c582eb83cf7aa00eccaa..cdec65e5d40dfd0abc0dcfb62c03f0eb72f849fe 100644 (file)
@@ -167,20 +167,23 @@ fn cast_target(cls: &[Option<Class>], size: Size) -> CastTarget {
     target
 }
 
+const MAX_INT_REGS: usize = 6; // RDI, RSI, RDX, RCX, R8, R9
+const MAX_SSE_REGS: usize = 8; // XMM0-7
+
 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
     where Ty: TyLayoutMethods<'a, C> + Copy,
           C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
 {
-    let mut int_regs = 6; // RDI, RSI, RDX, RCX, R8, R9
-    let mut sse_regs = 8; // XMM0-7
+    let mut int_regs = MAX_INT_REGS;
+    let mut sse_regs = MAX_SSE_REGS;
 
     let mut x86_64_ty = |arg: &mut ArgType<'a, Ty>, is_arg: bool| {
         let mut cls_or_mem = classify_arg(cx, arg);
 
-        let mut needed_int = 0;
-        let mut needed_sse = 0;
         if is_arg {
             if let Ok(cls) = cls_or_mem {
+                let mut needed_int = 0;
+                let mut needed_sse = 0;
                 for &c in &cls {
                     match c {
                         Some(Class::Int) => needed_int += 1,
@@ -188,8 +191,20 @@ pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
                         _ => {}
                     }
                 }
-                if arg.layout.is_aggregate() && (int_regs < needed_int || sse_regs < needed_sse) {
-                    cls_or_mem = Err(Memory);
+                match (int_regs.checked_sub(needed_int), sse_regs.checked_sub(needed_sse)) {
+                    (Some(left_int), Some(left_sse)) => {
+                        int_regs = left_int;
+                        sse_regs = left_sse;
+                    }
+                    _ => {
+                        // Not enough registers for this argument, so it will be
+                        // passed on the stack, but we only mark aggregates
+                        // explicitly as indirect `byval` arguments, as LLVM will
+                        // automatically put immediates on the stack itself.
+                        if arg.layout.is_aggregate() {
+                            cls_or_mem = Err(Memory);
+                        }
+                    }
                 }
             }
         }
@@ -201,14 +216,14 @@ pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
                 } else {
                     // `sret` parameter thus one less integer register available
                     arg.make_indirect();
+                    // NOTE(eddyb) return is handled first, so no registers
+                    // should've been used yet.
+                    assert_eq!(int_regs, MAX_INT_REGS);
                     int_regs -= 1;
                 }
             }
             Ok(ref cls) => {
                 // split into sized chunks passed individually
-                int_regs -= needed_int;
-                sse_regs -= needed_sse;
-
                 if arg.layout.is_aggregate() {
                     let size = arg.layout.size;
                     arg.cast_to(cast_target(cls, size))
index 1bebe420251fda2520ec7d9d9bf9ebcc755102d1..b65813fd8e38d6adb73bb68c38340918fd352c31 100644 (file)
@@ -16,7 +16,6 @@
 #![feature(step_trait)]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #[macro_use] extern crate log;
index fdd747cdb865a5dcefa3a3db5b2a0d56d9a73c7f..b139083e99fc1e9d57d5413b18b5c83fff7352e8 100644 (file)
@@ -19,6 +19,10 @@ pub fn opts() -> TargetOptions {
         target_family: Some("windows".to_string()),
         is_like_windows: true,
         is_like_msvc: true,
+        // set VSLANG to 1033 can prevent link.exe from using
+        // language packs, and avoid generating Non-UTF-8 error
+        // messages if a link error occurred.
+        link_env: vec![("VSLANG".to_string(), "1033".to_string())],
         pre_link_args: args,
         crt_static_allows_dylibs: true,
         crt_static_respected: true,
index bbb0825ee082afa4a706e35e557c3fe82fd93e7b..5c23ad4a4edfbd361fb8d1259402834e7cc88b72 100644 (file)
@@ -17,6 +17,7 @@
     CanonicalVarValues,
     OriginalQueryValues,
     QueryResponse,
+    QueryRegionConstraints,
     Certainty,
 };
 use rustc::traits::{
@@ -151,14 +152,14 @@ fn make_solution(
         let solution = constrained_subst.unchecked_map(|cs| match ambiguous {
             true => QueryResponse {
                 var_values: cs.subst.make_identity(self.tcx),
-                region_constraints: Vec::new(),
+                region_constraints: QueryRegionConstraints::default(),
                 certainty: Certainty::Ambiguous,
                 value: (),
             },
 
             false => QueryResponse {
                 var_values: cs.subst,
-                region_constraints: Vec::new(),
+                region_constraints: QueryRegionConstraints::default(),
 
                 // FIXME: restore this later once we get better at handling regions
                 // region_constraints: cs.constraints
index 8e4b9da6de268304f7704321f67e80ea390ddffd..6e8eed0f907255072a714081506e4a7aeaddecb6 100644 (file)
@@ -15,7 +15,7 @@
 use crate::generic_types;
 use std::iter;
 
-crate fn wf_clause_for_raw_ptr<'tcx>(tcx: TyCtxt<'tcx>, mutbl: hir::Mutability) -> Clauses<'tcx> {
+crate fn wf_clause_for_raw_ptr(tcx: TyCtxt<'_>, mutbl: hir::Mutability) -> Clauses<'_> {
     let ptr_ty = generic_types::raw_ptr(tcx, mutbl);
 
     let wf_clause = ProgramClause {
     tcx.mk_clauses(iter::once(wf_clause))
 }
 
-crate fn wf_clause_for_fn_ptr<'tcx>(
-    tcx: TyCtxt<'tcx>,
+crate fn wf_clause_for_fn_ptr(
+    tcx: TyCtxt<'_>,
     arity_and_output: usize,
     variadic: bool,
     unsafety: hir::Unsafety,
     abi: abi::Abi,
-) -> Clauses<'tcx> {
+) -> Clauses<'_> {
     let fn_ptr = generic_types::fn_ptr(tcx, arity_and_output, variadic, unsafety, abi);
 
     let wf_clause = ProgramClause {
@@ -50,7 +50,7 @@
     tcx.mk_clauses(iter::once(wf_clause))
 }
 
-crate fn wf_clause_for_slice<'tcx>(tcx: TyCtxt<'tcx>) -> Clauses<'tcx> {
+crate fn wf_clause_for_slice(tcx: TyCtxt<'_>) -> Clauses<'_> {
     let ty = generic_types::bound(tcx, 0);
     let slice_ty = tcx.mk_slice(ty);
 
     tcx.mk_clauses(iter::once(wf_clause))
 }
 
-crate fn wf_clause_for_tuple<'tcx>(tcx: TyCtxt<'tcx>, arity: usize) -> Clauses<'tcx> {
+crate fn wf_clause_for_tuple(tcx: TyCtxt<'_>, arity: usize) -> Clauses<'_> {
     let type_list = generic_types::type_list(tcx, arity);
     let tuple_ty = tcx.mk_ty(ty::Tuple(type_list));
 
     tcx.mk_clauses(iter::once(wf_clause))
 }
 
-crate fn wf_clause_for_ref<'tcx>(tcx: TyCtxt<'tcx>, mutbl: hir::Mutability) -> Clauses<'tcx> {
+crate fn wf_clause_for_ref(tcx: TyCtxt<'_>, mutbl: hir::Mutability) -> Clauses<'_> {
     let region = tcx.mk_region(
         ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0))
     );
     tcx.mk_clauses(iter::once(wf_clause))
 }
 
-crate fn wf_clause_for_fn_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses<'tcx> {
+crate fn wf_clause_for_fn_def(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> {
     let fn_def = generic_types::fn_def(tcx, def_id);
 
     let wf_clause = ProgramClause {
index 3abd7e90cf10fbd111e1e78b9ed4007bf23a6f55..ecd888b606981d10422cea7acad21d1092fce5d9 100644 (file)
@@ -279,10 +279,10 @@ fn dtorck_constraint_for_ty<'tcx>(
 }
 
 /// Calculates the dtorck constraint for a type.
-crate fn adt_dtorck_constraint<'tcx>(
-    tcx: TyCtxt<'tcx>,
+crate fn adt_dtorck_constraint(
+    tcx: TyCtxt<'_>,
     def_id: DefId,
-) -> Result<DtorckConstraint<'tcx>, NoSolution> {
+) -> Result<DtorckConstraint<'_>, NoSolution> {
     let def = tcx.adt_def(def_id);
     let span = tcx.def_span(def_id);
     debug!("dtorck_constraint: {:?}", def);
@@ -313,7 +313,7 @@ fn dtorck_constraint_for_ty<'tcx>(
     Ok(result)
 }
 
-fn dedup_dtorck_constraint<'tcx>(c: &mut DtorckConstraint<'tcx>) {
+fn dedup_dtorck_constraint(c: &mut DtorckConstraint<'_>) {
     let mut outlives = FxHashSet::default();
     let mut dtorck_types = FxHashSet::default();
 
index 7311fd96dadc78f7e271f23eb7dcd1e8984d80e3..12b19a2648d7f6d8577d66efbdd6f80fce80c992 100644 (file)
@@ -2,7 +2,6 @@
 //! the guts are broken up into modules; see the comments in those modules.
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #![feature(crate_visibility_modifier)]
index 017368558314824c1dfa9c8bdf227680b58135fa..9ff685bb4ee8a8976c12cbe83666aea044edf0d0 100644 (file)
@@ -160,7 +160,7 @@ fn visit_clause(&mut self, clause: Clause<'tcx>) {
     );
 }
 
-crate fn environment<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Environment<'tcx> {
+crate fn environment(tcx: TyCtxt<'_>, def_id: DefId) -> Environment<'_> {
     use super::{Lower, IntoFromEnvGoal};
     use rustc::hir::{Node, TraitItemKind, ImplItemKind, ItemKind, ForeignItemKind};
 
index 2a6613101614d1e0077964e542d6a67c51921df5..c81b1dc8974b0bf16e1b75f2646cd47f9a19cbc9 100644 (file)
@@ -155,7 +155,7 @@ fn into_well_formed_goal(self) -> DomainGoal<'tcx> {
     }
 }
 
-crate fn program_clauses_for<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses<'tcx> {
+crate fn program_clauses_for(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> {
     // FIXME(eddyb) this should only be using `def_kind`.
     match tcx.def_key(def_id).disambiguated_data.data {
         DefPathData::TypeNs(..) => match tcx.def_kind(def_id) {
@@ -181,7 +181,7 @@ fn into_well_formed_goal(self) -> DomainGoal<'tcx> {
     }
 }
 
-fn program_clauses_for_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses<'tcx> {
+fn program_clauses_for_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> {
     // `trait Trait<P1..Pn> where WC { .. } // P0 == Self`
 
     // Rule Implemented-From-Env (see rustc guide)
@@ -337,7 +337,7 @@ fn program_clauses_for_impl(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses<'tcx> {
     tcx.mk_clauses(iter::once(Clause::ForAll(ty::Binder::bind(clause))))
 }
 
-pub fn program_clauses_for_type_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses<'tcx> {
+pub fn program_clauses_for_type_def(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> {
     // Rule WellFormed-Type
     //
     // `struct Ty<P1..Pn> where WC1, ..., WCm`
@@ -411,10 +411,10 @@ pub fn program_clauses_for_type_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> C
     tcx.mk_clauses(iter::once(well_formed_clause).chain(from_env_clauses))
 }
 
-pub fn program_clauses_for_associated_type_def<'tcx>(
-    tcx: TyCtxt<'tcx>,
+pub fn program_clauses_for_associated_type_def(
+    tcx: TyCtxt<'_>,
     item_id: DefId,
-) -> Clauses<'tcx> {
+) -> Clauses<'_> {
     // Rule ProjectionEq-Placeholder
     //
     // ```
@@ -549,10 +549,10 @@ pub fn program_clauses_for_associated_type_def<'tcx>(
     tcx.mk_clauses(clauses)
 }
 
-pub fn program_clauses_for_associated_type_value<'tcx>(
-    tcx: TyCtxt<'tcx>,
+pub fn program_clauses_for_associated_type_value(
+    tcx: TyCtxt<'_>,
     item_id: DefId,
-) -> Clauses<'tcx> {
+) -> Clauses<'_> {
     // Rule Normalize-From-Impl (see rustc guide)
     //
     // ```
@@ -611,7 +611,7 @@ pub fn program_clauses_for_associated_type_value<'tcx>(
     tcx.mk_clauses(iter::once(normalize_clause))
 }
 
-pub fn dump_program_clauses<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn dump_program_clauses(tcx: TyCtxt<'_>) {
     if !tcx.features().rustc_attrs {
         return;
     }
@@ -628,7 +628,7 @@ struct ClauseDumper<'tcx> {
 
 impl ClauseDumper<'tcx> {
     fn process_attrs(&mut self, hir_id: hir::HirId, attrs: &[ast::Attribute]) {
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(hir_id);
+        let def_id = self.tcx.hir().local_def_id(hir_id);
         for attr in attrs {
             let mut clauses = None;
 
index 0375ad4a08f26c8e95eba2fbca11a55323d62380..7154b7958b932ddbe6d9797c9202b5af1a77422a 100644 (file)
@@ -7,6 +7,7 @@
 use crate::hir::def::{CtorOf, Res, DefKind};
 use crate::hir::def_id::DefId;
 use crate::hir::HirVec;
+use crate::hir::ptr::P;
 use crate::lint;
 use crate::middle::lang_items::SizedTraitLangItem;
 use crate::middle::resolve_lifetime as rl;
@@ -23,7 +24,6 @@
 use smallvec::SmallVec;
 use syntax::ast;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
-use syntax::ptr::P;
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, Span, MultiSpan};
@@ -34,7 +34,6 @@
 use std::iter;
 use std::slice;
 
-use super::{check_type_alias_enum_variants_enabled};
 use rustc_data_structures::fx::FxHashSet;
 
 #[derive(Debug)]
@@ -1595,7 +1594,6 @@ pub fn associated_path_to_ty(
                 });
                 if let Some(variant_def) = variant_def {
                     if permit_variants {
-                        check_type_alias_enum_variants_enabled(tcx, span);
                         tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span);
                         return Ok((qself_ty, DefKind::Variant, variant_def.def_id));
                     } else {
@@ -2001,7 +1999,7 @@ pub fn res_to_ty(&self,
 
                 let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
                 let item_id = tcx.hir().get_parent_node(hir_id);
-                let item_def_id = tcx.hir().local_def_id_from_hir_id(item_id);
+                let item_def_id = tcx.hir().local_def_id(item_id);
                 let generics = tcx.generics_of(item_def_id);
                 let index = generics.param_def_id_to_index[&def_id];
                 tcx.mk_ty_param(index, tcx.hir().name(hir_id).as_interned_str())
@@ -2093,7 +2091,7 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
                 self.res_to_ty(opt_self_ty, path, false)
             }
             hir::TyKind::Def(item_id, ref lifetimes) => {
-                let did = tcx.hir().local_def_id_from_hir_id(item_id.id);
+                let did = tcx.hir().local_def_id(item_id.id);
                 self.impl_trait_ty_to_ty(did, lifetimes)
             }
             hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
@@ -2175,7 +2173,7 @@ pub fn ast_const_to_const(
         debug!("ast_const_to_const(id={:?}, ast_const={:?})", ast_const.hir_id, ast_const);
 
         let tcx = self.tcx();
-        let def_id = tcx.hir().local_def_id_from_hir_id(ast_const.hir_id);
+        let def_id = tcx.hir().local_def_id(ast_const.hir_id);
 
         let mut const_ = ty::Const {
             val: ConstValue::Unevaluated(
@@ -2191,9 +2189,9 @@ pub fn ast_const_to_const(
             // parent item and construct a `ParamConst`.
             let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
             let item_id = tcx.hir().get_parent_node(hir_id);
-            let item_def_id = tcx.hir().local_def_id_from_hir_id(item_id);
+            let item_def_id = tcx.hir().local_def_id(item_id);
             let generics = tcx.generics_of(item_def_id);
-            let index = generics.param_def_id_to_index[&tcx.hir().local_def_id_from_hir_id(hir_id)];
+            let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id)];
             let name = tcx.hir().name(hir_id).as_interned_str();
             const_.val = ConstValue::Param(ty::ParamConst::new(index, name));
         }
index b435c99ad01f5f3e097484bb0647c2994cf3deb7..eeed5be867807bc670fe1fae482a9f8987518e18 100644 (file)
@@ -5,6 +5,7 @@
 use rustc::hir::{self, PatKind, Pat, ExprKind};
 use rustc::hir::def::{Res, DefKind, CtorKind};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
+use rustc::hir::ptr::P;
 use rustc::infer;
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc::traits::{ObligationCause, ObligationCauseCode};
@@ -12,7 +13,6 @@
 use rustc::ty::subst::Kind;
 use syntax::ast;
 use syntax::source_map::Spanned;
-use syntax::ptr::P;
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax_pos::Span;
 use syntax_pos::hygiene::CompilerDesugaringKind;
@@ -458,7 +458,7 @@ pub fn check_pat_walk(
                                 match ty.sty {
                                     ty::Array(..) | ty::Slice(..) => {
                                         err.help("the semantics of slice patterns changed \
-                                                  recently; see issue #23121");
+                                                  recently; see issue #62254");
                                     }
                                     _ => {}
                                 }
index 6c0deededdc738b2513719c102d25f4dc10f6024..d2f2f89cf0b1c7dce33459727c574eb1da9f2259 100644 (file)
@@ -72,7 +72,7 @@ fn check_closure(
             opt_kind, expected_sig
         );
 
-        let expr_def_id = self.tcx.hir().local_def_id_from_hir_id(expr.hir_id);
+        let expr_def_id = self.tcx.hir().local_def_id(expr.hir_id);
 
         let ClosureSignatures {
             bound_sig,
index 4bd2f216224a5f62fb41472974a9c8e01b336fee..94c76deade279c0b248e30d882088b8f3392b740 100644 (file)
@@ -54,6 +54,7 @@
 use errors::DiagnosticBuilder;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
+use rustc::hir::ptr::P;
 use rustc::infer::{Coercion, InferResult, InferOk};
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc::traits::{self, ObligationCause, ObligationCauseCode};
@@ -67,7 +68,6 @@
 use smallvec::{smallvec, SmallVec};
 use std::ops::Deref;
 use syntax::feature_gate;
-use syntax::ptr::P;
 use syntax::symbol::sym;
 use syntax_pos;
 
index a2621abf44d8dd29229d8f0107aa95985f542092..c4c4e10a14cc0ad1838b45c4e87534abcdcf7174 100644 (file)
@@ -29,7 +29,7 @@
 ///    struct/enum definition for the nominal type itself (i.e.
 ///    cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`).
 ///
-pub fn check_drop_impl<'tcx>(tcx: TyCtxt<'tcx>, drop_impl_did: DefId) -> Result<(), ErrorReported> {
+pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), ErrorReported> {
     let dtor_self_type = tcx.type_of(drop_impl_did);
     let dtor_predicates = tcx.predicates_of(drop_impl_did);
     match dtor_self_type.sty {
index 21fa219a1cab27ee1e63baeb361eb68406834bfb..603726dfe238c9e967a945cae9df82e5002f86bd 100644 (file)
 
 use errors::{Applicability, DiagnosticBuilder};
 use syntax::ast;
-use syntax::ptr::P;
 use syntax::symbol::{Symbol, LocalInternedString, kw, sym};
 use syntax::source_map::Span;
 use syntax::util::lev_distance::find_best_match_for_name;
 use rustc::hir;
 use rustc::hir::{ExprKind, QPath};
 use rustc::hir::def::{CtorKind, Res, DefKind};
+use rustc::hir::ptr::P;
 use rustc::infer;
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc::mir::interpret::GlobalId;
@@ -901,7 +901,7 @@ fn check_expr_repeat(
         expr: &'tcx hir::Expr,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
-        let count_def_id = tcx.hir().local_def_id_from_hir_id(count.hir_id);
+        let count_def_id = tcx.hir().local_def_id(count.hir_id);
         let count = if self.const_param_def_id(count).is_some() {
             Ok(self.to_const(count, tcx.type_of(count_def_id)))
         } else {
index 0bd078dace410bc6823b92d55614efe1bc374f49..7e4768d81b868663170d88f1703efa6f48ad7a2d 100644 (file)
@@ -75,7 +75,7 @@ fn record(&mut self,
                 // If unresolved type isn't a ty_var then unresolved_type_span is None
                 self.fcx.need_type_info_err_in_generator(
                     self.kind,
-                    unresolved_type_span.unwrap_or(yield_data.span),
+                    unresolved_type_span.unwrap_or(source_span),
                     unresolved_type,
                 )
                     .span_note(yield_data.span, &*note)
index 8c2b8d1565f2f033e0dbeede85cb654ccbe488c3..531ecd11dcb20ed26d8fbbf8ccc0778ca13d0f0e 100644 (file)
@@ -22,7 +22,7 @@ fn equate_intrinsic_type<'tcx>(
     inputs: Vec<Ty<'tcx>>,
     output: Ty<'tcx>,
 ) {
-    let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
+    let def_id = tcx.hir().local_def_id(it.hir_id);
 
     match it.node {
         hir::ForeignItemKind::Fn(..) => {}
@@ -79,7 +79,7 @@ pub fn intrisic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
 
 /// Remember to add all intrinsics here, in librustc_codegen_llvm/intrinsic.rs,
 /// and in libcore/intrinsics.rs
-pub fn check_intrinsic_type<'tcx>(tcx: TyCtxt<'tcx>, it: &hir::ForeignItem) {
+pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) {
     let param = |n| tcx.mk_ty_param(n, InternedString::intern(&format!("P{}", n)));
     let name = it.ident.as_str();
 
@@ -145,7 +145,6 @@ pub fn check_intrinsic_type<'tcx>(tcx: TyCtxt<'tcx>, it: &hir::ForeignItem) {
             "rustc_peek" => (1, vec![param(0)], param(0)),
             "panic_if_uninhabited" => (1, Vec::new(), tcx.mk_unit()),
             "init" => (1, Vec::new(), param(0)),
-            "uninit" => (1, Vec::new(), param(0)),
             "forget" => (1, vec![param(0)], tcx.mk_unit()),
             "transmute" => (2, vec![ param(0) ], param(1)),
             "move_val_init" => {
@@ -385,7 +384,7 @@ pub fn check_intrinsic_type<'tcx>(tcx: TyCtxt<'tcx>, it: &hir::ForeignItem) {
 }
 
 /// Type-check `extern "platform-intrinsic" { ... }` functions.
-pub fn check_platform_intrinsic_type<'tcx>(tcx: TyCtxt<'tcx>, it: &hir::ForeignItem) {
+pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) {
     let param = |n| {
         let name = InternedString::intern(&format!("P{}", n));
         tcx.mk_ty_param(n, name)
index b492197870b7539b1aa1b500cb65e701ef2d968f..a7e4f8e5c6289948bb556d212d5ded5492d3a60b 100644 (file)
@@ -26,7 +26,6 @@
 use syntax::ast;
 use syntax_pos::Span;
 
-use crate::{check_type_alias_enum_variants_enabled};
 use self::probe::{IsSuggestion, ProbeScope};
 
 pub fn provide(providers: &mut ty::query::Providers<'_>) {
@@ -197,7 +196,7 @@ pub fn lookup_method(
         )?;
 
         for import_id in &pick.import_ids {
-            let import_def_id = self.tcx.hir().local_def_id_from_hir_id(*import_id);
+            let import_def_id = self.tcx.hir().local_def_id(*import_id);
             debug!("used_trait_import: {:?}", import_def_id);
             Lrc::get_mut(&mut self.tables.borrow_mut().used_trait_imports)
                 .unwrap().insert(import_def_id);
@@ -417,8 +416,6 @@ pub fn resolve_ufcs(
                     tcx.hygienic_eq(method_name, vd.ident, adt_def.did)
                 });
                 if let Some(variant_def) = variant_def {
-                    check_type_alias_enum_variants_enabled(tcx, span);
-
                     // Braced variants generate unusable names in value namespace (reserved for
                     // possible future use), so variants resolved as associated items may refer to
                     // them as well. It's ok to use the variant's id as a ctor id since an
@@ -437,7 +434,7 @@ pub fn resolve_ufcs(
                                        self_ty, expr_id, ProbeScope::TraitsInScope)?;
         debug!("resolve_ufcs: pick={:?}", pick);
         for import_id in pick.import_ids {
-            let import_def_id = tcx.hir().local_def_id_from_hir_id(import_id);
+            let import_def_id = tcx.hir().local_def_id(import_id);
             debug!("resolve_ufcs: used_trait_import: {:?}", import_def_id);
             Lrc::get_mut(&mut self.tables.borrow_mut().used_trait_imports)
                 .unwrap().insert(import_def_id);
index 661883f2ac11d6916b2e7d1dfbe370bb6ada856a..bd4cf9d208684de104e9da519c6a97502a7eb58b 100644 (file)
@@ -970,9 +970,9 @@ fn pick(mut self) -> PickResult<'tcx> {
 
         debug!("pick: actual search failed, assemble diagnotics");
 
-        let static_candidates = mem::replace(&mut self.static_candidates, vec![]);
+        let static_candidates = mem::take(&mut self.static_candidates);
         let private_candidate = self.private_candidate.take();
-        let unsatisfied_predicates = mem::replace(&mut self.unsatisfied_predicates, vec![]);
+        let unsatisfied_predicates = mem::take(&mut self.unsatisfied_predicates);
 
         // things failed, so lets look at all traits, for diagnostic purposes now:
         self.reset();
index fa1b07d2dcfcdfdfe4189d1013d44ccc15c2c807..8dcfa184d7dad5aff8adc53a04756ee7e26bb8b6 100644 (file)
@@ -775,12 +775,12 @@ fn cmp(&self, other: &TraitInfo) -> Ordering {
 }
 
 /// Retrieves all traits in this crate and any dependent crates.
-pub fn all_traits<'tcx>(tcx: TyCtxt<'tcx>) -> Vec<TraitInfo> {
+pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
     tcx.all_traits(LOCAL_CRATE).iter().map(|&def_id| TraitInfo { def_id }).collect()
 }
 
 /// Computes all traits in this crate and any dependent crates.
-fn compute_all_traits<'tcx>(tcx: TyCtxt<'tcx>) -> Vec<DefId> {
+fn compute_all_traits(tcx: TyCtxt<'_>) -> Vec<DefId> {
     use hir::itemlikevisit;
 
     let mut traits = vec![];
@@ -797,7 +797,7 @@ fn visit_item(&mut self, i: &'v hir::Item) {
             match i.node {
                 hir::ItemKind::Trait(..) |
                 hir::ItemKind::TraitAlias(..) => {
-                    let def_id = self.map.local_def_id_from_hir_id(i.hir_id);
+                    let def_id = self.map.local_def_id(i.hir_id);
                     self.traits.push(def_id);
                 }
                 _ => ()
index 37866bab9009d9f5175a6499508804503048c24a..efe9079e19e4bb3268c3251a8bd0833cb4bf2c8d 100644 (file)
@@ -93,6 +93,7 @@
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
+use rustc::hir::ptr::P;
 use crate::middle::lang_items;
 use crate::namespace::Namespace;
 use rustc::infer::{self, InferCtxt, InferOk, InferResult};
 use syntax::ast;
 use syntax::attr;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
-use syntax::ptr::P;
 use syntax::source_map::{DUMMY_SP, original_sp};
 use syntax::symbol::{kw, sym};
 
@@ -698,31 +698,31 @@ fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
     fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
 }
 
-pub fn check_wf_new<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn check_wf_new(tcx: TyCtxt<'_>) {
     let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
     tcx.hir().krate().par_visit_all_item_likes(&mut visit);
 }
 
-fn check_mod_item_types<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
+fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
     tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
 }
 
-fn typeck_item_bodies<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) {
+fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
     debug_assert!(crate_num == LOCAL_CRATE);
     tcx.par_body_owners(|body_owner_def_id| {
         tcx.ensure().typeck_tables_of(body_owner_def_id);
     });
 }
 
-fn check_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
+fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
     wfcheck::check_item_well_formed(tcx, def_id);
 }
 
-fn check_trait_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
+fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
     wfcheck::check_trait_item(tcx, def_id);
 }
 
-fn check_impl_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
+fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
     wfcheck::check_impl_item(tcx, def_id);
 }
 
@@ -742,7 +742,7 @@ pub fn provide(providers: &mut Providers<'_>) {
     };
 }
 
-fn adt_destructor<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<ty::Destructor> {
+fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
     tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
 }
 
@@ -755,10 +755,10 @@ fn adt_destructor<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<ty::Destruct
 /// may not succeed. In some cases where this function returns `None`
 /// (notably closures), `typeck_tables(def_id)` would wind up
 /// redirecting to the owning function.
-fn primary_body_of<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn primary_body_of(
+    tcx: TyCtxt<'_>,
     id: hir::HirId,
-) -> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)> {
+) -> Option<(hir::BodyId, Option<&hir::FnDecl>)> {
     match tcx.hir().get(id) {
         Node::Item(item) => {
             match item.node {
@@ -796,7 +796,7 @@ fn primary_body_of<'tcx>(
     }
 }
 
-fn has_typeck_tables<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
+fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     // Closures' tables come from their outermost function,
     // as they are part of the same "inference environment".
     let outer_def_id = tcx.closure_base_def_id(def_id);
@@ -808,11 +808,11 @@ fn has_typeck_tables<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
     primary_body_of(tcx, id).is_some()
 }
 
-fn used_trait_imports<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx DefIdSet {
+fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
     &*tcx.typeck_tables_of(def_id).used_trait_imports
 }
 
-fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::TypeckTables<'tcx> {
+fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> {
     // Closures' tables come from their outermost function,
     // as they are part of the same "inference environment".
     let outer_def_id = tcx.closure_base_def_id(def_id);
@@ -856,7 +856,8 @@ fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::TypeckT
             let revealed_ty = if tcx.features().impl_trait_in_bindings {
                 fcx.instantiate_opaque_types_from_value(
                     id,
-                    &expected_type
+                    &expected_type,
+                    body.value.span,
                 )
             } else {
                 expected_type
@@ -912,7 +913,7 @@ fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::TypeckT
     tables
 }
 
-fn check_abi<'tcx>(tcx: TyCtxt<'tcx>, span: Span, abi: Abi) {
+fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
     if !tcx.sess.target.target.is_abi_supported(abi) {
         struct_span_err!(tcx.sess, span, E0570,
             "The ABI `{}` is not supported for the current target", abi).emit()
@@ -962,7 +963,8 @@ fn visit_local(&mut self, local: &'tcx hir::Local) {
                 let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
                     self.fcx.instantiate_opaque_types_from_value(
                         self.parent_id,
-                        &o_ty
+                        &o_ty,
+                        ty.span,
                     )
                 } else {
                     o_ty
@@ -1058,7 +1060,11 @@ fn check_fn<'a, 'tcx>(
 
     let declared_ret_ty = fn_sig.output();
     fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
-    let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty);
+    let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(
+        fn_id,
+        &declared_ret_ty,
+        decl.output.span(),
+    );
     fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
     fn_sig = fcx.tcx.mk_fn_sig(
         fn_sig.inputs().iter().cloned(),
@@ -1079,7 +1085,7 @@ fn check_fn<'a, 'tcx>(
         fcx.yield_ty = Some(yield_ty);
     }
 
-    let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir().local_def_id_from_hir_id(fn_id));
+    let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir().local_def_id(fn_id));
     let outer_hir_id = fcx.tcx.hir().as_local_hir_id(outer_def_id).unwrap();
     GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id, }.visit_body(body);
 
@@ -1177,7 +1183,7 @@ fn check_fn<'a, 'tcx>(
 
     // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
     if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
-        if panic_impl_did == fcx.tcx.hir().local_def_id_from_hir_id(fn_id) {
+        if panic_impl_did == fcx.tcx.hir().local_def_id(fn_id) {
             if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
                 // at this point we don't care if there are duplicate handlers or if the handler has
                 // the wrong signature as this value we'll be used when writing metadata and that
@@ -1235,7 +1241,7 @@ fn check_fn<'a, 'tcx>(
 
     // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
     if let Some(alloc_error_handler_did) = fcx.tcx.lang_items().oom() {
-        if alloc_error_handler_did == fcx.tcx.hir().local_def_id_from_hir_id(fn_id) {
+        if alloc_error_handler_did == fcx.tcx.hir().local_def_id(fn_id) {
             if let Some(alloc_layout_did) = fcx.tcx.lang_items().alloc_layout() {
                 if declared_ret_ty.sty != ty::Never {
                     fcx.tcx.sess.span_err(
@@ -1285,8 +1291,8 @@ fn check_fn<'a, 'tcx>(
     (fcx, gen_ty)
 }
 
-fn check_struct<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId, span: Span) {
-    let def_id = tcx.hir().local_def_id_from_hir_id(id);
+fn check_struct(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
+    let def_id = tcx.hir().local_def_id(id);
     let def = tcx.adt_def(def_id);
     def.destructor(tcx); // force the destructor to be evaluated
     check_representable(tcx, span, def_id);
@@ -1299,8 +1305,8 @@ fn check_struct<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId, span: Span) {
     check_packed(tcx, span, def_id);
 }
 
-fn check_union<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId, span: Span) {
-    let def_id = tcx.hir().local_def_id_from_hir_id(id);
+fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
+    let def_id = tcx.hir().local_def_id(id);
     let def = tcx.adt_def(def_id);
     def.destructor(tcx); // force the destructor to be evaluated
     check_representable(tcx, span, def_id);
@@ -1328,18 +1334,18 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
     debug!(
         "check_item_type(it.hir_id={}, it.name={})",
         it.hir_id,
-        tcx.def_path_str(tcx.hir().local_def_id_from_hir_id(it.hir_id))
+        tcx.def_path_str(tcx.hir().local_def_id(it.hir_id))
     );
     let _indenter = indenter();
     match it.node {
         // Consts can play a role in type-checking, so they are included here.
         hir::ItemKind::Static(..) => {
-            let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
+            let def_id = tcx.hir().local_def_id(it.hir_id);
             tcx.typeck_tables_of(def_id);
             maybe_check_static_with_link_section(tcx, def_id, it.span);
         }
         hir::ItemKind::Const(..) => {
-            tcx.typeck_tables_of(tcx.hir().local_def_id_from_hir_id(it.hir_id));
+            tcx.typeck_tables_of(tcx.hir().local_def_id(it.hir_id));
         }
         hir::ItemKind::Enum(ref enum_definition, _) => {
             check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
@@ -1347,7 +1353,7 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
         hir::ItemKind::Fn(..) => {} // entirely within check_item_body
         hir::ItemKind::Impl(.., ref impl_item_refs) => {
             debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
-            let impl_def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
+            let impl_def_id = tcx.hir().local_def_id(it.hir_id);
             if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
                 check_impl_items_against_trait(
                     tcx,
@@ -1361,7 +1367,7 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
             }
         }
         hir::ItemKind::Trait(..) => {
-            let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
+            let def_id = tcx.hir().local_def_id(it.hir_id);
             check_on_unimplemented(tcx, def_id, it);
         }
         hir::ItemKind::Struct(..) => {
@@ -1371,13 +1377,13 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
             check_union(tcx, it.hir_id, it.span);
         }
         hir::ItemKind::Existential(..) => {
-            let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
+            let def_id = tcx.hir().local_def_id(it.hir_id);
 
             let substs = InternalSubsts::identity_for_item(tcx, def_id);
             check_opaque(tcx, def_id, substs, it.span);
         }
         hir::ItemKind::Ty(..) => {
-            let def_id = tcx.hir().local_def_id_from_hir_id(it.hir_id);
+            let def_id = tcx.hir().local_def_id(it.hir_id);
             let pty_ty = tcx.type_of(def_id);
             let generics = tcx.generics_of(def_id);
             check_bounds_are_used(tcx, &generics, pty_ty);
@@ -1395,7 +1401,7 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
                 }
             } else {
                 for item in &m.items {
-                    let generics = tcx.generics_of(tcx.hir().local_def_id_from_hir_id(item.hir_id));
+                    let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
                     if generics.params.len() - generics.own_counts().lifetimes != 0 {
                         let mut err = struct_span_err!(
                             tcx.sess,
@@ -1461,14 +1467,14 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span)
     }
 }
 
-fn check_on_unimplemented<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, item: &hir::Item) {
-    let item_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id);
+fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item) {
+    let item_def_id = tcx.hir().local_def_id(item.hir_id);
     // an error would be reported if this fails.
     let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item_def_id);
 }
 
-fn report_forbidden_specialization<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn report_forbidden_specialization(
+    tcx: TyCtxt<'_>,
     impl_item: &hir::ImplItem,
     parent_impl: DefId,
 ) {
@@ -1545,7 +1551,7 @@ fn check_impl_items_against_trait<'tcx>(
     // and compatible with trait signature
     for impl_item in impl_items() {
         let ty_impl_item = tcx.associated_item(
-            tcx.hir().local_def_id_from_hir_id(impl_item.hir_id));
+            tcx.hir().local_def_id(impl_item.hir_id));
         let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id)
             .find(|ac| Namespace::from(&impl_item.node) == Namespace::from(ac.kind) &&
                        tcx.hygienic_eq(ty_impl_item.ident, ac.ident, impl_trait_ref.def_id))
@@ -1684,7 +1690,7 @@ fn check_impl_items_against_trait<'tcx>(
 /// Checks whether a type can be represented in memory. In particular, it
 /// identifies types that contain themselves without indirection through a
 /// pointer, which would mean their size is unbounded.
-fn check_representable<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, item_def_id: DefId) -> bool {
+fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: DefId) -> bool {
     let rty = tcx.type_of(item_def_id);
 
     // Check that it is possible to represent this type. This call identifies
@@ -1706,7 +1712,7 @@ fn check_representable<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, item_def_id: DefId) ->
     return true;
 }
 
-pub fn check_simd<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
+pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
     let t = tcx.type_of(def_id);
     if let ty::Adt(def, substs) = t.sty {
         if def.is_struct() {
@@ -1735,7 +1741,7 @@ pub fn check_simd<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
     }
 }
 
-fn check_packed<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
+fn check_packed(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
     let repr = tcx.adt_def(def_id).repr;
     if repr.packed() {
         for attr in tcx.get_attrs(def_id).iter() {
@@ -1759,7 +1765,7 @@ fn check_packed<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
     }
 }
 
-fn check_packed_inner<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, stack: &mut Vec<DefId>) -> bool {
+fn check_packed_inner(tcx: TyCtxt<'_>, def_id: DefId, stack: &mut Vec<DefId>) -> bool {
     let t = tcx.type_of(def_id);
     if stack.contains(&def_id) {
         debug!("check_packed_inner: {:?} is recursive", t);
@@ -1833,7 +1839,7 @@ fn bad_non_zero_sized_fields<'tcx>(
     err.emit();
 }
 
-fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
+fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
     let adt = tcx.adt_def(def_id);
     if !adt.repr.transparent() {
         return;
@@ -1903,7 +1909,7 @@ fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
 
 #[allow(trivial_numeric_casts)]
 pub fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, vs: &'tcx [hir::Variant], id: hir::HirId) {
-    let def_id = tcx.hir().local_def_id_from_hir_id(id);
+    let def_id = tcx.hir().local_def_id(id);
     let def = tcx.adt_def(def_id);
     def.destructor(tcx); // force the destructor to be evaluated
 
@@ -1931,7 +1937,7 @@ pub fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, vs: &'tcx [hir::Variant], i
 
     for v in vs {
         if let Some(ref e) = v.node.disr_expr {
-            tcx.typeck_tables_of(tcx.hir().local_def_id_from_hir_id(e.hir_id));
+            tcx.typeck_tables_of(tcx.hir().local_def_id(e.hir_id));
         }
     }
 
@@ -1982,7 +1988,7 @@ pub fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, vs: &'tcx [hir::Variant], i
     check_transparent(tcx, sp, def_id);
 }
 
-fn report_unexpected_variant_res<'tcx>(tcx: TyCtxt<'tcx>, res: Res, span: Span, qpath: &QPath) {
+fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span, qpath: &QPath) {
     span_err!(tcx.sess, span, E0533,
               "expected unit struct/variant or constant, found {} `{}`",
               res.descr(),
@@ -2000,7 +2006,7 @@ fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
         let tcx = self.tcx;
         let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
         let item_id = tcx.hir().ty_param_owner(hir_id);
-        let item_def_id = tcx.hir().local_def_id_from_hir_id(item_id);
+        let item_def_id = tcx.hir().local_def_id(item_id);
         let generics = tcx.generics_of(item_def_id);
         let index = generics.param_def_id_to_index[&def_id];
         tcx.arena.alloc(ty::GenericPredicates {
@@ -2445,8 +2451,9 @@ fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
         &self,
         parent_id: hir::HirId,
         value: &T,
+        value_span: Span,
     ) -> T {
-        let parent_def_id = self.tcx.hir().local_def_id_from_hir_id(parent_id);
+        let parent_def_id = self.tcx.hir().local_def_id(parent_id);
         debug!("instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
                parent_def_id,
                value);
@@ -2457,6 +2464,7 @@ fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
                 self.body_id,
                 self.param_env,
                 value,
+                value_span,
             )
         );
 
index 5313e1d0f73a34099c6835c155c8e0133a8ef5b1..c66d746d6e0293e78898a181fae714df9bcdd1e9 100644 (file)
@@ -138,7 +138,7 @@ pub fn regionck_expr(&self, body: &'tcx hir::Body) {
     /// types from which we should derive implied bounds, if any.
     pub fn regionck_item(&self, item_id: hir::HirId, span: Span, wf_tys: &[Ty<'tcx>]) {
         debug!("regionck_item(item.id={:?}, wf_tys={:?})", item_id, wf_tys);
-        let subject = self.tcx.hir().local_def_id_from_hir_id(item_id);
+        let subject = self.tcx.hir().local_def_id(item_id);
         let mut rcx = RegionCtxt::new(
             self,
             RepeatingScope(item_id),
index ac39757df74dc38b69a94e707bd4b9f0815f246a..155cabb27a92f0f1a94b873ffa1edae6aad90f5a 100644 (file)
@@ -248,7 +248,7 @@ fn final_upvar_tys(&self, closure_id: hir::HirId) -> Vec<Ty<'tcx>> {
         // This may change if abstract return types of some sort are
         // implemented.
         let tcx = self.tcx;
-        let closure_def_id = tcx.hir().local_def_id_from_hir_id(closure_id);
+        let closure_def_id = tcx.hir().local_def_id(closure_id);
 
         tcx.upvars(closure_def_id).iter().flat_map(|upvars| {
             upvars
index 034ff5f8347679387d5392ff5c4dde512e0a3be2..a41f4ec91a426e49e73237929cd9c6adada2443c 100644 (file)
@@ -3,7 +3,7 @@
 
 use crate::hir::def_id::DefId;
 use rustc::traits::{self, ObligationCauseCode};
-use rustc::ty::{self, Lift, Ty, TyCtxt, GenericParamDefKind, TypeFoldable, ToPredicate};
+use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable, ToPredicate};
 use rustc::ty::subst::{Subst, InternalSubsts};
 use rustc::util::nodemap::{FxHashSet, FxHashMap};
 use rustc::mir::interpret::ConstValue;
@@ -68,7 +68,7 @@ fn with_fcx<F>(&mut self, f: F)
 /// We do this check as a pre-pass before checking fn bodies because if these constraints are
 /// not included it frequently leads to confusing errors in fn bodies. So it's better to check
 /// the types first.
-pub fn check_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
+pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
     let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
     let item = tcx.hir().expect_item(hir_id);
 
@@ -95,7 +95,7 @@ pub fn check_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
         // won't be allowed unless there's an *explicit* implementation of `Send`
         // for `T`
         hir::ItemKind::Impl(_, polarity, defaultness, _, ref trait_ref, ref self_ty, _) => {
-            let is_auto = tcx.impl_trait_ref(tcx.hir().local_def_id_from_hir_id(item.hir_id))
+            let is_auto = tcx.impl_trait_ref(tcx.hir().local_def_id(item.hir_id))
                                 .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id));
             if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) {
                 tcx.sess.span_err(item.span, "impls of auto traits cannot be default");
@@ -156,7 +156,7 @@ pub fn check_item_well_formed<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
     }
 }
 
-pub fn check_trait_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
+pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) {
     let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
     let trait_item = tcx.hir().expect_trait_item(hir_id);
 
@@ -167,7 +167,7 @@ pub fn check_trait_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
     check_associated_item(tcx, trait_item.hir_id, trait_item.span, method_sig);
 }
 
-pub fn check_impl_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
+pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: DefId) {
     let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
     let impl_item = tcx.hir().expect_impl_item(hir_id);
 
@@ -178,8 +178,8 @@ pub fn check_impl_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
     check_associated_item(tcx, impl_item.hir_id, impl_item.span, method_sig);
 }
 
-fn check_associated_item<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn check_associated_item(
+    tcx: TyCtxt<'_>,
     item_id: hir::HirId,
     span: Span,
     sig_if_method: Option<&hir::MethodSig>,
@@ -188,7 +188,7 @@ fn check_associated_item<'tcx>(
 
     let code = ObligationCauseCode::MiscObligation;
     for_id(tcx, item_id, span).with_fcx(|fcx, tcx| {
-        let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id_from_hir_id(item_id));
+        let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id(item_id));
 
         let (mut implied_bounds, self_ty) = match item.container {
             ty::TraitContainer(_) => (vec![], fcx.tcx.mk_self_type()),
@@ -231,8 +231,8 @@ fn for_item<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item) -> CheckWfFcxBuilder<'tcx
     for_id(tcx, item.hir_id, item.span)
 }
 
-fn for_id<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId, span: Span) -> CheckWfFcxBuilder<'tcx> {
-    let def_id = tcx.hir().local_def_id_from_hir_id(id);
+fn for_id(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) -> CheckWfFcxBuilder<'_> {
+    let def_id = tcx.hir().local_def_id(id);
     CheckWfFcxBuilder {
         inherited: Inherited::build(tcx, def_id),
         id,
@@ -252,7 +252,7 @@ fn check_type_defn<'tcx, F>(
 {
     for_item(tcx, item).with_fcx(|fcx, fcx_tcx| {
         let variants = lookup_fields(fcx);
-        let def_id = fcx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let def_id = fcx.tcx.hir().local_def_id(item.hir_id);
         let packed = fcx.tcx.adt_def(def_id).repr.packed();
 
         for variant in &variants {
@@ -261,14 +261,15 @@ fn check_type_defn<'tcx, F>(
             let needs_drop_copy = || {
                 packed && {
                     let ty = variant.fields.last().unwrap().ty;
-                    fcx.tcx.erase_regions(&ty).lift_to_tcx(fcx_tcx)
-                        .map(|ty| ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id)))
-                        .unwrap_or_else(|| {
+                    let ty = fcx.tcx.erase_regions(&ty);
+                    if ty.has_local_value() {
                             fcx_tcx.sess.delay_span_bug(
                                 item.span, &format!("inference variables in {:?}", ty));
                             // Just treat unresolved type expression as if it needs drop.
                             true
-                        })
+                    } else {
+                        ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id))
+                    }
                 }
             };
             let all_sized =
@@ -316,10 +317,10 @@ fn check_type_defn<'tcx, F>(
     });
 }
 
-fn check_trait<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item) {
+fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item) {
     debug!("check_trait: {:?}", item.hir_id);
 
-    let trait_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id);
+    let trait_def_id = tcx.hir().local_def_id(item.hir_id);
 
     let trait_def = tcx.trait_def(trait_def_id);
     if trait_def.is_marker {
@@ -339,9 +340,9 @@ fn check_trait<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item) {
     });
 }
 
-fn check_item_fn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item) {
+fn check_item_fn(tcx: TyCtxt<'_>, item: &hir::Item) {
     for_item(tcx, item).with_fcx(|fcx, tcx| {
-        let def_id = fcx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let def_id = fcx.tcx.hir().local_def_id(item.hir_id);
         let sig = fcx.tcx.fn_sig(def_id);
         let sig = fcx.normalize_associated_types_in(item.span, &sig);
         let mut implied_bounds = vec![];
@@ -351,8 +352,8 @@ fn check_item_fn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item) {
     })
 }
 
-fn check_item_type<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn check_item_type(
+    tcx: TyCtxt<'_>,
     item_id: hir::HirId,
     ty_span: Span,
     allow_foreign_ty: bool,
@@ -360,7 +361,7 @@ fn check_item_type<'tcx>(
     debug!("check_item_type: {:?}", item_id);
 
     for_id(tcx, item_id, ty_span).with_fcx(|fcx, gcx| {
-        let ty = gcx.type_of(gcx.hir().local_def_id_from_hir_id(item_id));
+        let ty = gcx.type_of(gcx.hir().local_def_id(item_id));
         let item_ty = fcx.normalize_associated_types_in(ty_span, &ty);
 
         let mut forbid_unsized = true;
@@ -393,7 +394,7 @@ fn check_impl<'tcx>(
     debug!("check_impl: {:?}", item);
 
     for_item(tcx, item).with_fcx(|fcx, tcx| {
-        let item_def_id = fcx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let item_def_id = fcx.tcx.hir().local_def_id(item.hir_id);
 
         match *ast_trait_ref {
             Some(ref ast_trait_ref) => {
@@ -942,7 +943,7 @@ fn check_variances_for_type_defn<'tcx>(
     item: &hir::Item,
     hir_generics: &hir::Generics,
 ) {
-    let item_def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id);
+    let item_def_id = tcx.hir().local_def_id(item.hir_id);
     let ty = tcx.type_of(item_def_id);
     if tcx.has_error_field(ty) {
         return;
@@ -979,7 +980,7 @@ fn check_variances_for_type_defn<'tcx>(
     }
 }
 
-fn report_bivariance<'tcx>(tcx: TyCtxt<'tcx>, span: Span, param_name: ast::Name) {
+fn report_bivariance(tcx: TyCtxt<'_>, span: Span, param_name: ast::Name) {
     let mut err = error_392(tcx, span, param_name);
 
     let suggested_marker_id = tcx.lang_items().phantom_data();
@@ -1022,10 +1023,10 @@ fn reject_shadowing_parameters(tcx: TyCtxt<'_>, def_id: DefId) {
 
 /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
 /// aren't true.
-fn check_false_global_bounds<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, span: Span, id: hir::HirId) {
+fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) {
     let empty_env = ty::ParamEnv::empty();
 
-    let def_id = fcx.tcx.hir().local_def_id_from_hir_id(id);
+    let def_id = fcx.tcx.hir().local_def_id(id);
     let predicates = fcx.tcx.predicates_of(def_id).predicates
         .iter()
         .map(|(p, _)| *p)
@@ -1068,19 +1069,19 @@ pub fn new(tcx: TyCtxt<'tcx>) -> CheckTypeWellFormedVisitor<'tcx> {
 impl ParItemLikeVisitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> {
     fn visit_item(&self, i: &'tcx hir::Item) {
         debug!("visit_item: {:?}", i);
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(i.hir_id);
+        let def_id = self.tcx.hir().local_def_id(i.hir_id);
         self.tcx.ensure().check_item_well_formed(def_id);
     }
 
     fn visit_trait_item(&self, trait_item: &'tcx hir::TraitItem) {
         debug!("visit_trait_item: {:?}", trait_item);
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(trait_item.hir_id);
+        let def_id = self.tcx.hir().local_def_id(trait_item.hir_id);
         self.tcx.ensure().check_trait_item_well_formed(def_id);
     }
 
     fn visit_impl_item(&self, impl_item: &'tcx hir::ImplItem) {
         debug!("visit_impl_item: {:?}", impl_item);
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(impl_item.hir_id);
+        let def_id = self.tcx.hir().local_def_id(impl_item.hir_id);
         self.tcx.ensure().check_impl_item_well_formed(def_id);
     }
 }
@@ -1100,9 +1101,11 @@ struct AdtField<'tcx> {
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn non_enum_variant(&self, struct_def: &hir::VariantData) -> AdtVariant<'tcx> {
         let fields = struct_def.fields().iter().map(|field| {
-            let field_ty = self.tcx.type_of(self.tcx.hir().local_def_id_from_hir_id(field.hir_id));
+            let field_ty = self.tcx.type_of(self.tcx.hir().local_def_id(field.hir_id));
             let field_ty = self.normalize_associated_types_in(field.span,
                                                               &field_ty);
+            let field_ty = self.resolve_vars_if_possible(&field_ty);
+            debug!("non_enum_variant: type of field {:?} is {:?}", field, field_ty);
             AdtField { ty: field_ty, span: field.span }
         })
         .collect();
@@ -1134,11 +1137,11 @@ fn impl_implied_bounds(&self, impl_def_id: DefId, span: Span) -> Vec<Ty<'tcx>> {
     }
 }
 
-fn error_392<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn error_392(
+    tcx: TyCtxt<'_>,
     span: Span,
     param_name: ast::Name,
-) -> DiagnosticBuilder<'tcx> {
+) -> DiagnosticBuilder<'_> {
     let mut err = struct_span_err!(tcx.sess, span, E0392,
                   "parameter `{}` is never used", param_name);
     err.span_label(span, "unused parameter");
index 6a95dec1c81bc2a58bd542f32768cd41c9fc6efc..a2632b20c2ecbca944f6bebedabb3f95d76c759f 100644 (file)
@@ -34,7 +34,7 @@
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn resolve_type_vars_in_body(&self, body: &'tcx hir::Body) -> &'tcx ty::TypeckTables<'tcx> {
         let item_id = self.tcx.hir().body_owner(body.id());
-        let item_def_id = self.tcx.hir().local_def_id_from_hir_id(item_id);
+        let item_def_id = self.tcx.hir().local_def_id(item_id);
 
         // This attribute causes us to dump some writeback information
         // in the form of errors, which is uSymbolfor unit tests.
@@ -363,10 +363,8 @@ fn visit_coercion_casts(&mut self) {
     }
 
     fn visit_free_region_map(&mut self) {
-        let free_region_map = self.tcx()
-            .lift_to_global(&self.fcx.tables.borrow().free_region_map);
-        let free_region_map = free_region_map.expect("all regions in free-region-map are global");
-        self.tables.free_region_map = free_region_map;
+        self.tables.free_region_map = self.fcx.tables.borrow().free_region_map.clone();
+        debug_assert!(!self.tables.free_region_map.elements().any(|r| r.has_local_value()));
     }
 
     fn visit_user_provided_tys(&mut self) {
@@ -381,12 +379,10 @@ fn visit_user_provided_tys(&mut self) {
                 local_id,
             };
 
-            let c_ty = if let Some(c_ty) = self.tcx().lift_to_global(c_ty) {
-                c_ty
-            } else {
+            if cfg!(debug_assertions) && c_ty.has_local_value() {
                 span_bug!(
                     hir_id.to_span(self.fcx.tcx),
-                    "writeback: `{:?}` missing from the global type context",
+                    "writeback: `{:?}` is a local value",
                     c_ty
                 );
             };
@@ -423,12 +419,10 @@ fn visit_user_provided_sigs(&mut self) {
         debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root);
 
         for (&def_id, c_sig) in fcx_tables.user_provided_sigs.iter() {
-            let c_sig = if let Some(c_sig) = self.tcx().lift_to_global(c_sig) {
-                c_sig
-            } else {
+            if cfg!(debug_assertions) && c_sig.has_local_value() {
                 span_bug!(
                     self.fcx.tcx.hir().span_if_local(def_id).unwrap(),
-                    "writeback: `{:?}` missing from the global type context",
+                    "writeback: `{:?}` is a local value",
                     c_sig
                 );
             };
@@ -592,10 +586,10 @@ fn visit_opaque_types(&mut self, span: Span) {
                 }
             }
 
-            if let Some(substs) = self.tcx().lift_to_global(&opaque_defn.substs) {
+            if !opaque_defn.substs.has_local_value() {
                 let new = ty::ResolvedOpaqueTy {
                     concrete_type: definition_ty,
-                    substs,
+                    substs: opaque_defn.substs,
                 };
 
                 let old = self.tables
@@ -617,7 +611,7 @@ fn visit_opaque_types(&mut self, span: Span) {
             } else {
                 self.tcx().sess.delay_span_bug(
                     span,
-                    "cannot lift `opaque_defn` substs to global type context",
+                    "`opaque_defn` is a local value",
                 );
             }
         }
@@ -743,20 +737,19 @@ fn visit_fru_field_types(&mut self) {
         }
     }
 
-    fn resolve<T>(&self, x: &T, span: &dyn Locatable) -> T::Lifted
+    fn resolve<T>(&self, x: &T, span: &dyn Locatable) -> T
     where
-        T: TypeFoldable<'tcx> + ty::Lift<'tcx>,
+        T: TypeFoldable<'tcx>,
     {
         let x = x.fold_with(&mut Resolver::new(self.fcx, span, self.body));
-        if let Some(lifted) = self.tcx().lift_to_global(&x) {
-            lifted
-        } else {
+        if cfg!(debug_assertions) && x.has_local_value() {
             span_bug!(
                 span.to_span(self.fcx.tcx),
-                "writeback: `{:?}` missing from the global type context",
+                "writeback: `{:?}` is a local value",
                 x
             );
         }
+        x
     }
 }
 
index 7e781eeec56a98b3a8a0d887fc632e0948f12755..ffc66ec16de139ed68602ea89f1d63bc7fd6fd9e 100644 (file)
@@ -13,7 +13,7 @@
 
 use rustc_data_structures::fx::FxHashMap;
 
-pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn check_crate(tcx: TyCtxt<'_>) {
     let mut used_trait_imports = DefIdSet::default();
     for &body_id in tcx.hir().krate().bodies.keys() {
         let item_def_id = tcx.hir().body_owner_def_id(body_id);
@@ -52,7 +52,7 @@ struct CheckVisitor<'tcx> {
 
 impl CheckVisitor<'tcx> {
     fn check_import(&self, id: hir::HirId, span: Span) {
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(id);
+        let def_id = self.tcx.hir().local_def_id(id);
         if !self.tcx.maybe_unused_trait_import(def_id) {
             return;
         }
@@ -70,7 +70,7 @@ fn check_import(&self, id: hir::HirId, span: Span) {
     }
 }
 
-fn unused_crates_lint<'tcx>(tcx: TyCtxt<'tcx>) {
+fn unused_crates_lint(tcx: TyCtxt<'_>) {
     let lint = lint::builtin::UNUSED_EXTERN_CRATES;
 
     // Collect first the crates that are completely unused.  These we
@@ -219,7 +219,7 @@ struct ExternCrateToLint {
 impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CollectExternCrateVisitor<'a, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
         if let hir::ItemKind::ExternCrate(orig_name) = item.node {
-            let extern_crate_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+            let extern_crate_def_id = self.tcx.hir().local_def_id(item.hir_id);
             self.crates_to_lint.push(
                 ExternCrateToLint {
                     def_id: extern_crate_def_id,
index 42deeaf31f4279d71ee1e85f9abb866876b63961..a95b9a03dcf77d90b449f4fbabb9553084c918cc 100644 (file)
@@ -17,7 +17,7 @@
 use hir::Node;
 use rustc::hir::{self, ItemKind};
 
-pub fn check_trait<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) {
+pub fn check_trait(tcx: TyCtxt<'_>, trait_def_id: DefId) {
     Checker { tcx, trait_def_id }
         .check(tcx.lang_items().drop_trait(), visit_implementation_of_drop)
         .check(tcx.lang_items().copy_trait(), visit_implementation_of_copy)
@@ -38,7 +38,7 @@ fn check<F>(&self, trait_def_id: Option<DefId>, mut f: F) -> &Self
     {
         if Some(self.trait_def_id) == trait_def_id {
             for &impl_id in self.tcx.hir().trait_impls(self.trait_def_id) {
-                let impl_def_id = self.tcx.hir().local_def_id_from_hir_id(impl_id);
+                let impl_def_id = self.tcx.hir().local_def_id(impl_id);
                 f(self.tcx, impl_def_id);
             }
         }
@@ -46,7 +46,7 @@ fn check<F>(&self, trait_def_id: Option<DefId>, mut f: F) -> &Self
     }
 }
 
-fn visit_implementation_of_drop<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) {
+fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: DefId) {
     if let ty::Adt(..) = tcx.type_of(impl_did).sty {
         /* do nothing */
     } else {
@@ -74,7 +74,7 @@ fn visit_implementation_of_drop<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) {
     }
 }
 
-fn visit_implementation_of_copy<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) {
+fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: DefId) {
     debug!("visit_implementation_of_copy: impl_did={:?}", impl_did);
 
     let impl_hir_id = if let Some(n) = tcx.hir().as_local_hir_id(impl_did) {
@@ -154,7 +154,7 @@ fn visit_implementation_of_coerce_unsized(tcx: TyCtxt<'tcx>, impl_did: DefId) {
     }
 }
 
-fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) {
+fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: DefId) {
     debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}",
            impl_did);
     if impl_did.is_local() {
index 6088c03fc06819eb37de948b15c2d40fdd44cb5d..fb79a85ea25bf9ffb5c4afd88f5760d3a870ba58 100644 (file)
@@ -7,7 +7,6 @@
 //! `tcx.inherent_impls(def_id)`). That value, however,
 //! is computed by selecting an idea from this table.
 
-use rustc::dep_graph::DepKind;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::hir;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use syntax_pos::Span;
 
 /// On-demand query: yields a map containing all types mapped to their inherent impls.
-pub fn crate_inherent_impls<'tcx>(
-    tcx: TyCtxt<'tcx>,
+pub fn crate_inherent_impls(
+    tcx: TyCtxt<'_>,
     crate_num: CrateNum,
-) -> &'tcx CrateInherentImpls {
+) -> &CrateInherentImpls {
     assert_eq!(crate_num, LOCAL_CRATE);
 
     let krate = tcx.hir().krate();
@@ -33,38 +32,14 @@ pub fn crate_inherent_impls<'tcx>(
 }
 
 /// On-demand query: yields a vector of the inherent impls for a specific type.
-pub fn inherent_impls<'tcx>(tcx: TyCtxt<'tcx>, ty_def_id: DefId) -> &'tcx [DefId] {
+pub fn inherent_impls(tcx: TyCtxt<'_>, ty_def_id: DefId) -> &[DefId] {
     assert!(ty_def_id.is_local());
 
-    // NB. Until we adopt the red-green dep-tracking algorithm (see
-    // [the plan] for details on that), we do some hackery here to get
-    // the dependencies correct.  Basically, we use a `with_ignore` to
-    // read the result we want. If we didn't have the `with_ignore`,
-    // we would wind up with a dependency on the entire crate, which
-    // we don't want. Then we go and add dependencies on all the impls
-    // in the result (which is what we wanted).
-    //
-    // The result is a graph with an edge from `Hir(I)` for every impl
-    // `I` defined on some type `T` to `CoherentInherentImpls(T)`,
-    // thus ensuring that if any of those impls change, the set of
-    // inherent impls is considered dirty.
-    //
-    // [the plan]: https://github.com/rust-lang/rust-roadmap/issues/4
-
-    let result = tcx.dep_graph.with_ignore(|| {
-        let crate_map = tcx.crate_inherent_impls(ty_def_id.krate);
-        match crate_map.inherent_impls.get(&ty_def_id) {
-            Some(v) => &v[..],
-            None => &[],
-        }
-    });
-
-    for &impl_def_id in &result[..] {
-        let def_path_hash = tcx.def_path_hash(impl_def_id);
-        tcx.dep_graph.read(def_path_hash.to_dep_node(DepKind::Hir));
+    let crate_map = tcx.crate_inherent_impls(ty_def_id.krate);
+    match crate_map.inherent_impls.get(&ty_def_id) {
+        Some(v) => &v[..],
+        None => &[],
     }
-
-    result
 }
 
 struct InherentCollect<'tcx> {
@@ -79,7 +54,7 @@ fn visit_item(&mut self, item: &hir::Item) {
             _ => return
         };
 
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let def_id = self.tcx.hir().local_def_id(item.hir_id);
         let self_ty = self.tcx.type_of(def_id);
         let lang_items = self.tcx.lang_items();
         match self_ty.sty {
@@ -282,7 +257,7 @@ fn check_def_id(&mut self, item: &hir::Item, def_id: DefId) {
             // Add the implementation to the mapping from implementation to base
             // type def ID, if there is a base type for this implementation and
             // the implementation does not have any associated traits.
-            let impl_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+            let impl_def_id = self.tcx.hir().local_def_id(item.hir_id);
             let vec = self.impls_map.inherent_impls.entry(def_id).or_default();
             vec.push(impl_def_id);
         } else {
index aae1b1777a30f77f7cf93a426c3c0e1fd34bec21..04b59a63e1d8ae788b7628c0639180f816dbff10 100644 (file)
@@ -5,7 +5,7 @@
 use rustc::traits::{self, IntercrateMode};
 use rustc::ty::TyCtxt;
 
-pub fn crate_inherent_impls_overlap_check<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) {
+pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, crate_num: CrateNum) {
     assert_eq!(crate_num, LOCAL_CRATE);
     let krate = tcx.hir().krate();
     krate.visit_all_item_likes(&mut InherentOverlapChecker { tcx });
@@ -89,7 +89,7 @@ fn visit_item(&mut self, item: &'v hir::Item) {
             hir::ItemKind::Struct(..) |
             hir::ItemKind::Trait(..) |
             hir::ItemKind::Union(..) => {
-                let type_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+                let type_def_id = self.tcx.hir().local_def_id(item.hir_id);
                 self.check_for_overlapping_inherent_impls(type_def_id);
             }
             _ => {}
index 4336e861ce216a50151adbad311431f90e367f45..1d0e433f07b3a90acc768c97df76f0f03fe4f3be 100644 (file)
@@ -18,8 +18,8 @@
 mod orphan;
 mod unsafety;
 
-fn check_impl<'tcx>(tcx: TyCtxt<'tcx>, hir_id: HirId) {
-    let impl_def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
+fn check_impl(tcx: TyCtxt<'_>, hir_id: HirId) {
+    let impl_def_id = tcx.hir().local_def_id(hir_id);
 
     // If there are no traits, then this implementation must have a
     // base type.
@@ -124,7 +124,7 @@ pub fn provide(providers: &mut Providers<'_>) {
     };
 }
 
-fn coherent_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
+fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) {
     let impls = tcx.hir().trait_impls(def_id);
     for &impl_id in impls {
         check_impl(tcx, impl_id);
@@ -135,7 +135,7 @@ fn coherent_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) {
     builtin::check_trait(tcx, def_id);
 }
 
-pub fn check_coherence<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn check_coherence(tcx: TyCtxt<'_>) {
     for &trait_def_id in tcx.hir().krate().trait_impls.keys() {
         tcx.ensure().coherent_trait(trait_def_id);
     }
@@ -152,7 +152,7 @@ pub fn check_coherence<'tcx>(tcx: TyCtxt<'tcx>) {
 /// same type. Likewise, no two inherent impls for a given type
 /// constructor provide a method with the same name.
 fn check_impl_overlap<'tcx>(tcx: TyCtxt<'tcx>, hir_id: HirId) {
-    let impl_def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
+    let impl_def_id = tcx.hir().local_def_id(hir_id);
     let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
     let trait_def_id = trait_ref.def_id;
 
index 4e6fcfe0593e2393a5bb0f765c6fd5c310af2ec3..299e18337bd309aa1d110353429f097d1b3f4b0e 100644 (file)
@@ -6,7 +6,7 @@
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir;
 
-pub fn check<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn check(tcx: TyCtxt<'_>) {
     let mut orphan = OrphanChecker { tcx };
     tcx.hir().krate().visit_all_item_likes(&mut orphan);
 }
@@ -22,7 +22,7 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
     /// to prevent inundating the user with a bunch of similar error
     /// reports.
     fn visit_item(&mut self, item: &hir::Item) {
-        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let def_id = self.tcx.hir().local_def_id(item.hir_id);
         // "Trait" impl
         if let hir::ItemKind::Impl(.., Some(_), _, _) = item.node {
             debug!("coherence2::orphan check: trait impl {}",
index c41a0e1514e6861da5c1fd1b2e68008f4da67df2..07fbfddd96e434e248fd323b3f56d5df41069cb7 100644 (file)
@@ -5,7 +5,7 @@
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir::{self, Unsafety};
 
-pub fn check<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn check(tcx: TyCtxt<'_>) {
     let mut unsafety = UnsafetyChecker { tcx };
     tcx.hir().krate().visit_all_item_likes(&mut unsafety);
 }
@@ -21,7 +21,7 @@ fn check_unsafety_coherence(&mut self,
                                 unsafety: hir::Unsafety,
                                 polarity: hir::ImplPolarity)
     {
-        let local_did = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let local_did = self.tcx.hir().local_def_id(item.hir_id);
         if let Some(trait_ref) = self.tcx.impl_trait_ref(local_did) {
             let trait_def = self.tcx.trait_def(trait_ref.def_id);
             let unsafe_attr = impl_generics.and_then(|generics| {
index 87e1166b7c041101ae8419b43d475251c8510ec9..09de228dd578034e87f409562b300a359aa07bb1 100644 (file)
@@ -56,7 +56,7 @@
 ///////////////////////////////////////////////////////////////////////////
 // Main entry point
 
-fn collect_mod_item_types<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
+fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
     tcx.hir().visit_item_likes_in_module(
         module_def_id,
         &mut CollectItemTypesVisitor { tcx }.as_deep_visitor()
@@ -124,12 +124,12 @@ fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
                 hir::GenericParamKind::Type {
                     default: Some(_), ..
                 } => {
-                    let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id);
+                    let def_id = self.tcx.hir().local_def_id(param.hir_id);
                     self.tcx.type_of(def_id);
                 }
                 hir::GenericParamKind::Type { .. } => {}
                 hir::GenericParamKind::Const { .. } => {
-                    let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id);
+                    let def_id = self.tcx.hir().local_def_id(param.hir_id);
                     self.tcx.type_of(def_id);
                 }
             }
@@ -139,7 +139,7 @@ fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
 
     fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
         if let hir::ExprKind::Closure(..) = expr.node {
-            let def_id = self.tcx.hir().local_def_id_from_hir_id(expr.hir_id);
+            let def_id = self.tcx.hir().local_def_id(expr.hir_id);
             self.tcx.generics_of(def_id);
             self.tcx.type_of(def_id);
         }
@@ -253,10 +253,10 @@ fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
     }
 }
 
-fn type_param_predicates<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn type_param_predicates(
+    tcx: TyCtxt<'_>,
     (item_def_id, def_id): (DefId, DefId),
-) -> &'tcx ty::GenericPredicates<'tcx> {
+) -> &ty::GenericPredicates<'_> {
     use rustc::hir::*;
 
     // In the AST, bounds can derive from two places. Either
@@ -265,7 +265,7 @@ fn type_param_predicates<'tcx>(
 
     let param_id = tcx.hir().as_local_hir_id(def_id).unwrap();
     let param_owner = tcx.hir().ty_param_owner(param_id);
-    let param_owner_def_id = tcx.hir().local_def_id_from_hir_id(param_owner);
+    let param_owner_def_id = tcx.hir().local_def_id(param_owner);
     let generics = tcx.generics_of(param_owner_def_id);
     let index = generics.param_def_id_to_index[&def_id];
     let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(param_id).as_interned_str());
@@ -381,11 +381,11 @@ fn type_parameter_bounds_in_generics(
 /// parameter with ID `param_id`. We use this so as to avoid running
 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
 /// conversion of the type to avoid inducing unnecessary cycles.
-fn is_param<'tcx>(tcx: TyCtxt<'tcx>, ast_ty: &hir::Ty, param_id: hir::HirId) -> bool {
+fn is_param(tcx: TyCtxt<'_>, ast_ty: &hir::Ty, param_id: hir::HirId) -> bool {
     if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = ast_ty.node {
         match path.res {
             Res::SelfTy(Some(def_id), None) | Res::Def(DefKind::TyParam, def_id) => {
-                def_id == tcx.hir().local_def_id_from_hir_id(param_id)
+                def_id == tcx.hir().local_def_id(param_id)
             }
             _ => false,
         }
@@ -394,10 +394,10 @@ fn is_param<'tcx>(tcx: TyCtxt<'tcx>, ast_ty: &hir::Ty, param_id: hir::HirId) ->
     }
 }
 
-fn convert_item<'tcx>(tcx: TyCtxt<'tcx>, item_id: hir::HirId) {
+fn convert_item(tcx: TyCtxt<'_>, item_id: hir::HirId) {
     let it = tcx.hir().expect_item(item_id);
     debug!("convert: item {} with id {}", it.ident, it.hir_id);
-    let def_id = tcx.hir().local_def_id_from_hir_id(item_id);
+    let def_id = tcx.hir().local_def_id(item_id);
     match it.node {
         // These don't define types.
         hir::ItemKind::ExternCrate(_)
@@ -406,7 +406,7 @@ fn convert_item<'tcx>(tcx: TyCtxt<'tcx>, item_id: hir::HirId) {
         | hir::ItemKind::GlobalAsm(_) => {}
         hir::ItemKind::ForeignMod(ref foreign_mod) => {
             for item in &foreign_mod.items {
-                let def_id = tcx.hir().local_def_id_from_hir_id(item.hir_id);
+                let def_id = tcx.hir().local_def_id(item.hir_id);
                 tcx.generics_of(def_id);
                 tcx.type_of(def_id);
                 tcx.predicates_of(def_id);
@@ -444,7 +444,7 @@ fn convert_item<'tcx>(tcx: TyCtxt<'tcx>, item_id: hir::HirId) {
             tcx.predicates_of(def_id);
 
             for f in struct_def.fields() {
-                let def_id = tcx.hir().local_def_id_from_hir_id(f.hir_id);
+                let def_id = tcx.hir().local_def_id(f.hir_id);
                 tcx.generics_of(def_id);
                 tcx.type_of(def_id);
                 tcx.predicates_of(def_id);
@@ -476,9 +476,9 @@ fn convert_item<'tcx>(tcx: TyCtxt<'tcx>, item_id: hir::HirId) {
     }
 }
 
-fn convert_trait_item<'tcx>(tcx: TyCtxt<'tcx>, trait_item_id: hir::HirId) {
+fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) {
     let trait_item = tcx.hir().expect_trait_item(trait_item_id);
-    let def_id = tcx.hir().local_def_id_from_hir_id(trait_item.hir_id);
+    let def_id = tcx.hir().local_def_id(trait_item.hir_id);
     tcx.generics_of(def_id);
 
     match trait_item.node {
@@ -497,8 +497,8 @@ fn convert_trait_item<'tcx>(tcx: TyCtxt<'tcx>, trait_item_id: hir::HirId) {
     tcx.predicates_of(def_id);
 }
 
-fn convert_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item_id: hir::HirId) {
-    let def_id = tcx.hir().local_def_id_from_hir_id(impl_item_id);
+fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::HirId) {
+    let def_id = tcx.hir().local_def_id(impl_item_id);
     tcx.generics_of(def_id);
     tcx.type_of(def_id);
     tcx.predicates_of(def_id);
@@ -507,8 +507,8 @@ fn convert_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item_id: hir::HirId) {
     }
 }
 
-fn convert_variant_ctor<'tcx>(tcx: TyCtxt<'tcx>, ctor_id: hir::HirId) {
-    let def_id = tcx.hir().local_def_id_from_hir_id(ctor_id);
+fn convert_variant_ctor(tcx: TyCtxt<'_>, ctor_id: hir::HirId) {
+    let def_id = tcx.hir().local_def_id(ctor_id);
     tcx.generics_of(def_id);
     tcx.type_of(def_id);
     tcx.predicates_of(def_id);
@@ -525,7 +525,7 @@ fn convert_enum_variant_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, variants:
         let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
         prev_discr = Some(
             if let Some(ref e) = variant.node.disr_expr {
-                let expr_did = tcx.hir().local_def_id_from_hir_id(e.hir_id);
+                let expr_did = tcx.hir().local_def_id(e.hir_id);
                 def.eval_explicit_discr(tcx, expr_did)
             } else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
                 Some(discr)
@@ -548,7 +548,7 @@ fn convert_enum_variant_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, variants:
         );
 
         for f in variant.node.data.fields() {
-            let def_id = tcx.hir().local_def_id_from_hir_id(f.hir_id);
+            let def_id = tcx.hir().local_def_id(f.hir_id);
             tcx.generics_of(def_id);
             tcx.type_of(def_id);
             tcx.predicates_of(def_id);
@@ -562,8 +562,8 @@ fn convert_enum_variant_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, variants:
     }
 }
 
-fn convert_variant<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn convert_variant(
+    tcx: TyCtxt<'_>,
     variant_did: Option<DefId>,
     ctor_did: Option<DefId>,
     ident: Ident,
@@ -578,7 +578,7 @@ fn convert_variant<'tcx>(
         .fields()
         .iter()
         .map(|f| {
-            let fid = tcx.hir().local_def_id_from_hir_id(f.hir_id);
+            let fid = tcx.hir().local_def_id(f.hir_id);
             let dup_span = seen_fields.get(&f.ident.modern()).cloned();
             if let Some(prev_span) = dup_span {
                 struct_span_err!(
@@ -619,7 +619,7 @@ fn convert_variant<'tcx>(
     )
 }
 
-fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::AdtDef {
+fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::AdtDef {
     use rustc::hir::*;
 
     let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
@@ -635,13 +635,13 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::AdtDef {
             let variants = def.variants
                 .iter()
                 .map(|v| {
-                    let variant_did = Some(tcx.hir().local_def_id_from_hir_id(v.node.id));
+                    let variant_did = Some(tcx.hir().local_def_id(v.node.id));
                     let ctor_did = v.node.data.ctor_hir_id()
-                        .map(|hir_id| tcx.hir().local_def_id_from_hir_id(hir_id));
+                        .map(|hir_id| tcx.hir().local_def_id(hir_id));
 
                     let discr = if let Some(ref e) = v.node.disr_expr {
                         distance_from_explicit = 0;
-                        ty::VariantDiscr::Explicit(tcx.hir().local_def_id_from_hir_id(e.hir_id))
+                        ty::VariantDiscr::Explicit(tcx.hir().local_def_id(e.hir_id))
                     } else {
                         ty::VariantDiscr::Relative(distance_from_explicit)
                     };
@@ -657,7 +657,7 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::AdtDef {
         ItemKind::Struct(ref def, _) => {
             let variant_did = None;
             let ctor_did = def.ctor_hir_id()
-                .map(|hir_id| tcx.hir().local_def_id_from_hir_id(hir_id));
+                .map(|hir_id| tcx.hir().local_def_id(hir_id));
 
             let variants = std::iter::once(convert_variant(
                 tcx, variant_did, ctor_did, item.ident, ty::VariantDiscr::Relative(0), def,
@@ -669,7 +669,7 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::AdtDef {
         ItemKind::Union(ref def, _) => {
             let variant_did = None;
             let ctor_did = def.ctor_hir_id()
-                .map(|hir_id| tcx.hir().local_def_id_from_hir_id(hir_id));
+                .map(|hir_id| tcx.hir().local_def_id(hir_id));
 
             let variants = std::iter::once(convert_variant(
                 tcx, variant_did, ctor_did, item.ident, ty::VariantDiscr::Relative(0), def,
@@ -686,10 +686,10 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::AdtDef {
 /// Ensures that the super-predicates of the trait with a `DefId`
 /// of `trait_def_id` are converted and stored. This also ensures that
 /// the transitive super-predicates are converted.
-fn super_predicates_of<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn super_predicates_of(
+    tcx: TyCtxt<'_>,
     trait_def_id: DefId,
-) -> &'tcx ty::GenericPredicates<'tcx> {
+) -> &ty::GenericPredicates<'_> {
     debug!("super_predicates(trait_def_id={:?})", trait_def_id);
     let trait_hir_id = tcx.hir().as_local_hir_id(trait_def_id).unwrap();
 
@@ -740,7 +740,7 @@ fn super_predicates_of<'tcx>(
     })
 }
 
-fn trait_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::TraitDef {
+fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TraitDef {
     let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
     let item = tcx.hir().expect_item(hir_id);
 
@@ -879,7 +879,7 @@ fn has_late_bound_regions<'tcx>(
     }
 }
 
-fn generics_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics {
+fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics {
     use rustc::hir::*;
 
     let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
@@ -889,7 +889,7 @@ fn generics_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics {
         Node::ImplItem(_) | Node::TraitItem(_) | Node::Variant(_) |
         Node::Ctor(..) | Node::Field(_) => {
             let parent_id = tcx.hir().get_parent_item(hir_id);
-            Some(tcx.hir().local_def_id_from_hir_id(parent_id))
+            Some(tcx.hir().local_def_id(parent_id))
         }
         Node::Expr(&hir::Expr {
             node: hir::ExprKind::Closure(..),
@@ -937,7 +937,7 @@ fn generics_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics {
                     opt_self = Some(ty::GenericParamDef {
                         index: 0,
                         name: kw::SelfUpper.as_interned_str(),
-                        def_id: tcx.hir().local_def_id_from_hir_id(param_id),
+                        def_id: tcx.hir().local_def_id(param_id),
                         pure_wrt_drop: false,
                         kind: ty::GenericParamDefKind::Type {
                             has_default: false,
@@ -983,7 +983,7 @@ fn generics_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics {
             .map(|(i, param)| ty::GenericParamDef {
                 name: param.name.ident().as_interned_str(),
                 index: own_start + i as u32,
-                def_id: tcx.hir().local_def_id_from_hir_id(param.hir_id),
+                def_id: tcx.hir().local_def_id(param.hir_id),
                 pure_wrt_drop: param.pure_wrt_drop,
                 kind: ty::GenericParamDefKind::Lifetime,
             }),
@@ -1050,7 +1050,7 @@ fn generics_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics {
                 let param_def = ty::GenericParamDef {
                     index: type_start + i as u32,
                     name: param.name.ident().as_interned_str(),
-                    def_id: tcx.hir().local_def_id_from_hir_id(param.hir_id),
+                    def_id: tcx.hir().local_def_id(param.hir_id),
                     pure_wrt_drop: param.pure_wrt_drop,
                     kind,
                 };
@@ -1122,7 +1122,7 @@ fn generics_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::Generics {
     })
 }
 
-fn report_assoc_ty_on_inherent_impl<'tcx>(tcx: TyCtxt<'tcx>, span: Span) {
+fn report_assoc_ty_on_inherent_impl(tcx: TyCtxt<'_>, span: Span) {
     span_err!(
         tcx.sess,
         span,
@@ -1131,7 +1131,7 @@ fn report_assoc_ty_on_inherent_impl<'tcx>(tcx: TyCtxt<'tcx>, span: Span) {
     );
 }
 
-fn type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> {
+fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
     checked_type_of(tcx, def_id, true).unwrap()
 }
 
@@ -1139,7 +1139,7 @@ fn type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> {
 ///
 /// If you want to fail anyway, you can set the `fail` parameter to true, but in this case,
 /// you'd better just call [`type_of`] directly.
-pub fn checked_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fail: bool) -> Option<Ty<'tcx>> {
+pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<'_>> {
     use rustc::hir::*;
 
     let hir_id = match tcx.hir().as_local_hir_id(def_id) {
@@ -1353,7 +1353,7 @@ pub fn checked_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fail: bool) -> Op
                                 None
                             }
                         }
-                        Node::TraitRef(&hir::TraitRef { ref path, .. }) => Some(path),
+                        Node::TraitRef(&hir::TraitRef { ref path, .. }) => Some(&**path),
                         _ => None,
                     };
 
@@ -1464,7 +1464,7 @@ pub fn checked_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fail: bool) -> Op
     })
 }
 
-fn find_existential_constraints<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> {
+fn find_existential_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
     use rustc::hir::{ImplItem, Item, TraitItem};
 
     debug!("find_existential_constraints({:?})", def_id);
@@ -1623,7 +1623,7 @@ fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'thi
             intravisit::NestedVisitorMap::All(&self.tcx.hir())
         }
         fn visit_item(&mut self, it: &'tcx Item) {
-            let def_id = self.tcx.hir().local_def_id_from_hir_id(it.hir_id);
+            let def_id = self.tcx.hir().local_def_id(it.hir_id);
             // The existential type itself or its children are not within its reveal scope.
             if def_id != self.def_id {
                 self.check(def_id);
@@ -1631,7 +1631,7 @@ fn visit_item(&mut self, it: &'tcx Item) {
             }
         }
         fn visit_impl_item(&mut self, it: &'tcx ImplItem) {
-            let def_id = self.tcx.hir().local_def_id_from_hir_id(it.hir_id);
+            let def_id = self.tcx.hir().local_def_id(it.hir_id);
             // The existential type itself or its children are not within its reveal scope.
             if def_id != self.def_id {
                 self.check(def_id);
@@ -1639,7 +1639,7 @@ fn visit_impl_item(&mut self, it: &'tcx ImplItem) {
             }
         }
         fn visit_trait_item(&mut self, it: &'tcx TraitItem) {
-            let def_id = self.tcx.hir().local_def_id_from_hir_id(it.hir_id);
+            let def_id = self.tcx.hir().local_def_id(it.hir_id);
             self.check(def_id);
             intravisit::walk_trait_item(self, it);
         }
@@ -1682,7 +1682,7 @@ fn visit_trait_item(&mut self, it: &'tcx TraitItem) {
     }
 }
 
-fn fn_sig<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::PolyFnSig<'tcx> {
+fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
     use rustc::hir::*;
     use rustc::hir::Node::*;
 
@@ -1720,7 +1720,7 @@ fn fn_sig<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::PolyFnSig<'tcx> {
             let ty = tcx.type_of(tcx.hir().get_parent_did(hir_id));
             let inputs = data.fields()
                 .iter()
-                .map(|f| tcx.type_of(tcx.hir().local_def_id_from_hir_id(f.hir_id)));
+                .map(|f| tcx.type_of(tcx.hir().local_def_id(f.hir_id)));
             ty::Binder::bind(tcx.mk_fn_sig(
                 inputs,
                 ty,
@@ -1758,7 +1758,7 @@ fn fn_sig<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::PolyFnSig<'tcx> {
     }
 }
 
-fn impl_trait_ref<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<ty::TraitRef<'tcx>> {
+fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> {
     let icx = ItemCtxt::new(tcx, def_id);
 
     let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
@@ -1773,7 +1773,7 @@ fn impl_trait_ref<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<ty::TraitRef
     }
 }
 
-fn impl_polarity<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> hir::ImplPolarity {
+fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> hir::ImplPolarity {
     let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
     match tcx.hir().expect_item(hir_id).node {
         hir::ItemKind::Impl(_, polarity, ..) => polarity,
@@ -1804,10 +1804,10 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>(
 /// Returns a list of type predicates for the definition with ID `def_id`, including inferred
 /// lifetime constraints. This includes all predicates returned by `explicit_predicates_of`, plus
 /// inferred constraints concerning which regions outlive other regions.
-fn predicates_defined_on<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn predicates_defined_on(
+    tcx: TyCtxt<'_>,
     def_id: DefId,
-) -> &'tcx ty::GenericPredicates<'tcx> {
+) -> &ty::GenericPredicates<'_> {
     debug!("predicates_defined_on({:?})", def_id);
     let mut result = tcx.explicit_predicates_of(def_id);
     debug!(
@@ -1834,7 +1834,7 @@ fn predicates_defined_on<'tcx>(
 /// Returns a list of all type predicates (explicit and implicit) for the definition with
 /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
 /// `Self: Trait` predicates for traits.
-fn predicates_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::GenericPredicates<'tcx> {
+fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::GenericPredicates<'_> {
     let mut result = tcx.predicates_defined_on(def_id);
 
     if tcx.is_trait(def_id) {
@@ -1861,10 +1861,10 @@ fn predicates_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::GenericPre
 
 /// Returns a list of user-specified type predicates for the definition with ID `def_id`.
 /// N.B., this does not include any implied/inferred constraints.
-fn explicit_predicates_of<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn explicit_predicates_of(
+    tcx: TyCtxt<'_>,
     def_id: DefId,
-) -> &'tcx ty::GenericPredicates<'tcx> {
+) -> &ty::GenericPredicates<'_> {
     use rustc::hir::*;
     use rustc_data_structures::fx::FxHashSet;
 
@@ -2036,7 +2036,7 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
     let mut index = parent_count + has_own_self as u32;
     for param in early_bound_lifetimes_from_generics(tcx, ast_generics) {
         let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
-            def_id: tcx.hir().local_def_id_from_hir_id(param.hir_id),
+            def_id: tcx.hir().local_def_id(param.hir_id),
             index,
             name: param.name.ident().as_interned_str(),
         }));
@@ -2154,7 +2154,7 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
             };
 
             let assoc_ty =
-                tcx.mk_projection(tcx.hir().local_def_id_from_hir_id(trait_item.hir_id),
+                tcx.mk_projection(tcx.hir().local_def_id(trait_item.hir_id),
                     self_trait_ref.substs);
 
             let bounds = AstConv::compute_bounds(
@@ -2271,7 +2271,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
     fty
 }
 
-fn is_foreign_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
+fn is_foreign_item(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     match tcx.hir().get_if_local(def_id) {
         Some(Node::ForeignItem(..)) => true,
         Some(_) => false,
@@ -2279,7 +2279,7 @@ fn is_foreign_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
     }
 }
 
-fn static_mutability<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<hir::Mutability> {
+fn static_mutability(tcx: TyCtxt<'_>, def_id: DefId) -> Option<hir::Mutability> {
     match tcx.hir().get_if_local(def_id) {
         Some(Node::Item(&hir::Item {
             node: hir::ItemKind::Static(_, mutbl, _), ..
@@ -2387,7 +2387,7 @@ fn from_target_feature(
     }
 }
 
-fn linkage_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Linkage {
+fn linkage_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: &str) -> Linkage {
     use rustc::mir::mono::Linkage::*;
 
     // Use the names from src/llvm/docs/LangRef.rst here. Most types are only
@@ -2422,7 +2422,7 @@ fn linkage_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Linkag
     }
 }
 
-fn codegen_fn_attrs<'tcx>(tcx: TyCtxt<'tcx>, id: DefId) -> CodegenFnAttrs {
+fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
     let attrs = tcx.get_attrs(id);
 
     let mut codegen_fn_attrs = CodegenFnAttrs::new();
index b833d8555ee0a6b7bb825ea6572117c361424ad3..029a8f9c41f68f4de6b79f1c8781c83bba5d0dc4 100644 (file)
 /// impl<'a> Trait<Foo> for Bar { type X = &'a i32; }
 /// //   ^ 'a is unused and appears in assoc type, error
 /// ```
-pub fn impl_wf_check<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn impl_wf_check(tcx: TyCtxt<'_>) {
     // We will tag this as part of the WF check -- logically, it is,
     // but it's one that we must perform earlier than the rest of
     // WfCheck.
     for &module in tcx.hir().krate().modules.keys() {
-        tcx.ensure().check_mod_impl_wf(tcx.hir().local_def_id(module));
+        tcx.ensure().check_mod_impl_wf(tcx.hir().local_def_id_from_node_id(module));
     }
 }
 
-fn check_mod_impl_wf<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
+fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: DefId) {
     tcx.hir().visit_item_likes_in_module(
         module_def_id,
         &mut ImplWfCheck { tcx }
@@ -79,7 +79,7 @@ struct ImplWfCheck<'tcx> {
 impl ItemLikeVisitor<'tcx> for ImplWfCheck<'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         if let hir::ItemKind::Impl(.., ref impl_item_refs) = item.node {
-            let impl_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+            let impl_def_id = self.tcx.hir().local_def_id(item.hir_id);
             enforce_impl_params_are_constrained(self.tcx,
                                                 impl_def_id,
                                                 impl_item_refs);
@@ -92,8 +92,8 @@ fn visit_trait_item(&mut self, _trait_item: &'tcx hir::TraitItem) { }
     fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) { }
 }
 
-fn enforce_impl_params_are_constrained<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn enforce_impl_params_are_constrained(
+    tcx: TyCtxt<'_>,
     impl_def_id: DefId,
     impl_item_refs: &[hir::ImplItemRef],
 ) {
@@ -109,7 +109,7 @@ fn enforce_impl_params_are_constrained<'tcx>(
 
     // Disallow unconstrained lifetimes, but only if they appear in assoc types.
     let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs.iter()
-        .map(|item_ref| tcx.hir().local_def_id_from_hir_id(item_ref.id.hir_id))
+        .map(|item_ref| tcx.hir().local_def_id(item_ref.id.hir_id))
         .filter(|&def_id| {
             let item = tcx.associated_item(def_id);
             item.kind == ty::AssocKind::Type && item.defaultness.has_value()
@@ -183,7 +183,7 @@ impl trait, self type, or predicates",
 }
 
 /// Enforce that we do not have two items in an impl with the same name.
-fn enforce_impl_items_are_distinct<'tcx>(tcx: TyCtxt<'tcx>, impl_item_refs: &[hir::ImplItemRef]) {
+fn enforce_impl_items_are_distinct(tcx: TyCtxt<'_>, impl_item_refs: &[hir::ImplItemRef]) {
     let mut seen_type_items = FxHashMap::default();
     let mut seen_value_items = FxHashMap::default();
     for impl_item_ref in impl_item_refs {
index 182594e768468fa8db0e7987456caed71ea0825e..934fc684eaeda1a24d74d3e90d2b2ad594787d05 100644 (file)
 #![feature(slice_patterns)]
 #![feature(never_type)]
 #![feature(inner_deref)]
+#![feature(mem_take)]
 
 #![recursion_limit="256"]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #[macro_use] extern crate log;
 use rustc::middle;
 use rustc::session;
 use rustc::util::common::ErrorReported;
-use rustc::session::config::{EntryFnType, nightly_options};
+use rustc::session::config::EntryFnType;
 use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt};
 use rustc::ty::subst::SubstsRef;
 use rustc::ty::{self, Ty, TyCtxt};
@@ -124,21 +124,6 @@ pub struct TypeAndSubsts<'tcx> {
     ty: Ty<'tcx>,
 }
 
-fn check_type_alias_enum_variants_enabled<'tcx>(tcx: TyCtxt<'tcx>, span: Span) {
-    if !tcx.features().type_alias_enum_variants {
-        let mut err = tcx.sess.struct_span_err(
-            span,
-            "enum variants on type aliases are experimental"
-        );
-        if nightly_options::is_nightly_build() {
-            help!(&mut err,
-                "add `#![feature(type_alias_enum_variants)]` to the \
-                crate attributes to enable");
-        }
-        err.emit();
-    }
-}
-
 fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl, abi: Abi, span: Span) {
     if decl.c_variadic && !(abi == Abi::C || abi == Abi::Cdecl) {
         let mut err = struct_span_err!(tcx.sess, span, E0045,
@@ -176,7 +161,7 @@ fn require_same_types<'tcx>(
     })
 }
 
-fn check_main_fn_ty<'tcx>(tcx: TyCtxt<'tcx>, main_def_id: DefId) {
+fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
     let main_id = tcx.hir().as_local_hir_id(main_def_id).unwrap();
     let main_span = tcx.def_span(main_def_id);
     let main_t = tcx.type_of(main_def_id);
@@ -241,7 +226,7 @@ fn check_main_fn_ty<'tcx>(tcx: TyCtxt<'tcx>, main_def_id: DefId) {
     }
 }
 
-fn check_start_fn_ty<'tcx>(tcx: TyCtxt<'tcx>, start_def_id: DefId) {
+fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
     let start_id = tcx.hir().as_local_hir_id(start_def_id).unwrap();
     let start_span = tcx.def_span(start_def_id);
     let start_t = tcx.type_of(start_def_id);
@@ -298,7 +283,7 @@ fn check_start_fn_ty<'tcx>(tcx: TyCtxt<'tcx>, start_def_id: DefId) {
     }
 }
 
-fn check_for_entry_fn<'tcx>(tcx: TyCtxt<'tcx>) {
+fn check_for_entry_fn(tcx: TyCtxt<'_>) {
     match tcx.entry_fn(LOCAL_CRATE) {
         Some((def_id, EntryFnType::Main)) => check_main_fn_ty(tcx, def_id),
         Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id),
@@ -315,7 +300,7 @@ pub fn provide(providers: &mut Providers<'_>) {
     impl_wf_check::provide(providers);
 }
 
-pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) -> Result<(), ErrorReported> {
+pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> {
     tcx.sess.profiler(|p| p.start_activity("type-check crate"));
 
     // this ensures that later parts of type checking can assume that items
@@ -324,7 +309,7 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) -> Result<(), ErrorReported> {
     tcx.sess.track_errors(|| {
         time(tcx.sess, "type collecting", || {
             for &module in tcx.hir().krate().modules.keys() {
-                tcx.ensure().collect_mod_item_types(tcx.hir().local_def_id(module));
+                tcx.ensure().collect_mod_item_types(tcx.hir().local_def_id_from_node_id(module));
             }
         });
     })?;
@@ -359,7 +344,7 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) -> Result<(), ErrorReported> {
 
     time(tcx.sess, "item-types checking", || {
         for &module in tcx.hir().krate().modules.keys() {
-            tcx.ensure().check_mod_item_types(tcx.hir().local_def_id(module));
+            tcx.ensure().check_mod_item_types(tcx.hir().local_def_id_from_node_id(module));
         }
     });
 
@@ -384,7 +369,7 @@ pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty) -> Ty<'tcx> {
     // def-ID that will be used to determine the traits/predicates in
     // scope.  This is derived from the enclosing item-like thing.
     let env_node_id = tcx.hir().get_parent_item(hir_ty.hir_id);
-    let env_def_id = tcx.hir().local_def_id_from_hir_id(env_node_id);
+    let env_def_id = tcx.hir().local_def_id(env_node_id);
     let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id);
 
     astconv::AstConv::ast_ty_to_ty(&item_cx, hir_ty)
@@ -398,7 +383,7 @@ pub fn hir_trait_to_predicates<'tcx>(
     // def-ID that will be used to determine the traits/predicates in
     // scope.  This is derived from the enclosing item-like thing.
     let env_hir_id = tcx.hir().get_parent_item(hir_trait.hir_ref_id);
-    let env_def_id = tcx.hir().local_def_id_from_hir_id(env_hir_id);
+    let env_def_id = tcx.hir().local_def_id(env_hir_id);
     let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id);
     let mut bounds = Bounds::default();
     let (principal, _) = AstConv::instantiate_poly_trait_ref_inner(
index f2661b46b8b0c56a291cbcf994a63bf034db3cae..6b288347ad00683875b77773b81034fc701451a5 100644 (file)
@@ -52,7 +52,7 @@ pub struct InferVisitor<'cx, 'tcx> {
 
 impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for InferVisitor<'cx, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
-        let item_did = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let item_did = self.tcx.hir().local_def_id(item.hir_id);
 
         debug!("InferVisitor::visit_item(item={:?})", item_did);
 
index 63e41e01fbff5ffb512558aa931cbd9dfafeefd9..6b8f6fccd40d73fba36dbadffc54f2d3658d9496 100644 (file)
@@ -20,10 +20,10 @@ pub fn provide(providers: &mut Providers<'_>) {
     };
 }
 
-fn inferred_outlives_of<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn inferred_outlives_of(
+    tcx: TyCtxt<'_>,
     item_def_id: DefId,
-) -> &'tcx [ty::Predicate<'tcx>] {
+) -> &[ty::Predicate<'_>] {
     let id = tcx
         .hir()
         .as_local_hir_id(item_def_id)
@@ -70,10 +70,10 @@ fn inferred_outlives_of<'tcx>(
     }
 }
 
-fn inferred_outlives_crate<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn inferred_outlives_crate(
+    tcx: TyCtxt<'_>,
     crate_num: CrateNum,
-) -> &'tcx CratePredicatesMap<'tcx> {
+) -> &CratePredicatesMap<'_> {
     assert_eq!(crate_num, LOCAL_CRATE);
 
     // Compute a map from each struct/enum/union S to the **explicit**
index 4690cb9eada2ecf63b5ef67ea722081acfb90899..3ae646b3ac7ceb12976969bceaed44c37633ed58 100644 (file)
@@ -3,7 +3,7 @@
 use rustc::ty::TyCtxt;
 use syntax::symbol::sym;
 
-pub fn test_inferred_outlives<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn test_inferred_outlives(tcx: TyCtxt<'_>) {
     tcx.hir()
        .krate()
        .visit_all_item_likes(&mut OutlivesTest { tcx });
@@ -15,7 +15,7 @@ struct OutlivesTest<'tcx> {
 
 impl ItemLikeVisitor<'tcx> for OutlivesTest<'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
-        let item_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let item_def_id = self.tcx.hir().local_def_id(item.hir_id);
 
         // For unit testing: check for a special "rustc_outlives"
         // attribute and report an error with various results if found.
index c6b0da3fe474c2cbb0ba8bd4754fd976ffc529b2..783890da639f477ee40b64fdcdd1d3cddd155ae1 100644 (file)
@@ -125,7 +125,7 @@ pub fn insert_outlives_predicate<'tcx>(
     }
 }
 
-fn is_free_region<'tcx>(tcx: TyCtxt<'tcx>, region: Region<'_>) -> bool {
+fn is_free_region(tcx: TyCtxt<'_>, region: Region<'_>) -> bool {
     // First, screen for regions that might appear in a type header.
     match region {
         // These correspond to `T: 'a` relationships:
index 36f0dbcd2fcbddc01ba3e783ace2c3c4d7b93785..b75a0912657fac462901603a181f2b5807e1fccd 100644 (file)
@@ -120,7 +120,7 @@ fn visit_impl_item(&mut self, impl_item: &hir::ImplItem) {
 impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
     fn visit_node_helper(&mut self, id: hir::HirId) {
         let tcx = self.terms_cx.tcx;
-        let def_id = tcx.hir().local_def_id_from_hir_id(id);
+        let def_id = tcx.hir().local_def_id(id);
         self.build_constraints_for_item(def_id);
     }
 
index 1a8871a3da9dab3230dda20d4cd554c5c9919301..343d7ea656fbb27d532d63ed696f1db19c66dca7 100644 (file)
@@ -34,7 +34,7 @@ pub fn provide(providers: &mut Providers<'_>) {
     };
 }
 
-fn crate_variances<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx CrateVariancesMap<'tcx> {
+fn crate_variances(tcx: TyCtxt<'_>, crate_num: CrateNum) -> &CrateVariancesMap<'_> {
     assert_eq!(crate_num, LOCAL_CRATE);
     let mut arena = arena::TypedArena::default();
     let terms_cx = terms::determine_parameters_to_be_inferred(tcx, &mut arena);
@@ -42,7 +42,7 @@ fn crate_variances<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx CrateV
     tcx.arena.alloc(solve::solve_constraints(constraints_cx))
 }
 
-fn variances_of<'tcx>(tcx: TyCtxt<'tcx>, item_def_id: DefId) -> &'tcx [ty::Variance] {
+fn variances_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[ty::Variance] {
     let id = tcx.hir().as_local_hir_id(item_def_id).expect("expected local def-id");
     let unsupported = || {
         // Variance not relevant.
index 3851b918c4855a7ad0962cdae39d32621ba55c67..51fb5465d1e5922a842c9f0448a454d87cde0b8f 100644 (file)
@@ -99,7 +99,7 @@ fn create_map(&self) -> FxHashMap<DefId, &'tcx [ty::Variance]> {
 
         let solutions = &self.solutions;
         self.terms_cx.inferred_starts.iter().map(|(&id, &InferredIndex(start))| {
-            let def_id = tcx.hir().local_def_id_from_hir_id(id);
+            let def_id = tcx.hir().local_def_id(id);
             let generics = tcx.generics_of(def_id);
             let count = generics.count();
 
index 3f6eadeac333479d551915e128b0e8de401f243b..7af7c79bb3c0d7f300f0403ab4b28b980a39fc2c 100644 (file)
@@ -103,7 +103,7 @@ fn lang_items(tcx: TyCtxt<'_>) -> Vec<(hir::HirId, Vec<ty::Variance>)> {
 impl<'a, 'tcx> TermsContext<'a, 'tcx> {
     fn add_inferreds_for_item(&mut self, id: hir::HirId) {
         let tcx = self.tcx;
-        let def_id = tcx.hir().local_def_id_from_hir_id(id);
+        let def_id = tcx.hir().local_def_id(id);
         let count = tcx.generics_of(def_id).count();
 
         if count == 0 {
index cefc200f5cba82dba9e14976d6a008d950754abf..9f6266b316f3a69dc43b8b3581286b206f72e090 100644 (file)
@@ -3,7 +3,7 @@
 use rustc::ty::TyCtxt;
 use syntax::symbol::sym;
 
-pub fn test_variance<'tcx>(tcx: TyCtxt<'tcx>) {
+pub fn test_variance(tcx: TyCtxt<'_>) {
     tcx.hir().krate().visit_all_item_likes(&mut VarianceTest { tcx });
 }
 
@@ -13,7 +13,7 @@ struct VarianceTest<'tcx> {
 
 impl ItemLikeVisitor<'tcx> for VarianceTest<'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
-        let item_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let item_def_id = self.tcx.hir().local_def_id(item.hir_id);
 
         // For unit testing: check for a special "rustc_variance"
         // attribute and report an error with various results if found.
index 67113787915a3e251b455c5d117d87faabbd219f..ad211763a6c46e4be4106948c0ad873f7aecf6fb 100644 (file)
@@ -16,7 +16,7 @@
 
 use crate::html::escape::Escape;
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub enum Cfg {
     /// Accepts all configurations.
     True,
index 41a56756a1480c5fb6affb69a0969377c6b1189e..350bcc9dbc649f4daed64d2193783aedd82eb016 100644 (file)
@@ -20,6 +20,7 @@
 use rustc::hir;
 use rustc::hir::def::{CtorKind, DefKind, Res};
 use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc::hir::ptr::P;
 use rustc::ty::subst::{InternalSubsts, SubstsRef, UnpackedKind};
 use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
 use rustc::ty::fold::TypeFolder;
@@ -29,7 +30,6 @@
 use syntax::attr;
 use syntax::ext::base::MacroKind;
 use syntax::source_map::{dummy_spanned, Spanned};
-use syntax::ptr::P;
 use syntax::symbol::{Symbol, kw, sym};
 use syntax::symbol::InternedString;
 use syntax_pos::{self, Pos, FileName};
@@ -223,7 +223,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Crate {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct ExternalCrate {
     pub name: String,
     pub src: FileName,
@@ -281,14 +281,14 @@ fn clean(&self, cx: &DocContext<'_>) -> ExternalCrate {
                     hir::ItemKind::Mod(_) => {
                         as_primitive(Res::Def(
                             DefKind::Mod,
-                            cx.tcx.hir().local_def_id_from_hir_id(id.id),
+                            cx.tcx.hir().local_def_id(id.id),
                         ))
                     }
                     hir::ItemKind::Use(ref path, hir::UseKind::Single)
                     if item.vis.node.is_pub() => {
                         as_primitive(path.res).map(|(_, prim, attrs)| {
                             // Pretend the primitive is local.
-                            (cx.tcx.hir().local_def_id_from_hir_id(id.id), prim, attrs)
+                            (cx.tcx.hir().local_def_id(id.id), prim, attrs)
                         })
                     }
                     _ => None
@@ -325,13 +325,13 @@ fn clean(&self, cx: &DocContext<'_>) -> ExternalCrate {
                     hir::ItemKind::Mod(_) => {
                         as_keyword(Res::Def(
                             DefKind::Mod,
-                            cx.tcx.hir().local_def_id_from_hir_id(id.id),
+                            cx.tcx.hir().local_def_id(id.id),
                         ))
                     }
                     hir::ItemKind::Use(ref path, hir::UseKind::Single)
                     if item.vis.node.is_pub() => {
                         as_keyword(path.res).map(|(_, prim, attrs)| {
-                            (cx.tcx.hir().local_def_id_from_hir_id(id.id), prim, attrs)
+                            (cx.tcx.hir().local_def_id(id.id), prim, attrs)
                         })
                     }
                     _ => None
@@ -355,7 +355,7 @@ fn clean(&self, cx: &DocContext<'_>) -> ExternalCrate {
 /// Anything with a source location and set of attributes and, optionally, a
 /// name. That is, anything that can be documented. This doesn't correspond
 /// directly to the AST's concept of an item; it's a strict superset.
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone)]
 pub struct Item {
     /// Stringified span
     pub source: Span,
@@ -392,7 +392,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
 impl Item {
     /// Finds the `doc` attribute as a NameValue and returns the corresponding
     /// value found.
-    pub fn doc_value<'a>(&'a self) -> Option<&'a str> {
+    pub fn doc_value(&self) -> Option<&str> {
         self.attrs.doc_value()
     }
     /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
@@ -528,7 +528,7 @@ pub fn is_default(&self) -> bool {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub enum ItemEnum {
     ExternCrateItem(String, Option<String>),
     ImportItem(Import),
@@ -594,7 +594,7 @@ pub fn is_associated(&self) -> bool {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Module {
     pub items: Vec<Item>,
     pub is_crate: bool,
@@ -654,7 +654,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(self.id),
+            def_id: cx.tcx.hir().local_def_id_from_node_id(self.id),
             inner: ModuleItem(Module {
                is_crate: self.is_crate,
                items,
@@ -699,11 +699,11 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 
 pub trait AttributesExt {
     /// Finds an attribute as List and returns the list of attributes nested inside.
-    fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a>;
+    fn lists(&self, name: Symbol) -> ListAttributesIter<'_>;
 }
 
 impl AttributesExt for [ast::Attribute] {
-    fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> {
+    fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
         ListAttributesIter {
             attrs: self.iter(),
             current_list: Vec::new().into_iter(),
@@ -731,7 +731,7 @@ fn has_word(self, word: Symbol) -> bool {
 /// Included files are kept separate from inline doc comments so that proper line-number
 /// information can be given when a doctest fails. Sugared doc comments and "raw" doc comments are
 /// kept separate because of issue #42760.
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum DocFragment {
     /// A doc fragment created from a `///` or `//!` doc comment.
     SugaredDoc(usize, syntax_pos::Span, String),
@@ -781,7 +781,7 @@ fn from_iter<T>(iter: T) -> Self
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)]
+#[derive(Clone, Debug, Default)]
 pub struct Attributes {
     pub doc_strings: Vec<DocFragment>,
     pub other_attrs: Vec<ast::Attribute>,
@@ -952,7 +952,7 @@ pub fn from_ast(diagnostic: &::errors::Handler,
 
     /// Finds the `doc` attribute as a NameValue and returns the corresponding
     /// value found.
-    pub fn doc_value<'a>(&'a self) -> Option<&'a str> {
+    pub fn doc_value(&self) -> Option<&str> {
         self.doc_strings.first().map(|s| s.as_str())
     }
 
@@ -1037,7 +1037,7 @@ fn hash<H: Hasher>(&self, hasher: &mut H) {
 }
 
 impl AttributesExt for Attributes {
-    fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> {
+    fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
         self.other_attrs.lists(name)
     }
 }
@@ -1048,7 +1048,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Attributes {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum GenericBound {
     TraitBound(PolyTrait, hir::TraitBoundModifier),
     Outlives(Lifetime),
@@ -1231,7 +1231,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Option<Vec<GenericBound>> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct Lifetime(String);
 
 impl Lifetime {
@@ -1326,7 +1326,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Option<Lifetime> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum WherePredicate {
     BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
     RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
@@ -1464,7 +1464,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Type {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum GenericParamDefKind {
     Lifetime,
     Type {
@@ -1498,7 +1498,7 @@ pub fn get_type(&self, cx: &DocContext<'_>) -> Option<Type> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct GenericParamDef {
     pub name: String,
 
@@ -1588,7 +1588,7 @@ fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
             }
             hir::GenericParamKind::Type { ref default, synthetic } => {
                 (self.name.ident().name.clean(cx), GenericParamDefKind::Type {
-                    did: cx.tcx.hir().local_def_id_from_hir_id(self.hir_id),
+                    did: cx.tcx.hir().local_def_id(self.hir_id),
                     bounds: self.bounds.clean(cx),
                     default: default.clean(cx),
                     synthetic: synthetic,
@@ -1596,7 +1596,7 @@ fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
             }
             hir::GenericParamKind::Const { ref ty } => {
                 (self.name.ident().name.clean(cx), GenericParamDefKind::Const {
-                    did: cx.tcx.hir().local_def_id_from_hir_id(self.hir_id),
+                    did: cx.tcx.hir().local_def_id(self.hir_id),
                     ty: ty.clean(cx),
                 })
             }
@@ -1610,7 +1610,7 @@ fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
 }
 
 // maybe use a Generic enum and use Vec<Generic>?
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Default, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Default, Hash)]
 pub struct Generics {
     pub params: Vec<GenericParamDef>,
     pub where_predicates: Vec<WherePredicate>,
@@ -1874,7 +1874,7 @@ pub fn get_all_types(
     (all_types.into_iter().collect(), ret_types)
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Method {
     pub generics: Generics,
     pub decl: FnDecl,
@@ -1902,7 +1902,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Method {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct TyMethod {
     pub header: hir::FnHeader,
     pub decl: FnDecl,
@@ -1911,7 +1911,7 @@ pub struct TyMethod {
     pub ret_types: Vec<Type>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Function {
     pub decl: FnDecl,
     pub generics: Generics,
@@ -1926,7 +1926,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
             (self.generics.clean(cx), (self.decl, self.body).clean(cx))
         });
 
-        let did = cx.tcx.hir().local_def_id_from_hir_id(self.id);
+        let did = cx.tcx.hir().local_def_id(self.id);
         let constness = if cx.tcx.is_min_const_fn(did) {
             hir::Constness::Const
         } else {
@@ -1952,7 +1952,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct FnDecl {
     pub inputs: Arguments,
     pub output: FunctionRetTy,
@@ -1989,7 +1989,7 @@ pub fn sugared_async_return_type(&self) -> FunctionRetTy {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct Arguments {
     pub values: Vec<Argument>,
 }
@@ -2063,13 +2063,13 @@ fn clean(&self, cx: &DocContext<'_>) -> FnDecl {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct Argument {
     pub type_: Type,
     pub name: String,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
+#[derive(Clone, PartialEq, Debug)]
 pub enum SelfTy {
     SelfValue,
     SelfBorrowed(Option<Lifetime>, Mutability),
@@ -2093,7 +2093,7 @@ pub fn to_self(&self) -> Option<SelfTy> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum FunctionRetTy {
     Return(Type),
     DefaultReturn,
@@ -2117,7 +2117,7 @@ fn def_id(&self) -> Option<DefId> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Trait {
     pub auto: bool,
     pub unsafety: hir::Unsafety,
@@ -2136,7 +2136,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: attrs,
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -2153,7 +2153,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct TraitAlias {
     pub generics: Generics,
     pub bounds: Vec<GenericBound>,
@@ -2166,7 +2166,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs,
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -2229,7 +2229,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
                 AssocTypeItem(bounds.clean(cx), default.clean(cx))
             }
         };
-        let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id);
+        let local_did = cx.tcx.hir().local_def_id(self.hir_id);
         Item {
             name: Some(self.ident.name.clean(cx)),
             attrs: self.attrs.clean(cx),
@@ -2262,7 +2262,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
                 generics: Generics::default(),
             }, true),
         };
-        let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id);
+        let local_did = cx.tcx.hir().local_def_id(self.hir_id);
         Item {
             name: Some(self.ident.name.clean(cx)),
             source: self.span.clean(cx),
@@ -2437,7 +2437,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
 }
 
 /// A trait reference, which may have higher ranked lifetimes.
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct PolyTrait {
     pub trait_: Type,
     pub generic_params: Vec<GenericParamDef>,
@@ -2446,7 +2446,7 @@ pub struct PolyTrait {
 /// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original
 /// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most
 /// importantly, it does not preserve mutability or boxes.
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum Type {
     /// Structs/enums/traits (most that would be an `hir::TyKind::Path`).
     ResolvedPath {
@@ -2469,7 +2469,6 @@ pub enum Type {
     Array(Box<Type>, String),
     Never,
     CVarArgs,
-    Unique(Box<Type>),
     RawPointer(Mutability, Box<Type>),
     BorrowedRef {
         lifetime: Option<Lifetime>,
@@ -2491,7 +2490,7 @@ pub enum Type {
     ImplTrait(Vec<GenericBound>),
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Copy, Debug)]
+#[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
 pub enum PrimitiveType {
     Isize, I8, I16, I32, I64, I128,
     Usize, U8, U16, U32, U64, U128,
@@ -2510,7 +2509,7 @@ pub enum PrimitiveType {
     CVarArgs,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Copy, Debug)]
+#[derive(Clone, Copy, Debug)]
 pub enum TypeKind {
     Enum,
     Function,
@@ -2520,7 +2519,6 @@ pub enum TypeKind {
     Struct,
     Union,
     Trait,
-    Variant,
     Typedef,
     Foreign,
     Macro,
@@ -2759,7 +2757,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Type {
             }
             TyKind::Slice(ref ty) => Slice(box ty.clean(cx)),
             TyKind::Array(ref ty, ref length) => {
-                let def_id = cx.tcx.hir().local_def_id_from_hir_id(length.hir_id);
+                let def_id = cx.tcx.hir().local_def_id(length.hir_id);
                 let param_env = cx.tcx.param_env(def_id);
                 let substs = InternalSubsts::identity_for_item(cx.tcx, def_id);
                 let cid = GlobalId {
@@ -2831,7 +2829,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Type {
                                     if let Some(lt) = lifetime.cloned() {
                                         if !lt.is_elided() {
                                             let lt_def_id =
-                                                cx.tcx.hir().local_def_id_from_hir_id(param.hir_id);
+                                                cx.tcx.hir().local_def_id(param.hir_id);
                                             lt_substs.insert(lt_def_id, lt.clean(cx));
                                         }
                                     }
@@ -2839,7 +2837,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Type {
                                 }
                                 hir::GenericParamKind::Type { ref default, .. } => {
                                     let ty_param_def_id =
-                                        cx.tcx.hir().local_def_id_from_hir_id(param.hir_id);
+                                        cx.tcx.hir().local_def_id(param.hir_id);
                                     let mut j = 0;
                                     let type_ = generic_args.args.iter().find_map(|arg| {
                                         match arg {
@@ -2863,7 +2861,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Type {
                                 }
                                 hir::GenericParamKind::Const { .. } => {
                                     let const_param_def_id =
-                                        cx.tcx.hir().local_def_id_from_hir_id(param.hir_id);
+                                        cx.tcx.hir().local_def_id(param.hir_id);
                                     let mut j = 0;
                                     let const_ = generic_args.args.iter().find_map(|arg| {
                                         match arg {
@@ -2984,10 +2982,11 @@ fn clean(&self, cx: &DocContext<'_>) -> Type {
             ty::FnPtr(_) => {
                 let ty = cx.tcx.lift(self).expect("FnPtr lift failed");
                 let sig = ty.fn_sig(cx.tcx);
+                let local_def_id = cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID);
                 BareFunction(box BareFunctionDecl {
                     unsafety: sig.unsafety(),
                     generic_params: Vec::new(),
-                    decl: (cx.tcx.hir().local_def_id(ast::CRATE_NODE_ID), sig).clean(cx),
+                    decl: (local_def_id, sig).clean(cx),
                     abi: sig.abi(),
                 })
             }
@@ -3160,7 +3159,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Constant {
 
 impl Clean<Item> for hir::StructField {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
-        let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id);
+        let local_did = cx.tcx.hir().local_def_id(self.hir_id);
 
         Item {
             name: Some(self.ident.name).clean(cx),
@@ -3190,7 +3189,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
     }
 }
 
-#[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug)]
+#[derive(Clone, PartialEq, Eq, Debug)]
 pub enum Visibility {
     Public,
     Inherited,
@@ -3219,7 +3218,7 @@ fn clean(&self, _: &DocContext<'_>) -> Option<Visibility> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Struct {
     pub struct_type: doctree::StructType,
     pub generics: Generics,
@@ -3227,7 +3226,7 @@ pub struct Struct {
     pub fields_stripped: bool,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Union {
     pub struct_type: doctree::StructType,
     pub generics: Generics,
@@ -3241,7 +3240,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3261,7 +3260,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3278,7 +3277,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
 /// This is a more limited form of the standard Struct, different in that
 /// it lacks the things most items have (name, id, parameterization). Found
 /// only as a variant in an enum.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct VariantStruct {
     pub struct_type: doctree::StructType,
     pub fields: Vec<Item>,
@@ -3295,7 +3294,7 @@ fn clean(&self, cx: &DocContext<'_>) -> VariantStruct {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Enum {
     pub variants: IndexVec<VariantIdx, Item>,
     pub generics: Generics,
@@ -3308,7 +3307,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3321,7 +3320,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Variant {
     pub kind: VariantKind,
 }
@@ -3335,7 +3334,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
             visibility: None,
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
-            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             inner: VariantItem(Variant {
                 kind: self.def.clean(cx),
             }),
@@ -3384,7 +3383,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub enum VariantKind {
     CLike,
     Tuple(Vec<Type>),
@@ -3402,7 +3401,7 @@ fn clean(&self, cx: &DocContext<'_>) -> VariantKind {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Span {
     pub filename: FileName,
     pub loline: usize,
@@ -3448,7 +3447,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Span {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct Path {
     pub global: bool,
     pub res: Res,
@@ -3471,7 +3470,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Path {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum GenericArg {
     Lifetime(Lifetime),
     Type(Type),
@@ -3488,7 +3487,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum GenericArgs {
     AngleBracketed {
         args: Vec<GenericArg>,
@@ -3528,7 +3527,7 @@ fn clean(&self, cx: &DocContext<'_>) -> GenericArgs {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct PathSegment {
     pub name: String,
     pub args: GenericArgs,
@@ -3553,7 +3552,6 @@ fn strip_type(ty: Type) -> Type {
         }
         Type::Slice(inner_ty) => Type::Slice(Box::new(strip_type(*inner_ty))),
         Type::Array(inner_ty, s) => Type::Array(Box::new(strip_type(*inner_ty)), s),
-        Type::Unique(inner_ty) => Type::Unique(Box::new(strip_type(*inner_ty))),
         Type::RawPointer(m, inner_ty) => Type::RawPointer(m, Box::new(strip_type(*inner_ty))),
         Type::BorrowedRef { lifetime, mutability, type_ } => {
             Type::BorrowedRef { lifetime, mutability, type_: Box::new(strip_type(*type_)) }
@@ -3625,7 +3623,7 @@ fn clean(&self, _: &DocContext<'_>) -> String {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Typedef {
     pub type_: Type,
     pub generics: Generics,
@@ -3637,7 +3635,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3649,7 +3647,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Existential {
     pub bounds: Vec<GenericBound>,
     pub generics: Generics,
@@ -3661,7 +3659,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3673,7 +3671,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct BareFunctionDecl {
     pub unsafety: hir::Unsafety,
     pub generic_params: Vec<GenericParamDef>,
@@ -3695,7 +3693,7 @@ fn clean(&self, cx: &DocContext<'_>) -> BareFunctionDecl {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Static {
     pub type_: Type,
     pub mutability: Mutability,
@@ -3712,7 +3710,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3725,7 +3723,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
     }
 }
 
-#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct Constant {
     pub type_: Type,
     pub expr: String,
@@ -3737,7 +3735,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3749,7 +3747,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
     }
 }
 
-#[derive(Debug, Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Copy, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
 pub enum Mutability {
     Mutable,
     Immutable,
@@ -3764,7 +3762,7 @@ fn clean(&self, _: &DocContext<'_>) -> Mutability {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Copy, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Copy, Debug, Hash)]
 pub enum ImplPolarity {
     Positive,
     Negative,
@@ -3779,7 +3777,7 @@ fn clean(&self, _: &DocContext<'_>) -> ImplPolarity {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Impl {
     pub unsafety: hir::Unsafety,
     pub generics: Generics,
@@ -3824,7 +3822,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
             name: None,
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -3994,7 +3992,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
             name: None,
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id(ast::CRATE_NODE_ID),
+            def_id: cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID),
             visibility: self.vis.clean(cx),
             stability: None,
             deprecation: None,
@@ -4003,7 +4001,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub enum Import {
     // use source as str;
     Simple(String, ImportSource),
@@ -4011,7 +4009,7 @@ pub enum Import {
     Glob(ImportSource)
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct ImportSource {
     pub path: Path,
     pub did: Option<DefId>,
@@ -4055,7 +4053,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
             name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
@@ -4227,7 +4225,7 @@ fn resolve_use_source(cx: &DocContext<'_>, path: Path) -> ImportSource {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Macro {
     pub source: String,
     pub imported_from: Option<String>,
@@ -4256,7 +4254,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct ProcMacro {
     pub kind: MacroKind,
     pub helpers: Vec<String>,
@@ -4271,7 +4269,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
             visibility: Some(Public),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
-            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
+            def_id: cx.tcx.hir().local_def_id(self.id),
             inner: ProcMacroItem(ProcMacro {
                 kind: self.kind,
                 helpers: self.helpers.clean(cx),
@@ -4280,7 +4278,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Stability {
     pub level: stability::StabilityLevel,
     pub feature: Option<String>,
@@ -4290,7 +4288,7 @@ pub struct Stability {
     pub issue: Option<u32>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Deprecation {
     pub since: Option<String>,
     pub note: Option<String>,
@@ -4340,13 +4338,13 @@ fn clean(&self, _: &DocContext<'_>) -> Deprecation {
 
 /// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
 /// `A: Send + Sync` in `Foo<A: Send + Sync>`).
-#[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct TypeBinding {
     pub name: String,
     pub kind: TypeBindingKind,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum TypeBindingKind {
     Equality {
         ty: Type,
@@ -4411,7 +4409,7 @@ pub fn enter_impl_trait<F, R>(cx: &DocContext<'_>, f: F) -> R
 where
     F: FnOnce() -> R,
 {
-    let old_bounds = mem::replace(&mut *cx.impl_trait_bounds.borrow_mut(), Default::default());
+    let old_bounds = mem::take(&mut *cx.impl_trait_bounds.borrow_mut());
     let r = f();
     assert!(cx.impl_trait_bounds.borrow().is_empty());
     *cx.impl_trait_bounds.borrow_mut() = old_bounds;
index 36e6a6003df0943ed821f854e1a41161a0eb4b18..e4fba73b8205a21c1c9e8f242092d1f88fd55d6c 100644 (file)
@@ -131,7 +131,7 @@ pub fn ty_params(mut params: Vec<clean::GenericParamDef>) -> Vec<clean::GenericP
     for param in &mut params {
         match param.kind {
             clean::GenericParamDefKind::Type { ref mut bounds, .. } => {
-                *bounds = ty_bounds(mem::replace(bounds, Vec::new()));
+                *bounds = ty_bounds(mem::take(bounds));
             }
             _ => panic!("expected only type parameters"),
         }
index 29ee59d12427425d97cb4228822d75c843af843a..c391baabee06beea47fa93edee55fc929da285f4 100644 (file)
@@ -363,7 +363,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
             // to the map from defid -> hirid
             let access_levels = AccessLevels {
                 map: access_levels.map.iter()
-                                    .map(|(&k, &v)| (tcx.hir().local_def_id_from_hir_id(k), v))
+                                    .map(|(&k, &v)| (tcx.hir().local_def_id(k), v))
                                     .collect()
             };
 
index 51deb4e9b974706cc393a04d8fe9146ea1948e77..45a3c8a3c2256ae20eb1e17ced42d1997a612527 100644 (file)
@@ -6,11 +6,11 @@
 use syntax::ast::{Name, NodeId};
 use syntax::attr;
 use syntax::ext::base::MacroKind;
-use syntax::ptr::P;
 use syntax_pos::{self, Span};
 
 use rustc::hir;
 use rustc::hir::def_id::CrateNum;
+use rustc::hir::ptr::P;
 
 pub struct Module<'hir> {
     pub name: Option<Name>,
@@ -78,7 +78,7 @@ pub fn new(
     }
 }
 
-#[derive(Debug, Clone, RustcEncodable, RustcDecodable, Copy)]
+#[derive(Debug, Clone, Copy)]
 pub enum StructType {
     /// A braced struct
     Plain,
index fa3bc3f5f4f8bda6064f139d92431490ae147a5a..9e5cc03b8312323f01505e4371c1e80b8a959474 100644 (file)
@@ -737,9 +737,6 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
                 }
             }
         }
-        clean::Unique(..) => {
-            panic!("should have been cleaned")
-        }
     }
 }
 
index 3f3f4c85e81fc5035f49d409a179b938cf615d5e..5f1a1b31616c1f0869bac051fac1206247021e1c 100644 (file)
@@ -110,7 +110,6 @@ fn from(kind: clean::TypeKind) -> ItemType {
             clean::TypeKind::Module     => ItemType::Module,
             clean::TypeKind::Static     => ItemType::Static,
             clean::TypeKind::Const      => ItemType::Constant,
-            clean::TypeKind::Variant    => ItemType::Variant,
             clean::TypeKind::Typedef    => ItemType::Typedef,
             clean::TypeKind::Foreign    => ItemType::ForeignType,
             clean::TypeKind::Macro      => ItemType::Macro,
index f0aff961c675170874e8a1429effc63505c789f0..2d69c29dfae3cda6e6c37af7322f3f9b73f3e92a 100644 (file)
@@ -660,7 +660,7 @@ pub fn run(mut krate: clean::Crate,
         deref_trait_did,
         deref_mut_trait_did,
         owned_box_did,
-        masked_crates: mem::replace(&mut krate.masked_crates, Default::default()),
+        masked_crates: mem::take(&mut krate.masked_crates),
         param_names: external_param_names,
         aliases: Default::default(),
     };
@@ -2541,7 +2541,7 @@ fn full_path(cx: &Context, item: &clean::Item) -> String {
     s
 }
 
-fn shorter<'a>(s: Option<&'a str>) -> String {
+fn shorter(s: Option<&str>) -> String {
     match s {
         Some(s) => s.lines()
             .skip_while(|s| s.chars().all(|c| c.is_whitespace()))
@@ -5188,9 +5188,6 @@ fn collect_paths_for_type(first_ty: clean::Type) -> Vec<String> {
             clean::Type::Array(ty, _) => {
                 work.push_back(*ty);
             },
-            clean::Type::Unique(ty) => {
-                work.push_back(*ty);
-            },
             clean::Type::RawPointer(_, ty) => {
                 work.push_back(*ty);
             },
index 0493bf7c5c0f51c9045f89337db911f0c1a2d0a6..59704dace4d15bfa6a23e47ba598457316414701 100644 (file)
@@ -146,6 +146,10 @@ img {
        max-width: 100%;
 }
 
+li {
+       position: relative;
+}
+
 .source .content {
        margin-top: 50px;
        max-width: none;
index 2564c611e54e59ebc25de0698cf1aab91b08b686..2da7aceae8bf4fd23c19b9aee537c0aaf03bf679 100644 (file)
@@ -119,7 +119,7 @@ fn fold_until(&mut self, level: u32) {
     /// Push a level `level` heading into the appropriate place in the
     /// hierarchy, returning a string containing the section number in
     /// `<num>.<num>.<num>` format.
-    pub fn push<'a>(&'a mut self, level: u32, name: String, id: String) -> &'a str {
+    pub fn push(&mut self, level: u32, name: String, id: String) -> &str {
         assert!(level >= 1);
 
         // collapse all previous sections into their parents until we
index 7a8b088020c5320c32a8e41accbdb026dae955cd..58777130b7f29339b530468d6da409c92e8bf073 100644 (file)
@@ -1,5 +1,4 @@
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/",
@@ -21,6 +20,7 @@
 #![feature(drain_filter)]
 #![feature(inner_deref)]
 #![feature(never_type)]
+#![feature(mem_take)]
 
 #![recursion_limit="256"]
 
@@ -42,8 +42,6 @@
 #[macro_use] extern crate log;
 extern crate rustc_errors as errors;
 
-extern crate serialize as rustc_serialize; // used by deriving
-
 use std::default::Default;
 use std::env;
 use std::panic;
index b0a37ea9c8081f50025fad2cfa5d50f5b0e80e1d..50a647f244db55a563dab1bbf447a79d4fd442c5 100644 (file)
@@ -17,7 +17,7 @@
 use crate::test::{TestOptions, Collector};
 
 /// Separate any lines at the start of the file that begin with `# ` or `%`.
-fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
+fn extract_leading_metadata(s: &str) -> (Vec<&str>, &str) {
     let mut metadata = Vec::new();
     let mut count = 0;
 
index 8666ba357b832f92bc10cf1f1c506c514575a2a1..144ff226c4283c619090d8a8f1deedbf613f2fd6 100644 (file)
@@ -4,7 +4,7 @@
 use crate::fold::{DocFolder};
 use crate::passes::Pass;
 
-use std::mem::replace;
+use std::mem::take;
 
 pub const COLLAPSE_DOCS: Pass = Pass {
     name: "collapse-docs",
@@ -46,7 +46,7 @@ fn collapse(doc_strings: &mut Vec<DocFragment>) {
     let mut docs = vec![];
     let mut last_frag: Option<DocFragment> = None;
 
-    for frag in replace(doc_strings, vec![]) {
+    for frag in take(doc_strings) {
         if let Some(mut curr_frag) = last_frag.take() {
             let curr_kind = curr_frag.kind();
             let new_kind = frag.kind();
index 70cd4b72199bca2f73a97531f38fd02c9201032b..a2a6b1efe820c21ec3f0fd5a8ee7575ab46ea947 100644 (file)
@@ -118,7 +118,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
     // doesn't work with it anyway, so pull them from the HIR map instead
     for &trait_did in cx.all_traits.iter() {
         for &impl_node in cx.tcx.hir().trait_impls(trait_did) {
-            let impl_did = cx.tcx.hir().local_def_id_from_hir_id(impl_node);
+            let impl_did = cx.tcx.hir().local_def_id(impl_node);
             inline::build_impl(cx, impl_did, &mut new_items);
         }
     }
index 7b90561bdadb92fd2d6a9594e46e597755e12ac9..63545ab45bf64fbb3da8b1689d08fe8f0d94a477 100644 (file)
@@ -528,13 +528,8 @@ pub fn make_test(s: &str,
         prog.push_str(everything_else);
     } else {
         let returns_result = everything_else.trim_end().ends_with("(())");
-        let returns_option = everything_else.trim_end().ends_with("Some(())");
         let (main_pre, main_post) = if returns_result {
-            (if returns_option {
-                "fn main() { fn _inner() -> Option<()> {"
-            } else {
-                "fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {"
-            },
+            ("fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {",
              "}\n_inner().unwrap() }")
         } else {
             ("fn main() {\n", "\n}")
index 781e62c3b274cfcfc15349bd19fb6d2df76bf119..fa5faaf3ff56828264c2f6bd0c2b62be1ad0906f 100644 (file)
@@ -66,12 +66,12 @@ fn store_path(&mut self, did: DefId) {
     }
 
     fn stability(&self, id: hir::HirId) -> Option<attr::Stability> {
-        self.cx.tcx.hir().opt_local_def_id_from_hir_id(id)
+        self.cx.tcx.hir().opt_local_def_id(id)
             .and_then(|def_id| self.cx.tcx.lookup_stability(def_id)).cloned()
     }
 
     fn deprecation(&self, id: hir::HirId) -> Option<attr::Deprecation> {
-        self.cx.tcx.hir().opt_local_def_id_from_hir_id(id)
+        self.cx.tcx.hir().opt_local_def_id(id)
             .and_then(|def_id| self.cx.tcx.lookup_deprecation(def_id))
     }
 
@@ -375,7 +375,7 @@ pub fn visit_item(&mut self, item: &'tcx hir::Item,
         let ident = renamed.unwrap_or(item.ident);
 
         if item.vis.node.is_pub() {
-            let def_id = self.cx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+            let def_id = self.cx.tcx.hir().local_def_id(item.hir_id);
             self.store_path(def_id);
         }
 
@@ -389,7 +389,7 @@ pub fn visit_item(&mut self, item: &'tcx hir::Item,
             _ if self.inlining && !item.vis.node.is_pub() => {}
             hir::ItemKind::GlobalAsm(..) => {}
             hir::ItemKind::ExternCrate(orig_name) => {
-                let def_id = self.cx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+                let def_id = self.cx.tcx.hir().local_def_id(item.hir_id);
                 om.extern_crates.push(ExternCrate {
                     cnum: self.cx.tcx.extern_mod_stmt_cnum(def_id)
                                 .unwrap_or(LOCAL_CRATE),
@@ -618,7 +618,7 @@ fn visit_local_macro(
 
         Macro {
 
-            def_id: self.cx.tcx.hir().local_def_id_from_hir_id(def.hir_id),
+            def_id: self.cx.tcx.hir().local_def_id(def.hir_id),
             attrs: &def.attrs,
             name: renamed.unwrap_or(def.name),
             whence: def.span,
index a7e7c09f9ae4411e9546f493278db7bebdfc3d61..726306d60ce1e1dbb9239e8ebd93f36fc8de7206 100644 (file)
@@ -1031,7 +1031,7 @@ pub fn pretty(&self) -> PrettyJson<'_> {
 
      /// If the Json value is an Object, returns the value associated with the provided key.
     /// Otherwise, returns None.
-    pub fn find<'a>(&'a self, key: &str) -> Option<&'a Json>{
+    pub fn find(&self, key: &str) -> Option<&Json> {
         match *self {
             Json::Object(ref map) => map.get(key),
             _ => None
@@ -1052,7 +1052,7 @@ pub fn find_path<'a>(&'a self, keys: &[&str]) -> Option<&'a Json>{
     /// If the Json value is an Object, performs a depth-first search until
     /// a value associated with the provided key is found. If no value is found
     /// or the Json value is not an Object, returns `None`.
-    pub fn search<'a>(&'a self, key: &str) -> Option<&'a Json> {
+    pub fn search(&self, key: &str) -> Option<&Json> {
         match self {
             &Json::Object(ref map) => {
                 match map.get(key) {
index 5a2fe2b244f556d16127daf3244da70fed785ecc..2925d8362c8d9a9cd2a0a44c00668e91da42d3d6 100644 (file)
@@ -2608,6 +2608,12 @@ mod test_map {
     use realstd::collections::CollectionAllocErr::*;
     use realstd::usize;
 
+    // https://github.com/rust-lang/rust/issues/62301
+    fn _assert_hashmap_is_unwind_safe() {
+        fn assert_unwind_safe<T: crate::panic::UnwindSafe>() {}
+        assert_unwind_safe::<HashMap<(), crate::cell::UnsafeCell<()>>>();
+    }
+
     #[test]
     fn test_zero_capacities() {
         type HM = HashMap<i32, i32>;
index 3d0568c16cdf67ebe2de4b196bf12ebbdb6e1075..a8d4d1181aa4fcb31b5f0f5beca28930454575e5 100644 (file)
@@ -1144,7 +1144,7 @@ pub trait Write {
 
     /// Like `write`, except that it writes from a slice of buffers.
     ///
-    /// Data is copied to from each buffer in order, with the final buffer
+    /// Data is copied from each buffer in order, with the final buffer
     /// read from possibly being only partially consumed. This method must
     /// behave as a call to `write` with the buffers concatenated would.
     ///
index 7c4eae6512df4822a448efb3f65967de69eb868d..2bfd3e4ad20e3d29170370a849b4705ccfa3f0f5 100644 (file)
@@ -44,6 +44,7 @@ pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<
     where R: Read, W: Write
 {
     let mut buf = unsafe {
+        #[allow(deprecated)]
         let mut buf: [u8; super::DEFAULT_BUF_SIZE] = mem::uninitialized();
         reader.initializer().initialize(&mut buf);
         buf
index 60e06139eba99c205bfc83501f4c0f72641cd5a5..fb9a228880eb7304d9484bce138313d6a9ec9c2d 100644 (file)
 #![feature(libc)]
 #![feature(link_args)]
 #![feature(linkage)]
+#![feature(mem_take)]
 #![feature(needs_panic_runtime)]
 #![feature(never_type)]
 #![feature(nll)]
index 7a3b5d30500a93a6cda9cb84d06aa5baa5f56c16..1d4fd98dd754f2991846a5330f59263a1403b0d5 100644 (file)
@@ -4,6 +4,7 @@
 
 use crate::any::Any;
 use crate::cell::UnsafeCell;
+use crate::collections;
 use crate::fmt;
 use crate::future::Future;
 use crate::pin::Pin;
@@ -285,6 +286,11 @@ impl RefUnwindSafe for atomic::AtomicBool {}
 #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
 impl<T> RefUnwindSafe for atomic::AtomicPtr<T> {}
 
+// https://github.com/rust-lang/rust/issues/62301
+#[stable(feature = "hashbrown", since = "1.36.0")]
+impl<K, V, S> UnwindSafe for collections::HashMap<K, V, S>
+    where K: UnwindSafe, V: UnwindSafe, S: UnwindSafe {}
+
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T> Deref for AssertUnwindSafe<T> {
     type Target = T;
index 9ef42063f94126cd28a79179836bf8d4a370c4e2..952fd9ebfdf0723d20494c6bd683ed537bdc4f76 100644 (file)
@@ -103,7 +103,9 @@ pub fn set_hook(hook: Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send>) {
         HOOK_LOCK.write_unlock();
 
         if let Hook::Custom(ptr) = old_hook {
-            Box::from_raw(ptr);
+            #[allow(unused_must_use)] {
+                Box::from_raw(ptr);
+            }
         }
     }
 }
@@ -362,7 +364,7 @@ fn fill(&mut self) -> &mut String {
 
     unsafe impl<'a> BoxMeUp for PanicPayload<'a> {
         fn box_me_up(&mut self) -> *mut (dyn Any + Send) {
-            let contents = mem::replace(self.fill(), String::new());
+            let contents = mem::take(self.fill());
             Box::into_raw(Box::new(contents))
         }
 
index a568f46663730f939f0acfe3df5a04f8ffd8eaf4..000f80f99e7a9bb861b3ffde10defa09355e8c1a 100644 (file)
@@ -1765,33 +1765,6 @@ fn stdin_works() {
         assert_eq!(out, "foobar\n");
     }
 
-
-    #[test]
-    #[cfg_attr(target_os = "android", ignore)]
-    #[cfg(unix)]
-    fn uid_works() {
-        use crate::os::unix::prelude::*;
-
-        let mut p = Command::new("/bin/sh")
-                            .arg("-c").arg("true")
-                            .uid(unsafe { libc::getuid() })
-                            .gid(unsafe { libc::getgid() })
-                            .spawn().unwrap();
-        assert!(p.wait().unwrap().success());
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "android", ignore)]
-    #[cfg(unix)]
-    fn uid_to_root_fails() {
-        use crate::os::unix::prelude::*;
-
-        // if we're already root, this isn't a valid test. Most of the bots run
-        // as non-root though (android is an exception).
-        if unsafe { libc::getuid() == 0 } { return }
-        assert!(Command::new("/bin/ls").uid(0).gid(0).spawn().is_err());
-    }
-
     #[test]
     #[cfg_attr(target_os = "android", ignore)]
     fn test_process_status() {
index 3c4f8e077c922ee536340b607fc3e2c2b29179cc..fbe36d10517eb1ae610638cff3a02db07f24a625 100644 (file)
@@ -140,7 +140,7 @@ fn wait_timeout_receiver<'a, 'b, T>(lock: &'a Mutex<State<T>>,
     new_guard
 }
 
-fn abort_selection<'a, T>(guard: &mut MutexGuard<'a , State<T>>) -> bool {
+fn abort_selection<T>(guard: &mut MutexGuard<'_, State<T>>) -> bool {
     match mem::replace(&mut guard.blocker, NoneBlocked) {
         NoneBlocked => true,
         BlockedSender(token) => {
@@ -383,7 +383,7 @@ pub fn drop_port(&self) {
         // needs to be careful to destroy the data *outside* of the lock to
         // prevent deadlock.
         let _data = if guard.cap != 0 {
-            mem::replace(&mut guard.buf.buf, Vec::new())
+            mem::take(&mut guard.buf.buf)
         } else {
             Vec::new()
         };
index c3b8bbd042606e17e1581d236a7fdb0975aebe21..3fef7552259c86eb52ac0c38b7d0d370f049f591 100644 (file)
@@ -1,3 +1,5 @@
+#![allow(deprecated)] // mem::uninitialized
+
 use crate::io::ErrorKind;
 use crate::mem;
 
index b3ef5f3064c167f1d658a0ebfe994d9f13241720..1f5c785f419075b56ff415827f3778b358d5eac0 100644 (file)
@@ -673,7 +673,7 @@ pub fn take_error(&self) -> io::Result<Option<io::Error>> {
     /// }
     /// ```
     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn incoming<'a>(&'a self) -> Incoming<'a> {
+    pub fn incoming(&self) -> Incoming<'_> {
         Incoming { listener: self }
     }
 }
index 01f5536ed7a6594a614d77c0896fbab98aa1883a..601957acd5c63efbb5bf985a03cab8a666695a0b 100644 (file)
@@ -140,7 +140,7 @@ pub unsafe fn abort_internal() -> ! {
 pub fn hashmap_random_keys() -> (u64, u64) {
     fn rdrand64() -> u64 {
         unsafe {
-            let mut ret: u64 = crate::mem::uninitialized();
+            let mut ret: u64 = 0;
             for _ in 0..10 {
                 if crate::arch::x86_64::_rdrand64_step(&mut ret) == 1 {
                     return ret;
index 41090caee8459fea5e08e6ad9054379d9da08da3..42edd5dbbea7c463d42e287ba26f11a11ce0a528 100644 (file)
@@ -198,7 +198,7 @@ pub fn as_pathname(&self) -> Option<&Path> {
         }
     }
 
-    fn address<'a>(&'a self) -> AddressKind<'a> {
+    fn address(&self) -> AddressKind<'_> {
         let len = self.len as usize - sun_path_offset(&self.addr);
         let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
 
@@ -894,7 +894,7 @@ pub fn take_error(&self) -> io::Result<Option<io::Error>> {
     /// }
     /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
-    pub fn incoming<'a>(&'a self) -> Incoming<'a> {
+    pub fn incoming(&self) -> Incoming<'_> {
         Incoming { listener: self }
     }
 }
index 1cb5553912981a532a4273d107855e543a69d6ae..36fb1fb5ff68d7086a397d037cc09c509c0e4f24 100644 (file)
@@ -195,7 +195,7 @@ fn wide_char_to_multi_byte(code_page: u32,
     }
 }
 
-pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
+pub fn truncate_utf16_at_nul(v: &[u16]) -> &[u16] {
     match v.iter().position(|c| *c == 0) {
         // don't include the 0
         Some(i) => &v[..i],
index f3178a5e9e6909f78eb0a72829bbead4729e3900..7eae28cb14fbc9c2be42f39533f56633c1efb2a4 100644 (file)
@@ -19,7 +19,7 @@ pub fn is_verbatim_sep(b: u8) -> bool {
     b == b'\\'
 }
 
-pub fn parse_prefix<'a>(path: &'a OsStr) -> Option<Prefix<'a>> {
+pub fn parse_prefix(path: &OsStr) -> Option<Prefix<'_>> {
     use crate::path::Prefix::*;
     unsafe {
         // The unsafety here stems from converting between &OsStr and &[u8]
index 493ee8a9a2d7c72ccbd26ef90fc429addcb7eecb..c77f30dfc7109cbd1d9f1c9287d216c6463210b4 100644 (file)
@@ -342,7 +342,7 @@ fn drop(&mut self) {
         // If anything here fails, there's not really much we can do, so we leak
         // the buffer/OVERLAPPED pointers to ensure we're at least memory safe.
         if self.pipe.cancel_io().is_err() || self.result().is_err() {
-            let buf = mem::replace(self.dst, Vec::new());
+            let buf = mem::take(self.dst);
             let overlapped = Box::new(unsafe { mem::zeroed() });
             let overlapped = mem::replace(&mut self.overlapped, overlapped);
             mem::forget((buf, overlapped));
index 44b0963302ddfe5491d5c020dd5edcc7f487b7a5..8789abe55c3d0b526d9526a5ea10f333d72e918c 100644 (file)
@@ -16,7 +16,7 @@ pub fn join(&self, path: &str) -> PathBuf {
             p.join(path)
         }
 
-        pub fn path<'a>(&'a self) -> &'a Path {
+        pub fn path(&self) -> &Path {
             let TempDir(ref p) = *self;
             p
         }
index 436620ae7293b267bf4bcda313faf9b287f30743..a0c298010b6b693726ae10f688b73e66aa4b9e50 100644 (file)
@@ -60,7 +60,7 @@ pub fn is_known(attr: &Attribute) -> bool {
 }
 
 pub fn is_known_lint_tool(m_item: Ident) -> bool {
-    ["clippy"].contains(&m_item.as_str().as_ref())
+    [sym::clippy, sym::rustc].contains(&m_item.name)
 }
 
 impl NestedMetaItem {
@@ -440,12 +440,12 @@ pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
     })
 }
 
-pub fn find_by_name<'a>(attrs: &'a [Attribute], name: Symbol) -> Option<&'a Attribute> {
+pub fn find_by_name(attrs: &[Attribute], name: Symbol) -> Option<&Attribute> {
     attrs.iter().find(|attr| attr.check_name(name))
 }
 
-pub fn filter_by_name<'a>(attrs: &'a [Attribute], name: Symbol)
-    -> impl Iterator<Item = &'a Attribute> {
+pub fn filter_by_name(attrs: &[Attribute], name: Symbol)
+                      -> impl Iterator<Item=&Attribute> {
     attrs.iter().filter(move |attr| attr.check_name(name))
 }
 
index 5473f55aa33704053b03cdf982f7f108fc162a9a..6fbd2ab7c43f2f7438071fe69543cee2852da455 100644 (file)
@@ -13,8 +13,7 @@
 use crate::parse::token;
 use crate::parse::parser::Parser;
 use crate::ptr::P;
-use crate::symbol::Symbol;
-use crate::symbol::{kw, sym};
+use crate::symbol::{sym, Symbol};
 use crate::tokenstream::{TokenStream, TokenTree};
 use crate::visit::{self, Visitor};
 use crate::util::map_in_place::MapInPlace;
@@ -197,7 +196,6 @@ pub struct Invocation {
 pub enum InvocationKind {
     Bang {
         mac: ast::Mac,
-        ident: Option<Ident>,
         span: Span,
     },
     Attr {
@@ -307,7 +305,7 @@ fn expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragment {
             } else {
                 self.resolve_imports();
                 if undetermined_invocations.is_empty() { break }
-                invocations = mem::replace(&mut undetermined_invocations, Vec::new());
+                invocations = mem::take(&mut undetermined_invocations);
                 force = !mem::replace(&mut progress, false);
                 continue
             };
@@ -664,13 +662,12 @@ fn expand_bang_invoc(&mut self,
                          ext: &SyntaxExtension)
                          -> Option<AstFragment> {
         let kind = invoc.fragment_kind;
-        let (mac, ident, span) = match invoc.kind {
-            InvocationKind::Bang { mac, ident, span } => (mac, ident, span),
+        let (mac, span) = match invoc.kind {
+            InvocationKind::Bang { mac, span } => (mac, span),
             _ => unreachable!(),
         };
         let path = &mac.node.path;
 
-        let ident = ident.unwrap_or_else(|| Ident::invalid());
         let validate = |this: &mut Self| {
             // feature-gate the macro invocation
             if let Some((feature, issue)) = ext.unstable_feature {
@@ -690,12 +687,6 @@ fn expand_bang_invoc(&mut self,
                 }
             }
 
-            if ident.name != kw::Invalid {
-                let msg = format!("macro {}! expects no ident argument, given '{}'", path, ident);
-                this.cx.span_err(path.span, &msg);
-                this.cx.trace_macros_diag();
-                return Err(kind.dummy(span));
-            }
             Ok(())
         };
 
@@ -729,19 +720,11 @@ fn expand_bang_invoc(&mut self,
             }
 
             SyntaxExtensionKind::Bang(expander) => {
-                if ident.name != kw::Invalid {
-                    let msg =
-                        format!("macro {}! expects no ident argument, given '{}'", path, ident);
-                    self.cx.span_err(path.span, &msg);
-                    self.cx.trace_macros_diag();
-                    kind.dummy(span)
-                } else {
-                    self.gate_proc_macro_expansion_kind(span, kind);
-                    let tok_result = expander.expand(self.cx, span, mac.node.stream());
-                    let result = self.parse_ast_fragment(tok_result, kind, path, span);
-                    self.gate_proc_macro_expansion(span, &result);
-                    result
-                }
+                self.gate_proc_macro_expansion_kind(span, kind);
+                let tok_result = expander.expand(self.cx, span, mac.node.stream());
+                let result = self.parse_ast_fragment(tok_result, kind, path, span);
+                self.gate_proc_macro_expansion(span, &result);
+                result
             }
         };
 
@@ -944,7 +927,7 @@ fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> A
     }
 
     fn collect_bang(&mut self, mac: ast::Mac, span: Span, kind: AstFragmentKind) -> AstFragment {
-        self.collect(kind, InvocationKind::Bang { mac, ident: None, span })
+        self.collect(kind, InvocationKind::Bang { mac, span })
     }
 
     fn collect_attr(&mut self,
@@ -1179,13 +1162,9 @@ fn visit_block(&mut self, block: &mut P<Block>) {
             ast::ItemKind::Mac(..) => {
                 self.check_attributes(&item.attrs);
                 item.and_then(|item| match item.node {
-                    ItemKind::Mac(mac) => {
-                        self.collect(AstFragmentKind::Items, InvocationKind::Bang {
-                            mac,
-                            ident: Some(item.ident),
-                            span: item.span,
-                        }).make_items()
-                    }
+                    ItemKind::Mac(mac) => self.collect(
+                        AstFragmentKind::Items, InvocationKind::Bang { mac, span: item.span }
+                    ).make_items(),
                     _ => unreachable!(),
                 })
             }
@@ -1525,9 +1504,7 @@ fn proc_macro_hygiene = proc_macro_hygiene,
     }
 
     fn enable_custom_inner_attributes(&self) -> bool {
-        self.features.map_or(false, |features| {
-            features.custom_inner_attributes || features.custom_attribute || features.rustc_attrs
-        })
+        self.features.map_or(false, |features| features.custom_inner_attributes)
     }
 }
 
index 92ce3779a3c8153999c862a14a41c72b9a97388b..fc8aa4793bc6111eba60d007e077c69ac1d7be7c 100644 (file)
@@ -901,7 +901,7 @@ fn may_be_ident(nt: &token::Nonterminal) -> bool {
 /// # Returns
 ///
 /// The parsed non-terminal.
-fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> Nonterminal {
+fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Nonterminal {
     if name == sym::tt {
         return token::NtTT(p.parse_token_tree());
     }
index ea7f8e356aa63214fbecbf501ec553829d47ec05..e04fd2ddc05bce62332409adbd00515ad3de7069 100644 (file)
@@ -249,7 +249,7 @@ pub fn transcribe(
             quoted::TokenTree::Delimited(mut span, delimited) => {
                 span = span.apply_mark(cx.current_expansion.mark);
                 stack.push(Frame::Delimited { forest: delimited, idx: 0, span });
-                result_stack.push(mem::replace(&mut result, Vec::new()));
+                result_stack.push(mem::take(&mut result));
             }
 
             // Nothing much to do here. Just push the token to the result, being careful to
index a6e8441a915e0c1464ce6b3acd4952286ff498e8..e1e39faaad4adfb626b57153acaa5a511ca11ef8 100644 (file)
@@ -31,6 +31,7 @@
 
 use errors::{Applicability, DiagnosticBuilder, Handler};
 use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::sync::Lock;
 use rustc_target::spec::abi::Abi;
 use syntax_pos::{Span, DUMMY_SP, MultiSpan};
 use log::debug;
@@ -323,7 +324,7 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     (active, nll, "1.0.0", Some(43234), None),
 
     // Allows using slice patterns.
-    (active, slice_patterns, "1.0.0", Some(23121), None),
+    (active, slice_patterns, "1.0.0", Some(62254), None),
 
     // Allows the definition of `const` functions with some advanced features.
     (active, const_fn, "1.2.0", Some(57563), None),
@@ -530,9 +531,6 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
     (active, lint_reasons, "1.31.0", Some(54503), None),
 
-    // Allows paths to enum variants on type aliases.
-    (active, type_alias_enum_variants, "1.31.0", Some(49683), None),
-
     // Allows exhaustive integer pattern matching on `usize` and `isize`.
     (active, precise_pointer_size_matching, "1.32.0", Some(56354), None),
 
@@ -573,6 +571,12 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     // Allows explicit discriminants on non-unit enum variants.
     (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
 
+    // Allows `impl Trait` with multiple unrelated lifetimes.
+    (active, member_constraints, "1.37.0", Some(61977), None),
+
+    // Allows `async || body` closures.
+    (active, async_closure, "1.37.0", Some(62290), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
@@ -610,7 +614,7 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     (removed, allocator, "1.0.0", None, None, None),
     (removed, simd, "1.0.0", Some(27731), None,
      Some("removed in favor of `#[repr(simd)]`")),
-    (removed, advanced_slice_patterns, "1.0.0", Some(23121), None,
+    (removed, advanced_slice_patterns, "1.0.0", Some(62254), None,
      Some("merged into `#![feature(slice_patterns)]`")),
     (removed, macro_reexport, "1.0.0", Some(29638), None,
      Some("subsumed by `pub use`")),
@@ -853,6 +857,8 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
     (accepted, extern_crate_self, "1.34.0", Some(56409), None),
     // Allows arbitrary delimited token streams in non-macro attributes.
     (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None),
+    // Allows paths to enum variants on type aliases including `Self`.
+    (accepted, type_alias_enum_variants, "1.37.0", Some(49683), None),
     // Allows using `#[repr(align(X))]` on enums with equivalent semantics
     // to wrapping an enum in a wrapper struct with `#[repr(align(X))]`.
     (accepted, repr_align_enum, "1.37.0", Some(57996), None),
@@ -1290,6 +1296,18 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
                                                     attribute is just used for rustc unit \
                                                     tests and will never be stable",
                                                     cfg_fn!(rustc_attrs))),
+    (sym::rustc_dump_env_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                    sym::rustc_attrs,
+                                                    "the `#[rustc_dump_env_program_clauses]` \
+                                                    attribute is just used for rustc unit \
+                                                    tests and will never be stable",
+                                                    cfg_fn!(rustc_attrs))),
+    (sym::rustc_object_lifetime_default, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                    sym::rustc_attrs,
+                                                    "the `#[rustc_object_lifetime_default]` \
+                                                    attribute is just used for rustc unit \
+                                                    tests and will never be stable",
+                                                    cfg_fn!(rustc_attrs))),
     (sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable,
                                     sym::rustc_attrs,
                                     "the `#[rustc_test_marker]` attribute \
@@ -1351,6 +1369,26 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
                                                 "internal implementation detail",
                                                 cfg_fn!(rustc_attrs))),
 
+    (sym::rustc_allocator_nounwind, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                sym::rustc_attrs,
+                                                "internal implementation detail",
+                                                cfg_fn!(rustc_attrs))),
+
+    (sym::rustc_doc_only_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                sym::rustc_attrs,
+                                                "internal implementation detail",
+                                                cfg_fn!(rustc_attrs))),
+
+    (sym::rustc_promotable, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                sym::rustc_attrs,
+                                                "internal implementation detail",
+                                                cfg_fn!(rustc_attrs))),
+
+    (sym::rustc_allow_const_fn_ptr, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                sym::rustc_attrs,
+                                                "internal implementation detail",
+                                                cfg_fn!(rustc_attrs))),
+
     (sym::rustc_dummy, Normal, template!(Word /* doesn't matter*/), Gated(Stability::Unstable,
                                          sym::rustc_attrs,
                                          "used by the test suite",
@@ -1637,6 +1675,14 @@ fn check_attribute(
             }
             debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage);
             return;
+        } else {
+            for segment in &attr.path.segments {
+                if segment.ident.as_str().starts_with("rustc") {
+                    let msg = "attributes starting with `rustc` are \
+                               reserved for use by the `rustc` compiler";
+                    gate_feature!(self, rustc_attrs, segment.ident.span, msg);
+                }
+            }
         }
         for &(n, ty) in self.plugin_attributes {
             if attr.path == n {
@@ -1647,19 +1693,13 @@ fn check_attribute(
                 return;
             }
         }
-        if !attr::is_known(attr) {
-            if attr.name_or_empty().as_str().starts_with("rustc_") {
-                let msg = "unless otherwise specified, attributes with the prefix `rustc_` \
-                           are reserved for internal compiler diagnostics";
-                gate_feature!(self, rustc_attrs, attr.span, msg);
-            } else if !is_macro {
-                // Only run the custom attribute lint during regular feature gate
-                // checking. Macro gating runs before the plugin attributes are
-                // registered, so we skip this in that case.
-                let msg = format!("The attribute `{}` is currently unknown to the compiler and \
-                                   may have meaning added to it in the future", attr.path);
-                gate_feature!(self, custom_attribute, attr.span, &msg);
-            }
+        if !is_macro && !attr::is_known(attr) {
+            // Only run the custom attribute lint during regular feature gate
+            // checking. Macro gating runs before the plugin attributes are
+            // registered, so we skip this in that case.
+            let msg = format!("The attribute `{}` is currently unknown to the compiler and \
+                                may have meaning added to it in the future", attr.path);
+            gate_feature!(self, custom_attribute, attr.span, &msg);
         }
     }
 }
@@ -2189,9 +2229,6 @@ fn visit_expr(&mut self, e: &'a ast::Expr) {
                                     "labels on blocks are unstable");
                 }
             }
-            ast::ExprKind::Closure(_, ast::IsAsync::Async { .. }, ..) => {
-                gate_feature_post!(&self, async_await, e.span, "async closures are unstable");
-            }
             ast::ExprKind::Async(..) => {
                 gate_feature_post!(&self, async_await, e.span, "async blocks are unstable");
             }
@@ -2525,6 +2562,10 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
     features
 }
 
+fn for_each_in_lock<T>(vec: &Lock<Vec<T>>, f: impl Fn(&T)) {
+    vec.borrow().iter().for_each(f);
+}
+
 pub fn check_crate(krate: &ast::Crate,
                    sess: &ParseSess,
                    features: &Features,
@@ -2537,27 +2578,26 @@ pub fn check_crate(krate: &ast::Crate,
         plugin_attributes,
     };
 
-    sess
-        .param_attr_spans
-        .borrow()
-        .iter()
-        .for_each(|span| gate_feature!(
-            &ctx,
-            param_attrs,
-            *span,
-            "attributes on function parameters are unstable"
-        ));
-
-    sess
-        .let_chains_spans
-        .borrow()
-        .iter()
-        .for_each(|span| gate_feature!(
-            &ctx,
-            let_chains,
-            *span,
-            "`let` expressions in this position are experimental"
-        ));
+    for_each_in_lock(&sess.param_attr_spans, |span| gate_feature!(
+        &ctx,
+        param_attrs,
+        *span,
+        "attributes on function parameters are unstable"
+    ));
+
+    for_each_in_lock(&sess.let_chains_spans, |span| gate_feature!(
+        &ctx,
+        let_chains,
+        *span,
+        "`let` expressions in this position are experimental"
+    ));
+
+    for_each_in_lock(&sess.async_closure_spans, |span| gate_feature!(
+        &ctx,
+        async_closure,
+        *span,
+        "async closures are unstable"
+    ));
 
     let visitor = &mut PostExpansionVisitor {
         context: &ctx,
index 337b84247361d8021d0ab88166afaf0ce3c8314a..a7c5ed158e0287158e3118869365ed8d6c0e360f 100644 (file)
@@ -8,14 +8,15 @@
        test(attr(deny(warnings))))]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #![feature(bind_by_move_pattern_guards)]
+#![feature(box_syntax)]
 #![feature(const_fn)]
 #![feature(const_transmute)]
 #![feature(crate_visibility_modifier)]
 #![feature(label_break_value)]
+#![feature(mem_take)]
 #![feature(nll)]
 #![feature(rustc_attrs)]
 #![feature(rustc_diagnostic_macros)]
index e23bc025f6e31c82b313c9b20b597551a2f6d40f..11a1de13fc217874cef8fb8d67eed2fefc9bd50b 100644 (file)
@@ -1261,7 +1261,6 @@ pub fn noop_visit_vis<T: MutVisitor>(Spanned { node, span }: &mut Visibility, vi
 
 #[cfg(test)]
 mod tests {
-    use std::io;
     use crate::ast::{self, Ident};
     use crate::util::parser_testing::{string_to_crate, matches_codepattern};
     use crate::print::pprust;
@@ -1271,7 +1270,7 @@ mod tests {
 
     // this version doesn't care about getting comments or docstrings in.
     fn fake_print_crate(s: &mut pprust::State<'_>,
-                        krate: &ast::Crate) -> io::Result<()> {
+                        krate: &ast::Crate) {
         s.print_mod(&krate.module, &krate.attrs)
     }
 
index 0ea0b2a694d7d0df87029de7914cf2da69c6a972..edcdb18a037d863f5b08fff410fce9c6e4c6bebc 100644 (file)
@@ -613,12 +613,12 @@ fn tokens_to_string(tokens: &[TokenType]) -> String {
                 let sum_with_parens = pprust::to_string(|s| {
                     use crate::print::pprust::PrintState;
 
-                    s.s.word("&")?;
-                    s.print_opt_lifetime(lifetime)?;
-                    s.print_mutability(mut_ty.mutbl)?;
-                    s.popen()?;
-                    s.print_type(&mut_ty.ty)?;
-                    s.print_type_bounds(" +", &bounds)?;
+                    s.s.word("&");
+                    s.print_opt_lifetime(lifetime);
+                    s.print_mutability(mut_ty.mutbl);
+                    s.popen();
+                    s.print_type(&mut_ty.ty);
+                    s.print_type_bounds(" +", &bounds);
                     s.pclose()
                 });
                 err.span_suggestion(
index 4e4fe4256c9b0a521834cbc283fcc956736e658b..3717bb435f69d07fb78f9cfd71417cd7ac02d4a0 100644 (file)
@@ -83,28 +83,6 @@ pub fn try_next_token(&mut self) -> Result<Token, ()> {
         Ok(ret_val)
     }
 
-    /// Immutably extract string if found at current position with given delimiters
-    fn peek_delimited(&self, from_ch: char, to_ch: char) -> Option<String> {
-        let mut pos = self.pos;
-        let mut idx = self.src_index(pos);
-        let mut ch = char_at(&self.src, idx);
-        if ch != from_ch {
-            return None;
-        }
-        pos = pos + Pos::from_usize(ch.len_utf8());
-        let start_pos = pos;
-        idx = self.src_index(pos);
-        while idx < self.end_src_index {
-            ch = char_at(&self.src, idx);
-            if ch == to_ch {
-                return Some(self.src[self.src_index(start_pos)..self.src_index(pos)].to_string());
-            }
-            pos = pos + Pos::from_usize(ch.len_utf8());
-            idx = self.src_index(pos);
-        }
-        return None;
-    }
-
     fn try_real_token(&mut self) -> Result<Token, ()> {
         let mut t = self.try_next_token()?;
         loop {
@@ -1474,6 +1452,7 @@ fn mk_sess(sm: Lrc<SourceMap>) -> ParseSess {
             ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
             param_attr_spans: Lock::new(Vec::new()),
             let_chains_spans: Lock::new(Vec::new()),
+            async_closure_spans: Lock::new(Vec::new()),
         }
     }
 
index 94ce6297fbefbfcfb9d13d09b8c05af344e56e60..6a870685938a04bb8463baf75a5c22b463b5e234 100644 (file)
@@ -1,10 +1,11 @@
 // Characters and their corresponding confusables were collected from
 // http://www.unicode.org/Public/security/10.0.0/confusables.txt
 
-use syntax_pos::{Span, Pos, NO_EXPANSION};
-use errors::{Applicability, DiagnosticBuilder};
 use super::StringReader;
+use errors::{Applicability, DiagnosticBuilder};
+use syntax_pos::{Pos, Span, NO_EXPANSION};
 
+#[rustfmt::skip] // for line breaks
 const UNICODE_ARRAY: &[(char, &str, char)] = &[
     ('
', "Line Separator", ' '),
     ('
', "Paragraph Separator", ' '),
     ('〉', "Right-Pointing Angle Bracket", '>'),
     ('〉', "Right Angle Bracket", '>'),
     ('》', "Right Double Angle Bracket", '>'),
-    ('>', "Fullwidth Greater-Than Sign", '>'), ];
-
+    ('>', "Fullwidth Greater-Than Sign", '>'),
+];
 
 const ASCII_ARRAY: &[(char, &str)] = &[
     (' ', "Space"),
     ('+', "Plus Sign"),
     ('<', "Less-Than Sign"),
     ('=', "Equals Sign"),
-    ('>', "Greater-Than Sign"), ];
-
-crate fn check_for_substitution<'a>(reader: &StringReader<'a>,
-                                  ch: char,
-                                  err: &mut DiagnosticBuilder<'a>) -> bool {
-    UNICODE_ARRAY
-    .iter()
-    .find(|&&(c, _, _)| c == ch)
-    .map(|&(_, u_name, ascii_char)| {
-        let span = Span::new(reader.pos, reader.next_pos, NO_EXPANSION);
-        match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) {
-            Some(&(ascii_char, ascii_name)) => {
-                // special help suggestion for "directed" double quotes
-                if let Some(s) = reader.peek_delimited('“', '”') {
-                    let msg = format!("Unicode characters '“' (Left Double Quotation Mark) and \
-                        '”' (Right Double Quotation Mark) look like '{}' ({}), but are not",
-                                ascii_char, ascii_name);
-                    err.span_suggestion(
-                        Span::new(reader.pos, reader.next_pos + Pos::from_usize(s.len()) +
-                            Pos::from_usize('”'.len_utf8()), NO_EXPANSION),
-                        &msg,
-                        format!("\"{}\"", s),
-                        Applicability::MaybeIncorrect);
-                } else {
-                    let msg =
-                        format!("Unicode character '{}' ({}) looks like '{}' ({}), but it is not",
-                                ch, u_name, ascii_char, ascii_name);
-                    err.span_suggestion(
-                        span,
-                        &msg,
-                        ascii_char.to_string(),
-                        Applicability::MaybeIncorrect);
-                }
-                true
-            },
-            None => {
-                let msg = format!("substitution character not found for '{}'", ch);
-                reader.sess.span_diagnostic.span_bug_no_panic(span, &msg);
-                false
-            }
+    ('>', "Greater-Than Sign"),
+];
+
+crate fn check_for_substitution<'a>(
+    reader: &StringReader<'a>,
+    ch: char,
+    err: &mut DiagnosticBuilder<'a>,
+) -> bool {
+    let (u_name, ascii_char) = match UNICODE_ARRAY.iter().find(|&&(c, _, _)| c == ch) {
+        Some(&(_u_char, u_name, ascii_char)) => (u_name, ascii_char),
+        None => return false,
+    };
+
+    let span = Span::new(reader.pos, reader.next_pos, NO_EXPANSION);
+
+    let ascii_name = match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) {
+        Some((_ascii_char, ascii_name)) => ascii_name,
+        None => {
+            let msg = format!("substitution character not found for '{}'", ch);
+            reader.sess.span_diagnostic.span_bug_no_panic(span, &msg);
+            return false
+        },
+    };
+
+    // special help suggestion for "directed" double quotes
+    if let Some(s) = reader.peek_delimited('“', '”') {
+        let msg = format!(
+            "Unicode characters '“' (Left Double Quotation Mark) and \
+             '”' (Right Double Quotation Mark) look like '{}' ({}), but are not",
+            ascii_char, ascii_name
+        );
+        err.span_suggestion(
+            Span::new(
+                reader.pos,
+                reader.next_pos + Pos::from_usize(s.len()) + Pos::from_usize('”'.len_utf8()),
+                NO_EXPANSION,
+            ),
+            &msg,
+            format!("\"{}\"", s),
+            Applicability::MaybeIncorrect,
+        );
+    } else {
+        let msg = format!(
+            "Unicode character '{}' ({}) looks like '{}' ({}), but it is not",
+            ch, u_name, ascii_char, ascii_name
+        );
+        err.span_suggestion(
+            span,
+            &msg,
+            ascii_char.to_string(),
+            Applicability::MaybeIncorrect,
+        );
+    }
+    true
+}
+
+impl StringReader<'_> {
+    /// Immutably extract string if found at current position with given delimiters
+    fn peek_delimited(&self, from_ch: char, to_ch: char) -> Option<&str> {
+        let tail = &self.src[self.src_index(self.pos)..];
+        let mut chars = tail.chars();
+        let first_char = chars.next()?;
+        if first_char != from_ch {
+            return None;
         }
-    }).unwrap_or(false)
+        let last_char_idx = chars.as_str().find(to_ch)?;
+        Some(&chars.as_str()[..last_char_idx])
+    }
 }
index e19eab371f44ed1550eae1a6e13372b2889ad419..4056905d5dd014a40f0187b539ed4e2caedc365f 100644 (file)
@@ -57,6 +57,8 @@ pub struct ParseSess {
     pub param_attr_spans: Lock<Vec<Span>>,
     // Places where `let` exprs were used and should be feature gated according to `let_chains`.
     pub let_chains_spans: Lock<Vec<Span>>,
+    // Places where `async || ..` exprs were used and should be feature gated.
+    pub async_closure_spans: Lock<Vec<Span>>,
 }
 
 impl ParseSess {
@@ -84,6 +86,7 @@ pub fn with_span_handler(handler: Handler, source_map: Lrc<SourceMap>) -> ParseS
             ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
             param_attr_spans: Lock::new(Vec::new()),
             let_chains_spans: Lock::new(Vec::new()),
+            async_closure_spans: Lock::new(Vec::new()),
         }
     }
 
index fc206580e3811a79c107d1598c0ef2a775e949eb..a95b6891fb9d5876d243bfabc8cfe545be4102eb 100644 (file)
@@ -2572,12 +2572,12 @@ fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>, lo: Span) -> PResult<'a,
                           };
                           let sugg = pprust::to_string(|s| {
                               use crate::print::pprust::PrintState;
-                              s.popen()?;
-                              s.print_expr(&e)?;
-                              s.s.word( ".")?;
-                              s.print_usize(float.trunc() as usize)?;
-                              s.pclose()?;
-                              s.s.word(".")?;
+                              s.popen();
+                              s.print_expr(&e);
+                              s.s.word( ".");
+                              s.print_usize(float.trunc() as usize);
+                              s.pclose();
+                              s.s.word(".");
                               s.s.word(fstr.splitn(2, ".").last().unwrap().to_string())
                           });
                           err.span_suggestion(
@@ -3221,21 +3221,24 @@ fn parse_lambda_expr(&mut self,
                              -> PResult<'a, P<Expr>>
     {
         let lo = self.token.span;
+
         let movability = if self.eat_keyword(kw::Static) {
             Movability::Static
         } else {
             Movability::Movable
         };
+
         let asyncness = if self.token.span.rust_2018() {
             self.parse_asyncness()
         } else {
             IsAsync::NotAsync
         };
-        let capture_clause = if self.eat_keyword(kw::Move) {
-            CaptureBy::Value
-        } else {
-            CaptureBy::Ref
-        };
+        if asyncness.is_async() {
+            // Feature gate `async ||` closures.
+            self.sess.async_closure_spans.borrow_mut().push(self.prev_span);
+        }
+
+        let capture_clause = self.parse_capture_clause();
         let decl = self.parse_fn_block_decl()?;
         let decl_hi = self.prev_span;
         let body = match decl.output {
@@ -3257,7 +3260,7 @@ fn parse_lambda_expr(&mut self,
             attrs))
     }
 
-    // `else` token already eaten
+    /// `else` token already eaten
     fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
         if self.eat_keyword(kw::If) {
             return self.parse_if_expr(ThinVec::new());
@@ -3306,7 +3309,7 @@ fn parse_while_expr(&mut self, opt_label: Option<Label>,
         Ok(self.mk_expr(span, ExprKind::While(cond, body, opt_label), attrs))
     }
 
-    // parse `loop {...}`, `loop` token already eaten
+    /// Parse `loop {...}`, `loop` token already eaten.
     fn parse_loop_expr(&mut self, opt_label: Option<Label>,
                            span_lo: Span,
                            mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
@@ -3316,17 +3319,20 @@ fn parse_loop_expr(&mut self, opt_label: Option<Label>,
         Ok(self.mk_expr(span, ExprKind::Loop(body, opt_label), attrs))
     }
 
-    /// Parses an `async move {...}` expression.
-    pub fn parse_async_block(&mut self, mut attrs: ThinVec<Attribute>)
-        -> PResult<'a, P<Expr>>
-    {
-        let span_lo = self.token.span;
-        self.expect_keyword(kw::Async)?;
-        let capture_clause = if self.eat_keyword(kw::Move) {
+    /// Parse an optional `move` prefix to a closure lke construct.
+    fn parse_capture_clause(&mut self) -> CaptureBy {
+        if self.eat_keyword(kw::Move) {
             CaptureBy::Value
         } else {
             CaptureBy::Ref
-        };
+        }
+    }
+
+    /// Parses an `async move? {...}` expression.
+    pub fn parse_async_block(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
+        let span_lo = self.token.span;
+        self.expect_keyword(kw::Async)?;
+        let capture_clause = self.parse_capture_clause();
         let (iattrs, body) = self.parse_inner_attrs_and_block()?;
         attrs.extend(iattrs);
         Ok(self.mk_expr(
@@ -4324,51 +4330,49 @@ fn is_auto_trait_item(&self) -> bool {
     fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility, lo: Span)
                      -> PResult<'a, Option<P<Item>>> {
         let token_lo = self.token.span;
-        let (ident, def) = match self.token.kind {
-            token::Ident(name, false) if name == kw::Macro => {
-                self.bump();
-                let ident = self.parse_ident()?;
-                let tokens = if self.check(&token::OpenDelim(token::Brace)) {
-                    match self.parse_token_tree() {
-                        TokenTree::Delimited(_, _, tts) => tts,
-                        _ => unreachable!(),
-                    }
-                } else if self.check(&token::OpenDelim(token::Paren)) {
-                    let args = self.parse_token_tree();
-                    let body = if self.check(&token::OpenDelim(token::Brace)) {
-                        self.parse_token_tree()
-                    } else {
-                        self.unexpected()?;
-                        unreachable!()
-                    };
-                    TokenStream::new(vec![
-                        args.into(),
-                        TokenTree::token(token::FatArrow, token_lo.to(self.prev_span)).into(),
-                        body.into(),
-                    ])
+        let (ident, def) = if self.eat_keyword(kw::Macro) {
+            let ident = self.parse_ident()?;
+            let tokens = if self.check(&token::OpenDelim(token::Brace)) {
+                match self.parse_token_tree() {
+                    TokenTree::Delimited(_, _, tts) => tts,
+                    _ => unreachable!(),
+                }
+            } else if self.check(&token::OpenDelim(token::Paren)) {
+                let args = self.parse_token_tree();
+                let body = if self.check(&token::OpenDelim(token::Brace)) {
+                    self.parse_token_tree()
                 } else {
                     self.unexpected()?;
                     unreachable!()
                 };
+                TokenStream::new(vec![
+                    args.into(),
+                    TokenTree::token(token::FatArrow, token_lo.to(self.prev_span)).into(),
+                    body.into(),
+                ])
+            } else {
+                self.unexpected()?;
+                unreachable!()
+            };
 
-                (ident, ast::MacroDef { tokens: tokens.into(), legacy: false })
-            }
-            token::Ident(name, _) if name == sym::macro_rules &&
-                                     self.look_ahead(1, |t| *t == token::Not) => {
-                let prev_span = self.prev_span;
-                self.complain_if_pub_macro(&vis.node, prev_span);
-                self.bump();
-                self.bump();
-
-                let ident = self.parse_ident()?;
-                let (delim, tokens) = self.expect_delimited_token_tree()?;
-                if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
-                    self.report_invalid_macro_expansion_item();
-                }
+            (ident, ast::MacroDef { tokens: tokens.into(), legacy: false })
+        } else if self.check_keyword(sym::macro_rules) &&
+                  self.look_ahead(1, |t| *t == token::Not) &&
+                  self.look_ahead(2, |t| t.is_ident()) {
+            let prev_span = self.prev_span;
+            self.complain_if_pub_macro(&vis.node, prev_span);
+            self.bump();
+            self.bump();
 
-                (ident, ast::MacroDef { tokens, legacy: true })
+            let ident = self.parse_ident()?;
+            let (delim, tokens) = self.expect_delimited_token_tree()?;
+            if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
+                self.report_invalid_macro_expansion_item();
             }
-            _ => return Ok(None),
+
+            (ident, ast::MacroDef { tokens, legacy: true })
+        } else {
+            return Ok(None);
         };
 
         let span = lo.to(self.prev_span);
@@ -4412,14 +4416,14 @@ fn parse_stmt_without_recovery(&mut self,
                   !self.is_existential_type_decl() &&
                   !self.is_auto_trait_item() &&
                   !self.is_async_fn() {
-            let pth = self.parse_path(PathStyle::Expr)?;
+            let path = self.parse_path(PathStyle::Expr)?;
 
             if !self.eat(&token::Not) {
                 let expr = if self.check(&token::OpenDelim(token::Brace)) {
-                    self.parse_struct_expr(lo, pth, ThinVec::new())?
+                    self.parse_struct_expr(lo, path, ThinVec::new())?
                 } else {
                     let hi = self.prev_span;
-                    self.mk_expr(lo.to(hi), ExprKind::Path(None, pth), ThinVec::new())
+                    self.mk_expr(lo.to(hi), ExprKind::Path(None, path), ThinVec::new())
                 };
 
                 let expr = self.with_res(Restrictions::STMT_EXPR, |this| {
@@ -4434,34 +4438,6 @@ fn parse_stmt_without_recovery(&mut self,
                 }));
             }
 
-            // it's a macro invocation
-            let id = match self.token.kind {
-                token::OpenDelim(_) => Ident::invalid(), // no special identifier
-                _ => self.parse_ident()?,
-            };
-
-            // check that we're pointing at delimiters (need to check
-            // again after the `if`, because of `parse_ident`
-            // consuming more tokens).
-            match self.token.kind {
-                token::OpenDelim(_) => {}
-                _ => {
-                    // we only expect an ident if we didn't parse one
-                    // above.
-                    let ident_str = if id.name == kw::Invalid {
-                        "identifier, "
-                    } else {
-                        ""
-                    };
-                    let tok_str = self.this_token_descr();
-                    let mut err = self.fatal(&format!("expected {}`(` or `{{`, found {}",
-                                                      ident_str,
-                                                      tok_str));
-                    err.span_label(self.token.span, format!("expected {}`(` or `{{`", ident_str));
-                    return Err(err)
-                },
-            }
-
             let (delim, tts) = self.expect_delimited_token_tree()?;
             let hi = self.prev_span;
 
@@ -4471,59 +4447,38 @@ fn parse_stmt_without_recovery(&mut self,
                 MacStmtStyle::NoBraces
             };
 
-            if id.name == kw::Invalid {
-                let mac = respan(lo.to(hi), Mac_ { path: pth, tts, delim });
-                let node = if delim == MacDelimiter::Brace ||
-                              self.token == token::Semi || self.token == token::Eof {
-                    StmtKind::Mac(P((mac, style, attrs.into())))
-                }
-                // We used to incorrectly stop parsing macro-expanded statements here.
-                // If the next token will be an error anyway but could have parsed with the
-                // earlier behavior, stop parsing here and emit a warning to avoid breakage.
-                else if macro_legacy_warnings &&
-                        self.token.can_begin_expr() &&
-                        match self.token.kind {
-                    // These can continue an expression, so we can't stop parsing and warn.
-                    token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) |
-                    token::BinOp(token::Minus) | token::BinOp(token::Star) |
-                    token::BinOp(token::And) | token::BinOp(token::Or) |
-                    token::AndAnd | token::OrOr |
-                    token::DotDot | token::DotDotDot | token::DotDotEq => false,
-                    _ => true,
-                } {
-                    self.warn_missing_semicolon();
-                    StmtKind::Mac(P((mac, style, attrs.into())))
-                } else {
-                    let e = self.mk_expr(mac.span, ExprKind::Mac(mac), ThinVec::new());
-                    let e = self.maybe_recover_from_bad_qpath(e, true)?;
-                    let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?;
-                    let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
-                    StmtKind::Expr(e)
-                };
-                Stmt {
-                    id: ast::DUMMY_NODE_ID,
-                    span: lo.to(hi),
-                    node,
-                }
+            let mac = respan(lo.to(hi), Mac_ { path, tts, delim });
+            let node = if delim == MacDelimiter::Brace ||
+                          self.token == token::Semi || self.token == token::Eof {
+                StmtKind::Mac(P((mac, style, attrs.into())))
+            }
+            // We used to incorrectly stop parsing macro-expanded statements here.
+            // If the next token will be an error anyway but could have parsed with the
+            // earlier behavior, stop parsing here and emit a warning to avoid breakage.
+            else if macro_legacy_warnings &&
+                    self.token.can_begin_expr() &&
+                    match self.token.kind {
+                // These can continue an expression, so we can't stop parsing and warn.
+                token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) |
+                token::BinOp(token::Minus) | token::BinOp(token::Star) |
+                token::BinOp(token::And) | token::BinOp(token::Or) |
+                token::AndAnd | token::OrOr |
+                token::DotDot | token::DotDotDot | token::DotDotEq => false,
+                _ => true,
+            } {
+                self.warn_missing_semicolon();
+                StmtKind::Mac(P((mac, style, attrs.into())))
             } else {
-                // if it has a special ident, it's definitely an item
-                //
-                // Require a semicolon or braces.
-                if style != MacStmtStyle::Braces && !self.eat(&token::Semi) {
-                    self.report_invalid_macro_expansion_item();
-                }
-                let span = lo.to(hi);
-                Stmt {
-                    id: ast::DUMMY_NODE_ID,
-                    span,
-                    node: StmtKind::Item({
-                        self.mk_item(
-                            span, id /*id is good here*/,
-                            ItemKind::Mac(respan(span, Mac_ { path: pth, tts, delim })),
-                            respan(lo, VisibilityKind::Inherited),
-                            attrs)
-                    }),
-                }
+                let e = self.mk_expr(mac.span, ExprKind::Mac(mac), ThinVec::new());
+                let e = self.maybe_recover_from_bad_qpath(e, true)?;
+                let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?;
+                let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
+                StmtKind::Expr(e)
+            };
+            Stmt {
+                id: ast::DUMMY_NODE_ID,
+                span: lo.to(hi),
+                node,
             }
         } else {
             // FIXME: Bad copy of attrs
@@ -4634,9 +4589,9 @@ pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
                     }
                     let sugg = pprust::to_string(|s| {
                         use crate::print::pprust::{PrintState, INDENT_UNIT};
-                        s.ibox(INDENT_UNIT)?;
-                        s.bopen()?;
-                        s.print_stmt(&stmt)?;
+                        s.ibox(INDENT_UNIT);
+                        s.bopen();
+                        s.print_stmt(&stmt);
                         s.bclose_maybe_open(stmt.span, INDENT_UNIT, false)
                     });
                     e.span_suggestion(
@@ -5734,9 +5689,12 @@ fn parse_fn_front_matter(&mut self)
     {
         let is_const_fn = self.eat_keyword(kw::Const);
         let const_span = self.prev_span;
-        let unsafety = self.parse_unsafety();
         let asyncness = self.parse_asyncness();
+        if let IsAsync::Async { .. } = asyncness {
+            self.ban_async_in_2015(self.prev_span);
+        }
         let asyncness = respan(self.prev_span, asyncness);
+        let unsafety = self.parse_unsafety();
         let (constness, unsafety, abi) = if is_const_fn {
             (respan(const_span, Constness::Const), unsafety, Abi::Rust)
         } else {
@@ -7254,13 +7212,7 @@ fn parse_item_implementation(
                                         item_,
                                         visibility,
                                         maybe_append(attrs, extra_attrs));
-                if self.token.span.rust_2015() {
-                    self.diagnostic().struct_span_err_with_code(
-                        async_span,
-                        "`async fn` is not permitted in the 2015 edition",
-                        DiagnosticId::Error("E0670".into())
-                    ).emit();
-                }
+                self.ban_async_in_2015(async_span);
                 return Ok(Some(item));
             }
         }
@@ -7534,6 +7486,19 @@ fn parse_item_implementation(
         self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, visibility)
     }
 
+    /// We are parsing `async fn`. If we are on Rust 2015, emit an error.
+    fn ban_async_in_2015(&self, async_span: Span) {
+        if async_span.rust_2015() {
+            self.diagnostic()
+                .struct_span_err_with_code(
+                    async_span,
+                    "`async fn` is not permitted in the 2015 edition",
+                    DiagnosticId::Error("E0670".into())
+                )
+                .emit();
+        }
+    }
+
     /// Parses a foreign item.
     crate fn parse_foreign_item(&mut self) -> PResult<'a, ForeignItem> {
         maybe_whole!(self, NtForeignItem, |ni| ni);
@@ -7609,26 +7574,17 @@ fn parse_macro_use_or_failure(
             let mac_lo = self.token.span;
 
             // item macro.
-            let pth = self.parse_path(PathStyle::Mod)?;
+            let path = self.parse_path(PathStyle::Mod)?;
             self.expect(&token::Not)?;
-
-            // a 'special' identifier (like what `macro_rules!` uses)
-            // is optional. We should eventually unify invoc syntax
-            // and remove this.
-            let id = if self.token.is_ident() {
-                self.parse_ident()?
-            } else {
-                Ident::invalid() // no special identifier
-            };
-            // eat a matched-delimiter token tree:
             let (delim, tts) = self.expect_delimited_token_tree()?;
             if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
                 self.report_invalid_macro_expansion_item();
             }
 
             let hi = self.prev_span;
-            let mac = respan(mac_lo.to(hi), Mac_ { path: pth, tts, delim });
-            let item = self.mk_item(lo.to(hi), id, ItemKind::Mac(mac), visibility, attrs);
+            let mac = respan(mac_lo.to(hi), Mac_ { path, tts, delim });
+            let item =
+                self.mk_item(lo.to(hi), Ident::invalid(), ItemKind::Mac(mac), visibility, attrs);
             return Ok(Some(item));
         }
 
@@ -7654,9 +7610,9 @@ fn parse_assoc_macro_invoc(&mut self, item_kind: &str, vis: Option<&Visibility>,
                 !(self.is_async_fn() && self.token.span.rust_2015()) {
             let prev_span = self.prev_span;
             let lo = self.token.span;
-            let pth = self.parse_path(PathStyle::Mod)?;
+            let path = self.parse_path(PathStyle::Mod)?;
 
-            if pth.segments.len() == 1 {
+            if path.segments.len() == 1 {
                 if !self.eat(&token::Not) {
                     return Err(self.missing_assoc_item_kind_err(item_kind, prev_span));
                 }
@@ -7676,7 +7632,7 @@ fn parse_assoc_macro_invoc(&mut self, item_kind: &str, vis: Option<&Visibility>,
                 self.expect(&token::Semi)?;
             }
 
-            Ok(Some(respan(lo.to(self.prev_span), Mac_ { path: pth, tts, delim })))
+            Ok(Some(respan(lo.to(self.prev_span), Mac_ { path, tts, delim })))
         } else {
             Ok(None)
         }
@@ -7689,7 +7645,7 @@ fn collect_tokens<F, R>(&mut self, f: F) -> PResult<'a, (R, TokenStream)>
         let mut tokens = Vec::new();
         let prev_collecting = match self.token_cursor.frame.last_token {
             LastToken::Collecting(ref mut list) => {
-                Some(mem::replace(list, Vec::new()))
+                Some(mem::take(list))
             }
             LastToken::Was(ref mut last) => {
                 tokens.extend(last.take());
@@ -7707,7 +7663,7 @@ fn collect_tokens<F, R>(&mut self, f: F) -> PResult<'a, (R, TokenStream)>
 
         // Pull out the tokens that we've collected from the call to `f` above.
         let mut collected_tokens = match *last_token {
-            LastToken::Collecting(ref mut v) => mem::replace(v, Vec::new()),
+            LastToken::Collecting(ref mut v) => mem::take(v),
             LastToken::Was(_) => panic!("our vector went away?"),
         };
 
index f5412f3e216026aa4502b3f1435413acc9447373..f64e95aee5bca91ee5ac4382bdf997db165a519e 100644 (file)
 
 use std::collections::VecDeque;
 use std::fmt;
-use std::io;
 use std::borrow::Cow;
 use log::debug;
 
@@ -172,7 +171,7 @@ pub enum Token {
 }
 
 impl Token {
-    pub fn is_eof(&self) -> bool {
+    crate fn is_eof(&self) -> bool {
         match *self {
             Token::Eof => true,
             _ => false,
@@ -223,20 +222,21 @@ fn buf_str(buf: &[BufEntry], left: usize, right: usize, lim: usize) -> String {
 }
 
 #[derive(Copy, Clone)]
-pub enum PrintStackBreak {
+crate enum PrintStackBreak {
     Fits,
     Broken(Breaks),
 }
 
 #[derive(Copy, Clone)]
-pub struct PrintStackElem {
+crate struct PrintStackElem {
     offset: isize,
     pbreak: PrintStackBreak
 }
 
 const SIZE_INFINITY: isize = 0xffff;
 
-pub fn mk_printer<'a>(out: Box<dyn io::Write+'a>, linewidth: usize) -> Printer<'a> {
+pub fn mk_printer(out: &mut String) -> Printer<'_> {
+    let linewidth = 78;
     // Yes 55, it makes the ring buffers big enough to never fall behind.
     let n: usize = 55 * linewidth;
     debug!("mk_printer {}", linewidth);
@@ -259,7 +259,7 @@ pub fn mk_printer<'a>(out: Box<dyn io::Write+'a>, linewidth: usize) -> Printer<'
 }
 
 pub struct Printer<'a> {
-    out: Box<dyn io::Write+'a>,
+    out: &'a mut String,
     buf_max_len: usize,
     /// Width of lines we're constrained to
     margin: isize,
@@ -300,8 +300,6 @@ fn default() -> Self {
     }
 }
 
-const SPACES: [u8; 128] = [b' '; 128];
-
 impl<'a> Printer<'a> {
     pub fn last_token(&mut self) -> Token {
         self.buf[self.right].token.clone()
@@ -312,16 +310,15 @@ pub fn replace_last_token(&mut self, t: Token) {
         self.buf[self.right].token = t;
     }
 
-    fn pretty_print_eof(&mut self) -> io::Result<()> {
+    fn pretty_print_eof(&mut self) {
         if !self.scan_stack.is_empty() {
             self.check_stack(0);
-            self.advance_left()?;
+            self.advance_left();
         }
         self.indent(0);
-        Ok(())
     }
 
-    fn pretty_print_begin(&mut self, b: BeginToken) -> io::Result<()> {
+    fn pretty_print_begin(&mut self, b: BeginToken) {
         if self.scan_stack.is_empty() {
             self.left_total = 1;
             self.right_total = 1;
@@ -335,24 +332,22 @@ fn pretty_print_begin(&mut self, b: BeginToken) -> io::Result<()> {
         self.buf[self.right] = BufEntry { token: Token::Begin(b), size: -self.right_total };
         let right = self.right;
         self.scan_push(right);
-        Ok(())
     }
 
-    fn pretty_print_end(&mut self) -> io::Result<()> {
+    fn pretty_print_end(&mut self) {
         if self.scan_stack.is_empty() {
             debug!("pp End/print Vec<{},{}>", self.left, self.right);
-            self.print_end()
+            self.print_end();
         } else {
             debug!("pp End/buffer Vec<{},{}>", self.left, self.right);
             self.advance_right();
             self.buf[self.right] = BufEntry { token: Token::End, size: -1 };
             let right = self.right;
             self.scan_push(right);
-            Ok(())
         }
     }
 
-    fn pretty_print_break(&mut self, b: BreakToken) -> io::Result<()> {
+    fn pretty_print_break(&mut self, b: BreakToken) {
         if self.scan_stack.is_empty() {
             self.left_total = 1;
             self.right_total = 1;
@@ -368,25 +363,24 @@ fn pretty_print_break(&mut self, b: BreakToken) -> io::Result<()> {
         self.scan_push(right);
         self.buf[self.right] = BufEntry { token: Token::Break(b), size: -self.right_total };
         self.right_total += b.blank_space;
-        Ok(())
     }
 
-    fn pretty_print_string(&mut self, s: Cow<'static, str>, len: isize) -> io::Result<()> {
+    fn pretty_print_string(&mut self, s: Cow<'static, str>, len: isize) {
         if self.scan_stack.is_empty() {
             debug!("pp String('{}')/print Vec<{},{}>",
                    s, self.left, self.right);
-            self.print_string(s, len)
+            self.print_string(s, len);
         } else {
             debug!("pp String('{}')/buffer Vec<{},{}>",
                    s, self.left, self.right);
             self.advance_right();
             self.buf[self.right] = BufEntry { token: Token::String(s, len), size: len };
             self.right_total += len;
-            self.check_stream()
+            self.check_stream();
         }
     }
 
-    pub fn check_stream(&mut self) -> io::Result<()> {
+    crate fn check_stream(&mut self) {
         debug!("check_stream Vec<{}, {}> with left_total={}, right_total={}",
                self.left, self.right, self.left_total, self.right_total);
         if self.right_total - self.left_total > self.space {
@@ -397,32 +391,31 @@ pub fn check_stream(&mut self) -> io::Result<()> {
                 let scanned = self.scan_pop_bottom();
                 self.buf[scanned].size = SIZE_INFINITY;
             }
-            self.advance_left()?;
+            self.advance_left();
             if self.left != self.right {
-                self.check_stream()?;
+                self.check_stream();
             }
         }
-        Ok(())
     }
 
-    pub fn scan_push(&mut self, x: usize) {
+    crate fn scan_push(&mut self, x: usize) {
         debug!("scan_push {}", x);
         self.scan_stack.push_front(x);
     }
 
-    pub fn scan_pop(&mut self) -> usize {
+    crate fn scan_pop(&mut self) -> usize {
         self.scan_stack.pop_front().unwrap()
     }
 
-    pub fn scan_top(&mut self) -> usize {
+    crate fn scan_top(&mut self) -> usize {
         *self.scan_stack.front().unwrap()
     }
 
-    pub fn scan_pop_bottom(&mut self) -> usize {
+    crate fn scan_pop_bottom(&mut self) -> usize {
         self.scan_stack.pop_back().unwrap()
     }
 
-    pub fn advance_right(&mut self) {
+    crate fn advance_right(&mut self) {
         self.right += 1;
         self.right %= self.buf_max_len;
         // Extend the buf if necessary.
@@ -432,7 +425,7 @@ pub fn advance_right(&mut self) {
         assert_ne!(self.right, self.left);
     }
 
-    pub fn advance_left(&mut self) -> io::Result<()> {
+    crate fn advance_left(&mut self) {
         debug!("advance_left Vec<{},{}>, sizeof({})={}", self.left, self.right,
                self.left, self.buf[self.left].size);
 
@@ -450,7 +443,7 @@ pub fn advance_left(&mut self) -> io::Result<()> {
                 _ => 0
             };
 
-            self.print(left, left_size)?;
+            self.print(left, left_size);
 
             self.left_total += len;
 
@@ -463,11 +456,9 @@ pub fn advance_left(&mut self) -> io::Result<()> {
 
             left_size = self.buf[self.left].size;
         }
-
-        Ok(())
     }
 
-    pub fn check_stack(&mut self, k: isize) {
+    crate fn check_stack(&mut self, k: isize) {
         if !self.scan_stack.is_empty() {
             let x = self.scan_top();
             match self.buf[x].token {
@@ -495,20 +486,19 @@ pub fn check_stack(&mut self, k: isize) {
         }
     }
 
-    pub fn print_newline(&mut self, amount: isize) -> io::Result<()> {
+    crate fn print_newline(&mut self, amount: isize) {
         debug!("NEWLINE {}", amount);
-        let ret = writeln!(self.out);
+        self.out.push('\n');
         self.pending_indentation = 0;
         self.indent(amount);
-        ret
     }
 
-    pub fn indent(&mut self, amount: isize) {
+    crate fn indent(&mut self, amount: isize) {
         debug!("INDENT {}", amount);
         self.pending_indentation += amount;
     }
 
-    pub fn get_top(&mut self) -> PrintStackElem {
+    crate fn get_top(&mut self) -> PrintStackElem {
         match self.print_stack.last() {
             Some(el) => *el,
             None => PrintStackElem {
@@ -518,7 +508,7 @@ pub fn get_top(&mut self) -> PrintStackElem {
         }
     }
 
-    pub fn print_begin(&mut self, b: BeginToken, l: isize) -> io::Result<()> {
+    crate fn print_begin(&mut self, b: BeginToken, l: isize) {
         if l > self.space {
             let col = self.margin - self.space + b.offset;
             debug!("print Begin -> push broken block at col {}", col);
@@ -533,52 +523,46 @@ pub fn print_begin(&mut self, b: BeginToken, l: isize) -> io::Result<()> {
                 pbreak: PrintStackBreak::Fits
             });
         }
-        Ok(())
     }
 
-    pub fn print_end(&mut self) -> io::Result<()> {
+    crate fn print_end(&mut self) {
         debug!("print End -> pop End");
         let print_stack = &mut self.print_stack;
         assert!(!print_stack.is_empty());
         print_stack.pop().unwrap();
-        Ok(())
     }
 
-    pub fn print_break(&mut self, b: BreakToken, l: isize) -> io::Result<()> {
+    crate fn print_break(&mut self, b: BreakToken, l: isize) {
         let top = self.get_top();
         match top.pbreak {
             PrintStackBreak::Fits => {
                 debug!("print Break({}) in fitting block", b.blank_space);
                 self.space -= b.blank_space;
                 self.indent(b.blank_space);
-                Ok(())
             }
             PrintStackBreak::Broken(Breaks::Consistent) => {
                 debug!("print Break({}+{}) in consistent block",
                        top.offset, b.offset);
-                let ret = self.print_newline(top.offset + b.offset);
+                self.print_newline(top.offset + b.offset);
                 self.space = self.margin - (top.offset + b.offset);
-                ret
             }
             PrintStackBreak::Broken(Breaks::Inconsistent) => {
                 if l > self.space {
                     debug!("print Break({}+{}) w/ newline in inconsistent",
                            top.offset, b.offset);
-                    let ret = self.print_newline(top.offset + b.offset);
+                    self.print_newline(top.offset + b.offset);
                     self.space = self.margin - (top.offset + b.offset);
-                    ret
                 } else {
                     debug!("print Break({}) w/o newline in inconsistent",
                            b.blank_space);
                     self.indent(b.blank_space);
                     self.space -= b.blank_space;
-                    Ok(())
                 }
             }
         }
     }
 
-    pub fn print_string(&mut self, s: Cow<'static, str>, len: isize) -> io::Result<()> {
+    crate fn print_string(&mut self, s: Cow<'static, str>, len: isize) {
         debug!("print String({})", s);
         // assert!(len <= space);
         self.space -= len;
@@ -587,23 +571,15 @@ pub fn print_string(&mut self, s: Cow<'static, str>, len: isize) -> io::Result<(
         //
         //   write!(self.out, "{: >n$}", "", n = self.pending_indentation as usize)?;
         //
-        // But that is significantly slower than using `SPACES`. This code is
-        // sufficiently hot, and indents can get sufficiently large, that the
-        // difference is significant on some workloads.
-        let spaces_len = SPACES.len() as isize;
-        while self.pending_indentation >= spaces_len {
-            self.out.write_all(&SPACES)?;
-            self.pending_indentation -= spaces_len;
-        }
-        if self.pending_indentation > 0 {
-            self.out.write_all(&SPACES[0..self.pending_indentation as usize])?;
-            self.pending_indentation = 0;
-        }
-
-        write!(self.out, "{}", s)
+        // But that is significantly slower. This code is sufficiently hot, and indents can get
+        // sufficiently large, that the difference is significant on some workloads.
+        self.out.reserve(self.pending_indentation as usize);
+        self.out.extend(std::iter::repeat(' ').take(self.pending_indentation as usize));
+        self.pending_indentation = 0;
+        self.out.push_str(&s);
     }
 
-    pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> {
+    crate fn print(&mut self, token: Token, l: isize) {
         debug!("print {} {} (remaining line space={})", token, l,
                self.space);
         debug!("{}", buf_str(&self.buf,
@@ -616,7 +592,7 @@ pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> {
             Token::Break(b) => self.print_break(b, l),
             Token::String(s, len) => {
                 assert_eq!(len, l);
-                self.print_string(s, len)
+                self.print_string(s, len);
             }
             Token::Eof => panic!(), // Eof should never get here.
         }
@@ -625,7 +601,7 @@ pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> {
     // Convenience functions to talk to the printer.
 
     /// "raw box"
-    pub fn rbox(&mut self, indent: usize, b: Breaks) -> io::Result<()> {
+    crate fn rbox(&mut self, indent: usize, b: Breaks) {
         self.pretty_print_begin(BeginToken {
             offset: indent as isize,
             breaks: b
@@ -633,57 +609,53 @@ pub fn rbox(&mut self, indent: usize, b: Breaks) -> io::Result<()> {
     }
 
     /// Inconsistent breaking box
-    pub fn ibox(&mut self, indent: usize) -> io::Result<()> {
+    crate fn ibox(&mut self, indent: usize) {
         self.rbox(indent, Breaks::Inconsistent)
     }
 
     /// Consistent breaking box
-    pub fn cbox(&mut self, indent: usize) -> io::Result<()> {
+    pub fn cbox(&mut self, indent: usize) {
         self.rbox(indent, Breaks::Consistent)
     }
 
-    pub fn break_offset(&mut self, n: usize, off: isize) -> io::Result<()> {
+    pub fn break_offset(&mut self, n: usize, off: isize) {
         self.pretty_print_break(BreakToken {
             offset: off,
             blank_space: n as isize
         })
     }
 
-    pub fn end(&mut self) -> io::Result<()> {
+    crate fn end(&mut self) {
         self.pretty_print_end()
     }
 
-    pub fn eof(&mut self) -> io::Result<()> {
+    pub fn eof(&mut self) {
         self.pretty_print_eof()
     }
 
-    pub fn word<S: Into<Cow<'static, str>>>(&mut self, wrd: S) -> io::Result<()> {
+    pub fn word<S: Into<Cow<'static, str>>>(&mut self, wrd: S) {
         let s = wrd.into();
         let len = s.len() as isize;
         self.pretty_print_string(s, len)
     }
 
-    fn spaces(&mut self, n: usize) -> io::Result<()> {
+    fn spaces(&mut self, n: usize) {
         self.break_offset(n, 0)
     }
 
-    pub fn zerobreak(&mut self) -> io::Result<()> {
+    crate fn zerobreak(&mut self) {
         self.spaces(0)
     }
 
-    pub fn space(&mut self) -> io::Result<()> {
+    pub fn space(&mut self) {
         self.spaces(1)
     }
 
-    pub fn hardbreak(&mut self) -> io::Result<()> {
+    pub fn hardbreak(&mut self) {
         self.spaces(SIZE_INFINITY as usize)
     }
 
     pub fn hardbreak_tok_offset(off: isize) -> Token {
         Token::Break(BreakToken {offset: off, blank_space: SIZE_INFINITY})
     }
-
-    pub fn hardbreak_tok() -> Token {
-        Self::hardbreak_tok_offset(0)
-    }
 }
index 3f059927e57fe9429628a95958762bab3de22e33..67646cce69b4f47d2addf5753ad5c20a98845fba 100644 (file)
@@ -21,8 +21,7 @@
 use syntax_pos::{DUMMY_SP, FileName};
 
 use std::borrow::Cow;
-use std::io::{self, Write, Read};
-use std::vec;
+use std::io::Read;
 
 pub enum AnnNode<'a> {
     Ident(&'a ast::Ident),
@@ -35,8 +34,8 @@ pub enum AnnNode<'a> {
 }
 
 pub trait PpAnn {
-    fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) -> io::Result<()> { Ok(()) }
-    fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) -> io::Result<()> { Ok(()) }
+    fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) { }
+    fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) { }
 }
 
 #[derive(Copy, Clone)]
@@ -54,21 +53,7 @@ pub struct State<'a> {
     is_expanded: bool
 }
 
-fn rust_printer<'a>(writer: Box<dyn Write+'a>, ann: &'a dyn PpAnn) -> State<'a> {
-    State {
-        s: pp::mk_printer(writer, DEFAULT_COLUMNS),
-        cm: None,
-        comments: None,
-        cur_cmnt: 0,
-        boxes: Vec::new(),
-        ann,
-        is_expanded: false
-    }
-}
-
-pub const INDENT_UNIT: usize = 4;
-
-pub const DEFAULT_COLUMNS: usize = 78;
+crate const INDENT_UNIT: usize = 4;
 
 /// Requires you to pass an input filename and reader so that
 /// it can scan the input text for comments to copy forward.
@@ -77,9 +62,9 @@ pub fn print_crate<'a>(cm: &'a SourceMap,
                        krate: &ast::Crate,
                        filename: FileName,
                        input: &mut dyn Read,
-                       out: Box<dyn Write+'a>,
+                       out: &mut String,
                        ann: &'a dyn PpAnn,
-                       is_expanded: bool) -> io::Result<()> {
+                       is_expanded: bool) {
     let mut s = State::new_from_input(cm, sess, filename, input, out, ann, is_expanded);
 
     if is_expanded && std_inject::injected_crate_name().is_some() {
@@ -93,16 +78,16 @@ pub fn print_crate<'a>(cm: &'a SourceMap,
         let list = attr::mk_list_item(
             DUMMY_SP, ast::Ident::with_empty_ctxt(sym::feature), vec![pi_nested]);
         let fake_attr = attr::mk_attr_inner(DUMMY_SP, attr::mk_attr_id(), list);
-        s.print_attribute(&fake_attr)?;
+        s.print_attribute(&fake_attr);
 
         // #![no_std]
         let no_std_meta = attr::mk_word_item(ast::Ident::with_empty_ctxt(sym::no_std));
         let fake_attr = attr::mk_attr_inner(DUMMY_SP, attr::mk_attr_id(), no_std_meta);
-        s.print_attribute(&fake_attr)?;
+        s.print_attribute(&fake_attr);
     }
 
-    s.print_mod(&krate.module, &krate.attrs)?;
-    s.print_remaining_comments()?;
+    s.print_mod(&krate.module, &krate.attrs);
+    s.print_remaining_comments();
     s.s.eof()
 }
 
@@ -111,7 +96,7 @@ pub fn new_from_input(cm: &'a SourceMap,
                           sess: &ParseSess,
                           filename: FileName,
                           input: &mut dyn Read,
-                          out: Box<dyn Write+'a>,
+                          out: &'a mut String,
                           ann: &'a dyn PpAnn,
                           is_expanded: bool) -> State<'a> {
         let comments = comments::gather_comments(sess, filename, input);
@@ -119,12 +104,12 @@ pub fn new_from_input(cm: &'a SourceMap,
     }
 
     pub fn new(cm: &'a SourceMap,
-               out: Box<dyn Write+'a>,
+               out: &'a mut String,
                ann: &'a dyn PpAnn,
                comments: Option<Vec<comments::Comment>>,
                is_expanded: bool) -> State<'a> {
         State {
-            s: pp::mk_printer(out, DEFAULT_COLUMNS),
+            s: pp::mk_printer(out),
             cm: Some(cm),
             comments,
             cur_cmnt: 0,
@@ -136,16 +121,23 @@ pub fn new(cm: &'a SourceMap,
 }
 
 pub fn to_string<F>(f: F) -> String where
-    F: FnOnce(&mut State<'_>) -> io::Result<()>,
+    F: FnOnce(&mut State<'_>),
 {
-    let mut wr = Vec::new();
+    let mut wr = String::new();
     {
-        let ann = NoAnn;
-        let mut printer = rust_printer(Box::new(&mut wr), &ann);
-        f(&mut printer).unwrap();
-        printer.s.eof().unwrap();
+        let mut printer = State {
+            s: pp::mk_printer(&mut wr),
+            cm: None,
+            comments: None,
+            cur_cmnt: 0,
+            boxes: Vec::new(),
+            ann: &NoAnn,
+            is_expanded: false
+        };
+        f(&mut printer);
+        printer.s.eof();
     }
-    String::from_utf8(wr).unwrap()
+    wr
 }
 
 fn binop_to_string(op: BinOpToken) -> &'static str {
@@ -254,7 +246,7 @@ pub fn token_to_string(token: &Token) -> String {
     token_kind_to_string(&token.kind)
 }
 
-pub fn nonterminal_to_string(nt: &Nonterminal) -> String {
+crate fn nonterminal_to_string(nt: &Nonterminal) -> String {
     match *nt {
         token::NtExpr(ref e)        => expr_to_string(e),
         token::NtMeta(ref e)        => meta_item_to_string(e),
@@ -366,20 +358,20 @@ pub fn fun_to_string(decl: &ast::FnDecl,
                      generics: &ast::Generics)
                      -> String {
     to_string(|s| {
-        s.head("")?;
+        s.head("");
         s.print_fn(decl, header, Some(name),
-                   generics, &source_map::dummy_spanned(ast::VisibilityKind::Inherited))?;
-        s.end()?; // Close the head box
-        s.end() // Close the outer box
+                   generics, &source_map::dummy_spanned(ast::VisibilityKind::Inherited));
+        s.end(); // Close the head box
+        s.end(); // Close the outer box
     })
 }
 
 pub fn block_to_string(blk: &ast::Block) -> String {
     to_string(|s| {
         // containing cbox, will be closed by print-block at }
-        s.cbox(INDENT_UNIT)?;
+        s.cbox(INDENT_UNIT);
         // head-ibox, will be closed by print-block after {
-        s.ibox(0)?;
+        s.ibox(0);
         s.print_block(blk)
     })
 }
@@ -426,14 +418,14 @@ pub trait PrintState<'a> {
     fn comments(&mut self) -> &mut Option<Vec<comments::Comment>>;
     fn cur_cmnt(&mut self) -> &mut usize;
 
-    fn word_space<S: Into<Cow<'static, str>>>(&mut self, w: S) -> io::Result<()> {
-        self.writer().word(w)?;
+    fn word_space<S: Into<Cow<'static, str>>>(&mut self, w: S) {
+        self.writer().word(w);
         self.writer().space()
     }
 
-    fn popen(&mut self) -> io::Result<()> { self.writer().word("(") }
+    fn popen(&mut self) { self.writer().word("(") }
 
-    fn pclose(&mut self) -> io::Result<()> { self.writer().word(")") }
+    fn pclose(&mut self) { self.writer().word(")") }
 
     fn is_begin(&mut self) -> bool {
         match self.writer().last_token() {
@@ -454,89 +446,86 @@ fn is_bol(&mut self) -> bool {
         self.writer().last_token().is_eof() || self.writer().last_token().is_hardbreak_tok()
     }
 
-    fn hardbreak_if_not_bol(&mut self) -> io::Result<()> {
+    fn hardbreak_if_not_bol(&mut self) {
         if !self.is_bol() {
-            self.writer().hardbreak()?
+            self.writer().hardbreak()
         }
-        Ok(())
     }
 
     // "raw box"
-    fn rbox(&mut self, u: usize, b: pp::Breaks) -> io::Result<()> {
+    fn rbox(&mut self, u: usize, b: pp::Breaks) {
         self.boxes().push(b);
         self.writer().rbox(u, b)
     }
 
-    fn ibox(&mut self, u: usize) -> io::Result<()> {
+    fn ibox(&mut self, u: usize) {
         self.boxes().push(pp::Breaks::Inconsistent);
-        self.writer().ibox(u)
+        self.writer().ibox(u);
     }
 
-    fn end(&mut self) -> io::Result<()> {
+    fn end(&mut self) {
         self.boxes().pop().unwrap();
         self.writer().end()
     }
 
-    fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()>
-        where F: FnMut(&mut Self, &T) -> io::Result<()>,
+    fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F)
+        where F: FnMut(&mut Self, &T),
     {
-        self.rbox(0, b)?;
+        self.rbox(0, b);
         let mut first = true;
         for elt in elts {
-            if first { first = false; } else { self.word_space(",")?; }
-            op(self, elt)?;
+            if first { first = false; } else { self.word_space(","); }
+            op(self, elt);
         }
-        self.end()
+        self.end();
     }
 
-    fn maybe_print_comment(&mut self, pos: BytePos) -> io::Result<()> {
+    fn maybe_print_comment(&mut self, pos: BytePos) {
         while let Some(ref cmnt) = self.next_comment() {
             if cmnt.pos < pos {
-                self.print_comment(cmnt)?;
+                self.print_comment(cmnt);
             } else {
                 break
             }
         }
-        Ok(())
     }
 
     fn print_comment(&mut self,
-                     cmnt: &comments::Comment) -> io::Result<()> {
-        let r = match cmnt.style {
+                     cmnt: &comments::Comment) {
+        match cmnt.style {
             comments::Mixed => {
                 assert_eq!(cmnt.lines.len(), 1);
-                self.writer().zerobreak()?;
-                self.writer().word(cmnt.lines[0].clone())?;
+                self.writer().zerobreak();
+                self.writer().word(cmnt.lines[0].clone());
                 self.writer().zerobreak()
             }
             comments::Isolated => {
-                self.hardbreak_if_not_bol()?;
+                self.hardbreak_if_not_bol();
                 for line in &cmnt.lines {
                     // Don't print empty lines because they will end up as trailing
                     // whitespace
                     if !line.is_empty() {
-                        self.writer().word(line.clone())?;
+                        self.writer().word(line.clone());
                     }
-                    self.writer().hardbreak()?;
+                    self.writer().hardbreak();
                 }
-                Ok(())
             }
             comments::Trailing => {
                 if !self.is_bol() {
-                    self.writer().word(" ")?;
+                    self.writer().word(" ");
                 }
                 if cmnt.lines.len() == 1 {
-                    self.writer().word(cmnt.lines[0].clone())?;
+                    self.writer().word(cmnt.lines[0].clone());
                     self.writer().hardbreak()
                 } else {
-                    self.ibox(0)?;
+                    self.ibox(0);
                     for line in &cmnt.lines {
                         if !line.is_empty() {
-                            self.writer().word(line.clone())?;
+                            self.writer().word(line.clone());
                         }
-                        self.writer().hardbreak()?;
+                        self.writer().hardbreak();
                     }
-                    self.end()
+                    self.end();
                 }
             }
             comments::BlankLine => {
@@ -546,18 +535,12 @@ fn print_comment(&mut self,
                     _ => false
                 };
                 if is_semi || self.is_begin() || self.is_end() {
-                    self.writer().hardbreak()?;
+                    self.writer().hardbreak();
                 }
-                self.writer().hardbreak()
-            }
-        };
-        match r {
-            Ok(()) => {
-                *self.cur_cmnt() = *self.cur_cmnt() + 1;
-                Ok(())
+                self.writer().hardbreak();
             }
-            Err(e) => Err(e),
         }
+        *self.cur_cmnt() = *self.cur_cmnt() + 1;
     }
 
     fn next_comment(&mut self) -> Option<comments::Comment> {
@@ -574,13 +557,13 @@ fn next_comment(&mut self) -> Option<comments::Comment> {
         }
     }
 
-    fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> {
-        self.maybe_print_comment(lit.span.lo())?;
+    fn print_literal(&mut self, lit: &ast::Lit) {
+        self.maybe_print_comment(lit.span.lo());
         self.writer().word(literal_to_string(lit.token))
     }
 
     fn print_string(&mut self, st: &str,
-                    style: ast::StrStyle) -> io::Result<()> {
+                    style: ast::StrStyle) {
         let st = match style {
             ast::StrStyle::Cooked => {
                 (format!("\"{}\"", st.escape_debug()))
@@ -595,28 +578,28 @@ fn print_string(&mut self, st: &str,
     }
 
     fn print_inner_attributes(&mut self,
-                              attrs: &[ast::Attribute]) -> io::Result<()> {
+                              attrs: &[ast::Attribute]) {
         self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, true)
     }
 
     fn print_inner_attributes_no_trailing_hardbreak(&mut self,
                                                    attrs: &[ast::Attribute])
-                                                   -> io::Result<()> {
+                                                   {
         self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, false)
     }
 
     fn print_outer_attributes(&mut self,
-                              attrs: &[ast::Attribute]) -> io::Result<()> {
+                              attrs: &[ast::Attribute]) {
         self.print_either_attributes(attrs, ast::AttrStyle::Outer, false, true)
     }
 
     fn print_inner_attributes_inline(&mut self,
-                                     attrs: &[ast::Attribute]) -> io::Result<()> {
+                                     attrs: &[ast::Attribute]) {
         self.print_either_attributes(attrs, ast::AttrStyle::Inner, true, true)
     }
 
     fn print_outer_attributes_inline(&mut self,
-                                     attrs: &[ast::Attribute]) -> io::Result<()> {
+                                     attrs: &[ast::Attribute]) {
         self.print_either_attributes(attrs, ast::AttrStyle::Outer, true, true)
     }
 
@@ -624,69 +607,67 @@ fn print_either_attributes(&mut self,
                               attrs: &[ast::Attribute],
                               kind: ast::AttrStyle,
                               is_inline: bool,
-                              trailing_hardbreak: bool) -> io::Result<()> {
+                              trailing_hardbreak: bool) {
         let mut count = 0;
         for attr in attrs {
             if attr.style == kind {
-                self.print_attribute_inline(attr, is_inline)?;
+                self.print_attribute_inline(attr, is_inline);
                 if is_inline {
-                    self.nbsp()?;
+                    self.nbsp();
                 }
                 count += 1;
             }
         }
         if count > 0 && trailing_hardbreak && !is_inline {
-            self.hardbreak_if_not_bol()?;
+            self.hardbreak_if_not_bol();
         }
-        Ok(())
     }
 
-    fn print_attribute_path(&mut self, path: &ast::Path) -> io::Result<()> {
+    fn print_attribute_path(&mut self, path: &ast::Path) {
         for (i, segment) in path.segments.iter().enumerate() {
             if i > 0 {
-                self.writer().word("::")?
+                self.writer().word("::");
             }
             if segment.ident.name != kw::PathRoot {
                 if segment.ident.name == kw::DollarCrate {
-                    self.print_dollar_crate(segment.ident)?;
+                    self.print_dollar_crate(segment.ident);
                 } else {
-                    self.writer().word(segment.ident.as_str().to_string())?;
+                    self.writer().word(segment.ident.as_str().to_string());
                 }
             }
         }
-        Ok(())
     }
 
-    fn print_attribute(&mut self, attr: &ast::Attribute) -> io::Result<()> {
+    fn print_attribute(&mut self, attr: &ast::Attribute) {
         self.print_attribute_inline(attr, false)
     }
 
     fn print_attribute_inline(&mut self, attr: &ast::Attribute,
-                              is_inline: bool) -> io::Result<()> {
+                              is_inline: bool) {
         if !is_inline {
-            self.hardbreak_if_not_bol()?;
+            self.hardbreak_if_not_bol();
         }
-        self.maybe_print_comment(attr.span.lo())?;
+        self.maybe_print_comment(attr.span.lo());
         if attr.is_sugared_doc {
-            self.writer().word(attr.value_str().unwrap().as_str().to_string())?;
+            self.writer().word(attr.value_str().unwrap().as_str().to_string());
             self.writer().hardbreak()
         } else {
             match attr.style {
-                ast::AttrStyle::Inner => self.writer().word("#![")?,
-                ast::AttrStyle::Outer => self.writer().word("#[")?,
+                ast::AttrStyle::Inner => self.writer().word("#!["),
+                ast::AttrStyle::Outer => self.writer().word("#["),
             }
             if let Some(mi) = attr.meta() {
-                self.print_meta_item(&mi)?
+                self.print_meta_item(&mi);
             } else {
-                self.print_attribute_path(&attr.path)?;
-                self.writer().space()?;
-                self.print_tts(attr.tokens.clone())?;
+                self.print_attribute_path(&attr.path);
+                self.writer().space();
+                self.print_tts(attr.tokens.clone());
             }
-            self.writer().word("]")
+            self.writer().word("]");
         }
     }
 
-    fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) -> io::Result<()> {
+    fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) {
         match item {
             ast::NestedMetaItem::MetaItem(ref mi) => {
                 self.print_meta_item(mi)
@@ -697,26 +678,26 @@ fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) -> io::Result<()>
         }
     }
 
-    fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> {
-        self.ibox(INDENT_UNIT)?;
+    fn print_meta_item(&mut self, item: &ast::MetaItem) {
+        self.ibox(INDENT_UNIT);
         match item.node {
-            ast::MetaItemKind::Word => self.print_attribute_path(&item.path)?,
+            ast::MetaItemKind::Word => self.print_attribute_path(&item.path),
             ast::MetaItemKind::NameValue(ref value) => {
-                self.print_attribute_path(&item.path)?;
-                self.writer().space()?;
-                self.word_space("=")?;
-                self.print_literal(value)?;
+                self.print_attribute_path(&item.path);
+                self.writer().space();
+                self.word_space("=");
+                self.print_literal(value);
             }
             ast::MetaItemKind::List(ref items) => {
-                self.print_attribute_path(&item.path)?;
-                self.popen()?;
+                self.print_attribute_path(&item.path);
+                self.popen();
                 self.commasep(Consistent,
                               &items[..],
-                              |s, i| s.print_meta_list_item(i))?;
-                self.pclose()?;
+                              |s, i| s.print_meta_list_item(i));
+                self.pclose();
             }
         }
-        self.end()
+        self.end();
     }
 
     /// This doesn't deserve to be called "pretty" printing, but it should be
@@ -726,44 +707,43 @@ fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> {
     /// appropriate macro, transcribe back into the grammar we just parsed from,
     /// and then pretty-print the resulting AST nodes (so, e.g., we print
     /// expression arguments as expressions). It can be done! I think.
-    fn print_tt(&mut self, tt: tokenstream::TokenTree) -> io::Result<()> {
+    fn print_tt(&mut self, tt: tokenstream::TokenTree) {
         match tt {
             TokenTree::Token(ref token) => {
-                self.writer().word(token_to_string(&token))?;
+                self.writer().word(token_to_string(&token));
                 match token.kind {
                     token::DocComment(..) => {
                         self.writer().hardbreak()
                     }
-                    _ => Ok(())
+                    _ => {}
                 }
             }
             TokenTree::Delimited(_, delim, tts) => {
-                self.writer().word(token_kind_to_string(&token::OpenDelim(delim)))?;
-                self.writer().space()?;
-                self.print_tts(tts)?;
-                self.writer().space()?;
+                self.writer().word(token_kind_to_string(&token::OpenDelim(delim)));
+                self.writer().space();
+                self.print_tts(tts);
+                self.writer().space();
                 self.writer().word(token_kind_to_string(&token::CloseDelim(delim)))
             },
         }
     }
 
-    fn print_tts(&mut self, tts: tokenstream::TokenStream) -> io::Result<()> {
-        self.ibox(0)?;
+    fn print_tts(&mut self, tts: tokenstream::TokenStream) {
+        self.ibox(0);
         for (i, tt) in tts.into_trees().enumerate() {
             if i != 0 {
-                self.writer().space()?;
+                self.writer().space();
             }
-            self.print_tt(tt)?;
+            self.print_tt(tt);
         }
-        self.end()
+        self.end();
     }
 
-    fn space_if_not_bol(&mut self) -> io::Result<()> {
-        if !self.is_bol() { self.writer().space()?; }
-        Ok(())
+    fn space_if_not_bol(&mut self) {
+        if !self.is_bol() { self.writer().space(); }
     }
 
-    fn nbsp(&mut self) -> io::Result<()> { self.writer().word(" ") }
+    fn nbsp(&mut self) { self.writer().word(" ") }
 
     // AST pretty-printer is used as a fallback for turning AST structures into token streams for
     // proc macros. Additionally, proc macros may stringify their input and expect it survive the
@@ -772,10 +752,10 @@ fn nbsp(&mut self) -> io::Result<()> { self.writer().word(" ") }
     // its hygiene data, most importantly name of the crate it refers to.
     // As a result we print `$crate` as `crate` if it refers to the local crate
     // and as `::other_crate_name` if it refers to some other crate.
-    fn print_dollar_crate(&mut self, ident: ast::Ident) -> io::Result<()> {
+    fn print_dollar_crate(&mut self, ident: ast::Ident) {
         let name = ident.span.ctxt().dollar_crate_name();
         if !ast::Ident::with_empty_ctxt(name).is_path_segment_keyword() {
-            self.writer().word("::")?;
+            self.writer().word("::");
         }
         self.writer().word(name.as_str().to_string())
     }
@@ -800,61 +780,52 @@ fn cur_cmnt(&mut self) -> &mut usize {
 }
 
 impl<'a> State<'a> {
-    pub fn cbox(&mut self, u: usize) -> io::Result<()> {
+    pub fn cbox(&mut self, u: usize) {
         self.boxes.push(pp::Breaks::Consistent);
-        self.s.cbox(u)
+        self.s.cbox(u);
     }
 
-    pub fn word_nbsp<S: Into<Cow<'static, str>>>(&mut self, w: S) -> io::Result<()> {
-        self.s.word(w)?;
+    crate fn word_nbsp<S: Into<Cow<'static, str>>>(&mut self, w: S) {
+        self.s.word(w);
         self.nbsp()
     }
 
-    pub fn head<S: Into<Cow<'static, str>>>(&mut self, w: S) -> io::Result<()> {
+    crate fn head<S: Into<Cow<'static, str>>>(&mut self, w: S) {
         let w = w.into();
         // outer-box is consistent
-        self.cbox(INDENT_UNIT)?;
+        self.cbox(INDENT_UNIT);
         // head-box is inconsistent
-        self.ibox(w.len() + 1)?;
+        self.ibox(w.len() + 1);
         // keyword that starts the head
         if !w.is_empty() {
-            self.word_nbsp(w)?;
+            self.word_nbsp(w);
         }
-        Ok(())
     }
 
-    pub fn bopen(&mut self) -> io::Result<()> {
-        self.s.word("{")?;
-        self.end() // close the head-box
+    crate fn bopen(&mut self) {
+        self.s.word("{");
+        self.end(); // close the head-box
     }
 
-    pub fn bclose_(&mut self, span: syntax_pos::Span,
-                   indented: usize) -> io::Result<()> {
+    crate fn bclose_(&mut self, span: syntax_pos::Span,
+                   indented: usize) {
         self.bclose_maybe_open(span, indented, true)
     }
-    pub fn bclose_maybe_open(&mut self, span: syntax_pos::Span,
-                             indented: usize, close_box: bool) -> io::Result<()> {
-        self.maybe_print_comment(span.hi())?;
-        self.break_offset_if_not_bol(1, -(indented as isize))?;
-        self.s.word("}")?;
+    crate fn bclose_maybe_open(&mut self, span: syntax_pos::Span,
+                             indented: usize, close_box: bool) {
+        self.maybe_print_comment(span.hi());
+        self.break_offset_if_not_bol(1, -(indented as isize));
+        self.s.word("}");
         if close_box {
-            self.end()?; // close the outer-box
+            self.end(); // close the outer-box
         }
-        Ok(())
     }
-    pub fn bclose(&mut self, span: syntax_pos::Span) -> io::Result<()> {
+    crate fn bclose(&mut self, span: syntax_pos::Span) {
         self.bclose_(span, INDENT_UNIT)
     }
 
-    pub fn in_cbox(&self) -> bool {
-        match self.boxes.last() {
-            Some(&last_box) => last_box == pp::Breaks::Consistent,
-            None => false
-        }
-    }
-
-    pub fn break_offset_if_not_bol(&mut self, n: usize,
-                                   off: isize) -> io::Result<()> {
+    crate fn break_offset_if_not_bol(&mut self, n: usize,
+                                   off: isize) {
         if !self.is_bol() {
             self.s.break_offset(n, off)
         } else {
@@ -864,79 +835,75 @@ pub fn break_offset_if_not_bol(&mut self, n: usize,
                 // break into the previous hardbreak.
                 self.s.replace_last_token(pp::Printer::hardbreak_tok_offset(off));
             }
-            Ok(())
         }
     }
 
     // Synthesizes a comment that was not textually present in the original source
     // file.
-    pub fn synth_comment(&mut self, text: String) -> io::Result<()> {
-        self.s.word("/*")?;
-        self.s.space()?;
-        self.s.word(text)?;
-        self.s.space()?;
+    pub fn synth_comment(&mut self, text: String) {
+        self.s.word("/*");
+        self.s.space();
+        self.s.word(text);
+        self.s.space();
         self.s.word("*/")
     }
 
 
 
-    pub fn commasep_cmnt<T, F, G>(&mut self,
+    crate fn commasep_cmnt<T, F, G>(&mut self,
                                   b: Breaks,
                                   elts: &[T],
                                   mut op: F,
-                                  mut get_span: G) -> io::Result<()> where
-        F: FnMut(&mut State<'_>, &T) -> io::Result<()>,
+                                  mut get_span: G) where
+        F: FnMut(&mut State<'_>, &T),
         G: FnMut(&T) -> syntax_pos::Span,
     {
-        self.rbox(0, b)?;
+        self.rbox(0, b);
         let len = elts.len();
         let mut i = 0;
         for elt in elts {
-            self.maybe_print_comment(get_span(elt).hi())?;
-            op(self, elt)?;
+            self.maybe_print_comment(get_span(elt).hi());
+            op(self, elt);
             i += 1;
             if i < len {
-                self.s.word(",")?;
+                self.s.word(",");
                 self.maybe_print_trailing_comment(get_span(elt),
-                                                  Some(get_span(&elts[i]).hi()))?;
-                self.space_if_not_bol()?;
+                                                  Some(get_span(&elts[i]).hi()));
+                self.space_if_not_bol();
             }
         }
-        self.end()
+        self.end();
     }
 
-    pub fn commasep_exprs(&mut self, b: Breaks,
-                          exprs: &[P<ast::Expr>]) -> io::Result<()> {
+    crate fn commasep_exprs(&mut self, b: Breaks,
+                          exprs: &[P<ast::Expr>]) {
         self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span)
     }
 
-    pub fn print_mod(&mut self, _mod: &ast::Mod,
-                     attrs: &[ast::Attribute]) -> io::Result<()> {
-        self.print_inner_attributes(attrs)?;
+    crate fn print_mod(&mut self, _mod: &ast::Mod,
+                     attrs: &[ast::Attribute]) {
+        self.print_inner_attributes(attrs);
         for item in &_mod.items {
-            self.print_item(item)?;
+            self.print_item(item);
         }
-        Ok(())
     }
 
-    pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
-                             attrs: &[ast::Attribute]) -> io::Result<()> {
-        self.print_inner_attributes(attrs)?;
+    crate fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
+                             attrs: &[ast::Attribute]) {
+        self.print_inner_attributes(attrs);
         for item in &nmod.items {
-            self.print_foreign_item(item)?;
+            self.print_foreign_item(item);
         }
-        Ok(())
     }
 
-    pub fn print_opt_lifetime(&mut self, lifetime: &Option<ast::Lifetime>) -> io::Result<()> {
+    crate fn print_opt_lifetime(&mut self, lifetime: &Option<ast::Lifetime>) {
         if let Some(lt) = *lifetime {
-            self.print_lifetime(lt)?;
-            self.nbsp()?;
+            self.print_lifetime(lt);
+            self.nbsp();
         }
-        Ok(())
     }
 
-    pub fn print_generic_arg(&mut self, generic_arg: &GenericArg) -> io::Result<()> {
+    crate fn print_generic_arg(&mut self, generic_arg: &GenericArg) {
         match generic_arg {
             GenericArg::Lifetime(lt) => self.print_lifetime(*lt),
             GenericArg::Type(ty) => self.print_type(ty),
@@ -944,136 +911,136 @@ pub fn print_generic_arg(&mut self, generic_arg: &GenericArg) -> io::Result<()>
         }
     }
 
-    pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> {
-        self.maybe_print_comment(ty.span.lo())?;
-        self.ibox(0)?;
+    crate fn print_type(&mut self, ty: &ast::Ty) {
+        self.maybe_print_comment(ty.span.lo());
+        self.ibox(0);
         match ty.node {
             ast::TyKind::Slice(ref ty) => {
-                self.s.word("[")?;
-                self.print_type(ty)?;
-                self.s.word("]")?;
+                self.s.word("[");
+                self.print_type(ty);
+                self.s.word("]");
             }
             ast::TyKind::Ptr(ref mt) => {
-                self.s.word("*")?;
+                self.s.word("*");
                 match mt.mutbl {
-                    ast::Mutability::Mutable => self.word_nbsp("mut")?,
-                    ast::Mutability::Immutable => self.word_nbsp("const")?,
+                    ast::Mutability::Mutable => self.word_nbsp("mut"),
+                    ast::Mutability::Immutable => self.word_nbsp("const"),
                 }
-                self.print_type(&mt.ty)?;
+                self.print_type(&mt.ty);
             }
             ast::TyKind::Rptr(ref lifetime, ref mt) => {
-                self.s.word("&")?;
-                self.print_opt_lifetime(lifetime)?;
-                self.print_mt(mt)?;
+                self.s.word("&");
+                self.print_opt_lifetime(lifetime);
+                self.print_mt(mt);
             }
             ast::TyKind::Never => {
-                self.s.word("!")?;
+                self.s.word("!");
             },
             ast::TyKind::Tup(ref elts) => {
-                self.popen()?;
+                self.popen();
                 self.commasep(Inconsistent, &elts[..],
-                              |s, ty| s.print_type(ty))?;
+                              |s, ty| s.print_type(ty));
                 if elts.len() == 1 {
-                    self.s.word(",")?;
+                    self.s.word(",");
                 }
-                self.pclose()?;
+                self.pclose();
             }
             ast::TyKind::Paren(ref typ) => {
-                self.popen()?;
-                self.print_type(typ)?;
-                self.pclose()?;
+                self.popen();
+                self.print_type(typ);
+                self.pclose();
             }
             ast::TyKind::BareFn(ref f) => {
                 self.print_ty_fn(f.abi,
                                  f.unsafety,
                                  &f.decl,
                                  None,
-                                 &f.generic_params)?;
+                                 &f.generic_params);
             }
             ast::TyKind::Path(None, ref path) => {
-                self.print_path(path, false, 0)?;
+                self.print_path(path, false, 0);
             }
             ast::TyKind::Path(Some(ref qself), ref path) => {
-                self.print_qpath(path, qself, false)?
+                self.print_qpath(path, qself, false)
             }
             ast::TyKind::TraitObject(ref bounds, syntax) => {
                 let prefix = if syntax == ast::TraitObjectSyntax::Dyn { "dyn" } else { "" };
-                self.print_type_bounds(prefix, &bounds[..])?;
+                self.print_type_bounds(prefix, &bounds[..]);
             }
             ast::TyKind::ImplTrait(_, ref bounds) => {
-                self.print_type_bounds("impl", &bounds[..])?;
+                self.print_type_bounds("impl", &bounds[..]);
             }
             ast::TyKind::Array(ref ty, ref length) => {
-                self.s.word("[")?;
-                self.print_type(ty)?;
-                self.s.word("; ")?;
-                self.print_expr(&length.value)?;
-                self.s.word("]")?;
+                self.s.word("[");
+                self.print_type(ty);
+                self.s.word("; ");
+                self.print_expr(&length.value);
+                self.s.word("]");
             }
             ast::TyKind::Typeof(ref e) => {
-                self.s.word("typeof(")?;
-                self.print_expr(&e.value)?;
-                self.s.word(")")?;
+                self.s.word("typeof(");
+                self.print_expr(&e.value);
+                self.s.word(")");
             }
             ast::TyKind::Infer => {
-                self.s.word("_")?;
+                self.s.word("_");
             }
             ast::TyKind::Err => {
-                self.popen()?;
-                self.s.word("/*ERROR*/")?;
-                self.pclose()?;
+                self.popen();
+                self.s.word("/*ERROR*/");
+                self.pclose();
             }
             ast::TyKind::ImplicitSelf => {
-                self.s.word("Self")?;
+                self.s.word("Self");
             }
             ast::TyKind::Mac(ref m) => {
-                self.print_mac(m)?;
+                self.print_mac(m);
             }
             ast::TyKind::CVarArgs => {
-                self.s.word("...")?;
+                self.s.word("...");
             }
         }
-        self.end()
+        self.end();
     }
 
-    pub fn print_foreign_item(&mut self,
-                              item: &ast::ForeignItem) -> io::Result<()> {
-        self.hardbreak_if_not_bol()?;
-        self.maybe_print_comment(item.span.lo())?;
-        self.print_outer_attributes(&item.attrs)?;
+    crate fn print_foreign_item(&mut self,
+                              item: &ast::ForeignItem) {
+        self.hardbreak_if_not_bol();
+        self.maybe_print_comment(item.span.lo());
+        self.print_outer_attributes(&item.attrs);
         match item.node {
             ast::ForeignItemKind::Fn(ref decl, ref generics) => {
-                self.head("")?;
+                self.head("");
                 self.print_fn(decl, ast::FnHeader::default(),
                               Some(item.ident),
-                              generics, &item.vis)?;
-                self.end()?; // end head-ibox
-                self.s.word(";")?;
-                self.end() // end the outer fn box
+                              generics, &item.vis);
+                self.end(); // end head-ibox
+                self.s.word(";");
+                self.end(); // end the outer fn box
             }
             ast::ForeignItemKind::Static(ref t, m) => {
-                self.head(visibility_qualified(&item.vis, "static"))?;
+                self.head(visibility_qualified(&item.vis, "static"));
                 if m == ast::Mutability::Mutable {
-                    self.word_space("mut")?;
+                    self.word_space("mut");
                 }
-                self.print_ident(item.ident)?;
-                self.word_space(":")?;
-                self.print_type(t)?;
-                self.s.word(";")?;
-                self.end()?; // end the head-ibox
-                self.end() // end the outer cbox
+                self.print_ident(item.ident);
+                self.word_space(":");
+                self.print_type(t);
+                self.s.word(";");
+                self.end(); // end the head-ibox
+                self.end(); // end the outer cbox
             }
             ast::ForeignItemKind::Ty => {
-                self.head(visibility_qualified(&item.vis, "type"))?;
-                self.print_ident(item.ident)?;
-                self.s.word(";")?;
-                self.end()?; // end the head-ibox
-                self.end() // end the outer cbox
+                self.head(visibility_qualified(&item.vis, "type"));
+                self.print_ident(item.ident);
+                self.s.word(";");
+                self.end(); // end the head-ibox
+                self.end(); // end the outer cbox
             }
             ast::ForeignItemKind::Macro(ref m) => {
-                self.print_mac(m)?;
+                self.print_mac(m);
                 match m.node.delim {
-                    MacDelimiter::Brace => Ok(()),
+                    MacDelimiter::Brace => {},
                     _ => self.s.word(";")
                 }
             }
@@ -1085,17 +1052,16 @@ fn print_associated_const(&mut self,
                               ty: &ast::Ty,
                               default: Option<&ast::Expr>,
                               vis: &ast::Visibility)
-                              -> io::Result<()>
     {
-        self.s.word(visibility_qualified(vis, ""))?;
-        self.word_space("const")?;
-        self.print_ident(ident)?;
-        self.word_space(":")?;
-        self.print_type(ty)?;
+        self.s.word(visibility_qualified(vis, ""));
+        self.word_space("const");
+        self.print_ident(ident);
+        self.word_space(":");
+        self.print_type(ty);
         if let Some(expr) = default {
-            self.s.space()?;
-            self.word_space("=")?;
-            self.print_expr(expr)?;
+            self.s.space();
+            self.word_space("=");
+            self.print_expr(expr);
         }
         self.s.word(";")
     }
@@ -1104,140 +1070,140 @@ fn print_associated_type(&mut self,
                              ident: ast::Ident,
                              bounds: Option<&ast::GenericBounds>,
                              ty: Option<&ast::Ty>)
-                             -> io::Result<()> {
-        self.word_space("type")?;
-        self.print_ident(ident)?;
+                             {
+        self.word_space("type");
+        self.print_ident(ident);
         if let Some(bounds) = bounds {
-            self.print_type_bounds(":", bounds)?;
+            self.print_type_bounds(":", bounds);
         }
         if let Some(ty) = ty {
-            self.s.space()?;
-            self.word_space("=")?;
-            self.print_type(ty)?;
+            self.s.space();
+            self.word_space("=");
+            self.print_type(ty);
         }
         self.s.word(";")
     }
 
     /// Pretty-print an item
-    pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
-        self.hardbreak_if_not_bol()?;
-        self.maybe_print_comment(item.span.lo())?;
-        self.print_outer_attributes(&item.attrs)?;
-        self.ann.pre(self, AnnNode::Item(item))?;
+    crate fn print_item(&mut self, item: &ast::Item) {
+        self.hardbreak_if_not_bol();
+        self.maybe_print_comment(item.span.lo());
+        self.print_outer_attributes(&item.attrs);
+        self.ann.pre(self, AnnNode::Item(item));
         match item.node {
             ast::ItemKind::ExternCrate(orig_name) => {
-                self.head(visibility_qualified(&item.vis, "extern crate"))?;
+                self.head(visibility_qualified(&item.vis, "extern crate"));
                 if let Some(orig_name) = orig_name {
-                    self.print_name(orig_name)?;
-                    self.s.space()?;
-                    self.s.word("as")?;
-                    self.s.space()?;
+                    self.print_name(orig_name);
+                    self.s.space();
+                    self.s.word("as");
+                    self.s.space();
                 }
-                self.print_ident(item.ident)?;
-                self.s.word(";")?;
-                self.end()?; // end inner head-block
-                self.end()?; // end outer head-block
+                self.print_ident(item.ident);
+                self.s.word(";");
+                self.end(); // end inner head-block
+                self.end(); // end outer head-block
             }
             ast::ItemKind::Use(ref tree) => {
-                self.head(visibility_qualified(&item.vis, "use"))?;
-                self.print_use_tree(tree)?;
-                self.s.word(";")?;
-                self.end()?; // end inner head-block
-                self.end()?; // end outer head-block
+                self.head(visibility_qualified(&item.vis, "use"));
+                self.print_use_tree(tree);
+                self.s.word(";");
+                self.end(); // end inner head-block
+                self.end(); // end outer head-block
             }
             ast::ItemKind::Static(ref ty, m, ref expr) => {
-                self.head(visibility_qualified(&item.vis, "static"))?;
+                self.head(visibility_qualified(&item.vis, "static"));
                 if m == ast::Mutability::Mutable {
-                    self.word_space("mut")?;
+                    self.word_space("mut");
                 }
-                self.print_ident(item.ident)?;
-                self.word_space(":")?;
-                self.print_type(ty)?;
-                self.s.space()?;
-                self.end()?; // end the head-ibox
+                self.print_ident(item.ident);
+                self.word_space(":");
+                self.print_type(ty);
+                self.s.space();
+                self.end(); // end the head-ibox
 
-                self.word_space("=")?;
-                self.print_expr(expr)?;
-                self.s.word(";")?;
-                self.end()?; // end the outer cbox
+                self.word_space("=");
+                self.print_expr(expr);
+                self.s.word(";");
+                self.end(); // end the outer cbox
             }
             ast::ItemKind::Const(ref ty, ref expr) => {
-                self.head(visibility_qualified(&item.vis, "const"))?;
-                self.print_ident(item.ident)?;
-                self.word_space(":")?;
-                self.print_type(ty)?;
-                self.s.space()?;
-                self.end()?; // end the head-ibox
-
-                self.word_space("=")?;
-                self.print_expr(expr)?;
-                self.s.word(";")?;
-                self.end()?; // end the outer cbox
+                self.head(visibility_qualified(&item.vis, "const"));
+                self.print_ident(item.ident);
+                self.word_space(":");
+                self.print_type(ty);
+                self.s.space();
+                self.end(); // end the head-ibox
+
+                self.word_space("=");
+                self.print_expr(expr);
+                self.s.word(";");
+                self.end(); // end the outer cbox
             }
             ast::ItemKind::Fn(ref decl, header, ref param_names, ref body) => {
-                self.head("")?;
+                self.head("");
                 self.print_fn(
                     decl,
                     header,
                     Some(item.ident),
                     param_names,
                     &item.vis
-                )?;
-                self.s.word(" ")?;
-                self.print_block_with_attrs(body, &item.attrs)?;
+                );
+                self.s.word(" ");
+                self.print_block_with_attrs(body, &item.attrs);
             }
             ast::ItemKind::Mod(ref _mod) => {
-                self.head(visibility_qualified(&item.vis, "mod"))?;
-                self.print_ident(item.ident)?;
+                self.head(visibility_qualified(&item.vis, "mod"));
+                self.print_ident(item.ident);
 
                 if _mod.inline || self.is_expanded {
-                    self.nbsp()?;
-                    self.bopen()?;
-                    self.print_mod(_mod, &item.attrs)?;
-                    self.bclose(item.span)?;
+                    self.nbsp();
+                    self.bopen();
+                    self.print_mod(_mod, &item.attrs);
+                    self.bclose(item.span);
                 } else {
-                    self.s.word(";")?;
-                    self.end()?; // end inner head-block
-                    self.end()?; // end outer head-block
+                    self.s.word(";");
+                    self.end(); // end inner head-block
+                    self.end(); // end outer head-block
                 }
 
             }
             ast::ItemKind::ForeignMod(ref nmod) => {
-                self.head("extern")?;
-                self.word_nbsp(nmod.abi.to_string())?;
-                self.bopen()?;
-                self.print_foreign_mod(nmod, &item.attrs)?;
-                self.bclose(item.span)?;
+                self.head("extern");
+                self.word_nbsp(nmod.abi.to_string());
+                self.bopen();
+                self.print_foreign_mod(nmod, &item.attrs);
+                self.bclose(item.span);
             }
             ast::ItemKind::GlobalAsm(ref ga) => {
-                self.head(visibility_qualified(&item.vis, "global_asm!"))?;
-                self.s.word(ga.asm.as_str().to_string())?;
-                self.end()?;
+                self.head(visibility_qualified(&item.vis, "global_asm!"));
+                self.s.word(ga.asm.as_str().to_string());
+                self.end();
             }
             ast::ItemKind::Ty(ref ty, ref generics) => {
-                self.head(visibility_qualified(&item.vis, "type"))?;
-                self.print_ident(item.ident)?;
-                self.print_generic_params(&generics.params)?;
-                self.end()?; // end the inner ibox
-
-                self.print_where_clause(&generics.where_clause)?;
-                self.s.space()?;
-                self.word_space("=")?;
-                self.print_type(ty)?;
-                self.s.word(";")?;
-                self.end()?; // end the outer ibox
+                self.head(visibility_qualified(&item.vis, "type"));
+                self.print_ident(item.ident);
+                self.print_generic_params(&generics.params);
+                self.end(); // end the inner ibox
+
+                self.print_where_clause(&generics.where_clause);
+                self.s.space();
+                self.word_space("=");
+                self.print_type(ty);
+                self.s.word(";");
+                self.end(); // end the outer ibox
             }
             ast::ItemKind::Existential(ref bounds, ref generics) => {
-                self.head(visibility_qualified(&item.vis, "existential type"))?;
-                self.print_ident(item.ident)?;
-                self.print_generic_params(&generics.params)?;
-                self.end()?; // end the inner ibox
+                self.head(visibility_qualified(&item.vis, "existential type"));
+                self.print_ident(item.ident);
+                self.print_generic_params(&generics.params);
+                self.end(); // end the inner ibox
 
-                self.print_where_clause(&generics.where_clause)?;
-                self.s.space()?;
-                self.print_type_bounds(":", bounds)?;
-                self.s.word(";")?;
-                self.end()?; // end the outer ibox
+                self.print_where_clause(&generics.where_clause);
+                self.s.space();
+                self.print_type_bounds(":", bounds);
+                self.s.word(";");
+                self.end(); // end the outer ibox
             }
             ast::ItemKind::Enum(ref enum_definition, ref params) => {
                 self.print_enum_def(
@@ -1246,15 +1212,15 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
                     item.ident,
                     item.span,
                     &item.vis
-                )?;
+                );
             }
             ast::ItemKind::Struct(ref struct_def, ref generics) => {
-                self.head(visibility_qualified(&item.vis, "struct"))?;
-                self.print_struct(struct_def, generics, item.ident, item.span, true)?;
+                self.head(visibility_qualified(&item.vis, "struct"));
+                self.print_struct(struct_def, generics, item.ident, item.span, true);
             }
             ast::ItemKind::Union(ref struct_def, ref generics) => {
-                self.head(visibility_qualified(&item.vis, "union"))?;
-                self.print_struct(struct_def, generics, item.ident, item.span, true)?;
+                self.head(visibility_qualified(&item.vis, "union"));
+                self.print_struct(struct_def, generics, item.ident, item.span, true);
             }
             ast::ItemKind::Impl(unsafety,
                           polarity,
@@ -1263,171 +1229,170 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
                           ref opt_trait,
                           ref ty,
                           ref impl_items) => {
-                self.head("")?;
-                self.print_visibility(&item.vis)?;
-                self.print_defaultness(defaultness)?;
-                self.print_unsafety(unsafety)?;
-                self.word_nbsp("impl")?;
+                self.head("");
+                self.print_visibility(&item.vis);
+                self.print_defaultness(defaultness);
+                self.print_unsafety(unsafety);
+                self.word_nbsp("impl");
 
                 if !generics.params.is_empty() {
-                    self.print_generic_params(&generics.params)?;
-                    self.s.space()?;
+                    self.print_generic_params(&generics.params);
+                    self.s.space();
                 }
 
                 if polarity == ast::ImplPolarity::Negative {
-                    self.s.word("!")?;
+                    self.s.word("!");
                 }
 
                 if let Some(ref t) = *opt_trait {
-                    self.print_trait_ref(t)?;
-                    self.s.space()?;
-                    self.word_space("for")?;
+                    self.print_trait_ref(t);
+                    self.s.space();
+                    self.word_space("for");
                 }
 
-                self.print_type(ty)?;
-                self.print_where_clause(&generics.where_clause)?;
+                self.print_type(ty);
+                self.print_where_clause(&generics.where_clause);
 
-                self.s.space()?;
-                self.bopen()?;
-                self.print_inner_attributes(&item.attrs)?;
+                self.s.space();
+                self.bopen();
+                self.print_inner_attributes(&item.attrs);
                 for impl_item in impl_items {
-                    self.print_impl_item(impl_item)?;
+                    self.print_impl_item(impl_item);
                 }
-                self.bclose(item.span)?;
+                self.bclose(item.span);
             }
             ast::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref trait_items) => {
-                self.head("")?;
-                self.print_visibility(&item.vis)?;
-                self.print_unsafety(unsafety)?;
-                self.print_is_auto(is_auto)?;
-                self.word_nbsp("trait")?;
-                self.print_ident(item.ident)?;
-                self.print_generic_params(&generics.params)?;
+                self.head("");
+                self.print_visibility(&item.vis);
+                self.print_unsafety(unsafety);
+                self.print_is_auto(is_auto);
+                self.word_nbsp("trait");
+                self.print_ident(item.ident);
+                self.print_generic_params(&generics.params);
                 let mut real_bounds = Vec::with_capacity(bounds.len());
                 for b in bounds.iter() {
                     if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
-                        self.s.space()?;
-                        self.word_space("for ?")?;
-                        self.print_trait_ref(&ptr.trait_ref)?;
+                        self.s.space();
+                        self.word_space("for ?");
+                        self.print_trait_ref(&ptr.trait_ref);
                     } else {
                         real_bounds.push(b.clone());
                     }
                 }
-                self.print_type_bounds(":", &real_bounds[..])?;
-                self.print_where_clause(&generics.where_clause)?;
-                self.s.word(" ")?;
-                self.bopen()?;
+                self.print_type_bounds(":", &real_bounds[..]);
+                self.print_where_clause(&generics.where_clause);
+                self.s.word(" ");
+                self.bopen();
                 for trait_item in trait_items {
-                    self.print_trait_item(trait_item)?;
+                    self.print_trait_item(trait_item);
                 }
-                self.bclose(item.span)?;
+                self.bclose(item.span);
             }
             ast::ItemKind::TraitAlias(ref generics, ref bounds) => {
-                self.head("")?;
-                self.print_visibility(&item.vis)?;
-                self.word_nbsp("trait")?;
-                self.print_ident(item.ident)?;
-                self.print_generic_params(&generics.params)?;
+                self.head("");
+                self.print_visibility(&item.vis);
+                self.word_nbsp("trait");
+                self.print_ident(item.ident);
+                self.print_generic_params(&generics.params);
                 let mut real_bounds = Vec::with_capacity(bounds.len());
                 // FIXME(durka) this seems to be some quite outdated syntax
                 for b in bounds.iter() {
                     if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
-                        self.s.space()?;
-                        self.word_space("for ?")?;
-                        self.print_trait_ref(&ptr.trait_ref)?;
+                        self.s.space();
+                        self.word_space("for ?");
+                        self.print_trait_ref(&ptr.trait_ref);
                     } else {
                         real_bounds.push(b.clone());
                     }
                 }
-                self.nbsp()?;
-                self.print_type_bounds("=", &real_bounds[..])?;
-                self.print_where_clause(&generics.where_clause)?;
-                self.s.word(";")?;
+                self.nbsp();
+                self.print_type_bounds("=", &real_bounds[..]);
+                self.print_where_clause(&generics.where_clause);
+                self.s.word(";");
             }
             ast::ItemKind::Mac(ref mac) => {
                 if item.ident.name == kw::Invalid {
-                    self.print_mac(mac)?;
+                    self.print_mac(mac);
                     match mac.node.delim {
                         MacDelimiter::Brace => {}
-                        _ => self.s.word(";")?,
+                        _ => self.s.word(";"),
                     }
                 } else {
-                    self.print_path(&mac.node.path, false, 0)?;
-                    self.s.word("! ")?;
-                    self.print_ident(item.ident)?;
-                    self.cbox(INDENT_UNIT)?;
-                    self.popen()?;
-                    self.print_tts(mac.node.stream())?;
-                    self.pclose()?;
-                    self.s.word(";")?;
-                    self.end()?;
+                    self.print_path(&mac.node.path, false, 0);
+                    self.s.word("! ");
+                    self.print_ident(item.ident);
+                    self.cbox(INDENT_UNIT);
+                    self.popen();
+                    self.print_tts(mac.node.stream());
+                    self.pclose();
+                    self.s.word(";");
+                    self.end();
                 }
             }
             ast::ItemKind::MacroDef(ref tts) => {
-                self.s.word("macro_rules! ")?;
-                self.print_ident(item.ident)?;
-                self.cbox(INDENT_UNIT)?;
-                self.popen()?;
-                self.print_tts(tts.stream())?;
-                self.pclose()?;
-                self.s.word(";")?;
-                self.end()?;
+                self.s.word("macro_rules! ");
+                self.print_ident(item.ident);
+                self.cbox(INDENT_UNIT);
+                self.popen();
+                self.print_tts(tts.stream());
+                self.pclose();
+                self.s.word(";");
+                self.end();
             }
         }
         self.ann.post(self, AnnNode::Item(item))
     }
 
-    fn print_trait_ref(&mut self, t: &ast::TraitRef) -> io::Result<()> {
+    fn print_trait_ref(&mut self, t: &ast::TraitRef) {
         self.print_path(&t.path, false, 0)
     }
 
     fn print_formal_generic_params(
         &mut self,
         generic_params: &[ast::GenericParam]
-    ) -> io::Result<()> {
+    ) {
         if !generic_params.is_empty() {
-            self.s.word("for")?;
-            self.print_generic_params(generic_params)?;
-            self.nbsp()?;
+            self.s.word("for");
+            self.print_generic_params(generic_params);
+            self.nbsp();
         }
-        Ok(())
     }
 
-    fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> io::Result<()> {
-        self.print_formal_generic_params(&t.bound_generic_params)?;
+    fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) {
+        self.print_formal_generic_params(&t.bound_generic_params);
         self.print_trait_ref(&t.trait_ref)
     }
 
-    pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
+    crate fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
                           generics: &ast::Generics, ident: ast::Ident,
                           span: syntax_pos::Span,
-                          visibility: &ast::Visibility) -> io::Result<()> {
-        self.head(visibility_qualified(visibility, "enum"))?;
-        self.print_ident(ident)?;
-        self.print_generic_params(&generics.params)?;
-        self.print_where_clause(&generics.where_clause)?;
-        self.s.space()?;
+                          visibility: &ast::Visibility) {
+        self.head(visibility_qualified(visibility, "enum"));
+        self.print_ident(ident);
+        self.print_generic_params(&generics.params);
+        self.print_where_clause(&generics.where_clause);
+        self.s.space();
         self.print_variants(&enum_definition.variants, span)
     }
 
-    pub fn print_variants(&mut self,
+    crate fn print_variants(&mut self,
                           variants: &[ast::Variant],
-                          span: syntax_pos::Span) -> io::Result<()> {
-        self.bopen()?;
+                          span: syntax_pos::Span) {
+        self.bopen();
         for v in variants {
-            self.space_if_not_bol()?;
-            self.maybe_print_comment(v.span.lo())?;
-            self.print_outer_attributes(&v.node.attrs)?;
-            self.ibox(INDENT_UNIT)?;
-            self.print_variant(v)?;
-            self.s.word(",")?;
-            self.end()?;
-            self.maybe_print_trailing_comment(v.span, None)?;
+            self.space_if_not_bol();
+            self.maybe_print_comment(v.span.lo());
+            self.print_outer_attributes(&v.node.attrs);
+            self.ibox(INDENT_UNIT);
+            self.print_variant(v);
+            self.s.word(",");
+            self.end();
+            self.maybe_print_trailing_comment(v.span, None);
         }
         self.bclose(span)
     }
 
-    pub fn print_visibility(&mut self, vis: &ast::Visibility) -> io::Result<()> {
+    crate fn print_visibility(&mut self, vis: &ast::Visibility) {
         match vis.node {
             ast::VisibilityKind::Public => self.word_nbsp("pub"),
             ast::VisibilityKind::Crate(sugar) => match sugar {
@@ -1442,62 +1407,61 @@ pub fn print_visibility(&mut self, vis: &ast::Visibility) -> io::Result<()> {
                     self.word_nbsp(format!("pub(in {})", path))
                 }
             }
-            ast::VisibilityKind::Inherited => Ok(())
+            ast::VisibilityKind::Inherited => {}
         }
     }
 
-    pub fn print_defaultness(&mut self, defaultness: ast::Defaultness) -> io::Result<()> {
+    crate fn print_defaultness(&mut self, defaultness: ast::Defaultness) {
         if let ast::Defaultness::Default = defaultness {
-            self.word_nbsp("default")?;
+            self.word_nbsp("default");
         }
-        Ok(())
     }
 
-    pub fn print_struct(&mut self,
+    crate fn print_struct(&mut self,
                         struct_def: &ast::VariantData,
                         generics: &ast::Generics,
                         ident: ast::Ident,
                         span: syntax_pos::Span,
-                        print_finalizer: bool) -> io::Result<()> {
-        self.print_ident(ident)?;
-        self.print_generic_params(&generics.params)?;
+                        print_finalizer: bool) {
+        self.print_ident(ident);
+        self.print_generic_params(&generics.params);
         match struct_def {
             ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
                 if let ast::VariantData::Tuple(..) = struct_def {
-                    self.popen()?;
+                    self.popen();
                     self.commasep(
                         Inconsistent, struct_def.fields(),
                         |s, field| {
-                            s.maybe_print_comment(field.span.lo())?;
-                            s.print_outer_attributes(&field.attrs)?;
-                            s.print_visibility(&field.vis)?;
+                            s.maybe_print_comment(field.span.lo());
+                            s.print_outer_attributes(&field.attrs);
+                            s.print_visibility(&field.vis);
                             s.print_type(&field.ty)
                         }
-                    )?;
-                    self.pclose()?;
+                    );
+                    self.pclose();
                 }
-                self.print_where_clause(&generics.where_clause)?;
+                self.print_where_clause(&generics.where_clause);
                 if print_finalizer {
-                    self.s.word(";")?;
+                    self.s.word(";");
                 }
-                self.end()?;
-                self.end() // close the outer-box
+                self.end();
+                self.end(); // close the outer-box
             }
             ast::VariantData::Struct(..) => {
-                self.print_where_clause(&generics.where_clause)?;
-                self.nbsp()?;
-                self.bopen()?;
-                self.hardbreak_if_not_bol()?;
+                self.print_where_clause(&generics.where_clause);
+                self.nbsp();
+                self.bopen();
+                self.hardbreak_if_not_bol();
 
                 for field in struct_def.fields() {
-                    self.hardbreak_if_not_bol()?;
-                    self.maybe_print_comment(field.span.lo())?;
-                    self.print_outer_attributes(&field.attrs)?;
-                    self.print_visibility(&field.vis)?;
-                    self.print_ident(field.ident.unwrap())?;
-                    self.word_nbsp(":")?;
-                    self.print_type(&field.ty)?;
-                    self.s.word(",")?;
+                    self.hardbreak_if_not_bol();
+                    self.maybe_print_comment(field.span.lo());
+                    self.print_outer_attributes(&field.attrs);
+                    self.print_visibility(&field.vis);
+                    self.print_ident(field.ident.unwrap());
+                    self.word_nbsp(":");
+                    self.print_type(&field.ty);
+                    self.s.word(",");
                 }
 
                 self.bclose(span)
@@ -1505,26 +1469,26 @@ pub fn print_struct(&mut self,
         }
     }
 
-    pub fn print_variant(&mut self, v: &ast::Variant) -> io::Result<()> {
-        self.head("")?;
+    crate fn print_variant(&mut self, v: &ast::Variant) {
+        self.head("");
         let generics = ast::Generics::default();
-        self.print_struct(&v.node.data, &generics, v.node.ident, v.span, false)?;
+        self.print_struct(&v.node.data, &generics, v.node.ident, v.span, false);
         match v.node.disr_expr {
             Some(ref d) => {
-                self.s.space()?;
-                self.word_space("=")?;
+                self.s.space();
+                self.word_space("=");
                 self.print_expr(&d.value)
             }
-            _ => Ok(())
+            _ => {}
         }
     }
 
-    pub fn print_method_sig(&mut self,
+    crate fn print_method_sig(&mut self,
                             ident: ast::Ident,
                             generics: &ast::Generics,
                             m: &ast::MethodSig,
                             vis: &ast::Visibility)
-                            -> io::Result<()> {
+                            {
         self.print_fn(&m.decl,
                       m.header,
                       Some(ident),
@@ -1532,12 +1496,12 @@ pub fn print_method_sig(&mut self,
                       vis)
     }
 
-    pub fn print_trait_item(&mut self, ti: &ast::TraitItem)
-                            -> io::Result<()> {
-        self.ann.pre(self, AnnNode::SubItem(ti.id))?;
-        self.hardbreak_if_not_bol()?;
-        self.maybe_print_comment(ti.span.lo())?;
-        self.print_outer_attributes(&ti.attrs)?;
+    crate fn print_trait_item(&mut self, ti: &ast::TraitItem)
+                            {
+        self.ann.pre(self, AnnNode::SubItem(ti.id));
+        self.hardbreak_if_not_bol();
+        self.maybe_print_comment(ti.span.lo());
+        self.print_outer_attributes(&ti.attrs);
         match ti.node {
             ast::TraitItemKind::Const(ref ty, ref default) => {
                 self.print_associated_const(
@@ -1545,184 +1509,174 @@ pub fn print_trait_item(&mut self, ti: &ast::TraitItem)
                     ty,
                     default.as_ref().map(|expr| &**expr),
                     &source_map::respan(ti.span.shrink_to_lo(), ast::VisibilityKind::Inherited),
-                )?;
+                );
             }
             ast::TraitItemKind::Method(ref sig, ref body) => {
                 if body.is_some() {
-                    self.head("")?;
+                    self.head("");
                 }
                 self.print_method_sig(
                     ti.ident,
                     &ti.generics,
                     sig,
                     &source_map::respan(ti.span.shrink_to_lo(), ast::VisibilityKind::Inherited),
-                )?;
+                );
                 if let Some(ref body) = *body {
-                    self.nbsp()?;
-                    self.print_block_with_attrs(body, &ti.attrs)?;
+                    self.nbsp();
+                    self.print_block_with_attrs(body, &ti.attrs);
                 } else {
-                    self.s.word(";")?;
+                    self.s.word(";");
                 }
             }
             ast::TraitItemKind::Type(ref bounds, ref default) => {
                 self.print_associated_type(ti.ident, Some(bounds),
-                                           default.as_ref().map(|ty| &**ty))?;
+                                           default.as_ref().map(|ty| &**ty));
             }
             ast::TraitItemKind::Macro(ref mac) => {
-                self.print_mac(mac)?;
+                self.print_mac(mac);
                 match mac.node.delim {
                     MacDelimiter::Brace => {}
-                    _ => self.s.word(";")?,
+                    _ => self.s.word(";"),
                 }
             }
         }
         self.ann.post(self, AnnNode::SubItem(ti.id))
     }
 
-    pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> {
-        self.ann.pre(self, AnnNode::SubItem(ii.id))?;
-        self.hardbreak_if_not_bol()?;
-        self.maybe_print_comment(ii.span.lo())?;
-        self.print_outer_attributes(&ii.attrs)?;
-        self.print_defaultness(ii.defaultness)?;
+    crate fn print_impl_item(&mut self, ii: &ast::ImplItem) {
+        self.ann.pre(self, AnnNode::SubItem(ii.id));
+        self.hardbreak_if_not_bol();
+        self.maybe_print_comment(ii.span.lo());
+        self.print_outer_attributes(&ii.attrs);
+        self.print_defaultness(ii.defaultness);
         match ii.node {
             ast::ImplItemKind::Const(ref ty, ref expr) => {
-                self.print_associated_const(ii.ident, ty, Some(expr), &ii.vis)?;
+                self.print_associated_const(ii.ident, ty, Some(expr), &ii.vis);
             }
             ast::ImplItemKind::Method(ref sig, ref body) => {
-                self.head("")?;
-                self.print_method_sig(ii.ident, &ii.generics, sig, &ii.vis)?;
-                self.nbsp()?;
-                self.print_block_with_attrs(body, &ii.attrs)?;
+                self.head("");
+                self.print_method_sig(ii.ident, &ii.generics, sig, &ii.vis);
+                self.nbsp();
+                self.print_block_with_attrs(body, &ii.attrs);
             }
             ast::ImplItemKind::Type(ref ty) => {
-                self.print_associated_type(ii.ident, None, Some(ty))?;
+                self.print_associated_type(ii.ident, None, Some(ty));
             }
             ast::ImplItemKind::Existential(ref bounds) => {
-                self.word_space("existential")?;
-                self.print_associated_type(ii.ident, Some(bounds), None)?;
+                self.word_space("existential");
+                self.print_associated_type(ii.ident, Some(bounds), None);
             }
             ast::ImplItemKind::Macro(ref mac) => {
-                self.print_mac(mac)?;
+                self.print_mac(mac);
                 match mac.node.delim {
                     MacDelimiter::Brace => {}
-                    _ => self.s.word(";")?,
+                    _ => self.s.word(";"),
                 }
             }
         }
         self.ann.post(self, AnnNode::SubItem(ii.id))
     }
 
-    pub fn print_stmt(&mut self, st: &ast::Stmt) -> io::Result<()> {
-        self.maybe_print_comment(st.span.lo())?;
+    crate fn print_stmt(&mut self, st: &ast::Stmt) {
+        self.maybe_print_comment(st.span.lo());
         match st.node {
             ast::StmtKind::Local(ref loc) => {
-                self.print_outer_attributes(&loc.attrs)?;
-                self.space_if_not_bol()?;
-                self.ibox(INDENT_UNIT)?;
-                self.word_nbsp("let")?;
-
-                self.ibox(INDENT_UNIT)?;
-                self.print_local_decl(loc)?;
-                self.end()?;
+                self.print_outer_attributes(&loc.attrs);
+                self.space_if_not_bol();
+                self.ibox(INDENT_UNIT);
+                self.word_nbsp("let");
+
+                self.ibox(INDENT_UNIT);
+                self.print_local_decl(loc);
+                self.end();
                 if let Some(ref init) = loc.init {
-                    self.nbsp()?;
-                    self.word_space("=")?;
-                    self.print_expr(init)?;
+                    self.nbsp();
+                    self.word_space("=");
+                    self.print_expr(init);
                 }
-                self.s.word(";")?;
-                self.end()?;
+                self.s.word(";");
+                self.end();
             }
-            ast::StmtKind::Item(ref item) => self.print_item(item)?,
+            ast::StmtKind::Item(ref item) => self.print_item(item),
             ast::StmtKind::Expr(ref expr) => {
-                self.space_if_not_bol()?;
-                self.print_expr_outer_attr_style(expr, false)?;
+                self.space_if_not_bol();
+                self.print_expr_outer_attr_style(expr, false);
                 if parse::classify::expr_requires_semi_to_be_stmt(expr) {
-                    self.s.word(";")?;
+                    self.s.word(";");
                 }
             }
             ast::StmtKind::Semi(ref expr) => {
-                self.space_if_not_bol()?;
-                self.print_expr_outer_attr_style(expr, false)?;
-                self.s.word(";")?;
+                self.space_if_not_bol();
+                self.print_expr_outer_attr_style(expr, false);
+                self.s.word(";");
             }
             ast::StmtKind::Mac(ref mac) => {
                 let (ref mac, style, ref attrs) = **mac;
-                self.space_if_not_bol()?;
-                self.print_outer_attributes(attrs)?;
-                self.print_mac(mac)?;
+                self.space_if_not_bol();
+                self.print_outer_attributes(attrs);
+                self.print_mac(mac);
                 if style == ast::MacStmtStyle::Semicolon {
-                    self.s.word(";")?;
+                    self.s.word(";");
                 }
             }
         }
         self.maybe_print_trailing_comment(st.span, None)
     }
 
-    pub fn print_block(&mut self, blk: &ast::Block) -> io::Result<()> {
+    crate fn print_block(&mut self, blk: &ast::Block) {
         self.print_block_with_attrs(blk, &[])
     }
 
-    pub fn print_block_unclosed(&mut self, blk: &ast::Block) -> io::Result<()> {
-        self.print_block_unclosed_indent(blk, INDENT_UNIT)
-    }
-
-    pub fn print_block_unclosed_with_attrs(&mut self, blk: &ast::Block,
-                                            attrs: &[ast::Attribute])
-                                           -> io::Result<()> {
-        self.print_block_maybe_unclosed(blk, INDENT_UNIT, attrs, false)
-    }
-
-    pub fn print_block_unclosed_indent(&mut self, blk: &ast::Block,
-                                       indented: usize) -> io::Result<()> {
+    crate fn print_block_unclosed_indent(&mut self, blk: &ast::Block,
+                                       indented: usize) {
         self.print_block_maybe_unclosed(blk, indented, &[], false)
     }
 
-    pub fn print_block_with_attrs(&mut self,
+    crate fn print_block_with_attrs(&mut self,
                                   blk: &ast::Block,
-                                  attrs: &[ast::Attribute]) -> io::Result<()> {
+                                  attrs: &[ast::Attribute]) {
         self.print_block_maybe_unclosed(blk, INDENT_UNIT, attrs, true)
     }
 
-    pub fn print_block_maybe_unclosed(&mut self,
+    crate fn print_block_maybe_unclosed(&mut self,
                                       blk: &ast::Block,
                                       indented: usize,
                                       attrs: &[ast::Attribute],
-                                      close_box: bool) -> io::Result<()> {
+                                      close_box: bool) {
         match blk.rules {
-            BlockCheckMode::Unsafe(..) => self.word_space("unsafe")?,
+            BlockCheckMode::Unsafe(..) => self.word_space("unsafe"),
             BlockCheckMode::Default => ()
         }
-        self.maybe_print_comment(blk.span.lo())?;
-        self.ann.pre(self, AnnNode::Block(blk))?;
-        self.bopen()?;
+        self.maybe_print_comment(blk.span.lo());
+        self.ann.pre(self, AnnNode::Block(blk));
+        self.bopen();
 
-        self.print_inner_attributes(attrs)?;
+        self.print_inner_attributes(attrs);
 
         for (i, st) in blk.stmts.iter().enumerate() {
             match st.node {
                 ast::StmtKind::Expr(ref expr) if i == blk.stmts.len() - 1 => {
-                    self.maybe_print_comment(st.span.lo())?;
-                    self.space_if_not_bol()?;
-                    self.print_expr_outer_attr_style(expr, false)?;
-                    self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi()))?;
+                    self.maybe_print_comment(st.span.lo());
+                    self.space_if_not_bol();
+                    self.print_expr_outer_attr_style(expr, false);
+                    self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi()));
                 }
-                _ => self.print_stmt(st)?,
+                _ => self.print_stmt(st),
             }
         }
 
-        self.bclose_maybe_open(blk.span, indented, close_box)?;
+        self.bclose_maybe_open(blk.span, indented, close_box);
         self.ann.post(self, AnnNode::Block(blk))
     }
 
     /// Print a `let pats = scrutinee` expression.
-    pub fn print_let(&mut self, pats: &[P<ast::Pat>], scrutinee: &ast::Expr) -> io::Result<()> {
-        self.s.word("let ")?;
+    crate fn print_let(&mut self, pats: &[P<ast::Pat>], scrutinee: &ast::Expr) {
+        self.s.word("let ");
 
-        self.print_pats(pats)?;
-        self.s.space()?;
+        self.print_pats(pats);
+        self.s.space();
 
-        self.word_space("=")?;
+        self.word_space("=");
         self.print_expr_cond_paren(
             scrutinee,
             Self::cond_needs_par(scrutinee)
@@ -1730,25 +1684,25 @@ pub fn print_let(&mut self, pats: &[P<ast::Pat>], scrutinee: &ast::Expr) -> io::
         )
     }
 
-    fn print_else(&mut self, els: Option<&ast::Expr>) -> io::Result<()> {
+    fn print_else(&mut self, els: Option<&ast::Expr>) {
         match els {
             Some(_else) => {
                 match _else.node {
                     // Another `else if` block.
                     ast::ExprKind::If(ref i, ref then, ref e) => {
-                        self.cbox(INDENT_UNIT - 1)?;
-                        self.ibox(0)?;
-                        self.s.word(" else if ")?;
-                        self.print_expr_as_cond(i)?;
-                        self.s.space()?;
-                        self.print_block(then)?;
+                        self.cbox(INDENT_UNIT - 1);
+                        self.ibox(0);
+                        self.s.word(" else if ");
+                        self.print_expr_as_cond(i);
+                        self.s.space();
+                        self.print_block(then);
                         self.print_else(e.as_ref().map(|e| &**e))
                     }
                     // Final `else` block.
                     ast::ExprKind::Block(ref b, _) => {
-                        self.cbox(INDENT_UNIT - 1)?;
-                        self.ibox(0)?;
-                        self.s.word(" else ")?;
+                        self.cbox(INDENT_UNIT - 1);
+                        self.ibox(0);
+                        self.s.word(" else ");
                         self.print_block(b)
                     }
                     // Constraints would be great here!
@@ -1757,33 +1711,33 @@ fn print_else(&mut self, els: Option<&ast::Expr>) -> io::Result<()> {
                     }
                 }
             }
-            _ => Ok(())
+            _ => {}
         }
     }
 
-    pub fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block,
-                    elseopt: Option<&ast::Expr>) -> io::Result<()> {
-        self.head("if")?;
+    crate fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block,
+                    elseopt: Option<&ast::Expr>) {
+        self.head("if");
 
-        self.print_expr_as_cond(test)?;
-        self.s.space()?;
+        self.print_expr_as_cond(test);
+        self.s.space();
 
-        self.print_block(blk)?;
+        self.print_block(blk);
         self.print_else(elseopt)
     }
 
-    pub fn print_mac(&mut self, m: &ast::Mac) -> io::Result<()> {
-        self.print_path(&m.node.path, false, 0)?;
-        self.s.word("!")?;
+    crate fn print_mac(&mut self, m: &ast::Mac) {
+        self.print_path(&m.node.path, false, 0);
+        self.s.word("!");
         match m.node.delim {
-            MacDelimiter::Parenthesis => self.popen()?,
-            MacDelimiter::Bracket => self.s.word("[")?,
+            MacDelimiter::Parenthesis => self.popen(),
+            MacDelimiter::Bracket => self.s.word("["),
             MacDelimiter::Brace => {
-                self.head("")?;
-                self.bopen()?;
+                self.head("");
+                self.bopen();
             }
         }
-        self.print_tts(m.node.stream())?;
+        self.print_tts(m.node.stream());
         match m.node.delim {
             MacDelimiter::Parenthesis => self.pclose(),
             MacDelimiter::Bracket => self.s.word("]"),
@@ -1792,19 +1746,19 @@ pub fn print_mac(&mut self, m: &ast::Mac) -> io::Result<()> {
     }
 
 
-    fn print_call_post(&mut self, args: &[P<ast::Expr>]) -> io::Result<()> {
-        self.popen()?;
-        self.commasep_exprs(Inconsistent, args)?;
+    fn print_call_post(&mut self, args: &[P<ast::Expr>]) {
+        self.popen();
+        self.commasep_exprs(Inconsistent, args);
         self.pclose()
     }
 
-    pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr, prec: i8) -> io::Result<()> {
+    crate fn print_expr_maybe_paren(&mut self, expr: &ast::Expr, prec: i8) {
         self.print_expr_cond_paren(expr, expr.precedence().order() < prec)
     }
 
     /// Print an expr using syntax that's acceptable in a condition position, such as the `cond` in
     /// `if cond { ... }`.
-    pub fn print_expr_as_cond(&mut self, expr: &ast::Expr) -> io::Result<()> {
+    crate fn print_expr_as_cond(&mut self, expr: &ast::Expr) {
         self.print_expr_cond_paren(expr, Self::cond_needs_par(expr))
     }
 
@@ -1822,114 +1776,112 @@ fn cond_needs_par(expr: &ast::Expr) -> bool {
     }
 
     /// Print `expr` or `(expr)` when `needs_par` holds.
-    fn print_expr_cond_paren(&mut self, expr: &ast::Expr, needs_par: bool) -> io::Result<()> {
+    fn print_expr_cond_paren(&mut self, expr: &ast::Expr, needs_par: bool) {
         if needs_par {
-            self.popen()?;
+            self.popen();
         }
-        self.print_expr(expr)?;
+        self.print_expr(expr);
         if needs_par {
-            self.pclose()?;
+            self.pclose();
         }
-        Ok(())
     }
 
     fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>],
-                      attrs: &[Attribute]) -> io::Result<()> {
-        self.ibox(INDENT_UNIT)?;
-        self.s.word("[")?;
-        self.print_inner_attributes_inline(attrs)?;
-        self.commasep_exprs(Inconsistent, &exprs[..])?;
-        self.s.word("]")?;
-        self.end()
+                      attrs: &[Attribute]) {
+        self.ibox(INDENT_UNIT);
+        self.s.word("[");
+        self.print_inner_attributes_inline(attrs);
+        self.commasep_exprs(Inconsistent, &exprs[..]);
+        self.s.word("]");
+        self.end();
     }
 
     fn print_expr_repeat(&mut self,
                          element: &ast::Expr,
                          count: &ast::AnonConst,
-                         attrs: &[Attribute]) -> io::Result<()> {
-        self.ibox(INDENT_UNIT)?;
-        self.s.word("[")?;
-        self.print_inner_attributes_inline(attrs)?;
-        self.print_expr(element)?;
-        self.word_space(";")?;
-        self.print_expr(&count.value)?;
-        self.s.word("]")?;
-        self.end()
+                         attrs: &[Attribute]) {
+        self.ibox(INDENT_UNIT);
+        self.s.word("[");
+        self.print_inner_attributes_inline(attrs);
+        self.print_expr(element);
+        self.word_space(";");
+        self.print_expr(&count.value);
+        self.s.word("]");
+        self.end();
     }
 
     fn print_expr_struct(&mut self,
                          path: &ast::Path,
                          fields: &[ast::Field],
                          wth: &Option<P<ast::Expr>>,
-                         attrs: &[Attribute]) -> io::Result<()> {
-        self.print_path(path, true, 0)?;
-        self.s.word("{")?;
-        self.print_inner_attributes_inline(attrs)?;
+                         attrs: &[Attribute]) {
+        self.print_path(path, true, 0);
+        self.s.word("{");
+        self.print_inner_attributes_inline(attrs);
         self.commasep_cmnt(
             Consistent,
             &fields[..],
             |s, field| {
-                s.ibox(INDENT_UNIT)?;
+                s.ibox(INDENT_UNIT);
                 if !field.is_shorthand {
-                    s.print_ident(field.ident)?;
-                    s.word_space(":")?;
+                    s.print_ident(field.ident);
+                    s.word_space(":");
                 }
-                s.print_expr(&field.expr)?;
-                s.end()
+                s.print_expr(&field.expr);
+                s.end();
             },
-            |f| f.span)?;
+            |f| f.span);
         match *wth {
             Some(ref expr) => {
-                self.ibox(INDENT_UNIT)?;
+                self.ibox(INDENT_UNIT);
                 if !fields.is_empty() {
-                    self.s.word(",")?;
-                    self.s.space()?;
+                    self.s.word(",");
+                    self.s.space();
                 }
-                self.s.word("..")?;
-                self.print_expr(expr)?;
-                self.end()?;
+                self.s.word("..");
+                self.print_expr(expr);
+                self.end();
             }
             _ => if !fields.is_empty() {
-                self.s.word(",")?
+                self.s.word(",")
             }
         }
-        self.s.word("}")?;
-        Ok(())
+        self.s.word("}");
     }
 
     fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>],
-                      attrs: &[Attribute]) -> io::Result<()> {
-        self.popen()?;
-        self.print_inner_attributes_inline(attrs)?;
-        self.commasep_exprs(Inconsistent, &exprs[..])?;
+                      attrs: &[Attribute]) {
+        self.popen();
+        self.print_inner_attributes_inline(attrs);
+        self.commasep_exprs(Inconsistent, &exprs[..]);
         if exprs.len() == 1 {
-            self.s.word(",")?;
+            self.s.word(",");
         }
         self.pclose()
     }
 
     fn print_expr_call(&mut self,
                        func: &ast::Expr,
-                       args: &[P<ast::Expr>]) -> io::Result<()> {
+                       args: &[P<ast::Expr>]) {
         let prec =
             match func.node {
                 ast::ExprKind::Field(..) => parser::PREC_FORCE_PAREN,
                 _ => parser::PREC_POSTFIX,
             };
 
-        self.print_expr_maybe_paren(func, prec)?;
+        self.print_expr_maybe_paren(func, prec);
         self.print_call_post(args)
     }
 
     fn print_expr_method_call(&mut self,
                               segment: &ast::PathSegment,
-                              args: &[P<ast::Expr>]) -> io::Result<()> {
+                              args: &[P<ast::Expr>]) {
         let base_args = &args[1..];
-        self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX)?;
-        self.s.word(".")?;
-        self.print_ident(segment.ident)?;
+        self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX);
+        self.s.word(".");
+        self.print_ident(segment.ident);
         if let Some(ref args) = segment.args {
-            self.print_generic_args(args, true)?;
+            self.print_generic_args(args, true);
         }
         self.print_call_post(base_args)
     }
@@ -1937,7 +1889,7 @@ fn print_expr_method_call(&mut self,
     fn print_expr_binary(&mut self,
                          op: ast::BinOp,
                          lhs: &ast::Expr,
-                         rhs: &ast::Expr) -> io::Result<()> {
+                         rhs: &ast::Expr) {
         let assoc_op = AssocOp::from_ast_binop(op.node);
         let prec = assoc_op.precedence() as i8;
         let fixity = assoc_op.fixity();
@@ -1968,217 +1920,217 @@ fn print_expr_binary(&mut self,
             _ => left_prec,
         };
 
-        self.print_expr_maybe_paren(lhs, left_prec)?;
-        self.s.space()?;
-        self.word_space(op.node.to_string())?;
+        self.print_expr_maybe_paren(lhs, left_prec);
+        self.s.space();
+        self.word_space(op.node.to_string());
         self.print_expr_maybe_paren(rhs, right_prec)
     }
 
     fn print_expr_unary(&mut self,
                         op: ast::UnOp,
-                        expr: &ast::Expr) -> io::Result<()> {
-        self.s.word(ast::UnOp::to_string(op))?;
+                        expr: &ast::Expr) {
+        self.s.word(ast::UnOp::to_string(op));
         self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
     }
 
     fn print_expr_addr_of(&mut self,
                           mutability: ast::Mutability,
-                          expr: &ast::Expr) -> io::Result<()> {
-        self.s.word("&")?;
-        self.print_mutability(mutability)?;
+                          expr: &ast::Expr) {
+        self.s.word("&");
+        self.print_mutability(mutability);
         self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
     }
 
-    pub fn print_expr(&mut self, expr: &ast::Expr) -> io::Result<()> {
+    crate fn print_expr(&mut self, expr: &ast::Expr) {
         self.print_expr_outer_attr_style(expr, true)
     }
 
     fn print_expr_outer_attr_style(&mut self,
                                   expr: &ast::Expr,
-                                  is_inline: bool) -> io::Result<()> {
-        self.maybe_print_comment(expr.span.lo())?;
+                                  is_inline: bool) {
+        self.maybe_print_comment(expr.span.lo());
 
         let attrs = &expr.attrs;
         if is_inline {
-            self.print_outer_attributes_inline(attrs)?;
+            self.print_outer_attributes_inline(attrs);
         } else {
-            self.print_outer_attributes(attrs)?;
+            self.print_outer_attributes(attrs);
         }
 
-        self.ibox(INDENT_UNIT)?;
-        self.ann.pre(self, AnnNode::Expr(expr))?;
+        self.ibox(INDENT_UNIT);
+        self.ann.pre(self, AnnNode::Expr(expr));
         match expr.node {
             ast::ExprKind::Box(ref expr) => {
-                self.word_space("box")?;
-                self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)?;
+                self.word_space("box");
+                self.print_expr_maybe_paren(expr, parser::PREC_PREFIX);
             }
             ast::ExprKind::Array(ref exprs) => {
-                self.print_expr_vec(&exprs[..], attrs)?;
+                self.print_expr_vec(&exprs[..], attrs);
             }
             ast::ExprKind::Repeat(ref element, ref count) => {
-                self.print_expr_repeat(element, count, attrs)?;
+                self.print_expr_repeat(element, count, attrs);
             }
             ast::ExprKind::Struct(ref path, ref fields, ref wth) => {
-                self.print_expr_struct(path, &fields[..], wth, attrs)?;
+                self.print_expr_struct(path, &fields[..], wth, attrs);
             }
             ast::ExprKind::Tup(ref exprs) => {
-                self.print_expr_tup(&exprs[..], attrs)?;
+                self.print_expr_tup(&exprs[..], attrs);
             }
             ast::ExprKind::Call(ref func, ref args) => {
-                self.print_expr_call(func, &args[..])?;
+                self.print_expr_call(func, &args[..]);
             }
             ast::ExprKind::MethodCall(ref segment, ref args) => {
-                self.print_expr_method_call(segment, &args[..])?;
+                self.print_expr_method_call(segment, &args[..]);
             }
             ast::ExprKind::Binary(op, ref lhs, ref rhs) => {
-                self.print_expr_binary(op, lhs, rhs)?;
+                self.print_expr_binary(op, lhs, rhs);
             }
             ast::ExprKind::Unary(op, ref expr) => {
-                self.print_expr_unary(op, expr)?;
+                self.print_expr_unary(op, expr);
             }
             ast::ExprKind::AddrOf(m, ref expr) => {
-                self.print_expr_addr_of(m, expr)?;
+                self.print_expr_addr_of(m, expr);
             }
             ast::ExprKind::Lit(ref lit) => {
-                self.print_literal(lit)?;
+                self.print_literal(lit);
             }
             ast::ExprKind::Cast(ref expr, ref ty) => {
                 let prec = AssocOp::As.precedence() as i8;
-                self.print_expr_maybe_paren(expr, prec)?;
-                self.s.space()?;
-                self.word_space("as")?;
-                self.print_type(ty)?;
+                self.print_expr_maybe_paren(expr, prec);
+                self.s.space();
+                self.word_space("as");
+                self.print_type(ty);
             }
             ast::ExprKind::Type(ref expr, ref ty) => {
                 let prec = AssocOp::Colon.precedence() as i8;
-                self.print_expr_maybe_paren(expr, prec)?;
-                self.word_space(":")?;
-                self.print_type(ty)?;
+                self.print_expr_maybe_paren(expr, prec);
+                self.word_space(":");
+                self.print_type(ty);
             }
             ast::ExprKind::Let(ref pats, ref scrutinee) => {
-                self.print_let(pats, scrutinee)?;
+                self.print_let(pats, scrutinee);
             }
             ast::ExprKind::If(ref test, ref blk, ref elseopt) => {
-                self.print_if(test, blk, elseopt.as_ref().map(|e| &**e))?;
+                self.print_if(test, blk, elseopt.as_ref().map(|e| &**e));
             }
             ast::ExprKind::While(ref test, ref blk, opt_label) => {
                 if let Some(label) = opt_label {
-                    self.print_ident(label.ident)?;
-                    self.word_space(":")?;
+                    self.print_ident(label.ident);
+                    self.word_space(":");
                 }
-                self.head("while")?;
-                self.print_expr_as_cond(test)?;
-                self.s.space()?;
-                self.print_block_with_attrs(blk, attrs)?;
+                self.head("while");
+                self.print_expr_as_cond(test);
+                self.s.space();
+                self.print_block_with_attrs(blk, attrs);
             }
             ast::ExprKind::ForLoop(ref pat, ref iter, ref blk, opt_label) => {
                 if let Some(label) = opt_label {
-                    self.print_ident(label.ident)?;
-                    self.word_space(":")?;
+                    self.print_ident(label.ident);
+                    self.word_space(":");
                 }
-                self.head("for")?;
-                self.print_pat(pat)?;
-                self.s.space()?;
-                self.word_space("in")?;
-                self.print_expr_as_cond(iter)?;
-                self.s.space()?;
-                self.print_block_with_attrs(blk, attrs)?;
+                self.head("for");
+                self.print_pat(pat);
+                self.s.space();
+                self.word_space("in");
+                self.print_expr_as_cond(iter);
+                self.s.space();
+                self.print_block_with_attrs(blk, attrs);
             }
             ast::ExprKind::Loop(ref blk, opt_label) => {
                 if let Some(label) = opt_label {
-                    self.print_ident(label.ident)?;
-                    self.word_space(":")?;
+                    self.print_ident(label.ident);
+                    self.word_space(":");
                 }
-                self.head("loop")?;
-                self.s.space()?;
-                self.print_block_with_attrs(blk, attrs)?;
+                self.head("loop");
+                self.s.space();
+                self.print_block_with_attrs(blk, attrs);
             }
             ast::ExprKind::Match(ref expr, ref arms) => {
-                self.cbox(INDENT_UNIT)?;
-                self.ibox(4)?;
-                self.word_nbsp("match")?;
-                self.print_expr_as_cond(expr)?;
-                self.s.space()?;
-                self.bopen()?;
-                self.print_inner_attributes_no_trailing_hardbreak(attrs)?;
+                self.cbox(INDENT_UNIT);
+                self.ibox(4);
+                self.word_nbsp("match");
+                self.print_expr_as_cond(expr);
+                self.s.space();
+                self.bopen();
+                self.print_inner_attributes_no_trailing_hardbreak(attrs);
                 for arm in arms {
-                    self.print_arm(arm)?;
+                    self.print_arm(arm);
                 }
-                self.bclose_(expr.span, INDENT_UNIT)?;
+                self.bclose_(expr.span, INDENT_UNIT);
             }
             ast::ExprKind::Closure(
                 capture_clause, asyncness, movability, ref decl, ref body, _) => {
-                self.print_movability(movability)?;
-                self.print_asyncness(asyncness)?;
-                self.print_capture_clause(capture_clause)?;
+                self.print_movability(movability);
+                self.print_asyncness(asyncness);
+                self.print_capture_clause(capture_clause);
 
-                self.print_fn_block_args(decl)?;
-                self.s.space()?;
-                self.print_expr(body)?;
-                self.end()?; // need to close a box
+                self.print_fn_block_args(decl);
+                self.s.space();
+                self.print_expr(body);
+                self.end(); // need to close a box
 
                 // a box will be closed by print_expr, but we didn't want an overall
                 // wrapper so we closed the corresponding opening. so create an
                 // empty box to satisfy the close.
-                self.ibox(0)?;
+                self.ibox(0);
             }
             ast::ExprKind::Block(ref blk, opt_label) => {
                 if let Some(label) = opt_label {
-                    self.print_ident(label.ident)?;
-                    self.word_space(":")?;
+                    self.print_ident(label.ident);
+                    self.word_space(":");
                 }
                 // containing cbox, will be closed by print-block at }
-                self.cbox(INDENT_UNIT)?;
+                self.cbox(INDENT_UNIT);
                 // head-box, will be closed by print-block after {
-                self.ibox(0)?;
-                self.print_block_with_attrs(blk, attrs)?;
+                self.ibox(0);
+                self.print_block_with_attrs(blk, attrs);
             }
             ast::ExprKind::Async(capture_clause, _, ref blk) => {
-                self.word_nbsp("async")?;
-                self.print_capture_clause(capture_clause)?;
-                self.s.space()?;
+                self.word_nbsp("async");
+                self.print_capture_clause(capture_clause);
+                self.s.space();
                 // cbox/ibox in analogy to the `ExprKind::Block` arm above
-                self.cbox(INDENT_UNIT)?;
-                self.ibox(0)?;
-                self.print_block_with_attrs(blk, attrs)?;
+                self.cbox(INDENT_UNIT);
+                self.ibox(0);
+                self.print_block_with_attrs(blk, attrs);
             }
             ast::ExprKind::Await(origin, ref expr) => {
                 match origin {
                     ast::AwaitOrigin::MacroLike => {
-                        self.s.word("await!")?;
-                        self.print_expr_maybe_paren(expr, parser::PREC_FORCE_PAREN)?;
+                        self.s.word("await!");
+                        self.print_expr_maybe_paren(expr, parser::PREC_FORCE_PAREN);
                     }
                     ast::AwaitOrigin::FieldLike => {
-                        self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX)?;
-                        self.s.word(".await")?;
+                        self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
+                        self.s.word(".await");
                     }
                 }
             }
             ast::ExprKind::Assign(ref lhs, ref rhs) => {
                 let prec = AssocOp::Assign.precedence() as i8;
-                self.print_expr_maybe_paren(lhs, prec + 1)?;
-                self.s.space()?;
-                self.word_space("=")?;
-                self.print_expr_maybe_paren(rhs, prec)?;
+                self.print_expr_maybe_paren(lhs, prec + 1);
+                self.s.space();
+                self.word_space("=");
+                self.print_expr_maybe_paren(rhs, prec);
             }
             ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => {
                 let prec = AssocOp::Assign.precedence() as i8;
-                self.print_expr_maybe_paren(lhs, prec + 1)?;
-                self.s.space()?;
-                self.s.word(op.node.to_string())?;
-                self.word_space("=")?;
-                self.print_expr_maybe_paren(rhs, prec)?;
+                self.print_expr_maybe_paren(lhs, prec + 1);
+                self.s.space();
+                self.s.word(op.node.to_string());
+                self.word_space("=");
+                self.print_expr_maybe_paren(rhs, prec);
             }
             ast::ExprKind::Field(ref expr, ident) => {
-                self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX)?;
-                self.s.word(".")?;
-                self.print_ident(ident)?;
+                self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
+                self.s.word(".");
+                self.print_ident(ident);
             }
             ast::ExprKind::Index(ref expr, ref index) => {
-                self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX)?;
-                self.s.word("[")?;
-                self.print_expr(index)?;
-                self.s.word("]")?;
+                self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
+                self.s.word("[");
+                self.print_expr(index);
+                self.s.word("]");
             }
             ast::ExprKind::Range(ref start, ref end, limits) => {
                 // Special case for `Range`.  `AssocOp` claims that `Range` has higher precedence
@@ -2187,55 +2139,55 @@ fn print_expr_outer_attr_style(&mut self,
                 // a "normal" binop gets parenthesized.  (`LOr` is the lowest-precedence binop.)
                 let fake_prec = AssocOp::LOr.precedence() as i8;
                 if let Some(ref e) = *start {
-                    self.print_expr_maybe_paren(e, fake_prec)?;
+                    self.print_expr_maybe_paren(e, fake_prec);
                 }
                 if limits == ast::RangeLimits::HalfOpen {
-                    self.s.word("..")?;
+                    self.s.word("..");
                 } else {
-                    self.s.word("..=")?;
+                    self.s.word("..=");
                 }
                 if let Some(ref e) = *end {
-                    self.print_expr_maybe_paren(e, fake_prec)?;
+                    self.print_expr_maybe_paren(e, fake_prec);
                 }
             }
             ast::ExprKind::Path(None, ref path) => {
-                self.print_path(path, true, 0)?
+                self.print_path(path, true, 0)
             }
             ast::ExprKind::Path(Some(ref qself), ref path) => {
-                self.print_qpath(path, qself, true)?
+                self.print_qpath(path, qself, true)
             }
             ast::ExprKind::Break(opt_label, ref opt_expr) => {
-                self.s.word("break")?;
-                self.s.space()?;
+                self.s.word("break");
+                self.s.space();
                 if let Some(label) = opt_label {
-                    self.print_ident(label.ident)?;
-                    self.s.space()?;
+                    self.print_ident(label.ident);
+                    self.s.space();
                 }
                 if let Some(ref expr) = *opt_expr {
-                    self.print_expr_maybe_paren(expr, parser::PREC_JUMP)?;
-                    self.s.space()?;
+                    self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
+                    self.s.space();
                 }
             }
             ast::ExprKind::Continue(opt_label) => {
-                self.s.word("continue")?;
-                self.s.space()?;
+                self.s.word("continue");
+                self.s.space();
                 if let Some(label) = opt_label {
-                    self.print_ident(label.ident)?;
-                    self.s.space()?
+                    self.print_ident(label.ident);
+                    self.s.space()
                 }
             }
             ast::ExprKind::Ret(ref result) => {
-                self.s.word("return")?;
+                self.s.word("return");
                 if let Some(ref expr) = *result {
-                    self.s.word(" ")?;
-                    self.print_expr_maybe_paren(expr, parser::PREC_JUMP)?;
+                    self.s.word(" ");
+                    self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
                 }
             }
             ast::ExprKind::InlineAsm(ref a) => {
-                self.s.word("asm!")?;
-                self.popen()?;
-                self.print_string(&a.asm.as_str(), a.asm_str_style)?;
-                self.word_space(":")?;
+                self.s.word("asm!");
+                self.popen();
+                self.print_string(&a.asm.as_str(), a.asm_str_style);
+                self.word_space(":");
 
                 self.commasep(Inconsistent, &a.outputs, |s, out| {
                     let constraint = out.constraint.as_str();
@@ -2243,33 +2195,30 @@ fn print_expr_outer_attr_style(&mut self,
                     match ch.next() {
                         Some('=') if out.is_rw => {
                             s.print_string(&format!("+{}", ch.as_str()),
-                                           ast::StrStyle::Cooked)?
+                                           ast::StrStyle::Cooked)
                         }
-                        _ => s.print_string(&constraint, ast::StrStyle::Cooked)?
+                        _ => s.print_string(&constraint, ast::StrStyle::Cooked)
                     }
-                    s.popen()?;
-                    s.print_expr(&out.expr)?;
-                    s.pclose()?;
-                    Ok(())
-                })?;
-                self.s.space()?;
-                self.word_space(":")?;
+                    s.popen();
+                    s.print_expr(&out.expr);
+                    s.pclose();
+                });
+                self.s.space();
+                self.word_space(":");
 
                 self.commasep(Inconsistent, &a.inputs, |s, &(co, ref o)| {
-                    s.print_string(&co.as_str(), ast::StrStyle::Cooked)?;
-                    s.popen()?;
-                    s.print_expr(o)?;
-                    s.pclose()?;
-                    Ok(())
-                })?;
-                self.s.space()?;
-                self.word_space(":")?;
+                    s.print_string(&co.as_str(), ast::StrStyle::Cooked);
+                    s.popen();
+                    s.print_expr(o);
+                    s.pclose();
+                });
+                self.s.space();
+                self.word_space(":");
 
                 self.commasep(Inconsistent, &a.clobbers,
                                    |s, co| {
-                    s.print_string(&co.as_str(), ast::StrStyle::Cooked)?;
-                    Ok(())
-                })?;
+                    s.print_string(&co.as_str(), ast::StrStyle::Cooked);
+                });
 
                 let mut options = vec![];
                 if a.volatile {
@@ -2283,611 +2232,572 @@ fn print_expr_outer_attr_style(&mut self,
                 }
 
                 if !options.is_empty() {
-                    self.s.space()?;
-                    self.word_space(":")?;
+                    self.s.space();
+                    self.word_space(":");
                     self.commasep(Inconsistent, &options,
                                   |s, &co| {
-                                      s.print_string(co, ast::StrStyle::Cooked)?;
-                                      Ok(())
-                                  })?;
+                                      s.print_string(co, ast::StrStyle::Cooked);
+                                  });
                 }
 
-                self.pclose()?;
+                self.pclose();
             }
-            ast::ExprKind::Mac(ref m) => self.print_mac(m)?,
+            ast::ExprKind::Mac(ref m) => self.print_mac(m),
             ast::ExprKind::Paren(ref e) => {
-                self.popen()?;
-                self.print_inner_attributes_inline(attrs)?;
-                self.print_expr(e)?;
-                self.pclose()?;
+                self.popen();
+                self.print_inner_attributes_inline(attrs);
+                self.print_expr(e);
+                self.pclose();
             },
             ast::ExprKind::Yield(ref e) => {
-                self.s.word("yield")?;
+                self.s.word("yield");
                 match *e {
                     Some(ref expr) => {
-                        self.s.space()?;
-                        self.print_expr_maybe_paren(expr, parser::PREC_JUMP)?;
+                        self.s.space();
+                        self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
                     }
                     _ => ()
                 }
             }
             ast::ExprKind::Try(ref e) => {
-                self.print_expr_maybe_paren(e, parser::PREC_POSTFIX)?;
-                self.s.word("?")?
+                self.print_expr_maybe_paren(e, parser::PREC_POSTFIX);
+                self.s.word("?")
             }
             ast::ExprKind::TryBlock(ref blk) => {
-                self.head("try")?;
-                self.s.space()?;
-                self.print_block_with_attrs(blk, attrs)?
+                self.head("try");
+                self.s.space();
+                self.print_block_with_attrs(blk, attrs)
             }
             ast::ExprKind::Err => {
-                self.popen()?;
-                self.s.word("/*ERROR*/")?;
-                self.pclose()?
+                self.popen();
+                self.s.word("/*ERROR*/");
+                self.pclose()
             }
         }
-        self.ann.post(self, AnnNode::Expr(expr))?;
-        self.end()
+        self.ann.post(self, AnnNode::Expr(expr));
+        self.end();
     }
 
-    pub fn print_local_decl(&mut self, loc: &ast::Local) -> io::Result<()> {
-        self.print_pat(&loc.pat)?;
+    crate fn print_local_decl(&mut self, loc: &ast::Local) {
+        self.print_pat(&loc.pat);
         if let Some(ref ty) = loc.ty {
-            self.word_space(":")?;
-            self.print_type(ty)?;
+            self.word_space(":");
+            self.print_type(ty);
         }
-        Ok(())
     }
 
-    pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
+    crate fn print_ident(&mut self, ident: ast::Ident) {
         if ident.is_raw_guess() {
-            self.s.word(format!("r#{}", ident))?;
+            self.s.word(format!("r#{}", ident));
         } else {
-            self.s.word(ident.as_str().to_string())?;
+            self.s.word(ident.as_str().to_string());
         }
         self.ann.post(self, AnnNode::Ident(&ident))
     }
 
-    pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
+    crate fn print_usize(&mut self, i: usize) {
         self.s.word(i.to_string())
     }
 
-    pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
-        self.s.word(name.as_str().to_string())?;
+    crate fn print_name(&mut self, name: ast::Name) {
+        self.s.word(name.as_str().to_string());
         self.ann.post(self, AnnNode::Name(&name))
     }
 
-    pub fn print_for_decl(&mut self, loc: &ast::Local,
-                          coll: &ast::Expr) -> io::Result<()> {
-        self.print_local_decl(loc)?;
-        self.s.space()?;
-        self.word_space("in")?;
-        self.print_expr(coll)
-    }
-
     fn print_path(&mut self,
                   path: &ast::Path,
                   colons_before_params: bool,
-                  depth: usize)
-                  -> io::Result<()>
-    {
-        self.maybe_print_comment(path.span.lo())?;
+                  depth: usize) {
+        self.maybe_print_comment(path.span.lo());
 
         for (i, segment) in path.segments[..path.segments.len() - depth].iter().enumerate() {
             if i > 0 {
-                self.s.word("::")?
+                self.s.word("::")
             }
-            self.print_path_segment(segment, colons_before_params)?;
+            self.print_path_segment(segment, colons_before_params);
         }
-
-        Ok(())
     }
 
     fn print_path_segment(&mut self,
                           segment: &ast::PathSegment,
-                          colons_before_params: bool)
-                          -> io::Result<()>
-    {
+                          colons_before_params: bool) {
         if segment.ident.name != kw::PathRoot {
             if segment.ident.name == kw::DollarCrate {
-                self.print_dollar_crate(segment.ident)?;
+                self.print_dollar_crate(segment.ident);
             } else {
-                self.print_ident(segment.ident)?;
+                self.print_ident(segment.ident);
             }
             if let Some(ref args) = segment.args {
-                self.print_generic_args(args, colons_before_params)?;
+                self.print_generic_args(args, colons_before_params);
             }
         }
-        Ok(())
     }
 
     fn print_qpath(&mut self,
                    path: &ast::Path,
                    qself: &ast::QSelf,
                    colons_before_params: bool)
-                   -> io::Result<()>
     {
-        self.s.word("<")?;
-        self.print_type(&qself.ty)?;
+        self.s.word("<");
+        self.print_type(&qself.ty);
         if qself.position > 0 {
-            self.s.space()?;
-            self.word_space("as")?;
+            self.s.space();
+            self.word_space("as");
             let depth = path.segments.len() - qself.position;
-            self.print_path(path, false, depth)?;
+            self.print_path(path, false, depth);
         }
-        self.s.word(">")?;
-        self.s.word("::")?;
+        self.s.word(">");
+        self.s.word("::");
         let item_segment = path.segments.last().unwrap();
-        self.print_ident(item_segment.ident)?;
+        self.print_ident(item_segment.ident);
         match item_segment.args {
             Some(ref args) => self.print_generic_args(args, colons_before_params),
-            None => Ok(()),
+            None => {},
         }
     }
 
     fn print_generic_args(&mut self,
                           args: &ast::GenericArgs,
                           colons_before_params: bool)
-                          -> io::Result<()>
     {
         if colons_before_params {
-            self.s.word("::")?
+            self.s.word("::")
         }
 
         match *args {
             ast::GenericArgs::AngleBracketed(ref data) => {
-                self.s.word("<")?;
+                self.s.word("<");
 
                 self.commasep(Inconsistent, &data.args, |s, generic_arg| {
                     s.print_generic_arg(generic_arg)
-                })?;
+                });
 
                 let mut comma = data.args.len() != 0;
 
                 for constraint in data.constraints.iter() {
                     if comma {
-                        self.word_space(",")?
+                        self.word_space(",")
                     }
-                    self.print_ident(constraint.ident)?;
-                    self.s.space()?;
+                    self.print_ident(constraint.ident);
+                    self.s.space();
                     match constraint.kind {
                         ast::AssocTyConstraintKind::Equality { ref ty } => {
-                            self.word_space("=")?;
-                            self.print_type(ty)?;
+                            self.word_space("=");
+                            self.print_type(ty);
                         }
                         ast::AssocTyConstraintKind::Bound { ref bounds } => {
-                            self.print_type_bounds(":", &*bounds)?;
+                            self.print_type_bounds(":", &*bounds);
                         }
                     }
                     comma = true;
                 }
 
-                self.s.word(">")?
+                self.s.word(">")
             }
 
             ast::GenericArgs::Parenthesized(ref data) => {
-                self.s.word("(")?;
+                self.s.word("(");
                 self.commasep(
                     Inconsistent,
                     &data.inputs,
-                    |s, ty| s.print_type(ty))?;
-                self.s.word(")")?;
+                    |s, ty| s.print_type(ty));
+                self.s.word(")");
 
                 if let Some(ref ty) = data.output {
-                    self.space_if_not_bol()?;
-                    self.word_space("->")?;
-                    self.print_type(ty)?;
+                    self.space_if_not_bol();
+                    self.word_space("->");
+                    self.print_type(ty);
                 }
             }
         }
-
-        Ok(())
     }
 
-    pub fn print_pat(&mut self, pat: &ast::Pat) -> io::Result<()> {
-        self.maybe_print_comment(pat.span.lo())?;
-        self.ann.pre(self, AnnNode::Pat(pat))?;
+    crate fn print_pat(&mut self, pat: &ast::Pat) {
+        self.maybe_print_comment(pat.span.lo());
+        self.ann.pre(self, AnnNode::Pat(pat));
         /* Pat isn't normalized, but the beauty of it
          is that it doesn't matter */
         match pat.node {
-            PatKind::Wild => self.s.word("_")?,
+            PatKind::Wild => self.s.word("_"),
             PatKind::Ident(binding_mode, ident, ref sub) => {
                 match binding_mode {
                     ast::BindingMode::ByRef(mutbl) => {
-                        self.word_nbsp("ref")?;
-                        self.print_mutability(mutbl)?;
+                        self.word_nbsp("ref");
+                        self.print_mutability(mutbl);
                     }
                     ast::BindingMode::ByValue(ast::Mutability::Immutable) => {}
                     ast::BindingMode::ByValue(ast::Mutability::Mutable) => {
-                        self.word_nbsp("mut")?;
+                        self.word_nbsp("mut");
                     }
                 }
-                self.print_ident(ident)?;
+                self.print_ident(ident);
                 if let Some(ref p) = *sub {
-                    self.s.word("@")?;
-                    self.print_pat(p)?;
+                    self.s.word("@");
+                    self.print_pat(p);
                 }
             }
             PatKind::TupleStruct(ref path, ref elts, ddpos) => {
-                self.print_path(path, true, 0)?;
-                self.popen()?;
+                self.print_path(path, true, 0);
+                self.popen();
                 if let Some(ddpos) = ddpos {
-                    self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p))?;
+                    self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p));
                     if ddpos != 0 {
-                        self.word_space(",")?;
+                        self.word_space(",");
                     }
-                    self.s.word("..")?;
+                    self.s.word("..");
                     if ddpos != elts.len() {
-                        self.s.word(",")?;
-                        self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p))?;
+                        self.s.word(",");
+                        self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p));
                     }
                 } else {
-                    self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p))?;
+                    self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p));
                 }
-                self.pclose()?;
+                self.pclose();
             }
             PatKind::Path(None, ref path) => {
-                self.print_path(path, true, 0)?;
+                self.print_path(path, true, 0);
             }
             PatKind::Path(Some(ref qself), ref path) => {
-                self.print_qpath(path, qself, false)?;
+                self.print_qpath(path, qself, false);
             }
             PatKind::Struct(ref path, ref fields, etc) => {
-                self.print_path(path, true, 0)?;
-                self.nbsp()?;
-                self.word_space("{")?;
+                self.print_path(path, true, 0);
+                self.nbsp();
+                self.word_space("{");
                 self.commasep_cmnt(
                     Consistent, &fields[..],
                     |s, f| {
-                        s.cbox(INDENT_UNIT)?;
+                        s.cbox(INDENT_UNIT);
                         if !f.node.is_shorthand {
-                            s.print_ident(f.node.ident)?;
-                            s.word_nbsp(":")?;
+                            s.print_ident(f.node.ident);
+                            s.word_nbsp(":");
                         }
-                        s.print_pat(&f.node.pat)?;
-                        s.end()
+                        s.print_pat(&f.node.pat);
+                        s.end();
                     },
-                    |f| f.node.pat.span)?;
+                    |f| f.node.pat.span);
                 if etc {
-                    if !fields.is_empty() { self.word_space(",")?; }
-                    self.s.word("..")?;
+                    if !fields.is_empty() { self.word_space(","); }
+                    self.s.word("..");
                 }
-                self.s.space()?;
-                self.s.word("}")?;
+                self.s.space();
+                self.s.word("}");
             }
             PatKind::Tuple(ref elts, ddpos) => {
-                self.popen()?;
+                self.popen();
                 if let Some(ddpos) = ddpos {
-                    self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p))?;
+                    self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p));
                     if ddpos != 0 {
-                        self.word_space(",")?;
+                        self.word_space(",");
                     }
-                    self.s.word("..")?;
+                    self.s.word("..");
                     if ddpos != elts.len() {
-                        self.s.word(",")?;
-                        self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p))?;
+                        self.s.word(",");
+                        self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p));
                     }
                 } else {
-                    self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p))?;
+                    self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p));
                     if elts.len() == 1 {
-                        self.s.word(",")?;
+                        self.s.word(",");
                     }
                 }
-                self.pclose()?;
+                self.pclose();
             }
             PatKind::Box(ref inner) => {
-                self.s.word("box ")?;
-                self.print_pat(inner)?;
+                self.s.word("box ");
+                self.print_pat(inner);
             }
             PatKind::Ref(ref inner, mutbl) => {
-                self.s.word("&")?;
+                self.s.word("&");
                 if mutbl == ast::Mutability::Mutable {
-                    self.s.word("mut ")?;
+                    self.s.word("mut ");
                 }
-                self.print_pat(inner)?;
+                self.print_pat(inner);
             }
-            PatKind::Lit(ref e) => self.print_expr(&**e)?,
+            PatKind::Lit(ref e) => self.print_expr(&**e),
             PatKind::Range(ref begin, ref end, Spanned { node: ref end_kind, .. }) => {
-                self.print_expr(begin)?;
-                self.s.space()?;
+                self.print_expr(begin);
+                self.s.space();
                 match *end_kind {
-                    RangeEnd::Included(RangeSyntax::DotDotDot) => self.s.word("...")?,
-                    RangeEnd::Included(RangeSyntax::DotDotEq) => self.s.word("..=")?,
-                    RangeEnd::Excluded => self.s.word("..")?,
+                    RangeEnd::Included(RangeSyntax::DotDotDot) => self.s.word("..."),
+                    RangeEnd::Included(RangeSyntax::DotDotEq) => self.s.word("..="),
+                    RangeEnd::Excluded => self.s.word(".."),
                 }
-                self.print_expr(end)?;
+                self.print_expr(end);
             }
             PatKind::Slice(ref before, ref slice, ref after) => {
-                self.s.word("[")?;
+                self.s.word("[");
                 self.commasep(Inconsistent,
                                    &before[..],
-                                   |s, p| s.print_pat(p))?;
+                                   |s, p| s.print_pat(p));
                 if let Some(ref p) = *slice {
-                    if !before.is_empty() { self.word_space(",")?; }
+                    if !before.is_empty() { self.word_space(","); }
                     if let PatKind::Wild = p.node {
                         // Print nothing
                     } else {
-                        self.print_pat(p)?;
+                        self.print_pat(p);
                     }
-                    self.s.word("..")?;
-                    if !after.is_empty() { self.word_space(",")?; }
+                    self.s.word("..");
+                    if !after.is_empty() { self.word_space(","); }
                 }
                 self.commasep(Inconsistent,
                                    &after[..],
-                                   |s, p| s.print_pat(p))?;
-                self.s.word("]")?;
+                                   |s, p| s.print_pat(p));
+                self.s.word("]");
             }
             PatKind::Paren(ref inner) => {
-                self.popen()?;
-                self.print_pat(inner)?;
-                self.pclose()?;
+                self.popen();
+                self.print_pat(inner);
+                self.pclose();
             }
-            PatKind::Mac(ref m) => self.print_mac(m)?,
+            PatKind::Mac(ref m) => self.print_mac(m),
         }
         self.ann.post(self, AnnNode::Pat(pat))
     }
 
-    fn print_pats(&mut self, pats: &[P<ast::Pat>]) -> io::Result<()> {
+    fn print_pats(&mut self, pats: &[P<ast::Pat>]) {
         let mut first = true;
         for p in pats {
             if first {
                 first = false;
             } else {
-                self.s.space()?;
-                self.word_space("|")?;
+                self.s.space();
+                self.word_space("|");
             }
-            self.print_pat(p)?;
+            self.print_pat(p);
         }
-        Ok(())
     }
 
-    fn print_arm(&mut self, arm: &ast::Arm) -> io::Result<()> {
+    fn print_arm(&mut self, arm: &ast::Arm) {
         // I have no idea why this check is necessary, but here it
         // is :(
         if arm.attrs.is_empty() {
-            self.s.space()?;
-        }
-        self.cbox(INDENT_UNIT)?;
-        self.ibox(0)?;
-        self.maybe_print_comment(arm.pats[0].span.lo())?;
-        self.print_outer_attributes(&arm.attrs)?;
-        self.print_pats(&arm.pats)?;
-        self.s.space()?;
+            self.s.space();
+        }
+        self.cbox(INDENT_UNIT);
+        self.ibox(0);
+        self.maybe_print_comment(arm.pats[0].span.lo());
+        self.print_outer_attributes(&arm.attrs);
+        self.print_pats(&arm.pats);
+        self.s.space();
         if let Some(ref e) = arm.guard {
-            self.word_space("if")?;
-            self.print_expr(e)?;
-            self.s.space()?;
+            self.word_space("if");
+            self.print_expr(e);
+            self.s.space();
         }
-        self.word_space("=>")?;
+        self.word_space("=>");
 
         match arm.body.node {
             ast::ExprKind::Block(ref blk, opt_label) => {
                 if let Some(label) = opt_label {
-                    self.print_ident(label.ident)?;
-                    self.word_space(":")?;
+                    self.print_ident(label.ident);
+                    self.word_space(":");
                 }
 
                 // the block will close the pattern's ibox
-                self.print_block_unclosed_indent(blk, INDENT_UNIT)?;
+                self.print_block_unclosed_indent(blk, INDENT_UNIT);
 
                 // If it is a user-provided unsafe block, print a comma after it
                 if let BlockCheckMode::Unsafe(ast::UserProvided) = blk.rules {
-                    self.s.word(",")?;
+                    self.s.word(",");
                 }
             }
             _ => {
-                self.end()?; // close the ibox for the pattern
-                self.print_expr(&arm.body)?;
-                self.s.word(",")?;
+                self.end(); // close the ibox for the pattern
+                self.print_expr(&arm.body);
+                self.s.word(",");
             }
         }
-        self.end() // close enclosing cbox
+        self.end(); // close enclosing cbox
     }
 
-    fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) -> io::Result<()> {
+    fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) {
         match explicit_self.node {
             SelfKind::Value(m) => {
-                self.print_mutability(m)?;
+                self.print_mutability(m);
                 self.s.word("self")
             }
             SelfKind::Region(ref lt, m) => {
-                self.s.word("&")?;
-                self.print_opt_lifetime(lt)?;
-                self.print_mutability(m)?;
+                self.s.word("&");
+                self.print_opt_lifetime(lt);
+                self.print_mutability(m);
                 self.s.word("self")
             }
             SelfKind::Explicit(ref typ, m) => {
-                self.print_mutability(m)?;
-                self.s.word("self")?;
-                self.word_space(":")?;
+                self.print_mutability(m);
+                self.s.word("self");
+                self.word_space(":");
                 self.print_type(typ)
             }
         }
     }
 
-    pub fn print_fn(&mut self,
+    crate fn print_fn(&mut self,
                     decl: &ast::FnDecl,
                     header: ast::FnHeader,
                     name: Option<ast::Ident>,
                     generics: &ast::Generics,
-                    vis: &ast::Visibility) -> io::Result<()> {
-        self.print_fn_header_info(header, vis)?;
+                    vis: &ast::Visibility) {
+        self.print_fn_header_info(header, vis);
 
         if let Some(name) = name {
-            self.nbsp()?;
-            self.print_ident(name)?;
+            self.nbsp();
+            self.print_ident(name);
         }
-        self.print_generic_params(&generics.params)?;
-        self.print_fn_args_and_ret(decl)?;
+        self.print_generic_params(&generics.params);
+        self.print_fn_args_and_ret(decl);
         self.print_where_clause(&generics.where_clause)
     }
 
-    pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl)
-        -> io::Result<()> {
-        self.popen()?;
-        self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, false))?;
-        self.pclose()?;
+    crate fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl) {
+        self.popen();
+        self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, false));
+        self.pclose();
 
         self.print_fn_output(decl)
     }
 
-    pub fn print_fn_block_args(
-            &mut self,
-            decl: &ast::FnDecl)
-            -> io::Result<()> {
-        self.s.word("|")?;
-        self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, true))?;
-        self.s.word("|")?;
+    crate fn print_fn_block_args(&mut self, decl: &ast::FnDecl) {
+        self.s.word("|");
+        self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, true));
+        self.s.word("|");
 
         if let ast::FunctionRetTy::Default(..) = decl.output {
-            return Ok(());
+            return;
         }
 
-        self.space_if_not_bol()?;
-        self.word_space("->")?;
+        self.space_if_not_bol();
+        self.word_space("->");
         match decl.output {
             ast::FunctionRetTy::Ty(ref ty) => {
-                self.print_type(ty)?;
+                self.print_type(ty);
                 self.maybe_print_comment(ty.span.lo())
             }
             ast::FunctionRetTy::Default(..) => unreachable!(),
         }
     }
 
-    pub fn print_movability(&mut self, movability: ast::Movability)
-                                -> io::Result<()> {
+    crate fn print_movability(&mut self, movability: ast::Movability) {
         match movability {
             ast::Movability::Static => self.word_space("static"),
-            ast::Movability::Movable => Ok(()),
+            ast::Movability::Movable => {},
         }
     }
 
-    pub fn print_asyncness(&mut self, asyncness: ast::IsAsync)
-                                -> io::Result<()> {
+    crate fn print_asyncness(&mut self, asyncness: ast::IsAsync) {
         if asyncness.is_async() {
-            self.word_nbsp("async")?;
+            self.word_nbsp("async");
         }
-        Ok(())
     }
 
-    pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureBy)
-                                -> io::Result<()> {
+    crate fn print_capture_clause(&mut self, capture_clause: ast::CaptureBy) {
         match capture_clause {
             ast::CaptureBy::Value => self.word_space("move"),
-            ast::CaptureBy::Ref => Ok(()),
+            ast::CaptureBy::Ref => {},
         }
     }
 
-    pub fn print_type_bounds(&mut self, prefix: &'static str, bounds: &[ast::GenericBound])
-                             -> io::Result<()> {
+    crate fn print_type_bounds(&mut self, prefix: &'static str, bounds: &[ast::GenericBound]) {
         if !bounds.is_empty() {
-            self.s.word(prefix)?;
+            self.s.word(prefix);
             let mut first = true;
             for bound in bounds {
                 if !(first && prefix.is_empty()) {
-                    self.nbsp()?;
+                    self.nbsp();
                 }
                 if first {
                     first = false;
                 } else {
-                    self.word_space("+")?;
+                    self.word_space("+");
                 }
 
                 match bound {
                     GenericBound::Trait(tref, modifier) => {
                         if modifier == &TraitBoundModifier::Maybe {
-                            self.s.word("?")?;
+                            self.s.word("?");
                         }
-                        self.print_poly_trait_ref(tref)?;
+                        self.print_poly_trait_ref(tref);
                     }
-                    GenericBound::Outlives(lt) => self.print_lifetime(*lt)?,
+                    GenericBound::Outlives(lt) => self.print_lifetime(*lt),
                 }
             }
         }
-        Ok(())
     }
 
-    pub fn print_lifetime(&mut self, lifetime: ast::Lifetime) -> io::Result<()> {
+    crate fn print_lifetime(&mut self, lifetime: ast::Lifetime) {
         self.print_name(lifetime.ident.name)
     }
 
-    pub fn print_lifetime_bounds(&mut self, lifetime: ast::Lifetime, bounds: &ast::GenericBounds)
-        -> io::Result<()>
-    {
-        self.print_lifetime(lifetime)?;
+    crate fn print_lifetime_bounds(
+        &mut self, lifetime: ast::Lifetime, bounds: &ast::GenericBounds) {
+        self.print_lifetime(lifetime);
         if !bounds.is_empty() {
-            self.s.word(": ")?;
+            self.s.word(": ");
             for (i, bound) in bounds.iter().enumerate() {
                 if i != 0 {
-                    self.s.word(" + ")?;
+                    self.s.word(" + ");
                 }
                 match bound {
-                    ast::GenericBound::Outlives(lt) => self.print_lifetime(*lt)?,
+                    ast::GenericBound::Outlives(lt) => self.print_lifetime(*lt),
                     _ => panic!(),
                 }
             }
         }
-        Ok(())
     }
 
-    pub fn print_generic_params(
-        &mut self,
-        generic_params: &[ast::GenericParam]
-    ) -> io::Result<()> {
+    crate fn print_generic_params(&mut self, generic_params: &[ast::GenericParam]) {
         if generic_params.is_empty() {
-            return Ok(());
+            return;
         }
 
-        self.s.word("<")?;
+        self.s.word("<");
 
         self.commasep(Inconsistent, &generic_params, |s, param| {
             match param.kind {
                 ast::GenericParamKind::Lifetime => {
-                    s.print_outer_attributes_inline(&param.attrs)?;
+                    s.print_outer_attributes_inline(&param.attrs);
                     let lt = ast::Lifetime { id: param.id, ident: param.ident };
                     s.print_lifetime_bounds(lt, &param.bounds)
                 }
                 ast::GenericParamKind::Type { ref default } => {
-                    s.print_outer_attributes_inline(&param.attrs)?;
-                    s.print_ident(param.ident)?;
-                    s.print_type_bounds(":", &param.bounds)?;
+                    s.print_outer_attributes_inline(&param.attrs);
+                    s.print_ident(param.ident);
+                    s.print_type_bounds(":", &param.bounds);
                     match default {
                         Some(ref default) => {
-                            s.s.space()?;
-                            s.word_space("=")?;
+                            s.s.space();
+                            s.word_space("=");
                             s.print_type(default)
                         }
-                        _ => Ok(())
+                        _ => {}
                     }
                 }
                 ast::GenericParamKind::Const { ref ty } => {
-                    s.print_outer_attributes_inline(&param.attrs)?;
-                    s.word_space("const")?;
-                    s.print_ident(param.ident)?;
-                    s.s.space()?;
-                    s.word_space(":")?;
-                    s.print_type(ty)?;
+                    s.print_outer_attributes_inline(&param.attrs);
+                    s.word_space("const");
+                    s.print_ident(param.ident);
+                    s.s.space();
+                    s.word_space(":");
+                    s.print_type(ty);
                     s.print_type_bounds(":", &param.bounds)
                 }
             }
-        })?;
+        });
 
-        self.s.word(">")?;
-        Ok(())
+        self.s.word(">");
     }
 
-    pub fn print_where_clause(&mut self, where_clause: &ast::WhereClause)
-                              -> io::Result<()> {
+    crate fn print_where_clause(&mut self, where_clause: &ast::WhereClause) {
         if where_clause.predicates.is_empty() {
-            return Ok(())
+            return;
         }
 
-        self.s.space()?;
-        self.word_space("where")?;
+        self.s.space();
+        self.word_space("where");
 
         for (i, predicate) in where_clause.predicates.iter().enumerate() {
             if i != 0 {
-                self.word_space(",")?;
+                self.word_space(",");
             }
 
             match *predicate {
@@ -2897,83 +2807,78 @@ pub fn print_where_clause(&mut self, where_clause: &ast::WhereClause)
                     ref bounds,
                     ..
                 }) => {
-                    self.print_formal_generic_params(bound_generic_params)?;
-                    self.print_type(bounded_ty)?;
-                    self.print_type_bounds(":", bounds)?;
+                    self.print_formal_generic_params(bound_generic_params);
+                    self.print_type(bounded_ty);
+                    self.print_type_bounds(":", bounds);
                 }
                 ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
                                                                                ref bounds,
                                                                                ..}) => {
-                    self.print_lifetime_bounds(*lifetime, bounds)?;
+                    self.print_lifetime_bounds(*lifetime, bounds);
                 }
                 ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ref lhs_ty,
                                                                        ref rhs_ty,
                                                                        ..}) => {
-                    self.print_type(lhs_ty)?;
-                    self.s.space()?;
-                    self.word_space("=")?;
-                    self.print_type(rhs_ty)?;
+                    self.print_type(lhs_ty);
+                    self.s.space();
+                    self.word_space("=");
+                    self.print_type(rhs_ty);
                 }
             }
         }
-
-        Ok(())
     }
 
-    pub fn print_use_tree(&mut self, tree: &ast::UseTree) -> io::Result<()> {
+    crate fn print_use_tree(&mut self, tree: &ast::UseTree) {
         match tree.kind {
             ast::UseTreeKind::Simple(rename, ..) => {
-                self.print_path(&tree.prefix, false, 0)?;
+                self.print_path(&tree.prefix, false, 0);
                 if let Some(rename) = rename {
-                    self.s.space()?;
-                    self.word_space("as")?;
-                    self.print_ident(rename)?;
+                    self.s.space();
+                    self.word_space("as");
+                    self.print_ident(rename);
                 }
             }
             ast::UseTreeKind::Glob => {
                 if !tree.prefix.segments.is_empty() {
-                    self.print_path(&tree.prefix, false, 0)?;
-                    self.s.word("::")?;
+                    self.print_path(&tree.prefix, false, 0);
+                    self.s.word("::");
                 }
-                self.s.word("*")?;
+                self.s.word("*");
             }
             ast::UseTreeKind::Nested(ref items) => {
                 if tree.prefix.segments.is_empty() {
-                    self.s.word("{")?;
+                    self.s.word("{");
                 } else {
-                    self.print_path(&tree.prefix, false, 0)?;
-                    self.s.word("::{")?;
+                    self.print_path(&tree.prefix, false, 0);
+                    self.s.word("::{");
                 }
                 self.commasep(Inconsistent, &items[..], |this, &(ref tree, _)| {
                     this.print_use_tree(tree)
-                })?;
-                self.s.word("}")?;
+                });
+                self.s.word("}");
             }
         }
-
-        Ok(())
     }
 
-    pub fn print_mutability(&mut self,
-                            mutbl: ast::Mutability) -> io::Result<()> {
+    crate fn print_mutability(&mut self, mutbl: ast::Mutability) {
         match mutbl {
             ast::Mutability::Mutable => self.word_nbsp("mut"),
-            ast::Mutability::Immutable => Ok(()),
+            ast::Mutability::Immutable => {},
         }
     }
 
-    pub fn print_mt(&mut self, mt: &ast::MutTy) -> io::Result<()> {
-        self.print_mutability(mt.mutbl)?;
+    crate fn print_mt(&mut self, mt: &ast::MutTy) {
+        self.print_mutability(mt.mutbl);
         self.print_type(&mt.ty)
     }
 
-    pub fn print_arg(&mut self, input: &ast::Arg, is_closure: bool) -> io::Result<()> {
-        self.ibox(INDENT_UNIT)?;
+    crate fn print_arg(&mut self, input: &ast::Arg, is_closure: bool) {
+        self.ibox(INDENT_UNIT);
         match input.ty.node {
-            ast::TyKind::Infer if is_closure => self.print_pat(&input.pat)?,
+            ast::TyKind::Infer if is_closure => self.print_pat(&input.pat),
             _ => {
                 if let Some(eself) = input.to_self() {
-                    self.print_explicit_self(&eself)?;
+                    self.print_explicit_self(&eself);
                 } else {
                     let invalid = if let PatKind::Ident(_, ident, _) = input.pat.node {
                         ident.name == kw::Invalid
@@ -2981,49 +2886,49 @@ pub fn print_arg(&mut self, input: &ast::Arg, is_closure: bool) -> io::Result<()
                         false
                     };
                     if !invalid {
-                        self.print_pat(&input.pat)?;
-                        self.s.word(":")?;
-                        self.s.space()?;
+                        self.print_pat(&input.pat);
+                        self.s.word(":");
+                        self.s.space();
                     }
-                    self.print_type(&input.ty)?;
+                    self.print_type(&input.ty);
                 }
             }
         }
-        self.end()
+        self.end();
     }
 
-    pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> io::Result<()> {
+    crate fn print_fn_output(&mut self, decl: &ast::FnDecl) {
         if let ast::FunctionRetTy::Default(..) = decl.output {
-            return Ok(());
+            return;
         }
 
-        self.space_if_not_bol()?;
-        self.ibox(INDENT_UNIT)?;
-        self.word_space("->")?;
+        self.space_if_not_bol();
+        self.ibox(INDENT_UNIT);
+        self.word_space("->");
         match decl.output {
             ast::FunctionRetTy::Default(..) => unreachable!(),
             ast::FunctionRetTy::Ty(ref ty) =>
-                self.print_type(ty)?
+                self.print_type(ty),
         }
-        self.end()?;
+        self.end();
 
         match decl.output {
             ast::FunctionRetTy::Ty(ref output) => self.maybe_print_comment(output.span.lo()),
-            _ => Ok(())
+            _ => {}
         }
     }
 
-    pub fn print_ty_fn(&mut self,
+    crate fn print_ty_fn(&mut self,
                        abi: abi::Abi,
                        unsafety: ast::Unsafety,
                        decl: &ast::FnDecl,
                        name: Option<ast::Ident>,
                        generic_params: &[ast::GenericParam])
-                       -> io::Result<()> {
-        self.ibox(INDENT_UNIT)?;
+                       {
+        self.ibox(INDENT_UNIT);
         if !generic_params.is_empty() {
-            self.s.word("for")?;
-            self.print_generic_params(generic_params)?;
+            self.s.word("for");
+            self.print_generic_params(generic_params);
         }
         let generics = ast::Generics {
             params: Vec::new(),
@@ -3037,97 +2942,71 @@ pub fn print_ty_fn(&mut self,
                       ast::FnHeader { unsafety, abi, ..ast::FnHeader::default() },
                       name,
                       &generics,
-                      &source_map::dummy_spanned(ast::VisibilityKind::Inherited))?;
-        self.end()
+                      &source_map::dummy_spanned(ast::VisibilityKind::Inherited));
+        self.end();
     }
 
-    pub fn maybe_print_trailing_comment(&mut self, span: syntax_pos::Span,
+    crate fn maybe_print_trailing_comment(&mut self, span: syntax_pos::Span,
                                         next_pos: Option<BytePos>)
-        -> io::Result<()> {
+        {
         let cm = match self.cm {
             Some(cm) => cm,
-            _ => return Ok(())
+            _ => return,
         };
         if let Some(ref cmnt) = self.next_comment() {
-            if cmnt.style != comments::Trailing { return Ok(()) }
+            if cmnt.style != comments::Trailing { return; }
             let span_line = cm.lookup_char_pos(span.hi());
             let comment_line = cm.lookup_char_pos(cmnt.pos);
             let next = next_pos.unwrap_or_else(|| cmnt.pos + BytePos(1));
             if span.hi() < cmnt.pos && cmnt.pos < next && span_line.line == comment_line.line {
-                self.print_comment(cmnt)?;
+                self.print_comment(cmnt);
             }
         }
-        Ok(())
     }
 
-    pub fn print_remaining_comments(&mut self) -> io::Result<()> {
+    crate fn print_remaining_comments(&mut self) {
         // If there aren't any remaining comments, then we need to manually
         // make sure there is a line break at the end.
         if self.next_comment().is_none() {
-            self.s.hardbreak()?;
+            self.s.hardbreak();
         }
         while let Some(ref cmnt) = self.next_comment() {
-            self.print_comment(cmnt)?;
-        }
-        Ok(())
-    }
-
-    pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
-                                                  opt_abi: Option<Abi>)
-        -> io::Result<()> {
-        match opt_abi {
-            Some(Abi::Rust) => Ok(()),
-            Some(abi) => {
-                self.word_nbsp("extern")?;
-                self.word_nbsp(abi.to_string())
-            }
-            None => Ok(())
-        }
-    }
-
-    pub fn print_extern_opt_abi(&mut self,
-                                opt_abi: Option<Abi>) -> io::Result<()> {
-        match opt_abi {
-            Some(abi) => {
-                self.word_nbsp("extern")?;
-                self.word_nbsp(abi.to_string())
-            }
-            None => Ok(())
+            self.print_comment(cmnt);
         }
     }
 
-    pub fn print_fn_header_info(&mut self,
+    crate fn print_fn_header_info(&mut self,
                                 header: ast::FnHeader,
-                                vis: &ast::Visibility) -> io::Result<()> {
-        self.s.word(visibility_qualified(vis, ""))?;
+                                vis: &ast::Visibility) {
+        self.s.word(visibility_qualified(vis, ""));
 
         match header.constness.node {
             ast::Constness::NotConst => {}
-            ast::Constness::Const => self.word_nbsp("const")?
+            ast::Constness::Const => self.word_nbsp("const")
         }
 
-        self.print_asyncness(header.asyncness.node)?;
-        self.print_unsafety(header.unsafety)?;
+        self.print_asyncness(header.asyncness.node);
+        self.print_unsafety(header.unsafety);
 
         if header.abi != Abi::Rust {
-            self.word_nbsp("extern")?;
-            self.word_nbsp(header.abi.to_string())?;
+            self.word_nbsp("extern");
+            self.word_nbsp(header.abi.to_string());
         }
 
         self.s.word("fn")
     }
 
-    pub fn print_unsafety(&mut self, s: ast::Unsafety) -> io::Result<()> {
+    crate fn print_unsafety(&mut self, s: ast::Unsafety) {
         match s {
-            ast::Unsafety::Normal => Ok(()),
+            ast::Unsafety::Normal => {},
             ast::Unsafety::Unsafe => self.word_nbsp("unsafe"),
         }
     }
 
-    pub fn print_is_auto(&mut self, s: ast::IsAuto) -> io::Result<()> {
+    crate fn print_is_auto(&mut self, s: ast::IsAuto) {
         match s {
             ast::IsAuto::Yes => self.word_nbsp("auto"),
-            ast::IsAuto::No => Ok(()),
+            ast::IsAuto::No => {}
         }
     }
 }
index f0cfa5a84a827ddc3fcb4d54fa4d5b42ad495a42..be580dc2e6a7e4aaff0ae4ef00ef235ee9842020 100644 (file)
@@ -41,11 +41,11 @@ pub struct P<T: ?Sized> {
     ptr: Box<T>
 }
 
-#[allow(non_snake_case)]
 /// Construct a `P<T>` from a `T` value.
+#[allow(non_snake_case)]
 pub fn P<T: 'static>(value: T) -> P<T> {
     P {
-        ptr: Box::new(value)
+        ptr: box value
     }
 }
 
index f90b76721ee16a29402eb3e432505abb288df948..c717f140ca368e36a8536c3debf526873832b7eb 100644 (file)
@@ -26,7 +26,6 @@
 use crate::feature_gate::Features;
 use crate::util::map_in_place::MapInPlace;
 use crate::parse::{token, ParseSess};
-use crate::print::pprust;
 use crate::ast::{self, Ident};
 use crate::ptr::P;
 use crate::symbol::{self, Symbol, kw, sym};
@@ -120,8 +119,8 @@ fn visit_crate(&mut self, c: &mut ast::Crate) {
         // We don't want to recurse into anything other than mods, since
         // mods or tests inside of functions will break things
         if let ast::ItemKind::Mod(mut module) = item.node {
-            let tests = mem::replace(&mut self.tests, Vec::new());
-            let tested_submods = mem::replace(&mut self.tested_submods, Vec::new());
+            let tests = mem::take(&mut self.tests);
+            let tested_submods = mem::take(&mut self.tested_submods);
             noop_visit_mod(&mut module, self);
             let tests = mem::replace(&mut self.tests, tests);
             let tested_submods = mem::replace(&mut self.tested_submods, tested_submods);
index cd906bb282b7e3f942f7ef19041829602edd903a..b32049b1da8c365992d1b284701b4553b654b331 100644 (file)
@@ -59,17 +59,6 @@ fn _dummy()
     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(all(bootstrap, parallel_compiler))]
-unsafe impl Send for TokenTree {}
-#[cfg(all(bootstrap, 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 733c4f83e37d4ca283153b1288601223ff137973..f850960624ce7eec4b8c5502c7b60e1a896b6022 100644 (file)
@@ -20,7 +20,7 @@ pub fn string_to_stream(source_str: String) -> TokenStream {
 }
 
 /// Map string to parser (via tts)
-pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> {
+pub fn string_to_parser(ps: &ParseSess, source_str: String) -> Parser<'_> {
     new_parser_from_source_str(ps, PathBuf::from("bogofile").into(), source_str)
 }
 
index 10d323ffb89f55b06cd4175912254d283421e048..637614a18bcc339a07f76cfd40bff8927a0e8171 100644 (file)
@@ -131,7 +131,7 @@ fn parse_assert<'a>(
     Ok(Assert { cond_expr, custom_message })
 }
 
-fn parse_custom_message<'a>(parser: &mut Parser<'a>) -> Option<TokenStream> {
+fn parse_custom_message(parser: &mut Parser<'_>) -> Option<TokenStream> {
     let ts = parser.parse_tokens();
     if !ts.is_empty() {
         Some(ts)
index 444cf1263ce255abcf6cce8b83a1fcfb5078dfa7..12482f7248e90b5eb43a71ea90ecde045eb96ead 100644 (file)
@@ -331,8 +331,8 @@ pub enum SubstructureFields<'a> {
 pub type EnumNonMatchCollapsedFunc<'a> =
     Box<dyn FnMut(&mut ExtCtxt<'_>, Span, (&[Ident], &[Ident]), &[P<Expr>]) -> P<Expr> + 'a>;
 
-pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
-                                -> RefCell<CombineSubstructureFunc<'a>> {
+pub fn combine_substructure(f: CombineSubstructureFunc<'_>)
+                            -> RefCell<CombineSubstructureFunc<'_>> {
     RefCell::new(f)
 }
 
index 90d826429da4db27ea777b0ce4e50ed2a55e3ac6..02b02e9b836957336bc51e566dc7d3aa211ef711 100644 (file)
@@ -39,10 +39,10 @@ pub enum PathKind {
 }
 
 impl<'a> Path<'a> {
-    pub fn new<'r>(path: Vec<&'r str>) -> Path<'r> {
+    pub fn new(path: Vec<&str>) -> Path<'_> {
         Path::new_(path, None, Vec::new(), PathKind::Std)
     }
-    pub fn new_local<'r>(path: &'r str) -> Path<'r> {
+    pub fn new_local(path: &str) -> Path<'_> {
         Path::new_(vec![path], None, Vec::new(), PathKind::Local)
     }
     pub fn new_<'r>(path: Vec<&'r str>,
@@ -117,7 +117,7 @@ pub enum Const {
 pub fn borrowed_ptrty<'r>() -> PtrTy<'r> {
     Borrowed(None, ast::Mutability::Immutable)
 }
-pub fn borrowed<'r>(ty: Box<Ty<'r>>) -> Ty<'r> {
+pub fn borrowed(ty: Box<Ty<'_>>) -> Ty<'_> {
     Ptr(ty, borrowed_ptrty())
 }
 
index b868f5b273c4e6942671bc09f1276a5af34a4274..77b69ddd303b49278e03717304ca3fece656bb59 100644 (file)
@@ -3,7 +3,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #![feature(in_band_lifetimes)]
index 2dd409bf5bee09b86a734bd60b881b7dcbd72993..07b9f60932024db20a488398270f7a42e4afdc03 100644 (file)
@@ -7,7 +7,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 
 #![deny(rust_2018_idioms)]
-#![deny(internal)]
 #![deny(unused_lifetimes)]
 
 #![feature(const_fn)]
index 266bd2a04a2222012209e4eacad48bb0f8c9574e..6a97e5f212732a4d91446a99bb48516c725de4fa 100644 (file)
         associated_type_defaults,
         associated_types,
         async_await,
+        async_closure,
         attr,
         attributes,
         attr_literals,
         cfg_target_thread_local,
         cfg_target_vendor,
         char,
+        clippy,
         clone,
         Clone,
         clone_closures,
         custom_inner_attributes,
         custom_test_frameworks,
         c_variadic,
+        declare_lint_pass,
         decl_macro,
         Default,
         default_lib_allocator,
         if_while_or_patterns,
         ignore,
         impl_header_lifetime_elision,
+        impl_lint_pass,
         impl_trait_in_bindings,
         import_shadowing,
         index,
         link_llvm_intrinsics,
         link_name,
         link_section,
+        LintPass,
         lint_reasons,
         literal,
         local_inner_macros,
         match_beginning_vert,
         match_default_bindings,
         may_dangle,
+        member_constraints,
         message,
         meta,
         min_const_fn,
index 6d42b01337ed531bd36e2c323a5effcbd9a7a548..14ea68d3788785246dd8458622893daf57a387cd 100644 (file)
@@ -108,6 +108,7 @@ pub fn new(out: T) -> io::Result<WinConsole<T>> {
         let fg;
         let bg;
         unsafe {
+            #[allow(deprecated)]
             let mut buffer_info = ::std::mem::uninitialized();
             if GetConsoleScreenBufferInfo(GetStdHandle(-11i32 as DWORD), &mut buffer_info) != 0 {
                 fg = bits_to_color(buffer_info.wAttributes);
index 5794e0b7683cbf7760e2ba505043555c54ae091a..41adc0a415370a42c5cf8d075ea4dd8032f2023e 100644 (file)
@@ -67,6 +67,8 @@ pub enum _Unwind_Context {}
 
 pub type _Unwind_Exception_Cleanup_Fn = extern "C" fn(unwind_code: _Unwind_Reason_Code,
                                                       exception: *mut _Unwind_Exception);
+#[cfg_attr(feature = "llvm-libunwind",
+           link(name = "unwind", kind = "static"))]
 extern "C" {
     #[unwind(allowed)]
     pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
@@ -91,6 +93,8 @@ pub enum _Unwind_Action {
     }
     pub use _Unwind_Action::*;
 
+    #[cfg_attr(feature = "llvm-libunwind",
+               link(name = "unwind", kind = "static"))]
     extern "C" {
         pub fn _Unwind_GetGR(ctx: *mut _Unwind_Context, reg_index: c_int) -> _Unwind_Word;
         pub fn _Unwind_SetGR(ctx: *mut _Unwind_Context, reg_index: c_int, value: _Unwind_Word);
@@ -144,6 +148,8 @@ enum _Unwind_VRS_DataRepresentation {
     pub const UNWIND_POINTER_REG: c_int = 12;
     pub const UNWIND_IP_REG: c_int = 15;
 
+    #[cfg_attr(feature = "llvm-libunwind",
+               link(name = "unwind", kind = "static"))]
     extern "C" {
         fn _Unwind_VRS_Get(ctx: *mut _Unwind_Context,
                            regclass: _Unwind_VRS_RegClass,
@@ -206,6 +212,8 @@ pub unsafe fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void {
 cfg_if::cfg_if! {
 if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
     // Not 32-bit iOS
+    #[cfg_attr(feature = "llvm-libunwind",
+               link(name = "unwind", kind = "static"))]
     extern "C" {
         #[unwind(allowed)]
         pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
@@ -215,6 +223,8 @@ pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
     }
 } else {
     // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace()
+    #[cfg_attr(feature = "llvm-libunwind",
+               link(name = "unwind", kind = "static"))]
     extern "C" {
         #[unwind(allowed)]
         pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
index d928d0888a0dfaf34a9580b731feeafb03b5aedd..9b70a40458287c08127f2ce5433b1b7b666c4db4 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-05-23
+date: 2019-07-04
 rustc: beta
 cargo: beta
 
index 7f2afd9c5715c2b0d44cda7595ed86723a60620c..b95b0ca1a89c00b103dd9200537be8bff3441ec3 100644 (file)
@@ -215,6 +215,29 @@ uint64_t get_c_many_params(void *a, void *b, void *c, void *d, struct quad f) {
     return f.c;
 }
 
+struct quad_floats {
+    float a;
+    float b;
+    float c;
+    float d;
+};
+
+float get_c_exhaust_sysv64_ints(
+    void *a,
+    void *b,
+    void *c,
+    void *d,
+    void *e,
+    void *f,
+    // `f` used the last integer register, so `g` goes on the stack.
+    // It also used to bring the "count of available integer registers" down to
+    // `-1` which broke the next SSE-only aggregate argument (`h`) - see #62350.
+    void *g,
+    struct quad_floats h
+) {
+    return h.c;
+}
+
 // Calculates the average of `(x + y) / n` where x: i64, y: f64. There must be exactly n pairs
 // passed as variadic arguments. There are two versions of this function: the
 // variadic one, and the one that takes a `va_list`.
index e94365058862a11b0e874fbc6da91bcf0008c32b..8200cf4e0167b89d70422b10676da3ca6856cb58 100644 (file)
@@ -1,8 +1,8 @@
-// Test that `-Zpgo-gen` creates expected instrumentation artifacts in LLVM IR.
+// Test that `-Cprofile-generate` creates expected instrumentation artifacts in LLVM IR.
 // Compiling with `-Cpanic=abort` because PGO+unwinding isn't supported on all platforms.
 
 // needs-profiler-support
-// compile-flags: -Z pgo-gen -Ccodegen-units=1 -Cpanic=abort
+// compile-flags: -Cprofile-generate -Ccodegen-units=1 -Cpanic=abort
 
 // CHECK: @__llvm_profile_raw_version =
 // CHECK: @__profc_{{.*}}pgo_instrumentation{{.*}}some_function{{.*}} = private global
index 13daa72a4d1f40f0ecd7eefa0b70d59a93c5c988..34f30548c5a8157f7ee2ea0e3362888ff1ee8677 100644 (file)
@@ -5,7 +5,7 @@
 // revisions:cfail1 cfail2
 // compile-flags: -Z query-dep-graph
 // aux-build:point.rs
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![feature(stmt_expr_attributes)]
index 9e34aedbed307a1d3002f410de26521216406b9c..662aa5353313401f99dabd3b79546c7b2529d9b0 100644 (file)
@@ -5,7 +5,7 @@
 
 // revisions:cfail1 cfail2
 // compile-flags: -Z query-dep-graph
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![feature(stmt_expr_attributes)]
index 04a41d71cc945f3c95631668cda0797b69dec6a7..f5d1acb621be38e65e868ab3ef75df8b297c5bb4 100644 (file)
@@ -3,7 +3,7 @@
 
 // revisions:cfail1 cfail2
 // compile-flags: -Z query-dep-graph -Cpanic=unwind
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(panic_unwind)]
 
index be287b86bbcbac2e1eff894754ee772f154df817..722e62ef11ded4ca086da662105f52c372828d3f 100644 (file)
@@ -3,7 +3,7 @@
 
 // revisions:cfail1 cfail2
 // compile-flags: -Z query-dep-graph
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![feature(stmt_expr_attributes)]
index 521fe99ebc2eb278e782f378abf7ad5a0af3a0d6..384441d6d0c71e510f4cb46f16f864906b01d21b 100644 (file)
@@ -4,7 +4,7 @@
 // revisions:cfail1 cfail2
 // compile-flags: -Z query-dep-graph
 // aux-build:point.rs
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![crate_type = "rlib"]
 #![feature(rustc_attrs)]
index c2796b5e3c90a7e3a3f4d6540b42a4ed6324f076..ec5899f3119d86b7e8e8c92a865a221a5fd8cabc 100644 (file)
@@ -3,7 +3,7 @@
 
 // revisions:cfail1 cfail2
 // compile-flags: -Z query-dep-graph
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![feature(stmt_expr_attributes)]
index 731dcdf78c933c74239974d1111e93d49cb88fae..f0e78f8d0a48341a32814fe882e7b3fb123576a6 100644 (file)
@@ -4,7 +4,7 @@
 // revisions:cfail1 cfail2
 // compile-flags: -Z query-dep-graph
 // aux-build:point.rs
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![crate_type = "rlib"]
 #![feature(rustc_attrs)]
index 76dcff848caf7f189766520bdfb662ed0ce40eb0..641d20ed6cc8ab86ff01d2ce606cb656d1745197 100644 (file)
@@ -2,7 +2,7 @@
 
 // revisions:cfail1 cfail2
 // compile-flags: -Z query-dep-graph
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![crate_type = "rlib"]
 #![feature(rustc_attrs)]
index 9c95d4cc2a9a50245607aa7acece6b5ae1789edd..9b8f9517bf149783e8fa87c0984bccaee764c2b9 100644 (file)
@@ -2,7 +2,7 @@
 
 // revisions:cfail1 cfail2
 // compile-flags: -Z query-dep-graph
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![crate_type = "rlib"]
 #![feature(rustc_attrs)]
index 55dd37451235a8254e67afd03cb908d94afb267e..d859cbef39f0971ebbcbdcc1e0ad61d9783369df 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 5165f9821fd88302c72db33115fe08fb4123f96b..24ab6b8e1845567a4fce6a7a6fa465ee92657573 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 516276a49ea8f3f9ae606d709e5cac0690aef0cd..8e713a1d992377c877d876102d97915e60877988 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index f553b2d1b5123a91bfbc8790c1f37432621b2b39..575b2e92966eab77abee99076670c9c4511a904e 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index aa2dc798b81c8f34427a881b73797d7f0871e326..7256c1aa15326e822deef19f419e778df094dde2 100644 (file)
@@ -10,7 +10,7 @@
 // results in a change of the ICH for the enum's metadata, and that it stays
 // the same between rev2 and rev3.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 5a29afa17d3c2656bc77a72fe47bcd5ad1b6e7c5..ef275cabeaff991b435a2de86e1a3b3986387547 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index e6423ebad128ca07b9f83ae2583a5404d3e6b756..0b9a0fd79451a1ea1db4d9e61bd6d28d2ea3b70d 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 503cb8732ef70ca72af773b2c60c651b132b4faf..ca45d36a6b0e4ec970802ad23ee7183870168dc4 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 7850291fc565ab789cfc4cfae746f583cdff33a5..84680a52ff3cefee9f38b00087f07b0dc8ed357e 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 6bc7d286e3adba5b6826647ddb77a5a6342e16a2..b84c393573b919874877da992419bd6dee37783d 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index eb0c33f7766b41e1ec7febbd38fbe555ea4a5a94..4d39ed68701dd9ec364db0e9ae640a03465fec4e 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 268c37508a73c0a62605ff76d77604627ab330cb..882383e84195792334e69352e860e2277e8c3e54 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 53e77a370a334ab99c5d78122c3cf1dd01037e16..deb1c45a52885252598504aa637848dcfda33d28 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index e016b92a9ebdf6951a6e691643f3eaffae33d8a9..68545b7daaa5cafd70c25ab488f701743a85b611 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index c04bdd43a9528b2622eb783fef174c135707c4ae..6222d948c98e915078d79f10bc43c17eeed7acad 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 02f2cd6634daf2e430d0ad5e72be3b92e285e9e7..840b2222d90a1d2a53dafec68ef9ce0b759a701b 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 0803f4e01d63b1775f5e37f01dfb0462876b5d5c..b370fcce8efda7b040a92492e1c697d7186806de 100644 (file)
@@ -8,7 +8,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -C debug-assertions
 
index 3bee2aca5b6c2f1c11d8c3f83b69cfceba0a29a6..6f74e0fdbc06e1a3dd18a2b890e03897fe5b2247 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index e478ff96c32768bf8c60ad3182f8a0acc98df25e..b708b99eabc9927919353bd1dc075b1fd5a268b9 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 8d32e33054ccc15d3831bbed8df9bb577f7127b0..e0c5696483158b008794c7b9840637dcda0d400d 100644 (file)
@@ -10,7 +10,7 @@
 // results in a change of the ICH for the struct's metadata, and that it stays
 // the same between rev2 and rev3.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index da57b485beb8a1619e9a5820ef382e868140f7a5..30b4e306820edfc9d6dfd4f2770c7bcf76c6d294 100644 (file)
@@ -10,7 +10,7 @@
 // results in a change of the ICH for the trait's metadata, and that it stays
 // the same between rev2 and rev3.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 1487129d09ea644702b4373885a8dbd04286c1c0..fa28b2ebedd132aa2a90b9b520edbcbc763832cf 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 4ffa0d9bb7ba7521b7c214b977d310bf5f96c24a..264e8f926ffe56ada243411e1f9531eb47387c05 100644 (file)
@@ -10,7 +10,7 @@
 // results in a change of the ICH for the enum's metadata, and that it stays
 // the same between rev2 and rev3.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 8c53ae6a03854e04b3ed962df18c666d1588aacd..776a0273ca7b6bf831d1460da85de2bd7051ff48 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 2d48707561c2903bc470d55a74e5d0aa6c4687d8..af2066b90f1d8aab93363f49f6de08a435bf629c 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 79a3bc9b20504250da6a06475fc8edcf0d3b65d6..d8ec76d76aa31977a3fcbfbec2d006584158bc75 100644 (file)
@@ -5,7 +5,7 @@
 // and make sure that the hash has changed, then change nothing between rev2 and
 // rev3 and make sure that the hash has not changed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
 
index 3c2ce765c480589e94d2fa3eefb767ec5ea1eaa9..b2b7e663151e2630b66e763d1621860036bf2754 100644 (file)
@@ -2,7 +2,7 @@
 // the nested items (or even added new ones).
 
 // revisions: cfail1 cfail2
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![crate_type = "rlib"]
 #![feature(rustc_attrs)]
index b0e9b1f9180f657961c23714eba949ae6c54c127..becc1538fb22506a9b44effcb379e73a6ec15840 100644 (file)
@@ -1,6 +1,6 @@
 // aux-build:incremental_proc_macro_aux.rs
 // revisions: cfail1 cfail2
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // This test makes sure that we still find the proc-macro registrar function
 // when we compile proc-macros incrementally (see #47292).
index 17e1b82187881edab55aa823e3c6dff0873bfde8..b8d5303fb4734d0834b843ca5ed87e606d40aa3f 100644 (file)
@@ -8,7 +8,7 @@
 
 // revisions:cfail1 cfail2 cfail3
 // compile-flags:-Zquery-dep-graph
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 
index ada93f79b261d7303210515d23ee3b136362c8e0..ab4d76eef364c7ad1484c44217bf8eb5b889ff2f 100644 (file)
@@ -1,6 +1,6 @@
 // revisions:cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph --test
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![crate_type = "rlib"]
index afc086213403c89c0506855c4fb137db735c93b1..709e9be663efa6ab207d3dae569676b4eda5b6ec 100644 (file)
@@ -3,7 +3,7 @@
 // subsequent runs) if incremental compilation is enabled.
 
 // revisions: cfail1 cfail2
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(on_unimplemented)]
 #![deny(unused_attributes)]
index 37bd8d0641fb9fea3b449c7b554653aebfd6af55..bfb5e539cc18ce06f3b00a54b59be4d79ff191bb 100644 (file)
@@ -4,7 +4,7 @@
 // enabled.
 
 // revisions: cfail1 cfail2
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![deny(unused_attributes)]
index 3e8d8fb1f94f109304046966c7ec02e6f2743f2b..6e791eacdf37a5336f024af92eb52732bde10ba1 100644 (file)
@@ -1,6 +1,6 @@
 // revisions: cfail1 cfail2
 // compile-flags: -Z query-dep-graph
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
index d1966646867a93a88b906b7b1e64bf802a060e90..044d63fd2a9f12f81f0838d28d23ba6831168e1d 100644 (file)
@@ -1,5 +1,5 @@
 // revisions: cfail1 cfail2 cfail3
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // This test case makes sure that we can compile with incremental compilation
 // enabled when there are macros exported from this crate. (See #37756)
index 3af9c0518924a84323d1a7c0e810b6cc0689a0db..b2411c0946fd4cc8e1f6ace189db33f237f5b56c 100644 (file)
@@ -6,7 +6,7 @@
 // Note that we specify -g so that the SourceFiles actually get referenced by the
 // incr. comp. cache:
 // compile-flags: -Z query-dep-graph -g
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![crate_type= "rlib"]
 
index c39d4145b586f13808f86a56e7add59c6dccb4ab..b88acd2af75abf2f93ac9887dc0fc706e9f86a7d 100644 (file)
@@ -1,6 +1,6 @@
 // revisions: cfail1 cfail2
 // compile-flags: -Z query-dep-graph
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
index 09c429f0ad8b609142ed69155b05d21623a60f69..8160f8f3a99f9333645404e5493c0d3fbb98a001 100644 (file)
@@ -4,7 +4,7 @@
 
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -O
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![crate_type="rlib"]
index da6aa79b9d35df1515f3edbee70d37fd2237c39f..24e5d2438bd0ae3d23e3f8c2860963b5be84bcee 100644 (file)
@@ -3,7 +3,7 @@
 
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Z query-dep-graph -O
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![crate_type="rlib"]
index f2acaa0121bb268499c9790c1e3fa5d4e1460134..a1d11f8aa5bbebbc728cf5968072843f30aa322d 100644 (file)
@@ -1,6 +1,6 @@
 // revisions: cfail1 cfail2 cfail3
 // compile-flags: -Coverflow-checks=on
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(warnings)]
 #![warn(const_err)]
index 59a7d61892ffbe0ea6631f400d6f6c40ac4275b7..f8efeca56141b4f499d9c9ff58571bc851ae76e3 100644 (file)
@@ -21,7 +21,7 @@ all: cpp-executable rust-executable
 
 cpp-executable:
        $(RUSTC) -Clinker-plugin-lto=on \
-                -Zpgo-gen="$(TMPDIR)"/cpp-profdata \
+                -Cprofile-generate="$(TMPDIR)"/cpp-profdata \
                 -o "$(TMPDIR)"/librustlib-xlto.a \
                 $(COMMON_FLAGS) \
                 ./rustlib.rs
@@ -39,7 +39,7 @@ cpp-executable:
                -o "$(TMPDIR)"/cpp-profdata/merged.profdata \
                "$(TMPDIR)"/cpp-profdata/default_*.profraw
        $(RUSTC) -Clinker-plugin-lto=on \
-                -Zpgo-use="$(TMPDIR)"/cpp-profdata/merged.profdata \
+                -Cprofile-use="$(TMPDIR)"/cpp-profdata/merged.profdata \
                 -o "$(TMPDIR)"/librustlib-xlto.a \
                 $(COMMON_FLAGS) \
                 ./rustlib.rs
@@ -57,7 +57,7 @@ rust-executable:
        $(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 \
+                -Cprofile-generate="$(TMPDIR)"/rs-profdata \
                 -L$(TMPDIR) \
                 $(COMMON_FLAGS) \
                 -Clinker=$(CLANG) \
@@ -78,7 +78,7 @@ rust-executable:
        rm "$(TMPDIR)"/libxyz.a
        (cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o)
        $(RUSTC) -Clinker-plugin-lto=on \
-                -Zpgo-use="$(TMPDIR)"/rs-profdata/merged.profdata \
+                -Cprofile-use="$(TMPDIR)"/rs-profdata/merged.profdata \
                 -L$(TMPDIR) \
                 $(COMMON_FLAGS) \
                 -Clinker=$(CLANG) \
index 56f31434adee4a17845a53459e6d7fa1003abf75..6c70d951c35eac1bab13496f79935c2824573f4d 100644 (file)
@@ -2,7 +2,7 @@
 
 -include ../tools.mk
 
-COMPILE_FLAGS=-Copt-level=3 -Clto=fat -Z pgo-gen="$(TMPDIR)"
+COMPILE_FLAGS=-Copt-level=3 -Clto=fat -Cprofile-generate="$(TMPDIR)"
 
 # LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC:
 # https://github.com/rust-lang/rust/issues/61002
index bb86160d2dfdf76c13081aa0de0c6e66208b29fa..3fbfeb09eb373d308e67a25b53b04084e5fe6b3c 100644 (file)
@@ -2,7 +2,7 @@
 
 -include ../tools.mk
 
-COMPILE_FLAGS=-O -Ccodegen-units=1 -Z pgo-gen="$(TMPDIR)"
+COMPILE_FLAGS=-O -Ccodegen-units=1 -Cprofile-generate="$(TMPDIR)"
 
 # LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC:
 # https://github.com/rust-lang/rust/issues/61002
index f0ab3b7d13d27444337c7d3ce385fa7828435533..3b66427c14c297dfb781d4ceb0e41a85c0e3e97a 100644 (file)
@@ -2,7 +2,7 @@
 
 -include ../tools.mk
 
-COMPILE_FLAGS=-g -Z pgo-gen="$(TMPDIR)"
+COMPILE_FLAGS=-g -Cprofile-generate="$(TMPDIR)"
 
 # LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC:
 # https://github.com/rust-lang/rust/issues/61002
index 72c3c34ee3741675510c54f0c7cd0b611762e4f7..61a73587759fece06a54b7fb37190baab494e379 100644 (file)
@@ -33,7 +33,7 @@ endif
 
 all:
        # Compile the test program with instrumentation
-       $(RUSTC) $(COMMON_FLAGS) -Z pgo-gen="$(TMPDIR)" main.rs
+       $(RUSTC) $(COMMON_FLAGS) -Cprofile-generate="$(TMPDIR)" main.rs
        # Run it in order to generate some profiling data
        $(call RUN,main some-argument) || exit 1
        # Postprocess the profiling data so it can be used by the compiler
@@ -41,7 +41,7 @@ all:
                -o "$(TMPDIR)"/merged.profdata \
                "$(TMPDIR)"/default_*.profraw
        # Compile the test program again, making use of the profiling data
-       $(RUSTC) $(COMMON_FLAGS) -Z pgo-use="$(TMPDIR)"/merged.profdata --emit=llvm-ir main.rs
+       $(RUSTC) $(COMMON_FLAGS) -Cprofile-use="$(TMPDIR)"/merged.profdata --emit=llvm-ir main.rs
        # Check that the generate IR contains some things that we expect
        #
        # We feed the file into LLVM FileCheck tool *in reverse* so that we see the
index 163e2c5a4625f7014e014fecd04612ab826dc266..cb857e3bc38d352561278f03ec51216deba01f94 100644 (file)
@@ -1,6 +1,7 @@
 use std::mem;
 
 fn main() {
+    #[allow(deprecated)]
     let xs: [u8; 4] = unsafe { mem::uninitialized() };
     let y = xs[0] + xs[1];
 }
index 2add3ccbe36f2f05a7160320b78297d5dccfeac2..35152e7f4babd4a6a28c8bc261979e07dbddcb59 100644 (file)
@@ -2,7 +2,8 @@
 // ignore-stage1
 // compile-flags: -D crate-not-okay
 
-#![feature(plugin, rustc_attrs)]
+#![feature(plugin, custom_attribute, custom_inner_attributes, rustc_attrs)]
+
 #![plugin(lint_for_crate)]
 #![rustc_crate_okay]
 #![rustc_crate_blue]
@@ -10,4 +11,4 @@
 #![rustc_crate_grey]
 #![rustc_crate_green]
 
-pub fn main() { }
+fn main() {}
index 0b9f9934fa9c8826e7b3459c7ebad62d5033df07..fdf0573b5e3ec829db9814d51d57fe647253c73f 100644 (file)
@@ -20,6 +20,7 @@
 // extern-return-TwoU64s
 // foreign-fn-with-byval
 // issue-28676
+// issue-62350-sysv-neg-reg-counts
 // struct-return
 
 // ignore-android
@@ -83,6 +84,9 @@ pub struct S {
     #[derive(Copy, Clone)]
     pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
 
+    #[derive(Copy, Clone)]
+    pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 }
+
     #[repr(C)]
     #[derive(Copy, Clone)]
     pub struct Floats { a: f64, b: u8, c: f64 }
@@ -108,6 +112,16 @@ pub struct Floats { a: f64, b: u8, c: f64 }
         pub fn get_z(x: S) -> u64;
         pub fn get_c_many_params(_: *const (), _: *const (),
                                  _: *const (), _: *const (), f: Quad) -> u64;
+        pub fn get_c_exhaust_sysv64_ints(
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            h: QuadFloats,
+        ) -> f32;
         pub fn rust_dbg_abi_1(q: Quad) -> Quad;
         pub fn rust_dbg_abi_2(f: Floats) -> Floats;
     }
@@ -263,6 +277,27 @@ pub fn issue_28676() {
         test();
     }
 
+    fn test_62350() {
+        use std::ptr;
+        unsafe {
+            let null = ptr::null();
+            let q = QuadFloats {
+                a: 10.2,
+                b: 20.3,
+                c: 30.4,
+                d: 40.5
+            };
+            assert_eq!(
+                get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q),
+                q.c,
+            );
+        }
+    }
+
+    pub fn issue_62350() {
+        test_62350();
+    }
+
     fn test1() {
         unsafe {
             let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa,
@@ -321,6 +356,7 @@ fn main() {
     extern_return_twou64s();
     foreign_fn_with_byval();
     issue_28676();
+    issue_62350();
     struct_return();
 }
 
diff --git a/src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs b/src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs
new file mode 100644 (file)
index 0000000..df81930
--- /dev/null
@@ -0,0 +1,46 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(improper_ctypes)]
+
+// ignore-wasm32-bare no libc to test ffi with
+
+#[derive(Copy, Clone)]
+pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 }
+
+mod rustrt {
+    use super::QuadFloats;
+
+    #[link(name = "rust_test_helpers", kind = "static")]
+    extern {
+        pub fn get_c_exhaust_sysv64_ints(
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            _: *const (),
+            h: QuadFloats,
+        ) -> f32;
+    }
+}
+
+fn test() {
+    unsafe {
+        let null = std::ptr::null();
+        let q = QuadFloats {
+            a: 10.2,
+            b: 20.3,
+            c: 30.4,
+            d: 40.5
+        };
+        assert_eq!(
+            rustrt::get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q),
+            q.c,
+        );
+    }
+}
+
+pub fn main() {
+    test();
+}
diff --git a/src/test/run-pass/async-await/async-fn-size-moved-locals.rs b/src/test/run-pass/async-await/async-fn-size-moved-locals.rs
new file mode 100644 (file)
index 0000000..139be7f
--- /dev/null
@@ -0,0 +1,98 @@
+// Test that we don't duplicate storage for futures moved around in .await, and
+// for futures moved into other futures.
+//
+// The exact sizes can change by a few bytes (we'd like to know when they do).
+// What we don't want to see is the wrong multiple of 1024 (the size of BigFut)
+// being reflected in the size.
+//
+// See issue #59123 for a full explanation.
+
+// edition:2018
+
+#![feature(async_await)]
+
+use std::future::Future;
+use std::pin::Pin;
+use std::task::{Context, Poll};
+
+const BIG_FUT_SIZE: usize = 1024;
+struct BigFut([u8; BIG_FUT_SIZE]);
+
+impl BigFut {
+    fn new() -> Self {
+        BigFut([0; BIG_FUT_SIZE])
+    } }
+
+impl Drop for BigFut {
+    fn drop(&mut self) {}
+}
+
+impl Future for BigFut {
+    type Output = ();
+
+    fn poll(self: Pin<&mut Self>, _ctx: &mut Context<'_>) -> Poll<Self::Output> {
+        Poll::Ready(())
+    }
+}
+
+#[allow(dead_code)]
+struct Joiner {
+    a: Option<BigFut>,
+    b: Option<BigFut>,
+    c: Option<BigFut>,
+}
+
+impl Future for Joiner {
+    type Output = ();
+
+    fn poll(self: Pin<&mut Self>, _ctx: &mut Context<'_>) -> Poll<Self::Output> {
+        Poll::Ready(())
+    }
+}
+
+fn noop() {}
+
+async fn single() {
+    let x = BigFut::new();
+    x.await;
+}
+
+async fn single_with_noop() {
+    let x = BigFut::new();
+    noop();
+    x.await;
+}
+
+async fn joined() {
+    let a = BigFut::new();
+    let b = BigFut::new();
+    let c = BigFut::new();
+
+    let joiner = Joiner {
+        a: Some(a),
+        b: Some(b),
+        c: Some(c),
+    };
+    joiner.await
+}
+
+async fn joined_with_noop() {
+    let a = BigFut::new();
+    let b = BigFut::new();
+    let c = BigFut::new();
+
+    let joiner = Joiner {
+        a: Some(a),
+        b: Some(b),
+        c: Some(c),
+    };
+    noop();
+    joiner.await
+}
+
+fn main() {
+    assert_eq!(1028, std::mem::size_of_val(&single()));
+    assert_eq!(1032, std::mem::size_of_val(&single_with_noop()));
+    assert_eq!(3084, std::mem::size_of_val(&joined()));
+    assert_eq!(3084, std::mem::size_of_val(&joined_with_noop()));
+}
index c4e328560ddf701c4067e26f5167cc52638b8096..7396918196c088a35c4108780728d80cb19ce766 100644 (file)
@@ -1,6 +1,6 @@
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 #[path = "../auxiliary/arc_wake.rs"]
 mod arc_wake;
@@ -58,31 +58,31 @@ fn wait(fut: impl Future<Output = u8>) -> u8 {
 fn base() -> WakeOnceThenComplete { WakeOnceThenComplete(false, 1) }
 
 async fn await1_level1() -> u8 {
-    await!(base())
+    base().await
 }
 
 async fn await2_level1() -> u8 {
-    await!(base()) + await!(base())
+    base().await + base().await
 }
 
 async fn await3_level1() -> u8 {
-    await!(base()) + await!(base()) + await!(base())
+    base().await + base().await + base().await
 }
 
 async fn await3_level2() -> u8 {
-    await!(await3_level1()) + await!(await3_level1()) + await!(await3_level1())
+    await3_level1().await + await3_level1().await + await3_level1().await
 }
 
 async fn await3_level3() -> u8 {
-    await!(await3_level2()) + await!(await3_level2()) + await!(await3_level2())
+    await3_level2().await + await3_level2().await + await3_level2().await
 }
 
 async fn await3_level4() -> u8 {
-    await!(await3_level3()) + await!(await3_level3()) + await!(await3_level3())
+    await3_level3().await + await3_level3().await + await3_level3().await
 }
 
 async fn await3_level5() -> u8 {
-    await!(await3_level4()) + await!(await3_level4()) + await!(await3_level4())
+    await3_level4().await + await3_level4().await + await3_level4().await
 }
 
 fn main() {
index 778d3ee0c70836d8734d6ecd23accb58411017fb..5ebb18b999ab6f83d071f65630740f08d74f9c5b 100644 (file)
@@ -2,7 +2,7 @@
 // handled incorrectly in generators.
 // compile-flags: -Copt-level=z -Cdebuginfo=2 --edition=2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 #![allow(unused)]
 
 use std::future::Future;
@@ -22,7 +22,7 @@ fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
 fn main() {
     let fut = async {
         let _rc = Rc::new(()); // Also crashes with Arc
-        await!(Never());
+        Never().await;
     };
     let _bla = fut; // Moving the future is required.
 }
diff --git a/src/test/run-pass/attr-on-generic-formals.rs b/src/test/run-pass/attr-on-generic-formals.rs
deleted file mode 100644 (file)
index 9ebf0fc..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#![allow(unused_attributes)]
-
-// This test ensures we can attach attributes to the formals in all
-// places where generic parameter lists occur, assuming appropriate
-// feature gates are enabled.
-//
-// (We are prefixing all tested features with `rustc_`, to ensure that
-// the attributes themselves won't be rejected by the compiler when
-// using `rustc_attrs` feature. There is a separate compile-fail/ test
-// ensuring that the attribute feature-gating works in this context.)
-
-#![feature(rustc_attrs)]
-#![allow(dead_code)]
-
-struct StLt<#[rustc_lt_struct] 'a>(&'a u32);
-struct StTy<#[rustc_ty_struct] I>(I);
-
-enum EnLt<#[rustc_lt_enum] 'b> { A(&'b u32), B }
-enum EnTy<#[rustc_ty_enum] J> { A(J), B }
-
-trait TrLt<#[rustc_lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
-trait TrTy<#[rustc_ty_trait] K> { fn foo(&self, _: K); }
-
-type TyLt<#[rustc_lt_type] 'd> = &'d u32;
-type TyTy<#[rustc_ty_type] L> = (L, );
-
-impl<#[rustc_lt_inherent] 'e> StLt<'e> { }
-impl<#[rustc_ty_inherent] M> StTy<M> { }
-
-impl<#[rustc_lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
-    fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } }
-}
-impl<#[rustc_ty_impl_for] N> TrTy<N> for StTy<N> {
-    fn foo(&self, _: N) { }
-}
-
-fn f_lt<#[rustc_lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
-fn f_ty<#[rustc_ty_fn] O>(_: O) { }
-
-impl<I> StTy<I> {
-    fn m_lt<#[rustc_lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
-    fn m_ty<#[rustc_ty_meth] P>(_: P) { }
-}
-
-fn hof_lt<Q>(_: Q)
-    where Q: for <#[rustc_lt_hof] 'i> Fn(&'i [u32]) -> &'i u32
-{
-}
-
-fn main() {
-
-}
diff --git a/src/test/run-pass/command-uid-gid.rs b/src/test/run-pass/command-uid-gid.rs
new file mode 100644 (file)
index 0000000..2b52c5d
--- /dev/null
@@ -0,0 +1,26 @@
+#![feature(rustc_private)]
+
+fn main() {
+    #[cfg(unix)]
+    run()
+}
+
+#[cfg(unix)]
+fn run() {
+    extern crate libc;
+    use std::process::Command;
+    use std::os::unix::prelude::*;
+
+    let mut p = Command::new("/bin/sh")
+        .arg("-c").arg("true")
+        .uid(unsafe { libc::getuid() })
+        .gid(unsafe { libc::getgid() })
+        .spawn().unwrap();
+    assert!(p.wait().unwrap().success());
+
+    // if we're already root, this isn't a valid test. Most of the bots run
+    // as non-root though (android is an exception).
+    if unsafe { libc::getuid() != 0 } {
+        assert!(Command::new("/bin/ls").uid(0).gid(0).spawn().is_err());
+    }
+}
diff --git a/src/test/run-pass/drop/dynamic-drop-async.rs b/src/test/run-pass/drop/dynamic-drop-async.rs
new file mode 100644 (file)
index 0000000..9226145
--- /dev/null
@@ -0,0 +1,328 @@
+// Test that values are not leaked in async functions, even in the cases where:
+// * Dropping one of the values panics while running the future.
+// * The future is dropped at one of its suspend points.
+// * Dropping one of the values panics while dropping the future.
+
+// run-pass
+// edition:2018
+// ignore-wasm32-bare compiled with panic=abort by default
+
+#![allow(unused_assignments)]
+#![allow(unused_variables)]
+#![feature(slice_patterns)]
+#![feature(async_await)]
+
+use std::{
+    cell::{Cell, RefCell},
+    future::Future,
+    marker::Unpin,
+    panic,
+    pin::Pin,
+    ptr,
+    rc::Rc,
+    task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
+    usize,
+};
+
+struct InjectedFailure;
+
+struct Defer<T> {
+    ready: bool,
+    value: Option<T>,
+}
+
+impl<T: Unpin> Future for Defer<T> {
+    type Output = T;
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
+        if self.ready {
+            Poll::Ready(self.value.take().unwrap())
+        } else {
+            self.ready = true;
+            Poll::Pending
+        }
+    }
+}
+
+/// Allocator tracks the creation and destruction of `Ptr`s.
+/// The `failing_op`-th operation will panic.
+struct Allocator {
+    data: RefCell<Vec<bool>>,
+    failing_op: usize,
+    cur_ops: Cell<usize>,
+}
+
+impl panic::UnwindSafe for Allocator {}
+impl panic::RefUnwindSafe for Allocator {}
+
+impl Drop for Allocator {
+    fn drop(&mut self) {
+        let data = self.data.borrow();
+        if data.iter().any(|d| *d) {
+            panic!("missing free: {:?}", data);
+        }
+    }
+}
+
+impl Allocator {
+    fn new(failing_op: usize) -> Self {
+        Allocator { failing_op, cur_ops: Cell::new(0), data: RefCell::new(vec![]) }
+    }
+    fn alloc(&self) -> impl Future<Output = Ptr<'_>> + '_ {
+        self.fallible_operation();
+
+        let mut data = self.data.borrow_mut();
+
+        let addr = data.len();
+        data.push(true);
+        Defer { ready: false, value: Some(Ptr(addr, self)) }
+    }
+    fn fallible_operation(&self) {
+        self.cur_ops.set(self.cur_ops.get() + 1);
+
+        if self.cur_ops.get() == self.failing_op {
+            panic!(InjectedFailure);
+        }
+    }
+}
+
+// Type that tracks whether it was dropped and can panic when it's created or
+// destroyed.
+struct Ptr<'a>(usize, &'a Allocator);
+impl<'a> Drop for Ptr<'a> {
+    fn drop(&mut self) {
+        match self.1.data.borrow_mut()[self.0] {
+            false => panic!("double free at index {:?}", self.0),
+            ref mut d => *d = false,
+        }
+
+        self.1.fallible_operation();
+    }
+}
+
+async fn dynamic_init(a: Rc<Allocator>, c: bool) {
+    let _x;
+    if c {
+        _x = Some(a.alloc().await);
+    }
+}
+
+async fn dynamic_drop(a: Rc<Allocator>, c: bool) {
+    let x = a.alloc().await;
+    if c {
+        Some(x)
+    } else {
+        None
+    };
+}
+
+struct TwoPtrs<'a>(Ptr<'a>, Ptr<'a>);
+async fn struct_dynamic_drop(a: Rc<Allocator>, c0: bool, c1: bool, c: bool) {
+    for i in 0..2 {
+        let x;
+        let y;
+        if (c0 && i == 0) || (c1 && i == 1) {
+            x = (a.alloc().await, a.alloc().await, a.alloc().await);
+            y = TwoPtrs(a.alloc().await, a.alloc().await);
+            if c {
+                drop(x.1);
+                a.alloc().await;
+                drop(y.0);
+                a.alloc().await;
+            }
+        }
+    }
+}
+
+async fn field_assignment(a: Rc<Allocator>, c0: bool) {
+    let mut x = (TwoPtrs(a.alloc().await, a.alloc().await), a.alloc().await);
+
+    x.1 = a.alloc().await;
+    x.1 = a.alloc().await;
+
+    let f = (x.0).0;
+    a.alloc().await;
+    if c0 {
+        (x.0).0 = f;
+    }
+    a.alloc().await;
+}
+
+async fn assignment(a: Rc<Allocator>, c0: bool, c1: bool) {
+    let mut _v = a.alloc().await;
+    let mut _w = a.alloc().await;
+    if c0 {
+        drop(_v);
+    }
+    _v = _w;
+    if c1 {
+        _w = a.alloc().await;
+    }
+}
+
+async fn array_simple(a: Rc<Allocator>) {
+    let _x = [a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await];
+}
+
+async fn vec_simple(a: Rc<Allocator>) {
+    let _x = vec![a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await];
+}
+
+async fn mixed_drop_and_nondrop(a: Rc<Allocator>) {
+    // check that destructor panics handle drop
+    // and non-drop blocks in the same scope correctly.
+    //
+    // Surprisingly enough, this used to not work.
+    let (x, y, z);
+    x = a.alloc().await;
+    y = 5;
+    z = a.alloc().await;
+}
+
+#[allow(unreachable_code)]
+async fn vec_unreachable(a: Rc<Allocator>) {
+    let _x = vec![a.alloc().await, a.alloc().await, a.alloc().await, return];
+}
+
+async fn slice_pattern_one_of(a: Rc<Allocator>, i: usize) {
+    let array = [a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await];
+    let _x = match i {
+        0 => {
+            let [a, ..] = array;
+            a
+        }
+        1 => {
+            let [_, a, ..] = array;
+            a
+        }
+        2 => {
+            let [_, _, a, _] = array;
+            a
+        }
+        3 => {
+            let [_, _, _, a] = array;
+            a
+        }
+        _ => panic!("unmatched"),
+    };
+    a.alloc().await;
+}
+
+async fn subslice_pattern_from_end_with_drop(a: Rc<Allocator>, arg: bool, arg2: bool) {
+    let arr = [a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await];
+    if arg2 {
+        drop(arr);
+        return;
+    }
+
+    if arg {
+        let [.., _x, _] = arr;
+    } else {
+        let [_, _y..] = arr;
+    }
+    a.alloc().await;
+}
+
+async fn subslice_pattern_reassign(a: Rc<Allocator>) {
+    let mut ar = [a.alloc().await, a.alloc().await, a.alloc().await];
+    let [_, _, _x] = ar;
+    ar = [a.alloc().await, a.alloc().await, a.alloc().await];
+    let [_, _y..] = ar;
+    a.alloc().await;
+}
+
+fn run_test<F, G>(cx: &mut Context<'_>, ref f: F)
+where
+    F: Fn(Rc<Allocator>) -> G,
+    G: Future<Output = ()>,
+{
+    for polls in 0.. {
+        // Run without any panics to find which operations happen after the
+        // penultimate `poll`.
+        let first_alloc = Rc::new(Allocator::new(usize::MAX));
+        let mut fut = Box::pin(f(first_alloc.clone()));
+        let mut ops_before_last_poll = 0;
+        let mut completed = false;
+        for _ in 0..polls {
+            ops_before_last_poll = first_alloc.cur_ops.get();
+            if let Poll::Ready(()) = fut.as_mut().poll(cx) {
+                completed = true;
+            }
+        }
+        drop(fut);
+
+        // Start at `ops_before_last_poll` so that we will always be able to
+        // `poll` the expected number of times.
+        for failing_op in ops_before_last_poll..first_alloc.cur_ops.get() {
+            let alloc = Rc::new(Allocator::new(failing_op + 1));
+            let f = &f;
+            let cx = &mut *cx;
+            let result = panic::catch_unwind(panic::AssertUnwindSafe(move || {
+                let mut fut = Box::pin(f(alloc));
+                for _ in 0..polls {
+                    let _ = fut.as_mut().poll(cx);
+                }
+                drop(fut);
+            }));
+            match result {
+                Ok(..) => panic!("test executed more ops on first call"),
+                Err(e) => {
+                    if e.downcast_ref::<InjectedFailure>().is_none() {
+                        panic::resume_unwind(e);
+                    }
+                }
+            }
+        }
+
+        if completed {
+            break;
+        }
+    }
+}
+
+fn clone_waker(data: *const ()) -> RawWaker {
+    RawWaker::new(data, &RawWakerVTable::new(clone_waker, drop, drop, drop))
+}
+
+fn main() {
+    let waker = unsafe { Waker::from_raw(clone_waker(ptr::null())) };
+    let context = &mut Context::from_waker(&waker);
+
+    run_test(context, |a| dynamic_init(a, false));
+    run_test(context, |a| dynamic_init(a, true));
+    run_test(context, |a| dynamic_drop(a, false));
+    run_test(context, |a| dynamic_drop(a, true));
+
+    run_test(context, |a| assignment(a, false, false));
+    run_test(context, |a| assignment(a, false, true));
+    run_test(context, |a| assignment(a, true, false));
+    run_test(context, |a| assignment(a, true, true));
+
+    run_test(context, |a| array_simple(a));
+    run_test(context, |a| vec_simple(a));
+    run_test(context, |a| vec_unreachable(a));
+
+    run_test(context, |a| struct_dynamic_drop(a, false, false, false));
+    run_test(context, |a| struct_dynamic_drop(a, false, false, true));
+    run_test(context, |a| struct_dynamic_drop(a, false, true, false));
+    run_test(context, |a| struct_dynamic_drop(a, false, true, true));
+    run_test(context, |a| struct_dynamic_drop(a, true, false, false));
+    run_test(context, |a| struct_dynamic_drop(a, true, false, true));
+    run_test(context, |a| struct_dynamic_drop(a, true, true, false));
+    run_test(context, |a| struct_dynamic_drop(a, true, true, true));
+
+    run_test(context, |a| field_assignment(a, false));
+    run_test(context, |a| field_assignment(a, true));
+
+    run_test(context, |a| mixed_drop_and_nondrop(a));
+
+    run_test(context, |a| slice_pattern_one_of(a, 0));
+    run_test(context, |a| slice_pattern_one_of(a, 1));
+    run_test(context, |a| slice_pattern_one_of(a, 2));
+    run_test(context, |a| slice_pattern_one_of(a, 3));
+
+    run_test(context, |a| subslice_pattern_from_end_with_drop(a, true, true));
+    run_test(context, |a| subslice_pattern_from_end_with_drop(a, true, false));
+    run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, true));
+    run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, false));
+    run_test(context, |a| subslice_pattern_reassign(a));
+}
index 009c59f2fa43dfe96cfbd0bdf17159450b9cfb71..38c34d2dc2e6f8fbc7802b706aa4267a7418d977 100644 (file)
@@ -2,6 +2,7 @@
 fn main() {
     // Check that the tail statement in the body unifies with something
     for _ in 0..3 {
+        #[allow(deprecated)]
         unsafe { std::mem::uninitialized() }
     }
 
diff --git a/src/test/run-pass/generator/size-moved-locals.rs b/src/test/run-pass/generator/size-moved-locals.rs
new file mode 100644 (file)
index 0000000..37e2e0c
--- /dev/null
@@ -0,0 +1,62 @@
+// Test that we don't duplicate storage for a variable that is moved to another
+// binding. This used to happen in the presence of unwind and drop edges (see
+// `complex` below.)
+//
+// The exact sizes here can change (we'd like to know when they do). What we
+// don't want to see is the `complex` generator size being upwards of 2048 bytes
+// (which would indicate it is reserving space for two copies of Foo.)
+//
+// See issue #59123 for a full explanation.
+
+// edition:2018
+
+#![feature(generators, generator_trait)]
+
+use std::ops::Generator;
+
+const FOO_SIZE: usize = 1024;
+struct Foo([u8; FOO_SIZE]);
+
+impl Drop for Foo {
+    fn drop(&mut self) {}
+}
+
+fn move_before_yield() -> impl Generator<Yield = (), Return = ()> {
+    static || {
+        let first = Foo([0; FOO_SIZE]);
+        let _second = first;
+        yield;
+        // _second dropped here
+    }
+}
+
+fn noop() {}
+
+fn move_before_yield_with_noop() -> impl Generator<Yield = (), Return = ()> {
+    static || {
+        let first = Foo([0; FOO_SIZE]);
+        noop();
+        let _second = first;
+        yield;
+        // _second dropped here
+    }
+}
+
+// Today we don't have NRVO (we allocate space for both `first` and `second`,)
+// but we can overlap `first` with `_third`.
+fn overlap_move_points() -> impl Generator<Yield = (), Return = ()> {
+    static || {
+        let first = Foo([0; FOO_SIZE]);
+        yield;
+        let second = first;
+        yield;
+        let _third = second;
+        yield;
+    }
+}
+
+fn main() {
+    assert_eq!(1028, std::mem::size_of_val(&move_before_yield()));
+    assert_eq!(1032, std::mem::size_of_val(&move_before_yield_with_noop()));
+    assert_eq!(2056, std::mem::size_of_val(&overlap_move_points()));
+}
diff --git a/src/test/run-pass/intrinsics/intrinsic-uninit.rs b/src/test/run-pass/intrinsics/intrinsic-uninit.rs
deleted file mode 100644 (file)
index 9555efb..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// run-pass
-// pretty-expanded FIXME #23616
-
-#![feature(intrinsics)]
-
-mod rusti {
-    extern "rust-intrinsic" {
-        pub fn uninit<T>() -> T;
-    }
-}
-pub fn main() {
-    let _a : isize = unsafe {rusti::uninit()};
-}
index e837fc81721a807c7a5166632d0a9263c9243988..111fb8aa506a4b91116101b55d1a42fce064d135 100644 (file)
@@ -12,7 +12,9 @@ pub enum Handler {
 }
 
 fn main() {
-    take(Handler::Default, Box::new(main));
+    #[allow(unused_must_use)] {
+        take(Handler::Default, Box::new(main));
+    }
 }
 
 #[inline(never)]
index 76437630309af1603364579864c03d0eb304c236..d4ce6496cae7733437612843ef850434a1b6d3c2 100644 (file)
@@ -4,6 +4,7 @@ trait FromUnchecked {
 
 impl FromUnchecked for [u8; 1] {
     unsafe fn from_unchecked() {
+        #[allow(deprecated)]
         let mut array: Self = std::mem::uninitialized();
         let _ptr = &mut array as *mut [u8] as *mut u8;
     }
diff --git a/src/test/run-pass/packed/packed-with-inference-vars-issue-61402.rs b/src/test/run-pass/packed/packed-with-inference-vars-issue-61402.rs
new file mode 100644 (file)
index 0000000..6028b8f
--- /dev/null
@@ -0,0 +1,21 @@
+// If a struct is packed and its last field has drop glue, then that
+// field needs to be Sized (to allow it to be destroyed out-of-place).
+//
+// This is checked by the compiler during wfcheck. That check used
+// to have problems with associated types in the last field - test
+// that this doesn't ICE.
+
+#![allow(unused_imports, dead_code)]
+
+pub struct S;
+
+pub trait Trait<R> { type Assoc; }
+
+impl<X> Trait<X> for S { type Assoc = X; }
+
+#[repr(C, packed)]
+struct PackedAssocSized {
+    pos: Box<<S as Trait<usize>>::Assoc>,
+}
+
+fn main() { println!("Hello, world!"); }
index 4ca4b407bd4ff2b70ca60e3aed042874bc8efcec..5026ad1ccd4ceae68cd31fdeab74f2c81707d7a5 100644 (file)
@@ -3,6 +3,7 @@
 // in a runtime panic.
 
 #![feature(never_type)]
+#![allow(deprecated)]
 
 use std::{mem, panic};
 
index ebe4f70378cf01d30e1d3d06b6ebc117b9b986e2..6badd203842ffec55d36c7e8aa8d7a5efb6277f7 100644 (file)
@@ -1,5 +1,7 @@
 // run-pass
+
 #![allow(stable_features)]
+#![allow(unused_must_use)]
 
 // ignore-emscripten no threads support
 
index 51a3b46d4619b204c12c33a94f8a31b522d62b84..0ab7e17f87b5a156a738fc3c37fa8b9f5e92b010 100644 (file)
@@ -1,7 +1,7 @@
 // run-pass
 #![feature(decl_macro)]
 
-r#macro_rules! r#struct {
+macro_rules! r#struct {
     ($r#struct:expr) => { $r#struct }
 }
 
index 92a0cc3a07b5211d629e9d23f5ed435f0e126a97..773d0ace90ed9dbc25792c4097c68e45768645d1 100644 (file)
@@ -49,6 +49,7 @@ fn main() {
 #[allow(unconditional_recursion)]
 fn recurse(array: &[u64]) {
     unsafe { black_box(array.as_ptr() as u64); }
+    #[allow(deprecated)]
     let local: [_; 1024] = unsafe { mem::uninitialized() };
     recurse(&local);
 }
index c971f567d954214ed134f171d88532fc34ebd3b4..78d8e5e3a5dbf39e9abf8059883df24647bdf652 100644 (file)
@@ -69,6 +69,7 @@ fn main() {
     unsafe {
         // This should be safe, because we don't match on it unless it's fully formed,
         // and it doesn't have a destructor.
+        #[allow(deprecated)]
         let mut dest: MyEnum = mem::uninitialized();
         while buf.len() > 0 {
             match parse_my_enum(&mut dest, &mut buf) {
index 57ccf11450913a3f458c2577d00ea989f44b9e4a..1209533efda82097f7564bfa2e4f9294398e83d5 100644 (file)
@@ -69,6 +69,7 @@ fn main() {
     unsafe {
         // This should be safe, because we don't match on it unless it's fully formed,
         // and it doesn't have a destructor.
+        #[allow(deprecated)]
         let mut dest: MyEnum = mem::uninitialized();
         while buf.len() > 0 {
             match parse_my_enum(&mut dest, &mut buf) {
index d297c895da5632dc5a61f0d186272a74bcde70fd..5dd9c1863d62da2b00b5343e8c4b35d956c59803 100644 (file)
@@ -65,6 +65,7 @@ fn main() {
     unsafe {
         // This should be safe, because we don't match on it unless it's fully formed,
         // and it doesn't have a destructor.
+        #[allow(deprecated)]
         let mut dest: MyEnum = mem::uninitialized();
         while buf.len() > 0 {
             match parse_my_enum(&mut dest, &mut buf) {
diff --git a/src/test/run-pass/type-alias-enum-variants-2.rs b/src/test/run-pass/type-alias-enum-variants-2.rs
deleted file mode 100644 (file)
index 0cf413b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#![feature(type_alias_enum_variants)]
-
-#[derive(Debug, PartialEq, Eq)]
-enum Foo {
-    Bar(i32),
-    Baz { i: i32 },
-}
-
-type FooAlias = Foo;
-type OptionAlias = Option<i32>;
-
-impl Foo {
-    fn foo() -> Self {
-        Self::Bar(3)
-    }
-}
-
-fn main() {
-    let t = FooAlias::Bar(1);
-    assert_eq!(t, Foo::Bar(1));
-    let t = FooAlias::Baz { i: 2 };
-    assert_eq!(t, Foo::Baz { i: 2 });
-    match t {
-        FooAlias::Bar(_i) => {}
-        FooAlias::Baz { i } => { assert_eq!(i, 2); }
-    }
-    assert_eq!(Foo::foo(), Foo::Bar(3));
-
-    assert_eq!(OptionAlias::Some(4), Option::Some(4));
-}
diff --git a/src/test/run-pass/type-alias-enum-variants.rs b/src/test/run-pass/type-alias-enum-variants.rs
deleted file mode 100644 (file)
index 0cf413b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#![feature(type_alias_enum_variants)]
-
-#[derive(Debug, PartialEq, Eq)]
-enum Foo {
-    Bar(i32),
-    Baz { i: i32 },
-}
-
-type FooAlias = Foo;
-type OptionAlias = Option<i32>;
-
-impl Foo {
-    fn foo() -> Self {
-        Self::Bar(3)
-    }
-}
-
-fn main() {
-    let t = FooAlias::Bar(1);
-    assert_eq!(t, Foo::Bar(1));
-    let t = FooAlias::Baz { i: 2 };
-    assert_eq!(t, Foo::Baz { i: 2 });
-    match t {
-        FooAlias::Bar(_i) => {}
-        FooAlias::Baz { i } => { assert_eq!(i, 2); }
-    }
-    assert_eq!(Foo::foo(), Foo::Bar(3));
-
-    assert_eq!(OptionAlias::Some(4), Option::Some(4));
-}
index b59971b3498027cdfef01442e9e2d4cf8d6ff98f..4bc247a3dcab5ba6a13b706e32c710d95e303bf5 100644 (file)
@@ -7,6 +7,7 @@
 #[derive(Clone)]
 struct Foo;
 
+#[allow(deprecated)]
 pub fn main() {
     unsafe {
         let _x: Foo = mem::uninitialized();
index 6112e9b30e83799ed5d66a30cc60c3504976ac64..4dcf512d286ffdb471cf894f53534a63388ca2c7 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags:--test
 // normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
 
index 4247fdf989556ffaea6c2a30c51d5e16d394905a..d25ac633d7bf2b63d51b28435846d98145dafc47 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags:-Z unstable-options --show-coverage
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(extern_types)]
 
index 463617a1143df4795a7829b884577fa2a5724fa8..27bcf6f39383a604cb7120f09504d9dd2339e564 100644 (file)
@@ -1,4 +1,4 @@
 // compile-flags:-Z unstable-options --show-coverage
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // an empty crate still has one item to document: the crate root
index 5cd7f490d1a9a82c593d81cf4bf2fcbea7d60b02..e4171d7cfb2508d27651410aeb52343bbc341af0 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags:-Z unstable-options --show-coverage
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 //! (remember the crate root is still a module)
 
index b4adf45b90b8af983caf762c7dc32142d62f4f21..414d6f8405816bb5bacad1ad992132ead1f9d711 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags:-Z unstable-options --show-coverage
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(doc_keyword)]
 
index 9024185856daaec0fe9c91e31f1aed6d6f1d9610..6ff1bfa7275deabeb411b322959fd850a7c0bdc3 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags:-Z unstable-options --show-coverage --document-private-items
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(unused)]
 
index 3c1dd35dfe1ab8a66a59c7e9b783d496c10e24e1..b7d2b1dc10c62fdb36c4ab0e207904d14d1e9803 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags:-Z unstable-options --show-coverage
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 //! gotta make sure we can count statics and consts correctly, too
 
index 5f32d5b0cccc7933d4fcbc14f6e36031aa2a0aa6..40d68423f1bc6f3a34382530949bdd43f816a67a 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags:-Z unstable-options --show-coverage
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(trait_alias)]
 
index 6f6d5b8b654da6486db24bae68ce0a1843caa65d..21169eeb8c83e9677838b3345f3b427d57a9ae39 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![doc(no_default_passes, passes = "collapse-docs unindent-comments")]
 
index 20f761fcf4f3b97a84a266fb6b35a171d3f53171..67bd9f73eeb5b1972882ee21faaeae2d9ccdaae9 100644 (file)
@@ -1,6 +1,6 @@
 // ignore-tidy-cr
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // This file checks the spans of intra-link warnings in a file with CRLF line endings. The
 // .gitattributes file in this directory should enforce it.
index 26d4598f7ad1ee24887355dd0fb2863bb542c6de..20770efa95315d6c2e19b5899b60bf6827fbb02b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
        //! Test with [Foo::baz], [Bar::foo], ...
      //! , [Uniooon::X] and [Qux::Z].
index 924e0386d3191e00b3414db3392ee43af9e26133..2b02d47d4b851594baf940c05345d6b3b26b2e3c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 /// ```
 /// \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
index 5e5ddebe108845387808d56a696e836f2f26de39..1bb19353ba2f761073477f18d585258c8ff395de 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(private_doc_tests)]
 
index 0e5be3292c05341f7b640f33882d799251008f2b..6756d3b5a6051bdf89e451113b49ff7b2646234f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 pub trait Foo {
     /**
index e82a41b7a7b81cb63fa343db8a9f867422cb4157..ffa421d4f7f2d2d22b7e20957bcfa7eceb6bbc3a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // This test purpose is to check that unused_imports lint isn't fired
 // by rustdoc. Why would it? Because when rustdoc is running, it uses
index 9138dd50defa06146503c5691decd12b78a07ba0..653c004c04b231c2606ce5f879dca7d4fb0b8d4c 100644 (file)
@@ -105,6 +105,7 @@ fn add(self, _: B0) -> Self::Output {
 impl<U: Unsigned> Add<U> for UTerm {
     type Output = U;
     fn add(self, _: U) -> Self::Output {
+        #[allow(deprecated)]
         unsafe { ::std::mem::uninitialized() }
     }
 }
index 31ae0143d4771aee9492a0333a3ad102f2bc6568..32258792b6e8b88c601b50ac6d4a53b5e84d69be 100644 (file)
 /// Err("This is returned from `main`, leading to panic")?;
 /// Ok::<(), &'static str>(())
 /// ```
-///
-/// This also works with `Option<()>`s now:
-///
-/// ```rust
-/// Some(())
-/// ```
-///
-/// ```rust,should_panic
-/// let x: &[u32] = &[];
-/// let _ = x.iter().next()?;
-/// Some(())
-/// ```
 pub fn check_process_termination() {}
index 64664377cd9435c05b6e07336d0c60c64f26e998..2a57876f464c0b391600265ff4577788514116af 100644 (file)
@@ -8,8 +8,7 @@
 extern crate rustc;
 extern crate rustc_plugin;
 
-use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass,
-                  LintArray};
+use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
 use rustc_plugin::Registry;
 use syntax::ast;
 declare_tool_lint!(pub clippy::TEST_LINT, Warn, "Warn about stuff");
     Warn, "Warn about other stuff"
 );
 
-declare_lint_pass!(Pass => [TEST_LINT, TEST_GROUP]);
+declare_tool_lint!(
+    /// Some docs
+    pub rustc::TEST_RUSTC_TOOL_LINT,
+    Deny,
+    "Deny internal stuff"
+);
+
+declare_lint_pass!(Pass => [TEST_LINT, TEST_GROUP, TEST_RUSTC_TOOL_LINT]);
 
 impl EarlyLintPass for Pass {
     fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
index 3264099c876d0bbf178be2de6a1764078e1fa9ea..3786c6de7e78c400a827cf3f4e339e47d232e6c1 100644 (file)
@@ -7,7 +7,7 @@
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use std::collections::{HashMap, HashSet};
 
-#[deny(default_hash_types)]
+#[deny(rustc::default_hash_types)]
 fn main() {
     let _map: HashMap<String, String> = HashMap::default();
     //~^ ERROR Prefer FxHashMap over HashMap, it has better performance
index 64f322cb0c165b13ddfe34d7babb3019b3e636f0..c1762d31323cf8b2a1a83ac008ab9659083fa964 100644 (file)
@@ -7,8 +7,8 @@ LL |     let _map: HashMap<String, String> = HashMap::default();
 note: lint level defined here
   --> $DIR/default_hash_types.rs:10:8
    |
-LL | #[deny(default_hash_types)]
-   |        ^^^^^^^^^^^^^^^^^^
+LL | #[deny(rustc::default_hash_types)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
 
 error: Prefer FxHashMap over HashMap, it has better performance
diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs
new file mode 100644 (file)
index 0000000..48dd5b1
--- /dev/null
@@ -0,0 +1,53 @@
+// compile-flags: -Z unstable-options
+
+#![feature(rustc_private)]
+#![deny(rustc::lint_pass_impl_without_macro)]
+
+extern crate rustc;
+
+use rustc::lint::{LintArray, LintPass};
+use rustc::{declare_lint, declare_lint_pass, impl_lint_pass, lint_array};
+
+declare_lint! {
+    pub TEST_LINT,
+    Allow,
+    "test"
+}
+
+struct Foo;
+
+impl LintPass for Foo { //~ERROR implementing `LintPass` by hand
+    fn get_lints(&self) -> LintArray {
+        lint_array!(TEST_LINT)
+    }
+
+    fn name(&self) -> &'static str {
+        "Foo"
+    }
+}
+
+macro_rules! custom_lint_pass_macro {
+    () => {
+        struct Custom;
+
+        impl LintPass for Custom { //~ERROR implementing `LintPass` by hand
+            fn get_lints(&self) -> LintArray {
+                lint_array!(TEST_LINT)
+            }
+
+            fn name(&self) -> &'static str {
+                "Custom"
+            }
+        }
+    };
+}
+
+custom_lint_pass_macro!();
+
+struct Bar;
+
+impl_lint_pass!(Bar => [TEST_LINT]);
+
+declare_lint_pass!(Baz => [TEST_LINT]);
+
+fn main() {}
diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr
new file mode 100644 (file)
index 0000000..b439ae2
--- /dev/null
@@ -0,0 +1,26 @@
+error: implementing `LintPass` by hand
+  --> $DIR/lint_pass_impl_without_macro.rs:19:6
+   |
+LL | impl LintPass for Foo {
+   |      ^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/lint_pass_impl_without_macro.rs:4:9
+   |
+LL | #![deny(rustc::lint_pass_impl_without_macro)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
+
+error: implementing `LintPass` by hand
+  --> $DIR/lint_pass_impl_without_macro.rs:33:14
+   |
+LL |         impl LintPass for Custom {
+   |              ^^^^^^^^
+...
+LL | custom_lint_pass_macro!();
+   | -------------------------- in this macro invocation
+   |
+   = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
+
+error: aborting due to 2 previous errors
+
index 9534ddbbc64714eaac5e940d9db3fb945d086b50..7564c0245802ddcde7d526be33212f8a2daa41ee 100644 (file)
@@ -1,7 +1,7 @@
 // compile-flags: -Z unstable-options
 
 #![feature(rustc_private)]
-#![deny(ty_pass_by_reference)]
+#![deny(rustc::ty_pass_by_reference)]
 #![allow(unused)]
 
 extern crate rustc;
index 0f9f24b98a08c0c1e3101f89a9dbb7de318aebd7..d2ed6b6a19c31eb722b665c1e9d76b7b33c316bc 100644 (file)
@@ -7,8 +7,8 @@ LL |     ty_ref: &Ty<'_>,
 note: lint level defined here
   --> $DIR/pass_ty_by_ref.rs:4:9
    |
-LL | #![deny(ty_pass_by_reference)]
-   |         ^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustc::ty_pass_by_reference)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: passing `TyCtxt<'_>` by reference
   --> $DIR/pass_ty_by_ref.rs:15:18
index 56033100344a602fd090cc18c1d579215b0ed7c8..0040230ec7d7c6e4871c9f7f7dff7adcccaf78e8 100644 (file)
@@ -1,7 +1,7 @@
 // compile-flags: -Z unstable-options
 
 #![feature(rustc_private)]
-#![deny(usage_of_qualified_ty)]
+#![deny(rustc::usage_of_qualified_ty)]
 #![allow(unused)]
 
 extern crate rustc;
index c3642e6a4ba74968c31b1fdce68b7986826ec9a9..72c23f8cd3cac0fc36ed3e96d1167c582ff33957 100644 (file)
@@ -7,8 +7,8 @@ LL |     ty_q: ty::Ty<'_>,
 note: lint level defined here
   --> $DIR/qualified_ty_ty_ctxt.rs:4:9
    |
-LL | #![deny(usage_of_qualified_ty)]
-   |         ^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustc::usage_of_qualified_ty)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: usage of qualified `ty::TyCtxt<'_>`
   --> $DIR/qualified_ty_ty_ctxt.rs:27:16
index dba0db69b7f39543ca46f2216d97dc5022d7b8a3..c6bd122f4e5489dd8f8f61733bbeed25977fb545 100644 (file)
@@ -6,7 +6,7 @@
 
 use rustc::ty::{self, Ty, TyKind};
 
-#[deny(usage_of_ty_tykind)]
+#[deny(rustc::usage_of_ty_tykind)]
 fn main() {
     let sty = TyKind::Bool; //~ ERROR usage of `ty::TyKind::<kind>`
 
index 10229a331c285b4a7a6ce71b517a42a8d0a19a1a..8add4252c4103a36e0b5c46161546eef87bab52c 100644 (file)
@@ -7,8 +7,8 @@ LL |     let sty = TyKind::Bool;
 note: lint level defined here
   --> $DIR/ty_tykind_usage.rs:9:8
    |
-LL | #[deny(usage_of_ty_tykind)]
-   |        ^^^^^^^^^^^^^^^^^^
+LL | #[deny(rustc::usage_of_ty_tykind)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: usage of `ty::TyKind::<kind>`
   --> $DIR/ty_tykind_usage.rs:14:9
index 7eee47dcb5fc7e801eaf89a8c20b28df46f2455e..fe42113eb2ee9df6af0041c1183f4846bb8e096c 100644 (file)
@@ -1,7 +1,7 @@
 #![warn(anonymous_parameters)]
 // Test for the anonymous_parameters deprecation lint (RFC 1685)
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2015
 // run-rustfix
 
index 74de0c0b83407492b1b2840660a1d8a23d27537a..dc0357721ec73bf6ba559da92b3b0c7c9cea5ca8 100644 (file)
@@ -1,7 +1,7 @@
 #![warn(anonymous_parameters)]
 // Test for the anonymous_parameters deprecation lint (RFC 1685)
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2015
 // run-rustfix
 
index 0ce46d312afef865384080ab5011269b954719a9..403cdbd7ff330a2a95ff57a76e03240f7faec8a1 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait ConstDefault {
     const DEFAULT: Self;
index 1b3e978594d69b6e0957119534ab75753b87e47d..f5a9bac6e3549bb8f5f366194619db93bd2d8a4d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(associated_type_bounds)]
 
index a9081d50cfc5dd989c102a8dcca45b83bd9a50c6..b0703a4ee22b3b35fc792be2e98cd53a4a46c004 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(associated_type_bounds)]
 
index 1602fdd275a2e9e7e5e16883e680c5efdf6f2f04..34bc0c9acbf4c1075249d6c54dbe7a5e5b0b3794 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(associated_type_bounds)]
 
index 38261ca4570eb96d0475010c1fe7fc238064e1b1..29622c9d030a3514aeb93ed46ee16097aec0e356 100644 (file)
@@ -70,13 +70,6 @@ fn async_nonmove_block(x: u8) -> impl Future<Output = u8> {
     }
 }
 
-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
@@ -134,11 +127,15 @@ fn foo() {}
 }
 
 impl Foo {
-    async fn async_method(x: u8) -> u8 {
+    async fn async_assoc_item(x: u8) -> u8 {
         unsafe {
             unsafe_async_fn(x).await
         }
     }
+
+    async unsafe fn async_unsafe_assoc_item(x: u8) -> u8 {
+        unsafe_async_fn(x).await
+    }
 }
 
 fn test_future_yields_once_then_returns<F, Fut>(f: F)
@@ -176,16 +173,20 @@ macro_rules! test_with_borrow {
     test! {
         async_block,
         async_nonmove_block,
-        async_closure,
         async_fn,
         generic_async_fn,
         async_fn_with_internal_borrow,
-        Foo::async_method,
+        Foo::async_assoc_item,
         |x| {
             async move {
                 unsafe { unsafe_async_fn(x).await }
             }
         },
+        |x| {
+            async move {
+                unsafe { Foo::async_unsafe_assoc_item(x).await }
+            }
+        },
     }
     test_with_borrow! {
         async_block_with_borrow_named_lifetime,
diff --git a/src/test/ui/async-await/async-closure-matches-expr.rs b/src/test/ui/async-await/async-closure-matches-expr.rs
new file mode 100644 (file)
index 0000000..1c192a4
--- /dev/null
@@ -0,0 +1,12 @@
+// build-pass
+// edition:2018
+
+#![feature(async_await, async_closure)]
+
+macro_rules! match_expr {
+    ($x:expr) => {}
+}
+
+fn main() {
+    match_expr!(async || {});
+}
diff --git a/src/test/ui/async-await/async-closure.rs b/src/test/ui/async-await/async-closure.rs
new file mode 100644 (file)
index 0000000..f5dc9e2
--- /dev/null
@@ -0,0 +1,81 @@
+// run-pass
+
+// edition:2018
+// aux-build:arc_wake.rs
+
+#![feature(async_await, async_closure)]
+
+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_closure(x: u8) -> impl Future<Output = u8> {
+    (async move |x: u8| -> u8 {
+        wake_and_yield_once().await;
+        x
+    })(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);
+        )* }
+    }
+
+    test! {
+        async_closure,
+    }
+}
diff --git a/src/test/ui/async-await/async-error-span.rs b/src/test/ui/async-await/async-error-span.rs
new file mode 100644 (file)
index 0000000..d362348
--- /dev/null
@@ -0,0 +1,17 @@
+// edition:2018
+#![feature(async_await)]
+
+// Regression test for issue #62382
+
+use std::future::Future;
+
+fn get_future() -> impl Future<Output = ()> {
+    panic!()
+}
+
+async fn foo() {
+    let a; //~ ERROR type inside `async` object must be known in this context
+    get_future().await;
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/async-error-span.stderr b/src/test/ui/async-await/async-error-span.stderr
new file mode 100644 (file)
index 0000000..bd8966b
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0698]: type inside `async` object must be known in this context
+  --> $DIR/async-error-span.rs:13:9
+   |
+LL |     let a;
+   |         ^ cannot infer type
+   |
+note: the type is part of the `async` object because of this `await`
+  --> $DIR/async-error-span.rs:14:5
+   |
+LL |     get_future().await;
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0698`.
diff --git a/src/test/ui/async-await/async-fn-multiple-lifetimes.rs b/src/test/ui/async-await/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-await/async-fn-multiple-lifetimes.stderr b/src/test/ui/async-await/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
-
index 8db7631ef41086cd70636b123ef234748a49c2cc..447e40dddd910f4b47aed0035bc157c645ed8e04 100644 (file)
@@ -1,6 +1,6 @@
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 #![allow(dead_code)]
 
 struct HasLifetime<'a>(&'a bool);
index f07fc2fceb5b6aacd9829014e88bb8fcd8b7613c..5e1b8c6280b81a7e94c99945cbf7c0bf31ee22d5 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 // compile-flags: --crate-type lib
 
index f375d58d98495997e6bd0ece6709e5e2f0bc7edd..a6f0211e41f98e369990176ff42af9fd4e5ef2bb 100644 (file)
@@ -1,7 +1,7 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 macro_rules! match_expr {
     ($x:expr) => {}
@@ -9,5 +9,4 @@ macro_rules! match_expr {
 
 fn main() {
     match_expr!(async {});
-    match_expr!(async || {});
 }
index e94a5f0853d72c7d4cbcede4469c2af31ed0d02c..f7dc874affd268170bc6c58e4ef5add1651e78ec 100644 (file)
@@ -1,7 +1,7 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 trait MyClosure {
     type Args;
@@ -20,7 +20,7 @@ async fn get_future<C: ?Sized + MyClosure>(_stream: MyStream<C>) {}
 
 async fn f() {
     let messages: MyStream<dyn FnMut()> = unimplemented!();
-    await!(get_future(messages));
+    get_future(messages).await;
 }
 
 fn main() {}
index f59f1160e703e4bd82eec71654567c737666ee61..92f3210ac89a38df7eb4ddf6f06def3d845cdf9b 100644 (file)
@@ -1,7 +1,7 @@
 // edition:2018
 
 #![allow(non_camel_case_types)]
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 mod outer_mod {
     pub mod await { //~ ERROR expected identifier, found reserved keyword `await`
index 7d8b7a257dad973c92fcfd5580f4be9551d85995..c37835d73e92be5b38148a95ab74ccf5b6b53cfe 100644 (file)
@@ -3,7 +3,7 @@
 // edition:2018
 // aux-build:arc_wake.rs
 
-#![feature(async_await, await_macro)]
+#![feature(async_await, async_closure, await_macro)]
 
 extern crate arc_wake;
 
diff --git a/src/test/ui/async-await/await-unsize.rs b/src/test/ui/async-await/await-unsize.rs
new file mode 100644 (file)
index 0000000..d5e2125
--- /dev/null
@@ -0,0 +1,16 @@
+// Regression test for #62312
+
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+async fn make_boxed_object() -> Box<dyn Send> {
+    Box::new(()) as _
+}
+
+async fn await_object() {
+    let _ = make_boxed_object().await;
+}
+
+fn main() {}
index c2b59eecb999304092f9ca8ccbea128017293d6d..dfd8b2e361eef1b1e0cd8ea77a309eb7989ee354 100644 (file)
@@ -3,7 +3,7 @@
 // run-pass
 
 #![allow(unused_variables)]
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 // 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.
index 708c570498460147de3cac9a1f6a884452d7966b..2a74485afb45094803b030dcdde26ebacbe37c17 100644 (file)
@@ -3,7 +3,7 @@
 // run-pass
 
 #![allow(unused_variables)]
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 // 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.
index e1111f9e0e4b952f26e494921bd24334f3ffdf6f..a5bc1810154750cf53a4553cd24958c203d4d44c 100644 (file)
@@ -28,6 +28,12 @@ macro_rules! accept_item { ($x:item) => {} }
         async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
     }
 
+    accept_item! {
+        impl Foo {
+            async fn bar() {} //~ 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
     };
index 05a06124dc220d4d519057f45c07aea6b04a9026..efb4462095d0d7e8b364ede027a5c7429575537f 100644 (file)
@@ -23,7 +23,19 @@ 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
+  --> $DIR/edition-deny-async-fns-2015.rs:16: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[E0670]: `async fn` is not permitted in the 2015 edition
+  --> $DIR/edition-deny-async-fns-2015.rs:38:9
    |
 LL |         async fn bar() {}
    |         ^^^^^
@@ -35,10 +47,10 @@ LL |         async fn foo() {}
    |         ^^^^^
 
 error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:16:5
+  --> $DIR/edition-deny-async-fns-2015.rs:33:13
    |
-LL |     async fn foo() {}
-   |     ^^^^^
+LL |             async fn bar() {}
+   |             ^^^^^
 
 error[E0706]: trait fns cannot be declared `async`
   --> $DIR/edition-deny-async-fns-2015.rs:20:5
@@ -46,12 +58,6 @@ error[E0706]: trait fns cannot be declared `async`
 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
+error: aborting due to 10 previous errors
 
 For more information about this error, try `rustc --explain E0670`.
diff --git a/src/test/ui/async-await/feature-async-closure.rs b/src/test/ui/async-await/feature-async-closure.rs
new file mode 100644 (file)
index 0000000..d07116b
--- /dev/null
@@ -0,0 +1,8 @@
+// edition:2018
+// gate-test-async_closure
+
+fn f() {
+    let _ = async || {}; //~ ERROR async closures are unstable
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/feature-async-closure.stderr b/src/test/ui/async-await/feature-async-closure.stderr
new file mode 100644 (file)
index 0000000..61909f8
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0658]: async closures are unstable
+  --> $DIR/feature-async-closure.rs:5:13
+   |
+LL |     let _ = async || {};
+   |             ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/62290
+   = help: add #![feature(async_closure)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
index 913f1435c6adf5b77fed4a81b5ae5fe3424493cf..8b60f2f82f1d6c83fd41d778ffdc3d41bfd1a44c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 // compile-flags: --crate-type lib
 
index bccdf0113ff69c948d9d8ac97309cf247b7ac31c..a18fad8bb9150b8affd7ded502f34ea924d590f0 100644 (file)
@@ -3,7 +3,7 @@
 // while those two fields were at the same offset (which is impossible).
 // That is, memory ordering of `(X, ())`, but offsets of `((), X)`.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
 #![feature(async_await)]
index 2157cf7d4f7abe9aafce3e252adf2d7876df77ae..c57dc6b0ef6f9e63a173bf4aee230453b69ffdcd 100644 (file)
@@ -1,7 +1,7 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(arbitrary_self_types, async_await, await_macro)]
+#![feature(arbitrary_self_types, async_await)]
 
 use std::task::{self, Poll};
 use std::future::Future;
@@ -37,11 +37,11 @@ fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context) -> Poll<R> {
 async fn __receive<WantFn, Fut>(want: WantFn) -> ()
     where Fut: Future<Output = ()>, WantFn: Fn(&Box<dyn Send + 'static>) -> Fut,
 {
-    await!(lazy(|_| ()));
+    lazy(|_| ()).await;
 }
 
 pub fn basic_spawn_receive() {
-    async { await!(__receive(|_| async { () })) };
+    async { __receive(|_| async { () }).await };
 }
 
 fn main() {}
index ad18f411875690413a23a64f3510ad54afb7215d..040989b33fc1a2746f0778e306d3285f32a8ee46 100644 (file)
@@ -1,7 +1,7 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 use std::sync::Arc;
 
index 4572e543f22de015b7c14b6bea6017aa17c54c33..4f383a51a88e7ecfb0e7884858e4c8c9822ecb83 100644 (file)
@@ -1,13 +1,13 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 use std::future::Future;
 
 #[allow(unused)]
 async fn foo<F: Future<Output = i32>>(x: &i32, future: F) -> i32 {
-    let y = await!(future);
+    let y = future.await;
     *x + y
 }
 
index 99d87b2273c2f2bfd20cb80c1f4cb5da1c84873d..47744aeea603499e84dedea88f447e5fd372ae6b 100644 (file)
@@ -1,7 +1,7 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 struct Xyz {
     a: u64,
index c758244002ff6e14930e187b11eab12f68a31096..9334ddb0af588e2335939bdef5cd5dc6c00bfabb 100644 (file)
@@ -1,7 +1,7 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 use std::future::Future;
 
index 31e7a65dc98e34c8f6f342067592a66e3637b343..1b843720102ab6a514a8aa32d2f9ccea6de7ddad 100644 (file)
@@ -2,7 +2,7 @@
 
 // compile-flags: --edition=2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await)]
 
 pub enum Uninhabited { }
 
@@ -15,7 +15,7 @@ async fn noop() { }
 #[allow(unused)]
 async fn contains_never() {
     let error = uninhabited_async();
-    await!(noop());
+    noop().await;
     let error2 = error;
 }
 
index f603c5bd3f9462b7e4c9027095eb346628da3e01..e4bdc96511e3c3f793322fb5dc274b2e63f683e7 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
 #![feature(async_await)]
index a4fe86501299fc80009856d93a13e32fe2c8ef3e..2328ceb144f205ec9b842d8742ce732ebc170369 100644 (file)
@@ -1,6 +1,6 @@
 // Test that existential types are allowed to contain late-bound regions.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
 #![feature(async_await, existential_type)]
index ecb80803383b4c5bd253f3186426ae003b281cab..99cdcbafc766fcb81de529a52c30ae472ac993d4 100644 (file)
@@ -1,5 +1,5 @@
 // aux-build:issue-60674.rs
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 #![feature(async_await)]
 
index da8b22bc104bf0ee4f582f25e48febe1d5618908..77ecc47dfef12cf66a9acdb5bf17ad1cacb4d900 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 //
 // Tests that we properly handle StorageDead/StorageLives for temporaries
diff --git a/src/test/ui/async-await/issues/issue-62009-1.rs b/src/test/ui/async-await/issues/issue-62009-1.rs
new file mode 100644 (file)
index 0000000..ac6605b
--- /dev/null
@@ -0,0 +1,17 @@
+// edition:2018
+
+#![feature(async_await)]
+
+async fn print_dur() {}
+
+fn main() {
+    async { let (); }.await;
+    //~^ ERROR `await` is only allowed inside `async` functions and blocks
+    async {
+    //~^ ERROR `await` is only allowed inside `async` functions and blocks
+        let task1 = print_dur().await;
+    }.await;
+    (|_| 2333).await;
+    //~^ ERROR `await` is only allowed inside `async` functions and blocks
+    //~^^ ERROR
+}
diff --git a/src/test/ui/async-await/issues/issue-62009-1.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr
new file mode 100644 (file)
index 0000000..2bbb6d0
--- /dev/null
@@ -0,0 +1,40 @@
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/issue-62009-1.rs:8:5
+   |
+LL | fn main() {
+   |    ---- this is not `async`
+LL |     async { let (); }.await;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/issue-62009-1.rs:10:5
+   |
+LL |   fn main() {
+   |      ---- this is not `async`
+...
+LL | /     async {
+LL | |
+LL | |         let task1 = print_dur().await;
+LL | |     }.await;
+   | |___________^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/issue-62009-1.rs:14:5
+   |
+LL | fn main() {
+   |    ---- this is not `async`
+...
+LL |     (|_| 2333).await;
+   |     ^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]: std::future::Future` is not satisfied
+  --> $DIR/issue-62009-1.rs:14:5
+   |
+LL |     (|_| 2333).await;
+   |     ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]`
+   |
+   = note: required by `std::future::poll_with_tls_context`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/issues/issue-62009-2.rs b/src/test/ui/async-await/issues/issue-62009-2.rs
new file mode 100644 (file)
index 0000000..52b62ea
--- /dev/null
@@ -0,0 +1,10 @@
+// edition:2018
+
+#![feature(async_await, async_closure)]
+
+async fn print_dur() {}
+
+fn main() {
+    (async || 2333)().await;
+    //~^ ERROR `await` is only allowed inside `async` functions and blocks
+}
diff --git a/src/test/ui/async-await/issues/issue-62009-2.stderr b/src/test/ui/async-await/issues/issue-62009-2.stderr
new file mode 100644 (file)
index 0000000..79b6803
--- /dev/null
@@ -0,0 +1,10 @@
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/issue-62009-2.rs:8:5
+   |
+LL | fn main() {
+   |    ---- this is not `async`
+LL |     (async || 2333)().await;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/issues/issue-62009.rs b/src/test/ui/async-await/issues/issue-62009.rs
deleted file mode 100644 (file)
index e2d58ca..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// edition:2018
-
-#![feature(async_await)]
-
-async fn print_dur() {}
-
-fn main() {
-    async { let (); }.await;
-    //~^ ERROR `await` is only allowed inside `async` functions and blocks
-    async {
-    //~^ ERROR `await` is only allowed inside `async` functions and blocks
-        let task1 = print_dur().await;
-    }.await;
-    (async || 2333)().await;
-    //~^ ERROR `await` is only allowed inside `async` functions and blocks
-    (|_| 2333).await;
-    //~^ ERROR `await` is only allowed inside `async` functions and blocks
-    //~^^ ERROR
-}
diff --git a/src/test/ui/async-await/issues/issue-62009.stderr b/src/test/ui/async-await/issues/issue-62009.stderr
deleted file mode 100644 (file)
index 53d1f34..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009.rs:8:5
-   |
-LL | fn main() {
-   |    ---- this is not `async`
-LL |     async { let (); }.await;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009.rs:10:5
-   |
-LL |   fn main() {
-   |      ---- this is not `async`
-...
-LL | /     async {
-LL | |
-LL | |         let task1 = print_dur().await;
-LL | |     }.await;
-   | |___________^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009.rs:14:5
-   |
-LL | fn main() {
-   |    ---- this is not `async`
-...
-LL |     (async || 2333)().await;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009.rs:16:5
-   |
-LL | fn main() {
-   |    ---- this is not `async`
-...
-LL |     (|_| 2333).await;
-   |     ^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
-
-error[E0277]: the trait bound `[closure@$DIR/issue-62009.rs:16:5: 16:15]: std::future::Future` is not satisfied
-  --> $DIR/issue-62009.rs:16:5
-   |
-LL |     (|_| 2333).await;
-   |     ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009.rs:16:5: 16:15]`
-   |
-   = note: required by `std::future::poll_with_tls_context`
-
-error: aborting due to 5 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/multiple-lifetimes/elided.rs b/src/test/ui/async-await/multiple-lifetimes/elided.rs
new file mode 100644 (file)
index 0000000..45f3170
--- /dev/null
@@ -0,0 +1,12 @@
+// edition:2018
+// run-pass
+
+// Test that we can use async fns with multiple arbitrary lifetimes.
+
+#![feature(async_await)]
+
+async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
+
+fn main() {
+    let _ = multiple_elided_lifetimes(&22, &44);
+}
diff --git a/src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs b/src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs
new file mode 100644 (file)
index 0000000..a7254ce
--- /dev/null
@@ -0,0 +1,14 @@
+// edition:2018
+// run-pass
+
+// Test that we can use async fns with multiple arbitrary lifetimes.
+
+#![feature(async_await)]
+
+async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8, _: fn(&u8)) {}
+
+fn gimme(_: &u8) { }
+
+fn main() {
+    let _ = multiple_named_lifetimes(&22, &44, gimme);
+}
diff --git a/src/test/ui/async-await/multiple-lifetimes/hrtb.rs b/src/test/ui/async-await/multiple-lifetimes/hrtb.rs
new file mode 100644 (file)
index 0000000..589e260
--- /dev/null
@@ -0,0 +1,17 @@
+// edition:2018
+// run-pass
+
+// Test that we can use async fns with multiple arbitrary lifetimes.
+
+#![feature(async_await)]
+#![allow(dead_code)]
+
+use std::ops::Add;
+
+async fn multiple_hrtb_and_single_named_lifetime_ok<'c>(
+    _: impl for<'a> Add<&'a u8>,
+    _: impl for<'b> Add<&'b u8>,
+    _: &'c u8,
+) {}
+
+fn main() {}
diff --git a/src/test/ui/async-await/multiple-lifetimes/named.rs b/src/test/ui/async-await/multiple-lifetimes/named.rs
new file mode 100644 (file)
index 0000000..7d13d48
--- /dev/null
@@ -0,0 +1,12 @@
+// edition:2018
+// run-pass
+
+// Test that we can use async fns with multiple arbitrary lifetimes.
+
+#![feature(arbitrary_self_types, async_await, await_macro)]
+
+async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}
+
+fn main() {
+    let _ = multiple_named_lifetimes(&22, &44);
+}
diff --git a/src/test/ui/async-await/multiple-lifetimes/partial-relation.rs b/src/test/ui/async-await/multiple-lifetimes/partial-relation.rs
new file mode 100644 (file)
index 0000000..903c439
--- /dev/null
@@ -0,0 +1,15 @@
+// edition:2018
+// run-pass
+
+#![feature(async_await)]
+
+async fn lotsa_lifetimes<'a, 'b, 'c>(a: &'a u32, b: &'b u32, c: &'c u32) -> (&'a u32, &'b u32)
+    where 'b: 'a
+{
+    drop((a, c));
+    (b, b)
+}
+
+fn main() {
+    let _ = lotsa_lifetimes(&22, &44, &66);
+}
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs
new file mode 100644 (file)
index 0000000..0862231
--- /dev/null
@@ -0,0 +1,18 @@
+// edition:2018
+// run-pass
+
+// Test that a feature gate is needed to use `impl Trait` as the
+// return type of an async.
+
+#![feature(async_await, member_constraints)]
+
+trait Trait<'a, 'b> { }
+impl<T> Trait<'_, '_> for T { }
+
+async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
+    (a, b)
+}
+
+fn main() {
+    let _ = async_ret_impl_trait(&22, &44);
+}
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs
new file mode 100644 (file)
index 0000000..08ecea4
--- /dev/null
@@ -0,0 +1,18 @@
+// edition:2018
+
+// Test that a feature gate is needed to use `impl Trait` as the
+// return type of an async.
+
+#![feature(async_await)]
+
+trait Trait<'a, 'b> { }
+impl<T> Trait<'_, '_> for T { }
+
+async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
+    //~^ ERROR ambiguous lifetime bound
+    (a, b)
+}
+
+fn main() {
+    let _ = async_ret_impl_trait(&22, &44);
+}
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr
new file mode 100644 (file)
index 0000000..de2c85d
--- /dev/null
@@ -0,0 +1,10 @@
+error: ambiguous lifetime bound in `impl Trait`
+  --> $DIR/ret-impl-trait-no-fg.rs:11:64
+   |
+LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
+   |                                                                ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other
+   |
+   = help: add #![feature(member_constraints)] to the crate attributes to enable
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
new file mode 100644 (file)
index 0000000..b4d5d3e
--- /dev/null
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+  --> $DIR/ret-impl-trait-one.rs:12:80
+   |
+LL |   async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
+   |  ________________________________--__--__________________________________________^
+   | |                                |   |
+   | |                                |   lifetime `'b` defined here
+   | |                                lifetime `'a` defined here
+LL | |
+LL | |     (a, b)
+LL | | }
+   | |_^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs
new file mode 100644 (file)
index 0000000..e1b7146
--- /dev/null
@@ -0,0 +1,27 @@
+// edition:2018
+
+// Test that a feature gate is needed to use `impl Trait` as the
+// return type of an async.
+
+#![feature(async_await, member_constraints)]
+
+trait Trait<'a> { }
+impl<T> Trait<'_> for T { }
+
+// Only `'a` permitted in return type, not `'b`.
+async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
+    //~^ ERROR lifetime mismatch
+    (a, b)
+}
+
+// As above, but `'b: 'a`, so return type can be inferred to `(&'a u8,
+// &'a u8)`.
+async fn async_ret_impl_trait2<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a>
+where
+    'b: 'a,
+{
+    (a, b)
+}
+
+fn main() {
+}
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr
new file mode 100644 (file)
index 0000000..f6d6115
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0623]: lifetime mismatch
+  --> $DIR/ret-impl-trait-one.rs:12:65
+   |
+LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
+   |                                           ------                ^^^^^^^^^^^^^^
+   |                                           |                     |
+   |                                           |                     ...but data from `b` is returned here
+   |                                           this parameter and the return type are declared with different lifetimes...
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-ref.rs b/src/test/ui/async-await/multiple-lifetimes/ret-ref.rs
new file mode 100644 (file)
index 0000000..98da901
--- /dev/null
@@ -0,0 +1,46 @@
+// edition:2018
+
+// Test that we get the expected borrow check errors when an async
+// function (which takes multiple lifetimes) only returns data from
+// one of them.
+
+#![feature(async_await)]
+
+async fn multiple_named_lifetimes<'a, 'b>(a: &'a u8, _: &'b u8) -> &'a u8 {
+    a
+}
+
+// Both are borrowed whilst the future is live.
+async fn future_live() {
+    let mut a = 22;
+    let mut b = 44;
+    let future = multiple_named_lifetimes(&a, &b);
+    a += 1; //~ ERROR cannot assign
+    b += 1; //~ ERROR cannot assign
+    let p = future.await;
+    drop(p);
+}
+
+// Just the return value is live after future is awaited.
+async fn just_return_live() {
+    let mut a = 22;
+    let mut b = 44;
+    let future = multiple_named_lifetimes(&a, &b);
+    let p = future.await;
+    a += 1; //~ ERROR cannot assign
+    b += 1;
+    drop(p);
+}
+
+// Once `p` is dead, both `a` and `b` are unborrowed.
+async fn after_both_dead() {
+    let mut a = 22;
+    let mut b = 44;
+    let future = multiple_named_lifetimes(&a, &b);
+    let p = future.await;
+    drop(p);
+    a += 1;
+    b += 1;
+}
+
+fn main() { }
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr
new file mode 100644 (file)
index 0000000..fe70d35
--- /dev/null
@@ -0,0 +1,37 @@
+error[E0506]: cannot assign to `a` because it is borrowed
+  --> $DIR/ret-ref.rs:18:5
+   |
+LL |     let future = multiple_named_lifetimes(&a, &b);
+   |                                           -- borrow of `a` occurs here
+LL |     a += 1;
+   |     ^^^^^^ assignment to borrowed `a` occurs here
+LL |     b += 1;
+LL |     let p = future.await;
+   |             ------ borrow later used here
+
+error[E0506]: cannot assign to `b` because it is borrowed
+  --> $DIR/ret-ref.rs:19:5
+   |
+LL |     let future = multiple_named_lifetimes(&a, &b);
+   |                                               -- borrow of `b` occurs here
+LL |     a += 1;
+LL |     b += 1;
+   |     ^^^^^^ assignment to borrowed `b` occurs here
+LL |     let p = future.await;
+   |             ------ borrow later used here
+
+error[E0506]: cannot assign to `a` because it is borrowed
+  --> $DIR/ret-ref.rs:30:5
+   |
+LL |     let future = multiple_named_lifetimes(&a, &b);
+   |                                           -- borrow of `a` occurs here
+LL |     let p = future.await;
+LL |     a += 1;
+   |     ^^^^^^ assignment to borrowed `a` occurs here
+LL |     b += 1;
+LL |     drop(p);
+   |          - borrow later used here
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0506`.
diff --git a/src/test/ui/async-await/multiple-lifetimes/variance.rs b/src/test/ui/async-await/multiple-lifetimes/variance.rs
new file mode 100644 (file)
index 0000000..b52ad17
--- /dev/null
@@ -0,0 +1,18 @@
+// edition:2018
+// run-pass
+
+// Test for async fn where the parameters have distinct lifetime
+// parameters that appear in all possible variances.
+
+#![feature(async_await)]
+
+#[allow(dead_code)]
+async fn lotsa_lifetimes<'a, 'b, 'c>(_: fn(&'a u8), _: fn(&'b u8) -> &'b u8, _: fn() -> &'c u8) { }
+
+fn take_any(_: &u8) { }
+fn identify(x: &u8) -> &u8 { x }
+fn give_back() -> &'static u8 { &22 }
+
+fn main() {
+    let _ = lotsa_lifetimes(take_any, identify, give_back);
+}
index 345f19b06233bfcfb8b23f1643375d9475f5035b..62d4b3fb6f23b9a82970b461674056ef79c03b5b 100644 (file)
@@ -1,6 +1,6 @@
 // edition:2018
 
-#![feature(async_await, await_macro)]
+#![feature(async_await, async_closure)]
 
 fn main() {
     let _ = async |x: u8| {};
diff --git a/src/test/ui/async-await/no-unsafe-async.rs b/src/test/ui/async-await/no-unsafe-async.rs
new file mode 100644 (file)
index 0000000..81e0cd7
--- /dev/null
@@ -0,0 +1,11 @@
+// edition:2018
+
+struct S;
+
+impl S {
+    #[cfg(FALSE)]
+    unsafe async fn g() {} //~ ERROR expected one of `extern` or `fn`, found `async`
+}
+
+#[cfg(FALSE)]
+unsafe async fn f() {} //~ ERROR expected one of `extern`, `fn`, or `{`, found `async`
diff --git a/src/test/ui/async-await/no-unsafe-async.stderr b/src/test/ui/async-await/no-unsafe-async.stderr
new file mode 100644 (file)
index 0000000..c339c7c
--- /dev/null
@@ -0,0 +1,14 @@
+error: expected one of `extern` or `fn`, found `async`
+  --> $DIR/no-unsafe-async.rs:7:12
+   |
+LL |     unsafe async fn g() {}
+   |            ^^^^^ expected one of `extern` or `fn` here
+
+error: expected one of `extern`, `fn`, or `{`, found `async`
+  --> $DIR/no-unsafe-async.rs:11:8
+   |
+LL | unsafe async fn f() {}
+   |        ^^^^^ expected one of `extern`, `fn`, or `{` here
+
+error: aborting due to 2 previous errors
+
index a4e080119345e8f1791f4e77496f4d468d98bcb3..54f3339870bda4012bc6b8b3a2404a47028d190b 100644 (file)
@@ -2,10 +2,10 @@
 // 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)]
+#![feature(async_await)]
 
 async fn recursive_async_function() -> () { //~ ERROR
-    await!(recursive_async_function());
+    recursive_async_function().await;
 }
 
 fn main() {}
diff --git a/src/test/ui/async-await/suggest-missing-await-closure.fixed b/src/test/ui/async-await/suggest-missing-await-closure.fixed
new file mode 100644 (file)
index 0000000..60c9a85
--- /dev/null
@@ -0,0 +1,23 @@
+// edition:2018
+// run-rustfix
+
+#![feature(async_await, async_closure)]
+
+fn take_u32(_x: u32) {}
+
+async fn make_u32() -> u32 {
+    22
+}
+
+#[allow(unused)]
+async fn suggest_await_in_async_closure() {
+    async || {
+        let x = make_u32();
+        take_u32(x.await)
+        //~^ ERROR mismatched types [E0308]
+        //~| HELP consider using `.await` here
+        //~| SUGGESTION x.await
+    };
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/suggest-missing-await-closure.rs b/src/test/ui/async-await/suggest-missing-await-closure.rs
new file mode 100644 (file)
index 0000000..cb992a2
--- /dev/null
@@ -0,0 +1,23 @@
+// edition:2018
+// run-rustfix
+
+#![feature(async_await, async_closure)]
+
+fn take_u32(_x: u32) {}
+
+async fn make_u32() -> u32 {
+    22
+}
+
+#[allow(unused)]
+async fn suggest_await_in_async_closure() {
+    async || {
+        let x = make_u32();
+        take_u32(x)
+        //~^ ERROR mismatched types [E0308]
+        //~| HELP consider using `.await` here
+        //~| SUGGESTION x.await
+    };
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/suggest-missing-await-closure.stderr b/src/test/ui/async-await/suggest-missing-await-closure.stderr
new file mode 100644 (file)
index 0000000..487ca6c
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+  --> $DIR/suggest-missing-await-closure.rs:16:18
+   |
+LL |         take_u32(x)
+   |                  ^
+   |                  |
+   |                  expected u32, found opaque type
+   |                  help: consider using `.await` here: `x.await`
+   |
+   = note: expected type `u32`
+              found type `impl std::future::Future`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
index 282be368c69cdaeb24b41264e214834eadb4462f..aa032682be82249e6df7ef28d5f936fd67a2ca16 100644 (file)
@@ -18,15 +18,4 @@ async fn suggest_await_in_async_fn() {
     //~| SUGGESTION x.await
 }
 
-#[allow(unused)]
-async fn suggest_await_in_async_closure() {
-    async || {
-        let x = make_u32();
-        take_u32(x.await)
-        //~^ ERROR mismatched types [E0308]
-        //~| HELP consider using `.await` here
-        //~| SUGGESTION x.await
-    };
-}
-
 fn main() {}
index 36103f050c1472e2a525b184c049546fa5613778..2ca814fbb22b5d57a6d54176c6aecdc2ef324def 100644 (file)
@@ -18,15 +18,4 @@ async fn suggest_await_in_async_fn() {
     //~| SUGGESTION x.await
 }
 
-#[allow(unused)]
-async fn suggest_await_in_async_closure() {
-    async || {
-        let x = make_u32();
-        take_u32(x)
-        //~^ ERROR mismatched types [E0308]
-        //~| HELP consider using `.await` here
-        //~| SUGGESTION x.await
-    };
-}
-
 fn main() {}
index 59c20dcfbc9473545da76246499188045b449071..9bae7150276a865ba90cd6647d18566ec57bbc8f 100644 (file)
@@ -10,18 +10,6 @@ LL |     take_u32(x)
    = note: expected type `u32`
               found type `impl std::future::Future`
 
-error[E0308]: mismatched types
-  --> $DIR/suggest-missing-await.rs:25:18
-   |
-LL |         take_u32(x)
-   |                  ^
-   |                  |
-   |                  expected u32, found opaque type
-   |                  help: consider using `.await` here: `x.await`
-   |
-   = note: expected type `u32`
-              found type `impl std::future::Future`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0308`.
index fc040bd1a5d10a01dc81aa4ac19103d224335d7b..e1588aadab62c03d12d2d285d5434a8957e316bc 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 #![feature(rustc_attrs)]
index c7fad3802e9d6d2ee778b8bc4961121faafc49b3..c1f667372f5158c74de4bc387584daf46053b341 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 #![feature(rustc_attrs)]
index d9cb551096092f6298d79ea32c6a42afd97c4180..8119df0c40cb0c6aad4105ca9b69f52eab860b3a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 #![feature(rustc_attrs)]
index ca5fdd9da859bae78bde7f472c409a9b310ec95e..df9c8d894652b5b280d5df09b5568c270f05a273 100644 (file)
@@ -6,10 +6,8 @@
 
 struct RefIntPair<'a, 'b>(&'a u32, &'b u32);
 
-impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> {
+impl<#[rustc_dummy] 'a, 'b, #[oops]> RefIntPair<'a, 'b> {
     //~^ ERROR trailing attribute after generic parameter
 }
 
-fn main() {
-
-}
+fn main() {}
index 55e7a9877846f271a79ac78561a15a13a9823d9c..5b4f5222a2b1404129d01d03eb521ad4221fdc41 100644 (file)
@@ -1,8 +1,8 @@
 error: trailing attribute after generic parameter
-  --> $DIR/attrs-with-no-formal-in-generics-1.rs:9:25
+  --> $DIR/attrs-with-no-formal-in-generics-1.rs:9:29
    |
-LL | impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> {
-   |                         ^^^^^^^ attributes must go before parameters
+LL | impl<#[rustc_dummy] 'a, 'b, #[oops]> RefIntPair<'a, 'b> {
+   |                             ^^^^^^^ attributes must go before parameters
 
 error: aborting due to previous error
 
index c795612acf08c13a59b92d967a4d332905182ec9..d1d044035260bf3fdadc7b641a42fc474f29910f 100644 (file)
@@ -6,7 +6,7 @@
 
 struct RefAny<'a, T>(&'a T);
 
-impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {}
+impl<#[rustc_dummy] 'a, #[rustc_dummy] T, #[oops]> RefAny<'a, T> {}
 //~^ ERROR trailing attribute after generic parameter
 
 fn main() {}
index acd0ae3678a7c275d10f09d059b3cc1b30eeb670..fce3ff7de78e88ec4a18e8fb712d2a7c45ca9fe4 100644 (file)
@@ -1,8 +1,8 @@
 error: trailing attribute after generic parameter
-  --> $DIR/attrs-with-no-formal-in-generics-2.rs:9:35
+  --> $DIR/attrs-with-no-formal-in-generics-2.rs:9:43
    |
-LL | impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {}
-   |                                   ^^^^^^^ attributes must go before parameters
+LL | impl<#[rustc_dummy] 'a, #[rustc_dummy] T, #[oops]> RefAny<'a, T> {}
+   |                                           ^^^^^^^ attributes must go before parameters
 
 error: aborting due to previous error
 
index 7808367f2c10f9e3b77e09d47e1c8f4bd5cabb9c..027b701e591babba97bf4d5ae52a733b4dcad9d4 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pp-exact - Make sure we actually print the attributes
 
 #![feature(rustc_attrs)]
index 348c70f35c328c8d359c37e883de70ca951e65cc..6aba6b89427e4b2429469e2f805fd58d84fbebce 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 
index 72c9a35dc07f049650835e28fe3eba078f7d5e08..c760a28ecf0bae1910ece6ef523c3a3c153c1290 100644 (file)
@@ -2,7 +2,7 @@
 // for completeness since .rs files linked from .rc files support this
 // notation to specify their module's attributes
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 
index 2d608acc71f71dd1c2d34816ca0a446d21d7bcf5..67439718bd3ccb2629635612fc4440916ff5c385 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pp-exact - Make sure we print all the attributes
 // pretty-expanded FIXME #23616
 
index a910340f4a06d01e7bca58bd59bc4d4f5765e2af..ffcdeb52a042f1383d6ef675afa87bde294f7349 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pp-exact - Make sure we actually print the attributes
 // pretty-expanded FIXME #23616
 
index 0716fcf7f26a8b909f1cc99c1cc3fc4198839d70..cc43210d8e3b9407044fc0bcfde577bcff7b9051 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Bastion of the Turbofish
 // ------------------------
index 6d91fd3508a867916bded4c64ee5bc22d4caee84..1d98067ce738ce396e1f1643190368299b702eb6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // rust-lang/rust#55552: The strategy pnkfelix landed in PR #55274
 // (for ensuring that NLL respects user-provided lifetime annotations)
index 5d084248a7f993d6d4b84aaef5f468db4ad70350..a4d6e9b777f0262b5f528a91ed696a2a9f82dcf3 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(exclusive_range_pattern)]
 #![warn(unreachable_patterns)]
index 1bfaecd16c0b698ee95cbeef5cbbee02e1be83bb..5f02e642defca750a21b28027c91237b0c04f85e 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(warnings)]
 
index 3e42284b72c3f8ed8f9eed17f3cf04c6cd1fb4e5..0ee738c2c2f3938497fc0954464b2c4b5a7e8f60 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn with_closure<F, A>(_: F)
     where F: FnOnce(A, &u32)
index cf417d7c2a8e8dc9ea893380872202912daa37dd..15711da4b0fbb6037d386e2a85dd145682feac58 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn with_closure<F, A>(_: F)
     where F: FnOnce(A, &u32)
index 477eb40c57e1fe3fd5e061fb2d38dc7ba78d935c..f7b4f2b24549e4a723e3c648346c2ca3348404c4 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn test<F: Fn(&u64, &u64)>(f: F) {}
 
index db9c0a6ef3be49e6935403e7b1f344b4629c54ed..db36985afe7a8ff0caf303a1bdb0277ea1e58317 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(const_err)]
 
index ff6d54468b8ec8c60d21f66731ed947558eb4121..b9bcc1b88a336ccec11e9f11dd2dd7bac4d0cf53 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     let s = "ZͨA͑ͦ͒͋ͤ͑̚L̄͑͋Ĝͨͥ̿͒̽̈́Oͥ͛ͭ!̏"; while true { break; }
index 81723bb15b77478a0c6f3ec2c7f1e26b66048b73..f005245e6dcb9141f6d0d4228159ccef678e5e62 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(never_type)]
 #![allow(unreachable_code)]
index e74067578069e2ab5745856e7d8c23c7092d7d44..a0ff580671a2079160b54d6de05b3cbb224e9780 100644 (file)
@@ -5,7 +5,7 @@
 // universe transition (#56105) may eventually become an error.
 
 // revisions: old re
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![cfg_attr(re, feature(re_rebalance_coherence))]
 
index a030314262270ec4cbdcc8d5f9ebd0d64ff031d8..22517f9da2e30ca2f90eb1d54d6b6cd87bcdd27d 100644 (file)
@@ -2,7 +2,7 @@
 // `MyType: !MyTrait` along with other "fundamental" wrappers.
 
 // aux-build:coherence_copy_like_lib.rs
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // skip-codgen
 // revisions: old re
 
index f1ab2f0f9461f696ff2b8803fa319e8febeba71e..0c7e7cad0359f2d07aa0b223b332efd9ebf207b4 100644 (file)
@@ -1,7 +1,7 @@
 // Test that cfg_attr doesn't emit any attributes when the
 // configuration variable is false. This mirrors `cfg-attr-multi-true.rs`
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(unused_must_use)]
 
index 86524e8bd28ffe32f2c33a601bbaa715abadaef8..645e4e71dfe9aca73d0f8a4c9942ca4f5f8f8f3f 100644 (file)
@@ -2,7 +2,7 @@
 // This is done by emitting two attributes that cause new warnings, and then
 // triggering those warnings.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(unused_must_use)]
 
index f592e486be951fdc6c25b9f8fab427780426fad8..cb40734c1d257fa88c0cf4490dcdbcf3fc68a242 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![feature(const_generics)]
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
 
index 0b4aeae7a4a390ea5ea8f8b771fb53d88f368963..b810efe73847e10c10ccda303e2a645136583642 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(const_generics)]
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
index 3ccf38e5619775499121eb5669eda91826931bb9..68e5a52e0ac5cba18c9873560dbf5a86768df1b0 100644 (file)
@@ -7,6 +7,7 @@
 
 fn foo<const SIZE: usize>() {
     let arr: [u8; SIZE] = unsafe {
+        #[allow(deprecated)]
         let mut array: [u8; SIZE] = mem::uninitialized();
         array
     };
index 5ecf9a049842d4a1631dff192f522b0b7e60277c..9aec85526955e2b3fe810cf3e52a5b462a776156 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 enum Foo {
     Bar = { let x = 1; 3 }
index 51b50b2e75f4f15376f24727860b9a153f7bf3ee..48cfea82bd65e338ae84f81cccb16fa7cd20ce31 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 pub trait Foo {
     fn foo(self) -> u32;
index cb4fb46bd055cfa50989c5030c50db29a2189b70..d209e604486873a8b9a451f354fa58ef4c2ef119 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     const MIN: i8 = -5;
index 9ac511767c0f7bf89ca0f48e5ad9b8616a210ec8..2cf6a5494dd8d8c15820ba66fbe9542822bc0fa9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 enum Foo {
     A = 5,
index 0e75ea8e66b3cd409024c154cae295f041a60bae..a9a3f071bf89fca25a13869cb7724cb8a22b5450 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(const_fn, rustc_attrs)]
 
index 854f97d4754dfe15906d4f137311e335932e3e81..029d4e5e3732edc5865025b90fa536ecfffed2dd 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::time::Duration;
 
index f8e6fd09c7e0a19da9ad65b0155b4e3aec46eedf..e2b3bc83c3f01ddff63579b7bec595ec2975dc35 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(extern_types)]
 
index 2ad1a633d125f18af76f35b09222dbad621ea1b9..ce0e11f29f44220616eb4e20307d5d80dca22f8e 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 pub trait Nullable {
     const NULL: Self;
index b9fe4eadd41322b87e921033d888c9b5fd59b53f..250bf954e9ac2f3938601ff7becd92dc32c9984f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #[derive(Copy, Clone, PartialEq, Eq)]
 #[repr(packed)]
 pub struct Num(u64);
index 9d7b05cd232b57499f5851b4529e17458d1ad225..9de150bd0528d618174510ebba17d61ea734c0a7 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct S(pub &'static u32, pub u32);
 
index cb45b86cd7ba30ac8d34ea5e6be4180a13206894..bf69bc28da41a910112e1ebd35dc8a9e42057039 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 pub struct Stats;
 
index 72a6072e4b7b46277deca3fd755a1af79cdb6361..4753bf0f7b174ecccdfa8c52e4edc2d662273756 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // https://github.com/rust-lang/rust/issues/51300
 
 #[derive(PartialEq, Eq, Clone, Copy)]
index b9958609971a7b687d42c85a89b279a86117528e..ac0940b33e47a82444599687b289ae0099f19a18 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 macro_rules! m {
     () => {{
index e8ac5a90880cebc08e46d62822701b6a21be1ef1..d300e0b5125dae283885b48e66bb0d56938b952b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 pub const STATIC_TRAIT: &dyn Test = &();
 
index 611fb89341de4842fcffe63ece78aaf129d27250..d04570c67ff2ebcb75c2eaf1e76b4561b915bc1f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Test that we can handle newtypes wrapping extern types
 
index 0d14cf0f6d95117465bf2455870a2c96bc33a8e5..cea367528c975aa90370a636817b166eac3ac7d5 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // if `X` were used instead of `x`, `X - 10` would result in a lint.
 // This file should never produce a lint, no matter how the const
index 34f61ed5a347410315fd1b79154f36966b181ea7..ca75d65a39a924160c0399e46afdaa7770493028 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 pub fn main() {
     let y: &'static mut [u8; 0] = &mut [];
index d882dad295b16d5e389e9e618899689014d7e0ca..4ff140fee7a71643f2548b2ca0c010624fb8793b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![warn(const_err)]
 
 #![crate_type = "lib"]
index dee09b70d9334ff6e4f66f7c4b3f33fa669191db..7f1586336e72192f74ca2091c3f0a4cb9e6921c8 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![warn(const_err)]
 
 pub const Z: u32 = 0 - 1;
index 61398f3a375c25f8fd4c6acc5026b8b04565d395..8a9f3fe974d918c30abe1c7246e730b59abce426 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 const PARSE_BOOL: Option<&'static str> = None;
 static FOO: (Option<&str>, u32) = (PARSE_BOOL, 42);
index fe8675d326eee4754db80b3ca126d6bc6dddd9de..d4b2220695102aa87ae61c857d08412951ec4fa4 100644 (file)
@@ -1,5 +1,10 @@
 #![allow(const_err)] // make sure we cannot allow away the errors tested here
 
+
+#[repr(transparent)]
+#[derive(Copy, Clone)]
+struct Wrap<T>(T);
+
 #[repr(usize)]
 #[derive(Copy, Clone)]
 enum Enum {
@@ -7,11 +12,20 @@ enum Enum {
 }
 union TransmuteEnum {
     in1: &'static u8,
+    in2: usize,
     out1: Enum,
+    out2: Wrap<Enum>,
 }
 
-// A pointer is guaranteed non-null
-const BAD_ENUM: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
+const GOOD_ENUM: Enum = unsafe { TransmuteEnum { in2: 0 }.out1 };
+
+const BAD_ENUM: Enum = unsafe { TransmuteEnum { in2: 1 }.out1 };
+//~^ ERROR is undefined behavior
+
+const BAD_ENUM_PTR: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
+//~^ ERROR is undefined behavior
+
+const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { TransmuteEnum { in1: &1 }.out2 };
 //~^ ERROR is undefined behavior
 
 // (Potentially) invalid enum discriminant
@@ -20,9 +34,7 @@ union TransmuteEnum {
 enum Enum2 {
     A = 2,
 }
-#[repr(transparent)]
-#[derive(Copy, Clone)]
-struct Wrap<T>(T);
+
 union TransmuteEnum2 {
     in1: usize,
     in2: &'static u8,
@@ -33,17 +45,17 @@ union TransmuteEnum2 {
 }
 const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 };
 //~^ ERROR is undefined behavior
-const BAD_ENUM3: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
+const BAD_ENUM2_PTR: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
 //~^ ERROR is undefined behavior
-const BAD_ENUM4: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
+const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
 //~^ ERROR is undefined behavior
 
 // Undef enum discriminant.
-const BAD_ENUM_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
+const BAD_ENUM2_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
 //~^ ERROR is undefined behavior
 
 // Pointer value in an enum with a niche that is not just 0.
-const BAD_ENUM_PTR: Option<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out3 };
+const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out3 };
 //~^ ERROR is undefined behavior
 
 // Invalid enum field content (mostly to test printing of paths for enum tuple
@@ -53,7 +65,7 @@ union TransmuteChar {
     b: char,
 }
 // Need to create something which does not clash with enum layout optimizations.
-const BAD_ENUM_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
+const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
 //~^ ERROR is undefined behavior
 
 fn main() {
index 2bf4cf9bfd65b2a35869df940569fe470f0a2b0a..8ecb1aabdd0f72a55a2e6b0de0c1681403fd3a55 100644 (file)
@@ -1,13 +1,29 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:14:1
+  --> $DIR/ub-enum.rs:22:1
    |
-LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
+LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { in2: 1 }.out1 };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 1, but expected a valid enum discriminant
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:34:1
+  --> $DIR/ub-enum.rs:25:1
+   |
+LL | const BAD_ENUM_PTR: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/ub-enum.rs:28:1
+   |
+LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { TransmuteEnum { in1: &1 }.out2 };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected something that cannot possibly fail to be equal to 0
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/ub-enum.rs:46:1
    |
 LL | const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected a valid enum discriminant
@@ -15,45 +31,45 @@ LL | const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:36:1
+  --> $DIR/ub-enum.rs:48:1
    |
-LL | const BAD_ENUM3: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
+LL | const BAD_ENUM2_PTR: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:38:1
+  --> $DIR/ub-enum.rs:50:1
    |
-LL | const BAD_ENUM4: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected something that cannot possibly fail to be in the range 2..=2
+LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected something that cannot possibly fail to be equal to 2
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:42:1
+  --> $DIR/ub-enum.rs:54:1
    |
-LL | const BAD_ENUM_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid enum discriminant
+LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid enum discriminant
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:46:1
+  --> $DIR/ub-enum.rs:58:1
    |
-LL | const BAD_ENUM_PTR: Option<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out3 };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
+LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out3 };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:56:1
+  --> $DIR/ub-enum.rs:68:1
    |
-LL | const BAD_ENUM_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .<downcast-variant(Some)>.0.1, but expected something less or equal to 1114111
+LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .<downcast-variant(Some)>.0.1, but expected something less or equal to 1114111
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
-error: aborting due to 7 previous errors
+error: aborting due to 9 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
index 3e0b0948ef3c3ff4b536809a261fb28bc50d6c72..bcbb4358aec03823682766573052a389ad4d2eba 100644 (file)
@@ -5,9 +5,19 @@
 use std::ptr::NonNull;
 use std::num::{NonZeroU8, NonZeroUsize};
 
+const NON_NULL: NonNull<u8> = unsafe { mem::transmute(1usize) };
+const NON_NULL_PTR: NonNull<u8> = unsafe { mem::transmute(&1) };
+
 const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
 //~^ ERROR it is undefined behavior to use this value
 
+const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
+//~^ ERROR it is undefined behavior to use this value
+    let ptr: &(u8, u8, u8) = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
+    let out_of_bounds_ptr = &ptr.2; // use address-of-field for pointer arithmetic
+    mem::transmute(out_of_bounds_ptr)
+} };
+
 const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
 //~^ ERROR it is undefined behavior to use this value
 const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
index 6230712ad6f232497c7123a6acf4d3b378470093..2f9423fed3530389b6f1a4b726d852cc56030050 100644 (file)
@@ -1,5 +1,5 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:8:1
+  --> $DIR/ub-nonnull.rs:11:1
    |
 LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
@@ -7,7 +7,20 @@ LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:11:1
+  --> $DIR/ub-nonnull.rs:14:1
+   |
+LL | / const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
+LL | |
+LL | |     let ptr: &(u8, u8, u8) = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
+LL | |     let out_of_bounds_ptr = &ptr.2; // use address-of-field for pointer arithmetic
+LL | |     mem::transmute(out_of_bounds_ptr)
+LL | | } };
+   | |____^ type validation failed: encountered a potentially NULL pointer, but expected something that cannot possibly fail to be greater or equal to 1
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/ub-nonnull.rs:21:1
    |
 LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
@@ -15,7 +28,7 @@ LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:13:1
+  --> $DIR/ub-nonnull.rs:23:1
    |
 LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
@@ -23,7 +36,7 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:20:1
+  --> $DIR/ub-nonnull.rs:30:1
    |
 LL | const UNINIT: NonZeroU8 = unsafe { Transmute { uninit: () }.out };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected something greater or equal to 1
@@ -31,7 +44,7 @@ LL | const UNINIT: NonZeroU8 = unsafe { Transmute { uninit: () }.out };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:28:1
+  --> $DIR/ub-nonnull.rs:38:1
    |
 LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range 10..=30
@@ -39,13 +52,13 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:34:1
+  --> $DIR/ub-nonnull.rs:44:1
    |
 LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 20, but expected something less or equal to 10, or greater or equal to 30
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
index a195e12defcea59b66d69b38df25e907c3000465..30bd47219239e3cead8eefa9d10cf86de5f9dffd 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Some constants that *are* valid
 #![feature(const_transmute)]
index d837da1066daa79d37c98a88dae7cefa80d536ae..7edb6bd03dabf2f3ca3f882a35d7cb15ba075035 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 static ASSERT: () = [()][!(std::mem::size_of::<u32>() == 4) as usize];
 
index dc9f292c2b8ad3c6358403936b627ec3dda05c82..37bf24c2fbed1529bc0d464d2040dcc93def4280 100644 (file)
@@ -1,5 +1,5 @@
 // Encountered while testing #44614.
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 pub fn main() {
     // Constant of generic type (int)
index dcf89f90e31da3e70aa1625c6921cc41424b5256..d2c89cb54a0eb39601fe5e56738ebd6d72bb7390 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 const fn i((a, b): (u32, u32)) -> u32 {
     a + b
index c06ab227f6463c6f5ca163a0aac371cf699683d9..6db3d1b3331fa8d66798706a3f85148586c86209 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::num::NonZeroU8;
 
index 8dd78ca0ba4950484de85fb0e1f2ed72deae0f68..dae5343fe3011691b3caaecaeb5fc61ba01ade11 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #[derive(PartialEq, Eq)]
 enum Cake {
index def4062339f9635ce253c8f6bd19478b1520ea73..583074888c9b66fb5b62c02d16e02f3c57b2b3d1 100644 (file)
@@ -1,5 +1,5 @@
 // https://github.com/rust-lang/rust/issues/55454
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct This<T>(T);
 
index c7617c9c7ad0342e0152fe28618a22582ac3567f..d22c789609f4d5b74926c07499a8f2a69de98311 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:const_fn_lib.rs
 
 extern crate const_fn_lib;
index 0b09b8469fd752f206b6dffa945d78dfffeef1fd..343fcb4859b37299204648bcf47dd2c9a4c25426 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct S(i32);
 
index 1c44237e49b7a2f20c0e3506df439630c4f4fa86..4787c1750d291942ef54b899c383a3af7f08c398 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 pub struct AA {
     pub data: [u8; 10],
index c48f54e567b2cb4f651a601f0badcc7776d291c0..0c927a0484d9d15ce704fddd9a8bc9622d50eb3d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(const_fn)]
 
index 424a16f7ed39b10aa34e222de064709d3e816f22..e889abf4abe4a56aa401d925db73384ac487f3d2 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {}
 
index 86a197ffb993ece641d6e19edd1f54e652eb32db..9d98d3be87464c43f28344f4e6845e4d77ae9c5b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 struct A;
 impl Drop for A {
index afa2c6a5b9e1c4fb143d3b1edfdb6c32ab9f1c6d..34dafd00d28dc8e85fe85febc058825f0c5f8024 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(const_raw_ptr_deref)]
 
index f98406e50e9aef7c917a0ee276f8909b3418131d..a31eaf40e0ede9b8b4809eea4443f6f40bc8128e 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // note this was only reproducible with lib crates
 // compile-flags: --crate-type=lib
 
index 9f41ed9a24523d4d1c4886851f6cd952d3fc55b5..efeb9fc551cc98993a799428997af6ea366cee4c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     assert_eq!(&mut [0; 1][..], &mut []);
index 0395795ef7bfe03e84f18e75f38dd384ae88c24d..0f9d37292958aa703dabcafad748323c8fe95a83 100644 (file)
@@ -5,7 +5,7 @@ const fn error(_: fn()) {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_allow_const_fn_ptr]
-//~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved
+//~^ ERROR internal implementation detail
 const fn compiles(_: fn()) {}
 
 fn main() {}
index c934307e918b931a1a779ac8eb1f42f00ddf4e87..d2ca0c8bc381b5a66e1edda7518cbe726e6fa965 100644 (file)
@@ -1,8 +1,8 @@
-error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics
-  --> $DIR/allow_const_fn_ptr_feature_gate.rs:7:3
+error[E0658]: internal implementation detail
+  --> $DIR/allow_const_fn_ptr_feature_gate.rs:7:1
    |
 LL | #[rustc_allow_const_fn_ptr]
-   |   ^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29642
    = help: add #![feature(rustc_attrs)] to the crate attributes to enable
index 23bd73325472e4ec7284486aaf9a7e40bff7da33..cb8f74186bd745e60261039d24e1c6a17d07c7f6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::cell::UnsafeCell;
 use std::sync::atomic::AtomicU32;
index dc21b9fe8cd1b655d380ba2fd0a00a4dbf5c175a..4eda785bb89895b54bfdfc3047fe2332e08bb3d8 100644 (file)
@@ -1,4 +1,4 @@
-//compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
 
index 6b6eea36361bf3fef2087c8123a5c34324c1fbad..8995aaacd8549fe833325e4d4ff13b53d6cd208e 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:promotable_const_fn_lib.rs
 
 extern crate promotable_const_fn_lib;
index d982f350208e22ac7f1a87e587e3fab30c61c07e..bdb472f3a9cce025094229341b45ec4a6f69408b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     let x: &'static u8 = &u8::max_value();
index 5e193b1b7de0bcaa283b7a8bcaa5bc5e31471129..23cae4fb57d573495fc518a95bd96f879b9f833e 100644 (file)
@@ -1,5 +1,5 @@
 // https://github.com/rust-lang/rust/issues/55454
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #[derive(PartialEq)]
 struct This<T>(T);
index 68b9a20ecf90bc0be8d9e9d50fead1d94c6715df..d57036ae58f35b64aeddd462a174228c938edec4 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     let _ = &[("", ""); 3];
index 27e1a111163b15999cc7c9f34718bc6f40d4cf2b..df09c76c5584d8afe9a9a315b1def7928e977f7a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 static mut STDERR_BUFFER_SPACE: [u8; 42] = [0u8; 42];
 
index ad38105b6aa0eaf1c287ff628c080b4becb6f629..f19defc64dd711fb587fb4a40f966b29256853b8 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct Wrap<T>(T);
 unsafe impl<T> Send for Wrap<T> {}
index 8d57e5074f1b1d919da4c7ddcbec72c972c0fa08..d0e625bf1997a0b74957da508e8bbaa735407380 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(unused)]
 
index 16b05310b9fcb64c8291a09f0be33c64ddbbb708..508ff7e0ae8e67d5bb1c6cb09cbf980710ee974f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 union Uninit {
     _never_use: *const u8,
index 496ce4fb378aec933ca76baac9209e2391e38b3a..92a67950986b0e4f4c492ec8e1f0aae20a4877ce 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(dead_code)]
 
index dee1d979cff1d5cf63785c35c37dbb3653c44864..363bda75f16955a20f6f4bac58bd1dce606f9e7a 100644 (file)
@@ -1,5 +1,5 @@
 // run-rustfix
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #[allow(deprecated, unused_imports)]
 use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT};
index b9e25e817bce463d2a2ab88a0c7bf64a362a6169..00c5f7b0b1257dcfc28001fc07387d6ee03895de 100644 (file)
@@ -1,5 +1,5 @@
 // run-rustfix
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #[allow(deprecated, unused_imports)]
 use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT};
index 4980a7f5aa31cb617510eff2175af74f0af96441..ed4055ecdd38cfd3e59decebaf5b655ea2fa675c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(deprecated)]
 
index 235146bad9c851f90c296a6987d46dfe267ff652..3fd434664675628768f4cf3243899909571076b7 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![forbid(deprecated)]
 
index b314eacc92e0e60d9ce547bb04f6692302f012f1..2c4d64e4e6063375ae634fa5a9a920832458023a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags: -Wunused
 
 // ensure there are no special warnings about uninhabited types
index f535791d7fbe498ea1c8f18c8ce5019b5b0d9983..cf14aef7900a73bda28932fc0772110b5f5e95d3 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Under the 2015 edition with the keyword_idents lint, `dyn` is
 // not entirely acceptable as an identifier.
index 27e490558689fe7fdc3ef18ff3063e7d4e5e1d9d..0d85b87dee5a163a5faefc6a34b0ee4c6cbd171e 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Under the 2015 edition with the keyword_idents lint, `dyn` is
 // not entirely acceptable as an identifier.
index 8cef5c2b349471d9a72247666ad5e8d002678575..2a8b6b24831c0376b793bf3eab3686cb18ed68e7 100644 (file)
@@ -1,7 +1,7 @@
 // Under the 2015 edition without the keyword_idents lint, `dyn` is
 // entirely acceptable as an identifier.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(non_camel_case_types)]
 
index ff3830d61755adb964085d27cb868fb4d0cc150a..2718e89a3f214d8d18a11f23b97e9405baa240c7 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // rust-lang/rust#56327: Some occurrences of `dyn` within a macro are
 // not instances of identifiers, and thus should *not* be caught by the
index 6361fff6ff43cb1bc2b4bb0b22e603223fca2a9c..93fe69e0af2172305a0408eea0e65007791524ec 100644 (file)
@@ -1,6 +1,6 @@
 // aux-build:edition-extern-crate-allowed.rs
 // edition:2015
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(rust_2018_idioms)]
 
index c2468df49398ade39b16655b6b54711e9a2c51ff..126421326949b41bc4c16ab9a9bf0692c50119e3 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rust_2018_preview)]
 
index 87a2a22105f4e747f8e434ee257d044332e3175c..4309a777d33f78a781195aabd51775c8041b09c7 100644 (file)
@@ -1,5 +1,5 @@
 // edition:2018
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rust_2018_preview)]
 //~^ WARN the feature `rust_2018_preview` is included in the Rust 2018 edition
index 940b0c3c63db090cf909cdcb0901f7115596a407..310bff21d1851636299fee16c2f6700e33014d96 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 // compile-flags:--extern edition_imports_2015
 // aux-build:edition-imports-2015.rs
index c3757ab193485a02f4106255da24490053ef413a..9c3beb1ce58c19b5a231a347c8799c4f6eb1f85f 100644 (file)
@@ -1,6 +1,6 @@
 // edition:2015
 // aux-build:edition-kw-macro-2015.rs
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(keyword_idents)]
 
index 6a30c49821904fff03bd15784e0cb4dc8aa536da..619e6424db441f645e1108571014bcb7d15ee40c 100644 (file)
@@ -1,6 +1,6 @@
 // edition:2018
 // aux-build:edition-kw-macro-2015.rs
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(keyword_idents)]
 
index 2f17f95b7a3beffb5ddbdf99a76c529400edeae9..d309485f05311d79d3cec8228abc0fcc67c16c54 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags:--emit=metadata --error-format=json -Z emit-artifact-notifications
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // ignore-pass
 // ^-- needed because `--pass check` does not emit the output needed.
 
diff --git a/src/test/ui/enum-variant-generic-args.rs b/src/test/ui/enum-variant-generic-args.rs
deleted file mode 100644 (file)
index dd1f5f3..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#![feature(type_alias_enum_variants)]
-
-enum Enum<T> { TSVariant(T), SVariant { v: T } }
-type Alias<T> = Enum<T>;
-type AliasFixed = Enum<()>;
-
-impl<T> Enum<T> {
-    fn ts_variant() {
-        Self::TSVariant(());
-        //~^ ERROR mismatched types [E0308]
-        Self::TSVariant::<()>(());
-        //~^ ERROR type arguments are not allowed for this type [E0109]
-        Self::<()>::TSVariant(());
-        //~^ ERROR type arguments are not allowed for this type [E0109]
-        //~^^ ERROR mismatched types [E0308]
-        Self::<()>::TSVariant::<()>(());
-        //~^ ERROR type arguments are not allowed for this type [E0109]
-        //~^^ ERROR type arguments are not allowed for this type [E0109]
-    }
-
-    fn s_variant() {
-        Self::SVariant { v: () };
-        //~^ ERROR mismatched types [E0308]
-        Self::SVariant::<()> { v: () };
-        //~^ ERROR type arguments are not allowed for this type [E0109]
-        //~^^ ERROR mismatched types [E0308]
-        Self::<()>::SVariant { v: () };
-        //~^ ERROR type arguments are not allowed for this type [E0109]
-        //~^^ ERROR mismatched types [E0308]
-        Self::<()>::SVariant::<()> { v: () };
-        //~^ ERROR type arguments are not allowed for this type [E0109]
-        //~^^ ERROR type arguments are not allowed for this type [E0109]
-        //~^^^ ERROR mismatched types [E0308]
-    }
-}
-
-fn main() {
-    // Tuple struct variant
-
-    Enum::<()>::TSVariant::<()>(());
-    //~^ ERROR type arguments are not allowed for this type [E0109]
-
-    Alias::TSVariant::<()>(());
-    //~^ ERROR type arguments are not allowed for this type [E0109]
-    Alias::<()>::TSVariant::<()>(());
-    //~^ ERROR type arguments are not allowed for this type [E0109]
-
-    AliasFixed::TSVariant::<()>(());
-    //~^ ERROR type arguments are not allowed for this type [E0109]
-    AliasFixed::<()>::TSVariant(());
-    //~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
-    AliasFixed::<()>::TSVariant::<()>(());
-    //~^ ERROR type arguments are not allowed for this type [E0109]
-    //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
-
-    // Struct variant
-
-    Enum::<()>::SVariant::<()> { v: () };
-    //~^ ERROR type arguments are not allowed for this type [E0109]
-
-    Alias::SVariant::<()> { v: () };
-    //~^ ERROR type arguments are not allowed for this type [E0109]
-    Alias::<()>::SVariant::<()> { v: () };
-    //~^ ERROR type arguments are not allowed for this type [E0109]
-
-    AliasFixed::SVariant::<()> { v: () };
-    //~^ ERROR type arguments are not allowed for this type [E0109]
-    AliasFixed::<()>::SVariant { v: () };
-    //~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
-    AliasFixed::<()>::SVariant::<()> { v: () };
-    //~^ ERROR type arguments are not allowed for this type [E0109]
-    //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
-}
diff --git a/src/test/ui/enum-variant-generic-args.stderr b/src/test/ui/enum-variant-generic-args.stderr
deleted file mode 100644 (file)
index 97b111a..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:9:25
-   |
-LL |         Self::TSVariant(());
-   |                         ^^ expected type parameter, found ()
-   |
-   = note: expected type `T`
-              found type `()`
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:11:27
-   |
-LL |         Self::TSVariant::<()>(());
-   |                           ^^ type argument not allowed
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:13:16
-   |
-LL |         Self::<()>::TSVariant(());
-   |                ^^ type argument not allowed
-
-error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:13:31
-   |
-LL |         Self::<()>::TSVariant(());
-   |                               ^^ expected type parameter, found ()
-   |
-   = note: expected type `T`
-              found type `()`
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:16:16
-   |
-LL |         Self::<()>::TSVariant::<()>(());
-   |                ^^ type argument not allowed
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:16:33
-   |
-LL |         Self::<()>::TSVariant::<()>(());
-   |                                 ^^ type argument not allowed
-
-error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:22:29
-   |
-LL |         Self::SVariant { v: () };
-   |                             ^^ expected type parameter, found ()
-   |
-   = note: expected type `T`
-              found type `()`
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:24:26
-   |
-LL |         Self::SVariant::<()> { v: () };
-   |                          ^^ type argument not allowed
-
-error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:24:35
-   |
-LL |         Self::SVariant::<()> { v: () };
-   |                                   ^^ expected type parameter, found ()
-   |
-   = note: expected type `T`
-              found type `()`
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:27:16
-   |
-LL |         Self::<()>::SVariant { v: () };
-   |                ^^ type argument not allowed
-
-error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:27:35
-   |
-LL |         Self::<()>::SVariant { v: () };
-   |                                   ^^ expected type parameter, found ()
-   |
-   = note: expected type `T`
-              found type `()`
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:30:16
-   |
-LL |         Self::<()>::SVariant::<()> { v: () };
-   |                ^^ type argument not allowed
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:30:32
-   |
-LL |         Self::<()>::SVariant::<()> { v: () };
-   |                                ^^ type argument not allowed
-
-error[E0308]: mismatched types
-  --> $DIR/enum-variant-generic-args.rs:30:41
-   |
-LL |         Self::<()>::SVariant::<()> { v: () };
-   |                                         ^^ expected type parameter, found ()
-   |
-   = note: expected type `T`
-              found type `()`
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:40:29
-   |
-LL |     Enum::<()>::TSVariant::<()>(());
-   |                             ^^ type argument not allowed
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:43:24
-   |
-LL |     Alias::TSVariant::<()>(());
-   |                        ^^ type argument not allowed
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:45:30
-   |
-LL |     Alias::<()>::TSVariant::<()>(());
-   |                              ^^ type argument not allowed
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:48:29
-   |
-LL |     AliasFixed::TSVariant::<()>(());
-   |                             ^^ type argument not allowed
-
-error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/enum-variant-generic-args.rs:50:18
-   |
-LL |     AliasFixed::<()>::TSVariant(());
-   |                  ^^ unexpected type argument
-
-error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/enum-variant-generic-args.rs:52:18
-   |
-LL |     AliasFixed::<()>::TSVariant::<()>(());
-   |                  ^^ unexpected type argument
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:52:35
-   |
-LL |     AliasFixed::<()>::TSVariant::<()>(());
-   |                                   ^^ type argument not allowed
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:58:28
-   |
-LL |     Enum::<()>::SVariant::<()> { v: () };
-   |                            ^^ type argument not allowed
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:61:23
-   |
-LL |     Alias::SVariant::<()> { v: () };
-   |                       ^^ type argument not allowed
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:63:29
-   |
-LL |     Alias::<()>::SVariant::<()> { v: () };
-   |                             ^^ type argument not allowed
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:66:28
-   |
-LL |     AliasFixed::SVariant::<()> { v: () };
-   |                            ^^ type argument not allowed
-
-error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/enum-variant-generic-args.rs:68:18
-   |
-LL |     AliasFixed::<()>::SVariant { v: () };
-   |                  ^^ unexpected type argument
-
-error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/enum-variant-generic-args.rs:70:18
-   |
-LL |     AliasFixed::<()>::SVariant::<()> { v: () };
-   |                  ^^ unexpected type argument
-
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/enum-variant-generic-args.rs:70:34
-   |
-LL |     AliasFixed::<()>::SVariant::<()> { v: () };
-   |                                  ^^ type argument not allowed
-
-error: aborting due to 28 previous errors
-
-Some errors have detailed explanations: E0107, E0109, E0308.
-For more information about an error, try `rustc --explain E0107`.
index cc2b8f64d9fa884e871a9dc00cfc8cc7e879f40b..4e32ef355606cb5c67778f69411522b5d26c71c4 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // This is a stub feature that doesn't control anything, so to make tidy happy,
 // gate-test-test_2018_feature
index c1c0c60d59ee0f6358c2ffb39153dac14c73a809..46bc17293bc902f8fc10188d8beb02d53cb45a3f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(warnings)]
 
index c5d5ca916a48aa94e1226ed22f8a6936c5440d31..c30608176aada702875d7374cec095bffb021602 100644 (file)
@@ -1,5 +1,5 @@
 // aux-build:cross_crate_ice.rs
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 extern crate cross_crate_ice;
 
index a0f3933ce33b23c5293e6496ca30763f8a2ea714..3a7e490260f3fbccf389518fb8b661e68d799c4d 100644 (file)
@@ -1,5 +1,5 @@
 // aux-build:cross_crate_ice2.rs
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 extern crate cross_crate_ice2;
 
index 2953f1745ee5b792870e471488d0d258c08aed8d..0f02cfaad7e06c01462c4ba480bb7e7a881dcb2f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(existential_type)]
 
index 299ae91b84386cfbb007e565d677f20f0bf79175..bfb91f68ffdd13cd23054df8fc4ac64552ea6ec4 100644 (file)
@@ -1,5 +1,5 @@
 #![feature(existential_type)]
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait Bar {}
 struct Dummy;
index 10f2c630582fca1f431a4bed078a43a88ac0d19b..0d9c7cdfe71c3612714048cde45c263e17667c13 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![feature(existential_type)]
 
 use std::fmt::Debug;
index 5d8d05c30878027067b3f24924a3f3b6ee6fc18a..56e1528c213efa3d1e58a608c5579b78d69cec1f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![feature(existential_type)]
 
 use std::fmt::Debug;
index a8bb0229f0e8d288fa6c230fdf5faa2554193e36..1ea01f17b70a31b3d9b14c7373d4ee5d698d27b6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(existential_type)]
 
index 6d2a12da7e443a283192df2c687c6cf8d77ad259..de52e88bae2096d2d1b29e555a0821c661489c8d 100644 (file)
@@ -1,5 +1,5 @@
 #![feature(existential_type)]
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 mod my_mod {
   use std::fmt::Debug;
 
index 736d812bc0aff919086f5719e5df9ffa5767047a..92268f1861d63535de87ea1563f9dfd4b41256e8 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #[deny(warnings)]
 
index 3622ba776453078e73145c417639e5c2eda2d258..28973d67564824b5f7a9138b26e3ebd02ce70b24 100644 (file)
@@ -1,2 +1,2 @@
 // compile-flags: --explain E0591
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
index 0e52f2c5158d422845b021639e0b8eafdcbcbef1..50fed6034aa02609131a12e6f8462c9c635ded7e 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags:--extern extern_prelude --extern Vec
 // aux-build:extern-prelude.rs
 // aux-build:extern-prelude-vec.rs
index 98ca3444c91bdd66d574f6ef953023194d5306de..dab946bb81810fd5abbd05293135b807bd819c3c 100644 (file)
@@ -3,7 +3,7 @@
 // `#![macro_escape]` is incompatible with crate-level `#![macro_use]`
 // already present in issue-43106-gating-of-builtin-attrs.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![macro_escape]
 //~^ WARN macro_escape is a deprecated synonym for macro_use
index 9cfefef4129de27e3e9e957db9099df93f6957fd..78391c0e104cc3e26a441fb48491320524f2c2d3 100644 (file)
@@ -15,5 +15,4 @@ async fn foo() {} //~ ERROR async fn is unstable
 
 fn main() {
     let _ = async {}; //~ ERROR async blocks are unstable
-    let _ = async || {}; //~ ERROR async closures are unstable
 }
index 43e41b4545869e568c6f86bf5cf1ceb8467693ec..1ea4da8da0c5e323f0d024b380164a66c873fe83 100644 (file)
@@ -40,15 +40,6 @@ LL |     let _ = async {};
    = note: for more information, see https://github.com/rust-lang/rust/issues/50547
    = help: add #![feature(async_await)] to the crate attributes to enable
 
-error[E0658]: async closures are unstable
-  --> $DIR/feature-gate-async-await.rs:18:13
-   |
-LL |     let _ = async || {};
-   |             ^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/50547
-   = help: add #![feature(async_await)] to the crate attributes to enable
-
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
index 4df1c7d6ed237784d642745e3455b205bcdd758a..2b1067b34891cc91ae6b62d6dc67d9e32f873cc4 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     const ARR: [i32; 6] = [42, 43, 44, 45, 46, 47];
diff --git a/src/test/ui/feature-gates/feature-gate-member-constraints.rs b/src/test/ui/feature-gates/feature-gate-member-constraints.rs
new file mode 100644 (file)
index 0000000..293a933
--- /dev/null
@@ -0,0 +1,9 @@
+trait Trait<'a, 'b> { }
+impl<T> Trait<'_, '_> for T {}
+
+fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> {
+    //~^ ERROR ambiguous lifetime bound
+    (x, y)
+}
+
+fn main() { }
diff --git a/src/test/ui/feature-gates/feature-gate-member-constraints.stderr b/src/test/ui/feature-gates/feature-gate-member-constraints.stderr
new file mode 100644 (file)
index 0000000..3745d5e
--- /dev/null
@@ -0,0 +1,10 @@
+error: ambiguous lifetime bound in `impl Trait`
+  --> $DIR/feature-gate-member-constraints.rs:4:43
+   |
+LL | fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> {
+   |                                           ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other
+   |
+   = help: add #![feature(member_constraints)] to the crate attributes to enable
+
+error: aborting due to previous error
+
index 5ec413cc71de0b26cab7e75dece06d26e3a7a8ec..d3a2e486416afd9ae47c570f4f8c31c716b8e510 100644 (file)
@@ -1,6 +1,23 @@
 // Test that `#[rustc_*]` attributes are gated by `rustc_attrs` feature gate.
 
-#[rustc_foo]
-//~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved
+#![feature(decl_macro)]
 
+mod rustc { pub macro unknown() {} }
+mod unknown { pub macro rustc() {} }
+
+#[rustc::unknown]
+//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
+//~| ERROR macro `rustc::unknown` may not be used in attributes
+fn f() {}
+
+#[unknown::rustc]
+//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
+//~| ERROR macro `unknown::rustc` may not be used in attributes
+fn g() {}
+
+#[rustc_dummy]
+//~^ ERROR used by the test suite
+#[rustc_unknown]
+//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
+//~| ERROR attribute `rustc_unknown` is currently unknown
 fn main() {}
index 3c823c8d4e25f4e6fd1e05bba620c1fce490be26..cdc7b27a749e5f4c21eb31bc814e9b3c6c7f8155 100644 (file)
@@ -1,12 +1,60 @@
-error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics
-  --> $DIR/feature-gate-rustc-attrs.rs:3:3
+error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler
+  --> $DIR/feature-gate-rustc-attrs.rs:8:3
    |
-LL | #[rustc_foo]
-   |   ^^^^^^^^^
+LL | #[rustc::unknown]
+   |   ^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29642
    = help: add #![feature(rustc_attrs)] to the crate attributes to enable
 
-error: aborting due to previous error
+error: macro `rustc::unknown` may not be used in attributes
+  --> $DIR/feature-gate-rustc-attrs.rs:8:1
+   |
+LL | #[rustc::unknown]
+   | ^^^^^^^^^^^^^^^^^
+
+error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler
+  --> $DIR/feature-gate-rustc-attrs.rs:13:12
+   |
+LL | #[unknown::rustc]
+   |            ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add #![feature(rustc_attrs)] to the crate attributes to enable
+
+error: macro `unknown::rustc` may not be used in attributes
+  --> $DIR/feature-gate-rustc-attrs.rs:13:1
+   |
+LL | #[unknown::rustc]
+   | ^^^^^^^^^^^^^^^^^
+
+error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler
+  --> $DIR/feature-gate-rustc-attrs.rs:20:3
+   |
+LL | #[rustc_unknown]
+   |   ^^^^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add #![feature(rustc_attrs)] to the crate attributes to enable
+
+error[E0658]: The attribute `rustc_unknown` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/feature-gate-rustc-attrs.rs:20:3
+   |
+LL | #[rustc_unknown]
+   |   ^^^^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add #![feature(custom_attribute)] to the crate attributes to enable
+
+error[E0658]: used by the test suite
+  --> $DIR/feature-gate-rustc-attrs.rs:18:1
+   |
+LL | #[rustc_dummy]
+   | ^^^^^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add #![feature(rustc_attrs)] to the crate attributes to enable
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
index fe3c1e0afdd6bbfe8f7818e735efc46efb6cd216..03bf933cd084dd11aa53b362d2eb1ff910dc2fcc 100644 (file)
@@ -4,7 +4,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized
 LL |         [1, 2, ..] => {}
    |                ^^
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/23121
+   = note: for more information, see https://github.com/rust-lang/rust/issues/62254
    = help: add #![feature(slice_patterns)] to the crate attributes to enable
 
 error[E0658]: syntax for subslices in slice patterns is not yet stabilized
@@ -13,7 +13,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized
 LL |         [1, .., 5] => {}
    |             ^^
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/23121
+   = note: for more information, see https://github.com/rust-lang/rust/issues/62254
    = help: add #![feature(slice_patterns)] to the crate attributes to enable
 
 error[E0658]: syntax for subslices in slice patterns is not yet stabilized
@@ -22,7 +22,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized
 LL |         [.., 4, 5] => {}
    |          ^^
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/23121
+   = note: for more information, see https://github.com/rust-lang/rust/issues/62254
    = help: add #![feature(slice_patterns)] to the crate attributes to enable
 
 error[E0658]: syntax for subslices in slice patterns is not yet stabilized
@@ -31,7 +31,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized
 LL |         [ xs.., 4, 5 ] => {}
    |           ^^
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/23121
+   = note: for more information, see https://github.com/rust-lang/rust/issues/62254
    = help: add #![feature(slice_patterns)] to the crate attributes to enable
 
 error[E0658]: syntax for subslices in slice patterns is not yet stabilized
@@ -40,7 +40,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized
 LL |         [ 1, xs.., 5 ] => {}
    |              ^^
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/23121
+   = note: for more information, see https://github.com/rust-lang/rust/issues/62254
    = help: add #![feature(slice_patterns)] to the crate attributes to enable
 
 error[E0658]: syntax for subslices in slice patterns is not yet stabilized
@@ -49,7 +49,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized
 LL |         [ 1, 2, xs.. ] => {}
    |                 ^^
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/23121
+   = note: for more information, see https://github.com/rust-lang/rust/issues/62254
    = help: add #![feature(slice_patterns)] to the crate attributes to enable
 
 error: aborting due to 6 previous errors
diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs
deleted file mode 100644 (file)
index c7d3304..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-enum Foo {
-    Bar(i32),
-    Baz { i: i32 },
-}
-
-type Alias = Foo;
-
-fn main() {
-    let t = Alias::Bar(0);
-    //~^ ERROR enum variants on type aliases are experimental
-    let t = Alias::Baz { i: 0 };
-    //~^ ERROR enum variants on type aliases are experimental
-    match t {
-        Alias::Bar(_i) => {}
-        //~^ ERROR enum variants on type aliases are experimental
-        Alias::Baz { i: _i } => {}
-        //~^ ERROR enum variants on type aliases are experimental
-    }
-}
diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr
deleted file mode 100644 (file)
index 43535af..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-error: enum variants on type aliases are experimental
-  --> $DIR/feature-gate-type_alias_enum_variants.rs:9:13
-   |
-LL |     let t = Alias::Bar(0);
-   |             ^^^^^^^^^^
-   |
-   = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable
-
-error: enum variants on type aliases are experimental
-  --> $DIR/feature-gate-type_alias_enum_variants.rs:11:13
-   |
-LL |     let t = Alias::Baz { i: 0 };
-   |             ^^^^^^^^^^
-   |
-   = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable
-
-error: enum variants on type aliases are experimental
-  --> $DIR/feature-gate-type_alias_enum_variants.rs:14:9
-   |
-LL |         Alias::Bar(_i) => {}
-   |         ^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable
-
-error: enum variants on type aliases are experimental
-  --> $DIR/feature-gate-type_alias_enum_variants.rs:16:9
-   |
-LL |         Alias::Baz { i: _i } => {}
-   |         ^^^^^^^^^^
-   |
-   = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable
-
-error: aborting due to 4 previous errors
-
index 8519cf741a3208338291501e36718855e5a28ed5..e4118546616035b4ccfb6f247c2435db1ade19b9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(unused_must_use)]
 
index df11800731c72bb3d1b661c0f54911767190bcb4..395456ce7c65b59593d939890f99c2e42f47482d 100644 (file)
@@ -2,7 +2,7 @@
 // but which encountered the same ICE/error. See `issue-53548.rs`
 // for details.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::cell::RefCell;
 use std::rc::Rc;
index 73a2bcdd55538988d542f1550a0b44f52d53e6d4..8136c65923b79ae59ccf06c1b69b088c62e77aa1 100644 (file)
@@ -15,7 +15,7 @@
 // also analogous to what we would do for higher-ranked regions
 // appearing within the trait in other positions).
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(generators)]
 
index 601d2a9e0a31f49835815de5b5c8d3ae1d0869c1..3c5cc84c6a6ac7d9e0e94c471de875fccfaa5894 100644 (file)
@@ -1,44 +1,38 @@
 // This test previously ensured that attributes on formals in generic parameter
 // lists are rejected without a feature gate.
-//
-// (We are prefixing all tested features with `rustc_`, to ensure that
-// the attributes themselves won't be rejected by the compiler when
-// using `rustc_attrs` feature. There is a separate compile-fail/ test
-// ensuring that the attribute feature-gating works in this context.)
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
-#![allow(dead_code)]
-
-struct StLt<#[rustc_lt_struct] 'a>(&'a u32);
-struct StTy<#[rustc_ty_struct] I>(I);
-enum EnLt<#[rustc_lt_enum] 'b> { A(&'b u32), B }
-enum EnTy<#[rustc_ty_enum] J> { A(J), B }
-trait TrLt<#[rustc_lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
-trait TrTy<#[rustc_ty_trait] K> { fn foo(&self, _: K); }
-type TyLt<#[rustc_lt_type] 'd> = &'d u32;
-type TyTy<#[rustc_ty_type] L> = (L, );
-
-impl<#[rustc_lt_inherent] 'e> StLt<'e> { }
-impl<#[rustc_ty_inherent] M> StTy<M> { }
-impl<#[rustc_lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
+
+struct StLt<#[rustc_dummy] 'a>(&'a u32);
+struct StTy<#[rustc_dummy] I>(I);
+enum EnLt<#[rustc_dummy] 'b> { A(&'b u32), B }
+enum EnTy<#[rustc_dummy] J> { A(J), B }
+trait TrLt<#[rustc_dummy] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
+trait TrTy<#[rustc_dummy] K> { fn foo(&self, _: K); }
+type TyLt<#[rustc_dummy] 'd> = &'d u32;
+type TyTy<#[rustc_dummy] L> = (L, );
+
+impl<#[rustc_dummy] 'e> StLt<'e> { }
+impl<#[rustc_dummy] M> StTy<M> { }
+impl<#[rustc_dummy] 'f> TrLt<'f> for StLt<'f> {
     fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } }
 }
-impl<#[rustc_ty_impl_for] N> TrTy<N> for StTy<N> {
+impl<#[rustc_dummy] N> TrTy<N> for StTy<N> {
     fn foo(&self, _: N) { }
 }
 
-fn f_lt<#[rustc_lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
-fn f_ty<#[rustc_ty_fn] O>(_: O) { }
+fn f_lt<#[rustc_dummy] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
+fn f_ty<#[rustc_dummy] O>(_: O) { }
 
 impl<I> StTy<I> {
-    fn m_lt<#[rustc_lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
-    fn m_ty<#[rustc_ty_meth] P>(_: P) { }
+    fn m_lt<#[rustc_dummy] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
+    fn m_ty<#[rustc_dummy] P>(_: P) { }
 }
 
 fn hof_lt<Q>(_: Q)
-    where Q: for <#[rustc_lt_hof] 'i> Fn(&'i [u32]) -> &'i u32
+    where Q: for <#[rustc_dummy] 'i> Fn(&'i [u32]) -> &'i u32
 {}
 
 fn main() {}
index f790af64b4df05ba45d64555dd5814b127be45c7..22ce47414b28d01b8e587e1e4081c1ba7678d6ba 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Test that compiling hello world succeeds with no output of any kind.
 
index 380ad20486ec47465d9d1e68ba15592262175af7..9c25e138d2c2852613f12be81d80966de028e6b2 100644 (file)
@@ -1,6 +1,6 @@
 // Make sure `$crate` and `crate` work in for basic cases of nested macros.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:intercrate.rs
 
 #![feature(decl_macro, crate_in_paths)]
index f4c1a931f68adbe38d2a4040c48e8202d027dce1..f361e3d5d49635ea74404cf7d015ee97744a950d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:local_inner_macros.rs
 
 extern crate local_inner_macros;
index 0a86234fdba1f7ae058895c56a308a2b93273242..23ee558cc17b0d41cd688ff0366995ffaa39c29d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:transparent-basic.rs
 
 #![feature(decl_macro, rustc_attrs)]
index 741685fe9b64995a85b95356e9434532110c5f70..3447f358d85f12e393ba9212b02f61d0aef81a42 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn macros() {
     macro_rules! foo{
index 20d778d20aef9d47e35f663d874ea8703557a2c3..9d7b2f2d088cc3908356aa5ca9a21d711cfc2f54 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct Foo<'a>(&'a u8);
 
index 26bd435cbac969aae33b556a8fc2b898ee9fd399..130de9ccf621d8f1197ef92397d4a9e730e3d580 100644 (file)
@@ -1,5 +1,5 @@
 #![feature(existential_type)]
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait Bar {}
 struct Dummy<U>(U);
index cc974ffea7bbc48a842b39fa3ed23e38a7b05722..0e83b4084b6ac32ffc73a1c611879c643732b7e0 100644 (file)
@@ -1,5 +1,5 @@
 #![feature(existential_type)]
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait Bar {}
 struct Dummy;
index 38511bd062c85d5a56bfc1754e9a11fac23572de..58966aefe1c32d9c24c12f81410ebf07080b4757 100644 (file)
@@ -1,5 +1,5 @@
 #![feature(existential_type)]
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait Bar {}
 struct Dummy;
index 90a7519074b53bebbda8c04bc9f7d3197aa34af6..7ae1ac4f5767cafd9c58fe9b16e5b2a87dea66cc 100644 (file)
@@ -10,7 +10,7 @@
 // concrete type against the bound, which forces the return type to be
 // `&'static i32` here.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn make_identity() -> impl Sized {
     |x: &'static i32| x
index dd9f5fd4647e0f5eb137a86ee7476e20a9fd58d7..f76724c8ab11daa2506377b2c631d2d7e3640f5f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(warnings)]
 
index c93c6a499bc75dfff49fc537acebb4dfa03305e5..6d3c0692970dc614151b6f71c372889420b6d024 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {}
 
index b29ae064b76c4d486d1e2d188433f42d4429eccf..32fc4a97ef44d9fe89957cd2d6234917d391ebf7 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(existential_type)]
 
index 2da15ac5b6e7e24239eff34999792c97135d26c6..7d69cd0a3038f5b65325b3eec85459de9c4f9cca 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::iter::once;
 
index 13671b8dbf448f2d4ef92d24fca8a987edf9f059..12e69b16adf0bffba81958e6ef65561ad35df049 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Tests for nested self-reference which caused a stack overflow.
 
index eb4456a0d592e1a37d4da91fe2e965d993ba9baa..ac26c10e55d838b1f23cc77b9a0b1969e17dda49 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(warnings)]
 
index 50646edd61a8585f6de31b7dd87dc062839e21e1..0c07101bb7ba0cd75e2f72b6dfb28d60742bd602 100644 (file)
@@ -1,7 +1,7 @@
 // This used to ICE because it creates an `impl Trait` that captures a
 // hidden empty region.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn server() -> impl FilterBase2 {
     segment2(|| { loop { } }).map2(|| "")
index 11f1a392239dcdeb491afbe0b5615ad47e49398e..ed066ce19243eecd1a93bd8e12ad49b0643ecd1e 100644 (file)
@@ -5,7 +5,7 @@
 // opaque type. As all regions are now required to outlive the bound in an
 // opaque type we avoid the issue here.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct A<F>(F);
 
index 8346542135becfc93c61d5ac02c844f392f2f1e8..92e5ea2f49df8cfd6b5ba251459e4e62e8f99e54 100644 (file)
@@ -1,5 +1,5 @@
 // Test that multiple liftimes are allowed in impl trait types.
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait X<'x>: Sized {}
 
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs
new file mode 100644 (file)
index 0000000..61e858e
--- /dev/null
@@ -0,0 +1,22 @@
+// compile-flags:-Zborrowck=mir
+
+#![feature(member_constraints)]
+#![feature(existential_type)]
+
+#[derive(Clone)]
+struct CopyIfEq<T, U>(T, U);
+
+impl<T: Copy> Copy for CopyIfEq<T, T> {}
+
+existential type E<'a, 'b>: Sized;
+
+fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
+    //~^ ERROR lifetime may not live long enough
+    let v = CopyIfEq::<*mut _, *mut _>(&mut {x}, &mut y);
+    let u = v;
+    let _: *mut &'a i32 = u.1;
+    unsafe { let _: &'b i32 = *u.0; }
+    u.0
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.stderr b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.stderr
new file mode 100644 (file)
index 0000000..b59dfbe
--- /dev/null
@@ -0,0 +1,12 @@
+error: lifetime may not live long enough
+  --> $DIR/error-handling.rs:13:56
+   |
+LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
+   |        -- lifetime `'a` defined here                   ^^^^^^^^^ opaque type requires that `'a` must outlive `'static`
+help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a constraint
+   |
+LL | existential type E<'a, 'b>: Sized; + 'a
+   |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs b/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs
new file mode 100644 (file)
index 0000000..2da3886
--- /dev/null
@@ -0,0 +1,54 @@
+// edition:2018
+// run-pass
+// revisions: migrate mir
+//[mir]compile-flags: -Z borrowck=mir
+
+#![feature(member_constraints)]
+
+trait Trait<'a, 'b> {}
+impl<T> Trait<'_, '_> for T {}
+
+// `Invert<'a> <: Invert<'b>` if `'b: 'a`, unlike most types.
+//
+// I am purposefully avoiding the terms co- and contra-variant because
+// their application to regions depends on how you interpreted Rust
+// regions. -nikomatsakis
+struct Invert<'a>(fn(&'a u8));
+
+fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Invert<'a>, b: Invert<'b>) -> impl Trait<'d, 'e>
+where
+    'c: 'a,
+    'c: 'b,
+    'd: 'c,
+{
+    // Representing the where clauses as a graph, where `A: B` is an
+    // edge `B -> A`:
+    //
+    // ```
+    // 'a -> 'c -> 'd
+    //        ^
+    //        |
+    //       'b
+    // ```
+    //
+    // Meanwhile we return a value &'0 u8 where we have the constraints:
+    //
+    // ```
+    // '0: 'a
+    // '0: 'b
+    // '0 in ['d, 'e]
+    // ```
+    //
+    // Here, ignoring the "in" constraint, the minimal choice for `'0`
+    // is `'c`, but that is not in the "in set". Still, that reduces
+    // the range of options in the "in set" to just `'d` (`'e: 'c`
+    // does not hold).
+    let p = if condition() { a } else { b };
+    p
+}
+
+fn condition() -> bool {
+    true
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.stderr b/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.stderr
new file mode 100644 (file)
index 0000000..4de872e
--- /dev/null
@@ -0,0 +1,19 @@
+warning[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/inverse-bounds.rs:16:70
+   |
+LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Invert<'a>, b: Invert<'b>) -> impl Trait<'d, 'e>
+   |                                                                      ^^^^^^^^^^^^^^^^^^
+   |
+   = note: hidden type `Invert<'_>` captures lifetime '_#8r
+   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
+   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
+   = note: for more information, try `rustc --explain E0729`
+
+warning: the feature `pin` has been stable since 1.33.0 and no longer requires an attribute to enable
+  --> $DIR/inverse-bounds.rs:4:60
+   |
+LL | #![feature(arbitrary_self_types, async_await, await_macro, pin)]
+   |                                                            ^^^
+   |
+   = note: #[warn(stable_features)] on by default
+
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs
new file mode 100644 (file)
index 0000000..553dea7
--- /dev/null
@@ -0,0 +1,29 @@
+// edition:2018
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: migrate mir
+//[mir]compile-flags: -Z borrowck=mir
+
+#![feature(member_constraints)]
+
+trait Trait<'a, 'b> { }
+impl<T> Trait<'_, '_> for T { }
+
+// Test case where we have elision in the impl trait and we have to
+// pick the right region.
+
+// Ultimately `Trait<'x, 'static>`.
+fn upper_bounds1(a: &u8) -> impl Trait<'_, 'static> {
+    (a, a)
+}
+
+// Ultimately `Trait<'x, 'x>`, so not really multiple bounds.
+fn upper_bounds2(a: &u8) -> impl Trait<'_, '_> {
+    (a, a)
+}
+
+// Kind of a weird annoying case.
+fn upper_bounds3<'b>(a: &u8) -> impl Trait<'_, 'b> {
+    (a, a)
+}
+
+fn main() { }
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-existential.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-existential.rs
new file mode 100644 (file)
index 0000000..43915e0
--- /dev/null
@@ -0,0 +1,32 @@
+// edition:2018
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: migrate mir
+//[mir]compile-flags: -Z borrowck=mir
+
+#![feature(member_constraints)]
+#![feature(existential_type)]
+
+trait Trait<'a, 'b> { }
+impl<T> Trait<'_, '_> for T { }
+
+// Here we wind up selecting `'a` and `'b` in the hidden type because
+// those are the types that appear in the original values.
+
+existential type Foo<'a, 'b>: Trait<'a, 'b>;
+
+fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> Foo<'a, 'b> {
+    // In this simple case, you have a hidden type `(&'0 u8, &'1 u8)` and constraints like
+    //
+    // ```
+    // 'a: '0
+    // 'b: '1
+    // '0 in ['a, 'b]
+    // '1 in ['a, 'b]
+    // ```
+    //
+    // We use the fact that `'a: 0'` must hold (combined with the in
+    // constraint) to determine that `'0 = 'a` must be the answer.
+    (a, b)
+}
+
+fn main() { }
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs
new file mode 100644 (file)
index 0000000..c0930ec
--- /dev/null
@@ -0,0 +1,29 @@
+// edition:2018
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: migrate mir
+//[mir]compile-flags: -Z borrowck=mir
+
+#![feature(member_constraints)]
+
+trait Trait<'a, 'b> { }
+impl<T> Trait<'_, '_> for T { }
+
+// Here we wind up selecting `'a` and `'b` in the hidden type because
+// those are the types that appear in the original values.
+
+fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
+    // In this simple case, you have a hidden type `(&'0 u8, &'1 u8)` and constraints like
+    //
+    // ```
+    // 'a: '0
+    // 'b: '1
+    // '0 in ['a, 'b]
+    // '1 in ['a, 'b]
+    // ```
+    //
+    // We use the fact that `'a: 0'` must hold (combined with the in
+    // constraint) to determine that `'0 = 'a` must be the answer.
+    (a, b)
+}
+
+fn main() { }
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs
new file mode 100644 (file)
index 0000000..ed36bda
--- /dev/null
@@ -0,0 +1,46 @@
+// edition:2018
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: migrate mir
+//[mir]compile-flags: -Z borrowck=mir
+
+#![feature(member_constraints)]
+
+trait Trait<'a, 'b> {}
+impl<T> Trait<'_, '_> for T {}
+
+// `Ordinary<'a> <: Ordinary<'b>` if `'a: 'b`, as with most types.
+//
+// I am purposefully avoiding the terms co- and contra-variant because
+// their application to regions depends on how you interpreted Rust
+// regions. -nikomatsakis
+struct Ordinary<'a>(&'a u8);
+
+// Here we wind up selecting `'e` in the hidden type because
+// we need something outlived by both `'a` and `'b` and only `'e` applies.
+
+fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
+where
+    'a: 'e,
+    'b: 'e,
+    'a: 'd,
+{
+    // We return a value:
+    //
+    // ```
+    // 'a: '0
+    // 'b: '1
+    // '0 in ['d, 'e]
+    // ```
+    //
+    // but we don't have it.
+    //
+    // We are forced to pick that '0 = 'e, because only 'e is outlived by *both* 'a and 'b.
+    let p = if condition() { a } else { b };
+    p
+}
+
+fn condition() -> bool {
+    true
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr
new file mode 100644 (file)
index 0000000..a255c48
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ordinary-bounds-unrelated.rs:18:74
+   |
+LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
+   |                                                                          ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs
new file mode 100644 (file)
index 0000000..db1641b
--- /dev/null
@@ -0,0 +1,38 @@
+// edition:2018
+
+#![feature(member_constraints)]
+
+trait Trait<'a, 'b> {}
+impl<T> Trait<'_, '_> for T {}
+
+// `Ordinary<'a> <: Ordinary<'b>` if `'a: 'b`, as with most types.
+//
+// I am purposefully avoiding the terms co- and contra-variant because
+// their application to regions depends on how you interpreted Rust
+// regions. -nikomatsakis
+struct Ordinary<'a>(&'a u8);
+
+// Here we get an error because none of our choices (either `'d` nor `'e`) are outlived
+// by both `'a` and `'b`.
+
+fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
+//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
+where
+    'a: 'e,
+    'b: 'd,
+{
+    // Hidden type `Ordinary<'0>` with constraints:
+    //
+    // ```
+    // 'a: '0
+    // 'b: '0
+    // 'a in ['d, 'e]
+    // ```
+    if condition() { a } else { b }
+}
+
+fn condition() -> bool {
+    true
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr
new file mode 100644 (file)
index 0000000..cd2d46a
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ordinary-bounds-unrelated.rs:18:74
+   |
+LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
+   |                                                                          ^^^^^^^^^^^^^^^^^^
+   |
+note: hidden type `Ordinary<'_>` captures the scope of call-site for function at 23:1
+  --> $DIR/ordinary-bounds-unrelated.rs:23:1
+   |
+LL | / {
+LL | |     // Hidden type `Ordinary<'0>` with constraints:
+LL | |     //
+LL | |     // ```
+...  |
+LL | |     if condition() { a } else { b }
+LL | | }
+   | |_^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr
new file mode 100644 (file)
index 0000000..af42ed1
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ordinary-bounds-unsuited.rs:20:62
+   |
+LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
+   |                                                              ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs
new file mode 100644 (file)
index 0000000..7f9c92f
--- /dev/null
@@ -0,0 +1,41 @@
+// edition:2018
+
+#![feature(member_constraints)]
+
+trait Trait<'a, 'b> {}
+impl<T> Trait<'_, '_> for T {}
+
+// `Ordinary<'a> <: Ordinary<'b>` if `'a: 'b`, as with most types.
+//
+// I am purposefully avoiding the terms co- and contra-variant because
+// their application to regions depends on how you interpreted Rust
+// regions. -nikomatsakis
+struct Ordinary<'a>(&'a u8);
+
+// Here we need something outlived by `'a` *and* outlived by `'b`, but
+// we can only name `'a` and `'b` (and neither suits). So we get an
+// error. Somewhat unfortunate, though, since the caller would have to
+// consider the loans for both `'a` and `'b` alive.
+
+fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
+    //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
+{
+    // We return a value:
+    //
+    // ```
+    // 'a: '0
+    // 'b: '1
+    // '0 in ['a, 'b]
+    // ```
+    //
+    // but we don't have it.
+    //
+    // We are forced to pick that '0 = 'e, because only 'e is outlived by *both* 'a and 'b.
+    if condition() { a } else { b }
+}
+
+fn condition() -> bool {
+    true
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr
new file mode 100644 (file)
index 0000000..59ce93f
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ordinary-bounds-unsuited.rs:20:62
+   |
+LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
+   |                                                              ^^^^^^^^^^^^^^^^^^
+   |
+note: hidden type `Ordinary<'_>` captures the scope of call-site for function at 22:1
+  --> $DIR/ordinary-bounds-unsuited.rs:22:1
+   |
+LL | / {
+LL | |     // We return a value:
+LL | |     //
+LL | |     // ```
+...  |
+LL | |     if condition() { a } else { b }
+LL | | }
+   | |_^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0700`.
index 2a5b365559e7788e82c9c88c8b84c8bd4408c666..52475f65a8353b0849060018056a7b15c446d53b 100644 (file)
@@ -1,10 +1,24 @@
+// run-pass
+
+#![feature(member_constraints)]
+
 use std::fmt::Debug;
 
 trait MultiRegionTrait<'a, 'b> {}
 impl<'a, 'b> MultiRegionTrait<'a, 'b> for (&'a u32, &'b u32) {}
 
 fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> {
-//~^ ERROR ambiguous lifetime bound
+    // Here we have a constraint that:
+    //
+    // (x, y) has type (&'0 u32, &'1 u32)
+    //
+    // where
+    //
+    // 'a: '0
+    //
+    // then we require that `('0 u32, &'1 u32): MultiRegionTrait<'a,
+    // 'b>`, which winds up imposing a requirement that `'0 = 'a` and
+    // `'1 = 'b`.
     (x, y)
 }
 
diff --git a/src/test/ui/impl-trait/needs_least_region_or_bound.stderr b/src/test/ui/impl-trait/needs_least_region_or_bound.stderr
deleted file mode 100644 (file)
index f1b4d9c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: ambiguous lifetime bound in `impl Trait`
-  --> $DIR/needs_least_region_or_bound.rs:6:55
-   |
-LL | fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> {
-   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other
-
-error: aborting due to previous error
-
index 9c9397999ff679c5f060b65432a0f072e1d89472..244293be7263643afc18348ccfbd2da52b94de2b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Test that `extern crate self;` is accepted
 // syntactically as an item for use in a macro.
index 6f6343a614886f0ed74518dfc669bb23898ce528..9cebb622eeda3f9ee2abd8037e6a07719adf4ddb 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 extern crate self as foo;
 
index cf91a9714ade089255f619b758e72234694856fc..30d87f90b30a535655b00294b6c863374158d892 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
 macro_rules! define_iso { () => {
index 6117e5f6f3cd76681303d344f7805e49190b4af2..cfae08fccaa4b72dc5e683fdfb4841f4cca89d1d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags:--cfg my_feature
 
 #![no_std]
index bb4cf6ca99c752e87e87d5911a6c4ea272e45101..c87d58f63e257b5ef92fb8b0e503c928841b60de 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:two_macros.rs
 
 extern crate two_macros;
index c5adeaf17fa9285c942b73bf0a812781d076e97b..9e69a27d7c4ce809380b67c3501480801363625d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:two_macros.rs
 
 extern crate two_macros as core;
index 317441079ff87c71953eaa45dec3eefb24e28f0e..613ccc0b2423460b766530d7f8b3db761acf2c2a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 // aux-build:gensymed.rs
 
index dbfba2c94339a61f28baea7339731f084d1d5147..1854ddf96b8db59a0f296a01b3c7c98832dc138b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 mod m {
     pub struct S(u8);
index 95316777fabf6330f8edd0e048207f362b92f65f..8cb602d868cd4c1e996bbe18095515580a63f41d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:issue-55811.rs
 
 extern crate issue_55811;
index 4113d4390c3c9d1fa16ad39ddeece67f2dbb9814..4763ae4be9995aff2cb940bea3ca9b7b62660cbf 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
 use ::std;
index 59aac952b92995d2ce83f77a32246796ab2f1098..b52ddaf89549e715e3889351c3ebc2c216836c0a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 macro_rules! define_exported { () => {
     #[macro_export]
index a073fe26eb619637637dc7b54f75fff00ccc7bc6..8eeb1cf07bb1a1638a359ddee891b51a2ee0e585 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #[macro_export(local_inner_macros)]
 macro_rules! dollar_crate_exported {
index 513b15ed088d87e47e63a2a33b9110de439f8324..a90b268db8c95d11e32835d81d4897525b0bd0b1 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // tests that the following code compiles, but produces a future-compatibility warning
 
index 92b21c4efa3a2a992fec62fd6bbefa9eedd10361..3d65cfc2340926f6b7e07a08c4d23a6b24b15245 100644 (file)
@@ -1,3 +1,4 @@
+#![allow(deprecated)]
 #![feature(core_intrinsics)]
 
 use std::intrinsics::{init};
index 857142dff64b7eb95e0188abefb88db7e930fd74..e1126316af34ee3ab4f0839bc18f80a663d3e47e 100644 (file)
@@ -1,5 +1,5 @@
 error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
-  --> $DIR/init-unsafe.rs:7:17
+  --> $DIR/init-unsafe.rs:8:17
    |
 LL |     let stuff = init::<isize>();
    |                 ^^^^^^^^^^^^^^^ call to unsafe function
index d2347c3077cf33a11bc191c161fdea8b4acbc939..4718aea0429c2148f8dd4addc9ebba7e06ff288a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // This test is the same code as in ui/symbol-names/issue-60925.rs but this checks that the
 // reproduction compiles successfully and doesn't segfault, whereas that test just checks that the
index d8e9aec81806e54accde2ba0b01d7ff54048e813..0781e5e3ed99080126f6c9d13caf5c4cc419c6e4 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #[derive(Debug)]
 enum Foo<'s> {
index 4b548362f4affdfe17789073aa989387091c6d40..7eac095de5da496d415e00500e1e0e8a9571b868 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 pub struct Foo;
index ceb44ecf7f58379dea230ebdf0588cfa2c724e63..111078abb37007a5a7538a71247c3c304365f864 100644 (file)
@@ -11,13 +11,9 @@ macro_rules! bar{() => (())}
 pub fn main() {
     foo!();
 
-    assert!({one! two()});
-    //~^ ERROR macros that expand to items
-    //~| ERROR cannot find macro `one!` in this scope
-    //~| ERROR mismatched types
+    assert!({one! two()}); //~ ERROR expected open delimiter
 
     // regardless of whether nested macro_rules works, the following should at
     // least throw a conventional error.
-    assert!({one! two});
-    //~^ ERROR expected `(` or `{`, found `}`
+    assert!({one! two}); //~ ERROR expected open delimiter
 }
index 584cdf43a8f4bafe862d2faab3869be92d290c04..73f948107f185fe2950ac2b4f1e6fd8beb2881ae 100644 (file)
@@ -1,38 +1,14 @@
-error: macros that expand to items must be delimited with braces or followed by a semicolon
-  --> $DIR/issue-10536.rs:14:22
+error: expected open delimiter
+  --> $DIR/issue-10536.rs:14:19
    |
 LL |     assert!({one! two()});
-   |                      ^^
-help: change the delimiters to curly braces
-   |
-LL |     assert!({one! two {}});
-   |                       ^^
-help: add a semicolon
-   |
-LL |     assert!({one! two();});
-   |                        ^
+   |                   ^^^ expected open delimiter
 
-error: expected `(` or `{`, found `}`
-  --> $DIR/issue-10536.rs:21:22
+error: expected open delimiter
+  --> $DIR/issue-10536.rs:18:19
    |
 LL |     assert!({one! two});
-   |                      ^ expected `(` or `{`
-
-error: cannot find macro `one!` in this scope
-  --> $DIR/issue-10536.rs:14:14
-   |
-LL |     assert!({one! two()});
-   |              ^^^
-
-error[E0308]: mismatched types
-  --> $DIR/issue-10536.rs:14:13
-   |
-LL |     assert!({one! two()});
-   |             ^^^^^^^^^^^^ expected bool, found ()
-   |
-   = note: expected type `bool`
-              found type `()`
+   |                   ^^^ expected open delimiter
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
index f2d4c5b47d782d8302f1e7d2a22d746bc5a5f8f6..091a7c52963426e561a518a2710d7c4b521c9971 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 0b74eaddcdd3a498d017056c6a4cb50a657da0c8..c9de39feda6913181803d4b05c208c837537144c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 #![deny(missing_docs)]
index 5e7f8ed7fd5d260d91347a5b8b43e6bc8cf1859b..d53ce9a1db86fd714f0b4aeb09d59f3e2de0d17c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 59d85b175cf6942e6c6f3c5887e8b7ff279d0e01..443c2be08bbd028d54822870c494f0ae6c903ff7 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 trait Common { fn dummy(&self) { } }
index e2028bd56f9bf0b0328c6706fb9babb1368bbe08..0298f83baf81c2e590c73ac81859e601aa890f70 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 //! Ensure the private trait Bar isn't complained about.
 
 #![deny(missing_docs)]
index fd4fb2443cbe7487fc23550303afe38462382aef..553648a5ebc2ec1879ce6f0f64c4cfba7cc827c2 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // #11612
 // We weren't updating the auto adjustments with all the resolved
index e62879f1f29ea175e729ea623d35b9744a627580..a44094bfb2391670c97a95dc31e584a1c464e0fa 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 84a14a8c09be6591f550b59ca9b3d871a87142d1..63b5a4dd1b31a72960aa4151e3c4795af776dd8e 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused_attributes)]
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
index c2572c78280eb3541af75596514e5e4acdb89230..67c1bdc32ede9085aaa4419fb1728cf213f9f59b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 0e118043d5564a54a3990f7688ed5ef1d7c90a81..2410e2f1367040d438bacd2453544fe44d120471 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 trait Foo {
index dcc25a446fad600d8c853586ce21867cdc5b753e..e04faabb7e8e0370bd819e9305e3fb0f08604a25 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 use std::slice;
index af2d95c5e4286d5dbbb43dd0955128ab88a72f86..0015169b11798109e5b9ef3777a43bb4d747775a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // defining static with struct that contains enum
 // with &'static str variant used to cause ICE
index 32965cb0c6d8c25c8a36c6e1ba55831c3e06437d..fb48abe26484ae45ffe1bb29c496fe8b112ce8d9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(unused_variables)]
 // pretty-expanded FIXME #23616
index 212fff7bcecd7a65c8912febb707617106435c19..fe5458a7d7c07b5887e3785ad1ed91f99529c05c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 pub struct Foo<'a, 'b: 'a> { foo: &'a &'b isize }
index 39e42dc2c0d5aa49b487c6e6f552ea13ce0173ac..0359bb581d5858e6157eb462abc5b5d7b44e43f2 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 trait Foo {
index d475ce1d833196ada4388faa8df6cb2f56e6b80e..06790fbd32457450a23b673cfc57316f6fa960a9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 4849077c144e1eb399ced895fa038ee3d837e5a9..e5f1b492f275be98571a07f6bea7b9d6fe7941ce 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 #![allow(unused_imports, dead_code)]
index 3ad388dc2d79019f198ed383c0d69ae2acca1e7c..8b04fa192ada1d11ec585e2138d51e831ee8a765 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 trait Foo: Sized {
index d8f225eb07c242b6f6aec9f22e8b6a307a2f78d6..be31fa5eabc592106b267bbd4e3a143d043609a6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused_imports)]
 // pretty-expanded FIXME #23616
 
index 54387804affebd646c7c1552a48e7b648ad12072..a276e27f9dcc45e8eac18ff592059fb10ca9e83a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 #[deny(dead_code)]
index 9b89c1631df15236faa81b91262eeb22d5dc3fdc..c164658331e9336d6a4a47906e1f47a1d2dc3a10 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 pub trait Reader {}
 
 enum Wrapper<'a> {
index 9249ba3d6466e992391ab3264ba4736968084b67..f229c0f7c26cfe781c587763d806dc9366e71722 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 pub type BigRat<T = isize> = T;
index bd3c99ad8d78b8eddfa103c9b6608e0f22445c8a..809a1088992a0bf545c73cde512efa8c3134b885 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused_macros)]
 #![allow(dead_code)]
 #![feature(asm)]
index 60daaafbcc8bd27ca49806503aef445a66317e88..bd6c7a2bda9f002f2e26712eae86e820514bd58c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 #![feature(fn_traits, unboxed_closures)]
index d2b56c0949d633613be1cfd63f7b8f129cbb7a6f..b8231ad4e8326ba0f698cc4a1ff074844df60b84 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 fn main() {}
index 4119cb055c590e101b73d83f498b106951991d9b..dd859475f9c8e06c58ecdeaf246e749e5269df70 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
index 4a1326113910e61cb8d1b38c00e7315958b64dc3..1731a356ccd195090b59bf38019c8441d79edd2f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 20634cc388110f83fd5b2e84e194e44b4c66f523..0da4d4a620bf9e620388a6cc0a25f4ab34656448 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 struct A<'a> {
     a: &'a i32,
index 3aa6c20ec57ec3d4c80529826982b34706d951be..693dea436bb06830b587a92b580365d197e98e5c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 trait MatrixRow { fn dummy(&self) { }}
index b570a2ced67bcea61f637a9b2e610b713fb8a0dc..a898ab20a48872acfabd13c77a410f3bc96ba19e 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 struct Parser<'a, I, O> {
     parse: Box<dyn FnMut(I) -> Result<O, String> + 'a>
index 706350fc1e205262f5c353a04c6fff73eefd306c..0f1d4f5410d57e9ff88170f5096b2f7c592f9649 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 // ignore-cloudabi no std::fs
index dce30275ff354bf391c9aae7219acb9b94a6ed9a..f24acb7b304e60508cebbdcd86dfcd820e550b54 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(box_syntax)]
 
index e2c0e8b91cceadfd8459adae962263807f44fe22..830d799fb652fee5ef96693e0fef36a2da0557fa 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused_must_use)]
 #[allow(dead_code)]
 fn check(a: &str) {
index 70f33e3e661813c3968f20881900ceeeefcf8800..595e0a4d25c65a7793dad94f92aa472ed092a7fe 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code, warnings)]
 
 static mut x: isize = 3;
index 133420b688ec24bc33976a42bfa34a81513cf847..7ec025ec3af756da0d92395b77e80a2ef387c37f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 struct A;
 impl Drop for A {
index 7993bbb38bb4abc7160e3a6ed4a94b532ec9c214..17135c191cafb0b0a5fe6620a34860f14ea9c2b2 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 45c5b858ecd177b66e684713d8b21361a4b90212..847b2eb60bbb55ff83e954a9aa39ba8cc07ff69c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Regression test for #17746
 
index 2fe54957b3c082f53bcdd690fd3309b5755d083e..d916abb9c73846a67e5882f209574a3259d307b5 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Test that we can parse where clauses on various forms of tuple
 // structs.
index c2cf2919ff0c501404aa77fb1386426d2b8351c6..f159ed4a0ceccbc788ba7c19096a40401ca42c99 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(unused_imports)]
 // These crossed imports should resolve fine, and not block on
index 67000d9a6ec3f5dd0f4583c8c93aef3a86e4bc34..06f259958f82236d83d172e62cadfbf54f274d7a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 pub trait Indexable<T>: std::ops::Index<usize, Output = T> {
     fn index2(&self, i: usize) -> &T {
index 4d0c4464759c6ee85edfdf37bb726d9c3798ecdb..da10a8647bac621fd738ea9d27ef1e5f6a65470f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 pub trait Promisable: Send + Sync {}
index 0177b70a6988504244096e7bf1c88142788a919e..db97a507b689aa57de3e9bfca9b8039e90f48e45 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
index 3e04a914d4586fbc4b3ca8edbf8ddc15aa415866..6b984c13da5d341cdeb0434891acd5c8e0a90fb6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Test that methods in trait impls should override default methods.
 
index 3de547bfe6fce822c6c7ecbc8a47b69fd8c1b9bf..0223e2ebea926a855406304ad4c2c82e19432b96 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
index c3bd022fa443c888289cf479f4b692b2f2eb9466..ec4429234bc59c44fe07b9f99057fc5ad33ba27d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #[derive(Eq, PartialEq, PartialOrd, Ord)]
 enum Test<'a> {
index fb31666b22eb543ee24ccb36342f978f4aa91e94..9b8275f81199932e277e7eda1a046061b71714c2 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 trait Tup {
     type T0;
     type T1;
index 0b9625b1868efa480670f85dab111f2d8b2fbf8f..387fd41fb7ae749b2a6cf1b083575d3f1380ae69 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 7fe662e907d733f3fc6af5f623ec3460a821d6d1..6dbfd3a0a982a65e0a158327daba77f50ce072ba 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 pub trait Foo : Send { }
 
index 4efc0719ffbb2f74ae521a3ffde24c69ef622088..30497d3e94f588a407f97bc7d2d84b70c984d2ad 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index b487cdd5c7574e33f6a4bfbc8e7ec48713af980b..0948cd3271b1c04ef834b6652d4c232949166b1b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 pub trait Hasher {
     type State;
 
index 8055e106251577eecc1f3c7457e1e05e8bd0835c..c800e0bd12a08b100024e99e24e2f1b2a9d39132 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // regression test for #19097
 
index 690fe944097c0033ccb02bcb771bcd2dce02eefb..37c0d7f05222bba5694765b8595a57126dea6369 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 pub trait Handler {
     fn handle(&self, _: &mut String);
 }
index 962cd8d3f6f54f21496fb670fb01898168d68bdd..76ed3efc4ed4936e1aeb131729663c1e995408d2 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused_imports)]
 #![deny(unused_qualifications)]
 
index 4be2cc6d1797b17c186a4196ef9169b56bb27608..e17ee053f33d8f66cc01c9efc6925f29f18c6c90 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 trait Trait<Input> {
index d11ef8af709ef10fa74e64f1ea8019eb33934e14..30c64573a15329e3dee411ee2cb50a76df8ad60d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused_variables)]
 // pretty-expanded FIXME #23616
 
index 5daa14b7cb7bb64e43a39785de03fbe657ecc8ba..28d266a1d61a2e27bfd03070b578640ae79d51b5 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 trait T {
index 59544393bae05f02fddc75ddba568ff454572c9c..40c9fdac7b01fb31bf7f0558e7b72a42d4267637 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(unused_variables)]
 use std::any::TypeId;
index 8b78952a6e2b1ded217620bbcf3c0c7a5b181192..c134d85c7e93d34c43c73e401c82e1375ec3730c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 trait Base {
index 8c58331e581b7e375c10607aeacfe8a32c49f086..015758dd6e1d29e439fa728fa87dbdec1d395328 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index b032b67c1ebd1216971459afac6df3f0e0502d35..ddd87a9f6e978ad1ffad5cc70b78f26291cd2a8f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index fb64ef89405577148098df31d5e50a8a30605957..d51cf0cfcb9807b3681db24f0102e90a36db38c8 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused_variables)]
 // Test that `<Type as Trait>::Output` and `Self::Output` are accepted as type annotations in let
 // bindings
index 6b5a4b2c10edae43b00d224d0836120a949899bc..fb88781ee283a4d7f95a1c503128ea364c3b925b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(fn_traits, unboxed_closures)]
 
index 6228d044ad11ac588170ac8a0fd6c46b2a8e1f4c..730f1a9a162a2b5830318b3a7ee7ae38c6983312 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // Check that associated types are `Sized`
 
 // pretty-expanded FIXME #23616
index 4ea567d25ca537bd3a328a74b2abeccd3ec5fe2d..68e0f65ca2382921d4f7d592dfb977da4b63bf70 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(stable_features)]
 
 // ignore-cloudabi no processes
index 98d856e172a2c52b59f6acdcf543e90c313d3f59..28cbde772c51d871d72056ac3fc43e840e770e43 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(unused_variables)]
 struct Foo;
index 0e69b7f3d1e0c57892f32ecc8e94940557d72793..5e0411b2cd2593b00d179313c8c5f565b96a4c7d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
index 1653a9da0045ac95a68720e117f743bb63cfbcc8..5c6929d45d1992a8f17ec3f54fd2d1453cda813b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index d4920c0c759039737dd7aeb2906bc60b38030044..13ce1daf30a2a0cb0d573fda503c0f040db63db0 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused_must_use)]
 use std::thread;
 
index 6ed3e027ffa486a3c264e99c955ff03d0da5ca7a..ea4cbf2cedeb7fdebf22f178c8e783819768be6d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // test that autoderef of a type like this does not
 // cause compiler to loop.  Note that no instances
index db32344864c46f7488ee92893ed333dae93aa01b..bde65229ec2866a4e2e39f13a0ea5ce7f810ba7b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(unused_imports)]
 #![allow(stable_features)]
index c5b28520945910f2f3e8c13cce8841920fdc5efb..0f0ac8f6462033ef5d752e86d1850d4c877f07a7 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index cfa252b095e47855d10d63bec8ffc8e7b3d545f2..e3b566d0503408e6f83836d702d90872f80a4da5 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index e504b4705daf286dd7a0396cf2181341c25b1501..bda7e8f818b15a9290fced0de1c0ec1f74f67dff 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // ignore-cloudabi no std::fs
 
 // Regression test for #20797.
index cceed542186699512aa06a0796577e2a4fd3f3f1..7d72ef839eab71a8c263bca6f981ce8ace41b0e1 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 pub trait Subscriber {
     type Input;
 }
index 86d4e63670f3bfe52d170db964198c7435bc8e75..92834bbb0e491438d1b5907b753e6d7701353ea8 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 pub trait Trait where Self::Out: std::fmt::Display {
     type Out;
 }
index 145b062baf678ca1c72f451026c7354d57447331..351a98d5c85b74c58974b3724aedce928612f42a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(unused_variables)]
 trait Trait<'a> {
index edf482afc53d4970455e554be0321b982a249dda..d0aa16bfb1645d908b8c1f7e0632e80f19f8883a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Regression test for issue #21245. Check that we are able to infer
 // the types in these examples correctly. It used to be that
index 12efce9496efa2af5df7bbf9c9f27b33bccf51fa..d5f1eec061d206c01440e106ff5f267861f2c2a9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 #![no_implicit_prelude]
index 518d3cfe5a660848a999a35152673a0c56b559a3..21e0d58b5f4a354a47920f2cacb19f2f0591072c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 450448f1a1185b4aaef5cbce8a5bb82c90b57f6a..133bcc2360a22ea007fd3ce9d0e03528058e3f2f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Test that the requirement (in `Bar`) that `T::Bar : 'static` does
 // not wind up propagating to `T`.
index e31316d0709b0b8c08bf3fc89a9c8cb79ec10f66..2f3ee7b7490915b135f37353815d7a3429cfbfcb 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
index 2b80f2f36c5ad1754b3f0ad7348abc81d40bdfe8..4aae089943f5b2abc761e0510c5b02760eebc388 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(unused_variables)]
 
index 8941bb1c2432128780393e82c6d061b1917ffb68..36b207bb2a481714a6de00c57e895f65f0535fcf 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(stable_features)]
 
 #![feature(cfg_target_feature)]
index f2065976b35d050b7313ca6624e3fb2d49155b75..1c8284c8295dcaee3a62816e5daf96c75111da3a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Regression test for #21726: an issue arose around the rules for
 // subtyping of projection types that resulted in an unconstrained
index 9b1e44c1817591a7d87134a9f9f12a27ab9048ec..de0aa2919cfbc0be87e83bfdaaee16ee0450e2b9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
index 8c0b664d78ad52c2cd15d5c2d4822817cf3be270..fbf31aa42437cd772960bfe071ca03281d5fad8a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 pub trait LineFormatter<'a> {
     type Iter: Iterator<Item=&'a str> + 'a;
     fn iter(&'a self, line: &'a str) -> Self::Iter;
index 3f3b1d3e5f1d9f5732c962215e3b04fd51932616..ec4695e5e0ac50cb63b4b30dcafb54df40e68d40 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(type_alias_bounds)]
 
 // pretty-expanded FIXME #23616
index bae7b2bfab4535b991df38a3230fac406f2103e7..201aea3a05c00bbdc24130ce668c55cd35c2a7bc 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 trait A<T: A<T>> {}
 
 fn main() {}
index a22c7e6173e1745caf6802705b78aa7807e2ffb4..befccc19bf8ef1919b0644c8c1d8e39457202457 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(type_alias_bounds)]
 
index f9b264623d6bb4c65a8f51ee1abb8ea9800c808e..81efb250dfa960ffa6187a7cb67db4fae00124c1 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // This test is reduced from libsyntax.  It is just checking that we
 // can successfully deal with a "deep" structure, which the drop-check
 // was hitting a recursion limit on at one point.
index a7b94c106a4c8a7680b9b132beff7ff4f089788a..37f40aa0421407cc9c0a0b2048368be7ea1c4778 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused_variables)]
 use std::collections::HashMap;
 use std::collections::hash_map::Entry::Vacant;
index bcc7a8a5ae0a3255845de805d45abd2408565780..065e7edc67e078f81fe239f6690d17b62377bc19 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 trait Test {}
 
 macro_rules! test {
index f5b26de54f5195bcd98176b59f2c5dba4e35b57f..7b1513a10c0efce1c1d0c1fa45634f95f484a905 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #[allow(dead_code)]
 static X: &'static str = &*"";
 fn main() {}
index 40cda23186a47f871ce1ba9b65378a6bccdb1a49..f735338fcdbc93437bb770e6f354e3c2f89e056b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
index 07b9951e68d3975d6cf4037d964027833619a7f9..151ad4e26645bd80e3fa8f713963b81df2f16cc5 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(non_camel_case_types)]
 
 // pretty-expanded FIXME #23616
index 1fc7b5a3f34c59e0beb8c6fbf7ff2cad9e612cf2..b445f9581b345791688ba246d31e0ffe57897657 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
index 9d77af0914f1754f95b58dfca07ec090857d41ba..2e57b16e3c7f06f64ca44affd7c21b78c432fd6a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 trait Inner {
     type T;
index c3b613a06cdfe340d8ee80f2c2999eee16e4448d..659e1e07942fe9078a3f4131eb342b1885893582 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 use std::marker::PhantomData;
 
index f363e6a0f47306db3368babb1009c758327c9d13..b10b2e49616fb5f420b8b6e9fb2948a3c8d4a833 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compiler-flags: -g
 
 pub struct Dst {
index 370d5c5aa3ea533b67ae19620463aa70d667b954..fad0ad7eccaa47744d96b4e4ea57dbfd68c9c311 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![feature(core_intrinsics)]
 #![allow(warnings)]
 
index 718fe606b80deb8fba4e388f89bd53990897f923..febdc4256c757fd0c9207d689fc45a24856e0f02 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #[derive(PartialEq)]
 struct Slice { slice: [u8] }
 
index d06647762a9b8d67d9d984e2d1012c17f2fcbc61..dc2de922ff0082d4c3f137ade0ded10925acc232 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Regression test for #24085. Errors were occurring in region
 // inference due to the requirement that `'a:b'`, which was getting
index 99b09ba74d5d9db72e3a2d0fbfd7b719160338cc..c5c8651d43bad67e34bbe9062b5dd9c05dff09b8 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #[derive(Copy,Clone)]
 struct Functions {
index 83e12caff6dd08e9f02f3a5690fee78a06067b90..eaadaf7c449df9093e101f63331601fcc7da5f24 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // This resulted in an ICE. Test for future-proofing
 // Issue #24227
 
index fafeff06426ddc8d98013ed87d9d37413712df02..09cc99f95077a9e16276fa5b474539ed859ffaab 100644 (file)
@@ -1,5 +1,5 @@
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait DictLike<'a> {
     type ItemsIterator: Iterator<Item=u8>;
index da48a76e2007d658c23d7095710f98c8a9f3168d..63d1687af5073c46bbcbd23f813635928ea3b99d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 struct Foo;
index 2424a1c92cd644a80981c1f7f204f7a379babf85..b500b9d56dd8310552aba0dbb04c33b7595e2718 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags:--cfg set1
 
 #![cfg_attr(set1, feature(rustc_attrs))]
index 36e121ddb7ad9ab1e0742251f519f7910d367492..a43933d20202d69310db2b227cb57ba1432b13cb 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
index 29b68c94c2e7ce5b9b4774785dec302555f3545d..9a2bbb82413f68ad53534e85c8a519427397b49b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
index 297f403c05ee7353d21e8d863735ad3bfc250cb1..12f8f88a17034724df9020e5f0e070673882f606 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
index d1638aa98a0b01228dfcadf559087845bf524392..c41b554df142ae16277172f99c7baf5d276adefb 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #[derive(Debug)]
 struct Row<T>([T]);
index 31ba102746b34acb8c8217ab90a05d26ecb63c32..32b4b75b0809ceae272952cf49ab826fff0e08a2 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 enum Sexpression {
     Num(()),
index 707cf1df512c2861b983c066b5a929903c2e02e7..1e3cc902e56b20c931118f992591d0d78d6d4660 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
index 5d4b65628de8252d4af17602af327dd6983b4b1f..7335d53f8a6408a7323a06fd100febcd8804722a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Tests that impls are allowed to have looser, more permissive bounds
 // than the traits require.
index 01b71652c0538466d2ff9bdffbd44bd639a12f28..45ca998a831ef6da97b2ddfadc8a0a948d38ac1f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 use std::ops::{Deref, DerefMut};
 
index 6aa5e03996b9df2819b0a0091c10c4d5740b7462..d6f51ce9c99dc39856919257ceed61f0a8f8429b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![deny(unused_attributes)]
 
 #[repr(C)]
index dd48440720fdaad2f841eed6399f2aeb5f0ad31a..a2b32a13678a5e2c3d6f9fd5fe7c7d0dbbcc8de3 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 pub struct Foo {
     x: isize,
index 1aafa11768fd36468935bbdd830549c6df77fc3b..e7584d941ba6c126c6abd3fdbf97275b61a6eb22 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 use std::cell::RefCell;
 use std::rc::Rc;
 
index 8403d9b450787c2c3ae8be6956e0c8c2c2a99378..58b8f07bca6d8773739b459bfe9592cb441cbf40 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 pub trait Trait<'a> {
     type T;
     type U;
index 683a931cc3d5ba062979b1c6f4a033608d499b36..5f566e186eb20bf29fc10dbb1cde6d2c38aff9e6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_snake_case)]
 
index 763e9ebe24b22159a446ba6028af7898a3f4fd49..9981f867bd00b84d1f00f3b09fedb49250bda711 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // Regression test for issue #27583. Unclear how useful this will be
 // going forward, since the issue in question was EXTREMELY sensitive
 // to compiler internals (like the precise numbering of nodes), but
index 22de7c7cfa53743c711d85228cd853c56f42871c..bb5a186b457d9835e76dd1fa383cc6d05966fc45 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused_assignments)]
 #![allow(unused_variables)]
 // Test that a field can have the same name in different variants
index d5157420617d75beb522456b061095482b24db5a..68933fc2e8a3b2f28340d893508d40ddd21fdf59 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Minimized version of issue-2804.rs. Both check that callee IDs don't
 // clobber the previous node ID in a macro expr
index fab91160a88be84ee5e0ca2170462b90df94d867..e36a9551ab549cfb2f64ddfbabc601c35d5d411a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 use std::rc::Rc;
 
index 9dcce9991f73c7cb65ddee4dec90215d6df70c92..cc4e63696e5f3dc9c5ca6aa964082b87d5e7bc80 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #[derive(Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
 struct Array<T> {
     f00: [T; 00],
index 44a85924e3d54d1f0da4d09f4f5acd440f604a42..05c4050b03a43b0b8f14f202468505b0d5def7a7 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // #28600 ICE: pub extern fn with parameter type &str inside struct impl
 
 struct Test;
index 7381c348cd61a98fd94e2d5297d6eb9c26e98fe0..2c0c01aa827abc0aef9298550c2faef8aebfd887 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 fn main() {}
index b7e02b85878f27f8bc8216a04dc6093077c71033..43564dfcc46bff0b6664fe83a886163dba8dc2e9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // Regression test for #28871. The problem is that rustc encountered
 // two ways to project, one from a where clause and one from the where
 // clauses on the trait definition. (In fact, in this case, the where
index 5365adf3e80de07a4a5881dfd3969d29149ecc1c..9267491aafd9d45ea50d386cbbb1f6b0e1755717 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 pub type Session = i32;
 pub struct StreamParser<'a, T> {
     _tokens: T,
index 4f6fa412e8b93ac543920d6ad4ff99b17a680f65..888a8010a2f6bcba7a7bcf18cc860a3b55829a00 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 pub struct Xyz<'a, V> {
     pub v: (V, &'a u32),
 }
index 9ac7742e4f8db467b8a0f8e5ae12a1b06caf4946..f9e89840314d4194d2b7648f217a19c68c534550 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #[derive(Debug)]
 struct Message<'a, P: 'a = &'a [u8]> {
index e0eb71f5de6ecbf73f1a51e449ea62405eb54ff2..b1ca76be10d0b74a6ade778995824a56b646679a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // This test ensures that each pointer type `P<X>` is covariant in `X`.
 
index 42f71a1b096153d8b0774d81e537f187fe5e45ff..36bc8002f99dbbf4224e450e779dda19c4792475 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused_must_use)]
 #![allow(dead_code)]
 #![allow(unused_mut)]
index 6c4b6183c37618b89cc6812f25f07cc95f049dc5..e3ccb0d6579d7de99d774ab4f1828a5230809de8 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 pub struct Chan;
 pub struct ChanSelect<'c, T> {
     chans: Vec<(&'c Chan, T)>,
index 1ea4a54226c6c962dbdfc1f12960cb844ff3da4a..7e016a715cd1f0efc8d9a8c3b75d7ed8a38dc912 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
index 2a0358bc52ab051b52269a2d1090b1f81f43e6c4..2532dac97729337c9c57aa35692502f032ccc45d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 struct S([u8; { struct Z; 0 }]);
 
index 8082694e15c02b810d3906dac6240d010c83ff4f..8966730fd87390c4c72fe9193e91db3909f7ec63 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![feature(optin_builtin_traits)]
 
 auto trait NotSame {}
index b68205eda8615f084e03e700e7a587f8333b1760..e472f71aa7f2541d0d16db2d2d24dfa1e0ead041 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #[derive(Debug)]
 pub struct Config {
     pub name: String,
index 58907e78e48191fc1e6421e9b3e01c65700f5f05..d4de756e56fa08f1945252619c581da3780b029f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![deny(unused_results)]
 #![allow(dead_code)]
 
index f37d868ab7ebc6e064101a80f0494e65c3555562..50a03d86acb5837fab43502d07b00900637a77eb 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Regression test for #29740. Inefficient MIR matching algorithms
 // generated way too much code for this sort of case, leading to OOM.
index 5bc3b0c537a775849be6681f01750cab86e60dd2..2598b07490e95f3741ac9d21b48ff62954140ed4 100644 (file)
@@ -1,5 +1,5 @@
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     let mut i = [1, 2, 3];
index f7e717c59ac029bdcbd9387a774b31303d8e3e58..608900301e0ef049b80d82b369d2d685365f94e5 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 pub struct Struct<K: 'static> {
     pub field: K,
index c9a6f537757d090538e97de10f36bddf4854c760..da3fe9ad6ec3e51c0018591748364569c8194006 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_snake_case)]
 // pretty-expanded FIXME #23616
index 3962f13fe9b388cc189a45f01c05d3ae1111aeee..1d28a91ea7e01d726d1327d655e43742fae64067 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 trait Make {
     type Out;
index 9abbe321604b4ae2ceb615c7ce1b053ed5fe0f29..eaad98d6785374cadf8daba84f2d3d08323a3192 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 trait Resources {
index 078f3f3dd2cd22aa9e0703363e37d46c00c0bf4c..03567b20a8fa60444b378cb4017a1b13b8b0a075 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(order_dependent_trait_objects)]
 
index 51608b48be27c922a2a96b0a13249a70fe7cd4bb..e6370bc84deaf0ff25cfe5185faafa15eee7264c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // only-x86_64
 
 #![allow(dead_code, non_upper_case_globals)]
index cc47e58fcdc15a0c8180141acc60f612b0a67167..036a1e3768843c982e66238218f4c7077bf5072d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(unused_variables)]
 const A: [u32; 1] = [0];
index 4fdc8dda8b42ce24d2a407180ec4c7eca96d955b..6a8305dabebf8d9e2ff27b4213ce7606e4ea7419 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Issue 33903:
 // Built-in indexing should be used even when the index is not
index b65de91d69b26a95051c3fe1ede2614c04645bd8..ea89e4cbdeb8813746e7d1a3fca1dda5dc5d59d9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 struct A {
index 19f9f13e14416af5fe32b1ea16e5a30ca49403d0..a8ff03e2a24819ccb8cda95813d8967cf2760de0 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 // rustc --test ignores2.rs && ./ignores2
index cca06c573e0877201861980d9cfa86e126a347a3..a921cb50612ddc4fe5f155ad9741553f32a7d0fc 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // #34751 ICE: 'rustc' panicked at 'assertion failed: !substs.has_regions_escaping_depth(0)'
 
index bfe444e5d3fc02599e09a1fcf48147f39cb77c7e..3202ef64021620f05e2bd65617a300124e8720f1 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(stable_features)]
 #![feature(associated_consts)]
 
index 2a80c9f05d84bdffe471af05be6085255ed33726..b415d6554058fef39799a44bfd0a6f0e691569c3 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![feature(specialization)]
 
 fn main() {}
index 500ba48e0b71c3103c7ce76d51ad02fad940e7e4..e2f0f98d57b4fffe5e6973f53d4ac28cd9156778 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Regression test for #35546. Check that we are able to codegen
 // this. Before we had problems because of the drop glue signature
index 48f7c845d5e840d636e56dc7ff85dbd2c417cd18..5ab668eed1899e52edd7fefd811b4c3feb2fd6ae 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 trait Canvas {
index c9ca2f71341edd59952710399e71b1470ede82c4..00c8cf1fb8aba5aa6d58622b328eb84199eee49f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 trait DeclarationParser {
     type Declaration;
index 9bccb2a21e33c3ac700cd22e5ae2016f41847bb3..e8fc073a158867f5216019ae1de765805846818d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused_must_use)]
 #![allow(dead_code)]
 #![allow(unused_mut)]
index 57d63e67f3c0b1bbad397145c2a047f28f13ec39..4d03d9bbca6b6df920c36fcc1fa1149c06af5e6a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // Tests for an LLVM abort when storing a lifetime-parametric fn into
 // context that is expecting one that is not lifetime-parametric
 // (i.e., has no `for <'_>`).
index a7cf0cd1bd53de282e46e4916a011627ec00a341..61c8029adf53bd05a0a7ec893bda4904c8216605 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![allow(warnings)]
index 209f797b15cd8985febfd97271e53fe41c70e7b3..1bec3d340d6653f70625192e1042b2b020b514c1 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![feature(slice_patterns)]
 
index bfc6406b921c0297e67e53b2da85e9f575086be9..fecff4e0246064931dedbd11f8fd128623e1fce8 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // Regression test for #37655. The problem was a false edge created by
 // coercion that wound up requiring that `'a` (in `split()`) outlive
 // `'b`, which shouldn't be necessary.
index a572781f092dbd0c6bf089906263c261db626418..eefdc72f0c3b3bd5451ac12fa3cc424ff7910db2 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 trait Foo {
     fn foo(&self);
index 2dcb0cd8cee819e9075c2fb988b8aacfd3588249..c1df28331a5481a6f9f1393f6b37da5b90426e32 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 type A = for<> fn();
 
index d9f32637a90d0715c26d584f6c94b1518299b70c..3c728e9def1e91254aa342275a0de1d29df4514b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #[repr(u64)]
 enum A {
index 8a7eaf29539cb48f0570dcead9e9492d4d2613a5..b290da520804291793859dd0764a6192071676ff 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index df321b8dcbbe72b816cc690e016280704295fab5..68981eaf2b568be1d872be34a7e31de0078c7d42 100644 (file)
@@ -1,5 +1,5 @@
 // aux-build:issue-38875-b.rs
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 extern crate issue_38875_b;
 
index 27d05b470becf89ba81de16c57a9ca657f232ac6..3d4b184ab6bc5f0853fc7455a0928769cd9d21b0 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 77be9d2c76bdbb635c7a4b5e5756b9e90720e9df..12ca9e1da0ffba7c5e1ee83b1708c79aeaf6eb46 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 fn f<T: ?for<'a> Sized>() {}
 
index 077e5cefd528f01a3052eb3a462fd653a10069c3..86e67560008ea1866a8d3807d8646d59b118b3e5 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 macro_rules! expr { () => { () } }
 
index eec8c85f276c7f63ee7c3edbbb79bed2fe705e72..f3fcfd2c8fbffb578d95f804e5a78e7f8ea27592 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 trait A {
index bc63aae0b9eacf2bfda1b373f7e7d7f238c69c3a..b8ff671bf38ae6f7b95d62ca6895fb8f995dee0b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 // pretty-expanded FIXME #23616
index 5018b1c62c770d1d79b8a8ee7ff5163e0286582d..613aad1a34f1f0e01f06040d32a3cbb40f3d1046 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(unreachable_code)]
 // Regression test for issue #39984.
index 0849f54374b498284ec2f6af9d40a3c8e98d3e13..412ddafdd97ce155ce2bb1f06e0846958a9fbcf2 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 macro_rules! m { () => { 0 } }
index fc036f3edd82a8f1ee29150d434b5b4cd72c506f..6e009ba6eb4449d5781fba046a7b8e08d38668c6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(unused_mut)]
 /*
index 2304badd17dbb44c28d089cdc8c0e73fcaa17fe9..499fa8a04f207102d2ee4a2f877264b1800952f8 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused)]
 
 fn f() {
index 45cd4fd94ef8be31c495e03690244010b4c8ff1a..5fad7e4a629171e6e0ee52fa104e3771c3f0fb14 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused)]
 
 fn f() {
index 50d9276e79a3253936e037aa9f273bdb02fcdaad..c051133cbed08cc404939ba4580a55c8d1c8822a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 macro_rules! m {
     ($i:meta) => {
         #[derive($i)]
index 4a43e11f47f2e69d0a6693d800a4f9c56586bd59..9cd2003628635b2008e40c6fc3c10af23a61f4ab 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 struct Foo;
 
index e8eeabaf3a9e87136d1db9f29557cee84d618203..c719664de0d06e31ebc9187b4041de55742d536f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 struct Function<T, F> { t: T, f: F }
 
index b837a1e23466fbb473389e4367b735d85d5291f9..92369fdcd4910774a97d82455073ae596516caf6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![deny(dead_code)]
 
 #[used]
index 4dddc484d332c70fb72af14dd1eadcdf903c7043..6c6cec25a9a497f7ea7f68da6e2397c5d9b99b23 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Regression test for #41936. The coerce-unsized trait check in
 // coherence was using subtyping, which triggered variance
index e54bc201c1db32fb0ad24c07c5de8c8fd0a251ba..2f2842598fc081d006af3f7f483fc7550a162fc0 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 
 fn main() {
index 9ad515bdf5a3ac6dc449cbb18ae8fc21bc167afd..f1a55169ffdfa4eec702f72f47022a89f65b3c3f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 struct Foo<T>(T);
 
index 34cb04657eba01a42863bbea54bce72113d49f3b..8cf0ae0030693bd0991e78951902576c5b12ce9d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(stable_features)]
 #![feature(associated_consts)]
index 3ed64bba9046fb4a64aae83f0a3910f8343d0f97..7e1d5036f37f11df824fe710cdc79d81f9ccc547 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused)]
 
 macro_rules! column {
index 6b8e7de85093efeb2197cb347d23db8c1172a6fd..3090e229b6dccb9206ec8e8a6f09b21ebdcb1e76 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 trait Trait {
     type Output;
index a123ae4849661c82dd3a572e2d36b48372aa27cb..f071d110f327e3b65bb5a25946b0e0ca21f93bd5 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(unused_variables)]
 trait VecN {
index f6d1b7073a2b3d8237d5b2442c4da5cec9176fd6..f6fe9fcbd89a336d6298e9a4117e5afa03ec9116 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 pub trait Foo<'a> {
     type Bar;
     fn foo(&'a self) -> Self::Bar;
index 8ed371485c214f0094e5e00aa6d7789c8d6ce6a1..42f30bf30239a700eeb2754dd9217bd8b7de52c9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // only-x86_64
 // no-prefer-dynamic
 // compile-flags: -Ctarget-feature=+avx -Clto
index b45d541f212558431c50853f81cd5e8a229a15e6..ef244e03857bf61271e5ee66e2505bbe10b940e9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 trait T {
     type X;
index 18b2ce85125f299ac14eff2fefa3ab1f971fddd2..7fdc4b1ee5b54117cdd0bcd07d2753627f2f2887 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 struct Foo(bool);
index 7a2eaac1fd214889f08dfa1e7282dd9285b87318..29b7eb5ee49c7369e0b7281fda989fb02bc38b2d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![feature(never_type)]
 #![feature(exhaustive_patterns)]
index c20c1cad669099ee68533788cb0597ee627cac83..13df61124829d377af4fe19db01333d93650b919 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 7dae6c8123bd956f80ccfb3b7f38549fdb92f7ce..93f0445d3433e77b430af8ed0370e14632d5e15a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 //! dox
 
 #![deny(missing_docs)]
index 697b4dcf42745fe45eb283da364331258121214d..735678047a539bdcca4440f6722fee9276ef1ef8 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 macro_rules! a {
     () => { "a" }
 }
index a2ef85a2a02c9c6827599347fc52ceb2833a4e65..99e018ba6c85503b5a6dfe2338a8fc97ca98923a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 use std::ops::Add;
 
index e1147ac99ace6764e2314510a90e82ad1bfd9dea..86f1158c1985e89cbff8a67bc13b151261a1e64a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![deny(non_camel_case_types)]
 
 #[allow(dead_code)]
index 4688c9b0a1fd06881172021cda3fa854b752bd09..9cf53973d870a4154f82e73ca1d04ab2d89c6208 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 mod my_mod {
     #[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
     pub struct Name<'a> {
index 6c78a3ba964b41f729f53e2e18ba835fe4ae1c58..f17d4f88d9094308c9081106f916c8172dcbe72b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #[repr(C,u8)]
 enum Foo {
index a9aeecb61b6a5c04b2a7291eb72efe16f37b1e95..03092022d4d55e7c7712927d39237ad9d1156e22 100644 (file)
@@ -3,7 +3,7 @@
 // See https://github.com/rust-lang/rust/issues/47309
 
 // compile-flags:-Clink-dead-code
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![crate_type="rlib"]
 
index 6d7b8f9cc1b0ca863abc47e9c01b8cbc4b7577c8..0d813e2fad2c8eb9f76b073082e67be00f208fe9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused_imports)]
 
 use {{}, {}};
index 74323317f195643a2ca754fab96e935d8ea35de1..95738828647f964bfc6a35dd8acbba49f9509bf0 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct AtomicRefMut<'a> {
     value: &'a mut i32,
index 377eeb67ae1b95d0f691faf7fde636a8a988ed6d..1b285f219dcbcb7619fb8e788ed9872b33b90b44 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct WithDrop;
 
index 22f2a1f364d1d21fb4777e0605422fb4f04e3ba5..dbf49c7621f677e17b5209bf52f31e04f122f6e6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct MyStruct<'a> {
     field: &'a mut (),
index cefc872668cebd9c773753d08cf20fd9bd726522..b3c344257b6a24213b1be3b4911060848b010d5a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Tests that automatic coercions from &mut T to *mut T
 // allow borrows of T to expire immediately - essentially, that
index 334bd608add15afc59366363de6b1b4d33c608fe..28671db09982fc5a54d764b92e0bcbe7b7172e56 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(non_upper_case_globals)]
 
 static mut x: &'static u32 = &0;
index b3cc350acf532c8ddd2c065ebbd90734656e7bab..c8540729352b270111be4af7913aa6e94d55972b 100644 (file)
@@ -1,6 +1,7 @@
 // This note is annotated because the purpose of the test
 // is to ensure that certain other notes are not generated.
 #![deny(unused_unsafe)] //~ NOTE
+#![allow(deprecated)]
 
 // (test that no note is generated on this unsafe fn)
 pub unsafe fn a() {
index adc36e266c2712450b8b6dba1eec3f2691491794..6df065b9807f2dff91c3f1c6cc3705c471967851 100644 (file)
@@ -1,5 +1,5 @@
 error: unnecessary `unsafe` block
-  --> $DIR/issue-48131.rs:8:9
+  --> $DIR/issue-48131.rs:9:9
    |
 LL |         unsafe { /* unnecessary */ }
    |         ^^^^^^ unnecessary `unsafe` block
@@ -11,7 +11,7 @@ LL | #![deny(unused_unsafe)]
    |         ^^^^^^^^^^^^^
 
 error: unnecessary `unsafe` block
-  --> $DIR/issue-48131.rs:19:13
+  --> $DIR/issue-48131.rs:20:13
    |
 LL |             unsafe { /* unnecessary */ }
    |             ^^^^^^ unnecessary `unsafe` block
index cf94094a7985fc806957678130915ad558fbbae9..3724bb6393ce688a5c586beae7cdfae9975e1d80 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 // pretty-expanded FIXME #23616
index b5dd673b0477df910dd8f6dce8e595a4a7d80c22..903b2e299296398f784b2513b287f8c417ebc696 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // Regression test for #48551. Covers a case where duplicate candidates
 // arose during associated type projection.
 
index 46d9e749aae2398b2f681942265d457b34fcc508..d3c6d17f416aee8ce954672bea962a49622d113b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 fn iter<'a>(data: &'a [usize]) -> impl Iterator<Item = usize> + 'a {
     data.iter()
         .map(
index dd7b9eeb8d54e65bb20898718f52199ffed886c7..79cc107d4fec216eb56e66f707a76c477362cce8 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // ignore-emscripten no i128 support
 
 fn fibs(n: u32) -> impl Iterator<Item=u128> {
index ad410f30c04d4cb4297987f22a80e3865c26372c..e75381afae9aeb7ca87258fdb4dc7c0d00759e61 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(stmt_expr_attributes)]
 #![warn(unused_attributes)] //~ NOTE lint level defined here
index cda1c4d5faae6a41b4e8b81f2b4486f171f425e1..f530c3853e38cdac8ea7e233d1c66f2292a084a3 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(decl_macro)]
 
index 1ba47d3b932ef70171f87e442d6d9fbdc506bc57..a32faa69841fdff9b5cca1ec1f8857328978aeaf 100644 (file)
@@ -4,7 +4,7 @@
 // second time. Uncool.
 
 // compile-flags:-Zmir-opt-level=3
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     let _ = (0 .. 1).filter(|_| [1].iter().all(|_| true)).count();
index 6868d481962b565b86505cd0bf3398d050289aeb..e728e45e60bc2f7245e1bdbfd7232509253ce974 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     assert!({false});
index d776d181b62682301ea9a8e00e5d8c0939a1dbd6..653b52902d2b50150a6aebd75bba178fa4482da3 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 use std::marker::PhantomData;
 
 struct Meta<A> {
index 70b4bc8b755aac7b31cb97c2de2655c354ac2736..59d4f9afdaa01f3c3d61f3f52c0c86b4e992278f 100644 (file)
@@ -1,6 +1,6 @@
 // Confirm that we don't accidentally divide or mod by zero in llvm_type
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 mod a {
     pub trait A {}
index 772c45dee11d749cd74bfef2a3634b180afb29be..b170e09d02d06937b7745346a8bf1f1ece1436e6 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: --crate-type dylib --target thumbv7em-none-eabihf
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // error-pattern: dropping unsupported crate type `dylib` for target `thumbv7em-none-eabihf`
 
 #![feature(no_core)]
index 989fcc041a097813116c6ecbef7e579ad862020c..c2ad60fd8cfade568bd2f61a09fa78ef678f02ce 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 const PATH_DOT: &[u8] = &[b'.'];
index 7b79807e4d7ff5df6ffa42a3e4a12a3ec698367d..b5ebf156a273039e6df217ddb8bdf8d10050baab 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![crate_type = "lib"]
 #![feature(linkage)]
index c58656330e12b38981e72d260f2aadc5667efa7f..727dd43d57454d2660335547bbf2f1165a4ba06d 100644 (file)
@@ -2,7 +2,7 @@
 // implied bounds was causing outlives relations that were not
 // properly handled.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {}
 
index bf6791734d4e23179e253f4093795fff8a1ffa4d..64ac0b1c03b975534a993e417827a0a1bdab7267 100644 (file)
@@ -1,4 +1,4 @@
-//compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct Foo {
     bar: dyn for<'r> Fn(usize, &'r dyn FnMut())
index 808b73ec72f75674b21ca1af178017716d16cb6e..cca17595051da2222226f66430859e8c4e7c8699 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 4d3b3f80a97e53f804ef0d18618d7ea26d50c161..7644810c947572dd51573e0eca0b053c9bf85edc 100644 (file)
@@ -1,7 +1,7 @@
 // Regression test for an NLL-related ICE (#53568) -- we failed to
 // resolve inference variables in "custom type-ops".
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait Future {
     type Item;
index 8a35b36d46d64f49d0a3aeafe1e3aa0d042d5711..b8dca96946a418750c69f7736d9b01078ee6ae5b 100644 (file)
@@ -1,7 +1,7 @@
 // rust-lang/rust#53675: At one point the compiler errored when a test
 // named `panic` used the `assert!` macro in expression position.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags: --test
 
 mod in_expression_position {
index ac1033add0ee49376c5eea7cf30bf169a601fcba..7aee500744d8e74b81444776b9f7fc579b82d3bf 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 pub struct GstRc {
     _obj: *const (),
index d6a14a6e11f674de9723f7e40f37632ee84da761..9bda7635effc2170e12ea40050651ddf0df4a637 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // This test checks that the `remove extra angle brackets` error doesn't happen for some
 // potential edge-cases..
index 8d3a4e72de411b88185c21909c5f404aa1030e43..eca27819a409a1bcd075e81eb8726a193b599d3c 100644 (file)
@@ -1,7 +1,7 @@
 // This test is a minimal version of an ICE in the dropck-eyepatch tests
 // found in the fix for #54943.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn foo<T>(_t: T) {
 }
index 41ca7c1498265b30c2be23281d86d1ea6dd900d9..c32f85dbe1a8c5db9137242898475ad212cc0dda 100644 (file)
@@ -2,7 +2,7 @@
 // found in the fix for #54943. In particular, this test is in unreachable
 // code as the initial fix for this ICE only worked if the code was reachable.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn foo<T>(_t: T) {
 }
index 185077bd684a87ecaac408212899eaeba80a8188..a9cc99c79d01af7e05a5a8f87999a5c4f338cd1a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // FIXME(#54943) This test targets the scenario where proving the WF requirements requires
 // knowing the value of the `_` type present in the user type annotation - unfortunately, figuring
 // out the value of that `_` requires type-checking the surrounding code, but that code is dead,
index 56f5ce9901e684d23fa5b01a575a74ae02d3c4b6..edbbe33c66fcc6b54366c85afed4b710b9503f7b 100644 (file)
@@ -2,7 +2,7 @@
 // is OK because the test is here to check that the compiler doesn't ICE (cf.
 // #5500).
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct TrieMapIterator<'a> {
     node: &'a usize
index e5963a7c435f0bf1cb865bb35fb6eee337e36bd3..db26b0372a6cf5c2375e40b1efe2bfa6f0798628 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 3a3eccdc33ce8f63e90b516e39f20b1c40568724..32d87586cf4d23e266ddb477fd986c7cc335348f 100644 (file)
@@ -1,7 +1,7 @@
 // Regression test for #56128. When this `pub(super) use...` gets
 // exploded in the HIR, we were not handling ids correctly.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 mod bar {
     pub(super) use self::baz::{x, y};
index bd222b7fe980ed64acc1101c8ac92c62a8d6ac46..6d6f23d2844a67c26dee3adf0f2a8f7a3dda756b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait FooTrait {}
 
index bd689e913aba6e1367357ebb6478abe16bf54302..6880a8a98d25ee838bc0eca0db6b7567e17415b3 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct T {}
 
index f20b0f41c7fa5ac535c67dcb901118b94d19cc65..b6cd8c927a279616e98c66bdcaad49521dd4d5d9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait Foo<Args> {
     type Output;
index abe0887e927b5cd15738b8748f7d15cfc7799692..7ba2f9cea8410aa591bb7bc02bef6f0a6e6c658f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait Foo {}
 impl Foo for dyn Send {}
index dab77bd660ca0d9d64a55ed369742d44016c74b3..c4247b3b11c2c87f57dbbb0598bc413eec33b9b7 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Originally from #53925.
 // Tests that the `unreachable_pub` lint doesn't fire for `pub self::bar::Bar`.
index 0d697e5619d249df7a121bd05dd3b47c45e07a0d..de7ae4b3c07646a66fd3c9db4168eb9c5eb82fab 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Tests that the `unreachable_pub` lint doesn't fire for `pub self::imp::f`.
 
index 78e8701335905e95f52ccb945dc2fd2ffd6d0956..a629729d395015fc1afbf48d492b5075a11c1cf6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(improper_ctypes)]
 
diff --git a/src/test/ui/issues/issue-57866.rs b/src/test/ui/issues/issue-57866.rs
deleted file mode 100644 (file)
index 77c50e5..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// compile-pass
-
-#![feature(type_alias_enum_variants)]
-
-enum Outer<T> {
-    A(T)
-}
-
-enum Inner {
-    A(i32)
-}
-
-type OuterAlias = Outer<Inner>;
-
-fn ice(x: OuterAlias) {
-    // Fine
-    match x {
-        OuterAlias::A(Inner::A(_)) => (),
-    }
-    // Not fine
-    match x {
-        OuterAlias::A(Inner::A(y)) => (),
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-58006.rs b/src/test/ui/issues/issue-58006.rs
deleted file mode 100644 (file)
index 1fb5fef..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#![feature(type_alias_enum_variants)]
-pub enum Enum {
-    A(usize),
-}
-
-impl Enum {
-    fn foo(&self) -> () {
-        match self {
-            Self::A => (),
-            //~^ ERROR expected unit struct/variant or constant, found tuple variant
-        }
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-58006.stderr b/src/test/ui/issues/issue-58006.stderr
deleted file mode 100644 (file)
index c34e133..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error[E0533]: expected unit struct/variant or constant, found tuple variant `<Self>::A`
-  --> $DIR/issue-58006.rs:9:13
-   |
-LL |             Self::A => (),
-   |             ^^^^^^^
-
-error: aborting due to previous error
-
index ad7067bb9b162059f91a6000efc79a543613851a..acb3e19765e66d338c447c60c381ac98b22ca588 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 5ac7acc8e3980e59c3a6d54fe251e85e66e04fa2..850e67db629c127f644b72847bad494f4c6d5023 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 19e0cfc7f2703fb8b25041080c2190671a1fee79..5c2250e25fc83ca5894aed6608ce915305afa248 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // pretty-expanded FIXME #23616
 
index fe4eaff742d623e8c227c60fdc25a7dbdb82e639..dca1e5979effb1cafa16cf5c11899ac4f3b9b2e4 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags: -Z unpretty=hir
 
 #![feature(existential_type)]
index 5acfdf9ed5342ef16b3476111b125ceec5e65831..139808974c6c3b137a12854ccc5a17987e9fe9ed 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags: -Z unpretty=hir
 
 #![feature(existential_type)]
index 2b23ccd258643b131afff67476d023676822a134..2fb0fee60bac50016df6a12dd6387a512d25b5bc 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 #[derive(PartialEq)]
index 49a313f90de09e78caba7715b7a078a6f3493a13..305f46c6d4ee9ccc41ae88f77a5465346ef83bda 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(improper_ctypes)]
 
index aa091ca594aababcb3f46914f28cb84ecc179700..70b301d3d9cbbd7701b42ffe0c35302cd800cc26 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 608c0c80716a6f6ffa0af0c612ee197c322f2b7f..6bf20d71d1f1ec3a9d56620d1cc531fc2943ed8b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // pretty-expanded FIXME #23616
 
 use std::mem;
index e835edea1134b6d6e3ef925e32d50d5367e66c9c..aae67637f2cbf97cc77d7c7ffe8661be49790262 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
index 0b94fabf385df486836a294c5710c60965cd1a5f..69901e97894c8146392fc5919e2e78960a3f7757 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 8b5c8505d3ad733ea0637bc7084e8c95f5d7d551..e336e0b47b2838e7b6e47e9a248656cc79064c89 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 619256c7871936069c35e245903f5999ecddfd0a..9570386730a7b00f999fea7c3b3e74b280a9e606 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index e4dafc073ab3b9bc0c91407e3d7714d361ccc4f5..653d002fa61b5617a45edcf36651def05df02c6c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index a65c667b08e45f3b1d44544fcb13502c507abae5..5fe88854b39f43f65a1154f10e7fe1c5e013aa42 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 7007c8a3a98bcc4e5534674e956450e366fe8a53..02a0e14d55e625c0aed356d87f3591f1245f8e5b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 trait Foo1 {}
 
 trait A {}
index 4cc21234796aeba0c335dc52286f90d67286e16c..6ffb721372a4e226520e8eec64380d5b7d1dcd34 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 #![allow(non_upper_case_globals)]
index 30acd61a34a09d14c503d6f313fb944fc8b6faec..f3bab42ee165f98b9854656202896b4847138b81 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 #![allow(non_snake_case)]
index e877dd64922140d04fc2379cd8ce74b6cde6e98c..78237421c982ba459255067386fa9c87e08327ff 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Regression test for issue 9243
 #![allow(non_upper_case_globals)]
index e4e9c4597192e88fc41d69df83a91637d67dd3d8..b1f2bd7569a96aebc727b24a953ef6a7e6e31d1c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 1e38ab9c6c2a4e4d4b3a3dab10a5c650695208d9..58eb32b111dd9aa0078673ab0b25ee523201582d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index ac98724d0375727019e5b71495939714b67d0b6a..f26e157bc706e5a85139f416d1c77c9ab580bd7c 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -A bad-style
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     let _InappropriateCamelCasing = true;
index 73dd656f60cf4e7900c44b2167202923a00540d1..d3a4201ba6070b4eee6ce5d4ac54e6fa044f21b6 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -W bad-style
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     let _InappropriateCamelCasing = true;
index d52c651ce38c83d1d3aeb354e8fde22af97409de..9fce66a0a83cc3821b794d3cbcbd5f79b9c13520 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // run-rustfix
 
 #![warn(ellipsis_inclusive_range_patterns)]
index 5174a8b8b7e6eb4e87e800fb6b70954359aadee6..f886e778b5938aa565802c4196a15fd959877ffb 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // run-rustfix
 
 #![warn(ellipsis_inclusive_range_patterns)]
index 7d3fd441ae5db2c48bcf10278982c87452ad3910..4cb35e907c8f928666216f9603b427d1481b2655 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(box_syntax)]
 #![feature(box_patterns)]
index 8872c0047fda53680e1c28c74dbf8b3071651e0d..47063a7c26786a517a494355b9f331056bcb8351 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(unused_parens)]
 
index e4be1edc5d7b5589f56beaec62bf18d4d9579a46..3802e01a7755634105507a4571ced073fb339ed6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![forbid(non_camel_case_types)]
 #![allow(dead_code)]
index 3a52996195c0d6e9b1b11ba59c2fe9deb452d55a..eda9e2cdfaa2f648a47206338c9fef1abead35f4 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(ellipsis_inclusive_range_patterns)]
 #![allow(unreachable_patterns)]
index 8ca5af21630a216c0b67c2ff525391fc09d562cd..95da4efa59041001e9085297ec025102697a995c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // Issue #7526: lowercase static constants in patterns look like bindings
 
 // This is similar to lint-lowercase-static-const-pattern.rs, except it
index 1f06b28398426508eee908022a2a4f912422e237..434e24c1d278c09afd6429f3e3d4bccf422abd42 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(non_camel_case_types)]
 
index c2fdfb4fe421aad56096f0c1eeb90978a0caa4d9..d025ee948546a54639ab8719fbfde44cfed9292a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(dead_code)]
 // This is ok because we often use the trailing underscore to mean 'prime'
index 9a6487d254239a12d49e9ca2cf7c2f459c029e4c..5bec82ce1a6f5128fe27abd456de503f4d178dac 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
index a0b4130c3e92a9ee72f6c6cb3c32cdf1fb4f515a..40f0a676381b4a5734ac147f66e6b02fcfcbc27c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(dead_code)]
 
index c9b33f06e215adc0701929f6fb798a4707c44e99..32a41179965f3bf80563491341d8ac6259b2c6cb 100644 (file)
@@ -1,7 +1,7 @@
 // aux-build:lint_output_format.rs
 
 #![feature(unstable_test_feature)]
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 extern crate lint_output_format;
 use lint_output_format::{foo, bar};
index a2031c2189ae14c41237c3d07598fd485947d445..652fd04bdf526edfa2e6df8d2c120adff1521ed1 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:lint_stability.rs
 // aux-build:inherited_stability.rs
 // aux-build:stability_cfg1.rs
index e04363faf4b607056d1dc19e99acfc24ea0113bb..aebc4f180857364abe71d526b83aad2a98cd8857 100644 (file)
@@ -4,7 +4,7 @@
 // FIXME(#44232) we should warn that this isn't used.
 #![feature(rust1)]
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 
 fn main() { }
index c372a980bed5ef6d984952ac8b84226ec1e28e95..93fa7a6e96e37c0aa53a424f2ffb3296acd7e45c 100644 (file)
@@ -4,7 +4,7 @@
 // FIXME(#44232) we should warn that this isn't used.
 #![feature(rust1)]
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 
 fn main() {}
index adef2f9e7690fb77da00e79c2bec1c94cc2fd525..e381c81453b10a4f1ce47d3a0106011322a4648a 100644 (file)
@@ -1,5 +1,5 @@
 // aux-build:lints-in-foreign-macros.rs
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(unused_imports)] //~ missing documentation for crate [missing_docs]
 #![warn(missing_docs)]
index 60baa2349876cb7ae9e8df7399e8c5654fbe3015..d0adf6a875d3e59523b91affb4893082e48d5704 100644 (file)
@@ -1,6 +1,6 @@
 // Issue #50124 - Test warning for unused operator expressions
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(unused_must_use)]
 
diff --git a/src/test/ui/lint/must_use-array.rs b/src/test/ui/lint/must_use-array.rs
new file mode 100644 (file)
index 0000000..97825dd
--- /dev/null
@@ -0,0 +1,47 @@
+#![deny(unused_must_use)]
+
+#[must_use]
+struct S;
+
+struct A;
+
+#[must_use]
+trait T {}
+
+impl T for A {}
+
+fn empty() -> [S; 0] {
+    []
+}
+
+fn singleton() -> [S; 1] {
+    [S]
+}
+
+fn many() -> [S; 4] {
+    [S, S, S, S]
+}
+
+fn array_of_impl_trait() -> [impl T; 2] {
+    [A, A]
+}
+
+fn impl_array() -> [(u8, Box<dyn T>); 2] {
+    [(0, Box::new(A)), (0, Box::new(A))]
+}
+
+fn array_of_arrays_of_arrays() -> [[[S; 1]; 2]; 1] {
+    [[[S], [S]]]
+}
+
+fn main() {
+    empty(); // ok
+    singleton(); //~ ERROR unused array of `S` that must be used
+    many(); //~ ERROR unused array of `S` that must be used
+    ([S], 0, ()); //~ ERROR unused array of `S` in tuple element 0 that must be used
+    array_of_impl_trait(); //~ ERROR unused array of implementers of `T` that must be used
+    impl_array();
+    //~^ ERROR unused array of boxed `T` trait objects in tuple element 1 that must be used
+    array_of_arrays_of_arrays();
+    //~^ ERROR unused array of arrays of arrays of `S` that must be used
+}
diff --git a/src/test/ui/lint/must_use-array.stderr b/src/test/ui/lint/must_use-array.stderr
new file mode 100644 (file)
index 0000000..a6dbd8e
--- /dev/null
@@ -0,0 +1,44 @@
+error: unused array of `S` that must be used
+  --> $DIR/must_use-array.rs:39:5
+   |
+LL |     singleton();
+   |     ^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/must_use-array.rs:1:9
+   |
+LL | #![deny(unused_must_use)]
+   |         ^^^^^^^^^^^^^^^
+
+error: unused array of `S` that must be used
+  --> $DIR/must_use-array.rs:40:5
+   |
+LL |     many();
+   |     ^^^^^^^
+
+error: unused array of `S` in tuple element 0 that must be used
+  --> $DIR/must_use-array.rs:41:6
+   |
+LL |     ([S], 0, ());
+   |      ^^^
+
+error: unused array of implementers of `T` that must be used
+  --> $DIR/must_use-array.rs:42:5
+   |
+LL |     array_of_impl_trait();
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unused array of boxed `T` trait objects in tuple element 1 that must be used
+  --> $DIR/must_use-array.rs:43:5
+   |
+LL |     impl_array();
+   |     ^^^^^^^^^^^^^
+
+error: unused array of arrays of arrays of `S` that must be used
+  --> $DIR/must_use-array.rs:45:5
+   |
+LL |     array_of_arrays_of_arrays();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
index 23df4fa6132d3838a411d2af96d8799b769080b9..0aa751443a0804f482881df0108e432a7915f466 100644 (file)
@@ -17,6 +17,23 @@ fn get_critical() -> impl NotSoCritical + Critical + DecidedlyUnimportant {
     Anon {}
 }
 
+fn get_boxed_critical() -> Box<dyn Critical> {
+    Box::new(Anon {})
+}
+
+fn get_nested_boxed_critical() -> Box<Box<dyn Critical>> {
+    Box::new(Box::new(Anon {}))
+}
+
+fn get_critical_tuple() -> (u32, Box<dyn Critical>, impl Critical, ()) {
+    (0, get_boxed_critical(), get_critical(), ())
+}
+
 fn main() {
     get_critical(); //~ ERROR unused implementer of `Critical` that must be used
+    get_boxed_critical(); //~ ERROR unused boxed `Critical` trait object that must be used
+    get_nested_boxed_critical();
+    //~^ ERROR unused boxed boxed `Critical` trait object that must be used
+    get_critical_tuple(); //~ ERROR unused boxed `Critical` trait object in tuple element 1
+    //~^ ERROR unused implementer of `Critical` in tuple element 2
 }
index 7e2b2f67964ac582d336d88cf5df3e302956f971..be74362e29d62b720dad2da64460f01c15bb1128 100644 (file)
@@ -1,5 +1,5 @@
 error: unused implementer of `Critical` that must be used
-  --> $DIR/must_use-trait.rs:21:5
+  --> $DIR/must_use-trait.rs:33:5
    |
 LL |     get_critical();
    |     ^^^^^^^^^^^^^^^
@@ -10,5 +10,29 @@ note: lint level defined here
 LL | #![deny(unused_must_use)]
    |         ^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: unused boxed `Critical` trait object that must be used
+  --> $DIR/must_use-trait.rs:34:5
+   |
+LL |     get_boxed_critical();
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error: unused boxed boxed `Critical` trait object that must be used
+  --> $DIR/must_use-trait.rs:35:5
+   |
+LL |     get_nested_boxed_critical();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unused boxed `Critical` trait object in tuple element 1 that must be used
+  --> $DIR/must_use-trait.rs:37:5
+   |
+LL |     get_critical_tuple();
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error: unused implementer of `Critical` in tuple element 2 that must be used
+  --> $DIR/must_use-trait.rs:37:5
+   |
+LL |     get_critical_tuple();
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
 
index 0b5a4eb785195f8eebe8b3835888ca20064c8f2f..979a67b15583a609e7748d73f36a401041f5c729 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // this tests the `unknown_lint` lint, especially the suggestions
 
index eba91d92afb5bf4c9f4a0faf38cf103aef648c7f..5320987040afc5818b58fc48d6c0cf5af566c50a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(lint_reasons)]
 
index 64e595120737990734d65f444832b3f9ede825ca..c145bd256d8f24b69cfd2b77632083b750b9ece9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![warn(overflowing_literals)]
 
 fn main() {
index 6739c7f096b59165eedb2736847ef31f89d7dda3..27b437b22eb032050ab7d608e6fbd77a5da9adf6 100644 (file)
@@ -4,7 +4,7 @@
 // suggestions to use `crate` given when it is on). When that feature becomes
 // stable, this test can be deleted.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 
 #![allow(unused)]
index 12726b6ecae380cd35e01bac162c3a1404f36f9b..545281604ea5072cbb2179e5b2eacc1382e17b08 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(crate_visibility_modifier)]
 
index 0bd775111359389932281fd6355f34832ad77aef..68a5819c9c708e1863b8211bab6f70bbf57727b6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(unused_imports)] // Warning explanation here, it's OK
 
index 26ab9fbe5c8f20f941052a2054cbe4e2840b0106..d234a2fb1a02c82ad2c4456eb323e20ab18acbe0 100644 (file)
@@ -2,7 +2,7 @@
 // should also deal with the edge cases where a label is shadowed,
 // within nested loops
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(label_break_value)]
 #![warn(unused_labels)]
index 4462c53152aca7fa9e742e023121b31876422771..185bfacea8046df59259f2a95d42b84f80656a80 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: --error-format pretty-json -Zunstable-options
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // The output for humans should just highlight the whole span without showing
 // the suggested replacement, but we also want to test that suggested
index 07d96d5c482503eab7d06e6f41b853ecada0b03d..396395a17f732b6a8a91f56e78f10d3cad8a4cd7 100644 (file)
@@ -8,8 +8,8 @@
   "spans": [
     {
       "file_name": "$DIR/unused_parens_json_suggestion.rs",
-      "byte_start": 576,
-      "byte_end": 589,
+      "byte_start": 611,
+      "byte_end": 624,
       "line_start": 15,
       "line_end": 15,
       "column_start": 14,
@@ -36,8 +36,8 @@
       "spans": [
         {
           "file_name": "$DIR/unused_parens_json_suggestion.rs",
-          "byte_start": 422,
-          "byte_end": 435,
+          "byte_start": 457,
+          "byte_end": 470,
           "line_start": 10,
           "line_end": 10,
           "column_start": 9,
@@ -66,8 +66,8 @@
       "spans": [
         {
           "file_name": "$DIR/unused_parens_json_suggestion.rs",
-          "byte_start": 576,
-          "byte_end": 589,
+          "byte_start": 611,
+          "byte_end": 624,
           "line_start": 15,
           "line_end": 15,
           "column_start": 14,
index 328f8232bafa84fcdd13be88bf90c80a71f83abc..6ec2af068018b11a37ece383424973eda30dd51c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![warn(unused_imports)]
 
 use crate::foo::Bar; //~ WARNING first import
diff --git a/src/test/ui/loops/loop-break-unsize.rs b/src/test/ui/loops/loop-break-unsize.rs
new file mode 100644 (file)
index 0000000..974c63c
--- /dev/null
@@ -0,0 +1,8 @@
+// Regression test for #62312
+// check-pass
+
+fn main() {
+    let _ = loop {
+        break Box::new(()) as Box<dyn Send>;
+    };
+}
index 93f322ab36804f1c4d34243d6e48acf4e1d854dd..316ee64072de0bcb4d7d56e98f6f7e1230e54fa9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // ignore-tidy-linelength
 
index 27f9862f70da5973c3ed26256f9bbff7c1fccde2..5ed8b2f416ecde20e1f2110a5224ee0a45cb3756 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // ignore-tidy-linelength
 
index 435ad3391a0d04fccdd693ee40aa4ef1db07ab8a..9047fbb95a2ea9911a0fe100eafa681a9eaf95fb 100644 (file)
@@ -1,7 +1,7 @@
 // Issue #21633: reject duplicate loop labels in function bodies.
 // This is testing interaction between lifetime-params and labels.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(dead_code, unused_variables)]
 
index 656ed6576e269855a60c48b05735b1c06cd892ee..9bb6a253b7f4aec03b033ccdf5ffebf1d6577881 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(dead_code, unused_variables)]
 
index fe697db9fbed66a4a3a6ae3023d9e60688f971c4..b8eb854b0b0f1bfdddee300a962b213996a4be11 100644 (file)
@@ -1,5 +1,5 @@
 // ignore-emscripten no asm! support
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![feature(asm)]
 #![allow(unused)]
 
index 3d35d53f777db58c8ab90a7ebe7bcbf88c38d563..8daa1c84f1dc32e8d4a0f56ec07839407c23b7b9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(extern_prelude)]
 
index 2477226ce212adfed7b79de6880736a0c93542ba..b2a639218b994c9d7adfe598cc7408644c6e3093 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:macro-in-other-crate.rs
 
 #![feature(decl_macro)]
index 6e53eb05121ccc92ac82a42d26c92baa77dc8523..a643e50e99557fae7b7145f9b02945a6ba3d9e3f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 
 fn main() {
index 17df72f36dbfe33db94f8985c55002a52715c860..2ee41b0880e184e0486df11b768548cb94f71def 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 macro_rules! foo {
index 03d57d2229991babe42745959b32b32e4bedbca7..5e58fc9c1ede8575e21a563c7fb95e1a803700ae 100644 (file)
@@ -1,6 +1,6 @@
 // aux-build:two_macros.rs
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused)]
 
 fn f() {
index a5de32e5d2a8b84eb26a11be46405898700c586d..4b6b65ec48b266d852052439432914c985ddb6d9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags: -Wunused
 
 // make sure write!() can't hide its unused Result
index efd658dd2b9a8fdabad1908149a1602e87160471..576120811dbc6cffc5b13dbaed87274931344b11 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -Z trace-macros
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     println!("Hello, World!");
index b5c992440d4dc65e803e7e8d4f42b8b7af559a95..c1a9d04e6d5cbbed68fc5cb2a153af6069570b07 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #[doc] //~ WARN attribute must be of the form
 #[ignore()] //~ WARN attribute must be of the form
index 860de200f625669153c27e9af11a335aa3f2b4b3..d4bc05f7cb42125206551beb210e3cb90deb72a6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct S<T>(*const T) where T: ?Sized;
 
index 4ee09dcdf1965d1e8307ff9daccae60cd42378ef..8df58a3486eb063d0b1d45c5aa4002d2116d03eb 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused)]
 
 struct S;
index da2f13f5a2f8a5304a1be4d60fb607cc63105b25..d1bee676c2f5c2f6fdb50280bda9724678bf53d1 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Check that method probing ObjectCandidate works in the presence of
 // auto traits and/or HRTBs.
index 11204af702a1c73bbca5c24d39f14053421c2f0c..d962a52139eea847d01cbaa3bcbb754ef4ab6dba 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(unused)]
 
 macro_rules! m {
index 6b047c35065358b2cd7e6cd6f1f7130679026815..fd5fbc30611a9181d6bf376125d5c53df734ddd4 100644 (file)
@@ -1,7 +1,7 @@
 // Test that an assignment of type ! makes the rest of the block dead code.
 
 #![feature(never_type)]
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![warn(unused)]
 
 
index ef78eaa2120cfd2903f2b7a2c09aa2815a6e04e8..5bad756b8762fa98c06b49abdc16912a547dca14 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![crate_type="lib"]
 
index 8ed6554877eaea039a9c22c7e334a1b519ce032d..7679bf22e3cd4323e4003aea25a8c1065a17fcec 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Test that we propagate region relations from closures precisely when there is
 // more than one non-local lower bound.
index d1945f4864c9a6b8d814fc0efd5e80cadca8eccd..1df7c6114eeaec657b8b8d48caa68d70a0c4a87a 100644 (file)
@@ -4,7 +4,7 @@
 // regions is erased.
 
 // compile-flags:-Zborrowck=mir -Zverbose
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 
index 2bc40fcb32783b7dd32b50fd282cb21813fb92fa..b1ea2c906da88df93629fc77d6ab8ebacbfde79a 100644 (file)
@@ -2,7 +2,7 @@
 // arbitrary types without ICEs.
 
 // compile-flags:-Zborrowck=mir
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 const HI: &str = "hi";
 
index 5c72225b11f0ffd907c0506c7e7d77bf57a3a98a..0f3d27d0665609b5bef71fc80db1ad804557472f 100644 (file)
@@ -3,7 +3,7 @@
 // including) the call to `use_x`. The `else` branch is not included.
 
 // compile-flags:-Zborrowck=mir
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(warnings)]
 #![feature(dropck_eyepatch)]
index 75431d40ce54221952f857a018b23207a49c44cb..48073f8749e757e1f39bd19f2e2304a334482d82 100644 (file)
@@ -3,7 +3,7 @@
 // `dyn T:` is lowered to `dyn T: ReEmpty` - check that we don't ICE in NLL for
 // the unexpected region.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait T {}
 fn f() where dyn T: {}
index 6d0d6e16a677588fc15e8c568fa32a5bf2ab083b..e9c8df46213b529a9de13c0aad61a6af39928a50 100644 (file)
@@ -1,6 +1,6 @@
 // extra unused mut lint tests for #51918
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(generators, nll)]
 #![deny(unused_mut)]
index d479a61baa22b7f74856846c57556f3bc324a7dc..1bd39db35d9aa157464237e298db371e34782ff6 100644 (file)
@@ -6,7 +6,7 @@
 // over a yield -- because the data that is borrowed (`*x`) is not
 // stored on the stack.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn foo(x: &mut u32) {
     move || {
index e75362750645ceb1a3e2899ea6203a86dc4c216e..c1205ba96ad69cebee364a2593f0af70fa4b57f0 100644 (file)
@@ -13,7 +13,7 @@
 //    |
 //    = note: move occurs because the value has type `A`, which does not implement the `Copy` trait
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(box_patterns)]
 
index 1fe4fffa324a63617a82590c90e642187ba58606..5a5db1a17f3f4195ae4e6405f1229b673b858457 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::collections::HashMap;
 use std::sync::Mutex;
index 80a85293e5a5cc165a303ec438bf4f9808d8cf0b..32c97a651c50f5aa2644c447218cb654f27f04cd 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn from_stdin(min: u64) -> Vec<u64> {
     use std::io::BufRead;
index 6357c3ccef1f8d515b45d30a2ed42217e31c2da3..1add91b1bd04a8c3c567f614c136f721c89d77cf 100644 (file)
@@ -1,7 +1,7 @@
 // rust-lang/rust#22323: regression test demonstrating that NLL
 // precisely tracks temporary destruction order.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     let _s = construct().borrow().consume_borrowed();
index 27e519005f62b473c49081e7fd9bcd8886f6c036..3f4818a28c8d668da166acb4fe0a3bd22baf1a39 100644 (file)
@@ -1,6 +1,6 @@
 // Regression test for #30104
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::ops::{Deref, DerefMut};
 
index 7e0ffd6cf36449353da44eda8d716969035062dc..bffff650158502884cf5cf77fae84b90de491643 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // rust-lang/rust#32382: Borrow checker used to complain about
 // `foobar_3` in the `impl` below, presumably due to some interaction
index c50473511f1168799d583879347b0c57c62411a1..8bf9028690fcd79541146160bc1dc5a8a9675d9e 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::borrow::Cow;
 
index 3f8e0f5ad3d7a8859b3030e2bf27689efe481da1..ecd7071ecc78359e52c4dbc2fe0088c70d8287ee 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct LoadedObject {
     bodies: Vec<Body>,
index ec992959a66ca7bb3975426e47bd30fdbd96631c..1e602f27247d7d165b854ecd3a2d72f7269f1c59 100644 (file)
@@ -3,7 +3,7 @@
 // bounds derived from `Sized` requirements” that checks that the fixed compiler
 // accepts this code fragment with both AST and MIR borrow checkers.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct Qey<Q: ?Sized>(Q);
 
index b45477c7fb10deb96bda96da36d6a3c41c7082bd..efffe80aae45fcd743ff2d15b8eb323d75125e86 100644 (file)
@@ -6,7 +6,7 @@
 // of the closure, as they were not present in the closure's generic
 // declarations otherwise.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn creash<'a>() {
     let x: &'a () = &();
index 4b8e6c680753083bbed11e36234a7fe983e101fe..935bf8cda5e999c934a421c9b7f9e3e4c501d427 100644 (file)
@@ -2,7 +2,7 @@
 // between `'a` and `'b` below due to inference variables introduced
 // during the normalization process.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct Drain<'a, T: 'a> {
     _marker: ::std::marker::PhantomData<&'a T>,
index 7a47a77f6bb4ccb24dce60261dd8aa0674d01038..f5400aaad8b458a66d16ff7894749da64b039722 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::ops::Deref;
 
index 81c50edfed1a4e3fd21ea5fba04733e9b0617127..25c1929b227c8fd4b66bf2424126515f9236e1bd 100644 (file)
@@ -6,7 +6,7 @@
 // parameter `x` -- since `'b` cannot be expressed in the caller's
 // space, that got promoted th `'static`.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::cell::{RefCell, Ref};
 
index 521d4d33d8633f8a5a68ebbb9cc7e2578ab17d72..a65635585dbb632a7cec7381d73b2974a91ed708 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(unused_mut)]
 
index 976098e40ad3d8d787b0079b4e1df60fff737781..73fce288f8bb6e792c26ea97dfd5ceb9eaac0eb9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(untagged_unions)]
 
index e02d6a0cb5a3957bed3a62507555cc11f08c8588..f9cea42e7c4ccd32bdafce21c396ec0f1e209080 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait Foo<'a> {
     const C: &'a u32;
index 776a0d359cda6f163a6b308eef7ccc63d3894800..65ca23cc88f6cbd792a6e5e734f84b36fcdde5c5 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait Foo {
     const BLAH: &'static str;
index 1164e9ef2d62feb77d2805cad013ac7db251de82..9237c27f57ea8ed784568f8bbfed31f63d2b1550 100644 (file)
@@ -1,7 +1,7 @@
 // Regression test for #61311
 // We would ICE after failing to normalize `Self::Proj` in the `impl` below.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 pub struct Unit;
 trait Obj {}
index a36ccd36113b586c9e577f973ee3e96b4ae9e9fe..59bceed08f909e6e206d0b52342a095d69ad6278 100644 (file)
@@ -1,7 +1,7 @@
 // Regression test for #61320
 // This is the same issue as #61311, just a larger test case.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 pub struct AndThen<A, B, F>
 where
index 3415c3eeabcdb7381d424d7bc8b41357cecbb195..72212e9e70c0fe0514ac8039426fa5adabb6969b 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -Zborrowck=mir
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(warnings)]
 
index fdf3f594841728602c2fb22242313667094dd72e..5c340434691f19066225347ba6ec8b6a18b0e75e 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags:-Zborrowck=mir
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 
index 23caa59b6b7bf0957839891e0871486976968763..1bbc896c270a1eaf30c77f3634760f0566f74047 100644 (file)
@@ -6,7 +6,7 @@
 // another -- effectively, the single lifetime `'a` is just inferred
 // to be the intersection of the two distinct lifetimes.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags:-Zno-leak-check
 
 #![feature(nll)]
index bac9e26588cae31bb74c69bdab519e53ed5181c0..4e8599b2e3fbec2ffe0725915f8cd80efe8e934c 100644 (file)
@@ -2,7 +2,7 @@
 // function returning always its first argument can be upcast to one
 // that returns either first or second argument.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags:-Zno-leak-check
 
 #![feature(nll)]
index 72987629848c88b873e004acebf6fc25e1bb8d48..36cd57a1b2d34524d343fba7e8bcd25c2cdb88a3 100644 (file)
@@ -4,7 +4,7 @@
 // placeholder region, but in NLL land it would fail because we had
 // rewritten `'static` to a region variable.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait Foo {
     fn foo(&self) { }
index dc67c1a68aaf639d4528b8d51fb85a60ed689b41..2293d7d4bbc0dd4109158e201d6a181e39af9e93 100644 (file)
@@ -1,6 +1,6 @@
 // Regression test for #53789.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::collections::BTreeMap;
 
index 1b80be2eaff99169c1e96e81baa0cf38a0b036d4..313b615fe8085bb574c0c4bc258ecd85209d2c55 100644 (file)
@@ -1,6 +1,6 @@
 // Regression test for #53789.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::collections::BTreeMap;
 use std::ops::Range;
index cda3915849e2d686853992c4fdde2d91f674b50f..147ea20348942865212007c3d269c6c8458fcaf6 100644 (file)
@@ -16,7 +16,7 @@
 // Fixed by tweaking the solver to recognize that the constraint from
 // the environment duplicates one from the trait.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![crate_type="lib"]
 
index 2e105ece8b55cf27fa3738e1054bc9e05794814a..148120d848bc0a43f5032c1064800c35d98879ea 100644 (file)
@@ -1,7 +1,7 @@
 // Test that when we infer the lifetime to a subset of the fn body, it
 // works out.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait MyTrait<'a> {
     type Output;
index 1245ce8583e293e1fa3a88ca384b09a968022ce7..fb50dce1af616ec86387b35749d668b3e526d0eb 100644 (file)
@@ -1,10 +1,7 @@
-// compile-flags:-Zborrowck=mir -Zverbose
-
 // Test that we can deduce when projections like `T::Item` outlive the
 // function body. Test that this does not imply that `T: 'a` holds.
 
-#![allow(warnings)]
-#![feature(rustc_attrs)]
+// compile-flags:-Zborrowck=mir -Zverbose
 
 use std::cell::Cell;
 
@@ -18,7 +15,6 @@ fn twice<F, T>(mut value: T, mut f: F)
     f(&value, Cell::new(&n));
 }
 
-#[rustc_errors]
 fn generic1<T: Iterator>(value: T) {
     // No error here:
     twice(value, |value_ref, item| invoke1(item));
@@ -30,7 +26,6 @@ fn invoke1<'a, T>(x: Cell<&'a Option<T>>)
 {
 }
 
-#[rustc_errors]
 fn generic2<T: Iterator>(value: T) {
     twice(value, |value_ref, item| invoke2(value_ref, item));
     //~^ ERROR the parameter type `T` may not live long enough
index 9cdb78a10281c0e3a9e1a0f8ad529bf164dfc712..9f0c60c1e1705a34424e546f32cc55a44bdb440f 100644 (file)
@@ -1,5 +1,5 @@
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/projection-implied-bounds.rs:35:18
+  --> $DIR/projection-implied-bounds.rs:30:18
    |
 LL |     twice(value, |value_ref, item| invoke2(value_ref, item));
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 452a8ea4f85d205cc443b9e6d99204388dd4a220..b9c9611e38c2c58647a47c8d60636b33bf3b9435 100644 (file)
@@ -3,7 +3,7 @@
 // we don't even propagate constraints from the closures to the callers.
 
 // compile-flags:-Zborrowck=mir -Zverbose
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
index 731476661112148053971caa944d21a80e19f012..4613dd29ef8f03417334781f9dfcc7c6c81bd346 100644 (file)
@@ -4,7 +4,7 @@
 //
 // Regression test for #53121.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait MyTrait<'a> {
     type Output;
index 7c7d64a8cb4d3d379b812c5d107c05ac60fb1148..89328c2ef1b331dcb92c8ca3eb6ea5938fed2f9a 100644 (file)
@@ -4,7 +4,7 @@
 // MyTrait<'a>>::Output: 'a` outlives `'a` (because the trait says
 // so).
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait MyTrait<'a> {
     type Output: 'a;
index f61f54f80a78bf02252201e588953cf483a15868..a68c3cf12fd7179a1ecd3adab2a247d0c2fb24e4 100644 (file)
@@ -1,12 +1,9 @@
 // compile-flags:-Zborrowck=mir -Zverbose
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Test that we assume that universal types like `T` outlive the
 // function body.
 
-#![allow(warnings)]
-#![feature(rustc_attrs)]
-
 use std::cell::Cell;
 
 fn twice<F, T>(value: T, mut f: F)
@@ -17,7 +14,6 @@ fn twice<F, T>(value: T, mut f: F)
     f(Cell::new(&value));
 }
 
-#[rustc_errors]
 fn generic<T>(value: T) {
     // No error here:
     twice(value, |r| invoke(r));
index 23b76bb196470984af9a50c1ce09bca138fd3f94..3efea7136307ce01a181879fd0dd8453284481c5 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Check that we don't try to downcast `_` when type-checking the annotation.
 fn main() {
index 6b9d30f5ab4259eadc86b5327cdeef3aafd3dcf6..66b3110d2afd0a1fdf1f8794ea7c28dba2a7c982 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // This test is reduced from a scenario pnkfelix encountered while
 // bootstrapping the compiler.
index af6ccf35d538c18a56b0a739c2918924ed891f17..eb701b9184e6a2aa3569423ff48328244552bf1a 100644 (file)
@@ -18,7 +18,7 @@
 
 
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct Foo(String);
 
index 25a9c2ed98e04095f53456dd8b70e87707b87984..af6585aadae66fe473c04099da4d8983b7541933 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 mod x;
 
index 2642cdff2bf6ae412c969641b9dea02ddfa6f5be..f71c8cd0e0c398f7ebc29a3e59c16a6d2469059c 100644 (file)
@@ -1,20 +1,20 @@
-error: 'a,Ambiguous
-  --> $DIR/object-lifetime-default.rs:24:1
+error: BaseDefault
+  --> $DIR/object-lifetime-default.rs:6:1
    |
-LL | struct G<'a,'b,T:'a,U:'a+'b>(&'a T, &'b U);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | struct A<T>(T);
+   | ^^^^^^^^^^^^^^^
 
-error: 'a,'b
-  --> $DIR/object-lifetime-default.rs:21:1
+error: BaseDefault
+  --> $DIR/object-lifetime-default.rs:9:1
    |
-LL | struct F<'a,'b,T:'a,U:'b>(&'a T, &'b U);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | struct B<'a,T>(&'a (), T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: 'b
-  --> $DIR/object-lifetime-default.rs:18:1
+error: 'a
+  --> $DIR/object-lifetime-default.rs:12:1
    |
-LL | struct E<'a,'b:'a,T:'b>(&'a T, &'b T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | struct C<'a,T:'a>(&'a T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: Ambiguous
   --> $DIR/object-lifetime-default.rs:15:1
@@ -22,23 +22,23 @@ error: Ambiguous
 LL | struct D<'a,'b,T:'a+'b>(&'a T, &'b T);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: 'a
-  --> $DIR/object-lifetime-default.rs:12:1
+error: 'b
+  --> $DIR/object-lifetime-default.rs:18:1
    |
-LL | struct C<'a,T:'a>(&'a T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | struct E<'a,'b:'a,T:'b>(&'a T, &'b T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: BaseDefault
-  --> $DIR/object-lifetime-default.rs:9:1
+error: 'a,'b
+  --> $DIR/object-lifetime-default.rs:21:1
    |
-LL | struct B<'a,T>(&'a (), T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | struct F<'a,'b,T:'a,U:'b>(&'a T, &'b U);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: BaseDefault
-  --> $DIR/object-lifetime-default.rs:6:1
+error: 'a,Ambiguous
+  --> $DIR/object-lifetime-default.rs:24:1
    |
-LL | struct A<T>(T);
-   | ^^^^^^^^^^^^^^^
+LL | struct G<'a,'b,T:'a,U:'a+'b>(&'a T, &'b U);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 7 previous errors
 
index a8b1ddfaba7f12075ff14e74f36376bba413deb0..c74a4d1cbbbfc53df44e7447c62c2ffca17309be 100644 (file)
@@ -1,6 +1,6 @@
 // Check that a trait with by-value self is considered object-safe.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(trivial_casts)]
 
index 59ed12c78f0268f859605d75a2a5fe4ba6323ad2..3ffeb81c1cbe37b3fd444470732d795abb4154b4 100644 (file)
@@ -1,6 +1,6 @@
 // Check that `Self` appearing in a phantom fn does not make a trait not object safe.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 trait Baz {
index 92c333b4092fcbe946bb9ce4c28b4703327bbef0..b96125aa952605c07b5ea7ecd09e8ae65db1f62c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![crate_type = "rlib"]
 #![no_std]
index 1e0f9e40cdca67b6654079a59d4dad6b077e03a5..ae8112b61c66f4158f84357c6c42de85065019be 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(bare_trait_objects)]
 
index 78c41f481af5d33d1ff906a80cfd4ab9a10215f1..ab45649f4de49d4fe498986f85f601718072f48a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags: -Z parse-only
 
 impl <*const u8>::AssocTy {} // OK
index 987c955d1dc3836f4d70f3a3c3d813c55c22d448..13dec95435be0344b0683df81fac3c3f7de3b4f3 100644 (file)
@@ -1,3 +1,3 @@
 fn main() {
-    foo! bar < //~ ERROR expected `(` or `{`, found `<`
+    foo! bar < //~ ERROR expected open delimiter
 }
index 6a17d39e8bfec4751d952b5dc8438c361cbaf2b0..e97839a4f4a5232eb7622302248d3d49d6b973c4 100644 (file)
@@ -1,8 +1,8 @@
-error: expected `(` or `{`, found `<`
-  --> $DIR/macro-bad-delimiter-ident.rs:2:14
+error: expected open delimiter
+  --> $DIR/macro-bad-delimiter-ident.rs:2:10
    |
 LL |     foo! bar <
-   |              ^ expected `(` or `{`
+   |          ^^^ expected open delimiter
 
 error: aborting due to previous error
 
index 3213e068053714e8e8556d10c667a35a5311c321..33c30d731087795996a48735fd23b3dfcb18c113 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(box_syntax)]
 #![allow(bare_trait_objects)]
index c655a15d268c1a90d00ffde41793d4c52ba0e43d..26ac3ead6a5a677f257891430af89ba892f25d01 100644 (file)
@@ -1,6 +1,6 @@
 // Fixes issue where `+` in generics weren't parsed if they were part of a `+=`.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct Whitespace<T: Clone + = ()> { t: T }
 struct TokenSplit<T: Clone +=  ()> { t: T }
index bcd0b24c7507fe352c1636c8db26f17ad2a71458..dd0599b4ab3631058ba7a0771f05cbc138e85f3b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     let _ = "Foo"_;
diff --git a/src/test/ui/pattern/enum-variant-generic-args.rs b/src/test/ui/pattern/enum-variant-generic-args.rs
deleted file mode 100644 (file)
index 8559953..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// run-pass
-
-#![feature(type_alias_enum_variants)]
-
-#![allow(irrefutable_let_patterns)]
-
-#[allow(dead_code)]
-enum Enum<T> { TSVariant(T), SVariant { v: T } }
-type Alias<T> = Enum<T>;
-type AliasFixed = Enum<()>;
-
-macro_rules! is_variant {
-    (TSVariant, $expr:expr) => (is_variant!(@check TSVariant, (_), $expr));
-    (SVariant, $expr:expr) => (is_variant!(@check SVariant, { v: _ }, $expr));
-    (@check $variant:ident, $matcher:tt, $expr:expr) => (
-        assert!(if let Enum::$variant::<()> $matcher = $expr { true } else { false },
-                "expr does not have correct type");
-    );
-}
-
-fn main() {
-    // Tuple struct variant
-
-    is_variant!(TSVariant, Enum::TSVariant(()));
-    is_variant!(TSVariant, Enum::TSVariant::<()>(()));
-    is_variant!(TSVariant, Enum::<()>::TSVariant(()));
-
-    is_variant!(TSVariant, Alias::TSVariant(()));
-    is_variant!(TSVariant, Alias::<()>::TSVariant(()));
-
-    is_variant!(TSVariant, AliasFixed::TSVariant(()));
-
-    // Struct variant
-
-    is_variant!(SVariant, Enum::SVariant { v: () });
-    is_variant!(SVariant, Enum::SVariant::<()> { v: () });
-    is_variant!(SVariant, Enum::<()>::SVariant { v: () });
-
-    is_variant!(SVariant, Alias::SVariant { v: () });
-    is_variant!(SVariant, Alias::<()>::SVariant { v: () });
-
-    is_variant!(SVariant, AliasFixed::SVariant { v: () });
-}
index 1bd392426695aa4ca6a1619767d879c28ce77093..e4434695446174e1f426d5c9f4dd77904e87c657 100644 (file)
@@ -3,7 +3,7 @@
 
 // (#55495: The --error-format is to sidestep an issue in our test harness)
 // compile-flags: --error-format human -Z print-fuel=foo
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct S1(u8, u16, u8);
 struct S2(u8, u16, u8);
index 4d2a0e27fd1a97424188dc39b177b66013138a81..b96348640fa1500fafc34a7e2deeed673766eed0 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -Z print-type-sizes
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // All of the types that occur in this function are uninteresting, in
 // that one cannot control the sizes of these types with the same sort
index ecfc03717db463694abc51b029672de0cc67ee07..f165526dffa231e2dfe1dcd7e424a2779ae3ccca 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -Z print-type-sizes
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // ignore-pass
 // ^-- needed because `--pass check` does not emit the output needed.
 //     FIXME: consider using an attribute instead of side-effects.
index 1b1d817420132170784d6c831d517d438f01e1bd..4cb7ae03b54069982a0c99ddbba75cc7c3a6f5e4 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -Z print-type-sizes
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // This file illustrates that when multiple structural types occur in
 // a function, every one of them is included in the output.
index 98b506b1f0db1d8deaf7475b7757b9dfeec0c67d..d9845fd6d70cc3c81cc2ddea4d8d709e25b48bb9 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -Z print-type-sizes
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // ignore-pass
 // ^-- needed because `--pass check` does not emit the output needed.
 //     FIXME: consider using an attribute instead of side-effects.
index f1b8a28ae304b942a4a3e68c959766c10d039f5a..4495a7770a7600fe3fdf3813f80eace46b0180be 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -Z print-type-sizes
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // ignore-pass
 // ^-- needed because `--pass check` does not emit the output needed.
 //     FIXME: consider using an attribute instead of side-effects.
index a8d409a91a240b467aa0e066dec95a3bc1bcf7db..dce4a61ef337b7c4849990cfd61ce519da245054 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -Z print-type-sizes
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // ignore-pass
 // ^-- needed because `--pass check` does not emit the output needed.
 //     FIXME: consider using an attribute instead of side-effects.
index c6d927cb1e56eaf821e3a1548c440d9ebadea5ed..1f894c5e252fadb97e1224ef544c7d6c11761bfa 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -Z print-type-sizes
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // This file illustrates how padding is handled: alignment
 // requirements can lead to the introduction of padding, either before
index 3b5248b6f7ebb26149c40b34c4aff91f07ef37a8..1e6f7ccca40f2e8ba6c0b715d33590d32476dcdb 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -Z print-type-sizes
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // ignore-pass
 // ^-- needed because `--pass check` does not emit the output needed.
 //     FIXME: consider using an attribute instead of side-effects.
index 6816bb71a0012cc70fe62fb831bdce04f925b789..7aad2715bc073ba2879027c891cd1688223c4a6d 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -Z print-type-sizes
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // This test makes sure that the tag is not grown for `repr(C)` or `repr(u8)`
 // variants (see https://github.com/rust-lang/rust/issues/50098 for the original bug).
index c33965c4f53eaa2e6cf6e76ffba9047678e92d68..ae4e492456af9ad8861775387bb5b41a97693635 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -Z print-type-sizes
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // ignore-pass
 // ^-- needed because `--pass check` does not emit the output needed.
 //     FIXME: consider using an attribute instead of side-effects.
index aa2d25a3926a51234e6a4bf7abed541a99a32c3e..77e2b4befba7d4feb9b70714c67cb6cf0b5c8b9b 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: -Z print-type-sizes
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // This file illustrates two things:
 //
index dcffdc3d4ef87e5a29f4d05ab125d09ab679a750..5ef6a61fea1747344b3f8c1219b903abd949abb7 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:issue-57264-1.rs
 
 extern crate issue_57264_1;
index 79d0d2c7cd785b6e7b70ff8002e1b691cbed0101..4d5c9cfa1d53430b42f1359ab5aaab48edbb83ed 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:issue-57264-2.rs
 
 extern crate issue_57264_2;
index 61c6130e47019550cdba73b0dc163f41073446d4..ef50875dcf678a0745f4abe0dae85a51bebd3573 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(existential_type)]
 #![deny(private_in_public)]
index a3e53bdf45de3f6a95540c1b625de4af2ce49bda..5c9ecd13b0976bc3516ec647fa8a90295002bfd3 100644 (file)
@@ -1,6 +1,6 @@
 // Patterns and expressions are not interface parts and don't produce private-in-public errors.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct Priv1(usize);
 struct Priv2;
index 419d521748c68e2119833fe7bb2045359516c57c..240ce1e2b03b6605434a8d32735e26ce71ef9bb4 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(warnings)]
 
 mod foo {
index 0ab17a1f3b312e56d36b046d8ab9b6d6c6c8fddf..4769607ff395d4038f2ffd83fde2b9f97b5dc8b4 100644 (file)
@@ -1,5 +1,5 @@
 // aux-build:attributes-included.rs
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(unused)]
 
index 0388e647b58aad7691f334de67c39ab8202380f8..e299454e0fc734d3483a16a48cf657fb0fe44209 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:test-macros.rs
 // aux-build:derive-helper-shadowed-2.rs
 
index e6b91324f95d0828856413fdad655d189c17e9d3..8b5d4e9d09ce3f70c4aa882230e5b6f20fa345a2 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:test-macros.rs
 
 extern crate test_macros;
index 2615db3e119f1366d9495631ba1a2e55f42c9fb1..2495e72751bb02c86d17a1b0a4035be92acbbc73 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 // aux-build:test-macros.rs
 
index f8d6bc5e0785dd98e2472683c7dc0a9fbaa98d65..5a77cd4ef4f5ad359acbc4e7854e13c564761c88 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 // aux-build:edition-imports-2015.rs
 
index 4b4ba52ecd7267f8d17dad398eda877a372e86c5..437ae930934709c94b2e4e54f33cf46bc83a8cb2 100644 (file)
@@ -1,12 +1,12 @@
 // aux-build:derive-unstable-2.rs
 
-#![allow(warnings)]
-
 #[macro_use]
 extern crate derive_unstable_2;
 
 #[derive(Unstable)]
-//~^ ERROR: reserved for internal compiler
+//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
+//~| ERROR attribute `rustc_foo` is currently unknown to the compiler
+
 struct A;
 
 fn main() {
index e2f51dd3d5dd2383d1370391346591044321e75e..803773db88e9636cecdcd07a0d10d59ad37a3c09 100644 (file)
@@ -1,5 +1,5 @@
-error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics
-  --> $DIR/expand-to-unstable-2.rs:8:10
+error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler
+  --> $DIR/expand-to-unstable-2.rs:6:10
    |
 LL | #[derive(Unstable)]
    |          ^^^^^^^^
@@ -7,6 +7,15 @@ LL | #[derive(Unstable)]
    = note: for more information, see https://github.com/rust-lang/rust/issues/29642
    = help: add #![feature(rustc_attrs)] to the crate attributes to enable
 
-error: aborting due to previous error
+error[E0658]: The attribute `rustc_foo` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/expand-to-unstable-2.rs:6:10
+   |
+LL | #[derive(Unstable)]
+   |          ^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add #![feature(custom_attribute)] to the crate attributes to enable
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
index 25a2a37614778e4f4c62b843659154bf79123c61..a6e64e1b1b1bdca30677c1fdbbbcafc5d2468678 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
 extern crate proc_macro;
index 6d3e5ec198d8557d8a0c9b67c7e18db7c2ef930d..2e20a3de6bf4746e0e3d313c302d34fbb320cbb8 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:test-macros.rs
 
 #[macro_use(Empty)]
index 2fbde5fedb95b7527c9157f61a62fdeb6935b524..ae10a3baa3e3a5b0fe3778c75709dc997f04ff3e 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:test-macros.rs
 
 #[macro_use]
index d1b1430fb5d034f5effb78dc6a711cfec95c0ddc..b101c09ed542438cfc01bcdc4caf1556a40e5b75 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:test-macros.rs
 
 #[macro_use]
index d39c42267fb96003d48941acaf05efdffe98c475..9d30f48846dba096761ac28c9ddcdd7408fa8844 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:test-macros.rs
 
 #![feature(proc_macro_hygiene)]
index e5a5f8beb45857f111f5673c361cdf53a162bfc7..e1e8218582f6be35d220721aa4ead8ec22adc704 100644 (file)
@@ -1,7 +1,7 @@
 //! Verify that the `decls` module implicitly added by the compiler does not cause `missing_docs`
 //! warnings.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // force-host
 // no-prefer-dynamic
 
index 52c706080f3c2cdbd85ffb0903b4de05f7ce2466..b8e88559b1518022838388a3e74db06c99bc2a00 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::ops::*;
 
index a8c3e9b0d62c0ce464fc4100d6ab017380ab3a09..4aec7a4159a135d9d3ccb3b2737c06d639258925 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::ops::*;
 
index 548676063caf7048a6f2c9bc98c1134ea624a14b..c7b310562d18e973f1f1530dd681a5028eeb2471 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 use std::ops::*;
 
index 173116ae357c57d4355ac23f1040f4a9f1737a38..d37eb0a3b843d6a6a7b8ae9640d4bc2dffb284b9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
index ecfa072aa817d5cbf44f449ce2326c7b7a1086f5..e95062de4d732f05708edae93a8e30222bb28ea3 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
index 5cbfe6ebebb7e339320fbb74574b39d05a44ac71..ee9e7a364b8c70f28f66af49b0e35b338426c827 100644 (file)
@@ -8,7 +8,7 @@
 // follow the same lifetime-elision rules used elsehwere. See
 // rust-lang/rust#56537
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn willy_no_annot<'w>(p: &'w str, q: &str) -> &'w str {
     let free_dumb = |_x| { p }; // no type annotation at all
index d6b36af9bd6f32c5f30626dcebf9c0a60a474a55..49de70ae0136593e7c43d49b8e019f64804bc2bc 100644 (file)
@@ -1,7 +1,7 @@
 // Test related to #22779. In this case, the impl is an inherent impl,
 // so it doesn't have to match any trait, so no error results.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 struct MySlice<'a, T:'a>(&'a mut [T]);
index deef9ab15b01eaf85b7d784e6a04299fde1184f5..4ce5daf384227011eb902bf6e4ff5f18a03b8f7a 100644 (file)
@@ -1,7 +1,7 @@
 // Test related to #22779, but where the `'a:'b` relation
 // appears in the trait too. No error here.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait Tr<'a, T> {
     fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b;
index ab24eda2c2d9666f9a0a1998ad6a5db1de91e9dd..e58bd31d9cbe988c10ad038e207995b9dc51fbf3 100644 (file)
@@ -1,7 +1,7 @@
 // Various tests related to testing how region inference works
 // with respect to the object receivers.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(warnings)]
 
 trait Foo {
index cda48347061763387a47c83367292023a59844dc..c3c7c51767d3a2b733eff5f9219c67a31446d0fc 100644 (file)
@@ -1,7 +1,7 @@
 // Various tests related to testing how region inference works
 // with respect to the object receivers.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(warnings)]
 
 trait Foo {
index d407bee416f1f680b3328c676c06d7d29bdcbe89..dcad2e81a5488b14dc187c06bbe5ee9157a4022f 100644 (file)
@@ -2,7 +2,7 @@
 // "projection gap": in this test, we know that `T: 'x`, and that is
 // enough to conclude that `T::Foo: 'x`.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(unused_variables)]
 
index c19fa98e914066341beb0f5b332ea235c9db9b9c..ff2e10804aec5bf6a340abcd6e6e3fb08f451ea6 100644 (file)
@@ -2,7 +2,7 @@
 // "projection gap": in this test, we know that `T::Foo: 'x`, and that
 // is (naturally) enough to conclude that `T::Foo: 'x`.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(unused_variables)]
 
index 7a19d17152cd4337f85e28699b8a72bd3c81b485..3596bf7e8c2c4b7b1c2cac2cdd7281260032e562 100644 (file)
@@ -2,7 +2,7 @@
 // "projection gap": in this test, we know that `T: 'x`, and that
 // is (naturally) enough to conclude that `T: 'x`.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 #![allow(unused_variables)]
 
index 045d289149025d3e61412bbf03b9ae6330440a2a..fc4d16184014352b36688564a3dc5e29cd7d90e9 100644 (file)
@@ -3,7 +3,7 @@
 //
 // Rule OutlivesNominalType from RFC 1214.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
index e087d65a5c7bc8d97a4a36d1956da245c4d5bdb8..d716cb9c55ba7acd72cb5e48f15cc11b85dc3180 100644 (file)
@@ -3,7 +3,7 @@
 //
 // Rule OutlivesNominalType from RFC 1214.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
index 20b391c263c269e568f2d71362601d81ff332835..39eb0842d3f6a60f92654e01f362e754abd396ab 100644 (file)
@@ -3,7 +3,7 @@
 //
 // Rule OutlivesNominalType from RFC 1214.
 
-//compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
index 7f84441903f5bb89490147760e739785d7a4aac5..561cad790f00efe1749147762d4d18581b11597f 100644 (file)
@@ -3,7 +3,7 @@
 //
 // Rule OutlivesNominalType from RFC 1214.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
index 07daa35a809819e40ec8ea0aa1945017ed1b3065..e1287c34bac1332763814d914b3cb4242ab19e3e 100644 (file)
@@ -3,7 +3,7 @@
 //
 // Rule OutlivesNominalType from RFC 1214.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
index 59da5fb0dc7de360580e644323e095db43ee3cdc..7f22ae23b8500a39ecba0b0b89fe3619ab8cda3e 100644 (file)
@@ -3,7 +3,7 @@
 //
 // Rule OutlivesNominalType from RFC 1214.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
index 096069c0ca4af5752a6fd58d2629961f30c8eca5..367f7a30201577963523e9815fbcfae29d01f5ed 100644 (file)
@@ -3,7 +3,7 @@
 //
 // Rule OutlivesNominalType from RFC 1214.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
index 3c8c4a1ef52aaf14b4558f5fa4b92f60fb57587e..f780275b684d18e374eee270d1745f8defb25884 100644 (file)
@@ -3,7 +3,7 @@
 //
 // Rule OutlivesNominalType from RFC 1214.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
index a6e976ebf8c91ce972793c258b85b534096873ae..e7fe7b6c16d4f9b5abfc686f51164526490d9f54 100644 (file)
@@ -5,7 +5,7 @@
 // `'r` is bound, that leads to badness. This test checks that
 // everything works.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 trait TheTrait {
index bad476d27794ea2a3787e6192c549cfb11ef65a7..928ed4baaa030903ef28ba57eb277d6ec4132754 100644 (file)
@@ -1,7 +1,7 @@
 // Test that `<F as Foo<'a>>::Type: 'b`, where `trait Foo<'a> { Type:
 // 'a; }`, does not require that `F: 'b`.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 trait SomeTrait<'a> {
index ca012c4e1eda0c4cd92b1953e965c1e47096fad2..5d0ed9993800dd70eb32b9e9c449e98604583411 100644 (file)
@@ -1,7 +1,7 @@
 // Test that scalar values outlive all regions.
 // Rule OutlivesScalar from RFC 1214.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 struct Foo<'a> {
index 71728e8a7313d06e1548b48d96995ee71e130ca5..d2993dbc4a41770ad63b359eaece99bb1b535fc0 100644 (file)
@@ -1,7 +1,7 @@
 // edition:2018
 // aux-build:removing-extern-crate.rs
 // run-rustfix
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(rust_2018_idioms)]
 #![allow(unused_imports)]
index b9cc1810e7cb5b02ba4b800bf7f9d230402894d1..22fdfc2b0ec9c659e6b10357ba0d5fb85cc8d410 100644 (file)
@@ -1,7 +1,7 @@
 // edition:2018
 // aux-build:removing-extern-crate.rs
 // run-rustfix
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(rust_2018_idioms)]
 #![allow(unused_imports)]
index 96c63ba4db8c9dfb0879a0a8023c340f3e34a7a9..cb535362266c00365163e35fd25ce5aa82f32b64 100644 (file)
@@ -1,5 +1,7 @@
 #[rustc_attribute_should_be_reserved]
-//~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved
+//~^ ERROR attribute `rustc_attribute_should_be_reserved` is currently unknown
+//~| ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
+
 macro_rules! foo {
     () => (());
 }
index c8738d1ed3429a15b9b03778dbf18df89b5dd9e2..0c62c82017e18fb8c91879fccdb2e195a19a863f 100644 (file)
@@ -1,4 +1,4 @@
-error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics
+error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler
   --> $DIR/reserved-attr-on-macro.rs:1:3
    |
 LL | #[rustc_attribute_should_be_reserved]
@@ -7,14 +7,23 @@ LL | #[rustc_attribute_should_be_reserved]
    = note: for more information, see https://github.com/rust-lang/rust/issues/29642
    = help: add #![feature(rustc_attrs)] to the crate attributes to enable
 
+error[E0658]: The attribute `rustc_attribute_should_be_reserved` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/reserved-attr-on-macro.rs:1:3
+   |
+LL | #[rustc_attribute_should_be_reserved]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add #![feature(custom_attribute)] to the crate attributes to enable
+
 error: cannot determine resolution for the macro `foo`
-  --> $DIR/reserved-attr-on-macro.rs:8:5
+  --> $DIR/reserved-attr-on-macro.rs:10:5
    |
 LL |     foo!();
    |     ^^^
    |
    = note: import resolution is stuck, try simplifying macro imports
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
index c2a2f28254226a40672eb15e83cf55c55534b982..5dc467d97e2bee540b8e44bc825824587ce23b07 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct S(u8);
 
index 7b499af632ecee2645fe079cde2cbfe6e9b342c6..6e75977b5900ef195223b6307e98500f963a2b0b 100644 (file)
@@ -2,7 +2,7 @@
 // rust-lang/rust#2329), that starts passing with this feature in
 // place.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(bind_by_move_pattern_guards)]
 
index aca6aa5f0f8676dd6369f9b37a367361aadeb684..40588ca331eba2dea66026c85834bbe9ae857813 100644 (file)
@@ -1,6 +1,6 @@
 #![feature(bind_by_move_pattern_guards)]
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct A { a: Box<i32> }
 
index 97061310d19e29e17f6a26049304f09194b8a86f..221b5cf6bfad85e979157a6f24c0d79e3cae9d23 100644 (file)
@@ -1,5 +1,5 @@
 // aux-build:uninhabited.rs
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![deny(unreachable_patterns)]
 #![feature(exhaustive_patterns)]
 
index 62f6e4463f936f214ea2f32c9f3edb4898d9b51a..dacaf489a90825ca3094e95c9d03cdf46c96ed7e 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:variants.rs
 
 extern crate variants;
index 438923e29246c99fe5f443cd126bf217a57b41c1..b662685ae24350c9bbadee8c6e55724bd2124504 100644 (file)
@@ -6,7 +6,7 @@
 // strange errors. This test ensures that we do not give compilation
 // errors.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait MyIterator<'a>: Iterator where Self::Item: 'a { }
 
index 968da9c8d568113b2505717e3fd5545e6670dbe9..4766d75c8f412209fae536288290fcad0509c7b0 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:underscore-imports.rs
 
 #![warn(unused_imports, unused_extern_crates)]
index 95f7cae0b87d20435afc2ed5dfe436a21073c5e6..3662a466ded146a9910636fdebfc21cfd8dcbec3 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:duplicate.rs
 
 extern crate duplicate;
index 8b5bb8b326097c4e50bdb6c630c6cb779da67a95..1cccc67e9ab63d8251b80ddccc5ad08e8a11c768 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:underscore-imports.rs
 
 extern crate underscore_imports;
index a82feb961f7aad90575711e2e26ba983965ed02d..762dfbe484396201c90fc4df42c3f8fb007f7c22 100644 (file)
@@ -1,6 +1,6 @@
 // This test should pass since 'identity' is const fn.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
     const _FOO: u8 = ::std::convert::identity(42u8);
index e66d46575664f5dc25dcf935d84cb5cdd8589a6c..710fdd57ed7b3739c734254f32fec2410ee91385 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags: -Z unpretty=expanded
 
 fn main() {
index a6b15f9bbf65d94d34bfd5434aed2531ed5133f8..c88f50c6813ece083ca4de134501862710614871 100644 (file)
@@ -4,7 +4,7 @@
 use ::std::prelude::v1::*;
 #[macro_use]
 extern crate std;
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags: -Z unpretty=expanded
 
 fn main() { if let 0 = 1 { } }
index c521d04fda5626c191dbd2f905ef888ae8c8dbe4..e796e37bbaa4524460f76e36cba87244594ab500 100644 (file)
@@ -1,5 +1,5 @@
 // compile-flags: --cfg something
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(param_attrs)]
 
index 589e5fcc00ead8f9a78dd81d41a78a061715f31a..9fc32d7cc55f0c7023516cad3b461f43952d0d98 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags: -Z parse-only
 
 #![feature(generic_associated_types)]
index 7fa71e4dd1a55f9af4b610318deabf24753d5bd3..7974ee9d39b195e0e2ae18704014867297ac198c 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags: -Z parse-only
 
 #![feature(generic_associated_types)]
index 82a7c2510e5d78f0cb1ce3eb616a919f2c465c96..03492631cb7c83335478b990465480917406d931 100644 (file)
@@ -3,7 +3,7 @@
 //FIXME(#44265): The lifetime shadowing and type parameter shadowing
 // should cause an error. Now it compiles (erroneously) and this will be addressed
 // by a future PR. Then remove the following:
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 trait Shadow<'a> {
     type Bar<'a>; // Error: shadowed lifetime
index 4ab4117dd6ccd8399a9d9527495da2b99c8338a8..fdd0516e4d654f310716a2fe998408d180d5800c 100644 (file)
@@ -1,7 +1,7 @@
 // compile-flags: --emit=metadata
 // aux-build:rmeta-rlib.rs
 // no-prefer-dynamic
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Check that building a metadata crate works with a dependent, rlib crate.
 // This is a cfail test since there is no executable to run.
index 9c88de7a0330b8863b470107ca6d6547907a798c..4f0db23f47dd9917ae4e40649d8759b9f49ed5e9 100644 (file)
@@ -1,7 +1,7 @@
 // compile-flags: --emit=metadata
 // aux-build:rmeta-meta.rs
 // no-prefer-dynamic
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Check that building a metadata crate works with a dependent, metadata-only
 // crate.
index 823ce80623b6c7972048a477378f6307be26e76b..430c1f06f43ac3c71bd27602d8ee7fce40dc5a91 100644 (file)
@@ -1,6 +1,6 @@
 // compile-flags: --emit=metadata
 // no-prefer-dynamic
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #[deny(warnings)]
 
index 09b31beb775859dedaecf63813c69f1d699937fd..2005d8f4d7941df4b556b20fdf0a327b5eed5afd 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 // compile-flags:--extern edition_lint_paths
 // aux-build:edition-lint-paths.rs
index 323c6e105f50369ed21897f9aecf78d7d172c62a..950ad1f5046817098ed9bf4784e78ff6ee49123d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(unused)]
 #![deny(explicit_outlives_requirements)]
index 368b8daf243eab4ea2a372824697294a0426a66c..6cd54aa68aedd0a8f88f08f5b67148ff5fb714ee 100644 (file)
@@ -1,6 +1,6 @@
 // aux-build:macro-use-warned-against.rs
 // aux-build:macro-use-warned-against2.rs
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(macro_use_extern_crate, unused)]
 
index 3311ded553117c8c1b8c4d5b1566af76739522eb..2d4cb6514ec2c2a1a504d147745bc20478d4681a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // force-host
 // no-prefer-dynamic
 
index 14575d18c236aa3275b669bdaae93c6bd1f1c887..7ddd2f547f071cf3cf357bfed3049aab7910e5c2 100644 (file)
@@ -1,6 +1,6 @@
 // run-rustfix
 // edition:2018
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:remove-extern-crate.rs
 // compile-flags:--extern remove_extern_crate
 
index 0ee85f34e40d99c98bbdb9bbc1649af77bcec8b5..298b16140264a5b160e1f80f7b4b87e59447fc39 100644 (file)
@@ -1,6 +1,6 @@
 // run-rustfix
 // edition:2018
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:remove-extern-crate.rs
 // compile-flags:--extern remove_extern_crate
 
index f0ca24714ed48c4429f1d693ebaf7c3353fd1c7b..7d136667b6dfb3cb9a33469bfe8a6ebc1568a1c9 100644 (file)
@@ -2,7 +2,7 @@
 // edition:2015
 // run-rustfix
 // rustfix-only-machine-applicable
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rust_2018_preview)]
 #![warn(rust_2018_compatibility)]
index f0ca24714ed48c4429f1d693ebaf7c3353fd1c7b..7d136667b6dfb3cb9a33469bfe8a6ebc1568a1c9 100644 (file)
@@ -2,7 +2,7 @@
 // edition:2015
 // run-rustfix
 // rustfix-only-machine-applicable
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rust_2018_preview)]
 #![warn(rust_2018_compatibility)]
index 5af13934e844a51232794200194fb6db66664754..f86a401cdf939104a699b4d666beab61224ffe77 100644 (file)
@@ -1,5 +1,5 @@
 // run-rustfix
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(rust_2018_compatibility)]
 
index faac13ab77912cacca191fdce606ef75d04ebf3c..6cc6aa12ff76eaac5287b947bff4e28039fe9300 100644 (file)
@@ -1,5 +1,5 @@
 // run-rustfix
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(rust_2018_compatibility)]
 
index c65f0fc30ef0ab99644540689b3bc07acd5ef4a3..7c1692fd7fb13d7b2307a6859161dacbb14f4a99 100644 (file)
@@ -1,7 +1,7 @@
 // Test that `try!` macros are rewritten.
 
 // run-rustfix
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(rust_2018_compatibility)]
 #![allow(unused_variables)]
index f435890a61dcb0c8424937a17beedd9292c92f2a..2089d367be69814c55cd2ae241788ddbd80cc46e 100644 (file)
@@ -1,7 +1,7 @@
 // Test that `try!` macros are rewritten.
 
 // run-rustfix
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(rust_2018_compatibility)]
 #![allow(unused_variables)]
index 0c2da1884b758744e4aff57539597b217d0c5a08..c6525869b021af5f4d19334c2bb1961da2c30507 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
 fn main() {
index 5c3c753f9a7857eb5399e42a8dc5a9010bc0e167..9af520a07693b75893b9c833a36a9fa2ff63ad05 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
 #![feature(decl_macro)]
index 9ec3a64113116b2f0b8f6c4c7cd05c5321b88f42..446b2d05717b0baa9cce8e7e7a14c0337ed91622 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 // compile-flags: --extern issue_56596_2
 // aux-build:issue-56596-2.rs
index 9a326b4c728bdd68eb791ba6166072b08629870e..dca9587c5d3692712256fc0fc6b11ef3ac811481 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
 // Macro imported with `#[macro_use] extern crate`
index ebc2717499843c28255eb685654310f5ff02b61a..e02f3ecc6292315ceee75e22ad9fee6087f37ce4 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags: -Zsave-analysis -Zemit-artifact-notifications
 // compile-flags: --crate-type rlib --error-format=json
 // ignore-pass
index 1217823da116ea6c275749cb81a9a71f4cfc898d..b409dfd7a1e08f2178f9019712f82835e475ad7d 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // Test to make sure that explicit self params work inside closures
 
index e4fe7324ef3a63550ae789c5fcf414965f5aa23a..73f23a9cc17cfe189571fd67e815841155419686 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(untagged_unions)]
 
index 57e01caa692de9a85756576a6226e91db0e1fc0e..5eb8c3622e4bd318274566d4737310ed2471bb0b 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
index 92b25cbf584109bb4092956aeb5bae547d6098d1..d9d7e66d0cae2d12c1cfe23c604b93d2855357e2 100644 (file)
@@ -5,7 +5,7 @@
 // (Normally, using `'static` would be preferred, but there are
 // times when that is not what you want.)
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(single_use_lifetimes)]
 
index 6c4d2a4a7ad41b9eba57a22236fa720dec3257c9..7285324ef63002119d492296d408b22939285e5d 100644 (file)
@@ -2,7 +2,7 @@
 // even when they are only used once (since to not use a named
 // lifetime is illegal!)
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(single_use_lifetimes)]
 #![allow(dead_code)]
index 4cdf1530a927bbbe158c38593994d5e08c4344f5..8efe806b6e6e2635116ed9a84ea1312e044f014c 100644 (file)
@@ -1,7 +1,7 @@
 // Test that we DO NOT warn when lifetime name is used in
 // both the argument and return.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(single_use_lifetimes)]
 #![allow(dead_code)]
index 375366e41c639a0b9ed37a09a45d0650fd839b36..09b01d8b05bae8fb78a59f1f149a2ec9a1222171 100644 (file)
@@ -1,7 +1,7 @@
 // Test that we DO NOT warn when lifetime name is used multiple
 // arguments, or more than once in a single argument.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(single_use_lifetimes)]
 #![allow(dead_code)]
index 63d03a2cf0a85aec277fc911a4c2ae5930e1e7d4..eb85a148e604098052399a849283116d4424597c 100644 (file)
@@ -1,6 +1,6 @@
 // Test that we DO NOT warn for a lifetime used twice in an impl.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(single_use_lifetimes)]
 #![allow(dead_code)]
index d4a0d71713ccd530748aa12eede8a18b1905d2b9..fd8c899f4fa6bf1904f7e5b8e12c9f78aa0a44a5 100644 (file)
@@ -1,7 +1,7 @@
 // Test that we DO NOT warn for a lifetime on an impl used in both
 // header and in an associated type.
 //
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(single_use_lifetimes)]
 #![allow(dead_code)]
index 82899fc896560eaf0d2e5db7a359a2fb630a7871..f51ea55d4e6b8846396c09866bb4e906d12cc487 100644 (file)
@@ -1,7 +1,7 @@
 //! A test to ensure that helpful `note` messages aren't emitted more often
 //! than necessary.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Although there are three warnings, we should only get two "lint level defined
 // here" notes pointing at the `warnings` span, one for each error type.
index c5998c1b40310093acdb71ef717c4957d3e62143..04c7ab0ea586ffc29eba5f5dc12fe1b0863c5751 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(unused)]
 
index 753c3599975fd25391610319ace7530e28e07337..a49c60e1277f30df988ed5e57e7a76957ae10345 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![warn(unused)]
 
index 3666982b4e2987b6d7f13536af58320f3285a676..4fa48fa133be16726c1639b6660103d71a50e3d7 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![feature(extern_types)]
 
 pub mod a {
index 0ee0637232ca4d444237c8b054ac4623a3ba2af9..074280b7b664651ed7d13393280be6a32c62ee1e 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(no_core, lang_items)]
 #![no_core]
index 13c6308b97e85d4e2e021f965a9c4eabd5064086..0e10131ce8d1f4d325935d7d5b0d835db04ff8d9 100644 (file)
@@ -1,13 +1,11 @@
-#[deprcated]    //~ ERROR E0658
-fn foo() {}     //~| HELP a built-in attribute with a similar name exists
-                //~| SUGGESTION deprecated
-                //~| HELP add #![feature(custom_attribute)] to the crate attributes to enable
+#[deprcated] //~ ERROR attribute `deprcated` is currently unknown
+fn foo() {}
 
-#[tests]        //~ ERROR E0658
-fn bar() {}     //~| HELP a built-in attribute with a similar name exists
-                //~| SUGGESTION test
-                //~| HELP add #![feature(custom_attribute)] to the crate attributes to enable
+#[tests] //~ ERROR attribute `tests` is currently unknown to the compiler
+fn bar() {}
 
-#[rustc_err]    //~ ERROR E0658
-fn main() {}    //~| HELP add #![feature(rustc_attrs)] to the crate attributes to enable
-                // don't suggest rustc attributes
+#[rustc_err]
+//~^ ERROR attribute `rustc_err` is currently unknown
+//~| ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
+
+fn main() {}
index 8367ff20aa408bd3a6518ab6d2be8aad66834b68..958688b4d390652f111e5a559de34780c51eab8a 100644 (file)
@@ -1,5 +1,5 @@
-error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics
-  --> $DIR/attribute-typos.rs:11:3
+error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler
+  --> $DIR/attribute-typos.rs:7:3
    |
 LL | #[rustc_err]
    |   ^^^^^^^^^
@@ -7,8 +7,17 @@ LL | #[rustc_err]
    = note: for more information, see https://github.com/rust-lang/rust/issues/29642
    = help: add #![feature(rustc_attrs)] to the crate attributes to enable
 
+error[E0658]: The attribute `rustc_err` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/attribute-typos.rs:7:3
+   |
+LL | #[rustc_err]
+   |   ^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add #![feature(custom_attribute)] to the crate attributes to enable
+
 error[E0658]: The attribute `tests` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/attribute-typos.rs:6:3
+  --> $DIR/attribute-typos.rs:4:3
    |
 LL | #[tests]
    |   ^^^^^ help: a built-in attribute with a similar name exists: `test`
@@ -25,6 +34,6 @@ LL | #[deprcated]
    = note: for more information, see https://github.com/rust-lang/rust/issues/29642
    = help: add #![feature(custom_attribute)] to the crate attributes to enable
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
index 1773f72fc741c4476a7507f3d20b31abacaf83ea..0881a631f3a767496abecf990910cb2e25ae32fb 100644 (file)
@@ -1,6 +1,6 @@
 // aux-build:foo.rs
 // compile-flags:--extern foo
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
 #![deny(unused_extern_crates)]
index ad7424a1bbbb9c76e544cf6467144b35ec82249e..a238db6d716238c699c745d29922045376fd7010 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags:--test
 
 #![deny(warnings)]
index b1c2a000d4a58e7cb3913eea6f2d425fd5ace9d1..831372d4506b312288dcb831d5b4da0995a587fa 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // aux-build:test_macro.rs
 // compile-flags:--test
 
index f936dd5758747f8d05f0babbbcfa4b6dce1bfb4e..9c38322fe96fd754f209b1b26bdeb2b0d21bd645 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // compile-flags: --test
 
 #[test]
index 964e21779d51bd8aa9596de1691e626656ee2665..4f25e57be566bd3ba1be6569e493b6ca79f84d3a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // #39665
 
 fn batches(n: &u32) -> impl Iterator<Item=&u32> {
index 3dfcf03ce79da7193881532f9e7df8e48ce96e71..284baa481497c9aece261db687df3d9c1c712036 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Test that `dyn ... + ?Sized + ...` resulting from the expansion of trait aliases is okay.
 
index 793d556d08ca24e71ddecb06dae6c6183f396e33..d1b7bf6c2d766cd886cb9999f7c13b53547425e9 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // Regression test related to #56288. Check that a supertrait projection (of
 // `Output`) that references `Self` can be ok if it is referencing a projection (of
index 3e9f612a2afee3af146ae55bf3b239d65390b53f..83dfe6664a505f5574246a074ec0a4dd4239cdbc 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // FIXME(eddyb) shorten the name so windows doesn't choke on it.
 #![crate_name = "trait_test"]
index 6254157e25da3eb960bfbbae82f677d0546a7fbb..17a2e05e99f2c7624e095a497a5186b0c28905d1 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 mod foo {
     pub use self::bar::T;
index 86d6585bc614316270b75ca6ba96c952c474bd3a..a3e3b31df922e48689efe468bb7a7ade4ab144e4 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 // #55266
 
 struct VTable<DST: ?Sized> {
index 06aa698ddefd7385396508a64cd76a743aacb40b..5538e0303ed12e939eb531a43246c84e22894254 100644 (file)
@@ -2,7 +2,7 @@
 // types are required. This test now just compiles fine, since the
 // relevant rules that triggered the overflow were removed.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 use std::marker::PhantomData;
index f63950ad5e9058981224fd1ca8e6f6ebd90cbf01..d42e51c7405ba327db90733b23e455f2dc0a632f 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(dead_code, unused)]
 
diff --git a/src/test/ui/type-alias-enum-variants-panic.rs b/src/test/ui/type-alias-enum-variants-panic.rs
deleted file mode 100644 (file)
index f97592f..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// ignore-tidy-linelength
-
-#![feature(type_alias_enum_variants)]
-
-#![allow(unreachable_code)]
-
-enum Enum { Variant {} }
-type Alias = Enum;
-
-fn main() {
-    Alias::Variant;
-    //~^ ERROR expected unit struct/variant or constant, found struct variant `<Alias>::Variant` [E0533]
-    let Alias::Variant = panic!();
-    //~^ ERROR expected unit struct/variant or constant, found struct variant `<Alias>::Variant` [E0533]
-    let Alias::Variant(..) = panic!();
-    //~^ ERROR expected tuple struct/variant, found struct variant `<Alias>::Variant` [E0164]
-}
diff --git a/src/test/ui/type-alias-enum-variants-panic.stderr b/src/test/ui/type-alias-enum-variants-panic.stderr
deleted file mode 100644 (file)
index 24cf85f..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0533]: expected unit struct/variant or constant, found struct variant `<Alias>::Variant`
-  --> $DIR/type-alias-enum-variants-panic.rs:11:5
-   |
-LL |     Alias::Variant;
-   |     ^^^^^^^^^^^^^^
-
-error[E0533]: expected unit struct/variant or constant, found struct variant `<Alias>::Variant`
-  --> $DIR/type-alias-enum-variants-panic.rs:13:9
-   |
-LL |     let Alias::Variant = panic!();
-   |         ^^^^^^^^^^^^^^
-
-error[E0164]: expected tuple struct/variant, found struct variant `<Alias>::Variant`
-  --> $DIR/type-alias-enum-variants-panic.rs:15:9
-   |
-LL |     let Alias::Variant(..) = panic!();
-   |         ^^^^^^^^^^^^^^^^^^ not a tuple variant or struct
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0164`.
diff --git a/src/test/ui/type-alias-enum-variants-priority-2.rs b/src/test/ui/type-alias-enum-variants-priority-2.rs
deleted file mode 100644 (file)
index 295f8ac..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#![feature(type_alias_enum_variants)]
-
-enum E {
-    V(u8)
-}
-
-impl E {
-    fn V() {}
-}
-
-fn main() {
-    <E>::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied
-}
diff --git a/src/test/ui/type-alias-enum-variants-priority-2.stderr b/src/test/ui/type-alias-enum-variants-priority-2.stderr
deleted file mode 100644 (file)
index 10a4b44..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0061]: this function takes 1 parameter but 0 parameters were supplied
-  --> $DIR/type-alias-enum-variants-priority-2.rs:12:5
-   |
-LL |     V(u8)
-   |     ----- defined here
-...
-LL |     <E>::V();
-   |     ^^^^^^^^ expected 1 parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0061`.
diff --git a/src/test/ui/type-alias-enum-variants-priority-3.rs b/src/test/ui/type-alias-enum-variants-priority-3.rs
deleted file mode 100644 (file)
index 33f9655..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#![feature(type_alias_enum_variants)]
-
-enum E {
-    V
-}
-
-fn check() -> <E>::V {}
-//~^ ERROR expected type, found variant `V`
-
-fn main() {}
diff --git a/src/test/ui/type-alias-enum-variants-priority-3.stderr b/src/test/ui/type-alias-enum-variants-priority-3.stderr
deleted file mode 100644 (file)
index b345154..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: expected type, found variant `V`
-  --> $DIR/type-alias-enum-variants-priority-3.rs:7:15
-   |
-LL | fn check() -> <E>::V {}
-   |               ^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/type-alias-enum-variants-priority.rs b/src/test/ui/type-alias-enum-variants-priority.rs
deleted file mode 100644 (file)
index 82cd21b..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#![feature(type_alias_enum_variants)]
-
-enum E {
-    V
-}
-
-trait Tr {
-    type V;
-    fn f() -> Self::V;
-}
-
-impl Tr for E {
-    type V = u8;
-    fn f() -> Self::V { 0 }
-    //~^ ERROR ambiguous associated item
-    //~| WARN this was previously accepted
-}
-
-fn main() {}
diff --git a/src/test/ui/type-alias-enum-variants-priority.stderr b/src/test/ui/type-alias-enum-variants-priority.stderr
deleted file mode 100644 (file)
index b827180..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-error: ambiguous associated item
-  --> $DIR/type-alias-enum-variants-priority.rs:14:15
-   |
-LL |     fn f() -> Self::V { 0 }
-   |               ^^^^^^^ help: use fully-qualified syntax: `<E as Trait>::V`
-   |
-   = note: #[deny(ambiguous_associated_items)] on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #57644 <https://github.com/rust-lang/rust/issues/57644>
-note: `V` could refer to variant defined here
-  --> $DIR/type-alias-enum-variants-priority.rs:4:5
-   |
-LL |     V
-   |     ^
-note: `V` could also refer to associated type defined here
-  --> $DIR/type-alias-enum-variants-priority.rs:8:5
-   |
-LL |     type V;
-   |     ^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/type-alias-enum-variants.rs b/src/test/ui/type-alias-enum-variants.rs
deleted file mode 100644 (file)
index c5974e5..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#![feature(type_alias_enum_variants)]
-
-type Alias<T> = Option<T>;
-
-fn main() {
-    let _ = Option::<u8>::None; // OK
-    let _ = Option::None::<u8>; // OK (Lint in future!)
-    let _ = Alias::<u8>::None; // OK
-    let _ = Alias::None::<u8>; // Error
-    //~^ type arguments are not allowed for this type
-}
diff --git a/src/test/ui/type-alias-enum-variants.stderr b/src/test/ui/type-alias-enum-variants.stderr
deleted file mode 100644 (file)
index 55f250f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0109]: type arguments are not allowed for this type
-  --> $DIR/type-alias-enum-variants.rs:9:27
-   |
-LL |     let _ = Alias::None::<u8>; // Error
-   |                           ^^ type argument not allowed
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0109`.
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs
new file mode 100644 (file)
index 0000000..0c21209
--- /dev/null
@@ -0,0 +1,59 @@
+// run-pass
+
+// Check that resolving, in the value namespace, to an `enum` variant
+// through a type alias is well behaved in the presence of generics.
+// We check for situations with:
+// 1. a generic type `Alias<T>`, we can type-apply `Alias` when referring to a variant.
+// 2. a monotype `AliasFixed` of generic `Enum<T>`, we can refer to variants
+//    and the type-application of `T` in `AliasFixed` is kept.
+
+#![allow(irrefutable_let_patterns)]
+
+enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
+type Alias<T> = Enum<T>;
+type AliasFixed = Enum<()>;
+
+macro_rules! is_variant {
+    (TSVariant, $expr:expr) => (is_variant!(@check TSVariant, (_), $expr));
+    (SVariant, $expr:expr) => (is_variant!(@check SVariant, { v: _ }, $expr));
+    (UVariant, $expr:expr) => (is_variant!(@check UVariant, {}, $expr));
+    (@check $variant:ident, $matcher:tt, $expr:expr) => (
+        assert!(if let Enum::$variant::<()> $matcher = $expr { true } else { false },
+                "expr does not have correct type");
+    );
+}
+
+fn main() {
+    // Tuple struct variant
+
+    is_variant!(TSVariant, Enum::TSVariant(()));
+    is_variant!(TSVariant, Enum::TSVariant::<()>(()));
+    is_variant!(TSVariant, Enum::<()>::TSVariant(()));
+
+    is_variant!(TSVariant, Alias::TSVariant(()));
+    is_variant!(TSVariant, Alias::<()>::TSVariant(()));
+
+    is_variant!(TSVariant, AliasFixed::TSVariant(()));
+
+    // Struct variant
+
+    is_variant!(SVariant, Enum::SVariant { v: () });
+    is_variant!(SVariant, Enum::SVariant::<()> { v: () });
+    is_variant!(SVariant, Enum::<()>::SVariant { v: () });
+
+    is_variant!(SVariant, Alias::SVariant { v: () });
+    is_variant!(SVariant, Alias::<()>::SVariant { v: () });
+
+    is_variant!(SVariant, AliasFixed::SVariant { v: () });
+
+    // Unit variant
+
+    is_variant!(UVariant, Enum::UVariant);
+    is_variant!(UVariant, Enum::UVariant::<()>);
+    is_variant!(UVariant, Enum::<()>::UVariant);
+
+    is_variant!(UVariant, Alias::UVariant);
+    is_variant!(UVariant, Alias::<()>::UVariant);
+
+    is_variant!(UVariant, AliasFixed::UVariant);
+}
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs
new file mode 100644 (file)
index 0000000..f182c3b
--- /dev/null
@@ -0,0 +1,105 @@
+// Checks that applied type arguments of enums, and aliases to them, are respected.
+// For example, `Self` is never a type constructor. Therefore, no types can be applied to it.
+//
+// We also check that the variant to an type-aliased enum cannot be type applied whether
+// that alias is generic or monomorphic.
+
+enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
+type Alias<T> = Enum<T>;
+type AliasFixed = Enum<()>;
+
+impl<T> Enum<T> {
+    fn ts_variant() {
+        Self::TSVariant(());
+        //~^ ERROR mismatched types [E0308]
+        Self::TSVariant::<()>(());
+        //~^ ERROR type arguments are not allowed for this type [E0109]
+        Self::<()>::TSVariant(());
+        //~^ ERROR type arguments are not allowed for this type [E0109]
+        //~^^ ERROR mismatched types [E0308]
+        Self::<()>::TSVariant::<()>(());
+        //~^ ERROR type arguments are not allowed for this type [E0109]
+        //~^^ ERROR type arguments are not allowed for this type [E0109]
+    }
+
+    fn s_variant() {
+        Self::SVariant { v: () };
+        //~^ ERROR mismatched types [E0308]
+        Self::SVariant::<()> { v: () };
+        //~^ ERROR type arguments are not allowed for this type [E0109]
+        //~^^ ERROR mismatched types [E0308]
+        Self::<()>::SVariant { v: () };
+        //~^ ERROR type arguments are not allowed for this type [E0109]
+        //~^^ ERROR mismatched types [E0308]
+        Self::<()>::SVariant::<()> { v: () };
+        //~^ ERROR type arguments are not allowed for this type [E0109]
+        //~^^ ERROR type arguments are not allowed for this type [E0109]
+        //~^^^ ERROR mismatched types [E0308]
+    }
+
+    fn u_variant() {
+        Self::UVariant::<()>;
+        //~^ ERROR type arguments are not allowed for this type [E0109]
+        Self::<()>::UVariant;
+        //~^ ERROR type arguments are not allowed for this type [E0109]
+        Self::<()>::UVariant::<()>;
+        //~^ ERROR type arguments are not allowed for this type [E0109]
+        //~^^ ERROR type arguments are not allowed for this type [E0109]
+    }
+}
+
+fn main() {
+    // Tuple struct variant
+
+    Enum::<()>::TSVariant::<()>(());
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+
+    Alias::TSVariant::<()>(());
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+    Alias::<()>::TSVariant::<()>(());
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+
+    AliasFixed::TSVariant::<()>(());
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+    AliasFixed::<()>::TSVariant(());
+    //~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
+    AliasFixed::<()>::TSVariant::<()>(());
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+    //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
+
+    // Struct variant
+
+    Enum::<()>::SVariant::<()> { v: () };
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+
+    Alias::SVariant::<()> { v: () };
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+    Alias::<()>::SVariant::<()> { v: () };
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+
+    AliasFixed::SVariant::<()> { v: () };
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+    AliasFixed::<()>::SVariant { v: () };
+    //~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
+    AliasFixed::<()>::SVariant::<()> { v: () };
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+    //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
+
+    // Unit variant
+
+    Enum::<()>::UVariant::<()>;
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+
+    Alias::UVariant::<()>;
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+    Alias::<()>::UVariant::<()>;
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+
+    AliasFixed::UVariant::<()>;
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+    AliasFixed::<()>::UVariant;
+    //~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
+    AliasFixed::<()>::UVariant::<()>;
+    //~^ ERROR type arguments are not allowed for this type [E0109]
+    //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
+}
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
new file mode 100644 (file)
index 0000000..ee73622
--- /dev/null
@@ -0,0 +1,256 @@
+error[E0308]: mismatched types
+  --> $DIR/enum-variant-generic-args.rs:13:25
+   |
+LL |         Self::TSVariant(());
+   |                         ^^ expected type parameter, found ()
+   |
+   = note: expected type `T`
+              found type `()`
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:15:27
+   |
+LL |         Self::TSVariant::<()>(());
+   |                           ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:17:16
+   |
+LL |         Self::<()>::TSVariant(());
+   |                ^^ type argument not allowed
+
+error[E0308]: mismatched types
+  --> $DIR/enum-variant-generic-args.rs:17:31
+   |
+LL |         Self::<()>::TSVariant(());
+   |                               ^^ expected type parameter, found ()
+   |
+   = note: expected type `T`
+              found type `()`
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:20:16
+   |
+LL |         Self::<()>::TSVariant::<()>(());
+   |                ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:20:33
+   |
+LL |         Self::<()>::TSVariant::<()>(());
+   |                                 ^^ type argument not allowed
+
+error[E0308]: mismatched types
+  --> $DIR/enum-variant-generic-args.rs:26:29
+   |
+LL |         Self::SVariant { v: () };
+   |                             ^^ expected type parameter, found ()
+   |
+   = note: expected type `T`
+              found type `()`
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:28:26
+   |
+LL |         Self::SVariant::<()> { v: () };
+   |                          ^^ type argument not allowed
+
+error[E0308]: mismatched types
+  --> $DIR/enum-variant-generic-args.rs:28:35
+   |
+LL |         Self::SVariant::<()> { v: () };
+   |                                   ^^ expected type parameter, found ()
+   |
+   = note: expected type `T`
+              found type `()`
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:31:16
+   |
+LL |         Self::<()>::SVariant { v: () };
+   |                ^^ type argument not allowed
+
+error[E0308]: mismatched types
+  --> $DIR/enum-variant-generic-args.rs:31:35
+   |
+LL |         Self::<()>::SVariant { v: () };
+   |                                   ^^ expected type parameter, found ()
+   |
+   = note: expected type `T`
+              found type `()`
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:34:16
+   |
+LL |         Self::<()>::SVariant::<()> { v: () };
+   |                ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:34:32
+   |
+LL |         Self::<()>::SVariant::<()> { v: () };
+   |                                ^^ type argument not allowed
+
+error[E0308]: mismatched types
+  --> $DIR/enum-variant-generic-args.rs:34:41
+   |
+LL |         Self::<()>::SVariant::<()> { v: () };
+   |                                         ^^ expected type parameter, found ()
+   |
+   = note: expected type `T`
+              found type `()`
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:41:26
+   |
+LL |         Self::UVariant::<()>;
+   |                          ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:43:16
+   |
+LL |         Self::<()>::UVariant;
+   |                ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:45:16
+   |
+LL |         Self::<()>::UVariant::<()>;
+   |                ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:45:32
+   |
+LL |         Self::<()>::UVariant::<()>;
+   |                                ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:54:29
+   |
+LL |     Enum::<()>::TSVariant::<()>(());
+   |                             ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:57:24
+   |
+LL |     Alias::TSVariant::<()>(());
+   |                        ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:59:30
+   |
+LL |     Alias::<()>::TSVariant::<()>(());
+   |                              ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:62:29
+   |
+LL |     AliasFixed::TSVariant::<()>(());
+   |                             ^^ type argument not allowed
+
+error[E0107]: wrong number of type arguments: expected 0, found 1
+  --> $DIR/enum-variant-generic-args.rs:64:18
+   |
+LL |     AliasFixed::<()>::TSVariant(());
+   |                  ^^ unexpected type argument
+
+error[E0107]: wrong number of type arguments: expected 0, found 1
+  --> $DIR/enum-variant-generic-args.rs:66:18
+   |
+LL |     AliasFixed::<()>::TSVariant::<()>(());
+   |                  ^^ unexpected type argument
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:66:35
+   |
+LL |     AliasFixed::<()>::TSVariant::<()>(());
+   |                                   ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:72:28
+   |
+LL |     Enum::<()>::SVariant::<()> { v: () };
+   |                            ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:75:23
+   |
+LL |     Alias::SVariant::<()> { v: () };
+   |                       ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:77:29
+   |
+LL |     Alias::<()>::SVariant::<()> { v: () };
+   |                             ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:80:28
+   |
+LL |     AliasFixed::SVariant::<()> { v: () };
+   |                            ^^ type argument not allowed
+
+error[E0107]: wrong number of type arguments: expected 0, found 1
+  --> $DIR/enum-variant-generic-args.rs:82:18
+   |
+LL |     AliasFixed::<()>::SVariant { v: () };
+   |                  ^^ unexpected type argument
+
+error[E0107]: wrong number of type arguments: expected 0, found 1
+  --> $DIR/enum-variant-generic-args.rs:84:18
+   |
+LL |     AliasFixed::<()>::SVariant::<()> { v: () };
+   |                  ^^ unexpected type argument
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:84:34
+   |
+LL |     AliasFixed::<()>::SVariant::<()> { v: () };
+   |                                  ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:90:28
+   |
+LL |     Enum::<()>::UVariant::<()>;
+   |                            ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:93:23
+   |
+LL |     Alias::UVariant::<()>;
+   |                       ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:95:29
+   |
+LL |     Alias::<()>::UVariant::<()>;
+   |                             ^^ type argument not allowed
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:98:28
+   |
+LL |     AliasFixed::UVariant::<()>;
+   |                            ^^ type argument not allowed
+
+error[E0107]: wrong number of type arguments: expected 0, found 1
+  --> $DIR/enum-variant-generic-args.rs:100:18
+   |
+LL |     AliasFixed::<()>::UVariant;
+   |                  ^^ unexpected type argument
+
+error[E0107]: wrong number of type arguments: expected 0, found 1
+  --> $DIR/enum-variant-generic-args.rs:102:18
+   |
+LL |     AliasFixed::<()>::UVariant::<()>;
+   |                  ^^ unexpected type argument
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/enum-variant-generic-args.rs:102:34
+   |
+LL |     AliasFixed::<()>::UVariant::<()>;
+   |                                  ^^ type argument not allowed
+
+error: aborting due to 39 previous errors
+
+Some errors have detailed explanations: E0107, E0109, E0308.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs
new file mode 100644 (file)
index 0000000..fa3e1a3
--- /dev/null
@@ -0,0 +1,23 @@
+// Check that an `enum` variant is resolved, in the value namespace,
+// with higher priority than other inherent items when there is a conflict.
+
+enum E {
+    V(u8)
+}
+
+impl E {
+    fn V() {}
+}
+
+enum E2 {
+    V,
+}
+
+impl E2 {
+    const V: u8 = 0;
+}
+
+fn main() {
+    <E>::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied
+    let _: u8 = <E2>::V; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
new file mode 100644 (file)
index 0000000..0394dda
--- /dev/null
@@ -0,0 +1,22 @@
+error[E0061]: this function takes 1 parameter but 0 parameters were supplied
+  --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:21:5
+   |
+LL |     V(u8)
+   |     ----- defined here
+...
+LL |     <E>::V();
+   |     ^^^^^^^^ expected 1 parameter
+
+error[E0308]: mismatched types
+  --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:22:17
+   |
+LL |     let _: u8 = <E2>::V;
+   |                 ^^^^^^^ expected u8, found enum `E2`
+   |
+   = note: expected type `u8`
+              found type `E2`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0061, E0308.
+For more information about an error, try `rustc --explain E0061`.
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs
new file mode 100644 (file)
index 0000000..7f69590
--- /dev/null
@@ -0,0 +1,37 @@
+// Check that a projection `Self::V` in a trait implementation,
+// with an associated type named `V`, for an `enum` with a variant named `V`,
+// results in triggering the deny-by-default lint `ambiguous_associated_items`.
+// The lint suggests that qualified syntax should be used instead.
+// That is, the user would write `<Self as Tr>::V`.
+//
+// The rationale for this is that while `enum` variants do currently
+// not exist in the type namespace but solely in the value namespace,
+// RFC #2593 "Enum variant types", would add enum variants to the type namespace.
+// However, currently `enum` variants are resolved with high priority as
+// they are resolved as inherent associated items.
+// Should #2953 therefore be implemented, `Self::V` would suddenly switch
+// from referring to the associated type `V` instead of the variant `V`.
+// The lint exists to keep us forward compatible with #2593.
+//
+// As a closing note, provided that #2933 was implemented and
+// if `enum` variants were given lower priority than associated types,
+// it would be impossible to refer to the `enum` variant `V` whereas
+// the associated type could be referred to with qualified syntax as seen above.
+
+enum E {
+    V
+}
+
+trait Tr {
+    type V;
+    fn f() -> Self::V;
+}
+
+impl Tr for E {
+    type V = u8;
+    fn f() -> Self::V { 0 }
+    //~^ ERROR ambiguous associated item
+    //~| WARN this was previously accepted
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr
new file mode 100644 (file)
index 0000000..f0dd689
--- /dev/null
@@ -0,0 +1,22 @@
+error: ambiguous associated item
+  --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:32:15
+   |
+LL |     fn f() -> Self::V { 0 }
+   |               ^^^^^^^ help: use fully-qualified syntax: `<E as Trait>::V`
+   |
+   = note: #[deny(ambiguous_associated_items)] on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #57644 <https://github.com/rust-lang/rust/issues/57644>
+note: `V` could refer to variant defined here
+  --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:22:5
+   |
+LL |     V
+   |     ^
+note: `V` could also refer to associated type defined here
+  --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:26:5
+   |
+LL |     type V;
+   |     ^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs
new file mode 100644 (file)
index 0000000..c1e56fc
--- /dev/null
@@ -0,0 +1,14 @@
+pub enum Enum {
+    A(usize),
+}
+
+impl Enum {
+    fn foo(&self) -> () {
+        match self {
+            Self::A => (),
+            //~^ ERROR expected unit struct/variant or constant, found tuple variant
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr
new file mode 100644 (file)
index 0000000..128a85e
--- /dev/null
@@ -0,0 +1,8 @@
+error[E0533]: expected unit struct/variant or constant, found tuple variant `<Self>::A`
+  --> $DIR/incorrect-variant-form-through-Self-issue-58006.rs:8:13
+   |
+LL |             Self::A => (),
+   |             ^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs
new file mode 100644 (file)
index 0000000..ce45d59
--- /dev/null
@@ -0,0 +1,21 @@
+// ignore-tidy-linelength
+
+// Check that creating/matching on an enum variant through an alias with
+// the wrong braced/unit form is caught as an error.
+
+enum Enum { Braced {}, Unit, Tuple() }
+type Alias = Enum;
+
+fn main() {
+    Alias::Braced;
+    //~^ ERROR expected unit struct/variant or constant, found struct variant `<Alias>::Braced` [E0533]
+    let Alias::Braced = panic!();
+    //~^ ERROR expected unit struct/variant or constant, found struct variant `<Alias>::Braced` [E0533]
+    let Alias::Braced(..) = panic!();
+    //~^ ERROR expected tuple struct/variant, found struct variant `<Alias>::Braced` [E0164]
+
+    Alias::Unit();
+    //~^ ERROR expected function, found enum variant `<Alias>::Unit`
+    let Alias::Unit() = panic!();
+    //~^ ERROR expected tuple struct/variant, found unit variant `<Alias>::Unit` [E0164]
+}
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr
new file mode 100644 (file)
index 0000000..c1ea816
--- /dev/null
@@ -0,0 +1,43 @@
+error[E0533]: expected unit struct/variant or constant, found struct variant `<Alias>::Braced`
+  --> $DIR/incorrect-variant-form-through-alias-caught.rs:10:5
+   |
+LL |     Alias::Braced;
+   |     ^^^^^^^^^^^^^
+
+error[E0533]: expected unit struct/variant or constant, found struct variant `<Alias>::Braced`
+  --> $DIR/incorrect-variant-form-through-alias-caught.rs:12:9
+   |
+LL |     let Alias::Braced = panic!();
+   |         ^^^^^^^^^^^^^
+
+error[E0164]: expected tuple struct/variant, found struct variant `<Alias>::Braced`
+  --> $DIR/incorrect-variant-form-through-alias-caught.rs:14:9
+   |
+LL |     let Alias::Braced(..) = panic!();
+   |         ^^^^^^^^^^^^^^^^^ not a tuple variant or struct
+
+error[E0618]: expected function, found enum variant `<Alias>::Unit`
+  --> $DIR/incorrect-variant-form-through-alias-caught.rs:17:5
+   |
+LL | enum Enum { Braced {}, Unit, Tuple() }
+   |                        ---- `<Alias>::Unit` defined here
+...
+LL |     Alias::Unit();
+   |     ^^^^^^^^^^^--
+   |     |
+   |     call expression requires function
+help: `<Alias>::Unit` is a unit variant, you need to write it without the parenthesis
+   |
+LL |     <Alias>::Unit;
+   |     ^^^^^^^^^^^^^
+
+error[E0164]: expected tuple struct/variant, found unit variant `<Alias>::Unit`
+  --> $DIR/incorrect-variant-form-through-alias-caught.rs:19:9
+   |
+LL |     let Alias::Unit() = panic!();
+   |         ^^^^^^^^^^^^^ not a tuple variant or struct
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0164, E0618.
+For more information about an error, try `rustc --explain E0164`.
diff --git a/src/test/ui/type-alias-enum-variants/issue-57866.rs b/src/test/ui/type-alias-enum-variants/issue-57866.rs
new file mode 100644 (file)
index 0000000..058b58e
--- /dev/null
@@ -0,0 +1,24 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+enum Outer<T> {
+    A(T)
+}
+
+enum Inner {
+    A(i32)
+}
+
+type OuterAlias = Outer<Inner>;
+
+fn ice(x: OuterAlias) {
+    // Fine
+    match x {
+        OuterAlias::A(Inner::A(_)) => (),
+    }
+    // Not fine
+    match x {
+        OuterAlias::A(Inner::A(y)) => (),
+    }
+}
+
+fn main() {}
index 21be61acb0c61cbbea3f4965fda79dc08793c561..bff04daed0d583b0e025643d9cae1009618e722e 100644 (file)
@@ -1,9 +1,7 @@
 // In this regression test we check that a path pattern referring to a unit variant
 // through a type alias is successful in inferring the generic argument.
 
-// compile-pass
-
-#![feature(type_alias_enum_variants)]
+// build-pass (FIXME(62277): could be check-pass?)
 
 enum Opt<T> {
     N,
diff --git a/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs
new file mode 100644 (file)
index 0000000..c1153fa
--- /dev/null
@@ -0,0 +1,14 @@
+// Check that a generic type for an `enum` admits type application
+// on both the type constructor and the generic type's variant.
+//
+// Also check that a type alias to said generic type admits type application
+// on the type constructor but *NOT* the variant.
+
+type Alias<T> = Option<T>;
+
+fn main() {
+    let _ = Option::<u8>::None; // OK
+    let _ = Option::None::<u8>; // OK (Lint in future!)
+    let _ = Alias::<u8>::None; // OK
+    let _ = Alias::None::<u8>; //~ ERROR type arguments are not allowed for this type
+}
diff --git a/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr
new file mode 100644 (file)
index 0000000..a1064d6
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/no-type-application-on-aliased-enum-variant.rs:13:27
+   |
+LL |     let _ = Alias::None::<u8>;
+   |                           ^^ type argument not allowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0109`.
diff --git a/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs
new file mode 100644 (file)
index 0000000..11f4b05
--- /dev/null
@@ -0,0 +1,11 @@
+// Check that the compiler will resolve `<E>::V` to the variant `V` in the type namespace
+// but will reject this because `enum` variants do not exist in the type namespace.
+
+enum E {
+    V
+}
+
+fn check() -> <E>::V {}
+//~^ ERROR expected type, found variant `V`
+
+fn main() {}
diff --git a/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr
new file mode 100644 (file)
index 0000000..f190bfb
--- /dev/null
@@ -0,0 +1,8 @@
+error: expected type, found variant `V`
+  --> $DIR/resolve-to-enum-variant-in-type-namespace-and-error.rs:8:15
+   |
+LL | fn check() -> <E>::V {}
+   |               ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs b/src/test/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs
new file mode 100644 (file)
index 0000000..3967773
--- /dev/null
@@ -0,0 +1,69 @@
+// run-pass
+
+// Check that it is possible to resolve, in the value namespace,
+// to an `enum` variant through a type alias. This includes `Self`.
+// Type qualified syntax `<Type>::Variant` also works when syntactically valid.
+
+#[derive(Debug, PartialEq, Eq)]
+enum Foo {
+    Bar(i32),
+    Baz { i: i32 },
+    Qux,
+}
+
+type FooAlias = Foo;
+type OptionAlias = Option<i32>;
+
+macro_rules! check_pat {
+    ($x:expr, $p:pat) => {
+        assert!(if let $p = $x { true } else { false });
+    };
+}
+
+impl Foo {
+    fn bar() -> Self {
+        let x = Self::Bar(3);
+        assert_eq!(x, <Self>::Bar(3));
+        check_pat!(x, Self::Bar(3));
+        x
+    }
+
+    fn baz() -> Self {
+        let x = Self::Baz { i: 42 };
+        check_pat!(x, Self::Baz { i: 42 });
+        x
+    }
+
+    fn qux() -> Self {
+        let x = Self::Qux;
+        assert_eq!(x, <Self>::Qux);
+        check_pat!(x, Self::Qux);
+        check_pat!(x, <Self>::Qux);
+        x
+    }
+}
+
+fn main() {
+    let bar = Foo::Bar(1);
+    assert_eq!(bar, FooAlias::Bar(1));
+    assert_eq!(bar, <FooAlias>::Bar(1));
+    check_pat!(bar, FooAlias::Bar(1));
+
+    let baz = FooAlias::Baz { i: 2 };
+    assert_eq!(baz, Foo::Baz { i: 2 });
+    check_pat!(baz, FooAlias::Baz { i: 2 });
+
+    let qux = Foo::Qux;
+    assert_eq!(qux, FooAlias::Qux);
+    assert_eq!(qux, <FooAlias>::Qux);
+    check_pat!(qux, FooAlias::Qux);
+    check_pat!(qux, <FooAlias>::Qux);
+
+    assert_eq!(Foo::bar(), Foo::Bar(3));
+    assert_eq!(Foo::baz(), Foo::Baz { i: 42 });
+    assert_eq!(Foo::qux(), Foo::Qux);
+
+    let some = Option::Some(4);
+    assert_eq!(some, OptionAlias::Some(4));
+    check_pat!(some, OptionAlias::Some(4));
+}
index f3cc5becc6f74c5f5515dbae2a5910c8557c4d38..06705a2ebf5ddb9d1dd0bb5d2f46b1a370e2fc38 100644 (file)
@@ -1,6 +1,6 @@
 // Test `ignored_generic_bounds` lint warning about bounds in type aliases.
 
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![allow(dead_code)]
 
 use std::rc::Rc;
index 9eed80ad886e0c876a3d14e08031382e7404dec3..710b7c9bbeefcb206061b1009cf532950d1990ef 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // rust-lang/rust#55810: types for a binding in a match arm can be
 // inferred from arms that come later in the match.
index 9fe8a5c832c5a6e1e47cdd78054d3ebe59f20d34..f476704cd8af020fd95052081dd2496cb17a76bd 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![deny(unused_variables)]
 
index 38a52d5860d4b667ee83e1bb79a84a3c98dd9e0f..a5360fa13c4ea22f730ed317413532b976db2976 100644 (file)
@@ -1,3 +1,5 @@
+#![allow(deprecated)]
+
 enum Void {}
 
 fn main() {
index de7a963577085e04d8443ebe1d1a2ed9fc4be155..25519ab2d6a7d1cfc9130988a68bd7df10b6be6e 100644 (file)
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `Err(_)` not covered
-  --> $DIR/uninhabited-matches-feature-gated.rs:5:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:7:19
    |
 LL |     let _ = match x {
    |                   ^ pattern `Err(_)` not covered
@@ -7,7 +7,7 @@ LL |     let _ = match x {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: type `&Void` is non-empty
-  --> $DIR/uninhabited-matches-feature-gated.rs:10:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:12:19
    |
 LL |     let _ = match x {};
    |                   ^
@@ -15,7 +15,7 @@ LL |     let _ = match x {};
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty
-  --> $DIR/uninhabited-matches-feature-gated.rs:13:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:15:19
    |
 LL |     let _ = match x {};
    |                   ^
@@ -23,7 +23,7 @@ LL |     let _ = match x {};
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty
-  --> $DIR/uninhabited-matches-feature-gated.rs:16:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:18:19
    |
 LL |     let _ = match x {};
    |                   ^
@@ -31,7 +31,7 @@ LL |     let _ = match x {};
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `&[_]` not covered
-  --> $DIR/uninhabited-matches-feature-gated.rs:19:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:21:19
    |
 LL |     let _ = match x {
    |                   ^ pattern `&[_]` not covered
@@ -39,7 +39,7 @@ LL |     let _ = match x {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `Err(_)` not covered
-  --> $DIR/uninhabited-matches-feature-gated.rs:27:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:29:19
    |
 LL |     let _ = match x {
    |                   ^ pattern `Err(_)` not covered
@@ -47,7 +47,7 @@ LL |     let _ = match x {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0005]: refutable pattern in local binding: `Err(_)` not covered
-  --> $DIR/uninhabited-matches-feature-gated.rs:32:9
+  --> $DIR/uninhabited-matches-feature-gated.rs:34:9
    |
 LL |     let Ok(x) = x;
    |         ^^^^^ pattern `Err(_)` not covered
index 05e849a3bb617852702dc047625e6186c2d3841c..90af8de447dfdaa2c9eea756580b7c51bb3a5a6a 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![feature(const_fn_union)]
 
 union U {
index 6665c58e457f118d5a8f8bc48e3c1080e08f1878..cbc5fcee2f0350e6a9836eeec39ac7552249e0c6 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 #![feature(never_type, exhaustive_patterns)]
 #![warn(unreachable_code)]
 #![warn(unreachable_patterns)]
index b07ab96bce13fe55ce2a4d58c9926c0c7f456a3c..e31bc91a00aad97ce4529103f5248831ef72c996 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
 
index 2e6bd82bda302b34a5da5c9f07b7d17bf067015d..19ad97a853e8301cfb495a9d9e380f4d819cf8c5 100644 (file)
@@ -1,4 +1,4 @@
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 // `std::ops::Index` has an `: ?Sized` bound on the `Idx` type param. This is
 // an accidental left-over from the times when it `Index` was by-reference.
index 31bfdd025d99dcd733898e547a794d9f68403f0f..09e071ec45420d6500047f485892a5ba71ca9eff 100644 (file)
@@ -1,5 +1,9 @@
-#![allow(unused_macros)]
+// check-pass
 
-macro_rules! macro_rules { () => {} } //~ ERROR user-defined macros may not be named `macro_rules`
+macro_rules! macro_rules { () => { struct S; } } // OK
 
-fn main() {}
+macro_rules! {} // OK, calls the macro defined above
+
+fn main() {
+    let s = S;
+}
diff --git a/src/test/ui/user-defined-macro-rules.stderr b/src/test/ui/user-defined-macro-rules.stderr
deleted file mode 100644 (file)
index 0575152..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: user-defined macros may not be named `macro_rules`
-  --> $DIR/user-defined-macro-rules.rs:3:1
-   |
-LL | macro_rules! macro_rules { () => {} }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
index 77bd2b79f8cbcf3bae8d1c0db47dc6b3c9133311..2113eb2addb9bc492b3b2020796213c7470f1f89 100644 (file)
@@ -2,7 +2,7 @@
 // they permit lifetimes to be approximated as expected.
 
 #![allow(dead_code)]
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct SomeStruct<T>(fn(T));
 
index cb8159d8a684808a0d29dccfea1557fe3ef34ece..ecd2204c991c6963c49780028c8937e38a26f558 100644 (file)
@@ -2,7 +2,7 @@
 // be shortened.
 
 #![allow(dead_code)]
-// compile-pass
+// build-pass (FIXME(62277): could be check-pass?)
 
 struct SomeStruct<T>(T);
 
index 52f777db2daa681aa2f149a348075b9a1da617d1..b8008152e2a0525b47d825d285e1b6b4ac7f0602 100644 (file)
@@ -591,9 +591,6 @@ fn update_pass_mode(&mut self, ln: &str, revision: Option<&str>, config: &Config
         } else if config.parse_name_directive(ln, "build-pass") {
             check_no_run("build-pass");
             Some(PassMode::Build)
-        } else if config.parse_name_directive(ln, "compile-pass") /* compatibility */ {
-            check_no_run("compile-pass");
-            Some(PassMode::Build)
         } else if config.parse_name_directive(ln, "run-pass") {
             if config.mode != Mode::Ui && config.mode != Mode::RunPass /* compatibility */ {
                 panic!("`run-pass` header is only supported in UI tests")
index 945f007c0d305c3ec069b5e5d911ef783f6d70e7..d2df509867fbbbd35730c90aef54a8e73b046cd6 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 945f007c0d305c3ec069b5e5d911ef783f6d70e7
+Subproject commit d2df509867fbbbd35730c90aef54a8e73b046cd6
index 597c9be8c75be3e664f189c4325c96cf9b464dc3..124483dd2f10fe3ba32f7f5b75f32224c77f9010 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 597c9be8c75be3e664f189c4325c96cf9b464dc3
+Subproject commit 124483dd2f10fe3ba32f7f5b75f32224c77f9010
index ccdc47b657a7600cbd0c2858eb52a8d712cfce18..85958b001dbff8523396809bfa844fc34a7869a8 160000 (submodule)
@@ -1 +1 @@
-Subproject commit ccdc47b657a7600cbd0c2858eb52a8d712cfce18
+Subproject commit 85958b001dbff8523396809bfa844fc34a7869a8