]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #88745 - hnj2:allow-trait-impl-missing-code, r=GuillaumeGomez
authorbors <bors@rust-lang.org>
Mon, 13 Sep 2021 09:41:22 +0000 (09:41 +0000)
committerbors <bors@rust-lang.org>
Mon, 13 Sep 2021 09:41:22 +0000 (09:41 +0000)
Allow missing code examples in trait impls.

Excludes Trait implementations from the items that need to have doc code examples when using the `rustdoc::missing_doc_code_examples` lint.

For details see #88741

fixes #88741

r? `@jyn514`

403 files changed:
.github/workflows/ci.yml
Cargo.lock
compiler/rustc_ast/src/attr/mod.rs
compiler/rustc_ast_lowering/src/expr.rs
compiler/rustc_ast_lowering/src/lib.rs
compiler/rustc_ast_passes/src/ast_validation.rs
compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
compiler/rustc_borrowck/src/region_infer/mod.rs
compiler/rustc_borrowck/src/type_check/canonical.rs
compiler/rustc_borrowck/src/type_check/free_region_relations.rs
compiler/rustc_borrowck/src/type_check/input_output.rs
compiler/rustc_borrowck/src/type_check/mod.rs
compiler/rustc_borrowck/src/type_check/relate_tys.rs
compiler/rustc_builtin_macros/src/asm.rs
compiler/rustc_builtin_macros/src/format.rs
compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs
compiler/rustc_codegen_cranelift/src/base.rs
compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
compiler/rustc_codegen_cranelift/src/value_and_place.rs
compiler/rustc_codegen_llvm/src/abi.rs
compiler/rustc_codegen_llvm/src/asm.rs
compiler/rustc_codegen_llvm/src/builder.rs
compiler/rustc_codegen_llvm/src/common.rs
compiler/rustc_codegen_llvm/src/consts.rs
compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
compiler/rustc_codegen_llvm/src/intrinsic.rs
compiler/rustc_codegen_llvm/src/type_of.rs
compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
compiler/rustc_codegen_ssa/src/mir/block.rs
compiler/rustc_codegen_ssa/src/mir/constant.rs
compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
compiler/rustc_codegen_ssa/src/mir/operand.rs
compiler/rustc_codegen_ssa/src/mir/place.rs
compiler/rustc_codegen_ssa/src/mir/rvalue.rs
compiler/rustc_codegen_ssa/src/traits/builder.rs
compiler/rustc_codegen_ssa/src/traits/consts.rs
compiler/rustc_const_eval/src/interpret/intrinsics.rs
compiler/rustc_const_eval/src/interpret/operand.rs
compiler/rustc_const_eval/src/interpret/place.rs
compiler/rustc_const_eval/src/interpret/step.rs
compiler/rustc_const_eval/src/interpret/terminator.rs
compiler/rustc_const_eval/src/interpret/validity.rs
compiler/rustc_const_eval/src/transform/check_consts/check.rs
compiler/rustc_const_eval/src/transform/promote_consts.rs
compiler/rustc_data_structures/src/graph/iterate/mod.rs
compiler/rustc_data_structures/src/graph/iterate/tests.rs
compiler/rustc_data_structures/src/graph/mod.rs
compiler/rustc_data_structures/src/lib.rs
compiler/rustc_data_structures/src/stable_hasher.rs
compiler/rustc_expand/src/base.rs
compiler/rustc_expand/src/expand.rs
compiler/rustc_expand/src/proc_macro_server.rs
compiler/rustc_feature/src/accepted.rs
compiler/rustc_feature/src/active.rs
compiler/rustc_feature/src/builtin_attrs.rs
compiler/rustc_feature/src/lib.rs
compiler/rustc_feature/src/removed.rs
compiler/rustc_hir/src/def.rs
compiler/rustc_hir/src/definitions.rs
compiler/rustc_hir_pretty/src/lib.rs
compiler/rustc_infer/src/infer/error_reporting/mod.rs
compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
compiler/rustc_infer/src/infer/error_reporting/note.rs
compiler/rustc_infer/src/infer/mod.rs
compiler/rustc_infer/src/infer/nll_relate/mod.rs
compiler/rustc_interface/src/callbacks.rs
compiler/rustc_interface/src/tests.rs
compiler/rustc_lint/src/types.rs
compiler/rustc_lint/src/unused.rs
compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
compiler/rustc_macros/src/session_diagnostic.rs
compiler/rustc_metadata/src/dependency_format.rs
compiler/rustc_metadata/src/locator.rs
compiler/rustc_metadata/src/rmeta/decoder.rs
compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
compiler/rustc_metadata/src/rmeta/encoder.rs
compiler/rustc_metadata/src/rmeta/mod.rs
compiler/rustc_middle/src/hir/exports.rs
compiler/rustc_middle/src/hir/map/collector.rs
compiler/rustc_middle/src/hir/map/mod.rs
compiler/rustc_middle/src/hir/mod.rs
compiler/rustc_middle/src/ich/hcx.rs
compiler/rustc_middle/src/mir/abstract_const.rs [deleted file]
compiler/rustc_middle/src/mir/mod.rs
compiler/rustc_middle/src/mir/query.rs
compiler/rustc_middle/src/mir/tcx.rs
compiler/rustc_middle/src/query/mod.rs
compiler/rustc_middle/src/thir.rs
compiler/rustc_middle/src/thir/abstract_const.rs [new file with mode: 0644]
compiler/rustc_middle/src/thir/visit.rs [new file with mode: 0644]
compiler/rustc_middle/src/traits/mod.rs
compiler/rustc_middle/src/ty/codec.rs
compiler/rustc_middle/src/ty/error.rs
compiler/rustc_middle/src/ty/layout.rs
compiler/rustc_middle/src/ty/mod.rs
compiler/rustc_middle/src/ty/util.rs
compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
compiler/rustc_mir_build/src/build/matches/mod.rs
compiler/rustc_mir_build/src/build/matches/simplify.rs
compiler/rustc_mir_build/src/build/mod.rs
compiler/rustc_mir_build/src/build/scope.rs
compiler/rustc_mir_build/src/check_unsafety.rs
compiler/rustc_mir_build/src/thir/mod.rs
compiler/rustc_mir_build/src/thir/visit.rs [deleted file]
compiler/rustc_mir_dataflow/src/move_paths/builder.rs
compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
compiler/rustc_mir_transform/src/coverage/mod.rs
compiler/rustc_mir_transform/src/coverage/spans.rs
compiler/rustc_mir_transform/src/lib.rs
compiler/rustc_mir_transform/src/lower_intrinsics.rs
compiler/rustc_mir_transform/src/lower_slice_len.rs
compiler/rustc_parse/src/lib.rs
compiler/rustc_parse/src/parser/attr_wrapper.rs
compiler/rustc_parse/src/parser/expr.rs
compiler/rustc_parse/src/parser/mod.rs
compiler/rustc_passes/src/dead.rs
compiler/rustc_passes/src/liveness.rs
compiler/rustc_passes/src/region.rs
compiler/rustc_privacy/src/lib.rs
compiler/rustc_query_impl/src/on_disk_cache.rs
compiler/rustc_query_system/src/dep_graph/graph.rs
compiler/rustc_query_system/src/query/job.rs
compiler/rustc_query_system/src/query/plumbing.rs
compiler/rustc_resolve/src/build_reduced_graph.rs
compiler/rustc_resolve/src/def_collector.rs
compiler/rustc_resolve/src/imports.rs
compiler/rustc_resolve/src/late/diagnostics.rs
compiler/rustc_resolve/src/lib.rs
compiler/rustc_resolve/src/macros.rs
compiler/rustc_serialize/src/serialize.rs
compiler/rustc_session/src/options.rs
compiler/rustc_span/src/hygiene.rs
compiler/rustc_span/src/lib.rs
compiler/rustc_span/src/source_map.rs
compiler/rustc_span/src/span_encoding.rs
compiler/rustc_span/src/symbol.rs
compiler/rustc_target/src/abi/call/mips64.rs
compiler/rustc_target/src/abi/call/mod.rs
compiler/rustc_target/src/abi/call/riscv.rs
compiler/rustc_target/src/abi/call/s390x.rs
compiler/rustc_target/src/abi/call/x86.rs
compiler/rustc_target/src/abi/call/x86_64.rs
compiler/rustc_target/src/abi/mod.rs
compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs [new file with mode: 0644]
compiler/rustc_target/src/spec/mod.rs
compiler/rustc_trait_selection/src/infer.rs
compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
compiler/rustc_trait_selection/src/traits/fulfill.rs
compiler/rustc_trait_selection/src/traits/mod.rs
compiler/rustc_trait_selection/src/traits/object_safety.rs
compiler/rustc_trait_selection/src/traits/project.rs
compiler/rustc_trait_selection/src/traits/select/mod.rs
compiler/rustc_typeck/src/check/check.rs
compiler/rustc_typeck/src/check/coercion.rs
compiler/rustc_typeck/src/check/compare_method.rs
compiler/rustc_typeck/src/check/demand.rs
compiler/rustc_typeck/src/check/method/probe.rs
compiler/rustc_typeck/src/check/method/suggest.rs
compiler/rustc_typeck/src/check/mod.rs
compiler/rustc_typeck/src/check/op.rs
compiler/rustc_typeck/src/check/regionck.rs
compiler/rustc_typeck/src/check/wfcheck.rs
compiler/rustc_typeck/src/collect.rs
library/core/primitive_docs/box_into_raw.md [new file with mode: 0644]
library/core/primitive_docs/fs_file.md [new file with mode: 0644]
library/core/primitive_docs/io_bufread.md [new file with mode: 0644]
library/core/primitive_docs/io_read.md [new file with mode: 0644]
library/core/primitive_docs/io_seek.md [new file with mode: 0644]
library/core/primitive_docs/io_write.md [new file with mode: 0644]
library/core/primitive_docs/net_tosocketaddrs.md [new file with mode: 0644]
library/core/primitive_docs/process_exit.md [new file with mode: 0644]
library/core/primitive_docs/string_string.md [new file with mode: 0644]
library/core/src/bool.rs
library/core/src/char/methods.rs
library/core/src/clone.rs
library/core/src/fmt/mod.rs
library/core/src/lib.rs
library/core/src/marker.rs
library/core/src/primitive_docs.rs [new file with mode: 0644]
library/core/src/slice/mod.rs
library/core/tests/fmt/builders.rs
library/proc_macro/src/bridge/mod.rs
library/proc_macro/src/lib.rs
library/std/primitive_docs/box_into_raw.md [new file with mode: 0644]
library/std/primitive_docs/fs_file.md [new file with mode: 0644]
library/std/primitive_docs/io_bufread.md [new file with mode: 0644]
library/std/primitive_docs/io_read.md [new file with mode: 0644]
library/std/primitive_docs/io_seek.md [new file with mode: 0644]
library/std/primitive_docs/io_write.md [new file with mode: 0644]
library/std/primitive_docs/net_tosocketaddrs.md [new file with mode: 0644]
library/std/primitive_docs/process_exit.md [new file with mode: 0644]
library/std/primitive_docs/string_string.md [new file with mode: 0644]
library/std/src/collections/mod.rs
library/std/src/io/buffered/tests.rs
library/std/src/io/mod.rs
library/std/src/primitive_docs.rs
library/test/src/formatters/junit.rs
library/test/src/term/terminfo/mod.rs
src/bootstrap/doc.rs
src/ci/docker/scripts/freebsd-toolchain.sh
src/ci/github-actions/ci.yml
src/ci/scripts/install-clang.sh
src/ci/scripts/verify-backported-commits.sh
src/doc/rustc/src/platform-support.md
src/doc/unstable-book/src/library-features/asm.md
src/librustdoc/clean/blanket_impl.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/clean/types.rs
src/librustdoc/clean/utils.rs
src/librustdoc/doctest.rs
src/librustdoc/formats/cache.rs
src/librustdoc/html/format.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render/context.rs
src/librustdoc/html/render/mod.rs
src/librustdoc/html/render/print_item.rs
src/librustdoc/html/static/css/rustdoc.css
src/librustdoc/json/conversions.rs
src/librustdoc/passes/bare_urls.rs
src/librustdoc/passes/calculate_doc_coverage.rs
src/librustdoc/passes/collect_intra_doc_links.rs
src/librustdoc/passes/html_tags.rs
src/librustdoc/visit_lib.rs
src/llvm-project
src/test/codegen/panic-in-drop-abort.rs [new file with mode: 0644]
src/test/debuginfo/basic-types.rs
src/test/debuginfo/msvc-pretty-enums.rs
src/test/debuginfo/pretty-std.rs
src/test/incremental/change_symbol_export_status.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/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/spans_significant_w_debuginfo.rs
src/test/incremental/spans_significant_w_panic.rs
src/test/incremental/string_constant.rs
src/test/incremental/thinlto/cgu_keeps_identical_fn.rs
src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff [new file with mode: 0644]
src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff
src/test/mir-opt/lower_intrinsics.f_u64.PreCodegen.before.mir
src/test/mir-opt/lower_intrinsics.f_unit.PreCodegen.before.mir
src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff
src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff
src/test/mir-opt/lower_intrinsics.rs
src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff
src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff
src/test/rustdoc-gui/docblock-table-overflow.goml
src/test/rustdoc-gui/src/lib2/lib.rs
src/test/rustdoc-js-std/multi-query.js
src/test/rustdoc-ui/coverage/enum-tuple-documented.rs [new file with mode: 0644]
src/test/rustdoc-ui/coverage/enum-tuple-documented.stdout [new file with mode: 0644]
src/test/rustdoc-ui/coverage/enum-tuple.rs [new file with mode: 0644]
src/test/rustdoc-ui/coverage/enum-tuple.stdout [new file with mode: 0644]
src/test/rustdoc-ui/coverage/enums.stdout
src/test/rustdoc-ui/intra-doc/anchors.rs
src/test/rustdoc-ui/intra-doc/anchors.stderr
src/test/rustdoc/auxiliary/issue-15318.rs
src/test/rustdoc/auxiliary/primitive-doc.rs
src/test/rustdoc/cross-crate-primitive-doc.rs
src/test/rustdoc/intra-doc/anchors.rs
src/test/rustdoc/intra-doc/auxiliary/my-core.rs
src/test/rustdoc/intra-doc/prim-methods-external-core.rs
src/test/rustdoc/intra-doc/prim-methods-local.rs
src/test/rustdoc/intra-link-prim-self.rs
src/test/rustdoc/issue-15318-2.rs
src/test/rustdoc/issue-88600.rs [new file with mode: 0644]
src/test/rustdoc/no_std-primitive.rs [new file with mode: 0644]
src/test/rustdoc/primitive/no_std.rs [new file with mode: 0644]
src/test/rustdoc/synthetic_auto/no-redundancy.rs
src/test/rustdoc/table-in-docblock.rs [new file with mode: 0644]
src/test/ui/array-slice-vec/slice_binary_search.rs
src/test/ui/asm/parse-error.rs
src/test/ui/asm/parse-error.stderr
src/test/ui/async-await/issues/issue-54752-async-block.stderr
src/test/ui/borrowck/borrowck-unused-mut-locals.rs
src/test/ui/borrowck/issue-82462.nll.stderr [new file with mode: 0644]
src/test/ui/borrowck/issue-82462.rs [new file with mode: 0644]
src/test/ui/borrowck/issue-82462.stderr [new file with mode: 0644]
src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.rs
src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr
src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs
src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr
src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.rs
src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs
src/test/ui/coercion/issue-88097.rs [new file with mode: 0644]
src/test/ui/const-generics/broken-mir-2.rs
src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs [new file with mode: 0644]
src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr [new file with mode: 0644]
src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr
src/test/ui/const-generics/generic_const_exprs/closures.stderr
src/test/ui/const-generics/generic_const_exprs/let-bindings.stderr
src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs [new file with mode: 0644]
src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr [new file with mode: 0644]
src/test/ui/const-generics/generic_const_exprs/unused_expr.stderr
src/test/ui/const-generics/issues/issue-67375.full.stderr
src/test/ui/const-generics/issues/issue-67945-2.full.stderr
src/test/ui/const-generics/unused_braces.stderr
src/test/ui/derives/clone-debug-dead-code.rs [new file with mode: 0644]
src/test/ui/derives/clone-debug-dead-code.stderr [new file with mode: 0644]
src/test/ui/deriving/deriving-clone-generic-struct.rs
src/test/ui/deriving/deriving-clone-struct.rs
src/test/ui/deriving/deriving-clone-tuple-struct.rs
src/test/ui/deriving/deriving-in-fn.rs
src/test/ui/expr/malformed_closure/missing_braces_around_block.fixed [new file with mode: 0644]
src/test/ui/expr/malformed_closure/missing_braces_around_block.rs [new file with mode: 0644]
src/test/ui/expr/malformed_closure/missing_braces_around_block.stderr [new file with mode: 0644]
src/test/ui/expr/malformed_closure/ruby_style_closure.rs [new file with mode: 0644]
src/test/ui/expr/malformed_closure/ruby_style_closure.stderr [new file with mode: 0644]
src/test/ui/generic-associated-types/impl_bounds.rs
src/test/ui/generic-associated-types/impl_bounds.stderr
src/test/ui/generic-associated-types/issue-86787.stderr
src/test/ui/generic-associated-types/missing-where-clause-on-trait.rs [new file with mode: 0644]
src/test/ui/generic-associated-types/missing-where-clause-on-trait.stderr [new file with mode: 0644]
src/test/ui/hrtb/issue-88446.rs [new file with mode: 0644]
src/test/ui/issues/issue-19358.rs
src/test/ui/issues/issue-20605.stderr
src/test/ui/issues/issue-3794.rs
src/test/ui/issues/issue-86865.rs [new file with mode: 0644]
src/test/ui/issues/issue-86865.stderr [new file with mode: 0644]
src/test/ui/lint/lint-unnecessary-parens.stderr
src/test/ui/lint/suggestions.stderr
src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr
src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr
src/test/ui/lint/unused_braces.stderr
src/test/ui/lint/unused_braces_borrow.stderr
src/test/ui/lint/unused_parens_json_suggestion.stderr
src/test/ui/lint/unused_parens_remove_json_suggestion.stderr
src/test/ui/monomorphize-abi-alignment.rs
src/test/ui/moves/move-1-unique.rs
src/test/ui/moves/move-3-unique.rs
src/test/ui/overloaded/overloaded-autoderef-order.rs
src/test/ui/parser/expr-as-stmt.fixed
src/test/ui/parser/expr-as-stmt.rs
src/test/ui/parser/expr-as-stmt.stderr
src/test/ui/path-lookahead.stderr
src/test/ui/self/ufcs-explicit-self.rs
src/test/ui/structs-enums/class-cast-to-trait-multiple-types.rs
src/test/ui/structs-enums/class-implement-traits.rs
src/test/ui/structs-enums/functional-struct-upd.rs
src/test/ui/structs-enums/tag-align-shape.rs
src/test/ui/suggestions/slice-issue-87994.rs [new file with mode: 0644]
src/test/ui/suggestions/slice-issue-87994.stderr [new file with mode: 0644]
src/test/ui/try-block/try-block-unused-delims.stderr
src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs [new file with mode: 0644]
src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr [new file with mode: 0644]
src/tools/clippy/Cargo.toml
src/tools/clippy/clippy_dev/Cargo.toml
src/tools/clippy/clippy_dummy/Cargo.toml
src/tools/clippy/clippy_lints/Cargo.toml
src/tools/clippy/clippy_lints/src/attrs.rs
src/tools/clippy/clippy_lints/src/cargo_common_metadata.rs
src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
src/tools/clippy/clippy_lints/src/copies.rs
src/tools/clippy/clippy_lints/src/doc.rs
src/tools/clippy/clippy_lints/src/implicit_hasher.rs
src/tools/clippy/clippy_lints/src/large_const_arrays.rs
src/tools/clippy/clippy_lints/src/loops/for_kv_map.rs
src/tools/clippy/clippy_lints/src/loops/iter_next_loop.rs
src/tools/clippy/clippy_lints/src/loops/mod.rs
src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
src/tools/clippy/clippy_lints/src/macro_use.rs
src/tools/clippy/clippy_lints/src/methods/manual_split_once.rs
src/tools/clippy/clippy_lints/src/module_style.rs
src/tools/clippy/clippy_lints/src/regex.rs
src/tools/clippy/clippy_lints/src/tabs_in_doc_comments.rs
src/tools/clippy/clippy_utils/Cargo.toml
src/tools/clippy/clippy_utils/src/lib.rs
src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
src/tools/clippy/lintcheck/Cargo.toml
src/tools/clippy/tests/ui/default_trait_access.fixed
src/tools/clippy/tests/ui/default_trait_access.rs
src/tools/linkchecker/main.rs
src/tools/miri
src/tools/rustfmt/src/macros.rs
src/tools/rustfmt/src/modules.rs
src/tools/rustfmt/src/utils.rs
src/tools/tidy/src/lib.rs
src/tools/tidy/src/main.rs
src/tools/tidy/src/primitive_docs.rs [new file with mode: 0644]

index ff4fa1527e93ad09beb3f137c458c5c79bc18600..78ff874e7550114f3919a77a108a9fd93514b788 100644 (file)
@@ -404,6 +404,7 @@ jobs:
               RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --host=aarch64-pc-windows-msvc --enable-full-tools --enable-profiler"
               SCRIPT: python x.py dist
               DIST_REQUIRE_ALL_TOOLS: 0
+              WINDOWS_SDK_20348_HACK: 1
             os: windows-latest-xl
           - name: dist-i686-mingw
             env:
index 80acf227698e96f463c72f10dce219247dbe3767..cde73166babb7ecdaddc308d373d61389a947f3d 100644 (file)
@@ -26,9 +26,9 @@ dependencies = [
 
 [[package]]
 name = "aho-corasick"
-version = "0.7.13"
+version = "0.7.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
 dependencies = [
  "memchr",
 ]
@@ -559,7 +559,7 @@ dependencies = [
  "cargo_metadata 0.12.0",
  "clippy_lints",
  "clippy_utils",
- "compiletest_rs 0.6.0",
+ "compiletest_rs",
  "derive-new",
  "filetime",
  "if_chain",
@@ -581,7 +581,7 @@ version = "0.0.1"
 dependencies = [
  "bytecount",
  "clap",
- "itertools 0.9.0",
+ "itertools 0.10.1",
  "opener",
  "regex",
  "shell-escape",
@@ -595,7 +595,7 @@ dependencies = [
  "cargo_metadata 0.12.0",
  "clippy_utils",
  "if_chain",
- "itertools 0.9.0",
+ "itertools 0.10.1",
  "pulldown-cmark 0.8.0",
  "quine-mc_cluskey",
  "regex-syntax",
@@ -687,29 +687,6 @@ dependencies = [
  "winapi",
 ]
 
-[[package]]
-name = "compiletest_rs"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0086d6ad78cf409c3061618cd98e2789d5c9ce598fc9651611cf62eae0a599cb"
-dependencies = [
- "diff",
- "filetime",
- "getopts",
- "lazy_static",
- "libc",
- "log",
- "miow",
- "regex",
- "rustfix 0.5.1",
- "serde",
- "serde_derive",
- "serde_json",
- "tempfile",
- "tester",
- "winapi",
-]
-
 [[package]]
 name = "compiletest_rs"
 version = "0.7.0"
@@ -2272,7 +2249,7 @@ name = "miri"
 version = "0.1.0"
 dependencies = [
  "colored",
- "compiletest_rs 0.7.0",
+ "compiletest_rs",
  "env_logger 0.8.1",
  "getrandom 0.2.0",
  "hex 0.4.2",
@@ -3005,9 +2982,9 @@ dependencies = [
 
 [[package]]
 name = "regex"
-version = "1.4.6"
+version = "1.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759"
+checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
 dependencies = [
  "aho-corasick",
  "memchr",
index 81195f7fb5cb2995ee4513aeac4cf0797158bcc1..5f17008bdc2b0747e118971443f2ca616f59d64c 100644 (file)
@@ -367,7 +367,7 @@ fn token_trees_and_spacings(&self) -> Vec<TreeAndSpacing> {
             let is_first = i == 0;
             if !is_first {
                 let mod_sep_span =
-                    Span::new(last_pos, segment.ident.span.lo(), segment.ident.span.ctxt());
+                    Span::new(last_pos, segment.ident.span.lo(), segment.ident.span.ctxt(), None);
                 idents.push(TokenTree::token(token::ModSep, mod_sep_span).into());
             }
             idents.push(TokenTree::Token(Token::from_ast_ident(segment.ident)).into());
index 16cd7a0bcdd394af214d0a0235fab976fb3c3636..ac7145bed7825d790ee6650eeddaae050d376588 100644 (file)
@@ -422,7 +422,9 @@ fn lower_expr_while_in_loop_scope(
         let if_kind = hir::ExprKind::If(new_cond, self.arena.alloc(then), Some(else_expr));
         let if_expr = self.expr(span, if_kind, ThinVec::new());
         let block = self.block_expr(self.arena.alloc(if_expr));
-        hir::ExprKind::Loop(block, opt_label, hir::LoopSource::While, span.with_hi(cond.span.hi()))
+        let span = self.lower_span(span.with_hi(cond.span.hi()));
+        let opt_label = self.lower_label(opt_label);
+        hir::ExprKind::Loop(block, opt_label, hir::LoopSource::While, span)
     }
 
     /// Desugar `try { <stmts>; <expr> }` into `{ <stmts>; ::std::ops::Try::from_output(<expr>) }`,
@@ -1450,8 +1452,13 @@ fn lower_expr_for(
             )
         };
 
+        // #82462: to correctly diagnose borrow errors, the block that contains
+        // the iter expr needs to have a span that covers the loop body.
+        let desugared_full_span =
+            self.mark_span_with_reason(DesugaringKind::ForLoop(ForLoopLoc::Head), e.span, None);
+
         let match_expr = self.arena.alloc(self.expr_match(
-            desugared_span,
+            desugared_full_span,
             into_iter_expr,
             arena_vec![self; iter_arm],
             hir::MatchSource::ForLoopDesugar,
@@ -1465,7 +1472,7 @@ fn lower_expr_for(
         // surrounding scope of the `match` since the `match` is not a terminating scope.
         //
         // Also, add the attributes to the outer returned expr node.
-        self.expr_drop_temps_mut(desugared_span, match_expr, attrs.into())
+        self.expr_drop_temps_mut(desugared_full_span, match_expr, attrs.into())
     }
 
     /// Desugar `ExprKind::Try` from: `<expr>?` into:
index fa14764c42a73f1707ac51729632769601f83de1..8d731d7a57895fa2a448de1f0b71e6c3636598a0 100644 (file)
@@ -165,6 +165,8 @@ struct LoweringContext<'a, 'hir: 'a> {
 pub trait ResolverAstLowering {
     fn def_key(&mut self, id: DefId) -> DefKey;
 
+    fn def_span(&self, id: LocalDefId) -> Span;
+
     fn item_generics_num_lifetimes(&self, def: DefId) -> usize;
 
     fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>>;
@@ -215,6 +217,11 @@ fn hash_spans(&self) -> bool {
         true
     }
 
+    #[inline]
+    fn def_span(&self, id: LocalDefId) -> Span {
+        self.resolver.def_span(id)
+    }
+
     #[inline]
     fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
         self.resolver.def_path_hash(def_id)
@@ -711,9 +718,14 @@ fn with_anonymous_lifetime_mode<R>(
     }
 
     /// Intercept all spans entering HIR.
-    /// For now we are not doing anything with the intercepted spans.
+    /// Mark a span as relative to the current owning item.
     fn lower_span(&self, span: Span) -> Span {
-        span
+        if self.sess.opts.debugging_opts.incremental_relative_spans {
+            span.with_parent(Some(self.current_hir_id_owner.0))
+        } else {
+            // Do not make spans relative when not using incremental compilation.
+            span
+        }
     }
 
     fn lower_ident(&self, ident: Ident) -> Ident {
@@ -781,7 +793,7 @@ fn lifetime_to_generic_param(
             node_id,
             DefPathData::LifetimeNs(str_name),
             ExpnId::root(),
-            span,
+            span.with_parent(None),
         );
 
         hir::GenericParam {
@@ -1513,7 +1525,7 @@ fn lower_opaque_impl_trait(
                         def_node_id,
                         DefPathData::LifetimeNs(name.ident().name),
                         ExpnId::root(),
-                        span,
+                        span.with_parent(None),
                     );
 
                     let (name, kind) = match name {
index aca4503903c066e0cd3013401e913ee8a3a45098..e9dce953c73888e3e80ea8258117bc3ac7a81878 100644 (file)
@@ -422,11 +422,25 @@ fn check_late_bound_lifetime_defs(&self, params: &[GenericParam]) {
     }
 
     fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
+        self.check_decl_num_args(fn_decl);
         self.check_decl_cvaradic_pos(fn_decl);
         self.check_decl_attrs(fn_decl);
         self.check_decl_self_param(fn_decl, self_semantic);
     }
 
+    /// Emits fatal error if function declaration has more than `u16::MAX` arguments
+    /// Error is fatal to prevent errors during typechecking
+    fn check_decl_num_args(&self, fn_decl: &FnDecl) {
+        let max_num_args: usize = u16::MAX.into();
+        if fn_decl.inputs.len() > max_num_args {
+            let Param { span, .. } = fn_decl.inputs[0];
+            self.err_handler().span_fatal(
+                span,
+                &format!("function can not have more than {} arguments", max_num_args),
+            );
+        }
+    }
+
     fn check_decl_cvaradic_pos(&self, fn_decl: &FnDecl) {
         match &*fn_decl.inputs {
             [Param { ty, span, .. }] => {
index ce1e7c14b1ff673b249fd3bc4fca294296c28403..f4cbbb60b053a2625f1c4578c96545d09a04a53c 100644 (file)
@@ -218,7 +218,19 @@ pub(crate) fn report_use_of_moved_or_uninitialized(
                             );
                             if self.fn_self_span_reported.insert(fn_span) {
                                 err.span_note(
-                                    self_arg.span,
+                                    // Check whether the source is accessible
+                                    if self
+                                        .infcx
+                                        .tcx
+                                        .sess
+                                        .source_map()
+                                        .span_to_snippet(self_arg.span)
+                                        .is_ok()
+                                    {
+                                        self_arg.span
+                                    } else {
+                                        fn_call_span
+                                    },
                                     "calling this operator moves the left-hand side",
                                 );
                             }
@@ -429,7 +441,10 @@ pub(crate) fn report_use_of_moved_or_uninitialized(
                     deref_target_ty
                 ));
 
-                err.span_note(deref_target, "deref defined here");
+                // Check first whether the source is accessible (issue #87060)
+                if self.infcx.tcx.sess.source_map().span_to_snippet(deref_target).is_ok() {
+                    err.span_note(deref_target, "deref defined here");
+                }
             }
 
             if let Some((_, mut old_err)) =
index 48e45a9b1ce72e7f1559df69e847f627d7bb4e0c..128faab8d722e204e189031a418ca24407465c53 100644 (file)
@@ -85,7 +85,7 @@ pub struct RegionInferenceContext<'tcx> {
         FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
 
     /// Map universe indexes to information on why we created it.
-    universe_causes: IndexVec<ty::UniverseIndex, UniverseInfo<'tcx>>,
+    universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
 
     /// Contains the minimum universe of any variable within the same
     /// SCC. We will ensure that no SCC contains values that are not
@@ -256,7 +256,7 @@ pub(crate) fn new(
             Location,
             FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>,
         >,
-        universe_causes: IndexVec<ty::UniverseIndex, UniverseInfo<'tcx>>,
+        universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
         type_tests: Vec<TypeTest<'tcx>>,
         liveness_constraints: LivenessValues<RegionVid>,
         elements: &Rc<RegionValueElements>,
@@ -1739,7 +1739,7 @@ fn check_member_constraints(
                     category: constraint.category,
                     from_closure: false,
                     span,
-                    variance_info: constraint.variance_info.clone(),
+                    variance_info: constraint.variance_info,
                 };
             }
             Locations::Single(loc) => loc,
@@ -1752,13 +1752,13 @@ fn check_member_constraints(
                 category,
                 from_closure: true,
                 span: span,
-                variance_info: constraint.variance_info.clone(),
+                variance_info: constraint.variance_info,
             })
             .unwrap_or(BlameConstraint {
                 category: constraint.category,
                 from_closure: false,
                 span: body.source_info(loc).span,
-                variance_info: constraint.variance_info.clone(),
+                variance_info: constraint.variance_info,
             })
     }
 
@@ -2001,7 +2001,7 @@ fn check_member_constraints(
                         category: constraint.category,
                         from_closure: false,
                         span: constraint.locations.span(body),
-                        variance_info: constraint.variance_info.clone(),
+                        variance_info: constraint.variance_info,
                     }
                 }
             })
@@ -2149,7 +2149,7 @@ fn check_member_constraints(
     }
 
     crate fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
-        self.universe_causes[universe].clone()
+        self.universe_causes[&universe].clone()
     }
 }
 
index 7a8c0a3da1f1f4854370e6982b9243463fe3a69a..18070164e82195f7430c297fe9926b07f86f5f15 100644 (file)
@@ -50,9 +50,10 @@ pub(super) fn fully_perform_op<R, Op>(
                 None => UniverseInfo::other(),
             };
             for u in old_universe..universe {
-                let info_universe =
-                    self.borrowck_context.constraints.universe_causes.push(universe_info.clone());
-                assert_eq!(u.as_u32() + 1, info_universe.as_u32());
+                self.borrowck_context
+                    .constraints
+                    .universe_causes
+                    .insert(u + 1, universe_info.clone());
             }
         }
 
@@ -70,9 +71,12 @@ pub(super) fn instantiate_canonical_with_fresh_inference_vars<T>(
         let (instantiated, _) =
             self.infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical);
 
-        for _ in 0..canonical.max_universe.as_u32() {
+        for u in 0..canonical.max_universe.as_u32() {
             let info = UniverseInfo::other();
-            self.borrowck_context.constraints.universe_causes.push(info);
+            self.borrowck_context
+                .constraints
+                .universe_causes
+                .insert(ty::UniverseIndex::from_u32(u), info);
         }
 
         instantiated
index e1e8f6a61adb817038607d3c103394d97c29e531..70c74940d6235e117b8400a96d8d6eba851f643a 100644 (file)
@@ -259,7 +259,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
                 // We add implied bounds from both the unnormalized and normalized ty
                 // See issue #87748
                 let constraints_implied_1 = self.add_implied_bounds(ty);
-                let TypeOpOutput { output: ty, constraints: constraints1, .. } = self
+                let TypeOpOutput { output: norm_ty, constraints: constraints1, .. } = self
                     .param_env
                     .and(type_op::normalize::Normalize::new(ty))
                     .fully_perform(self.infcx)
@@ -286,8 +286,9 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
                 // }
                 // ```
                 // Both &Self::Bar and &() are WF
-                let constraints_implied_2 = self.add_implied_bounds(ty);
-                normalized_inputs_and_output.push(ty);
+                let constraints_implied_2 =
+                    if ty != norm_ty { self.add_implied_bounds(norm_ty) } else { None };
+                normalized_inputs_and_output.push(norm_ty);
                 constraints1.into_iter().chain(constraints_implied_1).chain(constraints_implied_2)
             })
             .collect();
index 9d6f6f60a94f91976edabb4f5c5174614750cb49..46d30a188edb903ecfd6b2b5b235ef4f155d38dc 100644 (file)
@@ -194,6 +194,8 @@ fn equate_normalized_input_or_output(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, span:
                     b
                 }
             };
+            // Note: if we have to introduce new placeholders during normalization above, then we won't have
+            // added those universes to the universe info, which we would want in `relate_tys`.
             if let Err(terr) =
                 self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation)
             {
index 2c8ff45b00da43813b3f3768bfb734df884d7a86..3e757827a5e6cff52c5d922973c634ac4dade462 100644 (file)
@@ -136,6 +136,8 @@ pub(crate) fn type_check<'mir, 'tcx>(
     upvars: &[Upvar<'tcx>],
 ) -> MirTypeckResults<'tcx> {
     let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body));
+    let mut universe_causes = FxHashMap::default();
+    universe_causes.insert(ty::UniverseIndex::from_u32(0), UniverseInfo::other());
     let mut constraints = MirTypeckRegionConstraints {
         placeholder_indices: PlaceholderIndices::default(),
         placeholder_index_to_region: IndexVec::default(),
@@ -144,7 +146,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
         member_constraints: MemberConstraintSet::default(),
         closure_bounds_mapping: Default::default(),
         type_tests: Vec::default(),
-        universe_causes: IndexVec::from_elem_n(UniverseInfo::other(), 1),
+        universe_causes,
     };
 
     let CreateResult {
@@ -159,9 +161,9 @@ pub(crate) fn type_check<'mir, 'tcx>(
         &mut constraints,
     );
 
-    for _ in ty::UniverseIndex::ROOT..infcx.universe() {
+    for u in ty::UniverseIndex::ROOT..infcx.universe() {
         let info = UniverseInfo::other();
-        constraints.universe_causes.push(info);
+        constraints.universe_causes.insert(u, info);
     }
 
     let mut borrowck_context = BorrowCheckContext {
@@ -924,7 +926,7 @@ struct BorrowCheckContext<'a, 'tcx> {
     crate closure_bounds_mapping:
         FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
 
-    crate universe_causes: IndexVec<ty::UniverseIndex, UniverseInfo<'tcx>>,
+    crate universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
 
     crate type_tests: Vec<TypeTest<'tcx>>,
 }
index 0b9c33ccb775a96ad7fe411259aaa6ba7bbd609e..de86d39cc3722e41b3ed67068269598d3da7220e 100644 (file)
@@ -80,10 +80,11 @@ fn param_env(&self) -> ty::ParamEnv<'tcx> {
     }
 
     fn create_next_universe(&mut self) -> ty::UniverseIndex {
-        let info_universe =
-            self.borrowck_context.constraints.universe_causes.push(self.universe_info.clone());
         let universe = self.infcx.create_next_universe();
-        assert_eq!(info_universe, universe);
+        self.borrowck_context
+            .constraints
+            .universe_causes
+            .insert(universe, self.universe_info.clone());
         universe
     }
 
index 652165fb9b60b1f646c7827aaa07d17548a6e8a1..c032364c008f34a551f782107b3eb7594a843884 100644 (file)
@@ -117,6 +117,10 @@ fn parse_args<'a>(
         let mut explicit_reg = false;
         let op = if !is_global_asm && p.eat_keyword(kw::In) {
             let reg = parse_reg(&mut p, &mut explicit_reg)?;
+            if p.eat_keyword(kw::Underscore) {
+                let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands");
+                return Err(err);
+            }
             let expr = p.parse_expr()?;
             ast::InlineAsmOperand::In { reg, expr }
         } else if !is_global_asm && p.eat_keyword(sym::out) {
@@ -129,6 +133,10 @@ fn parse_args<'a>(
             ast::InlineAsmOperand::Out { reg, expr, late: true }
         } else if !is_global_asm && p.eat_keyword(sym::inout) {
             let reg = parse_reg(&mut p, &mut explicit_reg)?;
+            if p.eat_keyword(kw::Underscore) {
+                let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands");
+                return Err(err);
+            }
             let expr = p.parse_expr()?;
             if p.eat(&token::FatArrow) {
                 let out_expr =
@@ -139,6 +147,10 @@ fn parse_args<'a>(
             }
         } else if !is_global_asm && p.eat_keyword(sym::inlateout) {
             let reg = parse_reg(&mut p, &mut explicit_reg)?;
+            if p.eat_keyword(kw::Underscore) {
+                let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands");
+                return Err(err);
+            }
             let expr = p.parse_expr()?;
             if p.eat(&token::FatArrow) {
                 let out_expr =
@@ -510,7 +522,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
             match expr_to_spanned_string(ecx, template_expr, msg) {
                 Ok(template_part) => template_part,
                 Err(err) => {
-                    if let Some(mut err) = err {
+                    if let Some((mut err, _)) = err {
                         err.emit();
                     }
                     return None;
index 8508b3b7ae6edb9a273d9f05e16950b75096e030..c7626dec4d7c0b29bc5c07efb1f0f2c1a0154906 100644 (file)
@@ -964,17 +964,19 @@ pub fn expand_preparsed_format_args(
         }
         Ok(fmt) => fmt,
         Err(err) => {
-            if let Some(mut err) = err {
+            if let Some((mut err, suggested)) = err {
                 let sugg_fmt = match args.len() {
                     0 => "{}".to_string(),
                     _ => format!("{}{{}}", "{} ".repeat(args.len())),
                 };
-                err.span_suggestion(
-                    fmt_sp.shrink_to_lo(),
-                    "you might be missing a string literal to format with",
-                    format!("\"{}\", ", sugg_fmt),
-                    Applicability::MaybeIncorrect,
-                );
+                if !suggested {
+                    err.span_suggestion(
+                        fmt_sp.shrink_to_lo(),
+                        "you might be missing a string literal to format with",
+                        format!("\"{}\", ", sugg_fmt),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
                 err.emit();
             }
             return DummyResult::raw_expr(sp, true);
index 44eae706ea8f6df56448214f8afab5383bc67ade..2144e7ed67acbc75a7e4ca0c3781e27148f5294c 100644 (file)
@@ -92,9 +92,9 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
     fn get_abi_param(&self, tcx: TyCtxt<'tcx>) -> SmallVec<[AbiParam; 2]> {
         match self.mode {
             PassMode::Ignore => smallvec![],
-            PassMode::Direct(attrs) => match &self.layout.abi {
+            PassMode::Direct(attrs) => match self.layout.abi {
                 Abi::Scalar(scalar) => smallvec![apply_arg_attrs_to_abi_param(
-                    AbiParam::new(scalar_to_clif_type(tcx, scalar.clone())),
+                    AbiParam::new(scalar_to_clif_type(tcx, scalar)),
                     attrs
                 )],
                 Abi::Vector { .. } => {
@@ -103,10 +103,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
                 }
                 _ => unreachable!("{:?}", self.layout.abi),
             },
-            PassMode::Pair(attrs_a, attrs_b) => match &self.layout.abi {
+            PassMode::Pair(attrs_a, attrs_b) => match self.layout.abi {
                 Abi::ScalarPair(a, b) => {
-                    let a = scalar_to_clif_type(tcx, a.clone());
-                    let b = scalar_to_clif_type(tcx, b.clone());
+                    let a = scalar_to_clif_type(tcx, a);
+                    let b = scalar_to_clif_type(tcx, b);
                     smallvec![
                         apply_arg_attrs_to_abi_param(AbiParam::new(a), attrs_a),
                         apply_arg_attrs_to_abi_param(AbiParam::new(b), attrs_b),
@@ -139,9 +139,9 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
     fn get_abi_return(&self, tcx: TyCtxt<'tcx>) -> (Option<AbiParam>, Vec<AbiParam>) {
         match self.mode {
             PassMode::Ignore => (None, vec![]),
-            PassMode::Direct(_) => match &self.layout.abi {
+            PassMode::Direct(_) => match self.layout.abi {
                 Abi::Scalar(scalar) => {
-                    (None, vec![AbiParam::new(scalar_to_clif_type(tcx, scalar.clone()))])
+                    (None, vec![AbiParam::new(scalar_to_clif_type(tcx, scalar))])
                 }
                 Abi::Vector { .. } => {
                     let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout).unwrap();
@@ -149,10 +149,10 @@ fn get_abi_return(&self, tcx: TyCtxt<'tcx>) -> (Option<AbiParam>, Vec<AbiParam>)
                 }
                 _ => unreachable!("{:?}", self.layout.abi),
             },
-            PassMode::Pair(_, _) => match &self.layout.abi {
+            PassMode::Pair(_, _) => match self.layout.abi {
                 Abi::ScalarPair(a, b) => {
-                    let a = scalar_to_clif_type(tcx, a.clone());
-                    let b = scalar_to_clif_type(tcx, b.clone());
+                    let a = scalar_to_clif_type(tcx, a);
+                    let b = scalar_to_clif_type(tcx, b);
                     (None, vec![AbiParam::new(a), AbiParam::new(b)])
                 }
                 _ => unreachable!("{:?}", self.layout.abi),
index 46a7485e4ef9ce2e0a7d859a1fa240c17fcaa39f..d29558a4e1f651d5b5f8274c9b53e09be11374fe 100644 (file)
@@ -726,15 +726,20 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
                     let ptr = fx.bcx.inst_results(call)[0];
                     lval.write_cvalue(fx, CValue::by_val(ptr, box_layout));
                 }
-                Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
+                Rvalue::NullaryOp(null_op, ty) => {
                     assert!(
                         lval.layout()
                             .ty
                             .is_sized(fx.tcx.at(stmt.source_info.span), ParamEnv::reveal_all())
                     );
-                    let ty_size = fx.layout_of(fx.monomorphize(ty)).size.bytes();
+                    let layout = fx.layout_of(fx.monomorphize(ty));
+                    let val = match null_op {
+                        NullOp::SizeOf => layout.size.bytes(),
+                        NullOp::AlignOf => layout.align.abi.bytes(),
+                        NullOp::Box => unreachable!(),
+                    };
                     let val =
-                        CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), ty_size.into());
+                        CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), val.into());
                     lval.write_cvalue(fx, val);
                 }
                 Rvalue::Aggregate(ref kind, ref operands) => match kind.as_ref() {
index 12f61e0c564aab39944b735e7d4f34057a8df842..48183b2d4f634ee8945c66aab6d66ec6f0adeda2 100644 (file)
 }
 
 pub(crate) fn clif_vector_type<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx>) -> Option<Type> {
-    let (element, count) = match &layout.abi {
-        Abi::Vector { element, count } => (element.clone(), *count),
+    let (element, count) = match layout.abi {
+        Abi::Vector { element, count } => (elementcount),
         _ => unreachable!(),
     };
 
@@ -823,7 +823,7 @@ fn swap(bcx: &mut FunctionBuilder<'_>, v: Value) -> Value {
             dest.write_cvalue(fx, val);
         };
 
-        pref_align_of | min_align_of | needs_drop | type_id | type_name | variant_count, () {
+        pref_align_of | needs_drop | type_id | type_name | variant_count, () {
             let const_val =
                 fx.tcx.const_eval_instance(ParamEnv::reveal_all(), instance, None).unwrap();
             let val = crate::constant::codegen_const_value(
index 364b3da92b88822fe614904ce75ed44582d2a288..30d5340935f14d90ea4773316340420a2fa11334 100644 (file)
@@ -49,11 +49,7 @@ fn codegen_field<'tcx>(
     }
 }
 
-fn scalar_pair_calculate_b_offset(
-    tcx: TyCtxt<'_>,
-    a_scalar: &Scalar,
-    b_scalar: &Scalar,
-) -> Offset32 {
+fn scalar_pair_calculate_b_offset(tcx: TyCtxt<'_>, a_scalar: Scalar, b_scalar: Scalar) -> Offset32 {
     let b_offset = a_scalar.value.size(&tcx).align_to(b_scalar.value.align(&tcx).abi);
     Offset32::new(b_offset.bytes().try_into().unwrap())
 }
@@ -124,12 +120,10 @@ pub(crate) fn load_scalar(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> Value {
         match self.0 {
             CValueInner::ByRef(ptr, None) => {
                 let clif_ty = match layout.abi {
-                    Abi::Scalar(ref scalar) => scalar_to_clif_type(fx.tcx, scalar.clone()),
-                    Abi::Vector { ref element, count } => {
-                        scalar_to_clif_type(fx.tcx, element.clone())
-                            .by(u16::try_from(count).unwrap())
-                            .unwrap()
-                    }
+                    Abi::Scalar(scalar) => scalar_to_clif_type(fx.tcx, scalar),
+                    Abi::Vector { element, count } => scalar_to_clif_type(fx.tcx, element)
+                        .by(u16::try_from(count).unwrap())
+                        .unwrap(),
                     _ => unreachable!("{:?}", layout.ty),
                 };
                 let mut flags = MemFlags::new();
@@ -147,13 +141,13 @@ pub(crate) fn load_scalar_pair(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> (Valu
         let layout = self.1;
         match self.0 {
             CValueInner::ByRef(ptr, None) => {
-                let (a_scalar, b_scalar) = match &layout.abi {
+                let (a_scalar, b_scalar) = match layout.abi {
                     Abi::ScalarPair(a, b) => (a, b),
                     _ => unreachable!("load_scalar_pair({:?})", self),
                 };
                 let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar);
-                let clif_ty1 = scalar_to_clif_type(fx.tcx, a_scalar.clone());
-                let clif_ty2 = scalar_to_clif_type(fx.tcx, b_scalar.clone());
+                let clif_ty1 = scalar_to_clif_type(fx.tcx, a_scalar);
+                let clif_ty2 = scalar_to_clif_type(fx.tcx, b_scalar);
                 let mut flags = MemFlags::new();
                 flags.set_notrap();
                 let val1 = ptr.load(fx, clif_ty1, flags);
@@ -564,7 +558,7 @@ fn transmute_value<'tcx>(
                 to_ptr.store(fx, val, flags);
                 return;
             }
-            Abi::ScalarPair(ref a_scalar, ref b_scalar) => {
+            Abi::ScalarPair(a_scalar, b_scalar) => {
                 let (value, extra) = from.load_scalar_pair(fx);
                 let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar);
                 to_ptr.store(fx, value, flags);
index cd55a61cbaf9d7b4c7675d73ff985a4478cf9fcf..1a0a3a0c340fa2bc4c43a84a5c74f597481ec8bd 100644 (file)
@@ -511,7 +511,12 @@ fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
     }
 
     fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value) {
-        // FIXME(wesleywiser, eddyb): We should apply `nounwind` and `noreturn` as appropriate to this callsite.
+        if self.ret.layout.abi.is_uninhabited() {
+            llvm::Attribute::NoReturn.apply_callsite(llvm::AttributePlace::Function, callsite);
+        }
+        if !self.can_unwind {
+            llvm::Attribute::NoUnwind.apply_callsite(llvm::AttributePlace::Function, callsite);
+        }
 
         let mut i = 0;
         let mut apply = |cx: &CodegenCx<'_, '_>, attrs: &ArgAttributes| {
@@ -536,16 +541,13 @@ fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll V
             }
             _ => {}
         }
-        if let abi::Abi::Scalar(ref scalar) = self.ret.layout.abi {
+        if let abi::Abi::Scalar(scalar) = self.ret.layout.abi {
             // If the value is a boolean, the range is 0..2 and that ultimately
             // become 0..0 when the type becomes i1, which would be rejected
             // by the LLVM verifier.
             if let Int(..) = scalar.value {
-                if !scalar.is_bool() {
-                    let range = scalar.valid_range_exclusive(bx);
-                    if range.start != range.end {
-                        bx.range_metadata(callsite, range);
-                    }
+                if !scalar.is_bool() && !scalar.is_always_valid(bx) {
+                    bx.range_metadata(callsite, scalar.valid_range);
                 }
             }
         }
index e0d312727a57df3b48807229b5d66030238e9a37..9690ad8b24603a17490099c9218d7d414f49dee3 100644 (file)
@@ -792,7 +792,7 @@ fn dummy_output_type(cx: &CodegenCx<'ll, 'tcx>, reg: InlineAsmRegClass) -> &'ll
 
 /// Helper function to get the LLVM type for a Scalar. Pointers are returned as
 /// the equivalent integer type.
-fn llvm_asm_scalar_type(cx: &CodegenCx<'ll, 'tcx>, scalar: &Scalar) -> &'ll Type {
+fn llvm_asm_scalar_type(cx: &CodegenCx<'ll, 'tcx>, scalar: Scalar) -> &'ll Type {
     match scalar.value {
         Primitive::Int(Integer::I8, _) => cx.type_i8(),
         Primitive::Int(Integer::I16, _) => cx.type_i16(),
@@ -812,7 +812,7 @@ fn llvm_fixup_input(
     reg: InlineAsmRegClass,
     layout: &TyAndLayout<'tcx>,
 ) -> &'ll Value {
-    match (reg, &layout.abi) {
+    match (reg, layout.abi) {
         (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
             if let Primitive::Int(Integer::I8, _) = s.value {
                 let vec_ty = bx.cx.type_vector(bx.cx.type_i8(), 8);
@@ -835,7 +835,7 @@ fn llvm_fixup_input(
             Abi::Vector { element, count },
         ) if layout.size.bytes() == 8 => {
             let elem_ty = llvm_asm_scalar_type(bx.cx, element);
-            let vec_ty = bx.cx.type_vector(elem_ty, *count);
+            let vec_ty = bx.cx.type_vector(elem_ty, count);
             let indices: Vec<_> = (0..count * 2).map(|x| bx.const_i32(x as i32)).collect();
             bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices))
         }
@@ -890,7 +890,7 @@ fn llvm_fixup_output(
     reg: InlineAsmRegClass,
     layout: &TyAndLayout<'tcx>,
 ) -> &'ll Value {
-    match (reg, &layout.abi) {
+    match (reg, layout.abi) {
         (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
             if let Primitive::Int(Integer::I8, _) = s.value {
                 bx.extract_element(value, bx.const_i32(0))
@@ -910,8 +910,8 @@ fn llvm_fixup_output(
             Abi::Vector { element, count },
         ) if layout.size.bytes() == 8 => {
             let elem_ty = llvm_asm_scalar_type(bx.cx, element);
-            let vec_ty = bx.cx.type_vector(elem_ty, *count * 2);
-            let indices: Vec<_> = (0..*count).map(|x| bx.const_i32(x as i32)).collect();
+            let vec_ty = bx.cx.type_vector(elem_ty, count * 2);
+            let indices: Vec<_> = (0..count).map(|x| bx.const_i32(x as i32)).collect();
             bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices))
         }
         (InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
@@ -965,7 +965,7 @@ fn llvm_fixup_output_type(
     reg: InlineAsmRegClass,
     layout: &TyAndLayout<'tcx>,
 ) -> &'ll Type {
-    match (reg, &layout.abi) {
+    match (reg, layout.abi) {
         (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
             if let Primitive::Int(Integer::I8, _) = s.value {
                 cx.type_vector(cx.type_i8(), 8)
index da24fe08f0dfd6b7349e5290c27b216671de7678..799f9a57e93a289d872d65714b6a8afd4ce6637b 100644 (file)
 use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
-use rustc_target::abi::{self, Align, Size};
+use rustc_target::abi::{self, Align, Size, WrappingRange};
 use rustc_target::spec::{HasTargetSpec, Target};
 use std::borrow::Cow;
 use std::ffi::CStr;
 use std::iter;
-use std::ops::{Deref, Range};
+use std::ops::Deref;
 use std::ptr;
 use tracing::debug;
 
@@ -382,7 +382,7 @@ fn from_immediate(&mut self, val: Self::Value) -> Self::Value {
             val
         }
     }
-    fn to_immediate_scalar(&mut self, val: Self::Value, scalar: &abi::Scalar) -> Self::Value {
+    fn to_immediate_scalar(&mut self, val: Self::Value, scalar: abi::Scalar) -> Self::Value {
         if scalar.is_bool() {
             return self.trunc(val, self.cx().type_i1());
         }
@@ -460,16 +460,15 @@ fn load_operand(&mut self, place: PlaceRef<'tcx, &'ll Value>) -> OperandRef<'tcx
         fn scalar_load_metadata<'a, 'll, 'tcx>(
             bx: &mut Builder<'a, 'll, 'tcx>,
             load: &'ll Value,
-            scalar: &abi::Scalar,
+            scalar: abi::Scalar,
         ) {
             match scalar.value {
                 abi::Int(..) => {
-                    let range = scalar.valid_range_exclusive(bx);
-                    if range.start != range.end {
-                        bx.range_metadata(load, range);
+                    if !scalar.is_always_valid(bx) {
+                        bx.range_metadata(load, scalar.valid_range);
                     }
                 }
-                abi::Pointer if !scalar.valid_range.contains_zero() => {
+                abi::Pointer if !scalar.valid_range.contains(0) => {
                     bx.nonnull_metadata(load);
                 }
                 _ => {}
@@ -489,17 +488,17 @@ fn scalar_load_metadata<'a, 'll, 'tcx>(
             }
             let llval = const_llval.unwrap_or_else(|| {
                 let load = self.load(place.layout.llvm_type(self), place.llval, place.align);
-                if let abi::Abi::Scalar(ref scalar) = place.layout.abi {
+                if let abi::Abi::Scalar(scalar) = place.layout.abi {
                     scalar_load_metadata(self, load, scalar);
                 }
                 load
             });
             OperandValue::Immediate(self.to_immediate(llval, place.layout))
-        } else if let abi::Abi::ScalarPair(ref a, ref b) = place.layout.abi {
+        } else if let abi::Abi::ScalarPair(a, b) = place.layout.abi {
             let b_offset = a.value.size(self).align_to(b.value.align(self).abi);
             let pair_ty = place.layout.llvm_type(self);
 
-            let mut load = |i, scalar: &abi::Scalar, align| {
+            let mut load = |i, scalar: abi::Scalar, align| {
                 let llptr = self.struct_gep(pair_ty, place.llval, i as u64);
                 let llty = place.layout.scalar_pair_element_llvm_type(self, i, false);
                 let load = self.load(llty, llptr, align);
@@ -555,7 +554,7 @@ fn write_operand_repeatedly(
         next_bx
     }
 
-    fn range_metadata(&mut self, load: &'ll Value, range: Range<u128>) {
+    fn range_metadata(&mut self, load: &'ll Value, range: WrappingRange) {
         if self.sess().target.arch == "amdgpu" {
             // amdgpu/LLVM does something weird and thinks an i64 value is
             // split into a v2i32, halving the bitwidth LLVM expects,
@@ -568,7 +567,7 @@ fn range_metadata(&mut self, load: &'ll Value, range: Range<u128>) {
             let llty = self.cx.val_ty(load);
             let v = [
                 self.cx.const_uint_big(llty, range.start),
-                self.cx.const_uint_big(llty, range.end),
+                self.cx.const_uint_big(llty, range.end.wrapping_add(1)),
             ];
 
             llvm::LLVMSetMetadata(
index cee582aec95ebf077b818093c990d77044451c07..73a8d4644316346c3347da6ed857777521f089c1 100644 (file)
@@ -228,7 +228,7 @@ fn const_to_opt_u128(&self, v: &'ll Value, sign_ext: bool) -> Option<u128> {
         })
     }
 
-    fn scalar_to_backend(&self, cv: Scalar, layout: &abi::Scalar, llty: &'ll Type) -> &'ll Value {
+    fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: &'ll Type) -> &'ll Value {
         let bitsize = if layout.is_bool() { 1 } else { layout.value.size(self).bits() };
         match cv {
             Scalar::Int(ScalarInt::ZST) => {
index e673b06f1552795b6b65ec64abf335a9ba20ded7..ef3a90fdecaaa7874479e8659119ba69416e7050 100644 (file)
@@ -111,7 +111,7 @@ fn append_chunks_of_init_and_uninit_bytes<'ll, 'a, 'b>(
                 Pointer::new(alloc_id, Size::from_bytes(ptr_offset)),
                 &cx.tcx,
             ),
-            &Scalar { value: Primitive::Pointer, valid_range: WrappingRange { start: 0, end: !0 } },
+            Scalar { value: Primitive::Pointer, valid_range: WrappingRange { start: 0, end: !0 } },
             cx.type_i8p_ext(address_space),
         ));
         next_offset = offset + pointer_size;
index 9a6391443dd010a2c383ceaf3479eb477c02ad8b..f913c3e4b703d4bcc00306d595de20c372c1c188 100644 (file)
@@ -1656,7 +1656,7 @@ fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) -> Vec<MemberDes
             Variants::Multiple {
                 tag_encoding:
                     TagEncoding::Niche { ref niche_variants, niche_start, dataful_variant },
-                ref tag,
+                tag,
                 ref variants,
                 tag_field,
             } => {
@@ -2082,10 +2082,8 @@ fn prepare_enum_metadata(
 
     let layout = cx.layout_of(enum_type);
 
-    if let (
-        &Abi::Scalar(_),
-        &Variants::Multiple { tag_encoding: TagEncoding::Direct, ref tag, .. },
-    ) = (&layout.abi, &layout.variants)
+    if let (Abi::Scalar(_), Variants::Multiple { tag_encoding: TagEncoding::Direct, tag, .. }) =
+        (layout.abi, &layout.variants)
     {
         return FinalMetadata(discriminant_type_metadata(tag.value));
     }
@@ -2093,8 +2091,8 @@ fn prepare_enum_metadata(
     if use_enum_fallback(cx) {
         let discriminant_type_metadata = match layout.variants {
             Variants::Single { .. } => None,
-            Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, ref tag, .. }
-            | Variants::Multiple { tag_encoding: TagEncoding::Direct, ref tag, .. } => {
+            Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, tag, .. }
+            | Variants::Multiple { tag_encoding: TagEncoding::Direct, tag, .. } => {
                 Some(discriminant_type_metadata(tag.value))
             }
         };
@@ -2146,9 +2144,7 @@ fn prepare_enum_metadata(
         // A single-variant enum has no discriminant.
         Variants::Single { .. } => None,
 
-        Variants::Multiple {
-            tag_encoding: TagEncoding::Niche { .. }, ref tag, tag_field, ..
-        } => {
+        Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, tag, tag_field, .. } => {
             // Find the integer type of the correct size.
             let size = tag.value.size(cx);
             let align = tag.value.align(cx);
@@ -2179,7 +2175,7 @@ fn prepare_enum_metadata(
             }
         }
 
-        Variants::Multiple { tag_encoding: TagEncoding::Direct, ref tag, tag_field, .. } => {
+        Variants::Multiple { tag_encoding: TagEncoding::Direct, tag, tag_field, .. } => {
             let discr_type = tag.value.to_ty(cx.tcx);
             let (size, align) = cx.size_and_align_of(discr_type);
 
index 1aa52d975e9a015854dedef358b1c9e67955661f..1060f911a9ed48739a9e4de5cff53559e0944b13 100644 (file)
@@ -133,7 +133,7 @@ fn codegen_intrinsic_call(
             }
             sym::va_arg => {
                 match fn_abi.ret.layout.abi {
-                    abi::Abi::Scalar(ref scalar) => {
+                    abi::Abi::Scalar(scalar) => {
                         match scalar.value {
                             Primitive::Int(..) => {
                                 if self.cx().size_of(ret_ty).bytes() < 4 {
index d615d230ea0d19a45dc5fca07233cc39cbb67526..3e39bf3e995a25cea16d1ae100d020729c64783b 100644 (file)
@@ -23,7 +23,7 @@ fn uncached_llvm_type<'a, 'tcx>(
 ) -> &'a Type {
     match layout.abi {
         Abi::Scalar(_) => bug!("handled elsewhere"),
-        Abi::Vector { ref element, count } => {
+        Abi::Vector { element, count } => {
             let element = layout.scalar_llvm_type_at(cx, element, Size::ZERO);
             return cx.type_vector(element, count);
         }
@@ -177,7 +177,7 @@ pub trait LayoutLlvmExt<'tcx> {
     fn scalar_llvm_type_at<'a>(
         &self,
         cx: &CodegenCx<'a, 'tcx>,
-        scalar: &Scalar,
+        scalar: Scalar,
         offset: Size,
     ) -> &'a Type;
     fn scalar_pair_element_llvm_type<'a>(
@@ -218,7 +218,7 @@ fn is_llvm_scalar_pair(&self) -> bool {
     /// of that field's type - this is useful for taking the address of
     /// that field and ensuring the struct has the right alignment.
     fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
-        if let Abi::Scalar(ref scalar) = self.abi {
+        if let Abi::Scalar(scalar) = self.abi {
             // Use a different cache for scalars because pointers to DSTs
             // can be either fat or thin (data pointers of fat pointers).
             if let Some(&llty) = cx.scalar_lltypes.borrow().get(&self.ty) {
@@ -286,7 +286,7 @@ fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
     }
 
     fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
-        if let Abi::Scalar(ref scalar) = self.abi {
+        if let Abi::Scalar(scalar) = self.abi {
             if scalar.is_bool() {
                 return cx.type_i1();
             }
@@ -297,7 +297,7 @@ fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
     fn scalar_llvm_type_at<'a>(
         &self,
         cx: &CodegenCx<'a, 'tcx>,
-        scalar: &Scalar,
+        scalar: Scalar,
         offset: Size,
     ) -> &'a Type {
         match scalar.value {
@@ -337,7 +337,7 @@ fn scalar_pair_element_llvm_type<'a>(
         }
 
         let (a, b) = match self.abi {
-            Abi::ScalarPair(ref a, ref b) => (a, b),
+            Abi::ScalarPair(a, b) => (a, b),
             _ => bug!("TyAndLayout::scalar_pair_element_llty({:?}): not applicable", self),
         };
         let scalar = [a, b][index];
index f0b32c96309d629f90e66a6aaa94c71967404753..e842f5e9391c806b0ba62d6b98b3ab4d4cd2c299 100644 (file)
@@ -404,7 +404,7 @@ fn msvc_enum_fallback(
 
             // calculate the range of values for the dataful variant
             let dataful_discriminant_range =
-                &dataful_variant_layout.largest_niche.as_ref().unwrap().scalar.valid_range;
+                dataful_variant_layout.largest_niche.unwrap().scalar.valid_range;
 
             let min = dataful_discriminant_range.start;
             let min = tag.value.size(&tcx).truncate(min);
index 2ca7e8fd7e8e377e05a8a89a52a6c276137625ed..cd0e9354c2441b419e49dd6a728b226e81234a02 100644 (file)
@@ -20,7 +20,7 @@
 use rustc_span::source_map::Span;
 use rustc_span::{sym, Symbol};
 use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode};
-use rustc_target::abi::{self, HasDataLayout};
+use rustc_target::abi::{self, HasDataLayout, WrappingRange};
 use rustc_target::spec::abi::Abi;
 
 /// Used by `FunctionCx::codegen_terminator` for emitting common patterns
@@ -1102,9 +1102,9 @@ fn codegen_argument(
                 // the load would just produce `OperandValue::Ref` instead
                 // of the `OperandValue::Immediate` we need for the call.
                 llval = bx.load(bx.backend_type(arg.layout), llval, align);
-                if let abi::Abi::Scalar(ref scalar) = arg.layout.abi {
+                if let abi::Abi::Scalar(scalar) = arg.layout.abi {
                     if scalar.is_bool() {
-                        bx.range_metadata(llval, 0..2);
+                        bx.range_metadata(llval, WrappingRange { start: 0, end: 1 });
                     }
                 }
                 // We store bools as `i8` so we need to truncate to `i1`.
@@ -1424,7 +1424,7 @@ fn codegen_transmute_into(
         let src = self.codegen_operand(bx, src);
 
         // Special-case transmutes between scalars as simple bitcasts.
-        match (&src.layout.abi, &dst.layout.abi) {
+        match (src.layout.abi, dst.layout.abi) {
             (abi::Abi::Scalar(src_scalar), abi::Abi::Scalar(dst_scalar)) => {
                 // HACK(eddyb) LLVM doesn't like `bitcast`s between pointers and non-pointers.
                 if (src_scalar.value == abi::Pointer) == (dst_scalar.value == abi::Pointer) {
index fa8a53e60b169d96c4d25288556fbf29b15844ca..93b39dc8e9ee102c8015ca4b21ebfd9f5c5d5fd1 100644 (file)
@@ -68,7 +68,7 @@ pub fn simd_shuffle_indices(
                         if let Some(prim) = field.val.try_to_scalar() {
                             let layout = bx.layout_of(field_ty);
                             let scalar = match layout.abi {
-                                Abi::Scalar(ref x) => x,
+                                Abi::Scalar(x) => x,
                                 _ => bug!("from_const: invalid ByVal layout: {:#?}", layout),
                             };
                             bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout))
index 75999225c031d2a071b7416a6c79d90f26e1f632..f943157dc66fa200cd61315d87754c5e2a96b501 100644 (file)
@@ -104,7 +104,6 @@ pub fn codegen_intrinsic_call(
                 }
             }
             sym::pref_align_of
-            | sym::min_align_of
             | sym::needs_drop
             | sym::type_id
             | sym::type_name
index 5cee25b5cca3b5f9fa5362341f4617aaa21f15b5..ce6cec67ad41ef7b17f7f73bf31925d3671c6c2b 100644 (file)
@@ -79,7 +79,7 @@ pub fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         let val = match val {
             ConstValue::Scalar(x) => {
                 let scalar = match layout.abi {
-                    Abi::Scalar(ref x) => x,
+                    Abi::Scalar(x) => x,
                     _ => bug!("from_const: invalid ByVal layout: {:#?}", layout),
                 };
                 let llval = bx.scalar_to_backend(x, scalar, bx.immediate_backend_type(layout));
@@ -87,7 +87,7 @@ pub fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
             }
             ConstValue::Slice { data, start, end } => {
                 let a_scalar = match layout.abi {
-                    Abi::ScalarPair(ref a, _) => a,
+                    Abi::ScalarPair(a, _) => a,
                     _ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout),
                 };
                 let a = Scalar::from_pointer(
@@ -162,7 +162,7 @@ pub fn from_immediate_or_packed_pair<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         llval: V,
         layout: TyAndLayout<'tcx>,
     ) -> Self {
-        let val = if let Abi::ScalarPair(ref a, ref b) = layout.abi {
+        let val = if let Abi::ScalarPair(a, b) = layout.abi {
             debug!("Operand::from_immediate_or_packed_pair: unpacking {:?} @ {:?}", llval, layout);
 
             // Deconstruct the immediate aggregate.
@@ -185,7 +185,7 @@ pub fn extract_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         let field = self.layout.field(bx.cx(), i);
         let offset = self.layout.fields.offset(i);
 
-        let mut val = match (self.val, &self.layout.abi) {
+        let mut val = match (self.val, self.layout.abi) {
             // If the field is ZST, it has no data.
             _ if field.is_zst() => {
                 return OperandRef::new_zst(bx, field);
@@ -200,7 +200,7 @@ pub fn extract_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
             }
 
             // Extract a scalar component from a pair.
-            (OperandValue::Pair(a_llval, b_llval), &Abi::ScalarPair(ref a, ref b)) => {
+            (OperandValue::Pair(a_llval, b_llval), Abi::ScalarPair(a, b)) => {
                 if offset.bytes() == 0 {
                     assert_eq!(field.size, a.value.size(bx.cx()));
                     OperandValue::Immediate(a_llval)
@@ -212,14 +212,14 @@ pub fn extract_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
             }
 
             // `#[repr(simd)]` types are also immediate.
-            (OperandValue::Immediate(llval), &Abi::Vector { .. }) => {
+            (OperandValue::Immediate(llval), Abi::Vector { .. }) => {
                 OperandValue::Immediate(bx.extract_element(llval, bx.cx().const_usize(i as u64)))
             }
 
             _ => bug!("OperandRef::extract_field({:?}): not applicable", self),
         };
 
-        match (&mut val, &field.abi) {
+        match (&mut val, field.abi) {
             (OperandValue::Immediate(llval), _) => {
                 // Bools in union fields needs to be truncated.
                 *llval = bx.to_immediate(*llval, field);
@@ -308,7 +308,7 @@ fn store_with_flags<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
             }
             OperandValue::Pair(a, b) => {
                 let (a_scalar, b_scalar) = match dest.layout.abi {
-                    Abi::ScalarPair(ref a, ref b) => (a, b),
+                    Abi::ScalarPair(a, b) => (a, b),
                     _ => bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout),
                 };
                 let ty = bx.backend_type(dest.layout);
index b48d6d42b43577d62242d06c0d2fc12b8d396815..4b07ed1a1e6c2b2bf884db3b94d42b206c58b9d4 100644 (file)
@@ -99,7 +99,7 @@ pub fn project_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
                     // Also handles the first field of Scalar, ScalarPair, and Vector layouts.
                     self.llval
                 }
-                Abi::ScalarPair(ref a, ref b)
+                Abi::ScalarPair(a, b)
                     if offset == a.value.size(bx.cx()).align_to(b.value.align(bx.cx()).abi) =>
                 {
                     // Offset matches second field.
@@ -222,7 +222,7 @@ pub fn codegen_get_discr<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
                     .map_or(index.as_u32() as u128, |discr| discr.val);
                 return bx.cx().const_uint_big(cast_to, discr_val);
             }
-            Variants::Multiple { ref tag, ref tag_encoding, tag_field, .. } => {
+            Variants::Multiple { tag, ref tag_encoding, tag_field, .. } => {
                 (tag, tag_encoding, tag_field)
             }
         };
index 3d8ea29160bd0941785274fa746c2883fb2fbae3..7403c21a9060e0e17da08a9b325d87525970cf99 100644 (file)
@@ -300,7 +300,7 @@ pub fn codegen_rvalue_operand(
                         let llval = operand.immediate();
 
                         let mut signed = false;
-                        if let Abi::Scalar(ref scalar) = operand.layout.abi {
+                        if let Abi::Scalar(scalar) = operand.layout.abi {
                             if let Int(_, s) = scalar.value {
                                 // We use `i1` for bytes that are always `0` or `1`,
                                 // e.g., `#[repr(i8)] enum E { A, B }`, but we can't
@@ -308,8 +308,7 @@ pub fn codegen_rvalue_operand(
                                 // then `i1 1` (i.e., E::B) is effectively `i8 -1`.
                                 signed = !scalar.is_bool() && s;
 
-                                let er = scalar.valid_range_exclusive(bx.cx());
-                                if er.end != er.start
+                                if !scalar.is_always_valid(bx.cx())
                                     && scalar.valid_range.end >= scalar.valid_range.start
                                 {
                                     // We want `table[e as usize ± k]` to not
@@ -487,20 +486,6 @@ pub fn codegen_rvalue_operand(
                 )
             }
 
-            mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
-                let ty = self.monomorphize(ty);
-                assert!(bx.cx().type_is_sized(ty));
-                let val = bx.cx().const_usize(bx.cx().layout_of(ty).size.bytes());
-                let tcx = self.cx.tcx();
-                (
-                    bx,
-                    OperandRef {
-                        val: OperandValue::Immediate(val),
-                        layout: self.cx.layout_of(tcx.types.usize),
-                    },
-                )
-            }
-
             mir::Rvalue::NullaryOp(mir::NullOp::Box, content_ty) => {
                 let content_ty = self.monomorphize(content_ty);
                 let content_layout = bx.cx().layout_of(content_ty);
@@ -525,6 +510,27 @@ pub fn codegen_rvalue_operand(
                 let operand = OperandRef { val: OperandValue::Immediate(val), layout: box_layout };
                 (bx, operand)
             }
+
+            mir::Rvalue::NullaryOp(null_op, ty) => {
+                let ty = self.monomorphize(ty);
+                assert!(bx.cx().type_is_sized(ty));
+                let layout = bx.cx().layout_of(ty);
+                let val = match null_op {
+                    mir::NullOp::SizeOf => layout.size.bytes(),
+                    mir::NullOp::AlignOf => layout.align.abi.bytes(),
+                    mir::NullOp::Box => unreachable!(),
+                };
+                let val = bx.cx().const_usize(val);
+                let tcx = self.cx.tcx();
+                (
+                    bx,
+                    OperandRef {
+                        val: OperandValue::Immediate(val),
+                        layout: self.cx.layout_of(tcx.types.usize),
+                    },
+                )
+            }
+
             mir::Rvalue::ThreadLocalRef(def_id) => {
                 assert!(bx.cx().tcx().is_static(def_id));
                 let static_ = bx.get_static(def_id);
index afb8ee3c40d5569169327fe602c1d2bcc54c5093..e7da96f0adafdaf53b510f3084c7f4ad684b59c3 100644 (file)
 use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout};
 use rustc_middle::ty::Ty;
 use rustc_span::Span;
-use rustc_target::abi::{Abi, Align, Scalar, Size};
+use rustc_target::abi::{Abi, Align, Scalar, Size, WrappingRange};
 use rustc_target::spec::HasTargetSpec;
 
-use std::ops::Range;
-
 #[derive(Copy, Clone)]
 pub enum OverflowOp {
     Add,
@@ -126,13 +124,13 @@ fn checked_binop(
 
     fn from_immediate(&mut self, val: Self::Value) -> Self::Value;
     fn to_immediate(&mut self, val: Self::Value, layout: TyAndLayout<'_>) -> Self::Value {
-        if let Abi::Scalar(ref scalar) = layout.abi {
+        if let Abi::Scalar(scalar) = layout.abi {
             self.to_immediate_scalar(val, scalar)
         } else {
             val
         }
     }
-    fn to_immediate_scalar(&mut self, val: Self::Value, scalar: &Scalar) -> Self::Value;
+    fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> Self::Value;
 
     fn alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value;
     fn dynamic_alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value;
@@ -158,7 +156,7 @@ fn write_operand_repeatedly(
         dest: PlaceRef<'tcx, Self::Value>,
     ) -> Self;
 
-    fn range_metadata(&mut self, load: Self::Value, range: Range<u128>);
+    fn range_metadata(&mut self, load: Self::Value, range: WrappingRange);
     fn nonnull_metadata(&mut self, load: Self::Value);
 
     fn store(&mut self, val: Self::Value, ptr: Self::Value, align: Align) -> Self::Value;
index 20f6618712327870212d734e8ca15062b03aacbf..5260b7cc33120e0e36c05d3d79eb0ad537b7d317 100644 (file)
@@ -28,7 +28,7 @@ pub trait ConstMethods<'tcx>: BackendTypes {
 
     fn const_data_from_alloc(&self, alloc: &Allocation) -> Self::Value;
 
-    fn scalar_to_backend(&self, cv: Scalar, layout: &abi::Scalar, llty: Self::Type) -> Self::Value;
+    fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: Self::Type) -> Self::Value;
     fn from_const_alloc(
         &self,
         layout: TyAndLayout<'tcx>,
index 07e974b72664bbefc7103a91f80532ea3135ec6e..b032ee96ce7b033a46f4db32cad8fc86e095ab5d 100644 (file)
@@ -160,17 +160,14 @@ pub fn emulate_intrinsic(
                 self.write_scalar(Scalar::from_machine_usize(result, self), dest)?;
             }
 
-            sym::min_align_of
-            | sym::pref_align_of
+            sym::pref_align_of
             | sym::needs_drop
             | sym::type_id
             | sym::type_name
             | sym::variant_count => {
                 let gid = GlobalId { instance, promoted: None };
                 let ty = match intrinsic_name {
-                    sym::min_align_of | sym::pref_align_of | sym::variant_count => {
-                        self.tcx.types.usize
-                    }
+                    sym::pref_align_of | sym::variant_count => self.tcx.types.usize,
                     sym::needs_drop => self.tcx.types.bool,
                     sym::type_id => self.tcx.types.u64,
                     sym::type_name => self.tcx.mk_static_str(),
@@ -194,7 +191,7 @@ pub fn emulate_intrinsic(
                 let val = self.read_scalar(&args[0])?.check_init()?;
                 let bits = val.to_bits(layout_of.size)?;
                 let kind = match layout_of.abi {
-                    Abi::Scalar(ref scalar) => scalar.value,
+                    Abi::Scalar(scalar) => scalar.value,
                     _ => span_bug!(
                         self.cur_span(),
                         "{} called on invalid type {:?}",
@@ -234,7 +231,8 @@ pub fn emulate_intrinsic(
                     &r,
                 )?;
                 let val = if overflowed {
-                    let num_bits = l.layout.size.bits();
+                    let size = l.layout.size;
+                    let num_bits = size.bits();
                     if l.layout.abi.is_signed() {
                         // For signed ints the saturated value depends on the sign of the first
                         // term since the sign of the second term can be inferred from this and
@@ -259,10 +257,7 @@ pub fn emulate_intrinsic(
                         // unsigned
                         if is_add {
                             // max unsigned
-                            Scalar::from_uint(
-                                u128::MAX >> (128 - num_bits),
-                                Size::from_bits(num_bits),
-                            )
+                            Scalar::from_uint(size.unsigned_int_max(), Size::from_bits(num_bits))
                         } else {
                             // underflow to 0
                             Scalar::from_uint(0u128, Size::from_bits(num_bits))
index 63aca67c9443c13b1724fa6fb2087cc6e94ec327..de870bd5c6cf1be3972ad5eede57b696572a7501 100644 (file)
@@ -274,11 +274,11 @@ fn try_read_immediate_from_mplace(
                 let scalar = alloc.read_scalar(alloc_range(Size::ZERO, mplace.layout.size))?;
                 Ok(Some(ImmTy { imm: scalar.into(), layout: mplace.layout }))
             }
-            Abi::ScalarPair(ref a, ref b) => {
+            Abi::ScalarPair(a, b) => {
                 // We checked `ptr_align` above, so all fields will have the alignment they need.
                 // We would anyway check against `ptr_align.restrict_for_offset(b_offset)`,
                 // which `ptr.offset(b_offset)` cannot possibly fail to satisfy.
-                let (a, b) = (&a.value, &b.value);
+                let (a, b) = (a.value, b.value);
                 let (a_size, b_size) = (a.size(self), b.size(self));
                 let b_offset = a_size.align_to(b.align(self).abi);
                 assert!(b_offset.bytes() > 0); // we later use the offset to tell apart the fields
@@ -648,7 +648,7 @@ pub fn read_discriminant(
                 };
                 return Ok((discr, index));
             }
-            Variants::Multiple { ref tag, ref tag_encoding, tag_field, .. } => {
+            Variants::Multiple { tag, ref tag_encoding, tag_field, .. } => {
                 (tag, tag_encoding, tag_field)
             }
         };
index 95a44e3fecf3d19b249c1f81924f123b5ebc010b..0da6d8169bd3a7b36c25f7d9aca0d7fbb1b3f871 100644 (file)
@@ -752,7 +752,7 @@ fn write_immediate_to_mplace_no_validate(
                 // We would anyway check against `ptr_align.restrict_for_offset(b_offset)`,
                 // which `ptr.offset(b_offset)` cannot possibly fail to satisfy.
                 let (a, b) = match dest.layout.abi {
-                    Abi::ScalarPair(ref a, ref b) => (&a.value, &b.value),
+                    Abi::ScalarPair(a, b) => (a.value, b.value),
                     _ => span_bug!(
                         self.cur_span(),
                         "write_immediate_to_mplace: invalid ScalarPair layout: {:#?}",
@@ -1000,7 +1000,7 @@ pub fn write_discriminant(
             }
             Variants::Multiple {
                 tag_encoding: TagEncoding::Direct,
-                tag: ref tag_layout,
+                tag: tag_layout,
                 tag_field,
                 ..
             } => {
@@ -1022,7 +1022,7 @@ pub fn write_discriminant(
             Variants::Multiple {
                 tag_encoding:
                     TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start },
-                tag: ref tag_layout,
+                tag: tag_layout,
                 tag_field,
                 ..
             } => {
index 09bd07660a33eb0fa3ca56cc16ce2d62c6ce7b37..6e35b33188cd238b858d1f3e696cebe86f49f364 100644 (file)
@@ -270,18 +270,23 @@ pub fn eval_rvalue_into_place(
                 M::box_alloc(self, &dest)?;
             }
 
-            NullaryOp(mir::NullOp::SizeOf, ty) => {
+            NullaryOp(null_op, ty) => {
                 let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty);
                 let layout = self.layout_of(ty)?;
                 if layout.is_unsized() {
                     // FIXME: This should be a span_bug (#80742)
                     self.tcx.sess.delay_span_bug(
                         self.frame().current_span(),
-                        &format!("SizeOf nullary MIR operator called for unsized type {}", ty),
+                        &format!("Nullary MIR operator called for unsized type {}", ty),
                     );
                     throw_inval!(SizeOfUnsizedType(ty));
                 }
-                self.write_scalar(Scalar::from_machine_usize(layout.size.bytes(), self), &dest)?;
+                let val = match null_op {
+                    mir::NullOp::SizeOf => layout.size.bytes(),
+                    mir::NullOp::AlignOf => layout.align.abi.bytes(),
+                    mir::NullOp::Box => unreachable!(),
+                };
+                self.write_scalar(Scalar::from_machine_usize(val, self), &dest)?;
             }
 
             Cast(cast_kind, ref operand, cast_ty) => {
index 1c8e5e9e23c3caefab88cd27f834bd67c5b8db48..a06903aedf6499a167e499e27cf7502f42958e3a 100644 (file)
@@ -187,17 +187,14 @@ fn check_argument_compat(
             return false;
         }
         // Compare layout
-        match (&caller.abi, &callee.abi) {
+        match (caller.abi, callee.abi) {
             // Different valid ranges are okay (once we enforce validity,
             // that will take care to make it UB to leave the range, just
             // like for transmute).
-            (abi::Abi::Scalar(ref caller), abi::Abi::Scalar(ref callee)) => {
-                caller.value == callee.value
+            (abi::Abi::Scalar(caller), abi::Abi::Scalar(callee)) => caller.value == callee.value,
+            (abi::Abi::ScalarPair(caller1, caller2), abi::Abi::ScalarPair(callee1, callee2)) => {
+                caller1.value == callee1.value && caller2.value == callee2.value
             }
-            (
-                abi::Abi::ScalarPair(ref caller1, ref caller2),
-                abi::Abi::ScalarPair(ref callee1, ref callee2),
-            ) => caller1.value == callee1.value && caller2.value == callee2.value,
             // Be conservative
             _ => false,
         }
index 03e0a8e7901d94c86f2077dd026e207e1aaea148..a6375ad0e02cf1e4011a163d6ac5279c7011affb 100644 (file)
@@ -618,40 +618,38 @@ fn try_visit_primitive(
     fn visit_scalar(
         &mut self,
         op: &OpTy<'tcx, M::PointerTag>,
-        scalar_layout: &ScalarAbi,
+        scalar_layout: ScalarAbi,
     ) -> InterpResult<'tcx> {
-        let value = self.read_scalar(op)?;
-        let valid_range = scalar_layout.valid_range.clone();
-        let WrappingRange { start: lo, end: hi } = valid_range;
-        // Determine the allowed range
-        // `max_hi` is as big as the size fits
-        let max_hi = u128::MAX >> (128 - op.layout.size.bits());
-        assert!(hi <= max_hi);
-        // We could also write `(hi + 1) % (max_hi + 1) == lo` but `max_hi + 1` overflows for `u128`
-        if (lo == 0 && hi == max_hi) || (hi + 1 == lo) {
+        if scalar_layout.valid_range.is_full_for(op.layout.size) {
             // Nothing to check
             return Ok(());
         }
-        // At least one value is excluded. Get the bits.
+        // At least one value is excluded.
+        let valid_range = scalar_layout.valid_range;
+        let WrappingRange { start, end } = valid_range;
+        let max_value = op.layout.size.unsigned_int_max();
+        assert!(end <= max_value);
+        // Determine the allowed range
+        let value = self.read_scalar(op)?;
         let value = try_validation!(
             value.check_init(),
             self.path,
             err_ub!(InvalidUninitBytes(None)) => { "{}", value }
-                expected { "something {}", wrapping_range_format(valid_range, max_hi) },
+                expected { "something {}", wrapping_range_format(valid_range, max_value) },
         );
         let bits = match value.try_to_int() {
             Err(_) => {
                 // So this is a pointer then, and casting to an int failed.
                 // Can only happen during CTFE.
                 let ptr = self.ecx.scalar_to_ptr(value);
-                if lo == 1 && hi == max_hi {
+                if start == 1 && end == max_value {
                     // Only null is the niche.  So make sure the ptr is NOT null.
                     if self.ecx.memory.ptr_may_be_null(ptr) {
                         throw_validation_failure!(self.path,
                             { "a potentially null pointer" }
                             expected {
                                 "something that cannot possibly fail to be {}",
-                                wrapping_range_format(valid_range, max_hi)
+                                wrapping_range_format(valid_range, max_value)
                             }
                         )
                     }
@@ -663,7 +661,7 @@ fn visit_scalar(
                         { "a pointer" }
                         expected {
                             "something that cannot possibly fail to be {}",
-                            wrapping_range_format(valid_range, max_hi)
+                            wrapping_range_format(valid_range, max_value)
                         }
                     )
                 }
@@ -676,7 +674,7 @@ fn visit_scalar(
         } else {
             throw_validation_failure!(self.path,
                 { "{}", bits }
-                expected { "something {}", wrapping_range_format(valid_range, max_hi) }
+                expected { "something {}", wrapping_range_format(valid_range, max_value) }
             )
         }
     }
@@ -786,7 +784,7 @@ fn visit_value(&mut self, op: &OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx>
                     { "a value of uninhabited type {:?}", op.layout.ty }
                 );
             }
-            Abi::Scalar(ref scalar_layout) => {
+            Abi::Scalar(scalar_layout) => {
                 self.visit_scalar(op, scalar_layout)?;
             }
             Abi::ScalarPair { .. } | Abi::Vector { .. } => {
index d02b4286c175a6396771cdc31e4f7ecebd0c822f..02b317b89810620357e2d88e0ef298b198845063 100644 (file)
@@ -648,7 +648,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
                 }
             }
 
-            Rvalue::NullaryOp(NullOp::SizeOf, _) => {}
+            Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {}
             Rvalue::NullaryOp(NullOp::Box, _) => self.check_op(ops::HeapAllocation),
 
             Rvalue::UnaryOp(_, ref operand) => {
index 6822ad2d7b5dd0d3e02f0f9a2029b407bd249839..8c24c9fa9769cff229679c50544c1f126988a1e2 100644 (file)
@@ -520,6 +520,7 @@ fn validate_rvalue(&self, rvalue: &Rvalue<'tcx>) -> Result<(), Unpromotable> {
             Rvalue::NullaryOp(op, _) => match op {
                 NullOp::Box => return Err(Unpromotable),
                 NullOp::SizeOf => {}
+                NullOp::AlignOf => {}
             },
 
             Rvalue::UnaryOp(op, operand) => {
index 09b91083a6347c61238198d399491ffec892891c..a9db3497b23908a50548e9a24ab74f189feed37d 100644 (file)
@@ -83,8 +83,58 @@ 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()) }
+    pub fn new(graph: &'graph G) -> Self {
+        Self { graph, stack: vec![], visited: BitSet::new_empty(graph.num_nodes()) }
+    }
+
+    /// Version of `push_start_node` that is convenient for chained
+    /// use.
+    pub fn with_start_node(mut self, start_node: G::Node) -> Self {
+        self.push_start_node(start_node);
+        self
+    }
+
+    /// Pushes another start node onto the stack. If the node
+    /// has not already been visited, then you will be able to
+    /// walk its successors (and so forth) after the current
+    /// contents of the stack are drained. If multiple start nodes
+    /// are added into the walk, then their mutual successors
+    /// will all be walked. You can use this method once the
+    /// iterator has been completely drained to add additional
+    /// start nodes.
+    pub fn push_start_node(&mut self, start_node: G::Node) {
+        if self.visited.insert(start_node) {
+            self.stack.push(start_node);
+        }
+    }
+
+    /// Searches all nodes reachable from the current start nodes.
+    /// This is equivalent to just invoke `next` repeatedly until
+    /// you get a `None` result.
+    pub fn complete_search(&mut self) {
+        while let Some(_) = self.next() {}
+    }
+
+    /// Returns true if node has been visited thus far.
+    /// A node is considered "visited" once it is pushed
+    /// onto the internal stack; it may not yet have been yielded
+    /// from the iterator. This method is best used after
+    /// the iterator is completely drained.
+    pub fn visited(&self, node: G::Node) -> bool {
+        self.visited.contains(node)
+    }
+}
+
+impl<G> std::fmt::Debug for DepthFirstSearch<'_, G>
+where
+    G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
+{
+    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        let mut f = fmt.debug_set();
+        for n in self.visited.iter() {
+            f.entry(&n);
+        }
+        f.finish()
     }
 }
 
index 0e038e88b221dfed3f8d3b6aabbdb0b272d9ab96..c498c289337f1a1eebe77955943ab88812ae2b9c 100644 (file)
@@ -20,3 +20,19 @@ fn is_cyclic() {
     assert!(!is_cyclic(&diamond_acyclic));
     assert!(is_cyclic(&diamond_cyclic));
 }
+
+#[test]
+fn dfs() {
+    let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3), (3, 0)]);
+
+    let result: Vec<usize> = DepthFirstSearch::new(&graph).with_start_node(0).collect();
+    assert_eq!(result, vec![0, 2, 3, 1]);
+}
+
+#[test]
+fn dfs_debug() {
+    let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3), (3, 0)]);
+    let mut dfs = DepthFirstSearch::new(&graph).with_start_node(0);
+    dfs.complete_search();
+    assert_eq!(format!("{{0, 1, 2, 3}}"), format!("{:?}", dfs));
+}
index dff22855629a8e4b9f93f6b7e7041a56b415ba2b..3560df6e5e204548dc2966179e26052d90298bfb 100644 (file)
@@ -32,7 +32,7 @@ fn depth_first_search(&self, from: Self::Node) -> iterate::DepthFirstSearch<'_,
     where
         Self: WithNumNodes,
     {
-        iterate::DepthFirstSearch::new(selffrom)
+        iterate::DepthFirstSearch::new(self).with_start_node(from)
     }
 }
 
index d128a688e751f72e75bc3767dc5bd6e34d7bdf7a..dd6a17b92aef303b85fc4eae0e0b6391e86b5d63 100644 (file)
@@ -21,6 +21,7 @@
 #![feature(iter_map_while)]
 #![feature(maybe_uninit_uninit_array)]
 #![feature(min_specialization)]
+#![feature(never_type)]
 #![feature(type_alias_impl_trait)]
 #![feature(new_uninit)]
 #![feature(nll)]
index 18b352cf3b0b9152f42eb6c43dfd536c92f4e1dd..354f9dd93cc4d4e491f6a15feffcdbf491a837dd 100644 (file)
@@ -209,6 +209,12 @@ fn hash_stable(&self, _: &mut CTX, hasher: &mut $crate::stable_hasher::StableHas
 impl_stable_hash_via_hash!(char);
 impl_stable_hash_via_hash!(());
 
+impl<CTX> HashStable<CTX> for ! {
+    fn hash_stable(&self, _ctx: &mut CTX, _hasher: &mut StableHasher) {
+        unreachable!()
+    }
+}
+
 impl<CTX> HashStable<CTX> for ::std::num::NonZeroU32 {
     fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
         self.get().hash_stable(ctx, hasher)
index 35df8aae4babb99d5488b87b99234a5d4ce6d7d1..b630bc1f4732f57f1185233d405e73d9b71518ff 100644 (file)
 use rustc_attr::{self as attr, Deprecation, Stability};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{self, Lrc};
-use rustc_errors::{DiagnosticBuilder, ErrorReported};
+use rustc_errors::{Applicability, DiagnosticBuilder, ErrorReported};
 use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
 use rustc_lint_defs::BuiltinLintDiagnostics;
 use rustc_parse::{self, nt_to_tokenstream, parser, MACRO_ARGUMENTS};
 use rustc_session::{parse::ParseSess, Limit, Session};
-use rustc_span::def_id::{CrateNum, DefId};
+use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
 use rustc_span::edition::Edition;
 use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId};
 use rustc_span::source_map::SourceMap;
@@ -843,6 +843,7 @@ pub fn expn_data(
 
 pub trait ResolverExpand {
     fn next_node_id(&mut self) -> NodeId;
+    fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId;
 
     fn resolve_dollar_crates(&mut self);
     fn visit_ast_fragment_with_placeholders(
@@ -1136,13 +1137,15 @@ pub fn resolve_path(
 }
 
 /// Extracts a string literal from the macro expanded version of `expr`,
-/// emitting `err_msg` if `expr` is not a string literal. This does not stop
-/// compilation on error, merely emits a non-fatal error and returns `None`.
+/// returning a diagnostic error of `err_msg` if `expr` is not a string literal.
+/// The returned bool indicates whether an applicable suggestion has already been
+/// added to the diagnostic to avoid emitting multiple suggestions. `Err(None)`
+/// indicates that an ast error was encountered.
 pub fn expr_to_spanned_string<'a>(
     cx: &'a mut ExtCtxt<'_>,
     expr: P<ast::Expr>,
     err_msg: &str,
-) -> Result<(Symbol, ast::StrStyle, Span), Option<DiagnosticBuilder<'a>>> {
+) -> Result<(Symbol, ast::StrStyle, Span), Option<(DiagnosticBuilder<'a>, bool)>> {
     // Perform eager expansion on the expression.
     // We want to be able to handle e.g., `concat!("foo", "bar")`.
     let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
@@ -1150,14 +1153,27 @@ pub fn expr_to_spanned_string<'a>(
     Err(match expr.kind {
         ast::ExprKind::Lit(ref l) => match l.kind {
             ast::LitKind::Str(s, style) => return Ok((s, style, expr.span)),
+            ast::LitKind::ByteStr(_) => {
+                let mut err = cx.struct_span_err(l.span, err_msg);
+                err.span_suggestion(
+                    expr.span.shrink_to_lo(),
+                    "consider removing the leading `b`",
+                    String::new(),
+                    Applicability::MaybeIncorrect,
+                );
+                Some((err, true))
+            }
             ast::LitKind::Err(_) => None,
-            _ => Some(cx.struct_span_err(l.span, err_msg)),
+            _ => Some((cx.struct_span_err(l.span, err_msg), false)),
         },
         ast::ExprKind::Err => None,
-        _ => Some(cx.struct_span_err(expr.span, err_msg)),
+        _ => Some((cx.struct_span_err(expr.span, err_msg), false)),
     })
 }
 
+/// Extracts a string literal from the macro expanded version of `expr`,
+/// emitting `err_msg` if `expr` is not a string literal. This does not stop
+/// compilation on error, merely emits a non-fatal error and returns `None`.
 pub fn expr_to_string(
     cx: &mut ExtCtxt<'_>,
     expr: P<ast::Expr>,
@@ -1165,7 +1181,7 @@ pub fn expr_to_string(
 ) -> Option<(Symbol, ast::StrStyle)> {
     expr_to_spanned_string(cx, expr, err_msg)
         .map_err(|err| {
-            err.map(|mut err| {
+            err.map(|(mut err, _)| {
                 err.emit();
             })
         })
index 3ccf9f446a63efa3b556902307568db60fad73e7..62066ca965784103fbc339d9005811601ab471f1 100644 (file)
@@ -588,7 +588,7 @@ fn collect_invocations(
         // Resolve `$crate`s in the fragment for pretty-printing.
         self.cx.resolver.resolve_dollar_crates();
 
-        let invocations = {
+        let mut invocations = {
             let mut collector = InvocationCollector {
                 // Non-derive macro invocations cannot see the results of cfg expansion - they
                 // will either be removed along with the item, or invoked before the cfg/cfg_attr
@@ -613,6 +613,19 @@ fn collect_invocations(
             self.cx
                 .resolver
                 .visit_ast_fragment_with_placeholders(self.cx.current_expansion.id, &fragment);
+
+            if self.cx.sess.opts.debugging_opts.incremental_relative_spans {
+                for (invoc, _) in invocations.iter_mut() {
+                    let expn_id = invoc.expansion_data.id;
+                    let parent_def = self.cx.resolver.invocation_parent(expn_id);
+                    let span = match &mut invoc.kind {
+                        InvocationKind::Bang { ref mut span, .. } => span,
+                        InvocationKind::Attr { attr, .. } => &mut attr.span,
+                        InvocationKind::Derive { path, .. } => &mut path.span,
+                    };
+                    *span = span.with_parent(Some(parent_def));
+                }
+            }
         }
 
         (fragment, invocations)
index 55700f7b0d495e119b07b2fda73c744314082cce..52b60c3047e1c9180ac3d314b6f3b5e666f91ef8 100644 (file)
@@ -745,7 +745,7 @@ fn source_file(&mut self, span: Self::Span) -> Self::SourceFile {
         self.sess.source_map().lookup_char_pos(span.lo()).file
     }
     fn parent(&mut self, span: Self::Span) -> Option<Self::Span> {
-        span.parent()
+        span.parent_callsite()
     }
     fn source(&mut self, span: Self::Span) -> Self::Span {
         span.source_callsite()
@@ -758,6 +758,12 @@ fn end(&mut self, span: Self::Span) -> LineColumn {
         let loc = self.sess.source_map().lookup_char_pos(span.hi());
         LineColumn { line: loc.line, column: loc.col.to_usize() }
     }
+    fn before(&mut self, span: Self::Span) -> Self::Span {
+        span.shrink_to_lo()
+    }
+    fn after(&mut self, span: Self::Span) -> Self::Span {
+        span.shrink_to_hi()
+    }
     fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {
         let self_loc = self.sess.source_map().lookup_char_pos(first.lo());
         let other_loc = self.sess.source_map().lookup_char_pos(second.lo());
index 725f8b8763af17d3d048395884ede1d07caec3c3..61e27d2e4cd41053db35dc55d60c8effeabdc63b 100644 (file)
@@ -16,7 +16,6 @@ macro_rules! declare_features {
                     since: $ver,
                     issue: to_nonzero($issue),
                     edition: None,
-                    description: concat!($($doc,)*),
                 }
             ),+
         ];
index a3807a2bb9fde64cb5a3a6e2574de2a9176f145f..366ed715434eda4e2598b6ea7558588881b43e72 100644 (file)
@@ -37,7 +37,6 @@ macro_rules! declare_features {
                     since: $ver,
                     issue: to_nonzero($issue),
                     edition: $edition,
-                    description: concat!($($doc,)*),
                 }
             ),+];
 
index e2aa54a59b2021401c8ab1f7fb751a34c50c1ac9..f74ea0e0c4d271c979df7f85c251922e1eb59f12 100644 (file)
@@ -453,6 +453,9 @@ macro_rules! experimental {
     ),
     // Enumerates "identity-like" conversion methods to suggest on type mismatch.
     rustc_attr!(rustc_conversion_suggestion, Normal, template!(Word), INTERNAL_UNSTABLE),
+    // Prevents field reads in the marked trait or method to be considered
+    // during dead code analysis.
+    rustc_attr!(rustc_trivial_field_reads, Normal, template!(Word), INTERNAL_UNSTABLE),
 
     // ==========================================================================
     // Internal attributes, Const related:
index cf102aa16e0571ffbf89dbbb64ced39c99282ebf..b25aab21e491afa1a54ac74cf7ad3fb7bff7bcc5 100644 (file)
@@ -51,7 +51,6 @@ pub struct Feature {
     pub since: &'static str,
     issue: Option<NonZeroU32>,
     pub edition: Option<Edition>,
-    description: &'static str,
 }
 
 #[derive(Copy, Clone, Debug)]
index efab0200ff502dbe26ea6c51fd9a563cc3eebe01..7b9b68268eacd8df4f5d51e684b5796f11a59e96 100644 (file)
@@ -16,7 +16,6 @@ macro_rules! declare_features {
                     since: $ver,
                     issue: to_nonzero($issue),
                     edition: None,
-                    description: concat!($($doc,)*),
                 }
             ),+
         ];
@@ -34,7 +33,6 @@ macro_rules! declare_features {
                     since: $ver,
                     issue: to_nonzero($issue),
                     edition: None,
-                    description: concat!($($doc,)*),
                 }
             ),+
         ];
index 853415c4173b561d26ff7e1a7cb6e9ff7d663204..cb668eb35e093da9b2194eef756f4208e436c677 100644 (file)
@@ -598,6 +598,11 @@ pub fn map_id<R>(self, mut map: impl FnMut(Id) -> R) -> Res<R> {
         }
     }
 
+    #[track_caller]
+    pub fn expect_non_local<OtherId>(self) -> Res<OtherId> {
+        self.map_id(|_| panic!("unexpected `Res::Local`"))
+    }
+
     pub fn macro_kind(self) -> Option<MacroKind> {
         match self {
             Res::Def(DefKind::Macro(kind), _) => Some(kind),
index 30a367052cba58411702cd20b1e0f50cbd478b9f..5f56f3a32addef5fb291dec2565ecf4e54779aa7 100644 (file)
@@ -14,6 +14,7 @@
 use rustc_index::vec::IndexVec;
 use rustc_span::hygiene::ExpnId;
 use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::Span;
 
 use std::fmt::{self, Write};
 use std::hash::Hash;
@@ -107,6 +108,8 @@ pub struct Definitions {
 
     /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
     expansions_that_defined: FxHashMap<LocalDefId, ExpnId>,
+
+    def_id_to_span: IndexVec<LocalDefId, Span>,
 }
 
 /// A unique identifier that we can use to lookup a definition
@@ -324,7 +327,7 @@ pub fn opt_hir_id_to_local_def_id(&self, hir_id: hir::HirId) -> Option<LocalDefI
     }
 
     /// Adds a root definition (no parent) and a few other reserved definitions.
-    pub fn new(stable_crate_id: StableCrateId) -> Definitions {
+    pub fn new(stable_crate_id: StableCrateId, crate_span: Span) -> Definitions {
         let key = DefKey {
             parent: None,
             disambiguated_data: DisambiguatedDefPathData {
@@ -341,11 +344,18 @@ pub fn new(stable_crate_id: StableCrateId) -> Definitions {
         let root = LocalDefId { local_def_index: table.allocate(key, def_path_hash) };
         assert_eq!(root.local_def_index, CRATE_DEF_INDEX);
 
+        let mut def_id_to_span = IndexVec::new();
+        // A relative span's parent must be an absolute span.
+        debug_assert_eq!(crate_span.data_untracked().parent, None);
+        let _root = def_id_to_span.push(crate_span);
+        debug_assert_eq!(_root, root);
+
         Definitions {
             table,
             def_id_to_hir_id: Default::default(),
             hir_id_to_def_id: Default::default(),
             expansions_that_defined: Default::default(),
+            def_id_to_span,
         }
     }
 
@@ -361,6 +371,7 @@ pub fn create_def(
         data: DefPathData,
         expn_id: ExpnId,
         mut next_disambiguator: impl FnMut(LocalDefId, DefPathData) -> u32,
+        span: Span,
     ) -> LocalDefId {
         debug!("create_def(parent={:?}, data={:?}, expn_id={:?})", parent, data, expn_id);
 
@@ -385,6 +396,11 @@ pub fn create_def(
             self.expansions_that_defined.insert(def_id, expn_id);
         }
 
+        // A relative span's parent must be an absolute span.
+        debug_assert_eq!(span.data_untracked().parent, None);
+        let _id = self.def_id_to_span.push(span);
+        debug_assert_eq!(_id, def_id);
+
         def_id
     }
 
@@ -412,6 +428,12 @@ pub fn expansion_that_defined(&self, id: LocalDefId) -> ExpnId {
         self.expansions_that_defined.get(&id).copied().unwrap_or_else(ExpnId::root)
     }
 
+    /// Retrieves the span of the given `DefId` if `DefId` is in the local crate.
+    #[inline]
+    pub fn def_span(&self, def_id: LocalDefId) -> Span {
+        self.def_id_to_span[def_id]
+    }
+
     pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
         self.def_id_to_hir_id.iter_enumerated().map(|(k, _)| k)
     }
index 36054c0484782016fd0bb57c1f151d383a76d610..67f92bc0a51a7b8a161f792589e49ce9227441bb 100644 (file)
@@ -1036,7 +1036,7 @@ pub fn print_stmt(&mut self, st: &hir::Stmt<'_>) {
         self.maybe_print_comment(st.span.lo());
         match st.kind {
             hir::StmtKind::Local(ref loc) => {
-                self.print_local(loc.init.as_deref(), |this| this.print_local_decl(&loc));
+                self.print_local(loc.init, |this| this.print_local_decl(&loc));
             }
             hir::StmtKind::Item(item) => self.ann.nested(self, Nested::Item(item)),
             hir::StmtKind::Expr(ref expr) => {
index 32150c7f4c615dfc18f5bd70481fc7ba5ba24dbd..1139b714d0a1ff155b8055258a14dae507ad88d3 100644 (file)
@@ -2345,7 +2345,7 @@ enum SubOrigin<'hir> {
                 );
                 err.span_suggestion(
                     generics.where_clause.tail_span_for_suggestion(),
-                    "consider adding a where clause".into(),
+                    "consider adding a where clause",
                     suggestion,
                     Applicability::MaybeIncorrect,
                 );
index 61c8113d052874c0874d8cdefdead70585c1fc15..43aa8a6efcec4df5db4a056cbf43078244d0eafb 100644 (file)
@@ -2,7 +2,7 @@
 
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use crate::infer::lexical_region_resolve::RegionResolutionError;
-use crate::infer::{Subtype, ValuePairs};
+use crate::infer::{SubregionOrigin, Subtype, ValuePairs};
 use crate::traits::ObligationCauseCode::CompareImplMethodObligation;
 use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::intravisit::Visitor;
 use rustc_middle::ty::error::ExpectedFound;
 use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_span::{MultiSpan, Span};
+use rustc_span::{MultiSpan, Span, Symbol};
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`.
     pub(super) fn try_report_impl_not_conforming_to_trait(&self) -> Option<ErrorReported> {
-        if let Some(ref error) = self.error {
-            debug!("try_report_impl_not_conforming_to_trait {:?}", error);
-            if let RegionResolutionError::SubSupConflict(
-                _,
-                var_origin,
-                sub_origin,
-                _sub,
-                sup_origin,
-                _sup,
-            ) = error.clone()
-            {
-                if let (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) =
-                    (&sup_origin, &sub_origin)
+        let error = self.error.as_ref()?;
+        debug!("try_report_impl_not_conforming_to_trait {:?}", error);
+        if let RegionResolutionError::SubSupConflict(
+            _,
+            var_origin,
+            sub_origin,
+            _sub,
+            sup_origin,
+            _sup,
+        ) = error.clone()
+        {
+            if let (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) = (&sup_origin, &sub_origin) {
+                if let (
+                    ValuePairs::Types(sub_expected_found),
+                    ValuePairs::Types(sup_expected_found),
+                    CompareImplMethodObligation { trait_item_def_id, .. },
+                ) = (&sub_trace.values, &sup_trace.values, &sub_trace.cause.code)
                 {
-                    if let (
-                        ValuePairs::Types(sub_expected_found),
-                        ValuePairs::Types(sup_expected_found),
-                        CompareImplMethodObligation { trait_item_def_id, .. },
-                    ) = (&sub_trace.values, &sup_trace.values, &sub_trace.cause.code)
-                    {
-                        if sup_expected_found == sub_expected_found {
-                            self.emit_err(
-                                var_origin.span(),
-                                sub_expected_found.expected,
-                                sub_expected_found.found,
-                                *trait_item_def_id,
-                            );
-                            return Some(ErrorReported);
-                        }
+                    if sup_expected_found == sub_expected_found {
+                        self.emit_err(
+                            var_origin.span(),
+                            sub_expected_found.expected,
+                            sub_expected_found.found,
+                            *trait_item_def_id,
+                        );
+                        return Some(ErrorReported);
                     }
                 }
             }
         }
+        if let RegionResolutionError::ConcreteFailure(origin, _, _) = error.clone() {
+            if let SubregionOrigin::CompareImplTypeObligation {
+                span,
+                item_name,
+                impl_item_def_id,
+                trait_item_def_id,
+            } = origin
+            {
+                self.emit_associated_type_err(span, item_name, impl_item_def_id, trait_item_def_id);
+                return Some(ErrorReported);
+            }
+        }
         None
     }
 
@@ -107,6 +116,25 @@ fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, trait_def_id:
         }
         err.emit();
     }
+
+    fn emit_associated_type_err(
+        &self,
+        span: Span,
+        item_name: Symbol,
+        impl_item_def_id: DefId,
+        trait_item_def_id: DefId,
+    ) {
+        let impl_sp = self.tcx().def_span(impl_item_def_id);
+        let trait_sp = self.tcx().def_span(trait_item_def_id);
+        let mut err = self
+            .tcx()
+            .sess
+            .struct_span_err(span, &format!("`impl` associated type signature for `{}` doesn't match `trait` associated type signature", item_name));
+        err.span_label(impl_sp, &format!("found"));
+        err.span_label(trait_sp, &format!("expected"));
+
+        err.emit();
+    }
 }
 
 struct TypeParamSpanVisitor<'tcx> {
index 4bc59a4baf5cae5c1bddb5c0a1ffbf05d711c41f..5f99a23f86e88b1d2df0045f1f0264e585b27fe2 100644 (file)
@@ -99,6 +99,12 @@ pub(super) fn note_region_origin(
                     "...so that the definition in impl matches the definition from the trait",
                 );
             }
+            infer::CompareImplTypeObligation { span, .. } => {
+                label_or_note(
+                    span,
+                    "...so that the definition in impl matches the definition from the trait",
+                );
+            }
         }
     }
 
@@ -356,6 +362,18 @@ pub(super) fn report_concrete_failure(
                 trait_item_def_id,
                 &format!("`{}: {}`", sup, sub),
             ),
+            infer::CompareImplTypeObligation {
+                span,
+                item_name,
+                impl_item_def_id,
+                trait_item_def_id,
+            } => self.report_extra_impl_obligation(
+                span,
+                item_name,
+                impl_item_def_id,
+                trait_item_def_id,
+                &format!("`{}: {}`", sup, sub),
+            ),
         }
     }
 
index bc98a3aa3f95e563d1982137b0ac0e7b4e65d71a..354b8e26d53d5dcaa466a9adc0208f598bfa3a85 100644 (file)
@@ -427,6 +427,15 @@ pub enum SubregionOrigin<'tcx> {
         impl_item_def_id: DefId,
         trait_item_def_id: DefId,
     },
+
+    /// Comparing the signature and requirements of an impl associated type
+    /// against the containing trait
+    CompareImplTypeObligation {
+        span: Span,
+        item_name: Symbol,
+        impl_item_def_id: DefId,
+        trait_item_def_id: DefId,
+    },
 }
 
 // `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
@@ -1810,6 +1819,7 @@ pub fn span(&self) -> Span {
             ReferenceOutlivesReferent(_, a) => a,
             CallReturn(a) => a,
             CompareImplMethodObligation { span, .. } => span,
+            CompareImplTypeObligation { span, .. } => span,
         }
     }
 
@@ -1833,6 +1843,17 @@ pub fn from_obligation_cause<F>(cause: &traits::ObligationCause<'tcx>, default:
                 trait_item_def_id,
             },
 
+            traits::ObligationCauseCode::CompareImplTypeObligation {
+                item_name,
+                impl_item_def_id,
+                trait_item_def_id,
+            } => SubregionOrigin::CompareImplTypeObligation {
+                span: cause.span,
+                item_name,
+                impl_item_def_id,
+                trait_item_def_id,
+            },
+
             _ => default(),
         }
     }
index c211d8e94a68b1b05b2ba0f8bedb276c57d0f2ae..e88c6608aca335540020bb44f498298afd00345a 100644 (file)
@@ -519,7 +519,7 @@ fn relate_with_variance<T: Relate<'tcx>>(
 
         let old_ambient_variance = self.ambient_variance;
         self.ambient_variance = self.ambient_variance.xform(variance);
-        self.ambient_variance_info = self.ambient_variance_info.clone().xform(info);
+        self.ambient_variance_info = self.ambient_variance_info.xform(info);
 
         debug!("relate_with_variance: ambient_variance = {:?}", self.ambient_variance);
 
@@ -597,12 +597,12 @@ fn regions(
 
         if self.ambient_covariance() {
             // Covariance: a <= b. Hence, `b: a`.
-            self.push_outlives(v_b, v_a, self.ambient_variance_info.clone());
+            self.push_outlives(v_b, v_a, self.ambient_variance_info);
         }
 
         if self.ambient_contravariance() {
             // Contravariant: b <= a. Hence, `a: b`.
-            self.push_outlives(v_a, v_b, self.ambient_variance_info.clone());
+            self.push_outlives(v_a, v_b, self.ambient_variance_info);
         }
 
         Ok(a)
index 3b852b8ccf9d0ffffb47e80769ac77abe64113da..95bd2993456abcd2d4c64c3317db3c87ed4996ce 100644 (file)
@@ -25,6 +25,16 @@ fn span_debug(span: rustc_span::Span, f: &mut fmt::Formatter<'_>) -> fmt::Result
     })
 }
 
+fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
+    tls::with_opt(|tcx| {
+        if let Some(tcx) = tcx {
+            let _span = tcx.source_span(def_id);
+            // Sanity check: relative span's parent must be an absolute span.
+            debug_assert_eq!(_span.data_untracked().parent, None);
+        }
+    })
+}
+
 /// This is a callback from `rustc_ast` as it cannot access the implicit state
 /// in `rustc_middle` otherwise. It is used to when diagnostic messages are
 /// emitted and stores them in the current query, if there is one.
@@ -56,6 +66,7 @@ fn def_id_debug(def_id: rustc_hir::def_id::DefId, f: &mut fmt::Formatter<'_>) ->
 /// TyCtxt in.
 pub fn setup_callbacks() {
     rustc_span::SPAN_DEBUG.swap(&(span_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
+    rustc_span::SPAN_TRACK.swap(&(track_span_parent as fn(_)));
     rustc_hir::def_id::DEF_ID_DEBUG.swap(&(def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
     TRACK_DIAGNOSTICS.swap(&(track_diagnostic as fn(&_)));
 }
index afab919bc3c2cff582ac90614c5f6d3a7bc9fc51..81433e571021ea94aaceaed02a1bc0680a7c2598 100644 (file)
@@ -743,6 +743,7 @@ macro_rules! tracked {
     tracked!(no_profiler_runtime, true);
     tracked!(osx_rpath_install_name, true);
     tracked!(panic_abort_tests, true);
+    tracked!(panic_in_drop, PanicStrategy::Abort);
     tracked!(partially_uninit_const_threshold, Some(123));
     tracked!(plt, Some(true));
     tracked!(polonius, true);
index 480f7756db3fe60476d766bc46ebffd852c38cf6..0143978cfba5f0eaa629bbe0f29b92cfbec4fa80 100644 (file)
@@ -1327,10 +1327,7 @@ fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
             };
             let (variants, tag) = match layout.variants {
                 Variants::Multiple {
-                    tag_encoding: TagEncoding::Direct,
-                    ref tag,
-                    ref variants,
-                    ..
+                    tag_encoding: TagEncoding::Direct, tag, ref variants, ..
                 } => (variants, tag),
                 _ => return,
             };
index 7a42e8c1037ba3dc58105a56a57d9368aa7b2a86..48b955e41ac69506c05e5e46b071c979293dd6d3 100644 (file)
@@ -3,7 +3,6 @@
 use rustc_ast as ast;
 use rustc_ast::util::{classify, parser};
 use rustc_ast::{ExprKind, StmtKind};
-use rustc_ast_pretty::pprust;
 use rustc_errors::{pluralize, Applicability};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -12,7 +11,7 @@
 use rustc_middle::ty::{self, Ty};
 use rustc_span::symbol::Symbol;
 use rustc_span::symbol::{kw, sym};
-use rustc_span::{BytePos, Span, DUMMY_SP};
+use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
 
 declare_lint! {
     /// The `unused_must_use` lint detects unused result of a type flagged as
@@ -491,77 +490,60 @@ fn emit_unused_delims_expr(
         left_pos: Option<BytePos>,
         right_pos: Option<BytePos>,
     ) {
-        let expr_text = if let Ok(snippet) = cx.sess().source_map().span_to_snippet(value.span) {
-            snippet
-        } else {
-            pprust::expr_to_string(value)
+        let spans = match value.kind {
+            ast::ExprKind::Block(ref block, None) if block.stmts.len() > 0 => {
+                let start = block.stmts[0].span;
+                let end = block.stmts[block.stmts.len() - 1].span;
+                if value.span.from_expansion() || start.from_expansion() || end.from_expansion() {
+                    (
+                        value.span.with_hi(value.span.lo() + BytePos(1)),
+                        value.span.with_lo(value.span.hi() - BytePos(1)),
+                    )
+                } else {
+                    (value.span.with_hi(start.lo()), value.span.with_lo(end.hi()))
+                }
+            }
+            ast::ExprKind::Paren(ref expr) => {
+                if value.span.from_expansion() || expr.span.from_expansion() {
+                    (
+                        value.span.with_hi(value.span.lo() + BytePos(1)),
+                        value.span.with_lo(value.span.hi() - BytePos(1)),
+                    )
+                } else {
+                    (value.span.with_hi(expr.span.lo()), value.span.with_lo(expr.span.hi()))
+                }
+            }
+            _ => return,
         };
         let keep_space = (
             left_pos.map_or(false, |s| s >= value.span.lo()),
             right_pos.map_or(false, |s| s <= value.span.hi()),
         );
-        self.emit_unused_delims(cx, value.span, &expr_text, ctx.into(), keep_space);
+        self.emit_unused_delims(cx, spans, ctx.into(), keep_space);
     }
 
     fn emit_unused_delims(
         &self,
         cx: &EarlyContext<'_>,
-        span: Span,
-        pattern: &str,
+        spans: (Span, Span),
         msg: &str,
         keep_space: (bool, bool),
     ) {
         // FIXME(flip1995): Quick and dirty fix for #70814. This should be fixed in rustdoc
         // properly.
-        if span == DUMMY_SP {
+        if spans.0 == DUMMY_SP || spans.1 == DUMMY_SP {
             return;
         }
 
-        cx.struct_span_lint(self.lint(), span, |lint| {
+        cx.struct_span_lint(self.lint(), MultiSpan::from(vec![spans.0, spans.1]), |lint| {
             let span_msg = format!("unnecessary {} around {}", Self::DELIM_STR, msg);
             let mut err = lint.build(&span_msg);
-            let mut ate_left_paren = false;
-            let mut ate_right_paren = false;
-            let parens_removed = pattern
-                .trim_matches(|c| match c {
-                    '(' | '{' => {
-                        if ate_left_paren {
-                            false
-                        } else {
-                            ate_left_paren = true;
-                            true
-                        }
-                    }
-                    ')' | '}' => {
-                        if ate_right_paren {
-                            false
-                        } else {
-                            ate_right_paren = true;
-                            true
-                        }
-                    }
-                    _ => false,
-                })
-                .trim();
-
-            let replace = {
-                let mut replace = if keep_space.0 {
-                    let mut s = String::from(" ");
-                    s.push_str(parens_removed);
-                    s
-                } else {
-                    String::from(parens_removed)
-                };
-
-                if keep_space.1 {
-                    replace.push(' ');
-                }
-                replace
-            };
-
+            let replacement = vec![
+                (spans.0, if keep_space.0 { " ".into() } else { "".into() }),
+                (spans.1, if keep_space.1 { " ".into() } else { "".into() }),
+            ];
             let suggestion = format!("remove these {}", Self::DELIM_STR);
-
-            err.span_suggestion_short(span, &suggestion, replace, Applicability::MachineApplicable);
+            err.multipart_suggestion(&suggestion, replacement, Applicability::MachineApplicable);
             err.emit();
         });
     }
@@ -770,14 +752,15 @@ fn check_unused_parens_pat(
                 // Otherwise proceed with linting.
                 _ => {}
             }
-
-            let pattern_text =
-                if let Ok(snippet) = cx.sess().source_map().span_to_snippet(value.span) {
-                    snippet
-                } else {
-                    pprust::pat_to_string(value)
-                };
-            self.emit_unused_delims(cx, value.span, &pattern_text, "pattern", (false, false));
+            let spans = if value.span.from_expansion() || inner.span.from_expansion() {
+                (
+                    value.span.with_hi(value.span.lo() + BytePos(1)),
+                    value.span.with_lo(value.span.hi() - BytePos(1)),
+                )
+            } else {
+                (value.span.with_hi(inner.span.lo()), value.span.with_lo(inner.span.hi()))
+            };
+            self.emit_unused_delims(cx, spans, "pattern", (false, false));
         }
     }
 }
@@ -870,14 +853,15 @@ fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) {
                     );
                 }
                 _ => {
-                    let pattern_text =
-                        if let Ok(snippet) = cx.sess().source_map().span_to_snippet(ty.span) {
-                            snippet
-                        } else {
-                            pprust::ty_to_string(ty)
-                        };
-
-                    self.emit_unused_delims(cx, ty.span, &pattern_text, "type", (false, false));
+                    let spans = if ty.span.from_expansion() || r.span.from_expansion() {
+                        (
+                            ty.span.with_hi(ty.span.lo() + BytePos(1)),
+                            ty.span.with_lo(ty.span.hi() - BytePos(1)),
+                        )
+                    } else {
+                        (ty.span.with_hi(r.span.lo()), ty.span.with_lo(r.span.hi()))
+                    };
+                    self.emit_unused_delims(cx, spans, "type", (false, false));
                 }
             }
         }
index 4f07a0c67c13f43f50b1962a992b0c9b6ad50136..9850f395a0f650a05d9bbb3e06ddb24b248e17d1 100644 (file)
@@ -203,56 +203,57 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
   report_fatal_error("bad AttributeKind");
 }
 
+template<typename T> static inline void AddAttribute(T *t, unsigned Index, Attribute Attr) {
+#if LLVM_VERSION_LT(14, 0)
+  t->addAttribute(Index, Attr);
+#else
+  t->addAttributeAtIndex(Index, Attr);
+#endif
+}
+
 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
                                              LLVMRustAttribute RustAttr) {
   CallBase *Call = unwrap<CallBase>(Instr);
   Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr));
-  Call->addAttribute(Index, Attr);
+  AddAttribute(Call, Index, Attr);
 }
 
 extern "C" void LLVMRustAddCallSiteAttrString(LLVMValueRef Instr, unsigned Index,
                                               const char *Name) {
   CallBase *Call = unwrap<CallBase>(Instr);
   Attribute Attr = Attribute::get(Call->getContext(), Name);
-  Call->addAttribute(Index, Attr);
+  AddAttribute(Call, Index, Attr);
 }
 
-
 extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
                                                  unsigned Index,
                                                  uint32_t Bytes) {
   CallBase *Call = unwrap<CallBase>(Instr);
-  AttrBuilder B;
-  B.addAlignmentAttr(Bytes);
-  Call->setAttributes(Call->getAttributes().addAttributes(
-      Call->getContext(), Index, B));
+  Attribute Attr = Attribute::getWithAlignment(Call->getContext(), Align(Bytes));
+  AddAttribute(Call, Index, Attr);
 }
 
 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
                                                        unsigned Index,
                                                        uint64_t Bytes) {
   CallBase *Call = unwrap<CallBase>(Instr);
-  AttrBuilder B;
-  B.addDereferenceableAttr(Bytes);
-  Call->setAttributes(Call->getAttributes().addAttributes(
-      Call->getContext(), Index, B));
+  Attribute Attr = Attribute::getWithDereferenceableBytes(Call->getContext(), Bytes);
+  AddAttribute(Call, Index, Attr);
 }
 
 extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr,
                                                              unsigned Index,
                                                              uint64_t Bytes) {
   CallBase *Call = unwrap<CallBase>(Instr);
-  AttrBuilder B;
-  B.addDereferenceableOrNullAttr(Bytes);
-  Call->setAttributes(Call->getAttributes().addAttributes(
-      Call->getContext(), Index, B));
+  Attribute Attr = Attribute::getWithDereferenceableOrNullBytes(Call->getContext(), Bytes);
+  AddAttribute(Call, Index, Attr);
 }
 
 extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr, unsigned Index,
                                              LLVMTypeRef Ty) {
   CallBase *Call = unwrap<CallBase>(Instr);
   Attribute Attr = Attribute::getWithByValType(Call->getContext(), unwrap(Ty));
-  Call->addAttribute(Index, Attr);
+  AddAttribute(Call, Index, Attr);
 }
 
 extern "C" void LLVMRustAddStructRetCallSiteAttr(LLVMValueRef Instr, unsigned Index,
@@ -263,28 +264,28 @@ extern "C" void LLVMRustAddStructRetCallSiteAttr(LLVMValueRef Instr, unsigned In
 #else
   Attribute Attr = Attribute::get(Call->getContext(), Attribute::StructRet);
 #endif
-  Call->addAttribute(Index, Attr);
+  AddAttribute(Call, Index, Attr);
 }
 
 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
                                              LLVMRustAttribute RustAttr) {
   Function *A = unwrap<Function>(Fn);
   Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr));
-  A->addAttribute(Index, Attr);
+  AddAttribute(A, Index, Attr);
 }
 
 extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn,
                                          unsigned Index,
                                          uint32_t Bytes) {
   Function *A = unwrap<Function>(Fn);
-  A->addAttribute(Index, Attribute::getWithAlignment(
+  AddAttribute(A, Index, Attribute::getWithAlignment(
       A->getContext(), llvm::Align(Bytes)));
 }
 
 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
                                                uint64_t Bytes) {
   Function *A = unwrap<Function>(Fn);
-  A->addAttribute(Index, Attribute::getWithDereferenceableBytes(A->getContext(),
+  AddAttribute(A, Index, Attribute::getWithDereferenceableBytes(A->getContext(),
                                                                 Bytes));
 }
 
@@ -292,7 +293,7 @@ extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn,
                                                      unsigned Index,
                                                      uint64_t Bytes) {
   Function *A = unwrap<Function>(Fn);
-  A->addAttribute(Index, Attribute::getWithDereferenceableOrNullBytes(
+  AddAttribute(A, Index, Attribute::getWithDereferenceableOrNullBytes(
       A->getContext(), Bytes));
 }
 
@@ -300,7 +301,7 @@ extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn, unsigned Index,
                                      LLVMTypeRef Ty) {
   Function *F = unwrap<Function>(Fn);
   Attribute Attr = Attribute::getWithByValType(F->getContext(), unwrap(Ty));
-  F->addAttribute(Index, Attr);
+  AddAttribute(F, Index, Attr);
 }
 
 extern "C" void LLVMRustAddStructRetAttr(LLVMValueRef Fn, unsigned Index,
@@ -311,7 +312,7 @@ extern "C" void LLVMRustAddStructRetAttr(LLVMValueRef Fn, unsigned Index,
 #else
   Attribute Attr = Attribute::get(F->getContext(), Attribute::StructRet);
 #endif
-  F->addAttribute(Index, Attr);
+  AddAttribute(F, Index, Attr);
 }
 
 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
@@ -319,7 +320,7 @@ extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
                                                    const char *Name,
                                                    const char *Value) {
   Function *F = unwrap<Function>(Fn);
-  F->addAttribute(Index, Attribute::get(
+  AddAttribute(F, Index, Attribute::get(
       F->getContext(), StringRef(Name), StringRef(Value)));
 }
 
@@ -330,7 +331,12 @@ extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
   Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr));
   AttrBuilder B(Attr);
   auto PAL = F->getAttributes();
-  auto PALNew = PAL.removeAttributes(F->getContext(), Index, B);
+  AttributeList PALNew;
+#if LLVM_VERSION_LT(14, 0)
+  PALNew = PAL.removeAttributes(F->getContext(), Index, B);
+#else
+  PALNew = PAL.removeAttributesAtIndex(F->getContext(), Index, B);
+#endif
   F->setAttributes(PALNew);
 }
 
index 8a0fce209b7fbeb0a9b6ddfea32a78c909864d61..80dcf99da6224b775936e1b1d746e89a640987c1 100644 (file)
@@ -448,7 +448,7 @@ fn generate_non_option_field_code(
                                             span_idx = Some(syn::Index::from(idx));
                                         } else {
                                             throw_span_err!(
-                                                info.span.clone().unwrap(),
+                                                info.span.unwrap(),
                                                 "type of field annotated with `#[suggestion(...)]` contains more than one Span"
                                             );
                                         }
@@ -460,7 +460,7 @@ fn generate_non_option_field_code(
                                             applicability_idx = Some(syn::Index::from(idx));
                                         } else {
                                             throw_span_err!(
-                                                info.span.clone().unwrap(),
+                                                info.span.unwrap(),
                                                 "type of field annotated with `#[suggestion(...)]` contains more than one Applicability"
                                             );
                                         }
@@ -479,7 +479,7 @@ fn generate_non_option_field_code(
                                     return Ok((span, applicability));
                                 }
                                 throw_span_err!(
-                                    info.span.clone().unwrap(),
+                                    info.span.unwrap(),
                                     "wrong types for suggestion",
                                     |diag| {
                                         diag.help("#[suggestion(...)] on a tuple field must be applied to fields of type (Span, Applicability)")
@@ -487,7 +487,7 @@ fn generate_non_option_field_code(
                                 );
                             }
                             _ => throw_span_err!(
-                                info.span.clone().unwrap(),
+                                info.span.unwrap(),
                                 "wrong field type for suggestion",
                                 |diag| {
                                     diag.help("#[suggestion(...)] should be applied to fields of type Span or (Span, Applicability)")
index 2d4deb1d8d5da43d9a2e19bdf5d8b32aad0c2383..b8d22560618162bdbdf6a88b047b96b88b1cdc9a 100644 (file)
@@ -400,21 +400,35 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
                 continue;
             }
             let cnum = CrateNum::new(i + 1);
-            let found_strategy = tcx.panic_strategy(cnum);
-            let is_compiler_builtins = tcx.is_compiler_builtins(cnum);
-            if is_compiler_builtins || desired_strategy == found_strategy {
+            if tcx.is_compiler_builtins(cnum) {
                 continue;
             }
 
-            sess.err(&format!(
-                "the crate `{}` is compiled with the \
+            let found_strategy = tcx.panic_strategy(cnum);
+            if desired_strategy != found_strategy {
+                sess.err(&format!(
+                    "the crate `{}` is compiled with the \
                                panic strategy `{}` which is \
                                incompatible with this crate's \
                                strategy of `{}`",
-                tcx.crate_name(cnum),
-                found_strategy.desc(),
-                desired_strategy.desc()
-            ));
+                    tcx.crate_name(cnum),
+                    found_strategy.desc(),
+                    desired_strategy.desc()
+                ));
+            }
+
+            let found_drop_strategy = tcx.panic_in_drop_strategy(cnum);
+            if tcx.sess.opts.debugging_opts.panic_in_drop != found_drop_strategy {
+                sess.err(&format!(
+                    "the crate `{}` is compiled with the \
+                               panic-in-drop strategy `{}` which is \
+                               incompatible with this crate's \
+                               strategy of `{}`",
+                    tcx.crate_name(cnum),
+                    found_drop_strategy.desc(),
+                    tcx.sess.opts.debugging_opts.panic_in_drop.desc()
+                ));
+            }
         }
     }
 }
index d3512b6cf579e18e1d0cd4d70914ae7c7d1f1231..b6922e0d72a065364c0e0444c70e961128ae5328 100644 (file)
@@ -1095,6 +1095,11 @@ impl CrateError {
                         == Symbol::intern(&sess.opts.debugging_opts.profiler_runtime)
                     {
                         err.note(&"the compiler may have been built without the profiler runtime");
+                    } else if crate_name.as_str().starts_with("rustc_") {
+                        err.help(
+                            "maybe you need to install the missing components with: \
+                             `rustup component add rust-src rustc-dev llvm-tools-preview`",
+                        );
                     }
                     err.span_label(span, "can't find crate");
                     err
index dd44e0cb1fa90872c1f64cad00ddb3d52bd75eb3..2a0332a11242ee757e4cd3ebb45ff3ab034b98fc 100644 (file)
@@ -26,6 +26,7 @@
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
 use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
 use rustc_middle::mir::{self, Body, Promoted};
+use rustc_middle::thir;
 use rustc_middle::ty::codec::TyDecoder;
 use rustc_middle::ty::{self, Ty, TyCtxt, Visibility};
 use rustc_serialize::{opaque, Decodable, Decoder};
@@ -536,11 +537,12 @@ fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<Span, String> {
         let hi =
             (hi + source_file.translated_source_file.start_pos) - source_file.original_start_pos;
 
-        Ok(Span::new(lo, hi, ctxt))
+        // Do not try to decode parent for foreign spans.
+        Ok(Span::new(lo, hi, ctxt, None))
     }
 }
 
-impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [mir::abstract_const::Node<'tcx>] {
+impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [thir::abstract_const::Node<'tcx>] {
     fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<Self, String> {
         ty::codec::RefDecodable::decode(d)
     }
@@ -1019,10 +1021,7 @@ fn get_diagnostic_items(&self) -> FxHashMap<Symbol, DefId> {
     }
 
     /// Iterates over each child of the given item.
-    fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Session)
-    where
-        F: FnMut(Export<hir::HirId>),
-    {
+    fn each_child_of_item(&self, id: DefIndex, mut callback: impl FnMut(Export), sess: &Session) {
         if let Some(data) = &self.root.proc_macro_data {
             /* If we are loading as a proc macro, we want to return the view of this crate
              * as a proc macro crate.
@@ -1198,14 +1197,14 @@ fn get_mir_for_ctfe(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
             .decode((self, tcx))
     }
 
-    fn get_mir_abstract_const(
+    fn get_thir_abstract_const(
         &self,
         tcx: TyCtxt<'tcx>,
         id: DefIndex,
-    ) -> Result<Option<&'tcx [mir::abstract_const::Node<'tcx>]>, ErrorReported> {
+    ) -> Result<Option<&'tcx [thir::abstract_const::Node<'tcx>]>, ErrorReported> {
         self.root
             .tables
-            .mir_abstract_consts
+            .thir_abstract_consts
             .get(self, id)
             .map_or(Ok(None), |v| Ok(Some(v.decode((self, tcx)))))
     }
index 41839c58021ab335c7b2e4c4391d9631544b2834..a01eaf68f01c20ec52da4d64333f199276c4c20f 100644 (file)
@@ -5,7 +5,6 @@
 
 use rustc_ast as ast;
 use rustc_data_structures::stable_map::FxHashMap;
-use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
@@ -117,7 +116,7 @@ fn into_args(self) -> (DefId, DefId) {
     optimized_mir => { tcx.arena.alloc(cdata.get_optimized_mir(tcx, def_id.index)) }
     mir_for_ctfe => { tcx.arena.alloc(cdata.get_mir_for_ctfe(tcx, def_id.index)) }
     promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
-    mir_abstract_const => { cdata.get_mir_abstract_const(tcx, def_id.index) }
+    thir_abstract_const => { cdata.get_thir_abstract_const(tcx, def_id.index) }
     unused_generic_params => { cdata.get_unused_generic_params(def_id.index) }
     const_param_default => { tcx.mk_const(cdata.get_const_param_default(tcx, def_id.index)) }
     mir_const_qualif => { cdata.mir_const_qualif(def_id.index) }
@@ -160,6 +159,7 @@ fn into_args(self) -> (DefId, DefId) {
     has_panic_handler => { cdata.root.has_panic_handler }
     is_profiler_runtime => { cdata.root.profiler_runtime }
     panic_strategy => { cdata.root.panic_strategy }
+    panic_in_drop_strategy => { cdata.root.panic_in_drop_strategy }
     extern_crate => {
         let r = *cdata.extern_crate.lock();
         r.map(|c| &*tcx.arena.alloc(c))
@@ -326,28 +326,27 @@ pub fn provide(providers: &mut Providers) {
             // (restrict scope of mutable-borrow of `visible_parent_map`)
             {
                 let visible_parent_map = &mut visible_parent_map;
-                let mut add_child =
-                    |bfs_queue: &mut VecDeque<_>, child: &Export<hir::HirId>, parent: DefId| {
-                        if child.vis != ty::Visibility::Public {
-                            return;
-                        }
+                let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &Export, parent: DefId| {
+                    if child.vis != ty::Visibility::Public {
+                        return;
+                    }
 
-                        if let Some(child) = child.res.opt_def_id() {
-                            match visible_parent_map.entry(child) {
-                                Entry::Occupied(mut entry) => {
-                                    // If `child` is defined in crate `cnum`, ensure
-                                    // that it is mapped to a parent in `cnum`.
-                                    if child.is_local() && entry.get().is_local() {
-                                        entry.insert(parent);
-                                    }
-                                }
-                                Entry::Vacant(entry) => {
+                    if let Some(child) = child.res.opt_def_id() {
+                        match visible_parent_map.entry(child) {
+                            Entry::Occupied(mut entry) => {
+                                // If `child` is defined in crate `cnum`, ensure
+                                // that it is mapped to a parent in `cnum`.
+                                if child.is_local() && entry.get().is_local() {
                                     entry.insert(parent);
-                                    bfs_queue.push_back(child);
                                 }
                             }
+                            Entry::Vacant(entry) => {
+                                entry.insert(parent);
+                                bfs_queue.push_back(child);
+                            }
                         }
-                    };
+                    }
+                };
 
                 while let Some(def) = bfs_queue.pop_front() {
                     for child in tcx.item_children(def).iter() {
@@ -393,11 +392,7 @@ pub fn visibility_untracked(&self, def: DefId) -> Visibility {
         self.get_crate_data(def.krate).get_visibility(def.index)
     }
 
-    pub fn item_children_untracked(
-        &self,
-        def_id: DefId,
-        sess: &Session,
-    ) -> Vec<Export<hir::HirId>> {
+    pub fn item_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec<Export> {
         let mut result = vec![];
         self.get_crate_data(def_id.krate).each_child_of_item(
             def_id.index,
index d8b9a4799760ef3d9cf79db8932c527a512de6ae..b0d22037f21a92d1766164e267819c82b49dc4c4 100644 (file)
@@ -23,6 +23,7 @@
     metadata_symbol_name, ExportedSymbol, SymbolExportLevel,
 };
 use rustc_middle::mir::interpret;
+use rustc_middle::thir;
 use rustc_middle::traits::specialization_graph;
 use rustc_middle::ty::codec::TyEncoder;
 use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
@@ -344,7 +345,7 @@ fn encode_alloc_id(
     }
 }
 
-impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for &'tcx [mir::abstract_const::Node<'tcx>] {
+impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for &'tcx [thir::abstract_const::Node<'tcx>] {
     fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
         (**self).encode(s)
     }
@@ -691,6 +692,7 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot<'tcx>> {
             hash: tcx.crate_hash(LOCAL_CRATE),
             stable_crate_id: tcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(),
             panic_strategy: tcx.sess.panic_strategy(),
+            panic_in_drop_strategy: tcx.sess.opts.debugging_opts.panic_in_drop,
             edition: tcx.sess.edition(),
             has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE),
             has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE),
@@ -1065,14 +1067,7 @@ fn encode_info_for_mod(&mut self, local_def_id: LocalDefId, md: &hir::Mod<'_>) {
         // items - we encode information about proc-macros later on.
         let reexports = if !self.is_proc_macro {
             match tcx.module_exports(local_def_id) {
-                Some(exports) => {
-                    let hir = self.tcx.hir();
-                    self.lazy(
-                        exports
-                            .iter()
-                            .map(|export| export.map_id(|id| hir.local_def_id_to_hir_id(id))),
-                    )
-                }
+                Some(exports) => self.lazy(exports),
                 _ => Lazy::empty(),
             }
         } else {
@@ -1304,9 +1299,10 @@ fn encode_mir(&mut self) {
             if encode_const {
                 record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- self.tcx.mir_for_ctfe(def_id));
 
-                let abstract_const = self.tcx.mir_abstract_const(def_id);
+                // FIXME(generic_const_exprs): this feels wrong to have in `encode_mir`
+                let abstract_const = self.tcx.thir_abstract_const(def_id);
                 if let Ok(Some(abstract_const)) = abstract_const {
-                    record!(self.tables.mir_abstract_consts[def_id.to_def_id()] <- abstract_const);
+                    record!(self.tables.thir_abstract_consts[def_id.to_def_id()] <- abstract_const);
                 }
             }
             record!(self.tables.promoted_mir[def_id.to_def_id()] <- self.tcx.promoted_mir(def_id));
index a487753f4628a4548275019870d0eaf0c9336982..1f307f3fdeee34baf4ef87a9c615cfa7a71cd968 100644 (file)
@@ -15,6 +15,7 @@
 use rustc_middle::middle::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
 use rustc_middle::mir;
+use rustc_middle::thir;
 use rustc_middle::ty::{self, ReprOptions, Ty};
 use rustc_serialize::opaque::Encoder;
 use rustc_session::config::SymbolManglingVersion;
@@ -204,6 +205,7 @@ macro_rules! Lazy {
     hash: Svh,
     stable_crate_id: StableCrateId,
     panic_strategy: PanicStrategy,
+    panic_in_drop_strategy: PanicStrategy,
     edition: Edition,
     has_global_allocator: bool,
     has_panic_handler: bool,
@@ -305,7 +307,7 @@ fn encode(&self, buf: &mut Encoder) -> LazyTables<'tcx> {
     mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
     mir_for_ctfe: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
     promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>,
-    mir_abstract_consts: Table<DefIndex, Lazy!(&'tcx [mir::abstract_const::Node<'tcx>])>,
+    thir_abstract_consts: Table<DefIndex, Lazy!(&'tcx [thir::abstract_const::Node<'tcx>])>,
     const_defaults: Table<DefIndex, Lazy<rustc_middle::ty::Const<'tcx>>>,
     unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>,
     // `def_keys` and `def_path_hashes` represent a lazy version of a
@@ -359,7 +361,7 @@ enum EntryKind {
 
 #[derive(MetadataEncodable, MetadataDecodable)]
 struct ModData {
-    reexports: Lazy<[Export<hir::HirId>]>,
+    reexports: Lazy<[Export]>,
     expansion: ExpnId,
 }
 
index be9e38aca65d10feeceb8e1d50b7fb208ef86ea5..f37b976fba68d3d6d450cee0c1cb4b9b353bb2ac 100644 (file)
 
 /// This is the replacement export map. It maps a module to all of the exports
 /// within.
-pub type ExportMap<Id> = FxHashMap<LocalDefId, Vec<Export<Id>>>;
+pub type ExportMap = FxHashMap<LocalDefId, Vec<Export>>;
 
 #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
-pub struct Export<Id> {
+pub struct Export {
     /// The name of the target.
     pub ident: Ident,
     /// The resolution of the target.
-    pub res: Res<Id>,
+    /// Local variables cannot be exported, so this `Res` doesn't need the ID parameter.
+    pub res: Res<!>,
     /// The span of the target.
     pub span: Span,
     /// The visibility of the export.
     /// We include non-`pub` exports for hygienic macros that get used from extern crates.
     pub vis: ty::Visibility,
 }
-
-impl<Id> Export<Id> {
-    pub fn map_id<R>(self, map: impl FnMut(Id) -> R) -> Export<R> {
-        Export { ident: self.ident, res: self.res.map_id(map), span: self.span, vis: self.vis }
-    }
-}
index 1351b4950f143cb9714bd4cc95fbe2ca7ba208ee..082948eba416d62c08714c36ac92d1b9be971e53 100644 (file)
@@ -62,13 +62,6 @@ fn hash_body(
     stable_hasher.finish()
 }
 
-/// Represents an entry and its parent `HirId`.
-#[derive(Copy, Clone, Debug)]
-pub struct Entry<'hir> {
-    parent: HirId,
-    node: Node<'hir>,
-}
-
 impl<'a, 'hir> NodeCollector<'a, 'hir> {
     pub(super) fn root(
         sess: &'a Session,
index e0b6039fe348f4bd0e24ed5581000ee9dec978b9..10714a4b706f6e0d8141a54f1589b22d53b27753 100644 (file)
@@ -969,22 +969,12 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
         .iter_enumerated()
         .filter_map(|(def_id, hod)| {
             let def_path_hash = tcx.untracked_resolutions.definitions.def_path_hash(def_id);
-            let mut hasher = StableHasher::new();
-            hod.as_ref()?.hash_stable(&mut hcx, &mut hasher);
-            AttributeMap { map: &tcx.untracked_crate.attrs, prefix: def_id }
-                .hash_stable(&mut hcx, &mut hasher);
-            Some((def_path_hash, hasher.finish()))
+            let hash = hod.as_ref()?.hash;
+            Some((def_path_hash, hash, def_id))
         })
         .collect();
     hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
 
-    let node_hashes = hir_body_nodes.iter().fold(
-        Fingerprint::ZERO,
-        |combined_fingerprint, &(def_path_hash, fingerprint)| {
-            combined_fingerprint.combine(def_path_hash.0.combine(fingerprint))
-        },
-    );
-
     let upstream_crates = upstream_crates(tcx);
 
     // We hash the final, remapped names of all local source files so we
@@ -1004,7 +994,17 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
     source_file_names.sort_unstable();
 
     let mut stable_hasher = StableHasher::new();
-    node_hashes.hash_stable(&mut hcx, &mut stable_hasher);
+    for (def_path_hash, fingerprint, def_id) in hir_body_nodes.iter() {
+        def_path_hash.0.hash_stable(&mut hcx, &mut stable_hasher);
+        fingerprint.hash_stable(&mut hcx, &mut stable_hasher);
+        AttributeMap { map: &tcx.untracked_crate.attrs, prefix: *def_id }
+            .hash_stable(&mut hcx, &mut stable_hasher);
+        if tcx.sess.opts.debugging_opts.incremental_relative_spans {
+            let span = tcx.untracked_resolutions.definitions.def_span(*def_id);
+            debug_assert_eq!(span.parent(), None);
+            span.hash_stable(&mut hcx, &mut stable_hasher);
+        }
+    }
     upstream_crates.hash_stable(&mut hcx, &mut stable_hasher);
     source_file_names.hash_stable(&mut hcx, &mut stable_hasher);
     tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher);
index 34aee4f1b3b3fc24703738a8be4c59927c4532c0..c8ea7454f0bf4a3fe22764c27295ca1de253e900 100644 (file)
@@ -153,6 +153,7 @@ pub fn provide(providers: &mut Providers) {
         index.parenting.get(&id).copied().unwrap_or(CRATE_HIR_ID)
     };
     providers.hir_attrs = |tcx, id| AttributeMap { map: &tcx.untracked_crate.attrs, prefix: id };
+    providers.source_span = |tcx, def_id| tcx.resolutions(()).definitions.def_span(def_id);
     providers.def_span = |tcx, def_id| tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP);
     providers.fn_arg_names = |tcx, id| {
         let hir = tcx.hir();
index 32ccdafaeb48c926a87609b2d77ae89564a19b9d..c7f58ce5b13371af578d7ce83203e2d667c36e06 100644 (file)
@@ -12,7 +12,7 @@
 use rustc_session::Session;
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::Symbol;
-use rustc_span::{BytePos, CachingSourceMapView, SourceFile, SpanData};
+use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData};
 
 use smallvec::SmallVec;
 use std::cmp::Ord;
@@ -28,7 +28,6 @@ fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
 /// things (e.g., each `DefId`/`DefPath` is only hashed once).
 #[derive(Clone)]
 pub struct StableHashingContext<'a> {
-    sess: &'a Session,
     definitions: &'a Definitions,
     cstore: &'a dyn CrateStore,
     pub(super) body_resolver: BodyResolver<'a>,
@@ -78,7 +77,6 @@ fn new_with_or_without_spans(
             !always_ignore_spans && !sess.opts.debugging_opts.incremental_ignore_spans;
 
         StableHashingContext {
-            sess,
             body_resolver: BodyResolver(krate),
             definitions,
             cstore,
@@ -229,6 +227,11 @@ fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
         self.def_path_hash(def_id)
     }
 
+    #[inline]
+    fn def_span(&self, def_id: LocalDefId) -> Span {
+        self.definitions.def_span(def_id)
+    }
+
     fn span_data_to_lines_and_cols(
         &mut self,
         span: &SpanData,
diff --git a/compiler/rustc_middle/src/mir/abstract_const.rs b/compiler/rustc_middle/src/mir/abstract_const.rs
deleted file mode 100644 (file)
index 1ef1024..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//! A subset of a mir body used for const evaluatability checking.
-use crate::mir::{self, CastKind};
-use crate::ty::{self, Ty};
-
-rustc_index::newtype_index! {
-    /// An index into an `AbstractConst`.
-    pub struct NodeId {
-        derive [HashStable]
-        DEBUG_FORMAT = "n{}",
-    }
-}
-
-/// A node of an `AbstractConst`.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
-pub enum Node<'tcx> {
-    Leaf(&'tcx ty::Const<'tcx>),
-    Binop(mir::BinOp, NodeId, NodeId),
-    UnaryOp(mir::UnOp, NodeId),
-    FunctionCall(NodeId, &'tcx [NodeId]),
-    Cast(CastKind, NodeId, Ty<'tcx>),
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
-pub enum NotConstEvaluatable {
-    Error(rustc_errors::ErrorReported),
-    MentionsInfer,
-    MentionsParam,
-}
-
-impl From<rustc_errors::ErrorReported> for NotConstEvaluatable {
-    fn from(e: rustc_errors::ErrorReported) -> NotConstEvaluatable {
-        NotConstEvaluatable::Error(e)
-    }
-}
-
-TrivialTypeFoldableAndLiftImpls! {
-    NotConstEvaluatable,
-}
index 38d4c5b4bd10ee208c49cd7bee2b4ca175597434..e8d30034dc4e6fdadb1cd82921a350db9a91a90c 100644 (file)
@@ -40,7 +40,6 @@
 use self::predecessors::{PredecessorCache, Predecessors};
 pub use self::query::*;
 
-pub mod abstract_const;
 pub mod coverage;
 mod generic_graph;
 pub mod generic_graphviz;
@@ -1736,7 +1735,7 @@ pub struct Place<'tcx> {
     pub projection: &'tcx List<PlaceElem<'tcx>>,
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(Place<'_>, 16);
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -2062,7 +2061,7 @@ pub enum Operand<'tcx> {
     Constant(Box<Constant<'tcx>>),
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(Operand<'_>, 24);
 
 impl<'tcx> Debug for Operand<'tcx> {
@@ -2200,7 +2199,7 @@ pub enum Rvalue<'tcx> {
     Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(Rvalue<'_>, 40);
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
@@ -2226,7 +2225,7 @@ pub enum AggregateKind<'tcx> {
     Generator(DefId, SubstsRef<'tcx>, hir::Movability),
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(AggregateKind<'_>, 48);
 
 #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
@@ -2278,6 +2277,8 @@ pub fn is_checkable(self) -> bool {
 pub enum NullOp {
     /// Returns the size of a value of that type
     SizeOf,
+    /// Returns the minimum alignment of a type
+    AlignOf,
     /// Creates a new uninitialized box for a value of that type
     Box,
 }
index 1bdb6ca012b4aa6bdd63b34a7968425d8d472aa5..567f65e83d98c5fa3e9e934e028cb2c162d47b35 100644 (file)
@@ -1,6 +1,6 @@
 //! Values computed by queries that use MIR.
 
-use crate::mir::{abstract_const, Body, Promoted};
+use crate::mir::{Body, Promoted};
 use crate::ty::{self, Ty, TyCtxt};
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::vec_map::VecMap;
@@ -431,16 +431,4 @@ pub fn mir_for_ctfe_opt_const_arg(self, def: ty::WithOptConstParam<DefId>) -> &'
             self.mir_for_ctfe(def.did)
         }
     }
-
-    #[inline]
-    pub fn mir_abstract_const_opt_const_arg(
-        self,
-        def: ty::WithOptConstParam<DefId>,
-    ) -> Result<Option<&'tcx [abstract_const::Node<'tcx>]>, ErrorReported> {
-        if let Some((did, param_did)) = def.as_const_arg() {
-            self.mir_abstract_const_of_const_arg((did, param_did))
-        } else {
-            self.mir_abstract_const(def.did)
-        }
-    }
 }
index 74d303cee5d1efc14c6689cecde1a9c651cb857d..b48e8a868efdb1cf01a0b9e9abf5cf93fbbad603 100644 (file)
@@ -196,7 +196,7 @@ pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx>
             Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx),
             Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx),
             Rvalue::NullaryOp(NullOp::Box, t) => tcx.mk_box(t),
-            Rvalue::NullaryOp(NullOp::SizeOf, _) => tcx.types.usize,
+            Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => tcx.types.usize,
             Rvalue::Aggregate(ref ak, ref ops) => match **ak {
                 AggregateKind::Array(ty) => tcx.mk_array(ty, ops.len() as u64),
                 AggregateKind::Tuple => tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx))),
index c93996162e3e372b491ce58f55d3927a39fe67d2..985d35ff9a9b18e9d9ddb4e05164f206e5ae25ed 100644 (file)
         desc { "get the resolver outputs" }
     }
 
+    /// Return the span for a definition.
+    /// Contrary to `def_span` below, this query returns the full absolute span of the definition.
+    /// This span is meant for dep-tracking rather than diagnostics. It should not be used outside
+    /// of rustc_middle::hir::source_map.
+    query source_span(key: LocalDefId) -> Span {
+        desc { "get the source span" }
+    }
+
     /// Represents crate as a whole (as distinct from the top-level crate module).
     /// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`),
     /// we will have to assume that any change means that you need to be recompiled.
     }
 
     /// Try to build an abstract representation of the given constant.
-    query mir_abstract_const(
+    query thir_abstract_const(
         key: DefId
-    ) -> Result<Option<&'tcx [mir::abstract_const::Node<'tcx>]>, ErrorReported> {
+    ) -> Result<Option<&'tcx [thir::abstract_const::Node<'tcx>]>, ErrorReported> {
         desc {
             |tcx| "building an abstract representation for {}", tcx.def_path_str(key),
         }
     }
     /// Try to build an abstract representation of the given constant.
-    query mir_abstract_const_of_const_arg(
+    query thir_abstract_const_of_const_arg(
         key: (LocalDefId, DefId)
-    ) -> Result<Option<&'tcx [mir::abstract_const::Node<'tcx>]>, ErrorReported> {
+    ) -> Result<Option<&'tcx [thir::abstract_const::Node<'tcx>]>, ErrorReported> {
         desc {
             |tcx|
             "building an abstract representation for the const argument {}",
         fatal_cycle
         desc { "query a crate's configured panic strategy" }
     }
+    query panic_in_drop_strategy(_: CrateNum) -> PanicStrategy {
+        fatal_cycle
+        desc { "query a crate's configured panic-in-drop strategy" }
+    }
     query is_no_builtins(_: CrateNum) -> bool {
         fatal_cycle
         desc { "test whether a crate has `#![no_builtins]`" }
         desc { "traits in scope at a block" }
     }
 
-    query module_exports(def_id: LocalDefId) -> Option<&'tcx [Export<LocalDefId>]> {
+    query module_exports(def_id: LocalDefId) -> Option<&'tcx [Export]> {
         desc { |tcx| "looking up items exported by `{}`", tcx.def_path_str(def_id.to_def_id()) }
     }
 
         eval_always
         desc { "fetching what a crate is named" }
     }
-    query item_children(def_id: DefId) -> &'tcx [Export<hir::HirId>] {
+    query item_children(def_id: DefId) -> &'tcx [Export] {
         desc { |tcx| "collecting child items of `{}`", tcx.def_path_str(def_id) }
     }
     query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> {
index 91a64e163e7c0172efd2cb58395ed574cd96402b..8d6fd1e729d3b52b5e4ec75dc6bd775317101924 100644 (file)
@@ -33,6 +33,9 @@
 use std::fmt;
 use std::ops::Index;
 
+pub mod abstract_const;
+pub mod visit;
+
 newtype_index! {
     /// An index to an [`Arm`] stored in [`Thir::arms`]
     #[derive(HashStable)]
diff --git a/compiler/rustc_middle/src/thir/abstract_const.rs b/compiler/rustc_middle/src/thir/abstract_const.rs
new file mode 100644 (file)
index 0000000..f80bead
--- /dev/null
@@ -0,0 +1,61 @@
+//! A subset of a mir body used for const evaluatability checking.
+use crate::mir;
+use crate::ty::{self, Ty, TyCtxt};
+use rustc_errors::ErrorReported;
+
+rustc_index::newtype_index! {
+    /// An index into an `AbstractConst`.
+    pub struct NodeId {
+        derive [HashStable]
+        DEBUG_FORMAT = "n{}",
+    }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
+pub enum CastKind {
+    /// thir::ExprKind::As
+    As,
+    /// thir::ExprKind::Use
+    Use,
+}
+
+/// A node of an `AbstractConst`.
+#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
+pub enum Node<'tcx> {
+    Leaf(&'tcx ty::Const<'tcx>),
+    Binop(mir::BinOp, NodeId, NodeId),
+    UnaryOp(mir::UnOp, NodeId),
+    FunctionCall(NodeId, &'tcx [NodeId]),
+    Cast(CastKind, NodeId, Ty<'tcx>),
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
+pub enum NotConstEvaluatable {
+    Error(ErrorReported),
+    MentionsInfer,
+    MentionsParam,
+}
+
+impl From<ErrorReported> for NotConstEvaluatable {
+    fn from(e: ErrorReported) -> NotConstEvaluatable {
+        NotConstEvaluatable::Error(e)
+    }
+}
+
+TrivialTypeFoldableAndLiftImpls! {
+    NotConstEvaluatable,
+}
+
+impl<'tcx> TyCtxt<'tcx> {
+    #[inline]
+    pub fn thir_abstract_const_opt_const_arg(
+        self,
+        def: ty::WithOptConstParam<rustc_hir::def_id::DefId>,
+    ) -> Result<Option<&'tcx [Node<'tcx>]>, ErrorReported> {
+        if let Some((did, param_did)) = def.as_const_arg() {
+            self.thir_abstract_const_of_const_arg((did, param_did))
+        } else {
+            self.thir_abstract_const(def.did)
+        }
+    }
+}
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
new file mode 100644 (file)
index 0000000..7fc15e0
--- /dev/null
@@ -0,0 +1,242 @@
+use super::{
+    Arm, Block, Expr, ExprKind, Guard, InlineAsmOperand, Pat, PatKind, Stmt, StmtKind, Thir,
+};
+use rustc_middle::ty::Const;
+
+pub trait Visitor<'a, 'tcx: 'a>: Sized {
+    fn thir(&self) -> &'a Thir<'tcx>;
+
+    fn visit_expr(&mut self, expr: &Expr<'tcx>) {
+        walk_expr(self, expr);
+    }
+
+    fn visit_stmt(&mut self, stmt: &Stmt<'tcx>) {
+        walk_stmt(self, stmt);
+    }
+
+    fn visit_block(&mut self, block: &Block) {
+        walk_block(self, block);
+    }
+
+    fn visit_arm(&mut self, arm: &Arm<'tcx>) {
+        walk_arm(self, arm);
+    }
+
+    fn visit_pat(&mut self, pat: &Pat<'tcx>) {
+        walk_pat(self, pat);
+    }
+
+    fn visit_const(&mut self, _cnst: &'tcx Const<'tcx>) {}
+}
+
+pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Expr<'tcx>) {
+    use ExprKind::*;
+    match expr.kind {
+        Scope { value, region_scope: _, lint_level: _ } => {
+            visitor.visit_expr(&visitor.thir()[value])
+        }
+        Box { value } => visitor.visit_expr(&visitor.thir()[value]),
+        If { cond, then, else_opt, if_then_scope: _ } => {
+            visitor.visit_expr(&visitor.thir()[cond]);
+            visitor.visit_expr(&visitor.thir()[then]);
+            if let Some(else_expr) = else_opt {
+                visitor.visit_expr(&visitor.thir()[else_expr]);
+            }
+        }
+        Call { fun, ref args, ty: _, from_hir_call: _, fn_span: _ } => {
+            visitor.visit_expr(&visitor.thir()[fun]);
+            for &arg in &**args {
+                visitor.visit_expr(&visitor.thir()[arg]);
+            }
+        }
+        Deref { arg } => visitor.visit_expr(&visitor.thir()[arg]),
+        Binary { lhs, rhs, op: _ } | LogicalOp { lhs, rhs, op: _ } => {
+            visitor.visit_expr(&visitor.thir()[lhs]);
+            visitor.visit_expr(&visitor.thir()[rhs]);
+        }
+        Unary { arg, op: _ } => visitor.visit_expr(&visitor.thir()[arg]),
+        Cast { source } => visitor.visit_expr(&visitor.thir()[source]),
+        Use { source } => visitor.visit_expr(&visitor.thir()[source]),
+        NeverToAny { source } => visitor.visit_expr(&visitor.thir()[source]),
+        Pointer { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]),
+        Let { expr, .. } => {
+            visitor.visit_expr(&visitor.thir()[expr]);
+        }
+        Loop { body } => visitor.visit_expr(&visitor.thir()[body]),
+        Match { scrutinee, ref arms } => {
+            visitor.visit_expr(&visitor.thir()[scrutinee]);
+            for &arm in &**arms {
+                visitor.visit_arm(&visitor.thir()[arm]);
+            }
+        }
+        Block { ref body } => visitor.visit_block(body),
+        Assign { lhs, rhs } | AssignOp { lhs, rhs, op: _ } => {
+            visitor.visit_expr(&visitor.thir()[lhs]);
+            visitor.visit_expr(&visitor.thir()[rhs]);
+        }
+        Field { lhs, name: _ } => visitor.visit_expr(&visitor.thir()[lhs]),
+        Index { lhs, index } => {
+            visitor.visit_expr(&visitor.thir()[lhs]);
+            visitor.visit_expr(&visitor.thir()[index]);
+        }
+        VarRef { id: _ } | UpvarRef { closure_def_id: _, var_hir_id: _ } => {}
+        Borrow { arg, borrow_kind: _ } => visitor.visit_expr(&visitor.thir()[arg]),
+        AddressOf { arg, mutability: _ } => visitor.visit_expr(&visitor.thir()[arg]),
+        Break { value, label: _ } => {
+            if let Some(value) = value {
+                visitor.visit_expr(&visitor.thir()[value])
+            }
+        }
+        Continue { label: _ } => {}
+        Return { value } => {
+            if let Some(value) = value {
+                visitor.visit_expr(&visitor.thir()[value])
+            }
+        }
+        ConstBlock { value } => visitor.visit_const(value),
+        Repeat { value, count } => {
+            visitor.visit_expr(&visitor.thir()[value]);
+            visitor.visit_const(count);
+        }
+        Array { ref fields } | Tuple { ref fields } => {
+            for &field in &**fields {
+                visitor.visit_expr(&visitor.thir()[field]);
+            }
+        }
+        Adt(box crate::thir::Adt {
+            ref fields,
+            ref base,
+            adt_def: _,
+            variant_index: _,
+            substs: _,
+            user_ty: _,
+        }) => {
+            for field in &**fields {
+                visitor.visit_expr(&visitor.thir()[field.expr]);
+            }
+            if let Some(base) = base {
+                visitor.visit_expr(&visitor.thir()[base.base]);
+            }
+        }
+        PlaceTypeAscription { source, user_ty: _ } | ValueTypeAscription { source, user_ty: _ } => {
+            visitor.visit_expr(&visitor.thir()[source])
+        }
+        Closure { closure_id: _, substs: _, upvars: _, movability: _, fake_reads: _ } => {}
+        Literal { literal, user_ty: _, const_id: _ } => visitor.visit_const(literal),
+        StaticRef { literal, def_id: _ } => visitor.visit_const(literal),
+        InlineAsm { ref operands, template: _, options: _, line_spans: _ } => {
+            for op in &**operands {
+                use InlineAsmOperand::*;
+                match op {
+                    In { expr, reg: _ }
+                    | Out { expr: Some(expr), reg: _, late: _ }
+                    | InOut { expr, reg: _, late: _ }
+                    | SymFn { expr } => visitor.visit_expr(&visitor.thir()[*expr]),
+                    SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
+                        visitor.visit_expr(&visitor.thir()[*in_expr]);
+                        if let Some(out_expr) = out_expr {
+                            visitor.visit_expr(&visitor.thir()[*out_expr]);
+                        }
+                    }
+                    Out { expr: None, reg: _, late: _ }
+                    | Const { value: _, span: _ }
+                    | SymStatic { def_id: _ } => {}
+                }
+            }
+        }
+        ThreadLocalRef(_) => {}
+        LlvmInlineAsm { ref outputs, ref inputs, asm: _ } => {
+            for &out_expr in &**outputs {
+                visitor.visit_expr(&visitor.thir()[out_expr]);
+            }
+            for &in_expr in &**inputs {
+                visitor.visit_expr(&visitor.thir()[in_expr]);
+            }
+        }
+        Yield { value } => visitor.visit_expr(&visitor.thir()[value]),
+    }
+}
+
+pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stmt<'tcx>) {
+    match &stmt.kind {
+        StmtKind::Expr { expr, scope: _ } => visitor.visit_expr(&visitor.thir()[*expr]),
+        StmtKind::Let {
+            initializer,
+            remainder_scope: _,
+            init_scope: _,
+            ref pattern,
+            lint_level: _,
+        } => {
+            if let Some(init) = initializer {
+                visitor.visit_expr(&visitor.thir()[*init]);
+            }
+            visitor.visit_pat(pattern);
+        }
+    }
+}
+
+pub fn walk_block<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, block: &Block) {
+    for &stmt in &*block.stmts {
+        visitor.visit_stmt(&visitor.thir()[stmt]);
+    }
+    if let Some(expr) = block.expr {
+        visitor.visit_expr(&visitor.thir()[expr]);
+    }
+}
+
+pub fn walk_arm<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, arm: &Arm<'tcx>) {
+    match arm.guard {
+        Some(Guard::If(expr)) => visitor.visit_expr(&visitor.thir()[expr]),
+        Some(Guard::IfLet(ref pat, expr)) => {
+            visitor.visit_pat(pat);
+            visitor.visit_expr(&visitor.thir()[expr]);
+        }
+        None => {}
+    }
+    visitor.visit_pat(&arm.pattern);
+    visitor.visit_expr(&visitor.thir()[arm.body]);
+}
+
+pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'tcx>) {
+    use PatKind::*;
+    match pat.kind.as_ref() {
+        AscribeUserType { subpattern, ascription: _ }
+        | Deref { subpattern }
+        | Binding {
+            subpattern: Some(subpattern),
+            mutability: _,
+            mode: _,
+            var: _,
+            ty: _,
+            is_primary: _,
+            name: _,
+        } => visitor.visit_pat(&subpattern),
+        Binding { .. } | Wild => {}
+        Variant { subpatterns, adt_def: _, substs: _, variant_index: _ } | Leaf { subpatterns } => {
+            for subpattern in subpatterns {
+                visitor.visit_pat(&subpattern.pattern);
+            }
+        }
+        Constant { value } => visitor.visit_const(value),
+        Range(range) => {
+            visitor.visit_const(range.lo);
+            visitor.visit_const(range.hi);
+        }
+        Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
+            for subpattern in prefix {
+                visitor.visit_pat(&subpattern);
+            }
+            if let Some(pat) = slice {
+                visitor.visit_pat(pat);
+            }
+            for subpattern in suffix {
+                visitor.visit_pat(&subpattern);
+            }
+        }
+        Or { pats } => {
+            for pat in pats {
+                visitor.visit_pat(&pat);
+            }
+        }
+    };
+}
index 74edb17fe32f1af9e4daccc8c1ab447c412893e8..e21a2d1034cdd3e923e8bba1838fc515dca6832a 100644 (file)
@@ -9,7 +9,7 @@
 mod structural_impls;
 
 use crate::infer::canonical::Canonical;
-use crate::mir::abstract_const::NotConstEvaluatable;
+use crate::thir::abstract_const::NotConstEvaluatable;
 use crate::ty::subst::SubstsRef;
 use crate::ty::{self, AdtKind, Ty, TyCtxt};
 
index 4edb6a327b0352f60fd61f148e8e491ee8507600..8b70692960df9374645d95e5ab188486c04a26db 100644 (file)
@@ -12,6 +12,7 @@
     self,
     interpret::{AllocId, Allocation},
 };
+use crate::thir;
 use crate::ty::subst::SubstsRef;
 use crate::ty::{self, List, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
@@ -362,7 +363,7 @@ fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [mir::abstract_const::Node<'tcx>] {
+impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [thir::abstract_const::Node<'tcx>] {
     fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
         Ok(decoder.tcx().arena.alloc_from_iter(
             (0..decoder.read_usize()?)
@@ -372,7 +373,7 @@ fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
     }
 }
 
-impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [mir::abstract_const::NodeId] {
+impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [thir::abstract_const::NodeId] {
     fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
         Ok(decoder.tcx().arena.alloc_from_iter(
             (0..decoder.read_usize()?)
index 796ca650bdd77f55bd1f7c6df12175c39a300904..08b4d3aecda0ae358abcd76529f8497010ce8069 100644 (file)
@@ -964,7 +964,7 @@ fn constrain_associated_type_structured_suggestion(
         {
             let (span, sugg) = if has_params {
                 let pos = span.hi() - BytePos(1);
-                let span = Span::new(pos, pos, span.ctxt());
+                let span = Span::new(pos, pos, span.ctxt(), span.parent());
                 (span, format!(", {} = {}", assoc.ident, ty))
             } else {
                 let item_args = self.format_generic_args(assoc_substs);
index f7ab9dd82ac738971450a43ea912ba456ea56a8e..1bea1cbc3b94be0129bbfa2a31d478547c6b193f 100644 (file)
@@ -290,9 +290,9 @@ fn scalar_pair(&self, a: Scalar, b: Scalar) -> Layout {
 
         // HACK(nox): We iter on `b` and then `a` because `max_by_key`
         // returns the last maximum.
-        let largest_niche = Niche::from_scalar(dl, b_offset, b.clone())
+        let largest_niche = Niche::from_scalar(dl, b_offset, b)
             .into_iter()
-            .chain(Niche::from_scalar(dl, Size::ZERO, a.clone()))
+            .chain(Niche::from_scalar(dl, Size::ZERO, a))
             .max_by_key(|niche| niche.available(dl));
 
         Layout {
@@ -401,7 +401,7 @@ fn univariant_uninterned(
             offsets[i as usize] = offset;
 
             if !repr.hide_niche() {
-                if let Some(mut niche) = field.largest_niche.clone() {
+                if let Some(mut niche) = field.largest_niche {
                     let available = niche.available(dl);
                     if available > largest_niche_available {
                         largest_niche_available = available;
@@ -449,12 +449,12 @@ fn univariant_uninterned(
                             // For plain scalars, or vectors of them, we can't unpack
                             // newtypes for `#[repr(C)]`, as that affects C ABIs.
                             Abi::Scalar(_) | Abi::Vector { .. } if optimize => {
-                                abi = field.abi.clone();
+                                abi = field.abi;
                             }
                             // But scalar pairs are Rust-specific and get
                             // treated as aggregates by C ABIs anyway.
                             Abi::ScalarPair(..) => {
-                                abi = field.abi.clone();
+                                abi = field.abi;
                             }
                             _ => {}
                         }
@@ -463,14 +463,14 @@ fn univariant_uninterned(
 
                 // Two non-ZST fields, and they're both scalars.
                 (
-                    Some((i, &TyAndLayout { layout: &Layout { abi: Abi::Scalar(ref a), .. }, .. })),
-                    Some((j, &TyAndLayout { layout: &Layout { abi: Abi::Scalar(ref b), .. }, .. })),
+                    Some((i, &TyAndLayout { layout: &Layout { abi: Abi::Scalar(a), .. }, .. })),
+                    Some((j, &TyAndLayout { layout: &Layout { abi: Abi::Scalar(b), .. }, .. })),
                     None,
                 ) => {
                     // Order by the memory placement, not source order.
                     let ((i, a), (j, b)) =
                         if offsets[i] < offsets[j] { ((i, a), (j, b)) } else { ((j, b), (i, a)) };
-                    let pair = self.scalar_pair(a.clone(), b.clone());
+                    let pair = self.scalar_pair(a, b);
                     let pair_offsets = match pair.fields {
                         FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
                             assert_eq!(memory_index, &[0, 1]);
@@ -512,9 +512,9 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
         let param_env = self.param_env;
         let dl = self.data_layout();
         let scalar_unit = |value: Primitive| {
-            let bits = value.size(dl).bits();
-            assert!(bits <= 128);
-            Scalar { value, valid_range: WrappingRange { start: 0, end: (!0 >> (128 - bits)) } }
+            let size = value.size(dl);
+            assert!(size.bits() <= 128);
+            Scalar { value, valid_range: WrappingRange { start: 0, end: size.unsigned_int_max() } }
         };
         let scalar = |value: Primitive| tcx.intern_layout(Layout::scalar(self, scalar_unit(value)));
 
@@ -609,7 +609,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
                         Abi::Aggregate { sized: true }
                     };
 
-                let largest_niche = if count != 0 { element.largest_niche.clone() } else { None };
+                let largest_niche = if count != 0 { element.largest_niche } else { None };
 
                 tcx.intern_layout(Layout {
                     variants: Variants::Single { index: VariantIdx::new(0) },
@@ -768,8 +768,8 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
 
                 // Compute the ABI of the element type:
                 let e_ly = self.layout_of(e_ty)?;
-                let e_abi = if let Abi::Scalar(ref scalar) = e_ly.abi {
-                    scalar.clone()
+                let e_abi = if let Abi::Scalar(scalar) = e_ly.abi {
+                    scalar
                 } else {
                     // This error isn't caught in typeck, e.g., if
                     // the element type of the vector is generic.
@@ -796,7 +796,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
                     variants: Variants::Single { index: VariantIdx::new(0) },
                     fields,
                     abi: Abi::Vector { element: e_abi, count: e_len },
-                    largest_niche: e_ly.largest_niche.clone(),
+                    largest_niche: e_ly.largest_niche,
                     size,
                     align,
                 })
@@ -843,13 +843,13 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
                         // If all non-ZST fields have the same ABI, forward this ABI
                         if optimize && !field.is_zst() {
                             // Normalize scalar_unit to the maximal valid range
-                            let field_abi = match &field.abi {
+                            let field_abi = match field.abi {
                                 Abi::Scalar(x) => Abi::Scalar(scalar_unit(x.value)),
                                 Abi::ScalarPair(x, y) => {
                                     Abi::ScalarPair(scalar_unit(x.value), scalar_unit(y.value))
                                 }
                                 Abi::Vector { element: x, count } => {
-                                    Abi::Vector { element: scalar_unit(x.value), count: *count }
+                                    Abi::Vector { element: scalar_unit(x.value), count }
                                 }
                                 Abi::Uninhabited | Abi::Aggregate { .. } => {
                                     Abi::Aggregate { sized: true }
@@ -970,7 +970,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
                                 Niche::from_scalar(dl, Size::ZERO, scalar.clone())
                             };
                             if let Some(niche) = niche {
-                                match &st.largest_niche {
+                                match st.largest_niche {
                                     Some(largest_niche) => {
                                         // Replace the existing niche even if they're equal,
                                         // because this one is at a lower offset.
@@ -1045,7 +1045,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
                         let niche_candidate = variants[i]
                             .iter()
                             .enumerate()
-                            .filter_map(|(j, &field)| Some((j, field.largest_niche.as_ref()?)))
+                            .filter_map(|(j, field)| Some((j, field.largest_niche?)))
                             .max_by_key(|(_, niche)| niche.available(dl));
 
                         if let Some((field_index, niche, (niche_start, niche_scalar))) =
@@ -1078,31 +1078,24 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
                                 Abi::Uninhabited
                             } else {
                                 match st[i].abi {
-                                    Abi::Scalar(_) => Abi::Scalar(niche_scalar.clone()),
-                                    Abi::ScalarPair(ref first, ref second) => {
+                                    Abi::Scalar(_) => Abi::Scalar(niche_scalar),
+                                    Abi::ScalarPair(first, second) => {
                                         // We need to use scalar_unit to reset the
                                         // valid range to the maximal one for that
                                         // primitive, because only the niche is
                                         // guaranteed to be initialised, not the
                                         // other primitive.
                                         if offset.bytes() == 0 {
-                                            Abi::ScalarPair(
-                                                niche_scalar.clone(),
-                                                scalar_unit(second.value),
-                                            )
+                                            Abi::ScalarPair(niche_scalar, scalar_unit(second.value))
                                         } else {
-                                            Abi::ScalarPair(
-                                                scalar_unit(first.value),
-                                                niche_scalar.clone(),
-                                            )
+                                            Abi::ScalarPair(scalar_unit(first.value), niche_scalar)
                                         }
                                     }
                                     _ => Abi::Aggregate { sized: true },
                                 }
                             };
 
-                            let largest_niche =
-                                Niche::from_scalar(dl, offset, niche_scalar.clone());
+                            let largest_niche = Niche::from_scalar(dl, offset, niche_scalar);
 
                             niche_filling_layout = Some(Layout {
                                 variants: Variants::Multiple {
@@ -1273,7 +1266,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
                     }
                 }
 
-                let tag_mask = !0u128 >> (128 - ity.size().bits());
+                let tag_mask = ity.size().unsigned_int_max();
                 let tag = Scalar {
                     value: Int(ity, signed),
                     valid_range: WrappingRange {
@@ -1283,7 +1276,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
                 };
                 let mut abi = Abi::Aggregate { sized: true };
                 if tag.value.size(dl) == size {
-                    abi = Abi::Scalar(tag.clone());
+                    abi = Abi::Scalar(tag);
                 } else {
                     // Try to use a ScalarPair for all tagged enums.
                     let mut common_prim = None;
@@ -1303,7 +1296,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
                             }
                         };
                         let prim = match field.abi {
-                            Abi::Scalar(ref scalar) => scalar.value,
+                            Abi::Scalar(scalar) => scalar.value,
                             _ => {
                                 common_prim = None;
                                 break;
@@ -1323,7 +1316,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
                         }
                     }
                     if let Some((prim, offset)) = common_prim {
-                        let pair = self.scalar_pair(tag.clone(), scalar_unit(prim));
+                        let pair = self.scalar_pair(tag, scalar_unit(prim));
                         let pair_offsets = match pair.fields {
                             FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
                                 assert_eq!(memory_index, &[0, 1]);
@@ -1347,7 +1340,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
                     abi = Abi::Uninhabited;
                 }
 
-                let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag.clone());
+                let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag);
 
                 let tagged_layout = Layout {
                     variants: Variants::Multiple {
@@ -1372,8 +1365,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
                         // pick the layout with the larger niche; otherwise,
                         // pick tagged as it has simpler codegen.
                         cmp::min_by_key(tagged_layout, niche_filling_layout, |layout| {
-                            let niche_size =
-                                layout.largest_niche.as_ref().map_or(0, |n| n.available(dl));
+                            let niche_size = layout.largest_niche.map_or(0, |n| n.available(dl));
                             (layout.size, cmp::Reverse(niche_size))
                         })
                     }
@@ -1560,7 +1552,7 @@ fn generator_layout(
             value: Primitive::Int(discr_int, false),
             valid_range: WrappingRange { start: 0, end: max_discr },
         };
-        let tag_layout = self.tcx.intern_layout(Layout::scalar(self, tag.clone()));
+        let tag_layout = self.tcx.intern_layout(Layout::scalar(self, tag));
         let tag_layout = TyAndLayout { ty: discr_int_ty, layout: tag_layout };
 
         let promoted_layouts = ineligible_locals
@@ -1832,7 +1824,7 @@ fn record_layout_for_printing_outlined(&self, layout: TyAndLayout<'tcx>) {
                 }
             }
 
-            Variants::Multiple { ref tag, ref tag_encoding, .. } => {
+            Variants::Multiple { tag, ref tag_encoding, .. } => {
                 debug!(
                     "print-type-size `{:#?}` adt general variants def {}",
                     layout.ty,
@@ -2240,7 +2232,7 @@ fn field_ty_or_layout(
             i: usize,
         ) -> TyMaybeWithLayout<'tcx> {
             let tcx = cx.tcx();
-            let tag_layout = |tag: &Scalar| -> TyAndLayout<'tcx> {
+            let tag_layout = |tag: Scalar| -> TyAndLayout<'tcx> {
                 let layout = Layout::scalar(cx, tag.clone());
                 TyAndLayout { layout: tcx.intern_layout(layout), ty: tag.value.to_ty(tcx) }
             };
@@ -2329,7 +2321,7 @@ fn field_ty_or_layout(
                             .nth(i)
                             .unwrap(),
                     ),
-                    Variants::Multiple { ref tag, tag_field, .. } => {
+                    Variants::Multiple { tag, tag_field, .. } => {
                         if i == tag_field {
                             return TyMaybeWithLayout::TyAndLayout(tag_layout(tag));
                         }
@@ -2347,7 +2339,7 @@ fn field_ty_or_layout(
                         }
 
                         // Discriminant field for enums (where applicable).
-                        Variants::Multiple { ref tag, .. } => {
+                        Variants::Multiple { tag, .. } => {
                             assert_eq!(i, 0);
                             return TyMaybeWithLayout::TyAndLayout(tag_layout(tag));
                         }
@@ -2906,7 +2898,7 @@ fn new_internal(
 
         // Handle safe Rust thin and fat pointers.
         let adjust_for_rust_scalar = |attrs: &mut ArgAttributes,
-                                      scalar: &Scalar,
+                                      scalar: Scalar,
                                       layout: TyAndLayout<'tcx>,
                                       offset: Size,
                                       is_return: bool| {
@@ -2921,7 +2913,7 @@ fn new_internal(
                 return;
             }
 
-            if !scalar.valid_range.contains_zero() {
+            if !scalar.valid_range.contains(0) {
                 attrs.set(ArgAttribute::NonNull);
             }
 
index fddfd6e435c0550e586f0ffa732a35784ab33f99..cd1e38445ae8c7a4c12194b5eb38ae79009e82ea 100644 (file)
@@ -127,7 +127,7 @@ pub struct ResolverOutputs {
     pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
     pub maybe_unused_trait_imports: FxHashSet<LocalDefId>,
     pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
-    pub export_map: ExportMap<LocalDefId>,
+    pub export_map: ExportMap,
     pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
     /// Extern prelude entries. The value is `true` if the entry was introduced
     /// via `extern crate` item and not `--extern` option or compiler built-in.
index 1b8e94260b9b5d73f0228dc5cf7b1aaffd5d262d..8a2abb037579839342b8b99eb9cb9fc6622c7761 100644 (file)
@@ -45,18 +45,6 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-fn signed_min(size: Size) -> i128 {
-    size.sign_extend(1_u128 << (size.bits() - 1)) as i128
-}
-
-fn signed_max(size: Size) -> i128 {
-    i128::MAX >> (128 - size.bits())
-}
-
-fn unsigned_max(size: Size) -> u128 {
-    u128::MAX >> (128 - size.bits())
-}
-
 fn int_size_and_signed<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (Size, bool) {
     let (int, signed) = match *ty.kind() {
         Int(ity) => (Integer::from_int_ty(&tcx, ity), true),
@@ -74,8 +62,8 @@ pub fn wrap_incr(self, tcx: TyCtxt<'tcx>) -> Self {
     pub fn checked_add(self, tcx: TyCtxt<'tcx>, n: u128) -> (Self, bool) {
         let (size, signed) = int_size_and_signed(tcx, self.ty);
         let (val, oflo) = if signed {
-            let min = signed_min(size);
-            let max = signed_max(size);
+            let min = size.signed_int_min();
+            let max = size.signed_int_max();
             let val = size.sign_extend(self.val) as i128;
             assert!(n < (i128::MAX as u128));
             let n = n as i128;
@@ -86,7 +74,7 @@ pub fn checked_add(self, tcx: TyCtxt<'tcx>, n: u128) -> (Self, bool) {
             let val = size.truncate(val);
             (val, oflo)
         } else {
-            let max = unsigned_max(size);
+            let max = size.unsigned_int_max();
             let val = self.val;
             let oflo = val > max - n;
             let val = if oflo { n - (max - val) - 1 } else { val + n };
@@ -621,7 +609,8 @@ pub fn numeric_max_val(&'tcx self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const<
         let val = match self.kind() {
             ty::Int(_) | ty::Uint(_) => {
                 let (size, signed) = int_size_and_signed(tcx, self);
-                let val = if signed { signed_max(size) as u128 } else { unsigned_max(size) };
+                let val =
+                    if signed { size.signed_int_max() as u128 } else { size.unsigned_int_max() };
                 Some(val)
             }
             ty::Char => Some(std::char::MAX as u128),
@@ -640,7 +629,7 @@ pub fn numeric_min_val(&'tcx self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const<
         let val = match self.kind() {
             ty::Int(_) | ty::Uint(_) => {
                 let (size, signed) = int_size_and_signed(tcx, self);
-                let val = if signed { size.truncate(signed_min(size) as u128) } else { 0 };
+                let val = if signed { size.truncate(size.signed_int_min() as u128) } else { 0 };
                 Some(val)
             }
             ty::Char => Some(0),
index 68de1af613d9f20d7b2e1f18a5082ed8486f2a51..be0d5d2f1b2af5565a64c4cf4700525da4032c52 100644 (file)
@@ -494,9 +494,8 @@ fn limit_capture_mutability(
     // Helper to get a `-1` value of the appropriate type
     fn neg_1_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
         let param_ty = ty::ParamEnv::empty().and(ty);
-        let bits = self.tcx.layout_of(param_ty).unwrap().size.bits();
-        let n = (!0u128) >> (128 - bits);
-        let literal = ty::Const::from_bits(self.tcx, n, param_ty);
+        let size = self.tcx.layout_of(param_ty).unwrap().size;
+        let literal = ty::Const::from_bits(self.tcx, size.unsigned_int_max(), param_ty);
 
         self.literal_operand(span, literal)
     }
index ba94e15444a1905f5c7efcd3da76cca26eab0edd..4df073c40e22c318eb620685d295283cf0ba4a15 100644 (file)
@@ -900,10 +900,7 @@ fn traverse_candidate<'pat, 'tcx: 'pat, C, T, I>(
 struct Binding<'tcx> {
     span: Span,
     source: Place<'tcx>,
-    name: Symbol,
     var_id: HirId,
-    var_ty: Ty<'tcx>,
-    mutability: Mutability,
     binding_mode: BindingMode,
 }
 
@@ -2063,7 +2060,7 @@ fn ascribe_types<'b>(
                 source_info.span, ascription.source, ascription.user_ty,
             );
 
-            let user_ty = ascription.user_ty.clone().user_ty(
+            let user_ty = ascription.user_ty.user_ty(
                 &mut self.canonical_user_type_annotations,
                 ascription.source.ty(&self.local_decls, self.tcx).ty,
                 source_info.span,
index 1feb8b0d7a06d4d670606ad508537afe718fa858..4ce26cc8dff46a10f4ecde92cba0feb3833425ac 100644 (file)
@@ -176,17 +176,22 @@ fn simplify_match_pair<'pat>(
                 Ok(())
             }
 
-            PatKind::Binding { name, mutability, mode, var, ty, ref subpattern, is_primary: _ } => {
+            PatKind::Binding {
+                name: _,
+                mutability: _,
+                mode,
+                var,
+                ty: _,
+                ref subpattern,
+                is_primary: _,
+            } => {
                 if let Ok(place_resolved) =
                     match_pair.place.clone().try_upvars_resolved(self.tcx, self.typeck_results)
                 {
                     candidate.bindings.push(Binding {
-                        name,
-                        mutability,
                         span: match_pair.pattern.span,
                         source: place_resolved.into_place(self.tcx, self.typeck_results),
                         var_id: var,
-                        var_ty: ty,
                         binding_mode: mode,
                     });
                 }
index 0a760a740dcaea5801a8b4bcb854d19ba6758d50..0ee740a6463593de96e159b1ffd434919aaa75d8 100644 (file)
@@ -47,10 +47,12 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
     // Ensure unsafeck is ran before we steal the THIR.
     match def {
         ty::WithOptConstParam { did, const_param_did: Some(const_param_did) } => {
-            tcx.ensure().thir_check_unsafety_for_const_arg((did, const_param_did))
+            tcx.ensure().thir_check_unsafety_for_const_arg((did, const_param_did));
+            tcx.ensure().thir_abstract_const_of_const_arg((did, const_param_did));
         }
         ty::WithOptConstParam { did, const_param_did: None } => {
-            tcx.ensure().thir_check_unsafety(did)
+            tcx.ensure().thir_check_unsafety(did);
+            tcx.ensure().thir_abstract_const(did);
         }
     }
 
index bd8d14fcd012c2ec5965940a517e50b568c234ef..b74208edafea6172643d9c02f41a5a8cfb7679d2 100644 (file)
@@ -118,9 +118,6 @@ struct Scope {
     /// the region span of this scope within source code.
     region_scope: region::Scope,
 
-    /// the span of that region_scope
-    region_scope_span: Span,
-
     /// set of places to drop when exiting this scope. This starts
     /// out empty but grows as variables are declared during the
     /// building process. This is a stack, so we always drop from the
@@ -420,7 +417,6 @@ fn push_scope(&mut self, region_scope: (region::Scope, SourceInfo), vis_scope: S
         self.scopes.push(Scope {
             source_scope: vis_scope,
             region_scope: region_scope.0,
-            region_scope_span: region_scope.1.span,
             drops: vec![],
             moved_locals: vec![],
             cached_unwind_block: None,
index 05a5fcef16ae53adb459e44413e0669f459ccfb5..0e82b187201422d4983f105718266d74e946fb1d 100644 (file)
@@ -1,5 +1,5 @@
 use crate::build::ExprCategory;
-use crate::thir::visit::{self, Visitor};
+use rustc_middle::thir::visit::{self, Visitor};
 
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
index e5123d8ef0c997e972d34768e5be1689b8546157..ddbe1b0b69c1eb9dba9686063215b7c4086f9618 100644 (file)
@@ -11,4 +11,3 @@
 crate mod pattern;
 
 mod util;
-pub mod visit;
diff --git a/compiler/rustc_mir_build/src/thir/visit.rs b/compiler/rustc_mir_build/src/thir/visit.rs
deleted file mode 100644 (file)
index 51c371b..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-use rustc_middle::thir::{self, *};
-use rustc_middle::ty::Const;
-
-pub trait Visitor<'a, 'tcx: 'a>: Sized {
-    fn thir(&self) -> &'a Thir<'tcx>;
-
-    fn visit_expr(&mut self, expr: &Expr<'tcx>) {
-        walk_expr(self, expr);
-    }
-
-    fn visit_stmt(&mut self, stmt: &Stmt<'tcx>) {
-        walk_stmt(self, stmt);
-    }
-
-    fn visit_block(&mut self, block: &Block) {
-        walk_block(self, block);
-    }
-
-    fn visit_arm(&mut self, arm: &Arm<'tcx>) {
-        walk_arm(self, arm);
-    }
-
-    fn visit_pat(&mut self, pat: &Pat<'tcx>) {
-        walk_pat(self, pat);
-    }
-
-    fn visit_const(&mut self, _cnst: &'tcx Const<'tcx>) {}
-}
-
-pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Expr<'tcx>) {
-    use ExprKind::*;
-    match expr.kind {
-        Scope { value, region_scope: _, lint_level: _ } => {
-            visitor.visit_expr(&visitor.thir()[value])
-        }
-        Box { value } => visitor.visit_expr(&visitor.thir()[value]),
-        If { cond, then, else_opt, if_then_scope: _ } => {
-            visitor.visit_expr(&visitor.thir()[cond]);
-            visitor.visit_expr(&visitor.thir()[then]);
-            if let Some(else_expr) = else_opt {
-                visitor.visit_expr(&visitor.thir()[else_expr]);
-            }
-        }
-        Call { fun, ref args, ty: _, from_hir_call: _, fn_span: _ } => {
-            visitor.visit_expr(&visitor.thir()[fun]);
-            for &arg in &**args {
-                visitor.visit_expr(&visitor.thir()[arg]);
-            }
-        }
-        Deref { arg } => visitor.visit_expr(&visitor.thir()[arg]),
-        Binary { lhs, rhs, op: _ } | LogicalOp { lhs, rhs, op: _ } => {
-            visitor.visit_expr(&visitor.thir()[lhs]);
-            visitor.visit_expr(&visitor.thir()[rhs]);
-        }
-        Unary { arg, op: _ } => visitor.visit_expr(&visitor.thir()[arg]),
-        Cast { source } => visitor.visit_expr(&visitor.thir()[source]),
-        Use { source } => visitor.visit_expr(&visitor.thir()[source]),
-        NeverToAny { source } => visitor.visit_expr(&visitor.thir()[source]),
-        Pointer { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]),
-        Let { expr, .. } => {
-            visitor.visit_expr(&visitor.thir()[expr]);
-        }
-        Loop { body } => visitor.visit_expr(&visitor.thir()[body]),
-        Match { scrutinee, ref arms } => {
-            visitor.visit_expr(&visitor.thir()[scrutinee]);
-            for &arm in &**arms {
-                visitor.visit_arm(&visitor.thir()[arm]);
-            }
-        }
-        Block { ref body } => visitor.visit_block(body),
-        Assign { lhs, rhs } | AssignOp { lhs, rhs, op: _ } => {
-            visitor.visit_expr(&visitor.thir()[lhs]);
-            visitor.visit_expr(&visitor.thir()[rhs]);
-        }
-        Field { lhs, name: _ } => visitor.visit_expr(&visitor.thir()[lhs]),
-        Index { lhs, index } => {
-            visitor.visit_expr(&visitor.thir()[lhs]);
-            visitor.visit_expr(&visitor.thir()[index]);
-        }
-        VarRef { id: _ } | UpvarRef { closure_def_id: _, var_hir_id: _ } => {}
-        Borrow { arg, borrow_kind: _ } => visitor.visit_expr(&visitor.thir()[arg]),
-        AddressOf { arg, mutability: _ } => visitor.visit_expr(&visitor.thir()[arg]),
-        Break { value, label: _ } => {
-            if let Some(value) = value {
-                visitor.visit_expr(&visitor.thir()[value])
-            }
-        }
-        Continue { label: _ } => {}
-        Return { value } => {
-            if let Some(value) = value {
-                visitor.visit_expr(&visitor.thir()[value])
-            }
-        }
-        ConstBlock { value } => visitor.visit_const(value),
-        Repeat { value, count } => {
-            visitor.visit_expr(&visitor.thir()[value]);
-            visitor.visit_const(count);
-        }
-        Array { ref fields } | Tuple { ref fields } => {
-            for &field in &**fields {
-                visitor.visit_expr(&visitor.thir()[field]);
-            }
-        }
-        Adt(box thir::Adt {
-            ref fields,
-            ref base,
-            adt_def: _,
-            variant_index: _,
-            substs: _,
-            user_ty: _,
-        }) => {
-            for field in &**fields {
-                visitor.visit_expr(&visitor.thir()[field.expr]);
-            }
-            if let Some(base) = base {
-                visitor.visit_expr(&visitor.thir()[base.base]);
-            }
-        }
-        PlaceTypeAscription { source, user_ty: _ } | ValueTypeAscription { source, user_ty: _ } => {
-            visitor.visit_expr(&visitor.thir()[source])
-        }
-        Closure { closure_id: _, substs: _, upvars: _, movability: _, fake_reads: _ } => {}
-        Literal { literal, user_ty: _, const_id: _ } => visitor.visit_const(literal),
-        StaticRef { literal, def_id: _ } => visitor.visit_const(literal),
-        InlineAsm { ref operands, template: _, options: _, line_spans: _ } => {
-            for op in &**operands {
-                use InlineAsmOperand::*;
-                match op {
-                    In { expr, reg: _ }
-                    | Out { expr: Some(expr), reg: _, late: _ }
-                    | InOut { expr, reg: _, late: _ }
-                    | SymFn { expr } => visitor.visit_expr(&visitor.thir()[*expr]),
-                    SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
-                        visitor.visit_expr(&visitor.thir()[*in_expr]);
-                        if let Some(out_expr) = out_expr {
-                            visitor.visit_expr(&visitor.thir()[*out_expr]);
-                        }
-                    }
-                    Out { expr: None, reg: _, late: _ }
-                    | Const { value: _, span: _ }
-                    | SymStatic { def_id: _ } => {}
-                }
-            }
-        }
-        ThreadLocalRef(_) => {}
-        LlvmInlineAsm { ref outputs, ref inputs, asm: _ } => {
-            for &out_expr in &**outputs {
-                visitor.visit_expr(&visitor.thir()[out_expr]);
-            }
-            for &in_expr in &**inputs {
-                visitor.visit_expr(&visitor.thir()[in_expr]);
-            }
-        }
-        Yield { value } => visitor.visit_expr(&visitor.thir()[value]),
-    }
-}
-
-pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stmt<'tcx>) {
-    match &stmt.kind {
-        StmtKind::Expr { expr, scope: _ } => visitor.visit_expr(&visitor.thir()[*expr]),
-        StmtKind::Let {
-            initializer,
-            remainder_scope: _,
-            init_scope: _,
-            ref pattern,
-            lint_level: _,
-        } => {
-            if let Some(init) = initializer {
-                visitor.visit_expr(&visitor.thir()[*init]);
-            }
-            visitor.visit_pat(pattern);
-        }
-    }
-}
-
-pub fn walk_block<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, block: &Block) {
-    for &stmt in &*block.stmts {
-        visitor.visit_stmt(&visitor.thir()[stmt]);
-    }
-    if let Some(expr) = block.expr {
-        visitor.visit_expr(&visitor.thir()[expr]);
-    }
-}
-
-pub fn walk_arm<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, arm: &Arm<'tcx>) {
-    match arm.guard {
-        Some(Guard::If(expr)) => visitor.visit_expr(&visitor.thir()[expr]),
-        Some(Guard::IfLet(ref pat, expr)) => {
-            visitor.visit_pat(pat);
-            visitor.visit_expr(&visitor.thir()[expr]);
-        }
-        None => {}
-    }
-    visitor.visit_pat(&arm.pattern);
-    visitor.visit_expr(&visitor.thir()[arm.body]);
-}
-
-pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'tcx>) {
-    use PatKind::*;
-    match pat.kind.as_ref() {
-        AscribeUserType { subpattern, ascription: _ }
-        | Deref { subpattern }
-        | Binding {
-            subpattern: Some(subpattern),
-            mutability: _,
-            mode: _,
-            var: _,
-            ty: _,
-            is_primary: _,
-            name: _,
-        } => visitor.visit_pat(&subpattern),
-        Binding { .. } | Wild => {}
-        Variant { subpatterns, adt_def: _, substs: _, variant_index: _ } | Leaf { subpatterns } => {
-            for subpattern in subpatterns {
-                visitor.visit_pat(&subpattern.pattern);
-            }
-        }
-        Constant { value } => visitor.visit_const(value),
-        Range(range) => {
-            visitor.visit_const(range.lo);
-            visitor.visit_const(range.hi);
-        }
-        Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
-            for subpattern in prefix {
-                visitor.visit_pat(&subpattern);
-            }
-            if let Some(pat) = slice {
-                visitor.visit_pat(pat);
-            }
-            for subpattern in suffix {
-                visitor.visit_pat(&subpattern);
-            }
-        }
-        Or { pats } => {
-            for pat in pats {
-                visitor.visit_pat(&pat);
-            }
-        }
-    };
-}
index cea465ea1ed9dc423045c5a80d5ffed630310173..407ba739463013ddb2346298efcc0774134141d9 100644 (file)
@@ -342,7 +342,7 @@ fn gather_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
             | Rvalue::AddressOf(..)
             | Rvalue::Discriminant(..)
             | Rvalue::Len(..)
-            | Rvalue::NullaryOp(NullOp::SizeOf, _)
+            | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _)
             | Rvalue::NullaryOp(NullOp::Box, _) => {
                 // This returns an rvalue with uninitialized contents. We can't
                 // move out of it here because it is an rvalue - assignments always
index 855dcbc431b1eca3f57c50bfda93a1ac5e853d14..1abb64219f6e97dee0a68d16da9e8e761152ce26 100644 (file)
@@ -5,6 +5,7 @@
 use rustc_middle::ty::layout;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_target::spec::abi::Abi;
+use rustc_target::spec::PanicStrategy;
 
 /// A pass that runs which is targeted at ensuring that codegen guarantees about
 /// unwinding are upheld for compilations of panic=abort programs.
@@ -82,10 +83,11 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
                     };
                     layout::fn_can_unwind(tcx, flags, sig.abi())
                 }
-                TerminatorKind::Drop { .. }
-                | TerminatorKind::DropAndReplace { .. }
-                | TerminatorKind::Assert { .. }
-                | TerminatorKind::FalseUnwind { .. } => {
+                TerminatorKind::Drop { .. } | TerminatorKind::DropAndReplace { .. } => {
+                    tcx.sess.opts.debugging_opts.panic_in_drop == PanicStrategy::Unwind
+                        && layout::fn_can_unwind(tcx, CodegenFnAttrFlags::empty(), Abi::Rust)
+                }
+                TerminatorKind::Assert { .. } | TerminatorKind::FalseUnwind { .. } => {
                     layout::fn_can_unwind(tcx, CodegenFnAttrFlags::empty(), Abi::Rust)
                 }
                 _ => continue,
index 6043606c37957da13fb600d9926ccdb49181a21a..b9e3c058ad7ec355e98206308bc31bb0e368cc5b 100644 (file)
@@ -263,7 +263,7 @@ fn inject_counters(&'a mut self) {
         }
 
         if let Err(e) = result {
-            bug!("Error processing: {:?}: {:?}", self.mir_body.source.def_id(), e)
+            bug!("Error processing: {:?}: {:?}", self.mir_body.source.def_id(), e.message)
         };
 
         // Depending on current `debug_options()`, `alert_on_unused_expressions()` could panic, so
index 2ea2e06029d679176e20719eab21f281c361eaa3..cc525a4d6b91ca1a1ab9e491b4086c57a6c46885 100644 (file)
@@ -196,7 +196,11 @@ pub fn current_macro(&self) -> Option<Symbol> {
     /// body_span), returns the macro name symbol.
     pub fn visible_macro(&self, body_span: Span) -> Option<Symbol> {
         if let Some(current_macro) = self.current_macro() {
-            if self.expn_span.parent().unwrap_or_else(|| bug!("macro must have a parent")).ctxt()
+            if self
+                .expn_span
+                .parent_callsite()
+                .unwrap_or_else(|| bug!("macro must have a parent"))
+                .ctxt()
                 == body_span.ctxt()
             {
                 return Some(current_macro);
index 9a074c10ef405bf4c80e8a546f320134eeb6fafa..90d7cbee976d0d1dcbcec069bcb6eb627da1eb9f 100644 (file)
@@ -306,7 +306,6 @@ fn mir_promoted(
     // this point, before we steal the mir-const result.
     // Also this means promotion can rely on all const checks having been done.
     let _ = tcx.mir_const_qualif_opt_const_arg(def);
-    let _ = tcx.mir_abstract_const_opt_const_arg(def.to_global());
     let mut body = tcx.mir_const(def).steal();
 
     let mut required_consts = Vec::new();
index 2f89b041c27b1f7062502f547ef5efbb840ec0fa..5848163af72fc22b0cc2d09f56f5f308e445852d 100644 (file)
@@ -92,14 +92,19 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
                         // since their semantics depend on the value of overflow-checks flag used
                         // during codegen. Issue #35310.
                     }
-                    sym::size_of => {
+                    sym::size_of | sym::min_align_of => {
                         if let Some((destination, target)) = *destination {
                             let tp_ty = substs.type_at(0);
+                            let null_op = match intrinsic_name {
+                                sym::size_of => NullOp::SizeOf,
+                                sym::min_align_of => NullOp::AlignOf,
+                                _ => bug!("unexpected intrinsic"),
+                            };
                             block.statements.push(Statement {
                                 source_info: terminator.source_info,
                                 kind: StatementKind::Assign(Box::new((
                                     destination,
-                                    Rvalue::NullaryOp(NullOp::SizeOf, tp_ty),
+                                    Rvalue::NullaryOp(null_op, tp_ty),
                                 ))),
                             });
                             terminator.kind = TerminatorKind::Goto { target };
index 30de374a2d8221ddb5cbed5138302b15f45d2cac..a2cce9f1eda076e12fc6f2f43b0465a5c4e62507 100644 (file)
@@ -75,13 +75,11 @@ fn lower_slice_len_call<'tcx>(
                     let deref_arg = tcx.mk_place_deref(arg);
                     let r_value = Rvalue::Len(deref_arg);
                     let len_statement_kind = StatementKind::Assign(Box::new((*dest, r_value)));
-                    let add_statement = Statement {
-                        kind: len_statement_kind,
-                        source_info: terminator.source_info.clone(),
-                    };
+                    let add_statement =
+                        Statement { kind: len_statement_kind, source_info: terminator.source_info };
 
                     // modify terminator into simple Goto
-                    let new_terminator_kind = TerminatorKind::Goto { target: bb.clone() };
+                    let new_terminator_kind = TerminatorKind::Goto { target: *bb };
 
                     let patch = SliceLenPatchInformation { add_statement, new_terminator_kind };
 
index 08615e7be9ca25f44cf6638a530d56b80f3fa167..af41a99ada4dd57997756c1f318b3a38c79741c5 100644 (file)
@@ -131,7 +131,7 @@ fn maybe_source_file_to_parser(
     let mut parser = stream_to_parser(sess, stream, None);
     parser.unclosed_delims = unclosed_delims;
     if parser.token == token::Eof {
-        parser.token.span = Span::new(end_pos, end_pos, parser.token.span.ctxt());
+        parser.token.span = Span::new(end_pos, end_pos, parser.token.span.ctxt(), None);
     }
 
     Ok(parser)
index 9f06bdcc135ba3d626d97fb418ffd18df84e859c..568682cc3e4e0498228dd4a1319ebc4ccf8a584b 100644 (file)
@@ -34,7 +34,7 @@ pub struct AttrWrapper {
 
 // This struct is passed around very frequently,
 // so make sure it doesn't accidentally get larger
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(AttrWrapper, 16);
 
 impl AttrWrapper {
index 05156745105a1c0a10b839720f00c8a957d153ef..dc80dab8c6c5f9d55f4c480a1ae932966fd74141 100644 (file)
@@ -1,9 +1,12 @@
 use super::pat::{RecoverColon, RecoverComma, PARAM_EXPECTED};
 use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
-use super::{AttrWrapper, BlockMode, ForceCollect, Parser, PathStyle, Restrictions, TokenType};
+use super::{
+    AttrWrapper, BlockMode, ClosureSpans, ForceCollect, Parser, PathStyle, Restrictions, TokenType,
+};
 use super::{SemiColonMode, SeqSep, TokenExpectType, TrailingToken};
 use crate::maybe_recover_from_interpolated_ty_qpath;
 
+use ast::token::DelimToken;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Token, TokenKind};
 use rustc_ast::tokenstream::Spacing;
@@ -91,6 +94,8 @@ impl<'a> Parser<'a> {
     /// Parses an expression.
     #[inline]
     pub fn parse_expr(&mut self) -> PResult<'a, P<Expr>> {
+        self.current_closure.take();
+
         self.parse_expr_res(Restrictions::empty(), None)
     }
 
@@ -1736,7 +1741,7 @@ fn parse_closure_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
         let capture_clause = self.parse_capture_clause()?;
         let decl = self.parse_fn_block_decl()?;
         let decl_hi = self.prev_token.span;
-        let body = match decl.output {
+        let mut body = match decl.output {
             FnRetTy::Default(_) => {
                 let restrictions = self.restrictions - Restrictions::STMT_EXPR;
                 self.parse_expr_res(restrictions, None)?
@@ -1753,11 +1758,28 @@ fn parse_closure_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
             self.sess.gated_spans.gate(sym::async_closure, span);
         }
 
-        Ok(self.mk_expr(
+        if self.token.kind == TokenKind::Semi && self.token_cursor.frame.delim == DelimToken::Paren
+        {
+            // It is likely that the closure body is a block but where the
+            // braces have been removed. We will recover and eat the next
+            // statements later in the parsing process.
+            body = self.mk_expr_err(body.span);
+        }
+
+        let body_span = body.span;
+
+        let closure = self.mk_expr(
             lo.to(body.span),
             ExprKind::Closure(capture_clause, asyncness, movability, decl, body, lo.to(decl_hi)),
             attrs,
-        ))
+        );
+
+        // Disable recovery for closure body
+        let spans =
+            ClosureSpans { whole_closure: closure.span, closing_pipe: decl_hi, body: body_span };
+        self.current_closure = Some(spans);
+
+        Ok(closure)
     }
 
     /// Parses an optional `move` prefix to a closure-like construct.
index c4419e995edac84940900418d87186aecdb89235..5c701fefd17de95b0d95dfaeaa64f625f61f27e2 100644 (file)
@@ -142,6 +142,17 @@ pub struct Parser<'a> {
     /// If present, this `Parser` is not parsing Rust code but rather a macro call.
     subparser_name: Option<&'static str>,
     capture_state: CaptureState,
+    /// This allows us to recover when the user forget to add braces around
+    /// multiple statements in the closure body.
+    pub current_closure: Option<ClosureSpans>,
+}
+
+/// Stores span informations about a closure.
+#[derive(Clone)]
+pub struct ClosureSpans {
+    pub whole_closure: Span,
+    pub closing_pipe: Span,
+    pub body: Span,
 }
 
 /// Indicates a range of tokens that should be replaced by
@@ -440,6 +451,7 @@ pub fn new(
                 replace_ranges: Vec::new(),
                 inner_attr_ranges: Default::default(),
             },
+            current_closure: None,
         };
 
         // Make parser point to the first token.
@@ -761,8 +773,11 @@ fn parse_seq_to_before_tokens<T>(
                     first = false;
                 } else {
                     match self.expect(t) {
-                        Ok(false) => {}
+                        Ok(false) => {
+                            self.current_closure.take();
+                        }
                         Ok(true) => {
+                            self.current_closure.take();
                             recovered = true;
                             break;
                         }
@@ -770,10 +785,29 @@ fn parse_seq_to_before_tokens<T>(
                             let sp = self.prev_token.span.shrink_to_hi();
                             let token_str = pprust::token_kind_to_string(t);
 
-                            // Attempt to keep parsing if it was a similar separator.
-                            if let Some(ref tokens) = t.similar_tokens() {
-                                if tokens.contains(&self.token.kind) && !unclosed_delims {
-                                    self.bump();
+                            match self.current_closure.take() {
+                                Some(closure_spans) if self.token.kind == TokenKind::Semi => {
+                                    // Finding a semicolon instead of a comma
+                                    // after a closure body indicates that the
+                                    // closure body may be a block but the user
+                                    // forgot to put braces around its
+                                    // statements.
+
+                                    self.recover_missing_braces_around_closure_body(
+                                        closure_spans,
+                                        expect_err,
+                                    )?;
+
+                                    continue;
+                                }
+
+                                _ => {
+                                    // Attempt to keep parsing if it was a similar separator.
+                                    if let Some(ref tokens) = t.similar_tokens() {
+                                        if tokens.contains(&self.token.kind) && !unclosed_delims {
+                                            self.bump();
+                                        }
+                                    }
                                 }
                             }
 
@@ -839,6 +873,65 @@ fn parse_seq_to_before_tokens<T>(
         Ok((v, trailing, recovered))
     }
 
+    fn recover_missing_braces_around_closure_body(
+        &mut self,
+        closure_spans: ClosureSpans,
+        mut expect_err: DiagnosticBuilder<'_>,
+    ) -> PResult<'a, ()> {
+        let initial_semicolon = self.token.span;
+
+        while self.eat(&TokenKind::Semi) {
+            let _ = self.parse_stmt(ForceCollect::Yes)?;
+        }
+
+        expect_err.set_primary_message(
+            "closure bodies that contain statements must be surrounded by braces",
+        );
+
+        let preceding_pipe_span = closure_spans.closing_pipe;
+        let following_token_span = self.token.span;
+
+        let mut first_note = MultiSpan::from(vec![initial_semicolon]);
+        first_note.push_span_label(
+            initial_semicolon,
+            "this `;` turns the preceding closure into a statement".to_string(),
+        );
+        first_note.push_span_label(
+            closure_spans.body,
+            "this expression is a statement because of the trailing semicolon".to_string(),
+        );
+        expect_err.span_note(first_note, "statement found outside of a block");
+
+        let mut second_note = MultiSpan::from(vec![closure_spans.whole_closure]);
+        second_note.push_span_label(
+            closure_spans.whole_closure,
+            "this is the parsed closure...".to_string(),
+        );
+        second_note.push_span_label(
+            following_token_span,
+            "...but likely you meant the closure to end here".to_string(),
+        );
+        expect_err.span_note(second_note, "the closure body may be incorrectly delimited");
+
+        expect_err.set_span(vec![preceding_pipe_span, following_token_span]);
+
+        let opening_suggestion_str = " {".to_string();
+        let closing_suggestion_str = "}".to_string();
+
+        expect_err.multipart_suggestion(
+            "try adding braces",
+            vec![
+                (preceding_pipe_span.shrink_to_hi(), opening_suggestion_str),
+                (following_token_span.shrink_to_lo(), closing_suggestion_str),
+            ],
+            Applicability::MaybeIncorrect,
+        );
+
+        expect_err.emit();
+
+        Ok(())
+    }
+
     /// Parses a sequence, not including the closing delimiter. The function
     /// `f` must consume tokens until reaching the next separator or
     /// closing bracket.
index 25ad00aaf1f753caa8f98f37224d898d5e1528ee..0a3093757166afee7641ddea25449c5322b27b17 100644 (file)
@@ -239,7 +239,69 @@ fn mark_live_symbols(&mut self) {
         }
     }
 
+    /// Automatically generated items marked with `rustc_trivial_field_reads`
+    /// will be ignored for the purposes of dead code analysis (see PR #85200
+    /// for discussion).
+    fn should_ignore_item(&self, def_id: DefId) -> bool {
+        if !self.tcx.has_attr(def_id, sym::automatically_derived)
+            && !self
+                .tcx
+                .impl_of_method(def_id)
+                .map_or(false, |impl_id| self.tcx.has_attr(impl_id, sym::automatically_derived))
+        {
+            return false;
+        }
+
+        let has_attr = |def_id| self.tcx.has_attr(def_id, sym::rustc_trivial_field_reads);
+
+        if has_attr(def_id) {
+            return true;
+        }
+
+        if let Some(impl_of) = self.tcx.impl_of_method(def_id) {
+            if has_attr(impl_of) {
+                return true;
+            }
+
+            if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of) {
+                if has_attr(trait_of) {
+                    return true;
+                }
+
+                if let Some(method_ident) = self.tcx.opt_item_name(def_id) {
+                    if let Some(trait_method) = self
+                        .tcx
+                        .associated_items(trait_of)
+                        .find_by_name_and_kind(self.tcx, method_ident, ty::AssocKind::Fn, trait_of)
+                    {
+                        if has_attr(trait_method.def_id) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        } else if let Some(trait_of) = self.tcx.trait_of_item(def_id) {
+            if has_attr(trait_of) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     fn visit_node(&mut self, node: Node<'tcx>) {
+        if let Some(item_def_id) = match node {
+            Node::Item(hir::Item { def_id, .. })
+            | Node::ForeignItem(hir::ForeignItem { def_id, .. })
+            | Node::TraitItem(hir::TraitItem { def_id, .. })
+            | Node::ImplItem(hir::ImplItem { def_id, .. }) => Some(def_id.to_def_id()),
+            _ => None,
+        } {
+            if self.should_ignore_item(item_def_id) {
+                return;
+            }
+        }
+
         let had_repr_c = self.repr_has_repr_c;
         let had_inherited_pub_visibility = self.inherited_pub_visibility;
         let had_pub_visibility = self.pub_visibility;
index ab9bfea96943f3eafe4505a4c7660d61bdfdf205..0d7abeba1a703c003cfbb13c05eb276d7c4c76b8 100644 (file)
@@ -775,7 +775,7 @@ fn propagate_through_block(&mut self, blk: &hir::Block<'_>, succ: LiveNode) -> L
         if blk.targeted_by_break {
             self.break_ln.insert(blk.hir_id, succ);
         }
-        let succ = self.propagate_through_opt_expr(blk.expr.as_deref(), succ);
+        let succ = self.propagate_through_opt_expr(blk.expr, succ);
         blk.stmts.iter().rev().fold(succ, |succ, stmt| self.propagate_through_stmt(stmt, succ))
     }
 
@@ -796,7 +796,7 @@ fn propagate_through_stmt(&mut self, stmt: &hir::Stmt<'_>, succ: LiveNode) -> Li
                 // initialization, which is mildly more complex than checking
                 // once at the func header but otherwise equivalent.
 
-                let succ = self.propagate_through_opt_expr(local.init.as_deref(), succ);
+                let succ = self.propagate_through_opt_expr(local.init, succ);
                 self.define_bindings_in_pat(&local.pat, succ)
             }
             hir::StmtKind::Item(..) => succ,
index 08702cad41c8b92b5e0a80676f16dd22d6e5b6c0..5fc8e230d72a3eba67aca78d8a258115f9d21e31 100644 (file)
@@ -812,7 +812,7 @@ fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
         resolve_expr(self, ex);
     }
     fn visit_local(&mut self, l: &'tcx Local<'tcx>) {
-        resolve_local(self, Some(&l.pat), l.init.as_deref());
+        resolve_local(self, Some(&l.pat), l.init);
     }
 }
 
index 35e25e52dc5f9f1e2fc12b492055eff4eeb9dbd3..391e43054239d2d9929acd6c89ab01eb9989a357 100644 (file)
@@ -19,8 +19,8 @@
 use rustc_middle::bug;
 use rustc_middle::hir::map::Map;
 use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
-use rustc_middle::mir::abstract_const::Node as ACNode;
 use rustc_middle::span_bug;
+use rustc_middle::thir::abstract_const::Node as ACNode;
 use rustc_middle::ty::fold::TypeVisitor;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::subst::{InternalSubsts, Subst};
index 5c2803c67e73fca87c75741741946820689356e2..bfd36bfb2db2321902c5c09ba6bcdc14d44cdd8f 100644 (file)
@@ -9,6 +9,7 @@
 use rustc_middle::dep_graph::{DepNode, DepNodeIndex, SerializedDepNodeIndex};
 use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
 use rustc_middle::mir::{self, interpret};
+use rustc_middle::thir;
 use rustc_middle::ty::codec::{RefDecodable, TyDecoder, TyEncoder};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_query_system::dep_graph::DepContext;
@@ -23,7 +24,7 @@
 };
 use rustc_span::source_map::{SourceMap, StableSourceFileId};
 use rustc_span::CachingSourceMapView;
-use rustc_span::{BytePos, ExpnData, ExpnHash, SourceFile, Span, DUMMY_SP};
+use rustc_span::{BytePos, ExpnData, ExpnHash, Pos, SourceFile, Span};
 use std::collections::hash_map::Entry;
 use std::mem;
 
@@ -33,6 +34,7 @@
 const TAG_FULL_SPAN: u8 = 0;
 // A partial span with no location information, encoded only with a `SyntaxContext`
 const TAG_PARTIAL_SPAN: u8 = 1;
+const TAG_RELATIVE_SPAN: u8 = 2;
 
 const TAG_SYNTAX_CONTEXT: u8 = 0;
 const TAG_EXPN_DATA: u8 = 1;
@@ -829,11 +831,26 @@ fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
 
 impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
     fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
+        let ctxt = SyntaxContext::decode(decoder)?;
+        let parent = Option::<LocalDefId>::decode(decoder)?;
         let tag: u8 = Decodable::decode(decoder)?;
 
         if tag == TAG_PARTIAL_SPAN {
-            let ctxt = SyntaxContext::decode(decoder)?;
-            return Ok(DUMMY_SP.with_ctxt(ctxt));
+            return Ok(Span::new(BytePos(0), BytePos(0), ctxt, parent));
+        } else if tag == TAG_RELATIVE_SPAN {
+            let dlo = u32::decode(decoder)?;
+            let dto = u32::decode(decoder)?;
+
+            let enclosing =
+                decoder.tcx.definitions_untracked().def_span(parent.unwrap()).data_untracked();
+            let span = Span::new(
+                enclosing.lo + BytePos::from_u32(dlo),
+                enclosing.lo + BytePos::from_u32(dto),
+                ctxt,
+                parent,
+            );
+
+            return Ok(span);
         } else {
             debug_assert_eq!(tag, TAG_FULL_SPAN);
         }
@@ -842,13 +859,12 @@ fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
         let line_lo = usize::decode(decoder)?;
         let col_lo = BytePos::decode(decoder)?;
         let len = BytePos::decode(decoder)?;
-        let ctxt = SyntaxContext::decode(decoder)?;
 
         let file_lo = decoder.file_index_to_file(file_lo_index);
         let lo = file_lo.lines[line_lo - 1] + col_lo;
         let hi = lo + len;
 
-        Ok(Span::new(lo, hi, ctxt))
+        Ok(Span::new(lo, hi, ctxt, parent))
     }
 }
 
@@ -906,7 +922,7 @@ fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
     }
 }
 
-impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [mir::abstract_const::Node<'tcx>] {
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [thir::abstract_const::Node<'tcx>] {
     fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
         RefDecodable::decode(d)
     }
@@ -1008,10 +1024,22 @@ impl<'a, 'tcx, E> Encodable<CacheEncoder<'a, 'tcx, E>> for Span
     E: 'a + OpaqueEncoder,
 {
     fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
-        let span_data = self.data();
-        if self.is_dummy() {
-            TAG_PARTIAL_SPAN.encode(s)?;
-            return span_data.ctxt.encode(s);
+        let span_data = self.data_untracked();
+        span_data.ctxt.encode(s)?;
+        span_data.parent.encode(s)?;
+
+        if span_data.is_dummy() {
+            return TAG_PARTIAL_SPAN.encode(s);
+        }
+
+        if let Some(parent) = span_data.parent {
+            let enclosing = s.tcx.definitions_untracked().def_span(parent).data_untracked();
+            if enclosing.contains(span_data) {
+                TAG_RELATIVE_SPAN.encode(s)?;
+                (span_data.lo - enclosing.lo).to_u32().encode(s)?;
+                (span_data.hi - enclosing.lo).to_u32().encode(s)?;
+                return Ok(());
+            }
         }
 
         let pos = s.source_map.byte_pos_to_line_and_col(span_data.lo);
@@ -1021,8 +1049,7 @@ fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
         };
 
         if partial_span {
-            TAG_PARTIAL_SPAN.encode(s)?;
-            return span_data.ctxt.encode(s);
+            return TAG_PARTIAL_SPAN.encode(s);
         }
 
         let (file_lo, line_lo, col_lo) = pos.unwrap();
@@ -1035,8 +1062,7 @@ fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> {
         source_file_index.encode(s)?;
         line_lo.encode(s)?;
         col_lo.encode(s)?;
-        len.encode(s)?;
-        span_data.ctxt.encode(s)
+        len.encode(s)
     }
 }
 
index 9c3dad8bd63499caa9204a38ea434506dcb19feb..e589d16992f6c22a43dee49c24d421ae17f21c0d 100644 (file)
@@ -11,6 +11,7 @@
 use parking_lot::Mutex;
 use smallvec::{smallvec, SmallVec};
 use std::collections::hash_map::Entry;
+use std::fmt::Debug;
 use std::hash::Hash;
 use std::marker::PhantomData;
 use std::sync::atomic::Ordering::Relaxed;
@@ -208,89 +209,99 @@ pub fn with_ignore<OP, R>(&self, op: OP) -> R
     ///   `arg` parameter.
     ///
     /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/incremental-compilation.html
-    pub fn with_task<Ctxt: HasDepContext<DepKind = K>, A, R>(
+    pub fn with_task<Ctxt: HasDepContext<DepKind = K>, A: Debug, R>(
         &self,
         key: DepNode<K>,
         cx: Ctxt,
         arg: A,
         task: fn(Ctxt, A) -> R,
-        hash_result: impl FnOnce(&mut Ctxt::StableHashingContext, &R) -> Option<Fingerprint>,
+        hash_result: fn(&mut Ctxt::StableHashingContext, &R) -> Option<Fingerprint>,
     ) -> (R, DepNodeIndex) {
-        self.with_task_impl(
-            key,
-            cx,
-            arg,
-            task,
-            |_key| {
-                Some(TaskDeps {
-                    #[cfg(debug_assertions)]
-                    node: Some(_key),
-                    reads: SmallVec::new(),
-                    read_set: Default::default(),
-                    phantom_data: PhantomData,
-                })
-            },
-            hash_result,
-        )
+        if self.is_fully_enabled() {
+            self.with_task_impl(key, cx, arg, task, hash_result)
+        } else {
+            // Incremental compilation is turned off. We just execute the task
+            // without tracking. We still provide a dep-node index that uniquely
+            // identifies the task so that we have a cheap way of referring to
+            // the query for self-profiling.
+            (task(cx, arg), self.next_virtual_depnode_index())
+        }
     }
 
-    fn with_task_impl<Ctxt: HasDepContext<DepKind = K>, A, R>(
+    fn with_task_impl<Ctxt: HasDepContext<DepKind = K>, A: Debug, R>(
         &self,
         key: DepNode<K>,
         cx: Ctxt,
         arg: A,
         task: fn(Ctxt, A) -> R,
-        create_task: fn(DepNode<K>) -> Option<TaskDeps<K>>,
-        hash_result: impl FnOnce(&mut Ctxt::StableHashingContext, &R) -> Option<Fingerprint>,
+        hash_result: fn(&mut Ctxt::StableHashingContext, &R) -> Option<Fingerprint>,
     ) -> (R, DepNodeIndex) {
-        if let Some(ref data) = self.data {
-            let dcx = cx.dep_context();
-            let task_deps = create_task(key).map(Lock::new);
-            let result = K::with_deps(task_deps.as_ref(), || task(cx, arg));
-            let edges = task_deps.map_or_else(|| smallvec![], |lock| lock.into_inner().reads);
-
-            let mut hcx = dcx.create_stable_hashing_context();
-            let hashing_timer = dcx.profiler().incr_result_hashing();
-            let current_fingerprint = hash_result(&mut hcx, &result);
-
-            let print_status = cfg!(debug_assertions) && dcx.sess().opts.debugging_opts.dep_tasks;
-
-            // Get timer for profiling `DepNode` interning
-            let node_intern_timer = self
-                .node_intern_event_id
-                .map(|eid| dcx.profiler().generic_activity_with_event_id(eid));
-            // Intern the new `DepNode`.
-            let (dep_node_index, prev_and_color) = data.current.intern_node(
-                dcx.profiler(),
-                &data.previous,
-                key,
-                edges,
-                current_fingerprint,
-                print_status,
-            );
-            drop(node_intern_timer);
+        // This function is only called when the graph is enabled.
+        let data = self.data.as_ref().unwrap();
 
-            hashing_timer.finish_with_query_invocation_id(dep_node_index.into());
+        // If the following assertion triggers, it can have two reasons:
+        // 1. Something is wrong with DepNode creation, either here or
+        //    in `DepGraph::try_mark_green()`.
+        // 2. Two distinct query keys get mapped to the same `DepNode`
+        //    (see for example #48923).
+        assert!(
+            !self.dep_node_exists(&key),
+            "forcing query with already existing `DepNode`\n\
+                 - query-key: {:?}\n\
+                 - dep-node: {:?}",
+            arg,
+            key
+        );
 
-            if let Some((prev_index, color)) = prev_and_color {
-                debug_assert!(
-                    data.colors.get(prev_index).is_none(),
-                    "DepGraph::with_task() - Duplicate DepNodeColor \
-                            insertion for {:?}",
-                    key
-                );
+        let task_deps = if key.kind.is_eval_always() {
+            None
+        } else {
+            Some(Lock::new(TaskDeps {
+                #[cfg(debug_assertions)]
+                node: Some(key),
+                reads: SmallVec::new(),
+                read_set: Default::default(),
+                phantom_data: PhantomData,
+            }))
+        };
+        let result = K::with_deps(task_deps.as_ref(), || task(cx, arg));
+        let edges = task_deps.map_or_else(|| smallvec![], |lock| lock.into_inner().reads);
+
+        let dcx = cx.dep_context();
+        let mut hcx = dcx.create_stable_hashing_context();
+        let hashing_timer = dcx.profiler().incr_result_hashing();
+        let current_fingerprint = hash_result(&mut hcx, &result);
+
+        let print_status = cfg!(debug_assertions) && dcx.sess().opts.debugging_opts.dep_tasks;
+
+        // Get timer for profiling `DepNode` interning
+        let node_intern_timer =
+            self.node_intern_event_id.map(|eid| dcx.profiler().generic_activity_with_event_id(eid));
+        // Intern the new `DepNode`.
+        let (dep_node_index, prev_and_color) = data.current.intern_node(
+            dcx.profiler(),
+            &data.previous,
+            key,
+            edges,
+            current_fingerprint,
+            print_status,
+        );
+        drop(node_intern_timer);
 
-                data.colors.insert(prev_index, color);
-            }
+        hashing_timer.finish_with_query_invocation_id(dep_node_index.into());
 
-            (result, dep_node_index)
-        } else {
-            // Incremental compilation is turned off. We just execute the task
-            // without tracking. We still provide a dep-node index that uniquely
-            // identifies the task so that we have a cheap way of referring to
-            // the query for self-profiling.
-            (task(cx, arg), self.next_virtual_depnode_index())
+        if let Some((prev_index, color)) = prev_and_color {
+            debug_assert!(
+                data.colors.get(prev_index).is_none(),
+                "DepGraph::with_task() - Duplicate DepNodeColor \
+                            insertion for {:?}",
+                key
+            );
+
+            data.colors.insert(prev_index, color);
         }
+
+        (result, dep_node_index)
     }
 
     /// Executes something within an "anonymous" task, that is, a task the
@@ -357,19 +368,6 @@ pub fn with_anon_task<Ctxt: DepContext<DepKind = K>, OP, R>(
         }
     }
 
-    /// Executes something within an "eval-always" task which is a task
-    /// that runs whenever anything changes.
-    pub fn with_eval_always_task<Ctxt: HasDepContext<DepKind = K>, A, R>(
-        &self,
-        key: DepNode<K>,
-        cx: Ctxt,
-        arg: A,
-        task: fn(Ctxt, A) -> R,
-        hash_result: impl FnOnce(&mut Ctxt::StableHashingContext, &R) -> Option<Fingerprint>,
-    ) -> (R, DepNodeIndex) {
-        self.with_task_impl(key, cx, arg, task, |_| None, hash_result)
-    }
-
     #[inline]
     pub fn read_index(&self, dep_node_index: DepNodeIndex) {
         if let Some(ref data) = self.data {
@@ -484,22 +482,11 @@ fn node_color(&self, dep_node: &DepNode<K>) -> Option<DepNodeColor> {
         None
     }
 
-    /// Try to read a node index for the node dep_node.
+    /// Try to mark a node index for the node dep_node.
+    ///
     /// A node will have an index, when it's already been marked green, or when we can mark it
     /// green. This function will mark the current task as a reader of the specified node, when
     /// a node index can be found for that node.
-    pub fn try_mark_green_and_read<Ctxt: QueryContext<DepKind = K>>(
-        &self,
-        tcx: Ctxt,
-        dep_node: &DepNode<K>,
-    ) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> {
-        self.try_mark_green(tcx, dep_node).map(|(prev_index, dep_node_index)| {
-            debug_assert!(self.is_green(&dep_node));
-            self.read_index(dep_node_index);
-            (prev_index, dep_node_index)
-        })
-    }
-
     pub fn try_mark_green<Ctxt: QueryContext<DepKind = K>>(
         &self,
         tcx: Ctxt,
index c3fdf4fc228511b0ebc767267f052461f681196a..98b2a450b19df73ff34e53d5e0078d580ea19b04 100644 (file)
@@ -143,6 +143,8 @@ impl<D> QueryJobId<D>
 where
     D: Copy + Clone + Eq + Hash,
 {
+    #[cold]
+    #[inline(never)]
     pub(super) fn find_cycle_in_stack(
         &self,
         query_map: QueryMap<D>,
index 3f22de6fba4077987d673cb21dfe8a4fea89b830..3534c3242959c1c4f944002e373f11910d6214ad 100644 (file)
@@ -2,8 +2,7 @@
 //! generate the actual methods on tcx which find and execute the provider,
 //! manage the caches, and so forth.
 
-use crate::dep_graph::{DepContext, DepKind, DepNode, DepNodeParams};
-use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
+use crate::dep_graph::{DepContext, DepKind, DepNode, DepNodeIndex, DepNodeParams};
 use crate::query::caches::QueryCache;
 use crate::query::config::{QueryDescription, QueryVtable, QueryVtableExt};
 use crate::query::job::{
 
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::{FxHashMap, FxHasher};
+#[cfg(parallel_compiler)]
+use rustc_data_structures::profiling::TimingGuard;
 use rustc_data_structures::sharded::{get_shard_index_by_hash, Sharded};
 use rustc_data_structures::sync::{Lock, LockGuard};
 use rustc_data_structures::thin_vec::ThinVec;
-#[cfg(not(parallel_compiler))]
-use rustc_errors::DiagnosticBuilder;
-use rustc_errors::{Diagnostic, FatalError};
+use rustc_errors::{DiagnosticBuilder, FatalError};
 use rustc_span::{Span, DUMMY_SP};
 use std::cell::Cell;
 use std::collections::hash_map::Entry;
@@ -148,24 +147,21 @@ fn default() -> QueryState<D, K> {
 
 /// A type representing the responsibility to execute the job in the `job` field.
 /// This will poison the relevant query if dropped.
-struct JobOwner<'tcx, D, C>
+struct JobOwner<'tcx, D, K>
 where
     D: Copy + Clone + Eq + Hash,
-    C: QueryCache,
+    K: Eq + Hash + Clone,
 {
-    state: &'tcx QueryState<D, C::Key>,
-    cache: &'tcx QueryCacheStore<C>,
-    key: C::Key,
+    state: &'tcx QueryState<D, K>,
+    key: K,
     id: QueryJobId<D>,
 }
 
 #[cold]
 #[inline(never)]
-#[cfg(not(parallel_compiler))]
 fn mk_cycle<CTX, V, R>(
     tcx: CTX,
-    root: QueryJobId<CTX::DepKind>,
-    span: Span,
+    error: CycleError,
     handle_cycle_error: fn(CTX, DiagnosticBuilder<'_>) -> V,
     cache: &dyn crate::query::QueryStorage<Value = V, Stored = R>,
 ) -> R
@@ -174,20 +170,15 @@ fn mk_cycle<CTX, V, R>(
     V: std::fmt::Debug,
     R: Clone,
 {
-    let error: CycleError = root.find_cycle_in_stack(
-        tcx.try_collect_active_jobs().unwrap(),
-        &tcx.current_query_job(),
-        span,
-    );
     let error = report_cycle(tcx.dep_context().sess(), error);
     let value = handle_cycle_error(tcx, error);
     cache.store_nocache(value)
 }
 
-impl<'tcx, D, C> JobOwner<'tcx, D, C>
+impl<'tcx, D, K> JobOwner<'tcx, D, K>
 where
     D: Copy + Clone + Eq + Hash,
-    C: QueryCache,
+    K: Eq + Hash + Clone,
 {
     /// Either gets a `JobOwner` corresponding the query, allowing us to
     /// start executing the query, or returns with the result of the query.
@@ -199,14 +190,13 @@ impl<'tcx, D, C> JobOwner<'tcx, D, C>
     /// for some compile-time benchmarks.
     #[inline(always)]
     fn try_start<'b, CTX>(
-        tcx: CTX,
-        state: &'b QueryState<CTX::DepKind, C::Key>,
-        cache: &'b QueryCacheStore<C>,
+        tcx: &'b CTX,
+        state: &'b QueryState<CTX::DepKind, K>,
         span: Span,
-        key: C::Key,
+        key: K,
         lookup: QueryLookup,
-        query: &QueryVtable<CTX, C::Key, C::Value>,
-    ) -> TryGetJob<'b, CTX::DepKind, C>
+        dep_kind: CTX::DepKind,
+    ) -> TryGetJob<'b, CTX::DepKind, K>
     where
         CTX: QueryContext,
     {
@@ -227,26 +217,24 @@ fn try_start<'b, CTX>(
                 let key = entry.key().clone();
                 entry.insert(QueryResult::Started(job));
 
-                let global_id = QueryJobId::new(id, shard, query.dep_kind);
-                let owner = JobOwner { state, cache, id: global_id, key };
+                let global_id = QueryJobId::new(id, shard, dep_kind);
+                let owner = JobOwner { state, id: global_id, key };
                 return TryGetJob::NotYetStarted(owner);
             }
             Entry::Occupied(mut entry) => {
                 match entry.get_mut() {
                     #[cfg(not(parallel_compiler))]
                     QueryResult::Started(job) => {
-                        let id = QueryJobId::new(job.id, shard, query.dep_kind);
+                        let id = QueryJobId::new(job.id, shard, dep_kind);
 
                         drop(state_lock);
 
                         // If we are single-threaded we know that we have cycle error,
                         // so we just return the error.
-                        return TryGetJob::Cycle(mk_cycle(
-                            tcx,
-                            id,
+                        return TryGetJob::Cycle(id.find_cycle_in_stack(
+                            tcx.try_collect_active_jobs().unwrap(),
+                            &tcx.current_query_job(),
                             span,
-                            query.handle_cycle_error,
-                            &cache.cache,
                         ));
                     }
                     #[cfg(parallel_compiler)]
@@ -258,7 +246,6 @@ fn try_start<'b, CTX>(
 
                         // Get the latch out
                         let latch = job.latch();
-                        let key = entry.key().clone();
 
                         drop(state_lock);
 
@@ -266,30 +253,10 @@ fn try_start<'b, CTX>(
                         // thread.
                         let result = latch.wait_on(tcx.current_query_job(), span);
 
-                        if let Err(cycle) = result {
-                            let cycle = report_cycle(tcx.dep_context().sess(), cycle);
-                            let value = (query.handle_cycle_error)(tcx, cycle);
-                            let value = cache.cache.store_nocache(value);
-                            return TryGetJob::Cycle(value);
+                        match result {
+                            Ok(()) => TryGetJob::JobCompleted(query_blocked_prof_timer),
+                            Err(cycle) => TryGetJob::Cycle(cycle),
                         }
-
-                        let cached = cache
-                            .cache
-                            .lookup(cache, &key, |value, index| {
-                                if unlikely!(tcx.dep_context().profiler().enabled()) {
-                                    tcx.dep_context().profiler().query_cache_hit(index.into());
-                                }
-                                #[cfg(debug_assertions)]
-                                {
-                                    cache.cache_hits.fetch_add(1, Ordering::Relaxed);
-                                }
-                                (value.clone(), index)
-                            })
-                            .unwrap_or_else(|_| panic!("value must be in cache after waiting"));
-
-                        query_blocked_prof_timer.finish_with_query_invocation_id(cached.1.into());
-
-                        return TryGetJob::JobCompleted(cached);
                     }
                     QueryResult::Poisoned => FatalError.raise(),
                 }
@@ -299,11 +266,18 @@ fn try_start<'b, CTX>(
 
     /// Completes the query by updating the query cache with the `result`,
     /// signals the waiter and forgets the JobOwner, so it won't poison the query
-    fn complete(self, result: C::Value, dep_node_index: DepNodeIndex) -> C::Stored {
+    fn complete<C>(
+        self,
+        cache: &QueryCacheStore<C>,
+        result: C::Value,
+        dep_node_index: DepNodeIndex,
+    ) -> C::Stored
+    where
+        C: QueryCache<Key = K>,
+    {
         // We can move out of `self` here because we `mem::forget` it below
         let key = unsafe { ptr::read(&self.key) };
         let state = self.state;
-        let cache = self.cache;
 
         // Forget ourself so our destructor won't poison the query
         mem::forget(self);
@@ -330,19 +304,10 @@ fn complete(self, result: C::Value, dep_node_index: DepNodeIndex) -> C::Stored {
     }
 }
 
-fn with_diagnostics<F, R>(f: F) -> (R, ThinVec<Diagnostic>)
-where
-    F: FnOnce(Option<&Lock<ThinVec<Diagnostic>>>) -> R,
-{
-    let diagnostics = Lock::new(ThinVec::new());
-    let result = f(Some(&diagnostics));
-    (result, diagnostics.into_inner())
-}
-
-impl<'tcx, D, C> Drop for JobOwner<'tcx, D, C>
+impl<'tcx, D, K> Drop for JobOwner<'tcx, D, K>
 where
     D: Copy + Clone + Eq + Hash,
-    C: QueryCache,
+    K: Eq + Hash + Clone,
 {
     #[inline(never)]
     #[cold]
@@ -373,22 +338,22 @@ pub(crate) struct CycleError {
 }
 
 /// The result of `try_start`.
-enum TryGetJob<'tcx, D, C>
+enum TryGetJob<'tcx, D, K>
 where
     D: Copy + Clone + Eq + Hash,
-    C: QueryCache,
+    K: Eq + Hash + Clone,
 {
     /// The query is not yet started. Contains a guard to the cache eventually used to start it.
-    NotYetStarted(JobOwner<'tcx, D, C>),
+    NotYetStarted(JobOwner<'tcx, D, K>),
 
     /// The query was already completed.
     /// Returns the result of the query and its dep-node index
     /// if it succeeded or a cycle error if it failed.
     #[cfg(parallel_compiler)]
-    JobCompleted((C::Stored, DepNodeIndex)),
+    JobCompleted(TimingGuard<'tcx>),
 
     /// Trying to execute the query resulted in a cycle.
-    Cycle(C::Stored),
+    Cycle(CycleError),
 }
 
 /// Checks if the query is already computed and in the cache.
@@ -428,119 +393,146 @@ fn try_execute_query<CTX, C>(
     span: Span,
     key: C::Key,
     lookup: QueryLookup,
+    dep_node: Option<DepNode<CTX::DepKind>>,
     query: &QueryVtable<CTX, C::Key, C::Value>,
     compute: fn(CTX::DepContext, C::Key) -> C::Value,
-) -> C::Stored
+) -> (C::Stored, Option<DepNodeIndex>)
 where
     C: QueryCache,
-    C::Key: DepNodeParams<CTX::DepContext>,
+    C::Key: Clone + DepNodeParams<CTX::DepContext>,
     CTX: QueryContext,
 {
-    let job = match JobOwner::<'_, CTX::DepKind, C>::try_start(
-        tcx,
+    match JobOwner::<'_, CTX::DepKind, C::Key>::try_start(
+        &tcx,
         state,
-        cache,
         span,
         key.clone(),
         lookup,
-        query,
+        query.dep_kind,
     ) {
-        TryGetJob::NotYetStarted(job) => job,
-        TryGetJob::Cycle(result) => return result,
+        TryGetJob::NotYetStarted(job) => {
+            let (result, dep_node_index) = execute_job(tcx, key, dep_node, query, job.id, compute);
+            let result = job.complete(cache, result, dep_node_index);
+            (result, Some(dep_node_index))
+        }
+        TryGetJob::Cycle(error) => {
+            let result = mk_cycle(tcx, error, query.handle_cycle_error, &cache.cache);
+            (result, None)
+        }
         #[cfg(parallel_compiler)]
-        TryGetJob::JobCompleted((v, index)) => {
-            tcx.dep_context().dep_graph().read_index(index);
-            return v;
+        TryGetJob::JobCompleted(query_blocked_prof_timer) => {
+            let (v, index) = cache
+                .cache
+                .lookup(cache, &key, |value, index| (value.clone(), index))
+                .unwrap_or_else(|_| panic!("value must be in cache after waiting"));
+
+            if unlikely!(tcx.dep_context().profiler().enabled()) {
+                tcx.dep_context().profiler().query_cache_hit(index.into());
+            }
+            #[cfg(debug_assertions)]
+            {
+                cache.cache_hits.fetch_add(1, Ordering::Relaxed);
+            }
+            query_blocked_prof_timer.finish_with_query_invocation_id(index.into());
+
+            (v, Some(index))
         }
-    };
+    }
+}
 
+fn execute_job<CTX, K, V>(
+    tcx: CTX,
+    key: K,
+    mut dep_node_opt: Option<DepNode<CTX::DepKind>>,
+    query: &QueryVtable<CTX, K, V>,
+    job_id: QueryJobId<CTX::DepKind>,
+    compute: fn(CTX::DepContext, K) -> V,
+) -> (V, DepNodeIndex)
+where
+    K: Clone + DepNodeParams<CTX::DepContext>,
+    V: Debug,
+    CTX: QueryContext,
+{
     let dep_graph = tcx.dep_context().dep_graph();
 
     // Fast path for when incr. comp. is off.
     if !dep_graph.is_fully_enabled() {
         let prof_timer = tcx.dep_context().profiler().query_provider();
-        let result = tcx.start_query(job.id, None, || compute(*tcx.dep_context(), key));
+        let result = tcx.start_query(job_id, None, || compute(*tcx.dep_context(), key));
         let dep_node_index = dep_graph.next_virtual_depnode_index();
         prof_timer.finish_with_query_invocation_id(dep_node_index.into());
-        return job.complete(result, dep_node_index);
+        return (result, dep_node_index);
     }
 
-    if query.anon {
-        let prof_timer = tcx.dep_context().profiler().query_provider();
+    if !query.anon && !query.eval_always {
+        // `to_dep_node` is expensive for some `DepKind`s.
+        let dep_node =
+            dep_node_opt.get_or_insert_with(|| query.to_dep_node(*tcx.dep_context(), &key));
 
-        let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
-            tcx.start_query(job.id, diagnostics, || {
-                dep_graph.with_anon_task(*tcx.dep_context(), query.dep_kind, || {
-                    compute(*tcx.dep_context(), key)
-                })
-            })
-        });
+        // The diagnostics for this query will be promoted to the current session during
+        // `try_mark_green()`, so we can ignore them here.
+        if let Some(ret) = tcx.start_query(job_id, None, || {
+            try_load_from_disk_and_cache_in_memory(tcx, &key, &dep_node, query, compute)
+        }) {
+            return ret;
+        }
+    }
 
-        prof_timer.finish_with_query_invocation_id(dep_node_index.into());
+    let prof_timer = tcx.dep_context().profiler().query_provider();
+    let diagnostics = Lock::new(ThinVec::new());
 
-        dep_graph.read_index(dep_node_index);
+    let (result, dep_node_index) = tcx.start_query(job_id, Some(&diagnostics), || {
+        if query.anon {
+            return dep_graph.with_anon_task(*tcx.dep_context(), query.dep_kind, || {
+                compute(*tcx.dep_context(), key)
+            });
+        }
 
-        let side_effects = QuerySideEffects { diagnostics };
+        // `to_dep_node` is expensive for some `DepKind`s.
+        let dep_node = dep_node_opt.unwrap_or_else(|| query.to_dep_node(*tcx.dep_context(), &key));
 
-        if unlikely!(!side_effects.is_empty()) {
-            tcx.store_side_effects_for_anon_node(dep_node_index, side_effects);
-        }
+        dep_graph.with_task(dep_node, *tcx.dep_context(), key, compute, query.hash_result)
+    });
 
-        return job.complete(result, dep_node_index);
-    }
+    prof_timer.finish_with_query_invocation_id(dep_node_index.into());
 
-    let dep_node = query.to_dep_node(*tcx.dep_context(), &key);
+    let diagnostics = diagnostics.into_inner();
+    let side_effects = QuerySideEffects { diagnostics };
 
-    if !query.eval_always {
-        // The diagnostics for this query will be
-        // promoted to the current session during
-        // `try_mark_green()`, so we can ignore them here.
-        let loaded = tcx.start_query(job.id, None, || {
-            let marked = dep_graph.try_mark_green_and_read(tcx, &dep_node);
-            marked.map(|(prev_dep_node_index, dep_node_index)| {
-                (
-                    load_from_disk_and_cache_in_memory(
-                        tcx,
-                        key.clone(),
-                        prev_dep_node_index,
-                        dep_node_index,
-                        &dep_node,
-                        query,
-                        compute,
-                    ),
-                    dep_node_index,
-                )
-            })
-        });
-        if let Some((result, dep_node_index)) = loaded {
-            return job.complete(result, dep_node_index);
+    if unlikely!(!side_effects.is_empty()) {
+        if query.anon {
+            tcx.store_side_effects_for_anon_node(dep_node_index, side_effects);
+        } else {
+            tcx.store_side_effects(dep_node_index, side_effects);
         }
     }
 
-    let (result, dep_node_index) = force_query_with_job(tcx, key, job, dep_node, query, compute);
-    dep_graph.read_index(dep_node_index);
-    result
+    (result, dep_node_index)
 }
 
-fn load_from_disk_and_cache_in_memory<CTX, K, V: Debug>(
+fn try_load_from_disk_and_cache_in_memory<CTX, K, V>(
     tcx: CTX,
-    key: K,
-    prev_dep_node_index: SerializedDepNodeIndex,
-    dep_node_index: DepNodeIndex,
+    key: &K,
     dep_node: &DepNode<CTX::DepKind>,
     query: &QueryVtable<CTX, K, V>,
     compute: fn(CTX::DepContext, K) -> V,
-) -> V
+) -> Option<(V, DepNodeIndex)>
 where
+    K: Clone,
     CTX: QueryContext,
+    V: Debug,
 {
     // Note this function can be called concurrently from the same query
     // We must ensure that this is handled correctly.
 
-    debug_assert!(tcx.dep_context().dep_graph().is_green(dep_node));
+    let dep_graph = tcx.dep_context().dep_graph();
+    let (prev_dep_node_index, dep_node_index) = dep_graph.try_mark_green(tcx, &dep_node)?;
+
+    debug_assert!(dep_graph.is_green(dep_node));
 
     // First we try to load the result from the on-disk cache.
-    let result = if query.cache_on_disk(tcx, &key, None) {
+    // Some things are never cached on disk.
+    if query.cache_on_disk(tcx, key, None) {
         let prof_timer = tcx.dep_context().profiler().incr_cache_loading();
         let result = query.try_load_from_disk(tcx, prev_dep_node_index);
         prof_timer.finish_with_query_invocation_id(dep_node_index.into());
@@ -552,43 +544,39 @@ fn load_from_disk_and_cache_in_memory<CTX, K, V: Debug>(
             "missing on-disk cache entry for {:?}",
             dep_node
         );
-        result
-    } else {
-        // Some things are never cached on disk.
-        None
-    };
 
-    if let Some(result) = result {
-        // If `-Zincremental-verify-ich` is specified, re-hash results from
-        // the cache and make sure that they have the expected fingerprint.
-        if unlikely!(tcx.dep_context().sess().opts.debugging_opts.incremental_verify_ich) {
-            incremental_verify_ich(*tcx.dep_context(), &result, dep_node, query);
+        if let Some(result) = result {
+            // If `-Zincremental-verify-ich` is specified, re-hash results from
+            // the cache and make sure that they have the expected fingerprint.
+            if unlikely!(tcx.dep_context().sess().opts.debugging_opts.incremental_verify_ich) {
+                incremental_verify_ich(*tcx.dep_context(), &result, dep_node, query);
+            }
+
+            return Some((result, dep_node_index));
         }
+    }
 
-        result
-    } else {
-        // We could not load a result from the on-disk cache, so
-        // recompute.
-        let prof_timer = tcx.dep_context().profiler().query_provider();
+    // We could not load a result from the on-disk cache, so
+    // recompute.
+    let prof_timer = tcx.dep_context().profiler().query_provider();
 
-        // The dep-graph for this computation is already in-place.
-        let result = tcx.dep_context().dep_graph().with_ignore(|| compute(*tcx.dep_context(), key));
+    // The dep-graph for this computation is already in-place.
+    let result = dep_graph.with_ignore(|| compute(*tcx.dep_context(), key.clone()));
 
-        prof_timer.finish_with_query_invocation_id(dep_node_index.into());
-
-        // Verify that re-running the query produced a result with the expected hash
-        // This catches bugs in query implementations, turning them into ICEs.
-        // For example, a query might sort its result by `DefId` - since `DefId`s are
-        // not stable across compilation sessions, the result could get up getting sorted
-        // in a different order when the query is re-run, even though all of the inputs
-        // (e.g. `DefPathHash` values) were green.
-        //
-        // See issue #82920 for an example of a miscompilation that would get turned into
-        // an ICE by this check
-        incremental_verify_ich(*tcx.dep_context(), &result, dep_node, query);
+    prof_timer.finish_with_query_invocation_id(dep_node_index.into());
 
-        result
-    }
+    // Verify that re-running the query produced a result with the expected hash
+    // This catches bugs in query implementations, turning them into ICEs.
+    // For example, a query might sort its result by `DefId` - since `DefId`s are
+    // not stable across compilation sessions, the result could get up getting sorted
+    // in a different order when the query is re-run, even though all of the inputs
+    // (e.g. `DefPathHash` values) were green.
+    //
+    // See issue #82920 for an example of a miscompilation that would get turned into
+    // an ICE by this check
+    incremental_verify_ich(*tcx.dep_context(), &result, dep_node, query);
+
+    Some((result, dep_node_index))
 }
 
 fn incremental_verify_ich<CTX, K, V: Debug>(
@@ -648,88 +636,6 @@ fn incremental_verify_ich<CTX, K, V: Debug>(
     }
 }
 
-fn force_query_with_job<C, CTX>(
-    tcx: CTX,
-    key: C::Key,
-    job: JobOwner<'_, CTX::DepKind, C>,
-    dep_node: DepNode<CTX::DepKind>,
-    query: &QueryVtable<CTX, C::Key, C::Value>,
-    compute: fn(CTX::DepContext, C::Key) -> C::Value,
-) -> (C::Stored, DepNodeIndex)
-where
-    C: QueryCache,
-    CTX: QueryContext,
-{
-    // If the following assertion triggers, it can have two reasons:
-    // 1. Something is wrong with DepNode creation, either here or
-    //    in `DepGraph::try_mark_green()`.
-    // 2. Two distinct query keys get mapped to the same `DepNode`
-    //    (see for example #48923).
-    assert!(
-        !tcx.dep_context().dep_graph().dep_node_exists(&dep_node),
-        "forcing query with already existing `DepNode`\n\
-                 - query-key: {:?}\n\
-                 - dep-node: {:?}",
-        key,
-        dep_node
-    );
-
-    let prof_timer = tcx.dep_context().profiler().query_provider();
-
-    let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
-        tcx.start_query(job.id, diagnostics, || {
-            if query.eval_always {
-                tcx.dep_context().dep_graph().with_eval_always_task(
-                    dep_node,
-                    *tcx.dep_context(),
-                    key,
-                    compute,
-                    query.hash_result,
-                )
-            } else {
-                tcx.dep_context().dep_graph().with_task(
-                    dep_node,
-                    *tcx.dep_context(),
-                    key,
-                    compute,
-                    query.hash_result,
-                )
-            }
-        })
-    });
-
-    prof_timer.finish_with_query_invocation_id(dep_node_index.into());
-
-    let side_effects = QuerySideEffects { diagnostics };
-
-    if unlikely!(!side_effects.is_empty()) && dep_node.kind != DepKind::NULL {
-        tcx.store_side_effects(dep_node_index, side_effects);
-    }
-
-    let result = job.complete(result, dep_node_index);
-
-    (result, dep_node_index)
-}
-
-#[inline(never)]
-fn get_query_impl<CTX, C>(
-    tcx: CTX,
-    state: &QueryState<CTX::DepKind, C::Key>,
-    cache: &QueryCacheStore<C>,
-    span: Span,
-    key: C::Key,
-    lookup: QueryLookup,
-    query: &QueryVtable<CTX, C::Key, C::Value>,
-    compute: fn(CTX::DepContext, C::Key) -> C::Value,
-) -> C::Stored
-where
-    CTX: QueryContext,
-    C: QueryCache,
-    C::Key: DepNodeParams<CTX::DepContext>,
-{
-    try_execute_query(tcx, state, cache, span, key, lookup, query, compute)
-}
-
 /// Ensure that either this query has all green inputs or been executed.
 /// Executing `query::ensure(D)` is considered a read of the dep-node `D`.
 /// Returns true if the query should still run.
@@ -739,13 +645,17 @@ fn get_query_impl<CTX, C>(
 ///
 /// Note: The optimization is only available during incr. comp.
 #[inline(never)]
-fn ensure_must_run<CTX, K, V>(tcx: CTX, key: &K, query: &QueryVtable<CTX, K, V>) -> bool
+fn ensure_must_run<CTX, K, V>(
+    tcx: CTX,
+    key: &K,
+    query: &QueryVtable<CTX, K, V>,
+) -> (bool, Option<DepNode<CTX::DepKind>>)
 where
     K: crate::dep_graph::DepNodeParams<CTX::DepContext>,
     CTX: QueryContext,
 {
     if query.eval_always {
-        return true;
+        return (true, None);
     }
 
     // Ensuring an anonymous query makes no sense
@@ -753,19 +663,21 @@ fn ensure_must_run<CTX, K, V>(tcx: CTX, key: &K, query: &QueryVtable<CTX, K, V>)
 
     let dep_node = query.to_dep_node(*tcx.dep_context(), key);
 
-    match tcx.dep_context().dep_graph().try_mark_green_and_read(tcx, &dep_node) {
+    let dep_graph = tcx.dep_context().dep_graph();
+    match dep_graph.try_mark_green(tcx, &dep_node) {
         None => {
-            // A None return from `try_mark_green_and_read` means that this is either
+            // A None return from `try_mark_green` means that this is either
             // a new dep node or that the dep node has already been marked red.
             // Either way, we can't call `dep_graph.read()` as we don't have the
             // DepNodeIndex. We must invoke the query itself. The performance cost
             // this introduces should be negligible as we'll immediately hit the
             // in-memory cache, or another query down the line will.
-            true
+            (true, Some(dep_node))
         }
         Some((_, dep_node_index)) => {
+            dep_graph.read_index(dep_node_index);
             tcx.dep_context().profiler().query_cache_hit(dep_node_index.into());
-            false
+            (false, None)
         }
     }
 }
@@ -804,23 +716,8 @@ fn force_query_impl<CTX, C>(
         Err(lookup) => lookup,
     };
 
-    let job = match JobOwner::<'_, CTX::DepKind, C>::try_start(
-        tcx,
-        state,
-        cache,
-        DUMMY_SP,
-        key.clone(),
-        lookup,
-        query,
-    ) {
-        TryGetJob::NotYetStarted(job) => job,
-        TryGetJob::Cycle(_) => return true,
-        #[cfg(parallel_compiler)]
-        TryGetJob::JobCompleted(_) => return true,
-    };
-
-    force_query_with_job(tcx, key, job, dep_node, query, compute);
-
+    let _ =
+        try_execute_query(tcx, state, cache, DUMMY_SP, key, lookup, Some(dep_node), query, compute);
     true
 }
 
@@ -842,25 +739,33 @@ pub fn get_query<Q, CTX>(
     CTX: QueryContext,
 {
     let query = &Q::VTABLE;
-    if let QueryMode::Ensure = mode {
-        if !ensure_must_run(tcx, &key, query) {
+    let dep_node = if let QueryMode::Ensure = mode {
+        let (must_run, dep_node) = ensure_must_run(tcx, &key, query);
+        if !must_run {
             return None;
         }
-    }
+        dep_node
+    } else {
+        None
+    };
 
     debug!("ty::query::get_query<{}>(key={:?}, span={:?})", Q::NAME, key, span);
     let compute = Q::compute_fn(tcx, &key);
-    let value = get_query_impl(
+    let (result, dep_node_index) = try_execute_query(
         tcx,
         Q::query_state(tcx),
         Q::query_cache(tcx),
         span,
         key,
         lookup,
+        dep_node,
         query,
         compute,
     );
-    Some(value)
+    if let Some(dep_node_index) = dep_node_index {
+        tcx.dep_context().dep_graph().read_index(dep_node_index)
+    }
+    Some(result)
 }
 
 pub fn force_query<Q, CTX>(tcx: CTX, dep_node: &DepNode<CTX::DepKind>) -> bool
index 2ee483d850e7b4ef156e27b48706685be3805fcc..55f2b04c4f1c1f6f258238e5bb8d14829eb5e41b 100644 (file)
@@ -228,7 +228,6 @@ pub fn get_module(&mut self, def_id: DefId) -> Module<'a> {
     crate fn build_reduced_graph_external(&mut self, module: Module<'a>) {
         let def_id = module.def_id().expect("unpopulated module without a def-id");
         for child in self.cstore().item_children_untracked(def_id, self.session) {
-            let child = child.map_id(|_| panic!("unexpected id"));
             let parent_scope = ParentScope::module(module, self);
             BuildReducedGraphVisitor { r: self, parent_scope }
                 .build_reduced_graph_for_external_crate_res(child);
@@ -946,9 +945,10 @@ fn build_reduced_graph_for_block(&mut self, block: &Block) {
     }
 
     /// Builds the reduced graph for a single item in an external crate.
-    fn build_reduced_graph_for_external_crate_res(&mut self, child: Export<NodeId>) {
+    fn build_reduced_graph_for_external_crate_res(&mut self, child: Export) {
         let parent = self.parent_scope.module;
         let Export { ident, res, vis, span } = child;
+        let res = res.expect_non_local();
         let expansion = self.parent_scope.expansion;
         // Record primary definitions.
         match res {
index 6f4f1bdaea1b7a97929bea82a63ad24c867f4637..5879cb1daa582f5360bb69a332cbf53d3d426635 100644 (file)
@@ -32,7 +32,13 @@ impl<'a, 'b> DefCollector<'a, 'b> {
     fn create_def(&mut self, node_id: NodeId, data: DefPathData, span: Span) -> LocalDefId {
         let parent_def = self.parent_def;
         debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def);
-        self.resolver.create_def(parent_def, node_id, data, self.expansion.to_expn_id(), span)
+        self.resolver.create_def(
+            parent_def,
+            node_id,
+            data,
+            self.expansion.to_expn_id(),
+            span.with_parent(None),
+        )
     }
 
     fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: LocalDefId, f: F) {
index dfb6d89a0d12601772f5ad183f2fc10b06fe727b..d4782edbc134645305d35091a0c252aa6b163de8 100644 (file)
@@ -11,7 +11,6 @@
 
 use rustc_ast::unwrap_or;
 use rustc_ast::NodeId;
-use rustc_ast_lowering::ResolverAstLowering;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::ptr_key::PtrKey;
 use rustc_errors::{pluralize, struct_span_err, Applicability};
@@ -1387,13 +1386,13 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
 
         let mut reexports = Vec::new();
 
-        module.for_each_child(self.r, |this, ident, _, binding| {
+        module.for_each_child(self.r, |_, ident, _, binding| {
             // Filter away ambiguous imports and anything that has def-site hygiene.
             // FIXME: Implement actual cross-crate hygiene.
             let is_good_import =
                 binding.is_import() && !binding.is_ambiguity() && !ident.span.from_expansion();
             if is_good_import || binding.is_macro_def() {
-                let res = binding.res().map_id(|id| this.local_def_id(id));
+                let res = binding.res().expect_non_local();
                 if res != def::Res::Err {
                     reexports.push(Export { ident, res, span: binding.span, vis: binding.vis });
                 }
index b2c0c7874655e0d6fe9fd6bf7a412ab1b5a4fb3b..a11d7a69c54f414588dcde497d979b16ed61d89c 100644 (file)
@@ -768,6 +768,7 @@ fn call_has_self_arg(&self, source: PathSource<'_>) -> Option<(Span, Option<Span
                                             args[1].span.lo(),
                                             args.last().unwrap().span.hi(),
                                             call_span.ctxt(),
+                                            None,
                                         ))
                                     } else {
                                         None
index 6d2961db9e3dace832a4e86ef6e3663148d7fbb3..d76ba80e42eab75a95eeddd5a836b802714ab616 100644 (file)
@@ -14,6 +14,7 @@
 #![feature(crate_visibility_modifier)]
 #![feature(format_args_capture)]
 #![feature(iter_zip)]
+#![feature(never_type)]
 #![feature(nll)]
 #![recursion_limit = "256"]
 #![allow(rustdoc::private_intra_doc_links)]
@@ -911,7 +912,7 @@ pub struct Resolver<'a> {
 
     /// `CrateNum` resolutions of `extern crate` items.
     extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
-    export_map: ExportMap<LocalDefId>,
+    export_map: ExportMap,
     trait_map: Option<NodeMap<Vec<TraitCandidate>>>,
 
     /// A map from nodes to anonymous modules.
@@ -1012,8 +1013,6 @@ pub struct Resolver<'a> {
 
     next_node_id: NodeId,
 
-    def_id_to_span: IndexVec<LocalDefId, Span>,
-
     node_id_to_def_id: FxHashMap<ast::NodeId, LocalDefId>,
     def_id_to_node_id: IndexVec<LocalDefId, ast::NodeId>,
 
@@ -1116,6 +1115,11 @@ fn def_key(&mut self, id: DefId) -> DefKey {
         }
     }
 
+    #[inline]
+    fn def_span(&self, id: LocalDefId) -> Span {
+        self.definitions.def_span(id)
+    }
+
     fn item_generics_num_lifetimes(&self, def_id: DefId) -> usize {
         if let Some(def_id) = def_id.as_local() {
             self.item_generics_num_lifetimes[&def_id]
@@ -1197,9 +1201,7 @@ fn create_def(
             disambiguator
         };
 
-        let def_id = self.definitions.create_def(parent, data, expn_id, next_disambiguator);
-
-        assert_eq!(self.def_id_to_span.push(span), def_id);
+        let def_id = self.definitions.create_def(parent, data, expn_id, next_disambiguator, span);
 
         // Some things for which we allocate `LocalDefId`s don't correspond to
         // anything in the AST, so they don't have a `NodeId`. For these cases
@@ -1225,6 +1227,11 @@ fn hash_spans(&self) -> bool {
         true
     }
 
+    #[inline]
+    fn def_span(&self, id: LocalDefId) -> Span {
+        self.resolver.def_span(id)
+    }
+
     #[inline]
     fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
         self.resolver.def_path_hash(def_id)
@@ -1269,14 +1276,12 @@ pub fn new(
         let mut module_map = FxHashMap::default();
         module_map.insert(root_local_def_id, graph_root);
 
-        let definitions = Definitions::new(session.local_stable_crate_id());
+        let definitions = Definitions::new(session.local_stable_crate_id(), krate.span);
         let root = definitions.get_root_def();
 
         let mut visibilities = FxHashMap::default();
         visibilities.insert(root_local_def_id, ty::Visibility::Public);
 
-        let mut def_id_to_span = IndexVec::default();
-        assert_eq!(def_id_to_span.push(rustc_span::DUMMY_SP), root);
         let mut def_id_to_node_id = IndexVec::default();
         assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), root);
         let mut node_id_to_def_id = FxHashMap::default();
@@ -1393,7 +1398,6 @@ pub fn new(
                 .collect(),
             lint_buffer: LintBuffer::default(),
             next_node_id: NodeId::from_u32(1),
-            def_id_to_span,
             node_id_to_def_id,
             def_id_to_node_id,
             placeholder_field_indices: Default::default(),
@@ -1487,7 +1491,7 @@ pub fn clone_outputs(&self) -> ResolverOutputs {
                 .iter()
                 .map(|(ident, entry)| (ident.name, entry.introduced_by_item))
                 .collect(),
-            main_def: self.main_def.clone(),
+            main_def: self.main_def,
             trait_impls: self.trait_impls.clone(),
             proc_macros,
             confused_type_with_std_module: self.confused_type_with_std_module.clone(),
@@ -3360,7 +3364,7 @@ pub fn all_macros(&self) -> &FxHashMap<Symbol, Res> {
     /// Retrieves the span of the given `DefId` if `DefId` is in the local crate.
     #[inline]
     pub fn opt_span(&self, def_id: DefId) -> Option<Span> {
-        if let Some(def_id) = def_id.as_local() { Some(self.def_id_to_span[def_id]) } else { None }
+        def_id.as_local().map(|def_id| self.definitions.def_span(def_id))
     }
 
     /// Checks if an expression refers to a function marked with
index 6dc3aa0888a8be605c2e114ecb6555cdd3db28a4..4dbac47c3cc8e35202613a948b6622e5d52a0779 100644 (file)
@@ -180,6 +180,10 @@ fn next_node_id(&mut self) -> NodeId {
         self.next_node_id()
     }
 
+    fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId {
+        self.invocation_parents[&id].0
+    }
+
     fn resolve_dollar_crates(&mut self) {
         hygiene::update_dollar_crate_names(|ctxt| {
             let ident = Ident::new(kw::DollarCrate, DUMMY_SP.with_ctxt(ctxt));
index ecc8dae04800a3a44dd7c031e8804e238d0ca61f..e32e4493726dbb7d279c66e1451a10d99ccfc41b 100644 (file)
@@ -366,6 +366,18 @@ fn decode(d: &mut D) -> Result<$ty, D::Error> {
     char emit_char read_char
 }
 
+impl<S: Encoder> Encodable<S> for ! {
+    fn encode(&self, _s: &mut S) -> Result<(), S::Error> {
+        unreachable!()
+    }
+}
+
+impl<D: Decoder> Decodable<D> for ! {
+    fn decode(_d: &mut D) -> Result<!, D::Error> {
+        unreachable!()
+    }
+}
+
 impl<S: Encoder> Encodable<S> for ::std::num::NonZeroU32 {
     fn encode(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_u32(self.get())
index 9a1be40558ccb3ca03796f97f6381065301b455e..bb29a87035e8001f2e24b160a11ed4dbc3dbd977 100644 (file)
@@ -349,6 +349,7 @@ mod desc {
     pub const parse_threads: &str = parse_number;
     pub const parse_passes: &str = "a space-separated list of passes, or `all`";
     pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
+    pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
     pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
     pub const parse_sanitizers: &str =
         "comma separated list of sanitizers: `address`, `hwaddress`, `leak`, `memory` or `thread`";
@@ -549,7 +550,7 @@ mod parse {
         }
     }
 
-    crate fn parse_panic_strategy(slot: &mut Option<PanicStrategy>, v: Option<&str>) -> bool {
+    crate fn parse_opt_panic_strategy(slot: &mut Option<PanicStrategy>, v: Option<&str>) -> bool {
         match v {
             Some("unwind") => *slot = Some(PanicStrategy::Unwind),
             Some("abort") => *slot = Some(PanicStrategy::Abort),
@@ -558,6 +559,15 @@ mod parse {
         true
     }
 
+    crate fn parse_panic_strategy(slot: &mut PanicStrategy, v: Option<&str>) -> bool {
+        match v {
+            Some("unwind") => *slot = PanicStrategy::Unwind,
+            Some("abort") => *slot = PanicStrategy::Abort,
+            _ => return false,
+        }
+        true
+    }
+
     crate fn parse_relro_level(slot: &mut Option<RelroLevel>, v: Option<&str>) -> bool {
         match v {
             Some(s) => match s.parse::<RelroLevel>() {
@@ -958,7 +968,7 @@ mod parse {
         "optimization level (0-3, s, or z; default: 0)"),
     overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "use overflow checks for integer arithmetic"),
-    panic: Option<PanicStrategy> = (None, parse_panic_strategy, [TRACKED],
+    panic: Option<PanicStrategy> = (None, parse_opt_panic_strategy, [TRACKED],
         "panic strategy to compile crate with"),
     passes: Vec<String> = (Vec::new(), parse_list, [TRACKED],
         "a list of extra LLVM passes to run (space separated)"),
@@ -1106,6 +1116,8 @@ mod parse {
     incremental_info: bool = (false, parse_bool, [UNTRACKED],
         "print high-level information about incremental reuse (or the lack thereof) \
         (default: no)"),
+    incremental_relative_spans: bool = (false, parse_bool, [TRACKED],
+        "hash spans relative to their parent item for incr. comp. (default: no)"),
     incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED],
         "verify incr. comp. hashes of green query instances (default: no)"),
     inline_mir: Option<bool> = (None, parse_opt_bool, [TRACKED],
@@ -1184,6 +1196,8 @@ mod parse {
         "pass `-install_name @rpath/...` to the macOS linker (default: no)"),
     panic_abort_tests: bool = (false, parse_bool, [TRACKED],
         "support compiling tests with panic=abort (default: no)"),
+    panic_in_drop: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy, [TRACKED],
+        "panic strategy for panics in drops"),
     parse_only: bool = (false, parse_bool, [UNTRACKED],
         "parse only; do not compile, assemble, or link (default: no)"),
     partially_uninit_const_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
index c22093c5a428811ac78241029325969330873b41..ef60608a27c8bb6bb03e1fe56e1ea54ab1af908b 100644 (file)
@@ -1357,9 +1357,7 @@ fn for_all_expns_in<E>(
     mut f: impl FnMut(ExpnId, &ExpnData, ExpnHash) -> Result<(), E>,
 ) -> Result<(), E> {
     let all_data: Vec<_> = HygieneData::with(|data| {
-        expns
-            .map(|expn| (expn, data.expn_data(expn).clone(), data.expn_hash(expn).clone()))
-            .collect()
+        expns.map(|expn| (expn, data.expn_data(expn).clone(), data.expn_hash(expn))).collect()
     });
     for (expn, data, hash) in all_data.into_iter() {
         f(expn, &data, hash)?;
index 5f41b1120126eece0e35c0f9df44b26eb74f9390..eb496140553ad80619d0a3bd0784c99db7cad80d 100644 (file)
@@ -41,7 +41,7 @@
 pub use hygiene::{DesugaringKind, ExpnKind, ForLoopLoc, MacroKind};
 pub use hygiene::{ExpnData, ExpnHash, ExpnId, LocalExpnId, SyntaxContext};
 pub mod def_id;
-use def_id::{CrateNum, DefId, DefPathHash, LOCAL_CRATE};
+use def_id::{CrateNum, DefId, DefPathHash, LocalDefId, LOCAL_CRATE};
 pub mod lev_distance;
 mod span_encoding;
 pub use span_encoding::{Span, DUMMY_SP};
@@ -434,24 +434,38 @@ pub struct SpanData {
     /// Information about where the macro came from, if this piece of
     /// code was created by a macro expansion.
     pub ctxt: SyntaxContext,
+    pub parent: Option<LocalDefId>,
 }
 
 impl SpanData {
     #[inline]
     pub fn span(&self) -> Span {
-        Span::new(self.lo, self.hi, self.ctxt)
+        Span::new(self.lo, self.hi, self.ctxt, self.parent)
     }
     #[inline]
     pub fn with_lo(&self, lo: BytePos) -> Span {
-        Span::new(lo, self.hi, self.ctxt)
+        Span::new(lo, self.hi, self.ctxt, self.parent)
     }
     #[inline]
     pub fn with_hi(&self, hi: BytePos) -> Span {
-        Span::new(self.lo, hi, self.ctxt)
+        Span::new(self.lo, hi, self.ctxt, self.parent)
     }
     #[inline]
     pub fn with_ctxt(&self, ctxt: SyntaxContext) -> Span {
-        Span::new(self.lo, self.hi, ctxt)
+        Span::new(self.lo, self.hi, ctxt, self.parent)
+    }
+    #[inline]
+    pub fn with_parent(&self, parent: Option<LocalDefId>) -> Span {
+        Span::new(self.lo, self.hi, self.ctxt, parent)
+    }
+    /// Returns `true` if this is a dummy span with any hygienic context.
+    #[inline]
+    pub fn is_dummy(self) -> bool {
+        self.lo.0 == 0 && self.hi.0 == 0
+    }
+    /// Returns `true` if `self` fully encloses `other`.
+    pub fn contains(self, other: Self) -> bool {
+        self.lo <= other.lo && other.hi <= self.hi
     }
 }
 
@@ -507,18 +521,25 @@ pub fn with_hi(self, hi: BytePos) -> Span {
     }
     #[inline]
     pub fn ctxt(self) -> SyntaxContext {
-        self.data().ctxt
+        self.data_untracked().ctxt
     }
     #[inline]
     pub fn with_ctxt(self, ctxt: SyntaxContext) -> Span {
-        self.data().with_ctxt(ctxt)
+        self.data_untracked().with_ctxt(ctxt)
+    }
+    #[inline]
+    pub fn parent(self) -> Option<LocalDefId> {
+        self.data().parent
+    }
+    #[inline]
+    pub fn with_parent(self, ctxt: Option<LocalDefId>) -> Span {
+        self.data().with_parent(ctxt)
     }
 
     /// Returns `true` if this is a dummy span with any hygienic context.
     #[inline]
     pub fn is_dummy(self) -> bool {
-        let span = self.data();
-        span.lo.0 == 0 && span.hi.0 == 0
+        self.data_untracked().is_dummy()
     }
 
     /// Returns `true` if this span comes from a macro or desugaring.
@@ -534,26 +555,26 @@ pub fn in_derive_expansion(self) -> bool {
 
     #[inline]
     pub fn with_root_ctxt(lo: BytePos, hi: BytePos) -> Span {
-        Span::new(lo, hi, SyntaxContext::root())
+        Span::new(lo, hi, SyntaxContext::root(), None)
     }
 
     /// Returns a new span representing an empty span at the beginning of this span.
     #[inline]
     pub fn shrink_to_lo(self) -> Span {
-        let span = self.data();
+        let span = self.data_untracked();
         span.with_hi(span.lo)
     }
     /// Returns a new span representing an empty span at the end of this span.
     #[inline]
     pub fn shrink_to_hi(self) -> Span {
-        let span = self.data();
+        let span = self.data_untracked();
         span.with_lo(span.hi)
     }
 
     #[inline]
     /// Returns `true` if `hi == lo`.
     pub fn is_empty(&self) -> bool {
-        let span = self.data();
+        let span = self.data_untracked();
         span.hi == span.lo
     }
 
@@ -566,7 +587,7 @@ pub fn substitute_dummy(self, other: Span) -> Span {
     pub fn contains(self, other: Span) -> bool {
         let span = self.data();
         let other = other.data();
-        span.lo <= other.lo && other.hi <= span.hi
+        span.contains(other)
     }
 
     /// Returns `true` if `self` touches `other`.
@@ -602,7 +623,7 @@ pub fn source_callsite(self) -> Span {
 
     /// The `Span` for the tokens in the previous macro expansion from which `self` was generated,
     /// if any.
-    pub fn parent(self) -> Option<Span> {
+    pub fn parent_callsite(self) -> Option<Span> {
         let expn_data = self.ctxt().outer_expn_data();
         if !expn_data.is_root() { Some(expn_data.call_site) } else { None }
     }
@@ -610,7 +631,7 @@ pub fn parent(self) -> Option<Span> {
     /// Walk down the expansion ancestors to find a span that's contained within `outer`.
     pub fn find_ancestor_inside(mut self, outer: Span) -> Option<Span> {
         while !outer.contains(self) {
-            self = self.parent()?;
+            self = self.parent_callsite()?;
         }
         Some(self)
     }
@@ -731,6 +752,7 @@ pub fn to(self, end: Span) -> Span {
             cmp::min(span_data.lo, end_data.lo),
             cmp::max(span_data.hi, end_data.hi),
             if span_data.ctxt == SyntaxContext::root() { end_data.ctxt } else { span_data.ctxt },
+            if span_data.parent == end_data.parent { span_data.parent } else { None },
         )
     }
 
@@ -748,6 +770,7 @@ pub fn between(self, end: Span) -> Span {
             span.hi,
             end.lo,
             if end.ctxt == SyntaxContext::root() { end.ctxt } else { span.ctxt },
+            if span.parent == end.parent { span.parent } else { None },
         )
     }
 
@@ -765,6 +788,7 @@ pub fn until(self, end: Span) -> Span {
             span.lo,
             end.lo,
             if end.ctxt == SyntaxContext::root() { end.ctxt } else { span.ctxt },
+            if span.parent == end.parent { span.parent } else { None },
         )
     }
 
@@ -774,6 +798,7 @@ pub fn from_inner(self, inner: InnerSpan) -> Span {
             span.lo + BytePos::from_usize(inner.start),
             span.lo + BytePos::from_usize(inner.end),
             span.ctxt,
+            span.parent,
         )
     }
 
@@ -812,7 +837,7 @@ pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span {
     pub fn remove_mark(&mut self) -> ExpnId {
         let mut span = self.data();
         let mark = span.ctxt.remove_mark();
-        *self = Span::new(span.lo, span.hi, span.ctxt);
+        *self = Span::new(span.lo, span.hi, span.ctxt, span.parent);
         mark
     }
 
@@ -820,7 +845,7 @@ pub fn remove_mark(&mut self) -> ExpnId {
     pub fn adjust(&mut self, expn_id: ExpnId) -> Option<ExpnId> {
         let mut span = self.data();
         let mark = span.ctxt.adjust(expn_id);
-        *self = Span::new(span.lo, span.hi, span.ctxt);
+        *self = Span::new(span.lo, span.hi, span.ctxt, span.parent);
         mark
     }
 
@@ -828,7 +853,7 @@ pub fn adjust(&mut self, expn_id: ExpnId) -> Option<ExpnId> {
     pub fn normalize_to_macros_2_0_and_adjust(&mut self, expn_id: ExpnId) -> Option<ExpnId> {
         let mut span = self.data();
         let mark = span.ctxt.normalize_to_macros_2_0_and_adjust(expn_id);
-        *self = Span::new(span.lo, span.hi, span.ctxt);
+        *self = Span::new(span.lo, span.hi, span.ctxt, span.parent);
         mark
     }
 
@@ -836,7 +861,7 @@ pub fn normalize_to_macros_2_0_and_adjust(&mut self, expn_id: ExpnId) -> Option<
     pub fn glob_adjust(&mut self, expn_id: ExpnId, glob_span: Span) -> Option<Option<ExpnId>> {
         let mut span = self.data();
         let mark = span.ctxt.glob_adjust(expn_id, glob_span);
-        *self = Span::new(span.lo, span.hi, span.ctxt);
+        *self = Span::new(span.lo, span.hi, span.ctxt, span.parent);
         mark
     }
 
@@ -848,7 +873,7 @@ pub fn reverse_glob_adjust(
     ) -> Option<Option<ExpnId>> {
         let mut span = self.data();
         let mark = span.ctxt.reverse_glob_adjust(expn_id, glob_span);
-        *self = Span::new(span.lo, span.hi, span.ctxt);
+        *self = Span::new(span.lo, span.hi, span.ctxt, span.parent);
         mark
     }
 
@@ -900,7 +925,7 @@ impl<D: Decoder> Decodable<D> for Span {
             let lo = d.read_struct_field("lo", Decodable::decode)?;
             let hi = d.read_struct_field("hi", Decodable::decode)?;
 
-            Ok(Span::new(lo, hi, SyntaxContext::root()))
+            Ok(Span::new(lo, hi, SyntaxContext::root(), None))
         })
     }
 }
@@ -961,7 +986,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 impl fmt::Debug for SpanData {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        (*SPAN_DEBUG)(Span::new(self.lo, self.hi, self.ctxt), f)
+        (*SPAN_DEBUG)(Span::new(self.lo, self.hi, self.ctxt, self.parent), f)
     }
 }
 
@@ -1922,6 +1947,7 @@ pub struct FileLines {
 
 pub static SPAN_DEBUG: AtomicRef<fn(Span, &mut fmt::Formatter<'_>) -> fmt::Result> =
     AtomicRef::new(&(default_span_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
+pub static SPAN_TRACK: AtomicRef<fn(LocalDefId)> = AtomicRef::new(&((|_| {}) as fn(_)));
 
 // _____________________________________________________________________________
 // SpanLinesError, SpanSnippetError, DistinctSources, MalformedSourceMapPositions
@@ -1976,6 +2002,7 @@ pub fn new(start: usize, end: usize) -> InnerSpan {
 pub trait HashStableContext {
     fn def_path_hash(&self, def_id: DefId) -> DefPathHash;
     fn hash_spans(&self) -> bool;
+    fn def_span(&self, def_id: LocalDefId) -> Span;
     fn span_data_to_lines_and_cols(
         &mut self,
         span: &SpanData,
@@ -1999,22 +2026,35 @@ impl<CTX> HashStable<CTX> for Span
     fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
         const TAG_VALID_SPAN: u8 = 0;
         const TAG_INVALID_SPAN: u8 = 1;
+        const TAG_RELATIVE_SPAN: u8 = 2;
 
         if !ctx.hash_spans() {
             return;
         }
 
-        self.ctxt().hash_stable(ctx, hasher);
+        let span = self.data_untracked();
+        span.ctxt.hash_stable(ctx, hasher);
+        span.parent.hash_stable(ctx, hasher);
 
-        if self.is_dummy() {
+        if span.is_dummy() {
             Hash::hash(&TAG_INVALID_SPAN, hasher);
             return;
         }
 
+        if let Some(parent) = span.parent {
+            let def_span = ctx.def_span(parent).data_untracked();
+            if def_span.contains(span) {
+                // This span is enclosed in a definition: only hash the relative position.
+                Hash::hash(&TAG_RELATIVE_SPAN, hasher);
+                (span.lo - def_span.lo).to_u32().hash_stable(ctx, hasher);
+                (span.hi - def_span.lo).to_u32().hash_stable(ctx, hasher);
+                return;
+            }
+        }
+
         // If this is not an empty or invalid span, we want to hash the last
         // position that belongs to it, as opposed to hashing the first
         // position past it.
-        let span = self.data();
         let (file, line_lo, col_lo, line_hi, col_hi) = match ctx.span_data_to_lines_and_cols(&span)
         {
             Some(pos) => pos,
index 9b8c8594ee843e88d5a4546a5566cfd624a8ed69..9e403eb3f67f3de9424a003c1ef56f68b4f899a2 100644 (file)
@@ -794,7 +794,7 @@ pub fn next_point(&self, sp: Span) -> Span {
             start_of_next_point.checked_add(width - 1).unwrap_or(start_of_next_point);
 
         let end_of_next_point = BytePos(cmp::max(sp.lo().0 + 1, end_of_next_point));
-        Span::new(BytePos(start_of_next_point), end_of_next_point, sp.ctxt())
+        Span::new(BytePos(start_of_next_point), end_of_next_point, sp.ctxt(), None)
     }
 
     /// Finds the width of the character, either before or after the end of provided span,
index cb017709c6c7bfc071268a71779f2c230f34827f..e9120b98aabc6e2e9bae1e71c8ce89418e874b7b 100644 (file)
@@ -4,7 +4,9 @@
 // The encoding format for inline spans were obtained by optimizing over crates in rustc/libstd.
 // See https://internals.rust-lang.org/t/rfc-compiler-refactoring-spans/1357/28
 
+use crate::def_id::LocalDefId;
 use crate::hygiene::SyntaxContext;
+use crate::SPAN_TRACK;
 use crate::{BytePos, SpanData};
 
 use rustc_data_structures::fx::FxIndexSet;
 ///   the code. No crates in `rustc-perf` need more than 15 bits for `ctxt`,
 ///   but larger crates might need more than 16 bits.
 ///
+/// In order to reliably use parented spans in incremental compilation,
+/// the dependency to the parent definition's span. This is performed
+/// using the callback `SPAN_TRACK` to access the query engine.
+///
 #[derive(Clone, Copy, Eq, PartialEq, Hash)]
 pub struct Span {
     base_or_index: u32,
@@ -70,25 +76,42 @@ pub struct Span {
 
 impl Span {
     #[inline]
-    pub fn new(mut lo: BytePos, mut hi: BytePos, ctxt: SyntaxContext) -> Self {
+    pub fn new(
+        mut lo: BytePos,
+        mut hi: BytePos,
+        ctxt: SyntaxContext,
+        parent: Option<LocalDefId>,
+    ) -> Self {
         if lo > hi {
             std::mem::swap(&mut lo, &mut hi);
         }
 
         let (base, len, ctxt2) = (lo.0, hi.0 - lo.0, ctxt.as_u32());
 
-        if len <= MAX_LEN && ctxt2 <= MAX_CTXT {
+        if len <= MAX_LEN && ctxt2 <= MAX_CTXT && parent.is_none() {
             // Inline format.
             Span { base_or_index: base, len_or_tag: len as u16, ctxt_or_zero: ctxt2 as u16 }
         } else {
             // Interned format.
-            let index = with_span_interner(|interner| interner.intern(&SpanData { lo, hi, ctxt }));
+            let index =
+                with_span_interner(|interner| interner.intern(&SpanData { lo, hi, ctxt, parent }));
             Span { base_or_index: index, len_or_tag: LEN_TAG, ctxt_or_zero: 0 }
         }
     }
 
     #[inline]
     pub fn data(self) -> SpanData {
+        let data = self.data_untracked();
+        if let Some(parent) = data.parent {
+            (*SPAN_TRACK)(parent);
+        }
+        data
+    }
+
+    /// Internal function to translate between an encoded span and the expanded representation.
+    /// This function must not be used outside the incremental engine.
+    #[inline]
+    pub fn data_untracked(self) -> SpanData {
         if self.len_or_tag != LEN_TAG {
             // Inline format.
             debug_assert!(self.len_or_tag as u32 <= MAX_LEN);
@@ -96,6 +119,7 @@ pub fn data(self) -> SpanData {
                 lo: BytePos(self.base_or_index),
                 hi: BytePos(self.base_or_index + self.len_or_tag as u32),
                 ctxt: SyntaxContext::from_u32(self.ctxt_or_zero as u32),
+                parent: None,
             }
         } else {
             // Interned format.
index 24023163cc30eb2b2ca072313f21f421f86b5764..c816d06045681ddebc9d40cf9417ade9768973da 100644 (file)
         rustc_synthetic,
         rustc_test_marker,
         rustc_then_this_would_need,
+        rustc_trivial_field_reads,
         rustc_unsafe_specialization_marker,
         rustc_variance,
         rustdoc,
index 28ca93c46921e1cd7f69e770f89e99a7c722b40b..2e00ffc7e14730a916f95b3d3514ad74dc9dfe9d 100644 (file)
@@ -3,7 +3,7 @@
 
 fn extend_integer_width_mips<Ty>(arg: &mut ArgAbi<'_, Ty>, bits: u64) {
     // Always sign extend u32 values on 64-bit mips
-    if let abi::Abi::Scalar(ref scalar) = arg.layout.abi {
+    if let abi::Abi::Scalar(scalar) = arg.layout.abi {
         if let abi::Int(i, signed) = scalar.value {
             if !signed && i.size().bits() == 32 {
                 if let PassMode::Direct(ref mut attrs) = arg.mode {
@@ -23,7 +23,7 @@ fn float_reg<'a, Ty, C>(cx: &C, ret: &ArgAbi<'a, Ty>, i: usize) -> Option<Reg>
     C: HasDataLayout,
 {
     match ret.layout.field(cx, i).abi {
-        abi::Abi::Scalar(ref scalar) => match scalar.value {
+        abi::Abi::Scalar(scalar) => match scalar.value {
             abi::F32 => Some(Reg::f32()),
             abi::F64 => Some(Reg::f64()),
             _ => None,
@@ -107,7 +107,7 @@ fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
                 let offset = arg.layout.fields.offset(i);
 
                 // We only care about aligned doubles
-                if let abi::Abi::Scalar(ref scalar) = field.abi {
+                if let abi::Abi::Scalar(scalar) = field.abi {
                     if let abi::F64 = scalar.value {
                         if offset.is_aligned(dl.f64_align.abi) {
                             // Insert enough integers to cover [last_offset, offset)
index 6d3c7318091076fbcbb0b2f7b5fab6c70ef5cfc7..927bebd8157a629aac8499de65420baece8947c7 100644 (file)
@@ -322,7 +322,7 @@ pub fn homogeneous_aggregate<C>(&self, cx: &C) -> Result<HomogeneousAggregate, H
             Abi::Uninhabited => Err(Heterogeneous),
 
             // The primitive for this algorithm.
-            Abi::Scalar(ref scalar) => {
+            Abi::Scalar(scalar) => {
                 let kind = match scalar.value {
                     abi::Int(..) | abi::Pointer => RegKind::Integer,
                     abi::F32 | abi::F64 => RegKind::Float,
@@ -450,9 +450,9 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
     pub fn new(
         cx: &impl HasDataLayout,
         layout: TyAndLayout<'a, Ty>,
-        scalar_attrs: impl Fn(&TyAndLayout<'a, Ty>, &abi::Scalar, Size) -> ArgAttributes,
+        scalar_attrs: impl Fn(&TyAndLayout<'a, Ty>, abi::Scalar, Size) -> ArgAttributes,
     ) -> Self {
-        let mode = match &layout.abi {
+        let mode = match layout.abi {
             Abi::Uninhabited => PassMode::Ignore,
             Abi::Scalar(scalar) => PassMode::Direct(scalar_attrs(&layout, scalar, Size::ZERO)),
             Abi::ScalarPair(a, b) => PassMode::Pair(
@@ -504,7 +504,7 @@ pub fn make_indirect_byval(&mut self) {
 
     pub fn extend_integer_width_to(&mut self, bits: u64) {
         // Only integers have signedness
-        if let Abi::Scalar(ref scalar) = self.layout.abi {
+        if let Abi::Scalar(scalar) = self.layout.abi {
             if let abi::Int(i, signed) = scalar.value {
                 if i.size().bits() < bits {
                     if let PassMode::Direct(ref mut attrs) = self.mode {
index 8c2ef8c7a017dfe130e2ac1799faee0241fdaff3..bbefc73a076d7dd7ccb0b10efc8b7a6ac5a21e99 100644 (file)
@@ -44,7 +44,7 @@ fn should_use_fp_conv_helper<'a, Ty, C>(
     Ty: TyAbiInterface<'a, C> + Copy,
 {
     match arg_layout.abi {
-        Abi::Scalar(ref scalar) => match scalar.value {
+        Abi::Scalar(scalar) => match scalar.value {
             abi::Int(..) | abi::Pointer => {
                 if arg_layout.size.bits() > xlen {
                     return Err(CannotUseFpConv);
@@ -297,7 +297,7 @@ fn classify_arg<'a, Ty, C>(
 }
 
 fn extend_integer_width<'a, Ty>(arg: &mut ArgAbi<'a, Ty>, xlen: u64) {
-    if let Abi::Scalar(ref scalar) = arg.layout.abi {
+    if let Abi::Scalar(scalar) = arg.layout.abi {
         if let abi::Int(i, _) = scalar.value {
             // 32-bit integers are always sign-extended
             if i.size().bits() == 32 && xlen > 32 {
index 594108925de8093e4ac90159ab035c714aff2c9b..38aaee64a4d6b6978daa0a02c0933aed38542958 100644 (file)
@@ -18,7 +18,7 @@ fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>) -> bool
     C: HasDataLayout,
 {
     match layout.abi {
-        abi::Abi::Scalar(ref scalar) => scalar.value.is_float(),
+        abi::Abi::Scalar(scalar) => scalar.value.is_float(),
         abi::Abi::Aggregate { .. } => {
             if layout.fields.count() == 1 && layout.fields.offset(0).bytes() == 0 {
                 is_single_fp_element(cx, layout.field(cx, 0))
index 3fc197b5d7537f494c7e830c776c19526b3324d5..28064d85bf1710ae6a218d43060951af9a763e5b 100644 (file)
@@ -14,7 +14,7 @@ fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>) -> bool
     C: HasDataLayout,
 {
     match layout.abi {
-        abi::Abi::Scalar(ref scalar) => scalar.value.is_float(),
+        abi::Abi::Scalar(scalar) => scalar.value.is_float(),
         abi::Abi::Aggregate { .. } => {
             if layout.fields.count() == 1 && layout.fields.offset(0).bytes() == 0 {
                 is_single_fp_element(cx, layout.field(cx, 0))
index 08f0aaba59af4891333db4179448682a8f314464..fae3c3af61bf01f02c41f72f1978ff7036513671 100644 (file)
@@ -49,7 +49,7 @@ fn classify<'a, Ty, C>(
         let mut c = match layout.abi {
             Abi::Uninhabited => return Ok(()),
 
-            Abi::Scalar(ref scalar) => match scalar.value {
+            Abi::Scalar(scalar) => match scalar.value {
                 abi::Int(..) | abi::Pointer => Class::Int,
                 abi::F32 | abi::F64 => Class::Sse,
             },
index b0ecd117dd20e89b4016bcb6660cfc9cb19e9e9a..af75007b09ae516457d4293aa49ee69541ca75da 100644 (file)
@@ -7,7 +7,7 @@
 use std::fmt;
 use std::iter::Step;
 use std::num::NonZeroUsize;
-use std::ops::{Add, AddAssign, Deref, Mul, Range, RangeInclusive, Sub};
+use std::ops::{Add, AddAssign, Deref, Mul, RangeInclusive, Sub};
 use std::str::FromStr;
 
 use rustc_index::vec::{Idx, IndexVec};
@@ -392,6 +392,21 @@ pub fn truncate(self, value: u128) -> u128 {
         // Truncate (shift left to drop out leftover values, shift right to fill with zeroes).
         (value << shift) >> shift
     }
+
+    #[inline]
+    pub fn signed_int_min(&self) -> i128 {
+        self.sign_extend(1_u128 << (self.bits() - 1)) as i128
+    }
+
+    #[inline]
+    pub fn signed_int_max(&self) -> i128 {
+        i128::MAX >> (128 - self.bits())
+    }
+
+    #[inline]
+    pub fn unsigned_int_max(&self) -> u128 {
+        u128::MAX >> (128 - self.bits())
+    }
 }
 
 // Panicking addition, subtraction and multiplication for convenience.
@@ -739,9 +754,8 @@ pub fn is_int(self) -> bool {
 ///
 ///    254 (-2), 255 (-1), 0, 1, 2
 ///
-/// This is intended specifically to mirror LLVM’s `!range` metadata,
-/// semantics.
-#[derive(Clone, PartialEq, Eq, Hash)]
+/// This is intended specifically to mirror LLVM’s `!range` metadata semantics.
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
 #[derive(HashStable_Generic)]
 pub struct WrappingRange {
     pub start: u128,
@@ -759,13 +773,6 @@ pub fn contains(&self, v: u128) -> bool {
         }
     }
 
-    /// Returns `true` if zero is contained in the range.
-    /// Equal to `range.contains(0)` but should be faster.
-    #[inline(always)]
-    pub fn contains_zero(&self) -> bool {
-        self.start > self.end || self.start == 0
-    }
-
     /// Returns `self` with replaced `start`
     #[inline(always)]
     pub fn with_start(mut self, start: u128) -> Self {
@@ -779,17 +786,29 @@ pub fn with_end(mut self, end: u128) -> Self {
         self.end = end;
         self
     }
+
+    /// Returns `true` if `size` completely fills the range.
+    #[inline]
+    pub fn is_full_for(&self, size: Size) -> bool {
+        let max_value = size.unsigned_int_max();
+        debug_assert!(self.start <= max_value && self.end <= max_value);
+        self.start == (self.end.wrapping_add(1) & max_value)
+    }
 }
 
 impl fmt::Debug for WrappingRange {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(fmt, "{}..={}", self.start, self.end)?;
+        if self.start > self.end {
+            write!(fmt, "(..={}) | ({}..)", self.end, self.start)?;
+        } else {
+            write!(fmt, "{}..={}", self.start, self.end)?;
+        }
         Ok(())
     }
 }
 
 /// Information about one scalar component of a Rust type.
-#[derive(Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub struct Scalar {
     pub value: Primitive,
@@ -803,25 +822,16 @@ pub struct Scalar {
 impl Scalar {
     #[inline]
     pub fn is_bool(&self) -> bool {
-        matches!(self.value, Int(I8, false))
-            && matches!(self.valid_range, WrappingRange { start: 0, end: 1 })
+        matches!(
+            self,
+            Scalar { value: Int(I8, false), valid_range: WrappingRange { start: 0, end: 1 } }
+        )
     }
 
-    /// Returns the valid range as a `x..y` range.
-    ///
-    /// If `x` and `y` are equal, the range is full, not empty.
-    pub fn valid_range_exclusive<C: HasDataLayout>(&self, cx: &C) -> Range<u128> {
-        // For a (max) value of -1, max will be `-1 as usize`, which overflows.
-        // However, that is fine here (it would still represent the full range),
-        // i.e., if the range is everything.
-        let bits = self.value.size(cx).bits();
-        assert!(bits <= 128);
-        let mask = !0u128 >> (128 - bits);
-        let start = self.valid_range.start;
-        let end = self.valid_range.end;
-        assert_eq!(start, start & mask);
-        assert_eq!(end, end & mask);
-        start..(end.wrapping_add(1) & mask)
+    /// Returns `true` if all possible numbers are valid, i.e `valid_range` covers the whole layout
+    #[inline]
+    pub fn is_always_valid<C: HasDataLayout>(&self, cx: &C) -> bool {
+        self.valid_range.is_full_for(self.value.size(cx))
     }
 }
 
@@ -960,7 +970,7 @@ impl AddressSpace {
 
 /// Describes how values of the type are passed by target ABIs,
 /// in terms of categories of C types there are ABI rules for.
-#[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
 pub enum Abi {
     Uninhabited,
     Scalar(Scalar),
@@ -988,8 +998,8 @@ pub fn is_unsized(&self) -> bool {
     /// Returns `true` if this is a single signed integer scalar
     #[inline]
     pub fn is_signed(&self) -> bool {
-        match *self {
-            Abi::Scalar(ref scal) => match scal.value {
+        match self {
+            Abi::Scalar(scal) => match scal.value {
                 Primitive::Int(_, signed) => signed,
                 _ => false,
             },
@@ -1058,7 +1068,7 @@ pub enum TagEncoding {
     },
 }
 
-#[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
 pub struct Niche {
     pub offset: Size,
     pub scalar: Scalar,
@@ -1071,10 +1081,10 @@ pub fn from_scalar<C: HasDataLayout>(cx: &C, offset: Size, scalar: Scalar) -> Op
     }
 
     pub fn available<C: HasDataLayout>(&self, cx: &C) -> u128 {
-        let Scalar { value, valid_range: ref v } = self.scalar;
-        let bits = value.size(cx).bits();
-        assert!(bits <= 128);
-        let max_value = !0u128 >> (128 - bits);
+        let Scalar { value, valid_range: v } = self.scalar;
+        let size = value.size(cx);
+        assert!(size.bits() <= 128);
+        let max_value = size.unsigned_int_max();
 
         // Find out how many values are outside the valid range.
         let niche = v.end.wrapping_add(1)..v.start;
@@ -1084,10 +1094,10 @@ pub fn available<C: HasDataLayout>(&self, cx: &C) -> u128 {
     pub fn reserve<C: HasDataLayout>(&self, cx: &C, count: u128) -> Option<(u128, Scalar)> {
         assert!(count > 0);
 
-        let Scalar { value, valid_range: v } = self.scalar.clone();
-        let bits = value.size(cx).bits();
-        assert!(bits <= 128);
-        let max_value = !0u128 >> (128 - bits);
+        let Scalar { value, valid_range: v } = self.scalar;
+        let size = value.size(cx);
+        assert!(size.bits() <= 128);
+        let max_value = size.unsigned_int_max();
 
         if count > max_value {
             return None;
@@ -1138,7 +1148,7 @@ pub struct Layout {
 
 impl Layout {
     pub fn scalar<C: HasDataLayout>(cx: &C, scalar: Scalar) -> Self {
-        let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar.clone());
+        let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar);
         let size = scalar.value.size(cx);
         let align = scalar.value.align(cx);
         Layout {
@@ -1264,25 +1274,22 @@ pub fn might_permit_raw_init<C>(self, cx: &C, zero: bool) -> bool
         Ty: TyAbiInterface<'a, C>,
         C: HasDataLayout,
     {
-        let scalar_allows_raw_init = move |s: &Scalar| -> bool {
+        let scalar_allows_raw_init = move |s: Scalar| -> bool {
             if zero {
                 // The range must contain 0.
-                s.valid_range.contains_zero()
+                s.valid_range.contains(0)
             } else {
-                // The range must include all values. `valid_range_exclusive` handles
-                // the wrap-around using target arithmetic; with wrap-around then the full
-                // range is one where `start == end`.
-                let range = s.valid_range_exclusive(cx);
-                range.start == range.end
+                // The range must include all values.
+                s.is_always_valid(cx)
             }
         };
 
         // Check the ABI.
-        let valid = match &self.abi {
+        let valid = match self.abi {
             Abi::Uninhabited => false, // definitely UB
             Abi::Scalar(s) => scalar_allows_raw_init(s),
             Abi::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2),
-            Abi::Vector { element: s, count } => *count == 0 || scalar_allows_raw_init(s),
+            Abi::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s),
             Abi::Aggregate { .. } => true, // Fields are checked below.
         };
         if !valid {
diff --git a/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs b/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs
new file mode 100644 (file)
index 0000000..01f5c19
--- /dev/null
@@ -0,0 +1,43 @@
+use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions};
+
+/// A base target for Nintendo 3DS devices using the devkitARM toolchain.
+///
+/// Requires the devkitARM toolchain for 3DS targets on the host system.
+
+pub fn target() -> Target {
+    let mut pre_link_args = LinkArgs::new();
+    pre_link_args.insert(
+        LinkerFlavor::Gcc,
+        vec![
+            "-specs=3dsx.specs".to_string(),
+            "-mtune=mpcore".to_string(),
+            "-mfloat-abi=hard".to_string(),
+            "-mtp=soft".to_string(),
+        ],
+    );
+
+    Target {
+        llvm_target: "armv6k-none-eabihf".to_string(),
+        pointer_width: 32,
+        data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+
+        options: TargetOptions {
+            os: "horizon".to_string(),
+            env: "newlib".to_string(),
+            vendor: "nintendo".to_string(),
+            abi: "eabihf".to_string(),
+            linker_flavor: LinkerFlavor::Gcc,
+            cpu: "mpcore".to_string(),
+            executables: true,
+            families: vec!["unix".to_string()],
+            linker: Some("arm-none-eabi-gcc".to_string()),
+            relocation_model: RelocModel::Static,
+            features: "+vfp2".to_string(),
+            pre_link_args,
+            exe_suffix: ".elf".to_string(),
+            panic_strategy: PanicStrategy::Abort,
+            ..Default::default()
+        },
+    }
+}
index 273221360b8b561ca9d1d5d265956861369f6488..920a929544abb31f0b3be9229f7f08370fe36c4d 100644 (file)
@@ -941,6 +941,8 @@ fn $module() {
 
     ("bpfeb-unknown-none", bpfeb_unknown_none),
     ("bpfel-unknown-none", bpfel_unknown_none),
+
+    ("armv6k-nintendo-3ds", armv6k_nintendo_3ds),
 }
 
 /// Warnings encountered when parsing the target `json`.
index c90649353e80f391b5739378a3bd29813bd5e22f..42cbed600d5bf92229ca6f6ff55002ded9d53d2c 100644 (file)
@@ -2,6 +2,7 @@
 use crate::traits::query::outlives_bounds::InferCtxtExt as _;
 use crate::traits::{self, TraitEngine, TraitEngineExt};
 
+use rustc_data_structures::stable_set::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
@@ -184,7 +185,7 @@ pub trait OutlivesEnvironmentExt<'tcx> {
     fn add_implied_bounds(
         &mut self,
         infcx: &InferCtxt<'a, 'tcx>,
-        fn_sig_tys: &[Ty<'tcx>],
+        fn_sig_tys: FxHashSet<Ty<'tcx>>,
         body_id: hir::HirId,
         span: Span,
     );
@@ -210,13 +211,13 @@ impl<'tcx> OutlivesEnvironmentExt<'tcx> for OutlivesEnvironment<'tcx> {
     fn add_implied_bounds(
         &mut self,
         infcx: &InferCtxt<'a, 'tcx>,
-        fn_sig_tys: &[Ty<'tcx>],
+        fn_sig_tys: FxHashSet<Ty<'tcx>>,
         body_id: hir::HirId,
         span: Span,
     ) {
         debug!("add_implied_bounds()");
 
-        for &ty in fn_sig_tys {
+        for ty in fn_sig_tys {
             let ty = infcx.resolve_vars_if_possible(ty);
             debug!("add_implied_bounds: ty = {}", ty);
             let implied_bounds = infcx.implied_outlives_bounds(self.param_env, body_id, ty, span);
index ddabe5967d79cf9566fd923249ce4bfcc4658bae..24fa5007f1ecdc446f528a307edd28f11ec0efd7 100644 (file)
@@ -6,16 +6,16 @@
 //! this is not as easy.
 //!
 //! In this case we try to build an abstract representation of this constant using
-//! `mir_abstract_const` which can then be checked for structural equality with other
+//! `thir_abstract_const` which can then be checked for structural equality with other
 //! generic constants mentioned in the `caller_bounds` of the current environment.
 use rustc_errors::ErrorReported;
 use rustc_hir::def::DefKind;
-use rustc_index::bit_set::BitSet;
 use rustc_index::vec::IndexVec;
 use rustc_infer::infer::InferCtxt;
-use rustc_middle::mir::abstract_const::{Node, NodeId, NotConstEvaluatable};
+use rustc_middle::mir;
 use rustc_middle::mir::interpret::ErrorHandled;
-use rustc_middle::mir::{self, Rvalue, StatementKind, TerminatorKind};
+use rustc_middle::thir;
+use rustc_middle::thir::abstract_const::{self, Node, NodeId, NotConstEvaluatable};
 use rustc_middle::ty::subst::{Subst, SubstsRef};
 use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
 use rustc_session::lint;
@@ -196,7 +196,7 @@ pub fn new(
         tcx: TyCtxt<'tcx>,
         uv: ty::Unevaluated<'tcx, ()>,
     ) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> {
-        let inner = tcx.mir_abstract_const_opt_const_arg(uv.def)?;
+        let inner = tcx.thir_abstract_const_opt_const_arg(uv.def)?;
         debug!("AbstractConst::new({:?}) = {:?}", uv, inner);
         Ok(inner.map(|inner| AbstractConst { inner, substs: uv.substs(tcx) }))
     }
@@ -223,35 +223,24 @@ pub fn root(self) -> Node<'tcx> {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-struct WorkNode<'tcx> {
-    node: Node<'tcx>,
-    span: Span,
-    used: bool,
-}
-
 struct AbstractConstBuilder<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
-    body: &'a mir::Body<'tcx>,
+    body_id: thir::ExprId,
+    body: &'a thir::Thir<'tcx>,
     /// The current WIP node tree.
-    ///
-    /// We require all nodes to be used in the final abstract const,
-    /// so we store this here. Note that we also consider nodes as used
-    /// if they are mentioned in an assert, so some used nodes are never
-    /// actually reachable by walking the [`AbstractConst`].
-    nodes: IndexVec<NodeId, WorkNode<'tcx>>,
-    locals: IndexVec<mir::Local, NodeId>,
-    /// We only allow field accesses if they access
-    /// the result of a checked operation.
-    checked_op_locals: BitSet<mir::Local>,
+    nodes: IndexVec<NodeId, Node<'tcx>>,
 }
 
 impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
+    fn root_span(&self) -> Span {
+        self.body.exprs[self.body_id].span
+    }
+
     fn error(&mut self, span: Option<Span>, msg: &str) -> Result<!, ErrorReported> {
         self.tcx
             .sess
-            .struct_span_err(self.body.span, "overly complex generic constant")
-            .span_label(span.unwrap_or(self.body.span), msg)
+            .struct_span_err(self.root_span(), "overly complex generic constant")
+            .span_label(span.unwrap_or(self.root_span()), msg)
             .help("consider moving this anonymous constant into a `const` function")
             .emit();
 
@@ -260,98 +249,49 @@ fn error(&mut self, span: Option<Span>, msg: &str) -> Result<!, ErrorReported> {
 
     fn new(
         tcx: TyCtxt<'tcx>,
-        body: &'a mir::Body<'tcx>,
+        (body, body_id): (&'a thir::Thir<'tcx>, thir::ExprId),
     ) -> Result<Option<AbstractConstBuilder<'a, 'tcx>>, ErrorReported> {
-        let mut builder = AbstractConstBuilder {
-            tcx,
-            body,
-            nodes: IndexVec::new(),
-            locals: IndexVec::from_elem(NodeId::MAX, &body.local_decls),
-            checked_op_locals: BitSet::new_empty(body.local_decls.len()),
-        };
-
-        // We don't have to look at concrete constants, as we
-        // can just evaluate them.
-        if !body.is_polymorphic {
-            return Ok(None);
-        }
+        let builder = AbstractConstBuilder { tcx, body_id, body, nodes: IndexVec::new() };
 
-        // We only allow consts without control flow, so
-        // we check for cycles here which simplifies the
-        // rest of this implementation.
-        if body.is_cfg_cyclic() {
-            builder.error(None, "cyclic anonymous constants are forbidden")?;
+        struct IsThirPolymorphic<'a, 'tcx> {
+            is_poly: bool,
+            thir: &'a thir::Thir<'tcx>,
+            tcx: TyCtxt<'tcx>,
         }
 
-        Ok(Some(builder))
-    }
-
-    fn add_node(&mut self, node: Node<'tcx>, span: Span) -> NodeId {
-        // Mark used nodes.
-        match node {
-            Node::Leaf(_) => (),
-            Node::Binop(_, lhs, rhs) => {
-                self.nodes[lhs].used = true;
-                self.nodes[rhs].used = true;
-            }
-            Node::UnaryOp(_, input) => {
-                self.nodes[input].used = true;
-            }
-            Node::FunctionCall(func, nodes) => {
-                self.nodes[func].used = true;
-                nodes.iter().for_each(|&n| self.nodes[n].used = true);
+        use thir::visit;
+        impl<'a, 'tcx: 'a> visit::Visitor<'a, 'tcx> for IsThirPolymorphic<'a, 'tcx> {
+            fn thir(&self) -> &'a thir::Thir<'tcx> {
+                &self.thir
             }
-            Node::Cast(_, operand, _) => {
-                self.nodes[operand].used = true;
+
+            fn visit_expr(&mut self, expr: &thir::Expr<'tcx>) {
+                self.is_poly |= expr.ty.definitely_has_param_types_or_consts(self.tcx);
+                if self.is_poly == false {
+                    visit::walk_expr(self, expr)
+                }
             }
-        }
 
-        // Nodes start as unused.
-        self.nodes.push(WorkNode { node, span, used: false })
-    }
+            fn visit_pat(&mut self, pat: &thir::Pat<'tcx>) {
+                self.is_poly |= pat.ty.definitely_has_param_types_or_consts(self.tcx);
+                if self.is_poly == false {
+                    visit::walk_pat(self, pat);
+                }
+            }
 
-    fn place_to_local(
-        &mut self,
-        span: Span,
-        p: &mir::Place<'tcx>,
-    ) -> Result<mir::Local, ErrorReported> {
-        const ZERO_FIELD: mir::Field = mir::Field::from_usize(0);
-        // Do not allow any projections.
-        //
-        // One exception are field accesses on the result of checked operations,
-        // which are required to support things like `1 + 2`.
-        if let Some(p) = p.as_local() {
-            debug_assert!(!self.checked_op_locals.contains(p));
-            Ok(p)
-        } else if let &[mir::ProjectionElem::Field(ZERO_FIELD, _)] = p.projection.as_ref() {
-            // Only allow field accesses if the given local
-            // contains the result of a checked operation.
-            if self.checked_op_locals.contains(p.local) {
-                Ok(p.local)
-            } else {
-                self.error(Some(span), "unsupported projection")?;
+            fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) {
+                self.is_poly |= ct.definitely_has_param_types_or_consts(self.tcx);
             }
-        } else {
-            self.error(Some(span), "unsupported projection")?;
         }
-    }
 
-    fn operand_to_node(
-        &mut self,
-        span: Span,
-        op: &mir::Operand<'tcx>,
-    ) -> Result<NodeId, ErrorReported> {
-        debug!("operand_to_node: op={:?}", op);
-        match op {
-            mir::Operand::Copy(p) | mir::Operand::Move(p) => {
-                let local = self.place_to_local(span, p)?;
-                Ok(self.locals[local])
-            }
-            mir::Operand::Constant(ct) => match ct.literal {
-                mir::ConstantKind::Ty(ct) => Ok(self.add_node(Node::Leaf(ct), span)),
-                mir::ConstantKind::Val(..) => self.error(Some(span), "unsupported constant")?,
-            },
+        let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body, tcx };
+        visit::walk_expr(&mut is_poly_vis, &body[body_id]);
+        debug!("AbstractConstBuilder: is_poly={}", is_poly_vis.is_poly);
+        if is_poly_vis.is_poly == false {
+            return Ok(None);
         }
+
+        Ok(Some(builder))
     }
 
     /// We do not allow all binary operations in abstract consts, so filter disallowed ones.
@@ -373,170 +313,126 @@ fn check_unop(op: mir::UnOp) -> bool {
         }
     }
 
-    fn build_statement(&mut self, stmt: &mir::Statement<'tcx>) -> Result<(), ErrorReported> {
-        debug!("AbstractConstBuilder: stmt={:?}", stmt);
-        let span = stmt.source_info.span;
-        match stmt.kind {
-            StatementKind::Assign(box (ref place, ref rvalue)) => {
-                let local = self.place_to_local(span, place)?;
-                match *rvalue {
-                    Rvalue::Use(ref operand) => {
-                        self.locals[local] = self.operand_to_node(span, operand)?;
-                        Ok(())
-                    }
-                    Rvalue::BinaryOp(op, box (ref lhs, ref rhs)) if Self::check_binop(op) => {
-                        let lhs = self.operand_to_node(span, lhs)?;
-                        let rhs = self.operand_to_node(span, rhs)?;
-                        self.locals[local] = self.add_node(Node::Binop(op, lhs, rhs), span);
-                        if op.is_checkable() {
-                            bug!("unexpected unchecked checkable binary operation");
-                        } else {
-                            Ok(())
-                        }
-                    }
-                    Rvalue::CheckedBinaryOp(op, box (ref lhs, ref rhs))
-                        if Self::check_binop(op) =>
-                    {
-                        let lhs = self.operand_to_node(span, lhs)?;
-                        let rhs = self.operand_to_node(span, rhs)?;
-                        self.locals[local] = self.add_node(Node::Binop(op, lhs, rhs), span);
-                        self.checked_op_locals.insert(local);
-                        Ok(())
-                    }
-                    Rvalue::UnaryOp(op, ref operand) if Self::check_unop(op) => {
-                        let operand = self.operand_to_node(span, operand)?;
-                        self.locals[local] = self.add_node(Node::UnaryOp(op, operand), span);
-                        Ok(())
-                    }
-                    Rvalue::Cast(cast_kind, ref operand, ty) => {
-                        let operand = self.operand_to_node(span, operand)?;
-                        self.locals[local] =
-                            self.add_node(Node::Cast(cast_kind, operand, ty), span);
-                        Ok(())
-                    }
-                    _ => self.error(Some(span), "unsupported rvalue")?,
-                }
-            }
-            // These are not actually relevant for us here, so we can ignore them.
-            StatementKind::AscribeUserType(..)
-            | StatementKind::StorageLive(_)
-            | StatementKind::StorageDead(_) => Ok(()),
-            _ => self.error(Some(stmt.source_info.span), "unsupported statement")?,
-        }
-    }
-
-    /// Possible return values:
-    ///
-    /// - `None`: unsupported terminator, stop building
-    /// - `Some(None)`: supported terminator, finish building
-    /// - `Some(Some(block))`: support terminator, build `block` next
-    fn build_terminator(
-        &mut self,
-        terminator: &mir::Terminator<'tcx>,
-    ) -> Result<Option<mir::BasicBlock>, ErrorReported> {
-        debug!("AbstractConstBuilder: terminator={:?}", terminator);
-        match terminator.kind {
-            TerminatorKind::Goto { target } => Ok(Some(target)),
-            TerminatorKind::Return => Ok(None),
-            TerminatorKind::Call {
-                ref func,
-                ref args,
-                destination: Some((ref place, target)),
-                // We do not care about `cleanup` here. Any branch which
-                // uses `cleanup` will fail const-eval and they therefore
-                // do not matter when checking for const evaluatability.
-                //
-                // Do note that even if `panic::catch_unwind` is made const,
-                // we still do not have to care about this, as we do not look
-                // into functions.
-                cleanup: _,
-                // Do not allow overloaded operators for now,
-                // we probably do want to allow this in the future.
-                //
-                // This is currently fairly irrelevant as it requires `const Trait`s.
-                from_hir_call: true,
-                fn_span,
-            } => {
-                let local = self.place_to_local(fn_span, place)?;
-                let func = self.operand_to_node(fn_span, func)?;
-                let args = self.tcx.arena.alloc_from_iter(
-                    args.iter()
-                        .map(|arg| self.operand_to_node(terminator.source_info.span, arg))
-                        .collect::<Result<Vec<NodeId>, _>>()?,
-                );
-                self.locals[local] = self.add_node(Node::FunctionCall(func, args), fn_span);
-                Ok(Some(target))
-            }
-            TerminatorKind::Assert { ref cond, expected: false, target, .. } => {
-                let p = match cond {
-                    mir::Operand::Copy(p) | mir::Operand::Move(p) => p,
-                    mir::Operand::Constant(_) => bug!("unexpected assert"),
-                };
-
-                const ONE_FIELD: mir::Field = mir::Field::from_usize(1);
-                debug!("proj: {:?}", p.projection);
-                if let Some(p) = p.as_local() {
-                    debug_assert!(!self.checked_op_locals.contains(p));
-                    // Mark locals directly used in asserts as used.
-                    //
-                    // This is needed because division does not use `CheckedBinop` but instead
-                    // adds an explicit assert for `divisor != 0`.
-                    self.nodes[self.locals[p]].used = true;
-                    return Ok(Some(target));
-                } else if let &[mir::ProjectionElem::Field(ONE_FIELD, _)] = p.projection.as_ref() {
-                    // Only allow asserts checking the result of a checked operation.
-                    if self.checked_op_locals.contains(p.local) {
-                        return Ok(Some(target));
-                    }
-                }
-
-                self.error(Some(terminator.source_info.span), "unsupported assertion")?;
-            }
-            _ => self.error(Some(terminator.source_info.span), "unsupported terminator")?,
-        }
-    }
-
-    /// Builds the abstract const by walking the mir from start to finish
-    /// and bailing out when encountering an unsupported operation.
+    /// Builds the abstract const by walking the thir and bailing out when
+    /// encountering an unspported operation.
     fn build(mut self) -> Result<&'tcx [Node<'tcx>], ErrorReported> {
-        let mut block = &self.body.basic_blocks()[mir::START_BLOCK];
-        // We checked for a cyclic cfg above, so this should terminate.
-        loop {
-            debug!("AbstractConstBuilder: block={:?}", block);
-            for stmt in block.statements.iter() {
-                self.build_statement(stmt)?;
-            }
+        debug!("Abstractconstbuilder::build: body={:?}", &*self.body);
+        self.recurse_build(self.body_id)?;
 
-            if let Some(next) = self.build_terminator(block.terminator())? {
-                block = &self.body.basic_blocks()[next];
-            } else {
-                break;
-            }
-        }
-
-        assert_eq!(self.locals[mir::RETURN_PLACE], self.nodes.last().unwrap());
         for n in self.nodes.iter() {
-            if let Node::Leaf(ty::Const { val: ty::ConstKind::Unevaluated(ct), ty: _ }) = n.node {
+            if let Node::Leaf(ty::Const { val: ty::ConstKind::Unevaluated(ct), ty: _ }) = n {
                 // `AbstractConst`s should not contain any promoteds as they require references which
                 // are not allowed.
                 assert_eq!(ct.promoted, None);
             }
         }
 
-        self.nodes[self.locals[mir::RETURN_PLACE]].used = true;
-        if let Some(&unused) = self.nodes.iter().find(|n| !n.used) {
-            self.error(Some(unused.span), "dead code")?;
-        }
+        Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter()))
+    }
 
-        Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter().map(|n| n.node)))
+    fn recurse_build(&mut self, node: thir::ExprId) -> Result<NodeId, ErrorReported> {
+        use thir::ExprKind;
+        let node = &self.body.exprs[node];
+        debug!("recurse_build: node={:?}", node);
+        Ok(match &node.kind {
+            // I dont know if handling of these 3 is correct
+            &ExprKind::Scope { value, .. } => self.recurse_build(value)?,
+            &ExprKind::PlaceTypeAscription { source, .. } |
+            &ExprKind::ValueTypeAscription { source, .. } => self.recurse_build(source)?,
+
+            // subtle: associated consts are literals this arm handles
+            // `<T as Trait>::ASSOC` as well as `12`
+            &ExprKind::Literal { literal, .. } => self.nodes.push(Node::Leaf(literal)),
+
+            ExprKind::Call { fun, args,  .. } => {
+                let fun = self.recurse_build(*fun)?;
+
+                let mut new_args = Vec::<NodeId>::with_capacity(args.len());
+                for &id in args.iter() {
+                    new_args.push(self.recurse_build(id)?);
+                }
+                let new_args = self.tcx.arena.alloc_slice(&new_args);
+                self.nodes.push(Node::FunctionCall(fun, new_args))
+            },
+            &ExprKind::Binary { op, lhs, rhs } if Self::check_binop(op) => {
+                let lhs = self.recurse_build(lhs)?;
+                let rhs = self.recurse_build(rhs)?;
+                self.nodes.push(Node::Binop(op, lhs, rhs))
+            }
+            &ExprKind::Unary { op, arg } if Self::check_unop(op) => {
+                let arg = self.recurse_build(arg)?;
+                self.nodes.push(Node::UnaryOp(op, arg))
+            },
+            // This is necessary so that the following compiles:
+            //
+            // ```
+            // fn foo<const N: usize>(a: [(); N + 1]) {
+            //     bar::<{ N + 1 }>();
+            // }
+            // ```
+            ExprKind::Block { body: thir::Block { stmts: box [], expr: Some(e), .. }} => self.recurse_build(*e)?,
+            // `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a
+            // "coercion cast" i.e. using a coercion or is a no-op.
+            // This is important so that `N as usize as usize` doesnt unify with `N as usize`. (untested)
+            &ExprKind::Use { source } => {
+                let arg = self.recurse_build(source)?;
+                self.nodes.push(Node::Cast(abstract_const::CastKind::Use, arg, node.ty))
+            },
+            &ExprKind::Cast { source } => {
+                let arg = self.recurse_build(source)?;
+                self.nodes.push(Node::Cast(abstract_const::CastKind::As, arg, node.ty))
+            },
+
+            // FIXME(generic_const_exprs): We may want to support these.
+            ExprKind::AddressOf { .. }
+            | ExprKind::Borrow { .. }
+            | ExprKind::Deref { .. }
+            | ExprKind::Repeat { .. }
+            | ExprKind::Array { .. }
+            | ExprKind::Block { .. }
+            | ExprKind::NeverToAny { .. }
+            | ExprKind::Tuple { .. }
+            | ExprKind::Index { .. }
+            | ExprKind::Field { .. }
+            | ExprKind::ConstBlock { .. }
+            | ExprKind::Adt(_) => self.error(
+                    Some(node.span),
+                    "unsupported operation in generic constant, this may be supported in the future",
+                )?,
+
+            ExprKind::Match { .. }
+            // we dont permit let stmts so `VarRef` and `UpvarRef` cant happen
+            | ExprKind::VarRef { .. }
+            | ExprKind::UpvarRef { .. }
+            | ExprKind::Closure { .. }
+            | ExprKind::Let { .. } // let expressions imply control flow
+            | ExprKind::Loop { .. }
+            | ExprKind::Assign { .. }
+            | ExprKind::StaticRef { .. }
+            | ExprKind::LogicalOp { .. }
+            // we handle valid unary/binary ops above
+            | ExprKind::Unary { .. }
+            | ExprKind::Binary { .. }
+            | ExprKind::Break { .. }
+            | ExprKind::Continue { .. }
+            | ExprKind::If { .. }
+            | ExprKind::Pointer { .. } // dont know if this is correct
+            | ExprKind::ThreadLocalRef(_)
+            | ExprKind::LlvmInlineAsm { .. }
+            | ExprKind::Return { .. }
+            | ExprKind::Box { .. } // allocations not allowed in constants
+            | ExprKind::AssignOp { .. }
+            | ExprKind::InlineAsm { .. }
+            | ExprKind::Yield { .. } => self.error(Some(node.span), "unsupported operation in generic constant")?,
+        })
     }
 }
 
 /// Builds an abstract const, do not use this directly, but use `AbstractConst::new` instead.
-pub(super) fn mir_abstract_const<'tcx>(
+pub(super) fn thir_abstract_const<'tcx>(
     tcx: TyCtxt<'tcx>,
     def: ty::WithOptConstParam<LocalDefId>,
-) -> Result<Option<&'tcx [mir::abstract_const::Node<'tcx>]>, ErrorReported> {
+) -> Result<Option<&'tcx [thir::abstract_const::Node<'tcx>]>, ErrorReported> {
     if tcx.features().generic_const_exprs {
         match tcx.def_kind(def.did) {
             // FIXME(generic_const_exprs): We currently only do this for anonymous constants,
@@ -547,8 +443,16 @@ pub(super) fn mir_abstract_const<'tcx>(
             DefKind::AnonConst => (),
             _ => return Ok(None),
         }
-        let body = tcx.mir_const(def).borrow();
-        AbstractConstBuilder::new(tcx, &body)?.map(AbstractConstBuilder::build).transpose()
+
+        let body = tcx.thir_body(def);
+        if body.0.borrow().exprs.is_empty() {
+            // type error in constant, there is no thir
+            return Err(ErrorReported);
+        }
+
+        AbstractConstBuilder::new(tcx, (&*body.0.borrow(), body.1))?
+            .map(AbstractConstBuilder::build)
+            .transpose()
     } else {
         Ok(None)
     }
@@ -682,11 +586,16 @@ pub(super) fn try_unify<'tcx>(
                 && iter::zip(a_args, b_args)
                     .all(|(&an, &bn)| try_unify(tcx, a.subtree(an), b.subtree(bn)))
         }
-        (Node::Cast(a_cast_kind, a_operand, a_ty), Node::Cast(b_cast_kind, b_operand, b_ty))
-            if (a_ty == b_ty) && (a_cast_kind == b_cast_kind) =>
+        (Node::Cast(a_kind, a_operand, a_ty), Node::Cast(b_kind, b_operand, b_ty))
+            if (a_ty == b_ty) && (a_kind == b_kind) =>
         {
             try_unify(tcx, a.subtree(a_operand), b.subtree(b_operand))
         }
-        _ => false,
+        // use this over `_ => false` to make adding variants to `Node` less error prone
+        (Node::Cast(..), _)
+        | (Node::FunctionCall(..), _)
+        | (Node::UnaryOp(..), _)
+        | (Node::Binop(..), _)
+        | (Node::Leaf(..), _) => false,
     }
 }
index 9ce6c58a0f1df4b81b08fbb494dff3458169a230..761b217c78f4e49c8734b8c638ef963c68763ee9 100644 (file)
@@ -19,7 +19,7 @@
 use rustc_hir::GenericParam;
 use rustc_hir::Item;
 use rustc_hir::Node;
-use rustc_middle::mir::abstract_const::NotConstEvaluatable;
+use rustc_middle::thir::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::ExpectedFound;
 use rustc_middle::ty::fold::TypeFolder;
 use rustc_middle::ty::{
@@ -249,10 +249,10 @@ fn report_selection_error(
                 if let ObligationCauseCode::WellFormed(Some(wf_loc)) =
                     root_obligation.cause.code.peel_derives()
                 {
-                    if let Some(cause) = self.tcx.diagnostic_hir_wf_check((
-                        tcx.erase_regions(obligation.predicate),
-                        wf_loc.clone(),
-                    )) {
+                    if let Some(cause) = self
+                        .tcx
+                        .diagnostic_hir_wf_check((tcx.erase_regions(obligation.predicate), *wf_loc))
+                    {
                         obligation.cause = cause;
                         span = obligation.cause.span;
                     }
index 0d3fd748645edb266980aa635a32a72f011529d5..9371ff3405eb04aefe6c3eca22c305faffd2349e 100644 (file)
@@ -23,7 +23,7 @@
 use rustc_middle::ty::{TypeAndMut, TypeckResults};
 use rustc_span::def_id::LOCAL_CRATE;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
+use rustc_span::{BytePos, DesugaringKind, ExpnKind, ForLoopLoc, MultiSpan, Span, DUMMY_SP};
 use rustc_target::spec::abi;
 use std::fmt;
 
@@ -680,7 +680,13 @@ fn suggest_add_reference_to_arg(
         points_at_arg: bool,
         has_custom_message: bool,
     ) -> bool {
-        if !points_at_arg {
+        let span = obligation.cause.span;
+        let points_at_for_iter = matches!(
+            span.ctxt().outer_expn_data().kind,
+            ExpnKind::Desugaring(DesugaringKind::ForLoop(ForLoopLoc::IntoIter))
+        );
+
+        if !points_at_arg && !points_at_for_iter {
             return false;
         }
 
@@ -695,7 +701,6 @@ fn suggest_add_reference_to_arg(
 
         never_suggest_borrow.push(self.tcx.get_diagnostic_item(sym::send_trait).unwrap());
 
-        let span = obligation.cause.span;
         let param_env = obligation.param_env;
         let trait_ref = trait_ref.skip_binder();
 
@@ -754,7 +759,11 @@ fn suggest_add_reference_to_arg(
                     );
 
                     // This if is to prevent a special edge-case
-                    if !span.from_expansion() {
+                    if matches!(
+                        span.ctxt().outer_expn_data().kind,
+                        ExpnKind::Root
+                            | ExpnKind::Desugaring(DesugaringKind::ForLoop(ForLoopLoc::IntoIter))
+                    ) {
                         // We don't want a borrowing suggestion on the fields in structs,
                         // ```
                         // struct Foo {
index 18abcc72bcee8d013950671b67c558c7f305c163..b376f4292924963574d690c85d6426119479fa89 100644 (file)
@@ -5,8 +5,8 @@
 use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_infer::traits::{SelectionError, TraitEngine, TraitEngineExt as _, TraitObligation};
-use rustc_middle::mir::abstract_const::NotConstEvaluatable;
 use rustc_middle::mir::interpret::ErrorHandled;
+use rustc_middle::thir::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::ToPredicate;
index 44c675243838a11e1213f6f5131af5edc5803db0..ef208c44471cbadf52d2b5dcdea6af83fc019092 100644 (file)
@@ -827,16 +827,16 @@ pub fn provide(providers: &mut ty::query::Providers) {
         vtable_entries,
         vtable_trait_upcasting_coercion_new_vptr_slot,
         subst_and_check_impossible_predicates,
-        mir_abstract_const: |tcx, def_id| {
+        thir_abstract_const: |tcx, def_id| {
             let def_id = def_id.expect_local();
             if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
-                tcx.mir_abstract_const_of_const_arg(def)
+                tcx.thir_abstract_const_of_const_arg(def)
             } else {
-                const_evaluatable::mir_abstract_const(tcx, ty::WithOptConstParam::unknown(def_id))
+                const_evaluatable::thir_abstract_const(tcx, ty::WithOptConstParam::unknown(def_id))
             }
         },
-        mir_abstract_const_of_const_arg: |tcx, (did, param_did)| {
-            const_evaluatable::mir_abstract_const(
+        thir_abstract_const_of_const_arg: |tcx, (did, param_did)| {
+            const_evaluatable::thir_abstract_const(
                 tcx,
                 ty::WithOptConstParam { did, const_param_did: Some(param_did) },
             )
index 57b8a84300ff9e0db5464fc1759d913c0b6ae9c9..4922cf45a4a109565db5478fb7b53c8a3b5c3e8d 100644 (file)
@@ -465,9 +465,9 @@ fn virtual_call_violation_for_method<'tcx>(
 
             let param_env = tcx.param_env(method.def_id);
 
-            let abi_of_ty = |ty: Ty<'tcx>| -> Option<&Abi> {
+            let abi_of_ty = |ty: Ty<'tcx>| -> Option<Abi> {
                 match tcx.layout_of(param_env.and(ty)) {
-                    Ok(layout) => Some(&layout.abi),
+                    Ok(layout) => Some(layout.abi),
                     Err(err) => {
                         // #78372
                         tcx.sess.delay_span_bug(
@@ -836,7 +836,7 @@ fn visit_unevaluated_const(
             //
             // This shouldn't really matter though as we can't really use any
             // constants which are not considered const evaluatable.
-            use rustc_middle::mir::abstract_const::Node;
+            use rustc_middle::thir::abstract_const::Node;
             if let Ok(Some(ct)) = AbstractConst::new(self.tcx, uv.shrink()) {
                 const_evaluatable::walk_abstract_const(self.tcx, ct, |node| match node.root() {
                     Node::Leaf(leaf) => {
index 7038f16a2c9c4032652964b9c2590f284706f675..92db0ca2a7c403d6c5f6c2666f6f9f33bd158cdd 100644 (file)
@@ -595,7 +595,7 @@ fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
             ty::ReLateBound(debruijn, br) if debruijn >= self.current_index => {
                 let universe = self.universe_for(debruijn);
                 let p = ty::PlaceholderRegion { universe, name: br.kind };
-                self.mapped_regions.insert(p.clone(), br);
+                self.mapped_regions.insert(p, br);
                 self.infcx.tcx.mk_region(ty::RePlaceholder(p))
             }
             _ => r,
@@ -613,7 +613,7 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
             ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
                 let universe = self.universe_for(debruijn);
                 let p = ty::PlaceholderType { universe, name: bound_ty.var };
-                self.mapped_types.insert(p.clone(), bound_ty);
+                self.mapped_types.insert(p, bound_ty);
                 self.infcx.tcx.mk_ty(ty::Placeholder(p))
             }
             _ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self),
@@ -637,7 +637,7 @@ fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
                     universe,
                     name: ty::BoundConst { var: bound_const, ty },
                 };
-                self.mapped_consts.insert(p.clone(), bound_const);
+                self.mapped_consts.insert(p, bound_const);
                 self.infcx.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(p), ty })
             }
             _ if ct.has_vars_bound_at_or_above(self.current_index) => ct.super_fold_with(self),
index 22013fb79cf797d3f68dd9d49a02331ee5e8b331..f5be8bf0949e6ff12caff47d9269a7ca6c2519da 100644 (file)
@@ -34,8 +34,8 @@
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::LateBoundRegionConversionTime;
 use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
-use rustc_middle::mir::abstract_const::NotConstEvaluatable;
 use rustc_middle::mir::interpret::ErrorHandled;
+use rustc_middle::thir::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::fast_reject;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::relate::TypeRelation;
@@ -2445,7 +2445,7 @@ fn get_provisional(
             "get_provisional = {:#?}",
             self.map.borrow().get(&fresh_trait_ref),
         );
-        Some(self.map.borrow().get(&fresh_trait_ref)?.clone())
+        Some(*self.map.borrow().get(&fresh_trait_ref)?)
     }
 
     /// Insert a provisional result into the cache. The result came
index 3c9d5b4def4e7a83a67655167919346a98b78eb7..1fd1253e5277d88a11a57dcf08887d3be94df09c 100644 (file)
@@ -688,7 +688,7 @@ fn check_opaque_meets_bounds<'tcx>(
         // Finally, resolve all regions. This catches wily misuses of
         // lifetime parameters.
         let fcx = FnCtxt::new(&inh, param_env, hir_id);
-        fcx.regionck_item(hir_id, span, &[]);
+        fcx.regionck_item(hir_id, span, FxHashSet::default());
     });
 }
 
index 3bfab9d513f375e6540a3f7471f3c3342d172485..6fe96e4cc27b2f0811939203903e8379b1cc5f4c 100644 (file)
@@ -1003,6 +1003,12 @@ fn try_find_coercion_lub<E>(
             exprs.len()
         );
 
+        // The following check fixes #88097, where the compiler erroneously
+        // attempted to coerce a closure type to itself via a function pointer.
+        if prev_ty == new_ty {
+            return Ok(prev_ty);
+        }
+
         // Special-case that coercion alone cannot handle:
         // Function items or non-capturing closures of differing IDs or InternalSubsts.
         let (a_sig, b_sig) = {
index d59291b8fd493e1a1c2106e7c629585ac3ff167a..d5b631df058aef9c12428677dbfa52f7aec344d3 100644 (file)
@@ -1,4 +1,5 @@
 use crate::errors::LifetimesOrBoundsMismatchOnTrait;
+use rustc_data_structures::stable_set::FxHashSet;
 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorReported};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -250,7 +251,7 @@ fn compare_predicate_entailment<'tcx>(
         // Compute placeholder form of impl and trait method tys.
         let tcx = infcx.tcx;
 
-        let mut wf_tys = vec![];
+        let mut wf_tys = FxHashSet::default();
 
         let (impl_sig, _) = infcx.replace_bound_vars_with_fresh_vars(
             impl_m_span,
@@ -398,7 +399,7 @@ fn compare_predicate_entailment<'tcx>(
         // Finally, resolve all regions. This catches wily misuses of
         // lifetime parameters.
         let fcx = FnCtxt::new(&inh, param_env, impl_m_hir_id);
-        fcx.regionck_item(impl_m_hir_id, impl_m_span, &wf_tys);
+        fcx.regionck_item(impl_m_hir_id, impl_m_span, wf_tys);
 
         Ok(())
     })
@@ -1098,7 +1099,7 @@ fn compare_const_param_types<'tcx>(
         }
 
         let fcx = FnCtxt::new(&inh, param_env, impl_c_hir_id);
-        fcx.regionck_item(impl_c_hir_id, impl_c_span, &[]);
+        fcx.regionck_item(impl_c_hir_id, impl_c_span, FxHashSet::default());
     });
 }
 
@@ -1216,7 +1217,7 @@ fn compare_type_predicate_entailment<'tcx>(
         // Finally, resolve all regions. This catches wily misuses of
         // lifetime parameters.
         let fcx = FnCtxt::new(&inh, param_env, impl_ty_hir_id);
-        fcx.regionck_item(impl_ty_hir_id, impl_ty_span, &[]);
+        fcx.regionck_item(impl_ty_hir_id, impl_ty_span, FxHashSet::default());
 
         Ok(())
     })
@@ -1436,10 +1437,10 @@ pub fn check_type_bounds<'tcx>(
         // lifetime parameters.
         let fcx = FnCtxt::new(&inh, param_env, impl_ty_hir_id);
         let implied_bounds = match impl_ty.container {
-            ty::TraitContainer(_) => vec![],
+            ty::TraitContainer(_) => FxHashSet::default(),
             ty::ImplContainer(def_id) => fcx.impl_implied_bounds(def_id, impl_ty_span),
         };
-        fcx.regionck_item(impl_ty_hir_id, impl_ty_span, &implied_bounds);
+        fcx.regionck_item(impl_ty_hir_id, impl_ty_span, implied_bounds);
 
         Ok(())
     })
index 808685d7fa9c8885038f470c9792050b815ee6de..6c94b5acec7da05fa5bcd8057a01fca7ceb1e10b 100644 (file)
@@ -589,7 +589,8 @@ pub fn check_ref(
                     // E.g. for `&format!("")`, where we want the span to the
                     // `format!()` invocation instead of its expansion.
                     if let Some(call_span) =
-                        iter::successors(Some(expr.span), |s| s.parent()).find(|&s| sp.contains(s))
+                        iter::successors(Some(expr.span), |s| s.parent_callsite())
+                            .find(|&s| sp.contains(s))
                     {
                         if sm.span_to_snippet(call_span).is_ok() {
                             return Some((
index 1c7d68a3d57d4325120a0586c07af81d385d9a64..cbfdce96bc57bdd0b1554f8b4e32ec1e8343faf6 100644 (file)
@@ -186,7 +186,7 @@ pub enum AutorefOrPtrAdjustment<'tcx> {
 impl<'tcx> AutorefOrPtrAdjustment<'tcx> {
     fn get_unsize(&self) -> Option<Ty<'tcx>> {
         match self {
-            AutorefOrPtrAdjustment::Autoref { mutbl: _, unsize } => unsize.clone(),
+            AutorefOrPtrAdjustment::Autoref { mutbl: _, unsize } => *unsize,
             AutorefOrPtrAdjustment::ToConstPtr => None,
         }
     }
index a746ad7ad4bc722b63c1d05287547301a87c87a6..9744f4f6483c75f8fcaf72f9db79c36cbf204219 100644 (file)
@@ -1655,7 +1655,7 @@ fn handle_external_res(
         tcx: TyCtxt<'_>,
         traits: &mut Vec<DefId>,
         external_mods: &mut FxHashSet<DefId>,
-        res: Res,
+        res: Res<!>,
     ) {
         match res {
             Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) => {
index 803c440bbc98b3ae6f06aed391238390d38ea9df..a10490a9a15c7b75a4db20790d62c4bad5e0f394 100644 (file)
@@ -388,7 +388,7 @@ fn typeck_with_fallback<'tcx>(
             // from normalization. We could just discard these, but to align with
             // compare_method and elsewhere, we just add implied bounds for
             // these types.
-            let mut wf_tys = vec![];
+            let mut wf_tys = FxHashSet::default();
             // Compute the fty from point of view of inside the fn.
             let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
             wf_tys.extend(fn_sig.inputs_and_output.iter());
@@ -451,7 +451,7 @@ fn typeck_with_fallback<'tcx>(
 
             fcx.write_ty(id, expected_type);
 
-            (fcx, vec![])
+            (fcx, FxHashSet::default())
         };
 
         let fallback_has_occurred = fcx.type_inference_fallback();
@@ -475,7 +475,7 @@ fn typeck_with_fallback<'tcx>(
         fcx.select_all_obligations_or_error();
 
         if fn_sig.is_some() {
-            fcx.regionck_fn(id, body, span, &wf_tys);
+            fcx.regionck_fn(id, body, span, wf_tys);
         } else {
             fcx.regionck_expr(body);
         }
index 9b495fba1975d01824abb7bb3095de2458d9c289..a574a63d63b28eb259c194969494cac59fbda510 100644 (file)
@@ -680,42 +680,53 @@ pub fn check_user_unop(
                         ex.span,
                         format!("cannot apply unary operator `{}`", op.as_str()),
                     );
-                    match actual.kind() {
-                        Uint(_) if op == hir::UnOp::Neg => {
-                            err.note("unsigned values cannot be negated");
-
-                            if let hir::ExprKind::Unary(
-                                _,
-                                hir::Expr {
-                                    kind:
-                                        hir::ExprKind::Lit(Spanned {
-                                            node: ast::LitKind::Int(1, _),
-                                            ..
-                                        }),
-                                    ..
-                                },
-                            ) = ex.kind
-                            {
-                                err.span_suggestion(
-                                    ex.span,
-                                    &format!(
-                                        "you may have meant the maximum value of `{}`",
-                                        actual
-                                    ),
-                                    format!("{}::MAX", actual),
-                                    Applicability::MaybeIncorrect,
-                                );
+
+                    let sp = self.tcx.sess.source_map().start_point(ex.span);
+                    if let Some(sp) =
+                        self.tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp)
+                    {
+                        // If the previous expression was a block expression, suggest parentheses
+                        // (turning this into a binary subtraction operation instead.)
+                        // for example, `{2} - 2` -> `({2}) - 2` (see src\test\ui\parser\expr-as-stmt.rs)
+                        self.tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp);
+                    } else {
+                        match actual.kind() {
+                            Uint(_) if op == hir::UnOp::Neg => {
+                                err.note("unsigned values cannot be negated");
+
+                                if let hir::ExprKind::Unary(
+                                    _,
+                                    hir::Expr {
+                                        kind:
+                                            hir::ExprKind::Lit(Spanned {
+                                                node: ast::LitKind::Int(1, _),
+                                                ..
+                                            }),
+                                        ..
+                                    },
+                                ) = ex.kind
+                                {
+                                    err.span_suggestion(
+                                        ex.span,
+                                        &format!(
+                                            "you may have meant the maximum value of `{}`",
+                                            actual
+                                        ),
+                                        format!("{}::MAX", actual),
+                                        Applicability::MaybeIncorrect,
+                                    );
+                                }
+                            }
+                            Str | Never | Char | Tuple(_) | Array(_, _) => {}
+                            Ref(_, ref lty, _) if *lty.kind() == Str => {}
+                            _ => {
+                                let missing_trait = match op {
+                                    hir::UnOp::Neg => "std::ops::Neg",
+                                    hir::UnOp::Not => "std::ops::Not",
+                                    hir::UnOp::Deref => "std::ops::UnDerf",
+                                };
+                                suggest_impl_missing(&mut err, operand_ty, &missing_trait);
                             }
-                        }
-                        Str | Never | Char | Tuple(_) | Array(_, _) => {}
-                        Ref(_, ref lty, _) if *lty.kind() == Str => {}
-                        _ => {
-                            let missing_trait = match op {
-                                hir::UnOp::Neg => "std::ops::Neg",
-                                hir::UnOp::Not => "std::ops::Not",
-                                hir::UnOp::Deref => "std::ops::UnDerf",
-                            };
-                            suggest_impl_missing(&mut err, operand_ty, &missing_trait);
                         }
                     }
                     err.emit();
index 290fa5fc36719278954ab0e9963399234d2d9ff3..134604a0e32b41ffea5e291c32ac60097f9011da 100644 (file)
@@ -76,6 +76,7 @@
 use crate::check::FnCtxt;
 use crate::mem_categorization as mc;
 use crate::middle::region;
+use rustc_data_structures::stable_set::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
@@ -126,7 +127,7 @@ pub fn regionck_expr(&self, body: &'tcx hir::Body<'tcx>) {
 
     /// Region checking during the WF phase for items. `wf_tys` are the
     /// 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>]) {
+    pub fn regionck_item(&self, item_id: hir::HirId, span: Span, wf_tys: FxHashSet<Ty<'tcx>>) {
         debug!("regionck_item(item.id={:?}, wf_tys={:?})", item_id, wf_tys);
         let subject = self.tcx.hir().local_def_id(item_id);
         let mut rcx = RegionCtxt::new(self, item_id, Subject(subject), self.param_env);
@@ -149,7 +150,7 @@ pub(crate) fn regionck_fn(
         fn_id: hir::HirId,
         body: &'tcx hir::Body<'tcx>,
         span: Span,
-        wf_tys: &[Ty<'tcx>],
+        wf_tys: FxHashSet<Ty<'tcx>>,
     ) {
         debug!("regionck_fn(id={})", fn_id);
         let subject = self.tcx.hir().body_owner_def_id(body.id());
@@ -286,15 +287,10 @@ fn visit_fn_body(
         // because it will have no effect.
         //
         // FIXME(#27579) return types should not be implied bounds
-        let fn_sig_tys: Vec<_> =
+        let fn_sig_tys: FxHashSet<_> =
             fn_sig.inputs().iter().cloned().chain(Some(fn_sig.output())).collect();
 
-        self.outlives_environment.add_implied_bounds(
-            self.fcx,
-            &fn_sig_tys[..],
-            body_id.hir_id,
-            span,
-        );
+        self.outlives_environment.add_implied_bounds(self.fcx, fn_sig_tys, body_id.hir_id, span);
         self.outlives_environment.save_implied_bounds(body_id.hir_id);
         self.link_fn_params(&body.params);
         self.visit_body(body);
index 17716afe3208fee68882fa83bdeb4d45cd6e6730..cb07fcf5fef5813fba8341be925567b9d55df4cc 100644 (file)
@@ -44,7 +44,7 @@ struct CheckWfFcxBuilder<'tcx> {
 impl<'tcx> CheckWfFcxBuilder<'tcx> {
     fn with_fcx<F>(&mut self, f: F)
     where
-        F: for<'b> FnOnce(&FnCtxt<'b, 'tcx>) -> Vec<Ty<'tcx>>,
+        F: for<'b> FnOnce(&FnCtxt<'b, 'tcx>) -> FxHashSet<Ty<'tcx>>,
     {
         let id = self.id;
         let span = self.span;
@@ -59,7 +59,7 @@ fn with_fcx<F>(&mut self, f: F)
             }
             let wf_tys = f(&fcx);
             fcx.select_all_obligations_or_error();
-            fcx.regionck_item(id, span, &wf_tys);
+            fcx.regionck_item(id, span, wf_tys);
         });
     }
 }
@@ -394,7 +394,7 @@ fn check_associated_item(
         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.types.self_param),
+            ty::TraitContainer(_) => (FxHashSet::default(), fcx.tcx.types.self_param),
             ty::ImplContainer(def_id) => {
                 (fcx.impl_implied_bounds(def_id, span), fcx.tcx.type_of(def_id))
             }
@@ -553,7 +553,7 @@ fn check_type_defn<'tcx, F>(
         check_where_clauses(fcx, item.span, item.def_id.to_def_id(), None);
 
         // No implied bounds in a struct definition.
-        vec![]
+        FxHashSet::default()
     });
 }
 
@@ -579,7 +579,7 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
     for_item(tcx, item).with_fcx(|fcx| {
         check_where_clauses(fcx, item.span, item.def_id.to_def_id(), None);
 
-        vec![]
+        FxHashSet::default()
     });
 }
 
@@ -620,7 +620,7 @@ fn check_item_fn(
     for_id(tcx, item_id, span).with_fcx(|fcx| {
         let def_id = tcx.hir().local_def_id(item_id);
         let sig = tcx.fn_sig(def_id);
-        let mut implied_bounds = vec![];
+        let mut implied_bounds = FxHashSet::default();
         check_fn_or_method(fcx, ident.span, sig, decl, def_id.to_def_id(), &mut implied_bounds);
         implied_bounds
     })
@@ -659,7 +659,7 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_fo
         }
 
         // No implied bounds in a const, etc.
-        vec![]
+        FxHashSet::default()
     });
 }
 
@@ -918,14 +918,14 @@ fn check_fn_or_method<'fcx, 'tcx>(
     sig: ty::PolyFnSig<'tcx>,
     hir_decl: &hir::FnDecl<'_>,
     def_id: DefId,
-    implied_bounds: &mut Vec<Ty<'tcx>>,
+    implied_bounds: &mut FxHashSet<Ty<'tcx>>,
 ) {
     let sig = fcx.tcx.liberate_late_bound_regions(def_id, sig);
 
     // Unnormalized types in signature are WF too
     implied_bounds.extend(sig.inputs());
     // FIXME(#27579) return types should not be implied bounds
-    implied_bounds.push(sig.output());
+    implied_bounds.insert(sig.output());
 
     // Normalize the input and output types one at a time, using a different
     // `WellFormedLoc` for each. We cannot call `normalize_associated_types`
@@ -977,7 +977,7 @@ fn check_fn_or_method<'fcx, 'tcx>(
     );
 
     // FIXME(#27579) return types should not be implied bounds
-    implied_bounds.push(sig.output());
+    implied_bounds.insert(sig.output());
 
     debug!(?implied_bounds);
 
@@ -1513,7 +1513,11 @@ fn enum_variants(&self, enum_def: &hir::EnumDef<'_>) -> Vec<AdtVariant<'tcx>> {
             .collect()
     }
 
-    pub(super) fn impl_implied_bounds(&self, impl_def_id: DefId, span: Span) -> Vec<Ty<'tcx>> {
+    pub(super) fn impl_implied_bounds(
+        &self,
+        impl_def_id: DefId,
+        span: Span,
+    ) -> FxHashSet<Ty<'tcx>> {
         match self.tcx.impl_trait_ref(impl_def_id) {
             Some(trait_ref) => {
                 // Trait impl: take implied bounds from all types that
@@ -1526,7 +1530,7 @@ pub(super) fn impl_implied_bounds(&self, impl_def_id: DefId, span: Span) -> Vec<
                 // Inherent impl: take implied bounds from the `self` type.
                 let self_ty = self.tcx.type_of(impl_def_id);
                 let self_ty = self.normalize_associated_types_in(span, self_ty);
-                vec![self_ty]
+                std::array::IntoIter::new([self_ty]).collect()
             }
         }
     }
index 3688fa05e038eb2948da4152ded88e55e01aabd5..8b1d1e450d0376cbac6d29d5837037bca61f3d64 100644 (file)
@@ -46,7 +46,7 @@
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
-use rustc_target::spec::{abi, SanitizerSet};
+use rustc_target::spec::{abi, PanicStrategy, SanitizerSet};
 use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
 use std::iter;
 
@@ -2683,6 +2683,13 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
         codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
     }
 
+    // With -Z panic-in-drop=abort, drop_in_place never unwinds.
+    if tcx.sess.opts.debugging_opts.panic_in_drop == PanicStrategy::Abort {
+        if Some(id) == tcx.lang_items().drop_in_place_fn() {
+            codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND;
+        }
+    }
+
     let supported_target_features = tcx.supported_target_features(LOCAL_CRATE);
 
     let mut inline_span = None;
diff --git a/library/core/primitive_docs/box_into_raw.md b/library/core/primitive_docs/box_into_raw.md
new file mode 100644 (file)
index 0000000..9dd0344
--- /dev/null
@@ -0,0 +1 @@
+../std/boxed/struct.Box.html#method.into_raw
diff --git a/library/core/primitive_docs/fs_file.md b/library/core/primitive_docs/fs_file.md
new file mode 100644 (file)
index 0000000..4023e34
--- /dev/null
@@ -0,0 +1 @@
+../std/fs/struct.File.html
diff --git a/library/core/primitive_docs/io_bufread.md b/library/core/primitive_docs/io_bufread.md
new file mode 100644 (file)
index 0000000..7beda2c
--- /dev/null
@@ -0,0 +1 @@
+../std/io/trait.BufRead.html
diff --git a/library/core/primitive_docs/io_read.md b/library/core/primitive_docs/io_read.md
new file mode 100644 (file)
index 0000000..b7ecf5e
--- /dev/null
@@ -0,0 +1 @@
+../std/io/trait.Read.html
diff --git a/library/core/primitive_docs/io_seek.md b/library/core/primitive_docs/io_seek.md
new file mode 100644 (file)
index 0000000..db0274d
--- /dev/null
@@ -0,0 +1 @@
+../std/io/trait.Seek.html
diff --git a/library/core/primitive_docs/io_write.md b/library/core/primitive_docs/io_write.md
new file mode 100644 (file)
index 0000000..92a3b88
--- /dev/null
@@ -0,0 +1 @@
+../std/io/trait.Write.html
diff --git a/library/core/primitive_docs/net_tosocketaddrs.md b/library/core/primitive_docs/net_tosocketaddrs.md
new file mode 100644 (file)
index 0000000..4daa10d
--- /dev/null
@@ -0,0 +1 @@
+../std/net/trait.ToSocketAddrs.html
diff --git a/library/core/primitive_docs/process_exit.md b/library/core/primitive_docs/process_exit.md
new file mode 100644 (file)
index 0000000..cae34d1
--- /dev/null
@@ -0,0 +1 @@
+../std/process/fn.exit.html
diff --git a/library/core/primitive_docs/string_string.md b/library/core/primitive_docs/string_string.md
new file mode 100644 (file)
index 0000000..303dc07
--- /dev/null
@@ -0,0 +1 @@
+../std/string/struct.String.html
index ca1c0ae759892466228d0f072e48a6da7da78df6..f14c2a4641627ec4378bad32c91e0b129bd6bbc7 100644 (file)
@@ -2,7 +2,8 @@
 
 #[lang = "bool"]
 impl bool {
-    /// Returns `Some(t)` if the `bool` is [`true`](keyword.true.html), or `None` otherwise.
+    /// Returns `Some(t)` if the `bool` is [`true`](../std/keyword.true.html),
+    /// or `None` otherwise.
     ///
     /// # Examples
     ///
@@ -18,7 +19,8 @@ pub fn then_some<T>(self, t: T) -> Option<T> {
         if self { Some(t) } else { None }
     }
 
-    /// Returns `Some(f())` if the `bool` is [`true`](keyword.true.html), or `None` otherwise.
+    /// Returns `Some(f())` if the `bool` is [`true`](../std/keyword.true.html),
+    /// or `None` otherwise.
     ///
     /// # Examples
     ///
index e6d3ac8f2d2c5d3637cb4fd144fc1572cedf691a..b1dd6aef97493e13500ce026a614005a1ee7c779 100644 (file)
@@ -24,7 +24,7 @@ impl char {
     /// decoding error.
     ///
     /// It can occur, for example, when giving ill-formed UTF-8 bytes to
-    /// [`String::from_utf8_lossy`](string/struct.String.html#method.from_utf8_lossy).
+    /// [`String::from_utf8_lossy`](../std/string/struct.String.html#method.from_utf8_lossy).
     #[stable(feature = "assoc_char_consts", since = "1.52.0")]
     pub const REPLACEMENT_CHARACTER: char = '\u{FFFD}';
 
@@ -96,7 +96,7 @@ pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::Into
     /// Converts a `u32` to a `char`.
     ///
     /// Note that all `char`s are valid [`u32`]s, and can be cast to one with
-    /// [`as`](keyword.as.html):
+    /// [`as`](../std/keyword.as.html):
     ///
     /// ```
     /// let c = '💯';
@@ -372,7 +372,7 @@ pub fn to_digit(self, radix: u32) -> Option<u32> {
     /// println!("\\u{{2764}}");
     /// ```
     ///
-    /// Using [`to_string`](string/trait.ToString.html#tymethod.to_string):
+    /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
     ///
     /// ```
     /// assert_eq!('❤'.escape_unicode().to_string(), "\\u{2764}");
@@ -448,7 +448,7 @@ pub(crate) fn escape_debug_ext(self, args: EscapeDebugExtArgs) -> EscapeDebug {
     /// println!("\\n");
     /// ```
     ///
-    /// Using [`to_string`](string/trait.ToString.html#tymethod.to_string):
+    /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
     ///
     /// ```
     /// assert_eq!('\n'.escape_debug().to_string(), "\\n");
@@ -502,7 +502,7 @@ pub fn escape_debug(self) -> EscapeDebug {
     /// println!("\\\"");
     /// ```
     ///
-    /// Using [`to_string`](string/trait.ToString.html#tymethod.to_string):
+    /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
     ///
     /// ```
     /// assert_eq!('"'.escape_default().to_string(), "\\\"");
@@ -937,7 +937,7 @@ pub fn is_numeric(self) -> bool {
     /// println!("i\u{307}");
     /// ```
     ///
-    /// Using [`to_string`](string/trait.ToString.html#tymethod.to_string):
+    /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
     ///
     /// ```
     /// assert_eq!('C'.to_lowercase().to_string(), "c");
@@ -1002,7 +1002,7 @@ pub fn to_lowercase(self) -> ToLowercase {
     /// println!("SS");
     /// ```
     ///
-    /// Using [`to_string`](string/trait.ToString.html#tymethod.to_string):
+    /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
     ///
     /// ```
     /// assert_eq!('c'.to_uppercase().to_string(), "C");
index 19faf9cddac6faa392a946742d00807d7441bf29..b02333b028850fd7a831adeb811e3bd6c7b37e61 100644 (file)
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "clone"]
 #[rustc_diagnostic_item = "Clone"]
+#[cfg_attr(not(bootstrap), rustc_trivial_field_reads)]
 pub trait Clone: Sized {
     /// Returns a copy of the value.
     ///
index 0a29843c9cf271b5ddd45c528748009d70903fff..166a8e3f28a4190e9adfeda75b90ec29153b8429 100644 (file)
@@ -582,6 +582,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
 )]
 #[doc(alias = "{:?}")]
 #[rustc_diagnostic_item = "debug_trait"]
+#[cfg_attr(not(bootstrap), rustc_trivial_field_reads)]
 pub trait Debug {
     /// Formats the value using the given formatter.
     ///
index 06a409c6a2eb9d0fe98dce8b21c405be4c631854..265ba9f1bb91b69d1fc9c2b162b4a18a03db34d9 100644 (file)
 #![feature(decl_macro)]
 #![feature(doc_cfg)]
 #![feature(doc_notable_trait)]
+#![feature(doc_primitive)]
 #![feature(exhaustive_patterns)]
 #![feature(extern_types)]
 #![feature(fundamental)]
@@ -355,3 +356,5 @@ pub mod arch {
         /* compiler built-in */
     }
 }
+
+include!("primitive_docs.rs");
index 82962a1fe13fc2ce59a3342904ee4044c286a627..a7ed5bfaf8598367492120435663c08676b55a0d 100644 (file)
@@ -99,17 +99,15 @@ pub trait Sized {
 /// `Unsize<dyn fmt::Debug>`.
 ///
 /// All implementations of `Unsize` are provided automatically by the compiler.
-///
-/// `Unsize` is implemented for:
-///
-/// - `[T; N]` is `Unsize<[T]>`
-/// - `T` is `Unsize<dyn Trait>` when `T: Trait`
-/// - `Foo<..., T, ...>` is `Unsize<Foo<..., U, ...>>` if:
-///   - `T: Unsize<U>`
-///   - Foo is a struct
-///   - Only the last field of `Foo` has a type involving `T`
-///   - `T` is not part of the type of any other fields
-///   - `Bar<T>: Unsize<Bar<U>>`, if the last field of `Foo` has type `Bar<T>`
+/// Those implementations are:
+///
+/// - Arrays `[T; N]` implement `Unsize<[T]>`.
+/// - Types implementing a trait `Trait` also implement `Unsize<dyn Trait>`.
+/// - Structs `Foo<..., T, ...>` implement `Unsize<Foo<..., U, ...>>` if all of these conditions
+///   are met:
+///   - `T: Unsize<U>`.
+///   - Only the last field of `Foo` has a type involving `T`.
+///   - `Bar<T>: Unsize<Bar<U>>`, where `Bar<T>` stands for the actual type of that last field.
 ///
 /// `Unsize` is used along with [`ops::CoerceUnsized`] to allow
 /// "user-defined" containers such as [`Rc`] to contain dynamically-sized
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
new file mode 100644 (file)
index 0000000..0de9126
--- /dev/null
@@ -0,0 +1,1307 @@
+// `library/{std,core}/src/primitive_docs.rs` should have the same contents.
+// These are different files so that relative links work properly without
+// having to have `CARGO_PKG_NAME` set, but conceptually they should always be the same.
+#[doc(primitive = "bool")]
+#[doc(alias = "true")]
+#[doc(alias = "false")]
+/// The boolean type.
+///
+/// The `bool` represents a value, which could only be either [`true`] or [`false`]. If you cast
+/// a `bool` into an integer, [`true`] will be 1 and [`false`] will be 0.
+///
+/// # Basic usage
+///
+/// `bool` implements various traits, such as [`BitAnd`], [`BitOr`], [`Not`], etc.,
+/// which allow us to perform boolean operations using `&`, `|` and `!`.
+///
+/// [`if`] requires a `bool` value as its conditional. [`assert!`], which is an
+/// important macro in testing, checks whether an expression is [`true`] and panics
+/// if it isn't.
+///
+/// ```
+/// let bool_val = true & false | false;
+/// assert!(!bool_val);
+/// ```
+///
+/// [`true`]: ../std/keyword.true.html
+/// [`false`]: ../std/keyword.false.html
+/// [`BitAnd`]: ops::BitAnd
+/// [`BitOr`]: ops::BitOr
+/// [`Not`]: ops::Not
+/// [`if`]: ../std/keyword.if.html
+///
+/// # Examples
+///
+/// A trivial example of the usage of `bool`:
+///
+/// ```
+/// let praise_the_borrow_checker = true;
+///
+/// // using the `if` conditional
+/// if praise_the_borrow_checker {
+///     println!("oh, yeah!");
+/// } else {
+///     println!("what?!!");
+/// }
+///
+/// // ... or, a match pattern
+/// match praise_the_borrow_checker {
+///     true => println!("keep praising!"),
+///     false => println!("you should praise!"),
+/// }
+/// ```
+///
+/// Also, since `bool` implements the [`Copy`] trait, we don't
+/// have to worry about the move semantics (just like the integer and float primitives).
+///
+/// Now an example of `bool` cast to integer type:
+///
+/// ```
+/// assert_eq!(true as i32, 1);
+/// assert_eq!(false as i32, 0);
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_bool {}
+
+#[doc(primitive = "never")]
+#[doc(alias = "!")]
+//
+/// The `!` type, also called "never".
+///
+/// `!` represents the type of computations which never resolve to any value at all. For example,
+/// the [`exit`] function `fn exit(code: i32) -> !` exits the process without ever returning, and
+/// so returns `!`.
+///
+/// `break`, `continue` and `return` expressions also have type `!`. For example we are allowed to
+/// write:
+///
+/// ```
+/// #![feature(never_type)]
+/// # fn foo() -> u32 {
+/// let x: ! = {
+///     return 123
+/// };
+/// # }
+/// ```
+///
+/// Although the `let` is pointless here, it illustrates the meaning of `!`. Since `x` is never
+/// assigned a value (because `return` returns from the entire function), `x` can be given type
+/// `!`. We could also replace `return 123` with a `panic!` or a never-ending `loop` and this code
+/// would still be valid.
+///
+/// A more realistic usage of `!` is in this code:
+///
+/// ```
+/// # fn get_a_number() -> Option<u32> { None }
+/// # loop {
+/// let num: u32 = match get_a_number() {
+///     Some(num) => num,
+///     None => break,
+/// };
+/// # }
+/// ```
+///
+/// Both match arms must produce values of type [`u32`], but since `break` never produces a value
+/// at all we know it can never produce a value which isn't a [`u32`]. This illustrates another
+/// behaviour of the `!` type - expressions with type `!` will coerce into any other type.
+///
+/// [`u32`]: prim@u32
+#[doc = concat!("[`exit`]: ", include_str!("../primitive_docs/process_exit.md"))]
+///
+/// # `!` and generics
+///
+/// ## Infallible errors
+///
+/// The main place you'll see `!` used explicitly is in generic code. Consider the [`FromStr`]
+/// trait:
+///
+/// ```
+/// trait FromStr: Sized {
+///     type Err;
+///     fn from_str(s: &str) -> Result<Self, Self::Err>;
+/// }
+/// ```
+///
+/// When implementing this trait for [`String`] we need to pick a type for [`Err`]. And since
+/// converting a string into a string will never result in an error, the appropriate type is `!`.
+/// (Currently the type actually used is an enum with no variants, though this is only because `!`
+/// was added to Rust at a later date and it may change in the future.) With an [`Err`] type of
+/// `!`, if we have to call [`String::from_str`] for some reason the result will be a
+/// [`Result<String, !>`] which we can unpack like this:
+///
+/// ```
+/// #![feature(exhaustive_patterns)]
+/// use std::str::FromStr;
+/// let Ok(s) = String::from_str("hello");
+/// ```
+///
+/// Since the [`Err`] variant contains a `!`, it can never occur. If the `exhaustive_patterns`
+/// feature is present this means we can exhaustively match on [`Result<T, !>`] by just taking the
+/// [`Ok`] variant. This illustrates another behaviour of `!` - it can be used to "delete" certain
+/// enum variants from generic types like `Result`.
+///
+/// ## Infinite loops
+///
+/// While [`Result<T, !>`] is very useful for removing errors, `!` can also be used to remove
+/// successes as well. If we think of [`Result<T, !>`] as "if this function returns, it has not
+/// errored," we get a very intuitive idea of [`Result<!, E>`] as well: if the function returns, it
+/// *has* errored.
+///
+/// For example, consider the case of a simple web server, which can be simplified to:
+///
+/// ```ignore (hypothetical-example)
+/// loop {
+///     let (client, request) = get_request().expect("disconnected");
+///     let response = request.process();
+///     response.send(client);
+/// }
+/// ```
+///
+/// Currently, this isn't ideal, because we simply panic whenever we fail to get a new connection.
+/// Instead, we'd like to keep track of this error, like this:
+///
+/// ```ignore (hypothetical-example)
+/// loop {
+///     match get_request() {
+///         Err(err) => break err,
+///         Ok((client, request)) => {
+///             let response = request.process();
+///             response.send(client);
+///         },
+///     }
+/// }
+/// ```
+///
+/// Now, when the server disconnects, we exit the loop with an error instead of panicking. While it
+/// might be intuitive to simply return the error, we might want to wrap it in a [`Result<!, E>`]
+/// instead:
+///
+/// ```ignore (hypothetical-example)
+/// fn server_loop() -> Result<!, ConnectionError> {
+///     loop {
+///         let (client, request) = get_request()?;
+///         let response = request.process();
+///         response.send(client);
+///     }
+/// }
+/// ```
+///
+/// Now, we can use `?` instead of `match`, and the return type makes a lot more sense: if the loop
+/// ever stops, it means that an error occurred. We don't even have to wrap the loop in an `Ok`
+/// because `!` coerces to `Result<!, ConnectionError>` automatically.
+///
+/// [`String::from_str`]: str::FromStr::from_str
+#[doc = concat!("[`String`]: ", include_str!("../primitive_docs/string_string.md"))]
+/// [`FromStr`]: str::FromStr
+///
+/// # `!` and traits
+///
+/// When writing your own traits, `!` should have an `impl` whenever there is an obvious `impl`
+/// which doesn't `panic!`. The reason is that functions returning an `impl Trait` where `!`
+/// does not have an `impl` of `Trait` cannot diverge as their only possible code path. In other
+/// words, they can't return `!` from every code path. As an example, this code doesn't compile:
+///
+/// ```compile_fail
+/// use std::ops::Add;
+///
+/// fn foo() -> impl Add<u32> {
+///     unimplemented!()
+/// }
+/// ```
+///
+/// But this code does:
+///
+/// ```
+/// use std::ops::Add;
+///
+/// fn foo() -> impl Add<u32> {
+///     if true {
+///         unimplemented!()
+///     } else {
+///         0
+///     }
+/// }
+/// ```
+///
+/// The reason is that, in the first example, there are many possible types that `!` could coerce
+/// to, because many types implement `Add<u32>`. However, in the second example,
+/// the `else` branch returns a `0`, which the compiler infers from the return type to be of type
+/// `u32`. Since `u32` is a concrete type, `!` can and will be coerced to it. See issue [#36375]
+/// for more information on this quirk of `!`.
+///
+/// [#36375]: https://github.com/rust-lang/rust/issues/36375
+///
+/// As it turns out, though, most traits can have an `impl` for `!`. Take [`Debug`]
+/// for example:
+///
+/// ```
+/// #![feature(never_type)]
+/// # use std::fmt;
+/// # trait Debug {
+/// #     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result;
+/// # }
+/// impl Debug for ! {
+///     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+///         *self
+///     }
+/// }
+/// ```
+///
+/// Once again we're using `!`'s ability to coerce into any other type, in this case
+/// [`fmt::Result`]. Since this method takes a `&!` as an argument we know that it can never be
+/// called (because there is no value of type `!` for it to be called with). Writing `*self`
+/// essentially tells the compiler "We know that this code can never be run, so just treat the
+/// entire function body as having type [`fmt::Result`]". This pattern can be used a lot when
+/// implementing traits for `!`. Generally, any trait which only has methods which take a `self`
+/// parameter should have such an impl.
+///
+/// On the other hand, one trait which would not be appropriate to implement is [`Default`]:
+///
+/// ```
+/// trait Default {
+///     fn default() -> Self;
+/// }
+/// ```
+///
+/// Since `!` has no values, it has no default value either. It's true that we could write an
+/// `impl` for this which simply panics, but the same is true for any type (we could `impl
+/// Default` for (eg.) [`File`] by just making [`default()`] panic.)
+///
+#[doc = concat!("[`File`]: ", include_str!("../primitive_docs/fs_file.md"))]
+/// [`Debug`]: fmt::Debug
+/// [`default()`]: Default::default
+///
+#[unstable(feature = "never_type", issue = "35121")]
+mod prim_never {}
+
+#[doc(primitive = "char")]
+/// A character type.
+///
+/// The `char` type represents a single character. More specifically, since
+/// 'character' isn't a well-defined concept in Unicode, `char` is a '[Unicode
+/// scalar value]', which is similar to, but not the same as, a '[Unicode code
+/// point]'.
+///
+/// [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value
+/// [Unicode code point]: https://www.unicode.org/glossary/#code_point
+///
+/// This documentation describes a number of methods and trait implementations on the
+/// `char` type. For technical reasons, there is additional, separate
+/// documentation in [the `std::char` module](char/index.html) as well.
+///
+/// # Representation
+///
+/// `char` is always four bytes in size. This is a different representation than
+/// a given character would have as part of a [`String`]. For example:
+///
+/// ```
+/// let v = vec!['h', 'e', 'l', 'l', 'o'];
+///
+/// // five elements times four bytes for each element
+/// assert_eq!(20, v.len() * std::mem::size_of::<char>());
+///
+/// let s = String::from("hello");
+///
+/// // five elements times one byte per element
+/// assert_eq!(5, s.len() * std::mem::size_of::<u8>());
+/// ```
+///
+#[doc = concat!("[`String`]: ", include_str!("../primitive_docs/string_string.md"))]
+///
+/// As always, remember that a human intuition for 'character' might not map to
+/// Unicode's definitions. For example, despite looking similar, the 'é'
+/// character is one Unicode code point while 'é' is two Unicode code points:
+///
+/// ```
+/// let mut chars = "é".chars();
+/// // U+00e9: 'latin small letter e with acute'
+/// assert_eq!(Some('\u{00e9}'), chars.next());
+/// assert_eq!(None, chars.next());
+///
+/// let mut chars = "é".chars();
+/// // U+0065: 'latin small letter e'
+/// assert_eq!(Some('\u{0065}'), chars.next());
+/// // U+0301: 'combining acute accent'
+/// assert_eq!(Some('\u{0301}'), chars.next());
+/// assert_eq!(None, chars.next());
+/// ```
+///
+/// This means that the contents of the first string above _will_ fit into a
+/// `char` while the contents of the second string _will not_. Trying to create
+/// a `char` literal with the contents of the second string gives an error:
+///
+/// ```text
+/// error: character literal may only contain one codepoint: 'é'
+/// let c = 'é';
+///         ^^^
+/// ```
+///
+/// Another implication of the 4-byte fixed size of a `char` is that
+/// per-`char` processing can end up using a lot more memory:
+///
+/// ```
+/// let s = String::from("love: ❤️");
+/// let v: Vec<char> = s.chars().collect();
+///
+/// assert_eq!(12, std::mem::size_of_val(&s[..]));
+/// assert_eq!(32, std::mem::size_of_val(&v[..]));
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_char {}
+
+#[doc(primitive = "unit")]
+#[doc(alias = "(")]
+#[doc(alias = ")")]
+#[doc(alias = "()")]
+//
+/// The `()` type, also called "unit".
+///
+/// The `()` type has exactly one value `()`, and is used when there
+/// is no other meaningful value that could be returned. `()` is most
+/// commonly seen implicitly: functions without a `-> ...` implicitly
+/// have return type `()`, that is, these are equivalent:
+///
+/// ```rust
+/// fn long() -> () {}
+///
+/// fn short() {}
+/// ```
+///
+/// The semicolon `;` can be used to discard the result of an
+/// expression at the end of a block, making the expression (and thus
+/// the block) evaluate to `()`. For example,
+///
+/// ```rust
+/// fn returns_i64() -> i64 {
+///     1i64
+/// }
+/// fn returns_unit() {
+///     1i64;
+/// }
+///
+/// let is_i64 = {
+///     returns_i64()
+/// };
+/// let is_unit = {
+///     returns_i64();
+/// };
+/// ```
+///
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_unit {}
+
+#[doc(primitive = "pointer")]
+#[doc(alias = "ptr")]
+#[doc(alias = "*")]
+#[doc(alias = "*const")]
+#[doc(alias = "*mut")]
+//
+/// Raw, unsafe pointers, `*const T`, and `*mut T`.
+///
+/// *[See also the `std::ptr` module](ptr).*
+///
+/// Working with raw pointers in Rust is uncommon, typically limited to a few patterns.
+/// Raw pointers can be unaligned or [`null`]. However, when a raw pointer is
+/// dereferenced (using the `*` operator), it must be non-null and aligned.
+///
+/// Storing through a raw pointer using `*ptr = data` calls `drop` on the old value, so
+/// [`write`] must be used if the type has drop glue and memory is not already
+/// initialized - otherwise `drop` would be called on the uninitialized memory.
+///
+/// Use the [`null`] and [`null_mut`] functions to create null pointers, and the
+/// [`is_null`] method of the `*const T` and `*mut T` types to check for null.
+/// The `*const T` and `*mut T` types also define the [`offset`] method, for
+/// pointer math.
+///
+/// # Common ways to create raw pointers
+///
+/// ## 1. Coerce a reference (`&T`) or mutable reference (`&mut T`).
+///
+/// ```
+/// let my_num: i32 = 10;
+/// let my_num_ptr: *const i32 = &my_num;
+/// let mut my_speed: i32 = 88;
+/// let my_speed_ptr: *mut i32 = &mut my_speed;
+/// ```
+///
+/// To get a pointer to a boxed value, dereference the box:
+///
+/// ```
+/// let my_num: Box<i32> = Box::new(10);
+/// let my_num_ptr: *const i32 = &*my_num;
+/// let mut my_speed: Box<i32> = Box::new(88);
+/// let my_speed_ptr: *mut i32 = &mut *my_speed;
+/// ```
+///
+/// This does not take ownership of the original allocation
+/// and requires no resource management later,
+/// but you must not use the pointer after its lifetime.
+///
+/// ## 2. Consume a box (`Box<T>`).
+///
+/// The [`into_raw`] function consumes a box and returns
+/// the raw pointer. It doesn't destroy `T` or deallocate any memory.
+///
+/// ```
+/// let my_speed: Box<i32> = Box::new(88);
+/// let my_speed: *mut i32 = Box::into_raw(my_speed);
+///
+/// // By taking ownership of the original `Box<T>` though
+/// // we are obligated to put it together later to be destroyed.
+/// unsafe {
+///     drop(Box::from_raw(my_speed));
+/// }
+/// ```
+///
+/// Note that here the call to [`drop`] is for clarity - it indicates
+/// that we are done with the given value and it should be destroyed.
+///
+/// ## 3. Create it using `ptr::addr_of!`
+///
+/// Instead of coercing a reference to a raw pointer, you can use the macros
+/// [`ptr::addr_of!`] (for `*const T`) and [`ptr::addr_of_mut!`] (for `*mut T`).
+/// These macros allow you to create raw pointers to fields to which you cannot
+/// create a reference (without causing undefined behaviour), such as an
+/// unaligned field. This might be necessary if packed structs or uninitialized
+/// memory is involved.
+///
+/// ```
+/// #[derive(Debug, Default, Copy, Clone)]
+/// #[repr(C, packed)]
+/// struct S {
+///     aligned: u8,
+///     unaligned: u32,
+/// }
+/// let s = S::default();
+/// let p = std::ptr::addr_of!(s.unaligned); // not allowed with coercion
+/// ```
+///
+/// ## 4. Get it from C.
+///
+/// ```
+/// # #![feature(rustc_private)]
+/// extern crate libc;
+///
+/// use std::mem;
+///
+/// unsafe {
+///     let my_num: *mut i32 = libc::malloc(mem::size_of::<i32>()) as *mut i32;
+///     if my_num.is_null() {
+///         panic!("failed to allocate memory");
+///     }
+///     libc::free(my_num as *mut libc::c_void);
+/// }
+/// ```
+///
+/// Usually you wouldn't literally use `malloc` and `free` from Rust,
+/// but C APIs hand out a lot of pointers generally, so are a common source
+/// of raw pointers in Rust.
+///
+/// [`null`]: ptr::null
+/// [`null_mut`]: ptr::null_mut
+/// [`is_null`]: pointer::is_null
+/// [`offset`]: pointer::offset
+#[doc = concat!("[`into_raw`]: ", include_str!("../primitive_docs/box_into_raw.md"))]
+/// [`drop`]: mem::drop
+/// [`write`]: ptr::write
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_pointer {}
+
+#[doc(primitive = "array")]
+#[doc(alias = "[]")]
+#[doc(alias = "[T;N]")] // unfortunately, rustdoc doesn't have fuzzy search for aliases
+#[doc(alias = "[T; N]")]
+/// A fixed-size array, denoted `[T; N]`, for the element type, `T`, and the
+/// non-negative compile-time constant size, `N`.
+///
+/// There are two syntactic forms for creating an array:
+///
+/// * A list with each element, i.e., `[x, y, z]`.
+/// * A repeat expression `[x; N]`, which produces an array with `N` copies of `x`.
+///   The type of `x` must be [`Copy`].
+///
+/// Note that `[expr; 0]` is allowed, and produces an empty array.
+/// This will still evaluate `expr`, however, and immediately drop the resulting value, so
+/// be mindful of side effects.
+///
+/// Arrays of *any* size implement the following traits if the element type allows it:
+///
+/// - [`Copy`]
+/// - [`Clone`]
+/// - [`Debug`]
+/// - [`IntoIterator`] (implemented for `[T; N]`, `&[T; N]` and `&mut [T; N]`)
+/// - [`PartialEq`], [`PartialOrd`], [`Eq`], [`Ord`]
+/// - [`Hash`]
+/// - [`AsRef`], [`AsMut`]
+/// - [`Borrow`], [`BorrowMut`]
+///
+/// Arrays of sizes from 0 to 32 (inclusive) implement the [`Default`] trait
+/// if the element type allows it. As a stopgap, trait implementations are
+/// statically generated up to size 32.
+///
+/// Arrays coerce to [slices (`[T]`)][slice], so a slice method may be called on
+/// an array. Indeed, this provides most of the API for working with arrays.
+/// Slices have a dynamic size and do not coerce to arrays.
+///
+/// You can move elements out of an array with a [slice pattern]. If you want
+/// one element, see [`mem::replace`].
+///
+/// # Examples
+///
+/// ```
+/// let mut array: [i32; 3] = [0; 3];
+///
+/// array[1] = 1;
+/// array[2] = 2;
+///
+/// assert_eq!([1, 2], &array[1..]);
+///
+/// // This loop prints: 0 1 2
+/// for x in array {
+///     print!("{} ", x);
+/// }
+/// ```
+///
+/// You can also iterate over reference to the array's elements:
+///
+/// ```
+/// let array: [i32; 3] = [0; 3];
+///
+/// for x in &array { }
+/// ```
+///
+/// You can use a [slice pattern] to move elements out of an array:
+///
+/// ```
+/// fn move_away(_: String) { /* Do interesting things. */ }
+///
+/// let [john, roa] = ["John".to_string(), "Roa".to_string()];
+/// move_away(john);
+/// move_away(roa);
+/// ```
+///
+/// # Editions
+///
+/// Prior to Rust 1.53, arrays did not implement [`IntoIterator`] by value, so the method call
+/// `array.into_iter()` auto-referenced into a [slice iterator](slice::iter). Right now, the old
+/// behavior is preserved in the 2015 and 2018 editions of Rust for compatibility, ignoring
+/// [`IntoIterator`] by value. In the future, the behavior on the 2015 and 2018 edition
+/// might be made consistent to the behavior of later editions.
+///
+/// ```rust,edition2018
+/// // Rust 2015 and 2018:
+///
+/// # #![allow(array_into_iter)] // override our `deny(warnings)`
+/// let array: [i32; 3] = [0; 3];
+///
+/// // This creates a slice iterator, producing references to each value.
+/// for item in array.into_iter().enumerate() {
+///     let (i, x): (usize, &i32) = item;
+///     println!("array[{}] = {}", i, x);
+/// }
+///
+/// // The `array_into_iter` lint suggests this change for future compatibility:
+/// for item in array.iter().enumerate() {
+///     let (i, x): (usize, &i32) = item;
+///     println!("array[{}] = {}", i, x);
+/// }
+///
+/// // You can explicitly iterate an array by value using
+/// // `IntoIterator::into_iter` or `std::array::IntoIter::new`:
+/// for item in IntoIterator::into_iter(array).enumerate() {
+///     let (i, x): (usize, i32) = item;
+///     println!("array[{}] = {}", i, x);
+/// }
+/// ```
+///
+/// Starting in the 2021 edition, `array.into_iter()` uses `IntoIterator` normally to iterate
+/// by value, and `iter()` should be used to iterate by reference like previous editions.
+///
+/// ```rust,edition2021
+/// // Rust 2021:
+///
+/// let array: [i32; 3] = [0; 3];
+///
+/// // This iterates by reference:
+/// for item in array.iter().enumerate() {
+///     let (i, x): (usize, &i32) = item;
+///     println!("array[{}] = {}", i, x);
+/// }
+///
+/// // This iterates by value:
+/// for item in array.into_iter().enumerate() {
+///     let (i, x): (usize, i32) = item;
+///     println!("array[{}] = {}", i, x);
+/// }
+/// ```
+///
+/// Future language versions might start treating the `array.into_iter()`
+/// syntax on editions 2015 and 2018 the same as on edition 2021. So code using
+/// those older editions should still be written with this change in mind, to
+/// prevent breakage in the future. The safest way to accomplish this is to
+/// avoid the `into_iter` syntax on those editions. If an edition update is not
+/// viable/desired, there are multiple alternatives:
+/// * use `iter`, equivalent to the old behavior, creating references
+/// * use [`IntoIterator::into_iter`], equivalent to the post-2021 behavior (Rust 1.53+)
+/// * replace `for ... in array.into_iter() {` with `for ... in array {`,
+///   equivalent to the post-2021 behavior (Rust 1.53+)
+///
+/// ```rust,edition2018
+/// // Rust 2015 and 2018:
+///
+/// let array: [i32; 3] = [0; 3];
+///
+/// // This iterates by reference:
+/// for item in array.iter() {
+///     let x: &i32 = item;
+///     println!("{}", x);
+/// }
+///
+/// // This iterates by value:
+/// for item in IntoIterator::into_iter(array) {
+///     let x: i32 = item;
+///     println!("{}", x);
+/// }
+///
+/// // This iterates by value:
+/// for item in array {
+///     let x: i32 = item;
+///     println!("{}", x);
+/// }
+///
+/// // IntoIter can also start a chain.
+/// // This iterates by value:
+/// for item in IntoIterator::into_iter(array).enumerate() {
+///     let (i, x): (usize, i32) = item;
+///     println!("array[{}] = {}", i, x);
+/// }
+/// ```
+///
+/// [slice]: prim@slice
+/// [`Debug`]: fmt::Debug
+/// [`Hash`]: hash::Hash
+/// [`Borrow`]: borrow::Borrow
+/// [`BorrowMut`]: borrow::BorrowMut
+/// [slice pattern]: ../reference/patterns.html#slice-patterns
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_array {}
+
+#[doc(primitive = "slice")]
+#[doc(alias = "[")]
+#[doc(alias = "]")]
+#[doc(alias = "[]")]
+/// A dynamically-sized view into a contiguous sequence, `[T]`. Contiguous here
+/// means that elements are laid out so that every element is the same
+/// distance from its neighbors.
+///
+/// *[See also the `std::slice` module](crate::slice).*
+///
+/// Slices are a view into a block of memory represented as a pointer and a
+/// length.
+///
+/// ```
+/// // slicing a Vec
+/// let vec = vec![1, 2, 3];
+/// let int_slice = &vec[..];
+/// // coercing an array to a slice
+/// let str_slice: &[&str] = &["one", "two", "three"];
+/// ```
+///
+/// Slices are either mutable or shared. The shared slice type is `&[T]`,
+/// while the mutable slice type is `&mut [T]`, where `T` represents the element
+/// type. For example, you can mutate the block of memory that a mutable slice
+/// points to:
+///
+/// ```
+/// let mut x = [1, 2, 3];
+/// let x = &mut x[..]; // Take a full slice of `x`.
+/// x[1] = 7;
+/// assert_eq!(x, &[1, 7, 3]);
+/// ```
+///
+/// As slices store the length of the sequence they refer to, they have twice
+/// the size of pointers to [`Sized`](marker/trait.Sized.html) types.
+/// Also see the reference on
+/// [dynamically sized types](../reference/dynamically-sized-types.html).
+///
+/// ```
+/// # use std::rc::Rc;
+/// let pointer_size = std::mem::size_of::<&u8>();
+/// assert_eq!(2 * pointer_size, std::mem::size_of::<&[u8]>());
+/// assert_eq!(2 * pointer_size, std::mem::size_of::<*const [u8]>());
+/// assert_eq!(2 * pointer_size, std::mem::size_of::<Box<[u8]>>());
+/// assert_eq!(2 * pointer_size, std::mem::size_of::<Rc<[u8]>>());
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_slice {}
+
+#[doc(primitive = "str")]
+//
+/// String slices.
+///
+/// *[See also the `std::str` module](crate::str).*
+///
+/// The `str` type, also called a 'string slice', is the most primitive string
+/// type. It is usually seen in its borrowed form, `&str`. It is also the type
+/// of string literals, `&'static str`.
+///
+/// String slices are always valid UTF-8.
+///
+/// # Examples
+///
+/// String literals are string slices:
+///
+/// ```
+/// let hello = "Hello, world!";
+///
+/// // with an explicit type annotation
+/// let hello: &'static str = "Hello, world!";
+/// ```
+///
+/// They are `'static` because they're stored directly in the final binary, and
+/// so will be valid for the `'static` duration.
+///
+/// # Representation
+///
+/// A `&str` is made up of two components: a pointer to some bytes, and a
+/// length. You can look at these with the [`as_ptr`] and [`len`] methods:
+///
+/// ```
+/// use std::slice;
+/// use std::str;
+///
+/// let story = "Once upon a time...";
+///
+/// let ptr = story.as_ptr();
+/// let len = story.len();
+///
+/// // story has nineteen bytes
+/// assert_eq!(19, len);
+///
+/// // We can re-build a str out of ptr and len. This is all unsafe because
+/// // we are responsible for making sure the two components are valid:
+/// let s = unsafe {
+///     // First, we build a &[u8]...
+///     let slice = slice::from_raw_parts(ptr, len);
+///
+///     // ... and then convert that slice into a string slice
+///     str::from_utf8(slice)
+/// };
+///
+/// assert_eq!(s, Ok(story));
+/// ```
+///
+/// [`as_ptr`]: str::as_ptr
+/// [`len`]: str::len
+///
+/// Note: This example shows the internals of `&str`. `unsafe` should not be
+/// used to get a string slice under normal circumstances. Use `as_str`
+/// instead.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_str {}
+
+#[doc(primitive = "tuple")]
+#[doc(alias = "(")]
+#[doc(alias = ")")]
+#[doc(alias = "()")]
+//
+/// A finite heterogeneous sequence, `(T, U, ..)`.
+///
+/// Let's cover each of those in turn:
+///
+/// Tuples are *finite*. In other words, a tuple has a length. Here's a tuple
+/// of length `3`:
+///
+/// ```
+/// ("hello", 5, 'c');
+/// ```
+///
+/// 'Length' is also sometimes called 'arity' here; each tuple of a different
+/// length is a different, distinct type.
+///
+/// Tuples are *heterogeneous*. This means that each element of the tuple can
+/// have a different type. In that tuple above, it has the type:
+///
+/// ```
+/// # let _:
+/// (&'static str, i32, char)
+/// # = ("hello", 5, 'c');
+/// ```
+///
+/// Tuples are a *sequence*. This means that they can be accessed by position;
+/// this is called 'tuple indexing', and it looks like this:
+///
+/// ```rust
+/// let tuple = ("hello", 5, 'c');
+///
+/// assert_eq!(tuple.0, "hello");
+/// assert_eq!(tuple.1, 5);
+/// assert_eq!(tuple.2, 'c');
+/// ```
+///
+/// The sequential nature of the tuple applies to its implementations of various
+/// traits. For example, in [`PartialOrd`] and [`Ord`], the elements are compared
+/// sequentially until the first non-equal set is found.
+///
+/// For more about tuples, see [the book](../book/ch03-02-data-types.html#the-tuple-type).
+///
+/// # Trait implementations
+///
+/// If every type inside a tuple implements one of the following traits, then a
+/// tuple itself also implements it.
+///
+/// * [`Clone`]
+/// * [`Copy`]
+/// * [`PartialEq`]
+/// * [`Eq`]
+/// * [`PartialOrd`]
+/// * [`Ord`]
+/// * [`Debug`]
+/// * [`Default`]
+/// * [`Hash`]
+///
+/// [`Debug`]: fmt::Debug
+/// [`Hash`]: hash::Hash
+///
+/// Due to a temporary restriction in Rust's type system, these traits are only
+/// implemented on tuples of arity 12 or less. In the future, this may change.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// let tuple = ("hello", 5, 'c');
+///
+/// assert_eq!(tuple.0, "hello");
+/// ```
+///
+/// Tuples are often used as a return type when you want to return more than
+/// one value:
+///
+/// ```
+/// fn calculate_point() -> (i32, i32) {
+///     // Don't do a calculation, that's not the point of the example
+///     (4, 5)
+/// }
+///
+/// let point = calculate_point();
+///
+/// assert_eq!(point.0, 4);
+/// assert_eq!(point.1, 5);
+///
+/// // Combining this with patterns can be nicer.
+///
+/// let (x, y) = calculate_point();
+///
+/// assert_eq!(x, 4);
+/// assert_eq!(y, 5);
+/// ```
+///
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_tuple {}
+
+#[doc(primitive = "f32")]
+/// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008).
+///
+/// This type can represent a wide range of decimal numbers, like `3.5`, `27`,
+/// `-113.75`, `0.0078125`, `34359738368`, `0`, `-1`. So unlike integer types
+/// (such as `i32`), floating point types can represent non-integer numbers,
+/// too.
+///
+/// However, being able to represent this wide range of numbers comes at the
+/// cost of precision: floats can only represent some of the real numbers and
+/// calculation with floats round to a nearby representable number. For example,
+/// `5.0` and `1.0` can be exactly represented as `f32`, but `1.0 / 5.0` results
+/// in `0.20000000298023223876953125` since `0.2` cannot be exactly represented
+/// as `f32`. Note, however, that printing floats with `println` and friends will
+/// often discard insignificant digits: `println!("{}", 1.0f32 / 5.0f32)` will
+/// print `0.2`.
+///
+/// Additionally, `f32` can represent some special values:
+///
+/// - −0.0: IEEE 754 floating point numbers have a bit that indicates their sign, so −0.0 is a
+///   possible value. For comparison −0.0 = +0.0, but floating point operations can carry
+///   the sign bit through arithmetic operations. This means −0.0 × +0.0 produces −0.0 and
+///   a negative number rounded to a value smaller than a float can represent also produces −0.0.
+/// - [∞](#associatedconstant.INFINITY) and
+///   [−∞](#associatedconstant.NEG_INFINITY): these result from calculations
+///   like `1.0 / 0.0`.
+/// - [NaN (not a number)](#associatedconstant.NAN): this value results from
+///   calculations like `(-1.0).sqrt()`. NaN has some potentially unexpected
+///   behavior: it is unequal to any float, including itself! It is also neither
+///   smaller nor greater than any float, making it impossible to sort. Lastly,
+///   it is considered infectious as almost all calculations where one of the
+///   operands is NaN will also result in NaN.
+///
+/// For more information on floating point numbers, see [Wikipedia][wikipedia].
+///
+/// *[See also the `std::f32::consts` module](crate::f32::consts).*
+///
+/// [wikipedia]: https://en.wikipedia.org/wiki/Single-precision_floating-point_format
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_f32 {}
+
+#[doc(primitive = "f64")]
+/// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008).
+///
+/// This type is very similar to [`f32`], but has increased
+/// precision by using twice as many bits. Please see [the documentation for
+/// `f32`][`f32`] or [Wikipedia on double precision
+/// values][wikipedia] for more information.
+///
+/// *[See also the `std::f64::consts` module](crate::f64::consts).*
+///
+/// [`f32`]: prim@f32
+/// [wikipedia]: https://en.wikipedia.org/wiki/Double-precision_floating-point_format
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_f64 {}
+
+#[doc(primitive = "i8")]
+//
+/// The 8-bit signed integer type.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_i8 {}
+
+#[doc(primitive = "i16")]
+//
+/// The 16-bit signed integer type.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_i16 {}
+
+#[doc(primitive = "i32")]
+//
+/// The 32-bit signed integer type.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_i32 {}
+
+#[doc(primitive = "i64")]
+//
+/// The 64-bit signed integer type.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_i64 {}
+
+#[doc(primitive = "i128")]
+//
+/// The 128-bit signed integer type.
+#[stable(feature = "i128", since = "1.26.0")]
+mod prim_i128 {}
+
+#[doc(primitive = "u8")]
+//
+/// The 8-bit unsigned integer type.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_u8 {}
+
+#[doc(primitive = "u16")]
+//
+/// The 16-bit unsigned integer type.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_u16 {}
+
+#[doc(primitive = "u32")]
+//
+/// The 32-bit unsigned integer type.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_u32 {}
+
+#[doc(primitive = "u64")]
+//
+/// The 64-bit unsigned integer type.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_u64 {}
+
+#[doc(primitive = "u128")]
+//
+/// The 128-bit unsigned integer type.
+#[stable(feature = "i128", since = "1.26.0")]
+mod prim_u128 {}
+
+#[doc(primitive = "isize")]
+//
+/// The pointer-sized signed integer type.
+///
+/// The size of this primitive is how many bytes it takes to reference any
+/// location in memory. For example, on a 32 bit target, this is 4 bytes
+/// and on a 64 bit target, this is 8 bytes.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_isize {}
+
+#[doc(primitive = "usize")]
+//
+/// The pointer-sized unsigned integer type.
+///
+/// The size of this primitive is how many bytes it takes to reference any
+/// location in memory. For example, on a 32 bit target, this is 4 bytes
+/// and on a 64 bit target, this is 8 bytes.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_usize {}
+
+#[doc(primitive = "reference")]
+#[doc(alias = "&")]
+#[doc(alias = "&mut")]
+//
+/// References, both shared and mutable.
+///
+/// A reference represents a borrow of some owned value. You can get one by using the `&` or `&mut`
+/// operators on a value, or by using a [`ref`](../std/keyword.ref.html) or
+/// <code>[ref](../std/keyword.ref.html) [mut](../std/keyword.mut.html)</code> pattern.
+///
+/// For those familiar with pointers, a reference is just a pointer that is assumed to be
+/// aligned, not null, and pointing to memory containing a valid value of `T` - for example,
+/// <code>&[bool]</code> can only point to an allocation containing the integer values `1`
+/// ([`true`](../std/keyword.true.html)) or `0` ([`false`](../std/keyword.false.html)), but
+/// creating a <code>&[bool]</code> that points to an allocation containing
+/// the value `3` causes undefined behaviour.
+/// In fact, <code>[Option]\<&T></code> has the same memory representation as a
+/// nullable but aligned pointer, and can be passed across FFI boundaries as such.
+///
+/// In most cases, references can be used much like the original value. Field access, method
+/// calling, and indexing work the same (save for mutability rules, of course). In addition, the
+/// comparison operators transparently defer to the referent's implementation, allowing references
+/// to be compared the same as owned values.
+///
+/// References have a lifetime attached to them, which represents the scope for which the borrow is
+/// valid. A lifetime is said to "outlive" another one if its representative scope is as long or
+/// longer than the other. The `'static` lifetime is the longest lifetime, which represents the
+/// total life of the program. For example, string literals have a `'static` lifetime because the
+/// text data is embedded into the binary of the program, rather than in an allocation that needs
+/// to be dynamically managed.
+///
+/// `&mut T` references can be freely coerced into `&T` references with the same referent type, and
+/// references with longer lifetimes can be freely coerced into references with shorter ones.
+///
+/// Reference equality by address, instead of comparing the values pointed to, is accomplished via
+/// implicit reference-pointer coercion and raw pointer equality via [`ptr::eq`], while
+/// [`PartialEq`] compares values.
+///
+/// ```
+/// use std::ptr;
+///
+/// let five = 5;
+/// let other_five = 5;
+/// let five_ref = &five;
+/// let same_five_ref = &five;
+/// let other_five_ref = &other_five;
+///
+/// assert!(five_ref == same_five_ref);
+/// assert!(five_ref == other_five_ref);
+///
+/// assert!(ptr::eq(five_ref, same_five_ref));
+/// assert!(!ptr::eq(five_ref, other_five_ref));
+/// ```
+///
+/// For more information on how to use references, see [the book's section on "References and
+/// Borrowing"][book-refs].
+///
+/// [book-refs]: ../book/ch04-02-references-and-borrowing.html
+///
+/// # Trait implementations
+///
+/// The following traits are implemented for all `&T`, regardless of the type of its referent:
+///
+/// * [`Copy`]
+/// * [`Clone`] \(Note that this will not defer to `T`'s `Clone` implementation if it exists!)
+/// * [`Deref`]
+/// * [`Borrow`]
+/// * [`Pointer`]
+///
+/// [`Deref`]: ops::Deref
+/// [`Borrow`]: borrow::Borrow
+/// [`Pointer`]: fmt::Pointer
+///
+/// `&mut T` references get all of the above except `Copy` and `Clone` (to prevent creating
+/// multiple simultaneous mutable borrows), plus the following, regardless of the type of its
+/// referent:
+///
+/// * [`DerefMut`]
+/// * [`BorrowMut`]
+///
+/// [`DerefMut`]: ops::DerefMut
+/// [`BorrowMut`]: borrow::BorrowMut
+/// [bool]: prim@bool
+///
+/// The following traits are implemented on `&T` references if the underlying `T` also implements
+/// that trait:
+///
+/// * All the traits in [`std::fmt`] except [`Pointer`] and [`fmt::Write`]
+/// * [`PartialOrd`]
+/// * [`Ord`]
+/// * [`PartialEq`]
+/// * [`Eq`]
+/// * [`AsRef`]
+/// * [`Fn`] \(in addition, `&T` references get [`FnMut`] and [`FnOnce`] if `T: Fn`)
+/// * [`Hash`]
+/// * [`ToSocketAddrs`]
+///
+/// [`std::fmt`]: fmt
+/// ['Pointer`]: fmt::Pointer
+/// [`Hash`]: hash::Hash
+#[doc = concat!("[`ToSocketAddrs`]: ", include_str!("../primitive_docs/net_tosocketaddrs.md"))]
+///
+/// `&mut T` references get all of the above except `ToSocketAddrs`, plus the following, if `T`
+/// implements that trait:
+///
+/// * [`AsMut`]
+/// * [`FnMut`] \(in addition, `&mut T` references get [`FnOnce`] if `T: FnMut`)
+/// * [`fmt::Write`]
+/// * [`Iterator`]
+/// * [`DoubleEndedIterator`]
+/// * [`ExactSizeIterator`]
+/// * [`FusedIterator`]
+/// * [`TrustedLen`]
+/// * [`Send`] \(note that `&T` references only get `Send` if <code>T: [Sync]</code>)
+/// * [`io::Write`]
+/// * [`Read`]
+/// * [`Seek`]
+/// * [`BufRead`]
+///
+/// [`FusedIterator`]: iter::FusedIterator
+/// [`TrustedLen`]: iter::TrustedLen
+#[doc = concat!("[`Seek`]: ", include_str!("../primitive_docs/io_seek.md"))]
+#[doc = concat!("[`BufRead`]: ", include_str!("../primitive_docs/io_bufread.md"))]
+#[doc = concat!("[`Read`]: ", include_str!("../primitive_docs/io_read.md"))]
+#[doc = concat!("[`io::Write`]: ", include_str!("../primitive_docs/io_write.md"))]
+///
+/// Note that due to method call deref coercion, simply calling a trait method will act like they
+/// work on references as well as they do on owned values! The implementations described here are
+/// meant for generic contexts, where the final type `T` is a type parameter or otherwise not
+/// locally known.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_ref {}
+
+#[doc(primitive = "fn")]
+//
+/// Function pointers, like `fn(usize) -> bool`.
+///
+/// *See also the traits [`Fn`], [`FnMut`], and [`FnOnce`].*
+///
+/// [`Fn`]: ops::Fn
+/// [`FnMut`]: ops::FnMut
+/// [`FnOnce`]: ops::FnOnce
+///
+/// Function pointers are pointers that point to *code*, not data. They can be called
+/// just like functions. Like references, function pointers are, among other things, assumed to
+/// not be null, so if you want to pass a function pointer over FFI and be able to accommodate null
+/// pointers, make your type [`Option<fn()>`](core::option#options-and-pointers-nullable-pointers)
+/// with your required signature.
+///
+/// ### Safety
+///
+/// Plain function pointers are obtained by casting either plain functions, or closures that don't
+/// capture an environment:
+///
+/// ```
+/// fn add_one(x: usize) -> usize {
+///     x + 1
+/// }
+///
+/// let ptr: fn(usize) -> usize = add_one;
+/// assert_eq!(ptr(5), 6);
+///
+/// let clos: fn(usize) -> usize = |x| x + 5;
+/// assert_eq!(clos(5), 10);
+/// ```
+///
+/// In addition to varying based on their signature, function pointers come in two flavors: safe
+/// and unsafe. Plain `fn()` function pointers can only point to safe functions,
+/// while `unsafe fn()` function pointers can point to safe or unsafe functions.
+///
+/// ```
+/// fn add_one(x: usize) -> usize {
+///     x + 1
+/// }
+///
+/// unsafe fn add_one_unsafely(x: usize) -> usize {
+///     x + 1
+/// }
+///
+/// let safe_ptr: fn(usize) -> usize = add_one;
+///
+/// //ERROR: mismatched types: expected normal fn, found unsafe fn
+/// //let bad_ptr: fn(usize) -> usize = add_one_unsafely;
+///
+/// let unsafe_ptr: unsafe fn(usize) -> usize = add_one_unsafely;
+/// let really_safe_ptr: unsafe fn(usize) -> usize = add_one;
+/// ```
+///
+/// ### ABI
+///
+/// On top of that, function pointers can vary based on what ABI they use. This
+/// is achieved by adding the `extern` keyword before the type, followed by the
+/// ABI in question. The default ABI is "Rust", i.e., `fn()` is the exact same
+/// type as `extern "Rust" fn()`. A pointer to a function with C ABI would have
+/// type `extern "C" fn()`.
+///
+/// `extern "ABI" { ... }` blocks declare functions with ABI "ABI". The default
+/// here is "C", i.e., functions declared in an `extern {...}` block have "C"
+/// ABI.
+///
+/// For more information and a list of supported ABIs, see [the nomicon's
+/// section on foreign calling conventions][nomicon-abi].
+///
+/// [nomicon-abi]: ../nomicon/ffi.html#foreign-calling-conventions
+///
+/// ### Variadic functions
+///
+/// Extern function declarations with the "C" or "cdecl" ABIs can also be *variadic*, allowing them
+/// to be called with a variable number of arguments. Normal Rust functions, even those with an
+/// `extern "ABI"`, cannot be variadic. For more information, see [the nomicon's section on
+/// variadic functions][nomicon-variadic].
+///
+/// [nomicon-variadic]: ../nomicon/ffi.html#variadic-functions
+///
+/// ### Creating function pointers
+///
+/// When `bar` is the name of a function, then the expression `bar` is *not* a
+/// function pointer. Rather, it denotes a value of an unnameable type that
+/// uniquely identifies the function `bar`. The value is zero-sized because the
+/// type already identifies the function. This has the advantage that "calling"
+/// the value (it implements the `Fn*` traits) does not require dynamic
+/// dispatch.
+///
+/// This zero-sized type *coerces* to a regular function pointer. For example:
+///
+/// ```rust
+/// use std::mem;
+///
+/// fn bar(x: i32) {}
+///
+/// let not_bar_ptr = bar; // `not_bar_ptr` is zero-sized, uniquely identifying `bar`
+/// assert_eq!(mem::size_of_val(&not_bar_ptr), 0);
+///
+/// let bar_ptr: fn(i32) = not_bar_ptr; // force coercion to function pointer
+/// assert_eq!(mem::size_of_val(&bar_ptr), mem::size_of::<usize>());
+///
+/// let footgun = &bar; // this is a shared reference to the zero-sized type identifying `bar`
+/// ```
+///
+/// The last line shows that `&bar` is not a function pointer either. Rather, it
+/// is a reference to the function-specific ZST. `&bar` is basically never what you
+/// want when `bar` is a function.
+///
+/// ### Traits
+///
+/// Function pointers implement the following traits:
+///
+/// * [`Clone`]
+/// * [`PartialEq`]
+/// * [`Eq`]
+/// * [`PartialOrd`]
+/// * [`Ord`]
+/// * [`Hash`]
+/// * [`Pointer`]
+/// * [`Debug`]
+///
+/// [`Hash`]: hash::Hash
+/// [`Pointer`]: fmt::Pointer
+///
+/// Due to a temporary restriction in Rust's type system, these traits are only implemented on
+/// functions that take 12 arguments or less, with the `"Rust"` and `"C"` ABIs. In the future, this
+/// may change.
+///
+/// In addition, function pointers of *any* signature, ABI, or safety are [`Copy`], and all *safe*
+/// function pointers implement [`Fn`], [`FnMut`], and [`FnOnce`]. This works because these traits
+/// are specially known to the compiler.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_fn {}
index b67038a7d5c2c491adc4568f3df45f37634768fc..a04e479e8570dc542b02066998b52266c096e18a 100644 (file)
@@ -2257,9 +2257,9 @@ pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
     /// assert!(match r { Ok(1..=4) => true, _ => false, });
     /// ```
     // Lint rustdoc::broken_intra_doc_links is allowed as `slice::sort_by_key` is
-    // in crate `alloc`, and as such doesn't exists yet when building `core`.
-    // links to downstream crate: #74481. Since primitives are only documented in
-    // libstd (#73423), this never leads to broken links in practice.
+    // in crate `alloc`, and as such doesn't exists yet when building `core`: #74481.
+    // This breaks links when slice is displayed in core, but changing it to use relative links
+    // would break when the item is re-exported. So allow the core links to be broken for now.
     #[allow(rustdoc::broken_intra_doc_links)]
     #[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
     #[inline]
index 7580010a28b4a5394ef5665d09f0a0a12a509e62..9567479c8137b5d4f0a7e8e0f07d7ee8edc0da12 100644 (file)
@@ -653,6 +653,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
 fn test_formatting_parameters_are_forwarded() {
     use std::collections::{BTreeMap, BTreeSet};
     #[derive(Debug)]
+    #[allow(dead_code)]
     struct Foo {
         bar: u32,
         baz: u32,
index 7001e827ad8456778b1225f190a2fcdf596551d2..bb05506defd0778c8f1f24e72d2a9d1617a64121 100644 (file)
@@ -162,6 +162,8 @@ fn sub(
                 fn source($self: $S::Span) -> $S::Span;
                 fn start($self: $S::Span) -> LineColumn;
                 fn end($self: $S::Span) -> LineColumn;
+                fn before($self: $S::Span) -> $S::Span;
+                fn after($self: $S::Span) -> $S::Span;
                 fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
                 fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
                 fn source_text($self: $S::Span) -> Option<String>;
index 243922b18b565dfd0a5b55fdf944f04d9f7aa555..e21a1507a62e200689e9a2d182d2673461baaa0f 100644 (file)
@@ -357,6 +357,18 @@ pub fn end(&self) -> LineColumn {
         self.0.end().add_1_to_column()
     }
 
+    /// Creates an empty span pointing to directly before this span.
+    #[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
+    pub fn before(&self) -> Span {
+        Span(self.0.before())
+    }
+
+    /// Creates an empty span pointing to directly after this span.
+    #[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
+    pub fn after(&self) -> Span {
+        Span(self.0.after())
+    }
+
     /// Creates a new span encompassing `self` and `other`.
     ///
     /// Returns `None` if `self` and `other` are from different files.
diff --git a/library/std/primitive_docs/box_into_raw.md b/library/std/primitive_docs/box_into_raw.md
new file mode 100644 (file)
index 0000000..307b9c8
--- /dev/null
@@ -0,0 +1 @@
+Box::into_raw
diff --git a/library/std/primitive_docs/fs_file.md b/library/std/primitive_docs/fs_file.md
new file mode 100644 (file)
index 0000000..13e4540
--- /dev/null
@@ -0,0 +1 @@
+fs::File
diff --git a/library/std/primitive_docs/io_bufread.md b/library/std/primitive_docs/io_bufread.md
new file mode 100644 (file)
index 0000000..bb688e3
--- /dev/null
@@ -0,0 +1 @@
+io::BufRead
diff --git a/library/std/primitive_docs/io_read.md b/library/std/primitive_docs/io_read.md
new file mode 100644 (file)
index 0000000..5118d7c
--- /dev/null
@@ -0,0 +1 @@
+io::Read
diff --git a/library/std/primitive_docs/io_seek.md b/library/std/primitive_docs/io_seek.md
new file mode 100644 (file)
index 0000000..122e6df
--- /dev/null
@@ -0,0 +1 @@
+io::Seek
diff --git a/library/std/primitive_docs/io_write.md b/library/std/primitive_docs/io_write.md
new file mode 100644 (file)
index 0000000..15dfc90
--- /dev/null
@@ -0,0 +1 @@
+io::Write
diff --git a/library/std/primitive_docs/net_tosocketaddrs.md b/library/std/primitive_docs/net_tosocketaddrs.md
new file mode 100644 (file)
index 0000000..a01f318
--- /dev/null
@@ -0,0 +1 @@
+net::ToSocketAddrs
diff --git a/library/std/primitive_docs/process_exit.md b/library/std/primitive_docs/process_exit.md
new file mode 100644 (file)
index 0000000..565a713
--- /dev/null
@@ -0,0 +1 @@
+process::exit
diff --git a/library/std/primitive_docs/string_string.md b/library/std/primitive_docs/string_string.md
new file mode 100644 (file)
index 0000000..ce7815f
--- /dev/null
@@ -0,0 +1 @@
+string::String
index 130bb5cb2b3c2b77f6b7402330dd2ded199be0f7..71645aadb1d88b717eb03e341be65ef07a24982b 100644 (file)
 //! Iterators also provide a series of *adapter* methods for performing common
 //! threads to sequences. Among the adapters are functional favorites like `map`,
 //! `fold`, `skip` and `take`. Of particular interest to collections is the
-//! `rev` adapter, that reverses any iterator that supports this operation. Most
+//! `rev` adapter, which reverses any iterator that supports this operation. Most
 //! collections provide reversible iterators as the way to iterate over them in
 //! reverse order.
 //!
index f6c2b499567abf9b245c42903ec5c98bd10cf780..d290c3c466035d5e2da432db494d263af24218b9 100644 (file)
@@ -468,9 +468,6 @@ struct ProgrammableSink {
     // Writes append to this slice
     pub buffer: Vec<u8>,
 
-    // Flush sets this flag
-    pub flushed: bool,
-
     // If true, writes will always be an error
     pub always_write_error: bool,
 
@@ -520,7 +517,6 @@ fn flush(&mut self) -> io::Result<()> {
         if self.always_flush_error {
             Err(io::Error::new(io::ErrorKind::Other, "test - always_flush_error"))
         } else {
-            self.flushed = true;
             Ok(())
         }
     }
index e8466fa06b899470cb213eb6ea295fdc1d6d86b6..4a35d36a9def72f284b48244219b347a9d140e80 100644 (file)
@@ -1611,7 +1611,7 @@ fn write_all_vectored(&mut self, mut bufs: &mut [IoSlice<'_>]) -> Result<()> {
     /// encountered.
     ///
     /// This method is primarily used to interface with the
-    /// [`format_args!()`] macro, but it is rare that this should
+    /// [`format_args!()`] macro, and it is rare that this should
     /// explicitly be called. The [`write!()`] macro should be favored to
     /// invoke this method instead.
     ///
index b0ebfe648a5234a8caf184d7ae90ef4fa87ac59f..0de9126dab2fe5679ea2390903a0c1e3293e59a4 100644 (file)
@@ -1,3 +1,6 @@
+// `library/{std,core}/src/primitive_docs.rs` should have the same contents.
+// These are different files so that relative links work properly without
+// having to have `CARGO_PKG_NAME` set, but conceptually they should always be the same.
 #[doc(primitive = "bool")]
 #[doc(alias = "true")]
 #[doc(alias = "false")]
 /// assert!(!bool_val);
 /// ```
 ///
-/// [`true`]: keyword.true.html
-/// [`false`]: keyword.false.html
+/// [`true`]: ../std/keyword.true.html
+/// [`false`]: ../std/keyword.false.html
 /// [`BitAnd`]: ops::BitAnd
 /// [`BitOr`]: ops::BitOr
 /// [`Not`]: ops::Not
-/// [`if`]: keyword.if.html
+/// [`if`]: ../std/keyword.if.html
 ///
 /// # Examples
 ///
@@ -103,7 +106,7 @@ mod prim_bool {}
 /// behaviour of the `!` type - expressions with type `!` will coerce into any other type.
 ///
 /// [`u32`]: prim@u32
-/// [`exit`]: process::exit
+#[doc = concat!("[`exit`]: ", include_str!("../primitive_docs/process_exit.md"))]
 ///
 /// # `!` and generics
 ///
@@ -188,7 +191,7 @@ mod prim_bool {}
 /// because `!` coerces to `Result<!, ConnectionError>` automatically.
 ///
 /// [`String::from_str`]: str::FromStr::from_str
-/// [`String`]: string::String
+#[doc = concat!("[`String`]: ", include_str!("../primitive_docs/string_string.md"))]
 /// [`FromStr`]: str::FromStr
 ///
 /// # `!` and traits
@@ -264,7 +267,7 @@ mod prim_bool {}
 /// `impl` for this which simply panics, but the same is true for any type (we could `impl
 /// Default` for (eg.) [`File`] by just making [`default()`] panic.)
 ///
-/// [`File`]: fs::File
+#[doc = concat!("[`File`]: ", include_str!("../primitive_docs/fs_file.md"))]
 /// [`Debug`]: fmt::Debug
 /// [`default()`]: Default::default
 ///
@@ -272,7 +275,6 @@ mod prim_bool {}
 mod prim_never {}
 
 #[doc(primitive = "char")]
-//
 /// A character type.
 ///
 /// The `char` type represents a single character. More specifically, since
@@ -304,7 +306,7 @@ mod prim_never {}
 /// assert_eq!(5, s.len() * std::mem::size_of::<u8>());
 /// ```
 ///
-/// [`String`]: string/struct.String.html
+#[doc = concat!("[`String`]: ", include_str!("../primitive_docs/string_string.md"))]
 ///
 /// As always, remember that a human intuition for 'character' might not map to
 /// Unicode's definitions. For example, despite looking similar, the 'é'
@@ -499,7 +501,7 @@ mod prim_unit {}
 /// [`null_mut`]: ptr::null_mut
 /// [`is_null`]: pointer::is_null
 /// [`offset`]: pointer::offset
-/// [`into_raw`]: Box::into_raw
+#[doc = concat!("[`into_raw`]: ", include_str!("../primitive_docs/box_into_raw.md"))]
 /// [`drop`]: mem::drop
 /// [`write`]: ptr::write
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -581,9 +583,9 @@ mod prim_pointer {}
 /// # Editions
 ///
 /// Prior to Rust 1.53, arrays did not implement [`IntoIterator`] by value, so the method call
-/// `array.into_iter()` auto-referenced into a [slice iterator](slice::iter). Right now, the old behavior
-/// is preserved in the 2015 and 2018 editions of Rust for compatibility, ignoring
-/// `IntoIterator` by value. In the future, the behavior on the 2015 and 2018 edition
+/// `array.into_iter()` auto-referenced into a [slice iterator](slice::iter). Right now, the old
+/// behavior is preserved in the 2015 and 2018 editions of Rust for compatibility, ignoring
+/// [`IntoIterator`] by value. In the future, the behavior on the 2015 and 2018 edition
 /// might be made consistent to the behavior of later editions.
 ///
 /// ```rust,edition2018
@@ -1042,15 +1044,15 @@ mod prim_usize {}
 /// References, both shared and mutable.
 ///
 /// A reference represents a borrow of some owned value. You can get one by using the `&` or `&mut`
-/// operators on a value, or by using a [`ref`](keyword.ref.html) or
-/// <code>[ref](keyword.ref.html) [mut](keyword.mut.html)</code> pattern.
+/// operators on a value, or by using a [`ref`](../std/keyword.ref.html) or
+/// <code>[ref](../std/keyword.ref.html) [mut](../std/keyword.mut.html)</code> pattern.
 ///
 /// For those familiar with pointers, a reference is just a pointer that is assumed to be
 /// aligned, not null, and pointing to memory containing a valid value of `T` - for example,
 /// <code>&[bool]</code> can only point to an allocation containing the integer values `1`
-/// ([`true`](keyword.true.html)) or `0` ([`false`](keyword.false.html)), but creating a
-/// <code>&[bool]</code> that points to an allocation containing the value `3` causes
-/// undefined behaviour.
+/// ([`true`](../std/keyword.true.html)) or `0` ([`false`](../std/keyword.false.html)), but
+/// creating a <code>&[bool]</code> that points to an allocation containing
+/// the value `3` causes undefined behaviour.
 /// In fact, <code>[Option]\<&T></code> has the same memory representation as a
 /// nullable but aligned pointer, and can be passed across FFI boundaries as such.
 ///
@@ -1117,6 +1119,7 @@ mod prim_usize {}
 ///
 /// [`DerefMut`]: ops::DerefMut
 /// [`BorrowMut`]: borrow::BorrowMut
+/// [bool]: prim@bool
 ///
 /// The following traits are implemented on `&T` references if the underlying `T` also implements
 /// that trait:
@@ -1134,7 +1137,7 @@ mod prim_usize {}
 /// [`std::fmt`]: fmt
 /// ['Pointer`]: fmt::Pointer
 /// [`Hash`]: hash::Hash
-/// [`ToSocketAddrs`]: net::ToSocketAddrs
+#[doc = concat!("[`ToSocketAddrs`]: ", include_str!("../primitive_docs/net_tosocketaddrs.md"))]
 ///
 /// `&mut T` references get all of the above except `ToSocketAddrs`, plus the following, if `T`
 /// implements that trait:
@@ -1155,9 +1158,10 @@ mod prim_usize {}
 ///
 /// [`FusedIterator`]: iter::FusedIterator
 /// [`TrustedLen`]: iter::TrustedLen
-/// [`Seek`]: io::Seek
-/// [`BufRead`]: io::BufRead
-/// [`Read`]: io::Read
+#[doc = concat!("[`Seek`]: ", include_str!("../primitive_docs/io_seek.md"))]
+#[doc = concat!("[`BufRead`]: ", include_str!("../primitive_docs/io_bufread.md"))]
+#[doc = concat!("[`Read`]: ", include_str!("../primitive_docs/io_read.md"))]
+#[doc = concat!("[`io::Write`]: ", include_str!("../primitive_docs/io_write.md"))]
 ///
 /// Note that due to method call deref coercion, simply calling a trait method will act like they
 /// work on references as well as they do on owned values! The implementations described here are
index c4b0e1e5c23392f00a4eaada6a288fb53a03df11..aa2448075141935819b27a6f4bfc69a12083c063 100644 (file)
@@ -53,7 +53,7 @@ fn write_result(
         // Because the testsuit node holds some of the information as attributes, we can't write it
         // until all of the tests has ran. Instead of writting every result as they come in, we add
         // them to a Vec and write them all at once when run is complete.
-        let duration = exec_time.map(|t| t.0.clone()).unwrap_or_default();
+        let duration = exec_time.map(|t| t.0).unwrap_or_default();
         self.results.push((desc.clone(), result.clone(), duration));
         Ok(())
     }
index f4c5a05d1e2cebbd97f717274c5d40c434887b78..694473f52c1a79970e86b1888b737e305db37041 100644 (file)
@@ -16,6 +16,7 @@
 use searcher::get_dbpath_for_term;
 
 /// A parsed terminfo database entry.
+#[allow(unused)]
 #[derive(Debug)]
 pub(crate) struct TermInfo {
     /// Names for the terminal
index c871411793073ee3c50f7fe0c42311510cbdfc27..fbc7f19cb731cfe309fc419250b51aa1919032e3 100644 (file)
@@ -590,10 +590,18 @@ fn run(self, builder: &Builder<'_>) {
         cargo.rustdocflag("-Znormalize-docs");
         cargo.rustdocflag("--show-type-layout");
         compile::rustc_cargo(builder, &mut cargo, target);
+        cargo.arg("-Zunstable-options");
         cargo.arg("-Zskip-rustdoc-fingerprint");
 
         // Only include compiler crates, no dependencies of those, such as `libc`.
+        // Do link to dependencies on `docs.rs` however using `rustdoc-map`.
         cargo.arg("--no-deps");
+        cargo.arg("-Zrustdoc-map");
+
+        // FIXME: `-Zrustdoc-map` does not yet correctly work for transitive dependencies,
+        // once this is no longer an issue the special case for `ena` can be removed.
+        cargo.rustdocflag("--extern-html-root-url");
+        cargo.rustdocflag("ena=https://docs.rs/ena/latest/");
 
         // Find dependencies for top level crates.
         let mut compiler_crates = HashSet::new();
index c7ff78ca90c9dd6b3bbbbc1233d293cada490b31..70c57e07fdeab7faa5b7f17b277c60f5280bc86c 100755 (executable)
@@ -53,7 +53,7 @@ files_to_extract=(
 for lib in c cxxrt gcc_s m thr util; do
   files_to_extract=("${files_to_extract[@]}" "./lib/lib${lib}.*" "./usr/lib/lib${lib}.*")
 done
-for lib in c++ c_nonshared compiler_rt execinfo gcc pthread rt ssp_nonshared; do
+for lib in c++ c_nonshared compiler_rt execinfo gcc pthread rt ssp_nonshared procstat; do
   files_to_extract=("${files_to_extract[@]}" "./usr/lib/lib${lib}.*")
 done
 
index 6417f5a984ad55070e00731831ef815bd472998c..c9f8692d41887e1546d32836cece40f546f421cf 100644 (file)
@@ -635,6 +635,9 @@ jobs:
               SCRIPT: python x.py dist
               # RLS does not build for aarch64-pc-windows-msvc. See rust-lang/rls#1693
               DIST_REQUIRE_ALL_TOOLS: 0
+              # Hack around this SDK version, because it doesn't work with clang.
+              # See https://github.com/rust-lang/rust/issues/88796
+              WINDOWS_SDK_20348_HACK: 1
             <<: *job-windows-xl
 
           - name: dist-i686-mingw
index 7b540b5c6e99dd2bc0f274df220bef1fb13f983a..fd29d3a022ad3860be66cbb67bf69415daee65a7 100755 (executable)
@@ -37,6 +37,12 @@ if isMacOS; then
     # `clang-ar` by accident.
     ciCommandSetEnv AR "ar"
 elif isWindows && [[ ${CUSTOM_MINGW-0} -ne 1 ]]; then
+
+    if [[ ${WINDOWS_SDK_20348_HACK-0} -eq 1 ]]; then
+        rm -rf '/c/Program Files (x86)/Windows Kits/10/include/10.0.20348.0'
+        mv '/c/Program Files (x86)/Windows Kits/10/include/'10.0.{19041,20348}.0
+    fi
+
     # 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
index 1023e4b0e2837d2ef4b2a7b4f07fb01cff29a2fc..d3da6d1ac915a3a24dd5ca14f0ef582c20042c8b 100755 (executable)
@@ -18,14 +18,6 @@ verify_backported_commits_main() {
     exit 0
   fi
 
-  echo 'git: unshallowing the repository so we can check commits'
-  git fetch \
-    --no-tags \
-    --no-recurse-submodules \
-    --progress \
-    --prune \
-    --unshallow
-
   if [[ $ci_base_branch == "beta" ]]; then
     verify_cherries master "$BETA_LIMIT" \
       || exit 1
index 6da0703beacc98d394f5af29b98abad5f5ecb6b1..3ba06e87220e343fa4547806f19891ba1189ecd0 100644 (file)
@@ -217,6 +217,7 @@ target | std | host | notes
 `armv5te-unknown-linux-uclibceabi` | ? |  | ARMv5TE Linux with uClibc
 `armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD
 `armv6-unknown-netbsd-eabihf` | ? |  |
+`armv6k-nintendo-3ds` | * |  | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain)
 `armv7-apple-ios` | ✓ |  | ARMv7 iOS, Cortex-a8
 `armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD
 `armv7-unknown-netbsd-eabihf` | ✓ | ✓ |
index a10928a7471770ae520ba86dd2a8396096cce420..444b1cbf3cc45535d01a4f66a67c2ee4df84db76 100644 (file)
@@ -375,7 +375,7 @@ Any reuse of a named label, local or otherwise, can result in a assembler or lin
 
 As a consequence, you should only use GNU assembler **numeric** [local labels] inside inline assembly code. Defining symbols in assembly code may lead to assembler and/or linker errors due to duplicate symbol definitions.
 
-Moreover, on x86 when using the default intel syntax, due to [an llvm bug], you shouldn't use labels exclusively made of `0` and `1` digits, e.g. `0`, `11` or `101010`, as they may end up being interpreted as binary values. Using `option(att_syntax)` will avoid any ambiguity, but that affects the syntax of the _entire_ `asm!` block.
+Moreover, on x86 when using the default intel syntax, due to [an llvm bug], you shouldn't use labels exclusively made of `0` and `1` digits, e.g. `0`, `11` or `101010`, as they may end up being interpreted as binary values. Using `options(att_syntax)` will avoid any ambiguity, but that affects the syntax of the _entire_ `asm!` block.
 
 ```rust,allow_fail
 #![feature(asm)]
index ff3641d6c9ab05adcf61bdca2a83228f468ef8d9..15d4563ad7461b7d083439bb726cd3a8b0289129 100644 (file)
@@ -17,7 +17,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
         let param_env = self.cx.tcx.param_env(item_def_id);
         let ty = self.cx.tcx.type_of(item_def_id);
 
-        debug!("get_blanket_impls({:?})", ty);
+        trace!("get_blanket_impls({:?})", ty);
         let mut impls = Vec::new();
         for &trait_def_id in self.cx.tcx.all_traits(()).iter() {
             if !self.cx.cache.access_levels.is_public(trait_def_id)
@@ -28,9 +28,10 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
             // NOTE: doesn't use `for_each_relevant_impl` to avoid looking at anything besides blanket impls
             let trait_impls = self.cx.tcx.trait_impls_of(trait_def_id);
             for &impl_def_id in trait_impls.blanket_impls() {
-                debug!(
+                trace!(
                     "get_blanket_impls: Considering impl for trait '{:?}' {:?}",
-                    trait_def_id, impl_def_id
+                    trait_def_id,
+                    impl_def_id
                 );
                 let trait_ref = self.cx.tcx.impl_trait_ref(impl_def_id).unwrap();
                 let is_param = matches!(trait_ref.self_ty().kind(), ty::Param(_));
@@ -50,9 +51,11 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                         // FIXME(eddyb) ignoring `obligations` might cause false positives.
                         drop(obligations);
 
-                        debug!(
+                        trace!(
                             "invoking predicate_may_hold: param_env={:?}, trait_ref={:?}, ty={:?}",
-                            param_env, trait_ref, ty
+                            param_env,
+                            trait_ref,
+                            ty
                         );
                         let predicates = self
                             .cx
index 0c81a5584301355e4d70e84c4b8139751c0d5b6b..29834c82b3de32a20d02e3a54aeec942089ddc50 100644 (file)
@@ -447,9 +447,9 @@ fn merge_attrs(
     }
 
     let (merged_attrs, cfg) = merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs);
-    debug!("merged_attrs={:?}", merged_attrs);
+    trace!("merged_attrs={:?}", merged_attrs);
 
-    debug!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id());
+    trace!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id());
     ret.push(clean::Item::from_def_id_and_attrs_and_parts(
         did,
         None,
@@ -482,12 +482,13 @@ fn build_module(
     // visit each node at most once.
     for &item in cx.tcx.item_children(did).iter() {
         if item.vis == ty::Visibility::Public {
-            if let Some(def_id) = item.res.mod_def_id() {
+            let res = item.res.expect_non_local();
+            if let Some(def_id) = res.mod_def_id() {
                 if did == def_id || !visited.insert(def_id) {
                     continue;
                 }
             }
-            if let Res::PrimTy(p) = item.res {
+            if let Res::PrimTy(p) = res {
                 // Primitive types can't be inlined so generate an import instead.
                 let prim_ty = clean::PrimitiveType::from(p);
                 items.push(clean::Item {
@@ -500,7 +501,7 @@ fn build_module(
                         clean::ImportSource {
                             path: clean::Path {
                                 global: false,
-                                res: item.res,
+                                res,
                                 segments: vec![clean::PathSegment {
                                     name: prim_ty.as_sym(),
                                     args: clean::GenericArgs::AngleBracketed {
@@ -515,9 +516,7 @@ fn build_module(
                     ))),
                     cfg: None,
                 });
-            } else if let Some(i) =
-                try_inline(cx, did, None, item.res, item.ident.name, None, visited)
-            {
+            } else if let Some(i) = try_inline(cx, did, None, res, item.ident.name, None, visited) {
                 items.extend(i)
             }
         }
@@ -557,7 +556,6 @@ fn build_macro(
     name: Symbol,
     import_def_id: Option<DefId>,
 ) -> clean::ItemKind {
-    let imported_from = cx.tcx.crate_name(def_id.krate);
     match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.sess()) {
         LoadedMacro::MacroDef(item_def, _) => {
             if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
@@ -569,7 +567,6 @@ fn build_macro(
                         def_id,
                         cx.tcx.visibility(import_def_id.unwrap_or(def_id)),
                     ),
-                    imported_from: Some(imported_from),
                 })
             } else {
                 unreachable!()
index e2ad21bba21b754400031c8bc6283494d0f974e9..e281bbc59c255c26e0b707e225d6356e5e60e6df 100644 (file)
@@ -164,14 +164,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
             );
         }
         inline::record_extern_fqn(cx, trait_ref.def_id, kind);
-        let path = external_path(
-            cx,
-            cx.tcx.item_name(trait_ref.def_id),
-            Some(trait_ref.def_id),
-            true,
-            bounds.to_vec(),
-            trait_ref.substs,
-        );
+        let path = external_path(cx, trait_ref.def_id, true, bounds.to_vec(), trait_ref.substs);
 
         debug!("ty::TraitRef\n  subst: {:?}\n", trait_ref.substs);
 
@@ -906,7 +899,7 @@ fn clean(&self, _: &mut DocContext<'_>) -> bool {
 impl Clean<Type> for hir::TraitRef<'_> {
     fn clean(&self, cx: &mut DocContext<'_>) -> Type {
         let path = self.path.clean(cx);
-        resolve_type(cx, path, self.hir_ref_id)
+        resolve_type(cx, path)
     }
 }
 
@@ -1164,7 +1157,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Item {
 
 fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
     use rustc_hir::GenericParamCount;
-    let hir::Ty { hir_id, span, ref kind } = *hir_ty;
+    let hir::Ty { hir_id: _, span, ref kind } = *hir_ty;
     let qpath = match kind {
         hir::TyKind::Path(qpath) => qpath,
         _ => unreachable!(),
@@ -1271,7 +1264,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
                 return cx.enter_alias(ty_substs, lt_substs, ct_substs, |cx| ty.clean(cx));
             }
             let path = path.clean(cx);
-            resolve_type(cx, path, hir_id)
+            resolve_type(cx, path)
         }
         hir::QPath::Resolved(Some(ref qself), ref p) => {
             // Try to normalize `<X as Y>::T` to a type
@@ -1292,7 +1285,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
                 name: p.segments.last().expect("segments were empty").ident.name,
                 self_def_id: Some(DefId::local(qself.hir_id.owner.local_def_index)),
                 self_type: Box::new(qself.clean(cx)),
-                trait_: Box::new(resolve_type(cx, trait_path, hir_id)),
+                trait_: Box::new(resolve_type(cx, trait_path)),
             }
         }
         hir::QPath::TypeRelative(ref qself, ref segment) => {
@@ -1308,7 +1301,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
                 name: segment.ident.name,
                 self_def_id: res.opt_def_id(),
                 self_type: Box::new(qself.clean(cx)),
-                trait_: Box::new(resolve_type(cx, trait_path, hir_id)),
+                trait_: Box::new(resolve_type(cx, trait_path)),
             }
         }
         hir::QPath::LangItem(..) => bug!("clean: requiring documentation of lang item"),
@@ -1406,7 +1399,7 @@ fn normalize(cx: &mut DocContext<'tcx>, ty: Ty<'_>) -> Option<Ty<'tcx>> {
 
 impl<'tcx> Clean<Type> for Ty<'tcx> {
     fn clean(&self, cx: &mut DocContext<'_>) -> Type {
-        debug!("cleaning type: {:?}", self);
+        trace!("cleaning type: {:?}", self);
         let ty = normalize(cx, self).unwrap_or(self);
         match *ty.kind() {
             ty::Never => Never,
@@ -1448,19 +1441,12 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
                     AdtKind::Enum => ItemType::Enum,
                 };
                 inline::record_extern_fqn(cx, did, kind);
-                let path = external_path(cx, cx.tcx.item_name(did), None, false, vec![], substs);
+                let path = external_path(cx, did, false, vec![], substs);
                 ResolvedPath { path, did, is_generic: false }
             }
             ty::Foreign(did) => {
                 inline::record_extern_fqn(cx, did, ItemType::ForeignType);
-                let path = external_path(
-                    cx,
-                    cx.tcx.item_name(did),
-                    None,
-                    false,
-                    vec![],
-                    InternalSubsts::empty(),
-                );
+                let path = external_path(cx, did, false, vec![], InternalSubsts::empty());
                 ResolvedPath { path, did, is_generic: false }
             }
             ty::Dynamic(ref obj, ref reg) => {
@@ -1484,8 +1470,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
 
                 for did in dids {
                     let empty = cx.tcx.intern_substs(&[]);
-                    let path =
-                        external_path(cx, cx.tcx.item_name(did), Some(did), false, vec![], empty);
+                    let path = external_path(cx, did, false, vec![], empty);
                     inline::record_extern_fqn(cx, did, ItemType::Trait);
                     let bound = PolyTrait {
                         trait_: ResolvedPath { path, did, is_generic: false },
@@ -1502,8 +1487,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
                     });
                 }
 
-                let path =
-                    external_path(cx, cx.tcx.item_name(did), Some(did), false, bindings, substs);
+                let path = external_path(cx, did, false, bindings, substs);
                 bounds.insert(
                     0,
                     PolyTrait {
@@ -1859,7 +1843,6 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Vec<Item> {
                 }
                 ItemKind::Macro(ref macro_def) => MacroItem(Macro {
                     source: display_macro_source(cx, name, &macro_def, def_id, &item.vis),
-                    imported_from: None,
                 }),
                 ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => {
                     let items = item_ids
index 5eff56a2200e10d396cfc9eba35c29b37b486859..b3c320555f9e53e08e030134b440432ed4722cab 100644 (file)
@@ -212,7 +212,7 @@ fn to_remote(url: impl ToString) -> ExternalLocation {
     crate fn keywords(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, Symbol)> {
         let root = self.def_id();
 
-        let as_keyword = |res: Res| {
+        let as_keyword = |res: Res<!>| {
             if let Res::Def(DefKind::Mod, def_id) = res {
                 let attrs = tcx.get_attrs(def_id);
                 let mut keyword = None;
@@ -243,7 +243,8 @@ fn to_remote(url: impl ToString) -> ExternalLocation {
                         hir::ItemKind::Use(ref path, hir::UseKind::Single)
                             if item.vis.node.is_pub() =>
                         {
-                            as_keyword(path.res).map(|(_, prim)| (id.def_id.to_def_id(), prim))
+                            as_keyword(path.res.expect_non_local())
+                                .map(|(_, prim)| (id.def_id.to_def_id(), prim))
                         }
                         _ => None,
                     }
@@ -274,7 +275,7 @@ fn to_remote(url: impl ToString) -> ExternalLocation {
         // Also note that this does not attempt to deal with modules tagged
         // duplicately for the same primitive. This is handled later on when
         // rendering by delegating everything to a hash map.
-        let as_primitive = |res: Res| {
+        let as_primitive = |res: Res<!>| {
             if let Res::Def(DefKind::Mod, def_id) = res {
                 let attrs = tcx.get_attrs(def_id);
                 let mut prim = None;
@@ -309,7 +310,7 @@ fn to_remote(url: impl ToString) -> ExternalLocation {
                         hir::ItemKind::Use(ref path, hir::UseKind::Single)
                             if item.vis.node.is_pub() =>
                         {
-                            as_primitive(path.res).map(|(_, prim)| {
+                            as_primitive(path.res.expect_non_local()).map(|(_, prim)| {
                                 // Pretend the primitive is local.
                                 (id.def_id.to_def_id(), prim)
                             })
@@ -461,60 +462,20 @@ pub fn from_def_id_and_attrs_and_parts(
             .map_or(&[][..], |v| v.as_slice())
             .iter()
             .filter_map(|ItemLink { link: s, link_text, did, ref fragment }| {
-                match did {
-                    Some(did) => {
-                        if let Ok((mut href, ..)) = href(did.clone(), cx) {
-                            if let Some(ref fragment) = *fragment {
-                                href.push('#');
-                                href.push_str(fragment);
-                            }
-                            Some(RenderedLink {
-                                original_text: s.clone(),
-                                new_text: link_text.clone(),
-                                href,
-                            })
-                        } else {
-                            None
-                        }
-                    }
-                    // FIXME(83083): using fragments as a side-channel for
-                    // primitive names is very unfortunate
-                    None => {
-                        let relative_to = &cx.current;
-                        if let Some(ref fragment) = *fragment {
-                            let url = match cx.cache().extern_locations.get(&self.def_id.krate()) {
-                                Some(&ExternalLocation::Local) => {
-                                    if relative_to[0] == "std" {
-                                        let depth = relative_to.len() - 1;
-                                        "../".repeat(depth)
-                                    } else {
-                                        let depth = relative_to.len();
-                                        format!("{}std/", "../".repeat(depth))
-                                    }
-                                }
-                                Some(ExternalLocation::Remote(ref s)) => {
-                                    format!("{}/std/", s.trim_end_matches('/'))
-                                }
-                                Some(ExternalLocation::Unknown) | None => {
-                                    format!("{}/std/", crate::DOC_RUST_LANG_ORG_CHANNEL)
-                                }
-                            };
-                            // This is a primitive so the url is done "by hand".
-                            let tail = fragment.find('#').unwrap_or_else(|| fragment.len());
-                            Some(RenderedLink {
-                                original_text: s.clone(),
-                                new_text: link_text.clone(),
-                                href: format!(
-                                    "{}primitive.{}.html{}",
-                                    url,
-                                    &fragment[..tail],
-                                    &fragment[tail..]
-                                ),
-                            })
-                        } else {
-                            panic!("This isn't a primitive?!");
-                        }
+                debug!(?did);
+                if let Ok((mut href, ..)) = href(*did, cx) {
+                    debug!(?href);
+                    if let Some(ref fragment) = *fragment {
+                        href.push('#');
+                        href.push_str(fragment);
                     }
+                    Some(RenderedLink {
+                        original_text: s.clone(),
+                        new_text: link_text.clone(),
+                        href,
+                    })
+                } else {
+                    None
                 }
             })
             .collect()
@@ -531,18 +492,10 @@ pub fn from_def_id_and_attrs_and_parts(
             .get(&self.def_id)
             .map_or(&[][..], |v| v.as_slice())
             .iter()
-            .filter_map(|ItemLink { link: s, link_text, did, fragment }| {
-                // FIXME(83083): using fragments as a side-channel for
-                // primitive names is very unfortunate
-                if did.is_some() || fragment.is_some() {
-                    Some(RenderedLink {
-                        original_text: s.clone(),
-                        new_text: link_text.clone(),
-                        href: String::new(),
-                    })
-                } else {
-                    None
-                }
+            .map(|ItemLink { link: s, link_text, .. }| RenderedLink {
+                original_text: s.clone(),
+                new_text: link_text.clone(),
+                href: String::new(),
             })
             .collect()
     }
@@ -963,7 +916,7 @@ fn from_iter<T>(iter: T) -> Self
     crate other_attrs: Vec<ast::Attribute>,
 }
 
-#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
 /// A link that has not yet been rendered.
 ///
 /// This link will be turned into a rendered link by [`Item::links`].
@@ -975,7 +928,7 @@ fn from_iter<T>(iter: T) -> Self
     /// This may not be the same as `link` if there was a disambiguator
     /// in an intra-doc link (e.g. \[`fn@f`\])
     pub(crate) link_text: String,
-    pub(crate) did: Option<DefId>,
+    pub(crate) did: DefId,
     /// The url fragment to append to the link
     pub(crate) fragment: Option<String>,
 }
@@ -1158,7 +1111,7 @@ impl GenericBound {
     crate fn maybe_sized(cx: &mut DocContext<'_>) -> GenericBound {
         let did = cx.tcx.require_lang_item(LangItem::Sized, None);
         let empty = cx.tcx.intern_substs(&[]);
-        let path = external_path(cx, cx.tcx.item_name(did), Some(did), false, vec![], empty);
+        let path = external_path(cx, did, false, vec![], empty);
         inline::record_extern_fqn(cx, did, ItemType::Trait);
         GenericBound::TraitBound(
             PolyTrait {
@@ -1802,6 +1755,39 @@ impl PrimitiveType {
             Never => sym::never,
         }
     }
+
+    /// Returns the DefId of the module with `doc(primitive)` for this primitive type.
+    /// Panics if there is no such module.
+    ///
+    /// This gives precedence to primitives defined in the current crate, and deprioritizes primitives defined in `core`,
+    /// but otherwise, if multiple crates define the same primitive, there is no guarantee of which will be picked.
+    /// In particular, if a crate depends on both `std` and another crate that also defines `doc(primitive)`, then
+    /// it's entirely random whether `std` or the other crate is picked. (no_std crates are usually fine unless multiple dependencies define a primitive.)
+    crate fn primitive_locations(tcx: TyCtxt<'_>) -> &FxHashMap<PrimitiveType, DefId> {
+        static PRIMITIVE_LOCATIONS: OnceCell<FxHashMap<PrimitiveType, DefId>> = OnceCell::new();
+        PRIMITIVE_LOCATIONS.get_or_init(|| {
+            let mut primitive_locations = FxHashMap::default();
+            // NOTE: technically this misses crates that are only passed with `--extern` and not loaded when checking the crate.
+            // This is a degenerate case that I don't plan to support.
+            for &crate_num in tcx.crates(()) {
+                let e = ExternalCrate { crate_num };
+                let crate_name = e.name(tcx);
+                debug!(?crate_num, ?crate_name);
+                for &(def_id, prim) in &e.primitives(tcx) {
+                    // HACK: try to link to std instead where possible
+                    if crate_name == sym::core && primitive_locations.contains_key(&prim) {
+                        continue;
+                    }
+                    primitive_locations.insert(prim, def_id);
+                }
+            }
+            let local_primitives = ExternalCrate { crate_num: LOCAL_CRATE }.primitives(tcx);
+            for (def_id, prim) in local_primitives {
+                primitive_locations.insert(prim, def_id);
+            }
+            primitive_locations
+        })
+    }
 }
 
 impl From<ast::IntTy> for PrimitiveType {
@@ -2202,7 +2188,6 @@ impl Import {
 #[derive(Clone, Debug)]
 crate struct Macro {
     crate source: String,
-    crate imported_from: Option<Symbol>,
 }
 
 #[derive(Clone, Debug)]
index de2cd60d2edcd048cca1cc1d4151c7ecea0aba2d..b0021d1234cd610ecdabb6494631ef10624dcffd 100644 (file)
     let krate = cx.tcx.hir().krate();
     let module = crate::visit_ast::RustdocVisitor::new(cx).visit(krate);
 
-    cx.cache.deref_trait_did = cx.tcx.lang_items().deref_trait();
-    cx.cache.deref_mut_trait_did = cx.tcx.lang_items().deref_mut_trait();
-    cx.cache.owned_box_did = cx.tcx.lang_items().owned_box();
-
     let mut externs = Vec::new();
     for &cnum in cx.tcx.crates(()).iter() {
         externs.push(ExternalCrate { crate_num: cnum });
@@ -97,7 +93,7 @@
 
 fn external_generic_args(
     cx: &mut DocContext<'_>,
-    trait_did: Option<DefId>,
+    did: DefId,
     has_self: bool,
     bindings: Vec<TypeBinding>,
     substs: SubstsRef<'_>,
@@ -125,42 +121,38 @@ fn external_generic_args(
         })
         .collect();
 
-    match trait_did {
-        // Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
-        Some(did) if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() => {
-            assert!(ty_kind.is_some());
-            let inputs = match ty_kind {
-                Some(ty::Tuple(ref tys)) => tys.iter().map(|t| t.expect_ty().clean(cx)).collect(),
-                _ => return GenericArgs::AngleBracketed { args, bindings },
-            };
-            let output = None;
-            // FIXME(#20299) return type comes from a projection now
-            // match types[1].kind {
-            //     ty::Tuple(ref v) if v.is_empty() => None, // -> ()
-            //     _ => Some(types[1].clean(cx))
-            // };
-            GenericArgs::Parenthesized { inputs, output }
-        }
-        _ => GenericArgs::AngleBracketed { args, bindings },
+    if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() {
+        let inputs = match ty_kind.unwrap() {
+            ty::Tuple(tys) => tys.iter().map(|t| t.expect_ty().clean(cx)).collect(),
+            _ => return GenericArgs::AngleBracketed { args, bindings },
+        };
+        let output = None;
+        // FIXME(#20299) return type comes from a projection now
+        // match types[1].kind {
+        //     ty::Tuple(ref v) if v.is_empty() => None, // -> ()
+        //     _ => Some(types[1].clean(cx))
+        // };
+        GenericArgs::Parenthesized { inputs, output }
+    } else {
+        GenericArgs::AngleBracketed { args, bindings }
     }
 }
 
-// trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar
-// from Fn<(A, B,), C> to Fn(A, B) -> C
 pub(super) fn external_path(
     cx: &mut DocContext<'_>,
-    name: Symbol,
-    trait_did: Option<DefId>,
+    did: DefId,
     has_self: bool,
     bindings: Vec<TypeBinding>,
     substs: SubstsRef<'_>,
 ) -> Path {
+    let def_kind = cx.tcx.def_kind(did);
+    let name = cx.tcx.item_name(did);
     Path {
         global: false,
-        res: Res::Err,
+        res: Res::Def(def_kind, did),
         segments: vec![PathSegment {
             name,
-            args: external_generic_args(cx, trait_did, has_self, bindings, substs),
+            args: external_generic_args(cx, did, has_self, bindings, substs),
         }],
     }
 }
@@ -409,8 +401,8 @@ fn print_const_with_custom_print_scalar(tcx: TyCtxt<'_>, ct: &'tcx ty::Const<'tc
 }
 
 /// Given a type Path, resolve it to a Type using the TyCtxt
-crate fn resolve_type(cx: &mut DocContext<'_>, path: Path, id: hir::HirId) -> Type {
-    debug!("resolve_type({:?},{:?})", path, id);
+crate fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
+    debug!("resolve_type({:?})", path);
 
     let is_generic = match path.res {
         Res::PrimTy(p) => return Primitive(PrimitiveType::from(p)),
@@ -418,7 +410,7 @@ fn print_const_with_custom_print_scalar(tcx: TyCtxt<'_>, ct: &'tcx ty::Const<'tc
             return Generic(kw::SelfUpper);
         }
         Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => {
-            return Generic(Symbol::intern(&path.whole_name()));
+            return Generic(path.segments[0].name);
         }
         Res::SelfTy(..) | Res::Def(DefKind::TyParam | DefKind::AssocTy, _) => true,
         _ => false,
index e6097f5cad7f30688168a3107bec371e08891826..9222a0338ae6fee7ae8bbb284f101ffe71354ace 100644 (file)
@@ -73,7 +73,7 @@
         search_paths: options.libs.clone(),
         crate_types,
         lint_opts: if !options.display_warnings { lint_opts } else { vec![] },
-        lint_cap: Some(options.lint_cap.clone().unwrap_or_else(|| lint::Forbid)),
+        lint_cap: Some(options.lint_cap.unwrap_or_else(|| lint::Forbid)),
         cg: options.codegen_options.clone(),
         externs: options.externs.clone(),
         unstable_features: options.render_options.unstable_features,
index 1830909d944606e1799a3acc5f2f48889a6a5ef9..bcfcc3d70395c1e3b996a50df2b1ed44af66c4da 100644 (file)
@@ -6,7 +6,7 @@
 use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::sym;
 
-use crate::clean::{self, GetDefId, ItemId};
+use crate::clean::{self, GetDefId, ItemId, PrimitiveType};
 use crate::config::RenderOptions;
 use crate::fold::DocFolder;
 use crate::formats::item_type::ItemType;
@@ -98,9 +98,6 @@
     stripped_mod: bool,
 
     crate search_index: Vec<IndexItem>,
-    crate deref_trait_did: Option<DefId>,
-    crate deref_mut_trait_did: Option<DefId>,
-    crate owned_box_did: Option<DefId>,
 
     // In rare case where a structure is defined in one module but implemented
     // in another, if the implementing module is parsed before defining module,
@@ -159,17 +156,16 @@ impl Cache {
             self.external_paths.insert(e.def_id(), (vec![name.to_string()], ItemType::Module));
         }
 
-        // Cache where all known primitives have their documentation located.
-        //
-        // Favor linking to as local extern as possible, so iterate all crates in
-        // reverse topological order.
-        for &e in krate.externs.iter().rev() {
-            for &(def_id, prim) in &e.primitives(tcx) {
-                self.primitive_locations.insert(prim, def_id);
-            }
-        }
-        for &(def_id, prim) in &krate.primitives {
-            self.primitive_locations.insert(prim, def_id);
+        // FIXME: avoid this clone (requires implementing Default manually)
+        self.primitive_locations = PrimitiveType::primitive_locations(tcx).clone();
+        for (prim, &def_id) in &self.primitive_locations {
+            let crate_name = tcx.crate_name(def_id.krate);
+            // Recall that we only allow primitive modules to be at the root-level of the crate.
+            // If that restriction is ever lifted, this will have to include the relative paths instead.
+            self.external_paths.insert(
+                def_id,
+                (vec![crate_name.to_string(), prim.as_sym().to_string()], ItemType::Primitive),
+            );
         }
 
         krate = CacheBuilder { tcx, cache: self }.fold_crate(krate);
index ea0458034899c54b2db6ff4368c8b7ba506a1c56..2fde0017dc80c63be5cb8a1ffc6728620da667f9 100644 (file)
@@ -509,7 +509,11 @@ fn to_module_fqp(shortty: ItemType, fqp: &[String]) -> &[String] {
         if shortty == ItemType::Module { fqp } else { &fqp[..fqp.len() - 1] }
     }
 
-    if !did.is_local() && !cache.access_levels.is_public(did) && !cache.document_private {
+    if !did.is_local()
+        && !cache.access_levels.is_public(did)
+        && !cache.document_private
+        && !cache.primitive_locations.values().any(|&id| id == did)
+    {
         return Err(HrefError::Private);
     }
 
@@ -517,6 +521,7 @@ fn to_module_fqp(shortty: ItemType, fqp: &[String]) -> &[String] {
     let (fqp, shortty, mut url_parts) = match cache.paths.get(&did) {
         Some(&(ref fqp, shortty)) => (fqp, shortty, {
             let module_fqp = to_module_fqp(shortty, fqp);
+            debug!(?fqp, ?shortty, ?module_fqp);
             href_relative_parts(module_fqp, relative_to)
         }),
         None => {
@@ -548,6 +553,7 @@ fn to_module_fqp(shortty: ItemType, fqp: &[String]) -> &[String] {
             url_parts.insert(0, root);
         }
     }
+    debug!(?url_parts);
     let last = &fqp.last().unwrap()[..];
     let filename;
     match shortty {
@@ -742,7 +748,7 @@ fn fmt_type<'cx>(
     use_absolute: bool,
     cx: &'cx Context<'_>,
 ) -> fmt::Result {
-    debug!("fmt_type(t = {:?})", t);
+    trace!("fmt_type(t = {:?})", t);
 
     match *t {
         clean::Generic(name) => write!(f, "{}", name),
index 5cd5254f3282d00f6dc4be2d0a37ede3613ed41d..c971e231463cdc56dd1f58c5871e06a7537f9168 100644 (file)
@@ -48,7 +48,7 @@
 mod tests;
 
 /// Options for rendering Markdown in the main body of documentation.
-pub(crate) fn opts() -> Options {
+pub(crate) fn main_body_opts() -> Options {
     Options::ENABLE_TABLES
         | Options::ENABLE_FOOTNOTES
         | Options::ENABLE_STRIKETHROUGH
@@ -56,9 +56,13 @@ pub(crate) fn opts() -> Options {
         | Options::ENABLE_SMART_PUNCTUATION
 }
 
-/// A subset of [`opts()`] used for rendering summaries.
+/// Options for rendering Markdown in summaries (e.g., in search results).
 pub(crate) fn summary_opts() -> Options {
-    Options::ENABLE_STRIKETHROUGH | Options::ENABLE_SMART_PUNCTUATION | Options::ENABLE_TABLES
+    Options::ENABLE_TABLES
+        | Options::ENABLE_FOOTNOTES
+        | Options::ENABLE_STRIKETHROUGH
+        | Options::ENABLE_TASKLISTS
+        | Options::ENABLE_SMART_PUNCTUATION
 }
 
 /// When `to_string` is called, this struct will emit the HTML corresponding to
@@ -441,6 +445,42 @@ fn next(&mut self) -> Option<Self::Item> {
     }
 }
 
+/// Wrap HTML tables into `<div>` to prevent having the doc blocks width being too big.
+struct TableWrapper<'a, I: Iterator<Item = Event<'a>>> {
+    inner: I,
+    stored_events: VecDeque<Event<'a>>,
+}
+
+impl<'a, I: Iterator<Item = Event<'a>>> TableWrapper<'a, I> {
+    fn new(iter: I) -> Self {
+        Self { inner: iter, stored_events: VecDeque::new() }
+    }
+}
+
+impl<'a, I: Iterator<Item = Event<'a>>> Iterator for TableWrapper<'a, I> {
+    type Item = Event<'a>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if let Some(first) = self.stored_events.pop_front() {
+            return Some(first);
+        }
+
+        let event = self.inner.next()?;
+
+        Some(match event {
+            Event::Start(Tag::Table(t)) => {
+                self.stored_events.push_back(Event::Start(Tag::Table(t)));
+                Event::Html(CowStr::Borrowed("<div>"))
+            }
+            Event::End(Tag::Table(t)) => {
+                self.stored_events.push_back(Event::Html(CowStr::Borrowed("</div>")));
+                Event::End(Tag::Table(t))
+            }
+            e => e,
+        })
+    }
+}
+
 type SpannedEvent<'a> = (Event<'a>, Range<usize>);
 
 /// Make headings links with anchor IDs and build up TOC.
@@ -981,7 +1021,7 @@ pub fn into_string(self) -> String {
             }
         };
 
-        let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut replacer));
+        let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(&mut replacer));
         let p = p.into_offset_iter();
 
         let mut s = String::with_capacity(md.len() * 3 / 2);
@@ -989,6 +1029,7 @@ pub fn into_string(self) -> String {
         let p = HeadingLinks::new(p, None, &mut ids);
         let p = Footnotes::new(p);
         let p = LinkReplacer::new(p.map(|(ev, _)| ev), links);
+        let p = TableWrapper::new(p);
         let p = CodeBlocks::new(p, codes, edition, playground);
         html::push_html(&mut s, p);
 
@@ -1000,7 +1041,7 @@ impl MarkdownWithToc<'_> {
     crate fn into_string(self) -> String {
         let MarkdownWithToc(md, mut ids, codes, edition, playground) = self;
 
-        let p = Parser::new_ext(md, opts()).into_offset_iter();
+        let p = Parser::new_ext(md, main_body_opts()).into_offset_iter();
 
         let mut s = String::with_capacity(md.len() * 3 / 2);
 
@@ -1009,7 +1050,8 @@ impl MarkdownWithToc<'_> {
         {
             let p = HeadingLinks::new(p, Some(&mut toc), &mut ids);
             let p = Footnotes::new(p);
-            let p = CodeBlocks::new(p.map(|(ev, _)| ev), codes, edition, playground);
+            let p = TableWrapper::new(p.map(|(ev, _)| ev));
+            let p = CodeBlocks::new(p, codes, edition, playground);
             html::push_html(&mut s, p);
         }
 
@@ -1025,7 +1067,7 @@ impl MarkdownHtml<'_> {
         if md.is_empty() {
             return String::new();
         }
-        let p = Parser::new_ext(md, opts()).into_offset_iter();
+        let p = Parser::new_ext(md, main_body_opts()).into_offset_iter();
 
         // Treat inline HTML as plain text.
         let p = p.map(|event| match event.0 {
@@ -1037,7 +1079,8 @@ impl MarkdownHtml<'_> {
 
         let p = HeadingLinks::new(p, None, &mut ids);
         let p = Footnotes::new(p);
-        let p = CodeBlocks::new(p.map(|(ev, _)| ev), codes, edition, playground);
+        let p = TableWrapper::new(p.map(|(ev, _)| ev));
+        let p = CodeBlocks::new(p, codes, edition, playground);
         html::push_html(&mut s, p);
 
         s
@@ -1099,7 +1142,7 @@ fn markdown_summary_with_limit(
         }
     };
 
-    let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut replacer));
+    let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer));
     let mut p = LinkReplacer::new(p, link_names);
 
     let mut buf = HtmlWithLimit::new(length_limit);
@@ -1246,7 +1289,8 @@ fn markdown_summary_with_limit(
         });
         None
     };
-    let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut push)).into_offset_iter();
+    let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(&mut push))
+        .into_offset_iter();
 
     // There's no need to thread an IdMap through to here because
     // the IDs generated aren't going to be emitted anywhere.
@@ -1285,7 +1329,7 @@ fn markdown_summary_with_limit(
         return code_blocks;
     }
 
-    let mut p = Parser::new_ext(md, opts()).into_offset_iter();
+    let mut p = Parser::new_ext(md, main_body_opts()).into_offset_iter();
 
     while let Some((event, offset)) = p.next() {
         if let Event::Start(Tag::CodeBlock(syntax)) = event {
index 733bedfdde9b487d2eee214069d469513a5fe366..34f9c0a8187a659f5602dd580755e5242398adbc 100644 (file)
@@ -69,7 +69,7 @@
 }
 
 // `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(Context<'_>, 104);
 
 /// Shared mutable state used in [`Context`] and elsewhere.
index 172fe5d164b7afc1f123971b97a2d7fa5b8b4d76..1f27357f6c6eaf938c219dae0a3320594cd2849d 100644 (file)
@@ -51,6 +51,7 @@
 use rustc_hir::def_id::DefId;
 use rustc_hir::Mutability;
 use rustc_middle::middle::stability;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::{kw, sym, Symbol};
 use serde::ser::SerializeSeq;
 use serde::{Serialize, Serializer};
@@ -224,7 +225,6 @@ struct AllTypes {
     opaque_tys: FxHashSet<ItemEntry>,
     statics: FxHashSet<ItemEntry>,
     constants: FxHashSet<ItemEntry>,
-    keywords: FxHashSet<ItemEntry>,
     attributes: FxHashSet<ItemEntry>,
     derives: FxHashSet<ItemEntry>,
     trait_aliases: FxHashSet<ItemEntry>,
@@ -245,7 +245,6 @@ fn new() -> AllTypes {
             opaque_tys: new_set(100),
             statics: new_set(100),
             constants: new_set(100),
-            keywords: new_set(100),
             attributes: new_set(100),
             derives: new_set(100),
             trait_aliases: new_set(100),
@@ -1069,13 +1068,13 @@ fn render_assoc_items(
         return;
     }
     if !traits.is_empty() {
-        let deref_impl = traits
-            .iter()
-            .find(|t| t.inner_impl().trait_.def_id_full(cache) == cache.deref_trait_did);
+        let deref_impl = traits.iter().find(|t| {
+            t.inner_impl().trait_.def_id_full(cache) == cx.tcx().lang_items().deref_trait()
+        });
         if let Some(impl_) = deref_impl {
-            let has_deref_mut = traits
-                .iter()
-                .any(|t| t.inner_impl().trait_.def_id_full(cache) == cache.deref_mut_trait_did);
+            let has_deref_mut = traits.iter().any(|t| {
+                t.inner_impl().trait_.def_id_full(cache) == cx.tcx().lang_items().deref_mut_trait()
+            });
             render_deref_methods(w, cx, impl_, containing_item, has_deref_mut);
         }
         let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) =
@@ -1165,7 +1164,7 @@ fn render_deref_methods(
     }
 }
 
-fn should_render_item(item: &clean::Item, deref_mut_: bool, cache: &Cache) -> bool {
+fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> bool {
     let self_type_opt = match *item.kind {
         clean::MethodItem(ref method, _) => method.decl.self_type(),
         clean::TyMethodItem(ref method) => method.decl.self_type(),
@@ -1179,7 +1178,7 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, cache: &Cache) -> bo
                 (mutability == Mutability::Mut, false, false)
             }
             SelfTy::SelfExplicit(clean::ResolvedPath { did, .. }) => {
-                (false, Some(did) == cache.owned_box_did, false)
+                (false, Some(did) == tcx.lang_items().owned_box(), false)
             }
             SelfTy::SelfValue => (false, false, true),
             _ => (false, false, false),
@@ -1302,7 +1301,7 @@ fn doc_impl_item(
             && match render_mode {
                 RenderMode::Normal => true,
                 RenderMode::ForDeref { mut_: deref_mut_ } => {
-                    should_render_item(&item, deref_mut_, cx.cache())
+                    should_render_item(&item, deref_mut_, cx.tcx())
                 }
             };
 
@@ -1800,13 +1799,13 @@ fn get_methods(
     for_deref: bool,
     used_links: &mut FxHashSet<String>,
     deref_mut: bool,
-    cache: &Cache,
+    tcx: TyCtxt<'_>,
 ) -> Vec<String> {
     i.items
         .iter()
         .filter_map(|item| match item.name {
             Some(ref name) if !name.is_empty() && item.is_method() => {
-                if !for_deref || should_render_item(item, deref_mut, cache) {
+                if !for_deref || should_render_item(item, deref_mut, tcx) {
                     Some(format!(
                         "<a href=\"#{}\">{}</a>",
                         get_next_url(used_links, format!("method.{}", name)),
@@ -1868,7 +1867,9 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
             let mut ret = v
                 .iter()
                 .filter(|i| i.inner_impl().trait_.is_none())
-                .flat_map(move |i| get_methods(i.inner_impl(), false, used_links_bor, false, cache))
+                .flat_map(move |i| {
+                    get_methods(i.inner_impl(), false, used_links_bor, false, cx.tcx())
+                })
                 .collect::<Vec<_>>();
             if !ret.is_empty() {
                 // We want links' order to be reproducible so we don't use unstable sort.
@@ -1886,11 +1887,9 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
         }
 
         if v.iter().any(|i| i.inner_impl().trait_.is_some()) {
-            if let Some(impl_) = v
-                .iter()
-                .filter(|i| i.inner_impl().trait_.is_some())
-                .find(|i| i.inner_impl().trait_.def_id_full(cache) == cache.deref_trait_did)
-            {
+            if let Some(impl_) = v.iter().filter(|i| i.inner_impl().trait_.is_some()).find(|i| {
+                i.inner_impl().trait_.def_id_full(cache) == cx.tcx().lang_items().deref_trait()
+            }) {
                 sidebar_deref_methods(cx, out, impl_, v);
             }
 
@@ -1988,10 +1987,9 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V
                 }
             }
         }
-        let deref_mut = v
-            .iter()
-            .filter(|i| i.inner_impl().trait_.is_some())
-            .any(|i| i.inner_impl().trait_.def_id_full(c) == c.deref_mut_trait_did);
+        let deref_mut = v.iter().filter(|i| i.inner_impl().trait_.is_some()).any(|i| {
+            i.inner_impl().trait_.def_id_full(c) == cx.tcx().lang_items().deref_mut_trait()
+        });
         let inner_impl = target
             .def_id_full(c)
             .or_else(|| {
@@ -2004,7 +2002,9 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V
             let mut ret = impls
                 .iter()
                 .filter(|i| i.inner_impl().trait_.is_none())
-                .flat_map(|i| get_methods(i.inner_impl(), true, &mut used_links, deref_mut, c))
+                .flat_map(|i| {
+                    get_methods(i.inner_impl(), true, &mut used_links, deref_mut, cx.tcx())
+                })
                 .collect::<Vec<_>>();
             if !ret.is_empty() {
                 write!(
index 470749ef7b3387759cc295e21533a43bab114636..52505f2d634717fa70f06a43f59d0a528a24b0f7 100644 (file)
@@ -256,6 +256,10 @@ fn cmp(
 
     debug!("{:?}", indices);
     let mut curty = None;
+    // See: https://github.com/rust-lang/rust/issues/88545
+    let item_table_block_size = 900usize;
+    let mut item_table_nth_element = 0usize;
+
     for &idx in &indices {
         let myitem = &items[idx];
         if myitem.is_stripped() {
@@ -275,11 +279,13 @@ fn cmp(
             write!(
                 w,
                 "<h2 id=\"{id}\" class=\"section-header\">\
-                       <a href=\"#{id}\">{name}</a></h2>\n{}",
+                    <a href=\"#{id}\">{name}</a>\
+                 </h2>\n{}",
                 ITEM_TABLE_OPEN,
                 id = cx.derive_id(short.to_owned()),
                 name = name
             );
+            item_table_nth_element = 0;
         }
 
         match *myitem.kind {
@@ -386,6 +392,13 @@ fn cmp(
                 );
             }
         }
+
+        item_table_nth_element += 1;
+        if item_table_nth_element > item_table_block_size {
+            w.write_str(ITEM_TABLE_CLOSE);
+            w.write_str(ITEM_TABLE_OPEN);
+            item_table_nth_element = 0;
+        }
     }
 
     if curty.is_some() {
@@ -944,15 +957,15 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni
 }
 
 fn print_tuple_struct_fields(w: &mut Buffer, cx: &Context<'_>, s: &[clean::Item]) {
-    for (i, ty) in s
-        .iter()
-        .map(|f| if let clean::StructFieldItem(ref ty) = *f.kind { ty } else { unreachable!() })
-        .enumerate()
-    {
+    for (i, ty) in s.iter().enumerate() {
         if i > 0 {
             w.write_str(",&nbsp;");
         }
-        write!(w, "{}", ty.print(cx));
+        match *ty.kind {
+            clean::StrippedItem(box clean::StructFieldItem(_)) => w.write_str("_"),
+            clean::StructFieldItem(ref ty) => write!(w, "{}", ty.print(cx)),
+            _ => unreachable!(),
+        }
     }
 }
 
@@ -1068,24 +1081,27 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
                     name = variant.name.as_ref().unwrap(),
                 );
                 for field in fields {
-                    use crate::clean::StructFieldItem;
-                    if let StructFieldItem(ref ty) = *field.kind {
-                        let id = cx.derive_id(format!(
-                            "variant.{}.field.{}",
-                            variant.name.as_ref().unwrap(),
-                            field.name.as_ref().unwrap()
-                        ));
-                        write!(
-                            w,
-                            "<span id=\"{id}\" class=\"variant small-section-header\">\
-                                 <a href=\"#{id}\" class=\"anchor field\"></a>\
-                                 <code>{f}:&nbsp;{t}</code>\
-                             </span>",
-                            id = id,
-                            f = field.name.as_ref().unwrap(),
-                            t = ty.print(cx)
-                        );
-                        document(w, cx, field, Some(variant));
+                    match *field.kind {
+                        clean::StrippedItem(box clean::StructFieldItem(_)) => {}
+                        clean::StructFieldItem(ref ty) => {
+                            let id = cx.derive_id(format!(
+                                "variant.{}.field.{}",
+                                variant.name.as_ref().unwrap(),
+                                field.name.as_ref().unwrap()
+                            ));
+                            write!(
+                                w,
+                                "<span id=\"{id}\" class=\"variant small-section-header\">\
+                                    <a href=\"#{id}\" class=\"anchor field\"></a>\
+                                    <code>{f}:&nbsp;{t}</code>\
+                                </span>",
+                                id = id,
+                                f = field.name.as_ref().unwrap(),
+                                t = ty.print(cx)
+                            );
+                            document(w, cx, field, Some(variant));
+                        }
+                        _ => unreachable!(),
                     }
                 }
                 w.write_str("</div></div>");
index 23ca6eeaf3bb969be1af9f6ab6526bdfa12a0171..2d4bfc62af68e94e5fa26c8c14ba306b2953a903 100644 (file)
@@ -522,6 +522,11 @@ nav.sub {
        position: relative;
 }
 
+.docblock > * {
+       max-width: 100%;
+       overflow-x: auto;
+}
+
 .content .out-of-band {
        flex-grow: 0;
        text-align: right;
index e6bbd237cda7d72f2f1320ae442c05cc6936f320..f8ea7a499b2340a4dcbd14e991d3f6131a1ba409 100644 (file)
@@ -30,9 +30,7 @@ pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> {
             .get(&item.def_id)
             .into_iter()
             .flatten()
-            .filter_map(|clean::ItemLink { link, did, .. }| {
-                did.map(|did| (link.clone(), from_item_id(did.into())))
-            })
+            .map(|clean::ItemLink { link, did, .. }| (link.clone(), from_item_id((*did).into())))
             .collect();
         let docs = item.attrs.collapsed_doc_value();
         let attrs = item
index 56ef15eb8842017b1320425fb719f4cf8390895c..37faa6742927a2860a543ab97f36f5a42dd92ce7 100644 (file)
@@ -2,7 +2,7 @@
 use crate::clean::*;
 use crate::core::DocContext;
 use crate::fold::DocFolder;
-use crate::html::markdown::opts;
+use crate::html::markdown::main_body_opts;
 use core::ops::Range;
 use pulldown_cmark::{Event, Parser, Tag};
 use regex::Regex;
@@ -83,7 +83,7 @@ fn fold_item(&mut self, item: Item) -> Option<Item> {
                 });
             };
 
-            let mut p = Parser::new_ext(&dox, opts()).into_offset_iter();
+            let mut p = Parser::new_ext(&dox, main_body_opts()).into_offset_iter();
 
             while let Some((event, range)) = p.next() {
                 match event {
index 92e678e4c024ba9f3f67b8f2f3bba8aa35715570..721af3313d27f6d33d76888b36d25f9fbcc62818 100644 (file)
@@ -4,8 +4,10 @@
 use crate::html::markdown::{find_testable_code, ErrorCodes};
 use crate::passes::doc_test_lints::{should_have_doc_example, Tests};
 use crate::passes::Pass;
+use rustc_hir as hir;
 use rustc_lint::builtin::MISSING_DOCS;
 use rustc_middle::lint::LintLevelSource;
+use rustc_middle::ty::DefIdTree;
 use rustc_session::lint;
 use rustc_span::FileName;
 use serde::Serialize;
@@ -221,10 +223,42 @@ fn fold_item(&mut self, i: clean::Item) -> Option<clean::Item> {
                     .hir()
                     .local_def_id_to_hir_id(i.def_id.expect_def_id().expect_local());
                 let (level, source) = self.ctx.tcx.lint_level_at_node(MISSING_DOCS, hir_id);
+
+                // In case we have:
+                //
+                // ```
+                // enum Foo { Bar(u32) }
+                // // or:
+                // struct Bar(u32);
+                // ```
+                //
+                // there is no need to require documentation on the fields of tuple variants and
+                // tuple structs.
+                let should_be_ignored = i
+                    .def_id
+                    .as_def_id()
+                    .and_then(|def_id| self.ctx.tcx.parent(def_id))
+                    .and_then(|def_id| self.ctx.tcx.hir().get_if_local(def_id))
+                    .map(|node| {
+                        matches!(
+                            node,
+                            hir::Node::Variant(hir::Variant {
+                                data: hir::VariantData::Tuple(_, _),
+                                ..
+                            }) | hir::Node::Item(hir::Item {
+                                kind: hir::ItemKind::Struct(hir::VariantData::Tuple(_, _), _),
+                                ..
+                            })
+                        )
+                    })
+                    .unwrap_or(false);
+
                 // `missing_docs` is allow-by-default, so don't treat this as ignoring the item
-                // unless the user had an explicit `allow`
-                let should_have_docs =
-                    level != lint::Level::Allow || matches!(source, LintLevelSource::Default);
+                // unless the user had an explicit `allow`.
+                //
+                let should_have_docs = !should_be_ignored
+                    && (level != lint::Level::Allow || matches!(source, LintLevelSource::Default));
+
                 debug!("counting {:?} {:?} in {:?}", i.type_(), i.name, filename);
                 self.items.entry(filename).or_default().count_item(
                     has_docs,
index 178c8c15a158861ca6483398e43650bf6c08f113..c0c37ee061198573e3cacc768966215563edaba5 100644 (file)
@@ -14,7 +14,7 @@
 };
 use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_middle::ty::TyCtxt;
-use rustc_middle::{bug, ty};
+use rustc_middle::{bug, span_bug, ty};
 use rustc_resolve::ParentScope;
 use rustc_session::lint::Lint;
 use rustc_span::hygiene::{MacroKind, SyntaxContext};
@@ -98,14 +98,10 @@ fn name(self, tcx: TyCtxt<'_>) -> Symbol {
         }
     }
 
-    fn def_id(self) -> DefId {
-        self.opt_def_id().expect("called def_id() on a primitive")
-    }
-
-    fn opt_def_id(self) -> Option<DefId> {
+    fn def_id(self, tcx: TyCtxt<'_>) -> DefId {
         match self {
-            Res::Def(_, id) => Some(id),
-            Res::Primitive(_) => None,
+            Res::Def(_, id) => id,
+            Res::Primitive(prim) => *PrimitiveType::primitive_locations(tcx).get(&prim).unwrap(),
         }
     }
 
@@ -237,10 +233,7 @@ enum AnchorFailure {
     /// link, Rustdoc disallows having a user-specified anchor.
     ///
     /// Most of the time this is fine, because you can just link to the page of
-    /// the item if you want to provide your own anchor. For primitives, though,
-    /// rustdoc uses the anchor as a side channel to know which page to link to;
-    /// it doesn't show up in the generated link. Ideally, rustdoc would remove
-    /// this limitation, allowing you to link to subheaders on primitives.
+    /// the item if you want to provide your own anchor.
     RustdocAnchorConflict(Res),
 }
 
@@ -388,7 +381,7 @@ fn resolve_primitive_associated_item(
                         ty::AssocKind::Const => "associatedconstant",
                         ty::AssocKind::Type => "associatedtype",
                     };
-                    let fragment = format!("{}#{}.{}", prim_ty.as_sym(), out, item_name);
+                    let fragment = format!("{}.{}", out, item_name);
                     (Res::Primitive(prim_ty), fragment, Some((kind.as_def_kind(), item.def_id)))
                 })
         })
@@ -475,14 +468,6 @@ fn resolve<'path>(
                     return handle_variant(self.cx, res, extra_fragment);
                 }
                 // Not a trait item; just return what we found.
-                Res::Primitive(ty) => {
-                    if extra_fragment.is_some() {
-                        return Err(ErrorKind::AnchorFailure(
-                            AnchorFailure::RustdocAnchorConflict(res),
-                        ));
-                    }
-                    return Ok((res, Some(ty.as_sym().to_string())));
-                }
                 _ => return Ok((res, extra_fragment.clone())),
             }
         }
@@ -517,6 +502,8 @@ fn resolve<'path>(
                 let (res, fragment, side_channel) =
                     self.resolve_associated_item(ty_res, item_name, ns, module_id)?;
                 let result = if extra_fragment.is_some() {
+                    // NOTE: can never be a primitive since `side_channel.is_none()` only when `res`
+                    // is a trait (and the side channel DefId is always an associated item).
                     let diag_res = side_channel.map_or(res, |(k, r)| Res::Def(k, r));
                     Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict(diag_res)))
                 } else {
@@ -1152,7 +1139,7 @@ fn resolve_link(
             module_id = DefId { krate, index: CRATE_DEF_INDEX };
         }
 
-        let (mut res, mut fragment) = self.resolve_with_disambiguator_cached(
+        let (mut res, fragment) = self.resolve_with_disambiguator_cached(
             ResolutionInfo {
                 module_id,
                 dis: disambiguator,
@@ -1174,16 +1161,7 @@ fn resolve_link(
             if let Some(prim) = resolve_primitive(path_str, TypeNS) {
                 // `prim@char`
                 if matches!(disambiguator, Some(Disambiguator::Primitive)) {
-                    if fragment.is_some() {
-                        anchor_failure(
-                            self.cx,
-                            diag_info,
-                            AnchorFailure::RustdocAnchorConflict(prim),
-                        );
-                        return None;
-                    }
                     res = prim;
-                    fragment = Some(prim.name(self.cx.tcx).to_string());
                 } else {
                     // `[char]` when a `char` module is in scope
                     let candidates = vec![res, prim];
@@ -1303,12 +1281,17 @@ fn resolve_link(
                     }
                 }
 
-                Some(ItemLink { link: ori_link.link, link_text, did: None, fragment })
+                Some(ItemLink {
+                    link: ori_link.link,
+                    link_text,
+                    did: res.def_id(self.cx.tcx),
+                    fragment,
+                })
             }
             Res::Def(kind, id) => {
                 verify(kind, id)?;
                 let id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id));
-                Some(ItemLink { link: ori_link.link, link_text, did: Some(id), fragment })
+                Some(ItemLink { link: ori_link.link, link_text, did: id, fragment })
             }
         }
     }
@@ -1323,7 +1306,7 @@ fn resolve_with_disambiguator_cached(
         if let Some(ref cached) = self.visited_links.get(&key) {
             match cached {
                 Some(cached) => {
-                    self.kind_side_channel.set(cached.side_channel.clone());
+                    self.kind_side_channel.set(cached.side_channel);
                     return Some(cached.res.clone());
                 }
                 None if cache_resolution_failure => return None,
@@ -2069,8 +2052,11 @@ fn anchor_failure(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>, failure: A
             diag.span_label(sp, "invalid anchor");
         }
         if let AnchorFailure::RustdocAnchorConflict(Res::Primitive(_)) = failure {
-            diag.note("this restriction may be lifted in a future release");
-            diag.note("see https://github.com/rust-lang/rust/issues/83083 for more information");
+            if let Some(sp) = sp {
+                span_bug!(sp, "anchors should be allowed now");
+            } else {
+                bug!("anchors should be allowed now");
+            }
         }
     });
 }
@@ -2198,10 +2184,11 @@ fn handle_variant(
     use rustc_middle::ty::DefIdTree;
 
     if extra_fragment.is_some() {
+        // NOTE: `res` can never be a primitive since this function is only called when `tcx.def_kind(res) == DefKind::Variant`.
         return Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict(res)));
     }
     cx.tcx
-        .parent(res.def_id())
+        .parent(res.def_id(cx.tcx))
         .map(|parent| {
             let parent_def = Res::Def(DefKind::Enum, parent);
             let variant = cx.tcx.expect_variant_res(res.as_hir_res().unwrap());
index f29d38e3e078a51251edb7668d72fa0465f0a8ef..a0144a5298eba24b3d2cc94f0e6d562473c00d08 100644 (file)
@@ -2,7 +2,7 @@
 use crate::clean::*;
 use crate::core::DocContext;
 use crate::fold::DocFolder;
-use crate::html::markdown::opts;
+use crate::html::markdown::main_body_opts;
 use core::ops::Range;
 use pulldown_cmark::{Event, Parser, Tag};
 use std::iter::Peekable;
@@ -192,7 +192,7 @@ fn fold_item(&mut self, item: Item) -> Option<Item> {
             let mut is_in_comment = None;
             let mut in_code_block = false;
 
-            let p = Parser::new_ext(&dox, opts()).into_offset_iter();
+            let p = Parser::new_ext(&dox, main_body_opts()).into_offset_iter();
 
             for (event, range) in p {
                 match event {
index 3e06b4173144ca4a26d5a7831d5e8f680c21c3aa..3e98ba08fb9ca376dbb5b4e4b0d307811f909e6d 100644 (file)
@@ -67,7 +67,7 @@ fn update(&mut self, did: DefId, level: Option<AccessLevel>) -> Option<AccessLev
         }
     }
 
-    fn visit_item(&mut self, res: Res) {
+    fn visit_item(&mut self, res: Res<!>) {
         let def_id = res.def_id();
         let vis = self.tcx.visibility(def_id);
         let inherited_item_level = if vis == Visibility::Public { self.prev_level } else { None };
index ec995b75d71c5f3b9a82fe084259477eb22f74da..86c7daa627aefda1371568b948eba21edf720747 160000 (submodule)
@@ -1 +1 @@
-Subproject commit ec995b75d71c5f3b9a82fe084259477eb22f74da
+Subproject commit 86c7daa627aefda1371568b948eba21edf720747
diff --git a/src/test/codegen/panic-in-drop-abort.rs b/src/test/codegen/panic-in-drop-abort.rs
new file mode 100644 (file)
index 0000000..62d0935
--- /dev/null
@@ -0,0 +1,54 @@
+// compile-flags: -Z panic-in-drop=abort -O
+
+// Ensure that unwinding code paths are eliminated from the output after
+// optimization.
+
+#![crate_type = "lib"]
+use std::any::Any;
+use std::mem::forget;
+
+pub struct ExternDrop;
+impl Drop for ExternDrop {
+    #[inline(always)]
+    fn drop(&mut self) {
+        // This call may potentially unwind.
+        extern "Rust" {
+            fn extern_drop();
+        }
+        unsafe {
+            extern_drop();
+        }
+    }
+}
+
+struct AssertNeverDrop;
+impl Drop for AssertNeverDrop {
+    #[inline(always)]
+    fn drop(&mut self) {
+        // This call should be optimized away as unreachable.
+        extern "C" {
+            fn should_not_appear_in_output();
+        }
+        unsafe {
+            should_not_appear_in_output();
+        }
+    }
+}
+
+// CHECK-LABEL: normal_drop
+// CHECK-NOT: should_not_appear_in_output
+#[no_mangle]
+pub fn normal_drop(x: ExternDrop) {
+    let guard = AssertNeverDrop;
+    drop(x);
+    forget(guard);
+}
+
+// CHECK-LABEL: indirect_drop
+// CHECK-NOT: should_not_appear_in_output
+#[no_mangle]
+pub fn indirect_drop(x: Box<dyn Any>) {
+    let guard = AssertNeverDrop;
+    drop(x);
+    forget(guard);
+}
index c35c32554983a6976d08789fb606d422d7713dd8..d300e374bec909e22d0b8356f566b680f13f67ef 100644 (file)
@@ -9,6 +9,10 @@
 // This fails on lldb 6.0.1 on x86-64 Fedora 28; so ignore Linux for now.
 // ignore-linux
 
+// This started failing in windows too. See https://github.com/rust-lang/rust/issues/88796
+// FIXME: fix and unignore this on windows
+// ignore-windows
+
 // compile-flags:-g
 
 // === GDB TESTS ===================================================================================
index 9463f82c797496b5a05f9fde1f3622f3dd47c1c4..67b5da510f843e5d8c55f64785a8d5a697616f68 100644 (file)
@@ -2,6 +2,10 @@
 // ignore-tidy-linelength
 // compile-flags:-g
 
+// This started failing recently. See https://github.com/rust-lang/rust/issues/88796
+// FIXME: fix and unignore this
+// ignore-windows
+
 // cdb-command: g
 
 // Note: The natvis used to visualize niche-layout enums don't work correctly in cdb
index baeada69d1c9a2883ff095deed89c8fc9b5b4d6b..cb2e6c618b1ab209ba016a1711bfee9e9cf4e72d 100644 (file)
@@ -6,6 +6,10 @@
 // min-lldb-version: 310
 // min-cdb-version: 10.0.18317.1001
 
+// This started failing recently. See https://github.com/rust-lang/rust/issues/88796
+// FIXME: fix and unignore this
+// ignore-windows
+
 // === GDB TESTS ===================================================================================
 
 // gdb-command: run
index 9b3b381d6210ac4f81b73721bc00fa01054c850a..dd3dce4e7209c746dfd49a479156ae8b6b23b060 100644 (file)
@@ -1,9 +1,15 @@
-// revisions: rpass1 rpass2
+// revisions: rpass1 rpass2 rpass3 rpass4
 // compile-flags: -Zquery-dep-graph
+// [rpass1]compile-flags: -Zincremental-ignore-spans
+// [rpass2]compile-flags: -Zincremental-ignore-spans
+// [rpass3]compile-flags: -Zincremental-relative-spans
+// [rpass4]compile-flags: -Zincremental-relative-spans
 
 #![feature(rustc_attrs)]
-#![rustc_partition_codegened(module = "change_symbol_export_status-mod1", cfg = "rpass2")]
+#![rustc_partition_reused(module = "change_symbol_export_status-mod1", cfg = "rpass2")]
 #![rustc_partition_reused(module = "change_symbol_export_status-mod2", cfg = "rpass2")]
+#![rustc_partition_reused(module = "change_symbol_export_status-mod1", cfg = "rpass4")]
+#![rustc_partition_reused(module = "change_symbol_export_status-mod2", cfg = "rpass4")]
 
 // This test case makes sure that a change in symbol visibility is detected by
 // our dependency tracking. We do this by changing a module's visibility to
 // even from an executable. Plain Rust functions are only exported from Rust
 // libraries, which our test infrastructure does not support.
 
-#[cfg(rpass1)]
+#[cfg(any(rpass1,rpass3))]
 pub mod mod1 {
     #[no_mangle]
     pub fn foo() {}
 }
 
-#[cfg(rpass2)]
+#[cfg(any(rpass2,rpass4))]
 mod mod1 {
     #[no_mangle]
     pub fn foo() {}
index d4201400f0fc697152f103ef29dbb3301fca7f8c..648f71f9230c3b3b7abe384e2cdbf81169907786 100644 (file)
@@ -6,8 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 
 #![allow(warnings)]
@@ -19,14 +25,16 @@ fn callee2(_x: u32, _y: i64) {}
 
 
 // Change Callee (Function)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_callee_function() {
     callee1(1, 2)
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_callee_function() {
     callee2(1, 2)
 }
@@ -34,14 +42,16 @@ pub fn change_callee_function() {
 
 
 // Change Argument (Function)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_argument_function() {
     callee1(1, 2)
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_argument_function() {
     callee1(1, 3)
 }
@@ -50,13 +60,15 @@ pub fn change_argument_function() {
 
 // Change Callee Indirectly (Function)
 mod change_callee_indirectly_function {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::callee1 as callee;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::callee2 as callee;
 
     #[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn change_callee_indirectly_function() {
         callee(1, 2)
     }
@@ -70,15 +82,17 @@ fn method2(&self, _x: char, _y: bool) {}
 }
 
 // Change Callee (Method)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_callee_method() {
     let s = Struct;
     s.method1('x', true);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_callee_method() {
     let s = Struct;
     s.method2('x', true);
@@ -87,15 +101,17 @@ pub fn change_callee_method() {
 
 
 // Change Argument (Method)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_argument_method() {
     let s = Struct;
     s.method1('x', true);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_argument_method() {
     let s = Struct;
     s.method1('y', true);
@@ -104,15 +120,17 @@ pub fn change_argument_method() {
 
 
 // Change Callee (Method, UFCS)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_ufcs_callee_method() {
     let s = Struct;
     Struct::method1(&s, 'x', true);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_ufcs_callee_method() {
     let s = Struct;
     Struct::method2(&s, 'x', true);
@@ -121,32 +139,36 @@ pub fn change_ufcs_callee_method() {
 
 
 // Change Argument (Method, UFCS)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_argument_method_ufcs() {
     let s = Struct;
     Struct::method1(&s, 'x', true);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_argument_method_ufcs() {
     let s = Struct;
-    Struct::method1(&s, 'x', false);
+    Struct::method1(&s, 'x',false);
 }
 
 
 
 // Change To UFCS
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_to_ufcs() {
     let s = Struct;
-    s.method1('x', true);
+    s.method1('x', true); // ------
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 // One might think this would be expanded in the hir_owner_nodes/Mir, but it actually
 // results in slightly different hir_owner/Mir.
 pub fn change_to_ufcs() {
@@ -162,15 +184,15 @@ fn method1(&self, _x: char, _y: bool) {}
 
 // Change UFCS Callee Indirectly
 pub mod change_ufcs_callee_indirectly {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::Struct as Struct;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::Struct2 as Struct;
 
     #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
     #[rustc_clean(cfg="cfail3")]
-
-
+    #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn change_ufcs_callee_indirectly() {
         let s = Struct;
         Struct::method1(&s, 'q', false)
index 4a00a6c72f79ea2572b4b29bca8eea9e8b931b15..2a4306fc17c2d9406a9df9c5acc0c9ff7adb70f6 100644 (file)
@@ -6,8 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans -Zmir-opt-level=0
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -Zmir-opt-level=0
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
 
 
 // Change closure body
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_closure_body() {
     let _ = || 1u32;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_closure_body() {
     let _ = || 3u32;
 }
@@ -30,15 +38,17 @@ pub fn change_closure_body() {
 
 
 // Add parameter
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_parameter() {
     let x = 0u32;
-    let _ = || x + 1;
+    let _ = |      | x + 1;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_parameter() {
     let x = 0u32;
     let _ = |x: u32| x + 1;
@@ -47,14 +57,16 @@ pub fn add_parameter() {
 
 
 // Change parameter pattern
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_parameter_pattern() {
-    let _ = |x: (u32,)| x;
+    let _ = | x  : (u32,)| x;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, typeck, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, typeck, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_parameter_pattern() {
     let _ = |(x,): (u32,)| x;
 }
@@ -62,14 +74,16 @@ pub fn change_parameter_pattern() {
 
 
 // Add `move` to closure
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_move() {
-    let _ = || 1;
+    let _ =      || 1;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_move() {
     let _ = move || 1;
 }
@@ -77,15 +91,17 @@ pub fn add_move() {
 
 
 // Add type ascription to parameter
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_type_ascription_to_parameter() {
-    let closure = |x| x + 1u32;
+    let closure = |x     | x + 1u32;
     let _: u32 = closure(1);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2", except = "hir_owner_nodes, typeck")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner_nodes, typeck")]
+#[rustc_clean(cfg = "cfail6")]
 pub fn add_type_ascription_to_parameter() {
     let closure = |x: u32| x + 1u32;
     let _: u32 = closure(1);
@@ -94,15 +110,17 @@ pub fn add_type_ascription_to_parameter() {
 
 
 // Change parameter type
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_parameter_type() {
     let closure = |x: u32| (x as u64) + 1;
     let _ = closure(1);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_parameter_type() {
     let closure = |x: u16| (x as u64) + 1;
     let _ = closure(1);
index 6e0db6a49aae2054db9aa0e27cec564c90491764..c85f0bbecdb3928bacb3afe2e5f33d66fe85bfeb 100644 (file)
@@ -7,7 +7,7 @@
 
 // build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// compile-flags: -Z query-dep-graph
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
index 26ff6b109dc326f2703462523cf07418d32114fb..7522fa5a0260c4ce30625781a5896f08a7b8d817 100644 (file)
@@ -6,8 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans -Zmir-opt-level=0
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -Zmir-opt-level=0
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
@@ -24,7 +30,7 @@ pub enum Enum {
 }
 
 // Change field value (struct-like) -----------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_field_value_struct_like() -> Enum {
     Enum::Struct {
         x: 0,
@@ -33,9 +39,11 @@ pub fn change_field_value_struct_like() -> Enum {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_field_value_struct_like() -> Enum {
     Enum::Struct {
         x: 0,
@@ -47,7 +55,7 @@ pub fn change_field_value_struct_like() -> Enum {
 
 
 // Change field order (struct-like) -----------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_field_order_struct_like() -> Enum {
     Enum::Struct {
         x: 3,
@@ -56,9 +64,11 @@ pub fn change_field_order_struct_like() -> Enum {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 // FIXME(michaelwoerister):Interesting. I would have thought that that changes the MIR. And it
 // would if it were not all constants
 pub fn change_field_order_struct_like() -> Enum {
@@ -86,18 +96,20 @@ pub enum Enum2 {
 }
 
 // Change constructor path (struct-like) ------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_constructor_path_struct_like() {
-    let _ = Enum::Struct {
+    let _ = Enum ::Struct {
         x: 0,
         y: 1,
         z: 2,
     };
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_constructor_path_struct_like() {
     let _ = Enum2::Struct {
         x: 0,
@@ -109,18 +121,20 @@ pub fn change_constructor_path_struct_like() {
 
 
 // Change variant (regular struct) ------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_constructor_variant_struct_like() {
-    let _ = Enum2::Struct {
+    let _ = Enum2::Struct  {
         x: 0,
         y: 1,
         z: 2,
     };
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_constructor_variant_struct_like() {
     let _ = Enum2::Struct2 {
         x: 0,
@@ -132,9 +146,9 @@ pub fn change_constructor_variant_struct_like() {
 
 // Change constructor path indirectly (struct-like) -------------------------
 pub mod change_constructor_path_indirectly_struct_like {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::Enum as TheEnum;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::Enum2 as TheEnum;
 
     #[rustc_clean(
@@ -143,6 +157,12 @@ pub mod change_constructor_path_indirectly_struct_like {
                 typeck"
     )]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,\
+                typeck"
+    )]
+    #[rustc_clean(cfg="cfail6")]
     pub fn function() -> TheEnum {
         TheEnum::Struct {
             x: 0,
@@ -156,13 +176,15 @@ pub fn function() -> TheEnum {
 // Change constructor variant indirectly (struct-like) ---------------------------
 pub mod change_constructor_variant_indirectly_struct_like {
     use super::Enum2;
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::Enum2::Struct as Variant;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::Enum2::Struct2 as Variant;
 
     #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn function() -> Enum2 {
         Variant {
             x: 0,
@@ -174,14 +196,16 @@ pub fn function() -> Enum2 {
 
 
 // Change field value (tuple-like) -------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_field_value_tuple_like() -> Enum {
     Enum::Tuple(0, 1, 2)
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_field_value_tuple_like() -> Enum {
     Enum::Tuple(0, 1, 3)
 }
@@ -189,17 +213,22 @@ pub fn change_field_value_tuple_like() -> Enum {
 
 
 // Change constructor path (tuple-like) --------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_constructor_path_tuple_like() {
-    let _ = Enum::Tuple(0, 1, 2);
+    let _ = Enum ::Tuple(0, 1, 2);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(
     cfg="cfail2",
     except="hir_owner_nodes,optimized_mir,typeck"
 )]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(
+    cfg="cfail5",
+    except="hir_owner_nodes,optimized_mir,typeck"
+)]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_constructor_path_tuple_like() {
     let _ = Enum2::Tuple(0, 1, 2);
 }
@@ -207,17 +236,22 @@ pub fn change_constructor_path_tuple_like() {
 
 
 // Change constructor variant (tuple-like) --------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_constructor_variant_tuple_like() {
-    let _ = Enum2::Tuple(0, 1, 2);
+    let _ = Enum2::Tuple (0, 1, 2);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(
     cfg="cfail2",
     except="hir_owner_nodes,optimized_mir,typeck"
 )]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(
+    cfg="cfail5",
+    except="hir_owner_nodes,optimized_mir,typeck"
+)]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_constructor_variant_tuple_like() {
     let _ = Enum2::Tuple2(0, 1, 2);
 }
@@ -225,9 +259,9 @@ pub fn change_constructor_variant_tuple_like() {
 
 // Change constructor path indirectly (tuple-like) ---------------------------
 pub mod change_constructor_path_indirectly_tuple_like {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::Enum as TheEnum;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::Enum2 as TheEnum;
 
     #[rustc_clean(
@@ -236,6 +270,12 @@ pub mod change_constructor_path_indirectly_tuple_like {
                 typeck"
     )]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,\
+                typeck"
+    )]
+    #[rustc_clean(cfg="cfail6")]
     pub fn function() -> TheEnum {
         TheEnum::Tuple(0, 1, 2)
     }
@@ -246,13 +286,15 @@ pub fn function() -> TheEnum {
 // Change constructor variant indirectly (tuple-like) ---------------------------
 pub mod change_constructor_variant_indirectly_tuple_like {
     use super::Enum2;
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::Enum2::Tuple as Variant;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::Enum2::Tuple2 as Variant;
 
     #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn function() -> Enum2 {
         Variant(0, 1, 2)
     }
@@ -272,14 +314,16 @@ pub enum Clike2 {
 }
 
 // Change constructor path (C-like) --------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_constructor_path_c_like() {
-    let _x = Clike::B;
+    let _x = Clike ::B;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_constructor_path_c_like() {
     let _x = Clike2::B;
 }
@@ -287,14 +331,16 @@ pub fn change_constructor_path_c_like() {
 
 
 // Change constructor variant (C-like) --------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_constructor_variant_c_like() {
     let _x = Clike::A;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_constructor_variant_c_like() {
     let _x = Clike::C;
 }
@@ -302,9 +348,9 @@ pub fn change_constructor_variant_c_like() {
 
 // Change constructor path indirectly (C-like) ---------------------------
 pub mod change_constructor_path_indirectly_c_like {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::Clike as TheEnum;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::Clike2 as TheEnum;
 
     #[rustc_clean(
@@ -313,6 +359,12 @@ pub mod change_constructor_path_indirectly_c_like {
                 typeck"
     )]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,\
+                typeck"
+    )]
+    #[rustc_clean(cfg="cfail6")]
     pub fn function() -> TheEnum {
         TheEnum::B
     }
@@ -323,13 +375,15 @@ pub fn function() -> TheEnum {
 // Change constructor variant indirectly (C-like) ---------------------------
 pub mod change_constructor_variant_indirectly_c_like {
     use super::Clike;
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::Clike::A as Variant;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::Clike::B as Variant;
 
     #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn function() -> Clike {
         Variant
     }
index 76bff3cad3882b56f63c85242941680da0ba21a5..ab9c740844b8fd3967b28fd69d8a3461fda9f2d0 100644 (file)
 // the same between rev2 and rev3.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
 
 
 // Change enum visibility -----------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumVisibility { A }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 pub enum EnumVisibility {
     A
 }
@@ -35,15 +43,17 @@ pub enum EnumVisibility {
 
 
 // Change name of a c-style variant -------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumChangeNameCStyleVariant {
     Variant1,
     Variant2,
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumChangeNameCStyleVariant {
     Variant1,
     Variant2Changed,
@@ -52,15 +62,17 @@ enum EnumChangeNameCStyleVariant {
 
 
 // Change name of a tuple-style variant ---------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumChangeNameTupleStyleVariant {
     Variant1,
     Variant2(u32, f32),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumChangeNameTupleStyleVariant {
     Variant1,
     Variant2Changed(u32, f32),
@@ -69,15 +81,17 @@ enum EnumChangeNameTupleStyleVariant {
 
 
 // Change name of a struct-style variant --------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumChangeNameStructStyleVariant {
     Variant1,
     Variant2 { a: u32, b: f32 },
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumChangeNameStructStyleVariant {
     Variant1,
     Variant2Changed { a: u32, b: f32 },
@@ -86,31 +100,33 @@ enum EnumChangeNameStructStyleVariant {
 
 
 // Change the value of a c-style variant --------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumChangeValueCStyleVariant0 {
     Variant1,
     Variant2 = 11,
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumChangeValueCStyleVariant0 {
     Variant1,
-
-    Variant2 =
-        22,
+    Variant2 = 22,
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumChangeValueCStyleVariant1 {
     Variant1,
     Variant2,
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumChangeValueCStyleVariant1 {
     Variant1,
     Variant2 = 11,
@@ -119,14 +135,16 @@ enum EnumChangeValueCStyleVariant1 {
 
 
 // Add a c-style variant ------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddCStyleVariant {
     Variant1,
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumAddCStyleVariant {
     Variant1,
     Variant2,
@@ -135,15 +153,17 @@ enum EnumAddCStyleVariant {
 
 
 // Remove a c-style variant ---------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumRemoveCStyleVariant {
     Variant1,
     Variant2,
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumRemoveCStyleVariant {
     Variant1,
 }
@@ -151,14 +171,16 @@ enum EnumRemoveCStyleVariant {
 
 
 // Add a tuple-style variant --------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddTupleStyleVariant {
     Variant1,
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumAddTupleStyleVariant {
     Variant1,
     Variant2(u32, f32),
@@ -167,15 +189,17 @@ enum EnumAddTupleStyleVariant {
 
 
 // Remove a tuple-style variant -----------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumRemoveTupleStyleVariant {
     Variant1,
     Variant2(u32, f32),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumRemoveTupleStyleVariant {
     Variant1,
 }
@@ -183,14 +207,16 @@ enum EnumRemoveTupleStyleVariant {
 
 
 // Add a struct-style variant -------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddStructStyleVariant {
     Variant1,
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumAddStructStyleVariant {
     Variant1,
     Variant2 { a: u32, b: f32 },
@@ -199,15 +225,17 @@ enum EnumAddStructStyleVariant {
 
 
 // Remove a struct-style variant ----------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumRemoveStructStyleVariant {
     Variant1,
     Variant2 { a: u32, b: f32 },
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumRemoveStructStyleVariant {
     Variant1,
 }
@@ -215,14 +243,16 @@ enum EnumRemoveStructStyleVariant {
 
 
 // Change the type of a field in a tuple-style variant ------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumChangeFieldTypeTupleStyleVariant {
     Variant1(u32, u32),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumChangeFieldTypeTupleStyleVariant {
     Variant1(u32,
         u64),
@@ -231,15 +261,17 @@ enum EnumChangeFieldTypeTupleStyleVariant {
 
 
 // Change the type of a field in a struct-style variant -----------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumChangeFieldTypeStructStyleVariant {
     Variant1,
     Variant2 { a: u32, b: u32 },
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumChangeFieldTypeStructStyleVariant {
     Variant1,
     Variant2 {
@@ -251,14 +283,16 @@ enum EnumChangeFieldTypeStructStyleVariant {
 
 
 // Change the name of a field in a struct-style variant -----------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumChangeFieldNameStructStyleVariant {
     Variant1 { a: u32, b: u32 },
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumChangeFieldNameStructStyleVariant {
     Variant1 { a: u32, c: u32 },
 }
@@ -266,14 +300,16 @@ enum EnumChangeFieldNameStructStyleVariant {
 
 
 // Change order of fields in a tuple-style variant ----------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumChangeOrderTupleStyleVariant {
     Variant1(u32, u64),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumChangeOrderTupleStyleVariant {
     Variant1(
         u64,
@@ -283,14 +319,16 @@ enum EnumChangeOrderTupleStyleVariant {
 
 
 // Change order of fields in a struct-style variant ---------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumChangeFieldOrderStructStyleVariant {
     Variant1 { a: u32, b: f32 },
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumChangeFieldOrderStructStyleVariant {
     Variant1 { b: f32, a: u32 },
 }
@@ -298,14 +336,16 @@ enum EnumChangeFieldOrderStructStyleVariant {
 
 
 // Add a field to a tuple-style variant ---------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddFieldTupleStyleVariant {
     Variant1(u32, u32),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumAddFieldTupleStyleVariant {
     Variant1(u32, u32, u32),
 }
@@ -313,14 +353,16 @@ enum EnumAddFieldTupleStyleVariant {
 
 
 // Add a field to a struct-style variant --------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddFieldStructStyleVariant {
     Variant1 { a: u32, b: u32 },
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumAddFieldStructStyleVariant {
     Variant1 { a: u32, b: u32, c: u32 },
 }
@@ -328,15 +370,17 @@ enum EnumAddFieldStructStyleVariant {
 
 
 // Add #[must_use] to the enum ------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddMustUse {
     Variant1,
     Variant2,
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 #[must_use]
 enum EnumAddMustUse {
     Variant1,
@@ -346,15 +390,17 @@ enum EnumAddMustUse {
 
 
 // Add #[repr(C)] to the enum -------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddReprC {
     Variant1,
     Variant2,
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="type_of")]
+#[rustc_clean(cfg="cfail6")]
 #[repr(C)]
 enum EnumAddReprC {
     Variant1,
@@ -364,14 +410,16 @@ enum EnumAddReprC {
 
 
 // Change the name of a type parameter ----------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumChangeNameOfTypeParameter<S> {
     Variant1(S),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumChangeNameOfTypeParameter<T> {
     Variant1(T),
 }
@@ -379,15 +427,17 @@ enum EnumChangeNameOfTypeParameter<T> {
 
 
 // Add a type parameter ------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddTypeParameter<S> {
     Variant1(S),
     Variant2(S),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumAddTypeParameter<S, T> {
     Variant1(S),
     Variant2(T),
@@ -396,14 +446,16 @@ enum EnumAddTypeParameter<S, T> {
 
 
 // Change the name of a lifetime parameter ------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumChangeNameOfLifetimeParameter<'a> {
     Variant1(&'a u32),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumChangeNameOfLifetimeParameter<'b> {
     Variant1(&'b u32),
 }
@@ -411,15 +463,17 @@ enum EnumChangeNameOfLifetimeParameter<'b> {
 
 
 // Add a lifetime parameter ---------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddLifetimeParameter<'a> {
     Variant1(&'a u32),
     Variant2(&'a u32),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumAddLifetimeParameter<'a, 'b> {
     Variant1(&'a u32),
     Variant2(&'b u32),
@@ -428,30 +482,34 @@ enum EnumAddLifetimeParameter<'a, 'b> {
 
 
 // Add a lifetime bound to a lifetime parameter -------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddLifetimeParameterBound<'a, 'b> {
     Variant1(&'a u32),
     Variant2(&'b u32),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumAddLifetimeParameterBound<'a, 'b: 'a> {
     Variant1(&'a u32),
     Variant2(&'b u32),
 }
 
 // Add a lifetime bound to a type parameter -----------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddLifetimeBoundToParameter<'a, T> {
     Variant1(T),
     Variant2(&'a u32),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,predicates_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumAddLifetimeBoundToParameter<'a, T: 'a> {
     Variant1(T),
     Variant2(&'a u32),
@@ -460,14 +518,16 @@ enum EnumAddLifetimeBoundToParameter<'a, T: 'a> {
 
 
 // Add a trait bound to a type parameter --------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddTraitBound<S> {
     Variant1(S),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumAddTraitBound<T: Sync> {
     Variant1(T),
 }
@@ -475,15 +535,17 @@ enum EnumAddTraitBound<T: Sync> {
 
 
 // Add a lifetime bound to a lifetime parameter in where clause ---------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddLifetimeParameterBoundWhere<'a, 'b> {
     Variant1(&'a u32),
     Variant2(&'b u32),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumAddLifetimeParameterBoundWhere<'a, 'b> where 'b: 'a {
     Variant1(&'a u32),
     Variant2(&'b u32),
@@ -492,15 +554,17 @@ enum EnumAddLifetimeParameterBoundWhere<'a, 'b> where 'b: 'a {
 
 
 // Add a lifetime bound to a type parameter in where clause -------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddLifetimeBoundToParameterWhere<'a, T> {
     Variant1(T),
     Variant2(&'a u32),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,predicates_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumAddLifetimeBoundToParameterWhere<'a, T> where T: 'a {
     Variant1(T),
     Variant2(&'a u32),
@@ -509,14 +573,16 @@ enum EnumAddLifetimeBoundToParameterWhere<'a, T> where T: 'a {
 
 
 // Add a trait bound to a type parameter in where clause ----------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumAddTraitBoundWhere<S> {
     Variant1(S),
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumAddTraitBoundWhere<T> where T: Sync {
     Variant1(T),
 }
@@ -524,15 +590,17 @@ enum EnumAddTraitBoundWhere<T> where T: Sync {
 
 
 // In an enum with two variants, swap usage of type parameters ----------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumSwapUsageTypeParameters<A, B> {
     Variant1 { a: A },
     Variant2 { a: B },
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumSwapUsageTypeParameters<A, B> {
     Variant1 {
         a: B
@@ -545,15 +613,17 @@ enum EnumSwapUsageTypeParameters<A, B> {
 
 
 // In an enum with two variants, swap usage of lifetime parameters ------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 enum EnumSwapUsageLifetimeParameters<'a, 'b> {
     Variant1 { a: &'a u32 },
     Variant2 { b: &'b u32 },
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 enum EnumSwapUsageLifetimeParameters<'a, 'b> {
     Variant1 {
         a: &'b u32
@@ -572,13 +642,15 @@ enum EnumSwapUsageLifetimeParameters<'a, 'b> {
 
 // Change field type in tuple-style variant indirectly by modifying a use statement
 mod change_field_type_indirectly_tuple_style {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedType1 as FieldType;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedType2 as FieldType;
 
     #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+    #[rustc_clean(cfg="cfail6")]
     enum TupleStyle {
         Variant1(
             FieldType
@@ -590,13 +662,15 @@ enum TupleStyle {
 
 // Change field type in record-style variant indirectly by modifying a use statement
 mod change_field_type_indirectly_struct_style {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedType1 as FieldType;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedType2 as FieldType;
 
     #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+    #[rustc_clean(cfg="cfail6")]
     enum StructStyle {
         Variant1 {
             a: FieldType
@@ -613,13 +687,15 @@ trait ReferencedTrait2 {}
 
 // Change trait bound of type parameter indirectly by modifying a use statement
 mod change_trait_bound_indirectly {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedTrait1 as Trait;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedTrait2 as Trait;
 
     #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")]
+    #[rustc_clean(cfg="cfail6")]
     enum Enum<T: Trait> {
         Variant1(T)
     }
@@ -629,13 +705,15 @@ enum Enum<T: Trait> {
 
 // Change trait bound of type parameter in where clause indirectly by modifying a use statement
 mod change_trait_bound_indirectly_where {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedTrait1 as Trait;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedTrait2 as Trait;
 
     #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")]
+    #[rustc_clean(cfg="cfail6")]
     enum Enum<T> where T: Trait {
         Variant1(T)
     }
index 40b6925bc72769ff8ded2221e620314fa212c5da..d5fb8a2e53437a118e03c66aa14dbcaa77f8c74f 100644 (file)
@@ -1,6 +1,12 @@
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
 //         the hash of the hir_owner_nodes node should change, but not the hash of
 //         either the hir_owner or the Metadata node.
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn body_not_exported_to_metadata() -> u32 {
     1
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn body_not_exported_to_metadata() -> u32 {
     2
 }
@@ -28,15 +36,17 @@ pub fn body_not_exported_to_metadata() -> u32 {
 //         marked as #[inline]. Only the hash of the hir_owner depnode should be
 //         unaffected by a change to the body.
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 #[inline]
 pub fn body_exported_to_metadata_because_of_inline() -> u32 {
     1
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 #[inline]
 pub fn body_exported_to_metadata_because_of_inline() -> u32 {
     2
@@ -48,15 +58,17 @@ pub fn body_exported_to_metadata_because_of_inline() -> u32 {
 //         generic. Only the hash of the hir_owner depnode should be
 //         unaffected by a change to the body.
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 #[inline]
 pub fn body_exported_to_metadata_because_of_generic() -> u32 {
     1
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 #[inline]
 pub fn body_exported_to_metadata_because_of_generic() -> u32 {
     2
index 1160bc376c49a182296ec26f99496eac7b9c79c2..783407a9e04f1cf8ef9e8adbc5a33bf3ebc520d6 100644 (file)
@@ -6,8 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
 #![crate_type = "rlib"]
 
 // Change function name --------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 extern "C" {
     pub fn change_function_name1(c: i64) -> i32;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2", except = "hir_owner")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner")]
+#[rustc_clean(cfg = "cfail6")]
 extern "C" {
     pub fn change_function_name2(c: i64) -> i32;
 }
 
 // Change parameter name -------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 extern "C" {
     pub fn change_parameter_name(c: i64) -> i32;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
 extern "C" {
     pub fn change_parameter_name(d: i64) -> i32;
 }
 
 // Change parameter type -------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 extern "C" {
     pub fn change_parameter_type(c: i64) -> i32;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
 extern "C" {
     pub fn change_parameter_type(c: i32) -> i32;
 }
 
 // Change return type ----------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 extern "C" {
     pub fn change_return_type(c: i32) -> i32;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
 extern "C" {
-    pub fn change_return_type(c: i32) -> i8;
+    pub fn change_return_type(c: i32) -> i8 ;
 }
 
 // Add parameter ---------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 extern "C" {
-    pub fn add_parameter(c: i32) -> i32;
+    pub fn add_parameter(c: i32        ) -> i32;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
 extern "C" {
     pub fn add_parameter(c: i32, d: i32) -> i32;
 }
 
 // Add return type -------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 extern "C" {
-    pub fn add_return_type(c: i32);
+    pub fn add_return_type(c: i32)       ;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
 extern "C" {
     pub fn add_return_type(c: i32) -> i32;
 }
 
 // Make function variadic ------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 extern "C" {
-    pub fn make_function_variadic(c: i32);
+    pub fn make_function_variadic(c: i32     );
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
 extern "C" {
     pub fn make_function_variadic(c: i32, ...);
 }
 
 // Change calling convention ---------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 extern "C" {
     pub fn change_calling_convention(c: i32);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2", except = "hir_owner")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner")]
+#[rustc_clean(cfg = "cfail6")]
 extern "rust-call" {
     pub fn change_calling_convention(c: i32);
 }
 
 // Make function public --------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 extern "C" {
     fn make_function_public(c: i32);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2", except = "hir_owner")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner")]
+#[rustc_clean(cfg = "cfail6")]
 extern "C" {
     pub fn make_function_public(c: i32);
 }
 
 // Add function ----------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 extern "C" {
     pub fn add_function1(c: i32);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2", except = "hir_owner")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner")]
+#[rustc_clean(cfg = "cfail6")]
 extern "C" {
     pub fn add_function1(c: i32);
     pub fn add_function2();
 }
 
 // Change link-name ------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 #[link(name = "foo")]
 extern "C" {
     pub fn change_link_name(c: i32);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
 #[link(name = "bar")]
 extern "C" {
     pub fn change_link_name(c: i32);
 
 // Indirectly change parameter type --------------------------------------------
 mod indirectly_change_parameter_type {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::c_i32 as c_int;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::c_i64 as c_int;
 
     #[rustc_clean(cfg = "cfail2")]
     #[rustc_clean(cfg = "cfail3")]
+    #[rustc_clean(cfg = "cfail5")]
+    #[rustc_clean(cfg = "cfail6")]
     extern "C" {
         pub fn indirectly_change_parameter_type(c: c_int);
     }
@@ -179,13 +209,15 @@ mod indirectly_change_parameter_type {
 
 // Indirectly change return type --------------------------------------------
 mod indirectly_change_return_type {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::c_i32 as c_int;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::c_i64 as c_int;
 
     #[rustc_clean(cfg = "cfail2")]
     #[rustc_clean(cfg = "cfail3")]
+    #[rustc_clean(cfg = "cfail5")]
+    #[rustc_clean(cfg = "cfail6")]
     extern "C" {
         pub fn indirectly_change_return_type() -> c_int;
     }
index e1460503d2d9424d0a0adf515ef7cf1e40342c72..5a944d28a0b913facc8955e2f829a7d50dcbce42 100644 (file)
@@ -6,8 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
@@ -15,7 +21,7 @@
 
 
 // Change loop body ------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_loop_body() {
     let mut _x = 0;
     for _ in 0..1 {
@@ -24,9 +30,11 @@ pub fn change_loop_body() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_loop_body() {
     let mut _x = 0;
     for _ in 0..1 {
@@ -38,7 +46,7 @@ pub fn change_loop_body() {
 
 
 // Change iteration variable name ----------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_iteration_variable_name() {
     let mut _x = 0;
     for _i in 0..1 {
@@ -47,9 +55,11 @@ pub fn change_iteration_variable_name() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_iteration_variable_name() {
     let mut _x = 0;
     for _a in 0..1 {
@@ -61,18 +71,20 @@ pub fn change_iteration_variable_name() {
 
 
 // Change iteration variable pattern -------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_iteration_variable_pattern() {
     let mut _x = 0;
-    for _i in &[0, 1, 2] {
+    for  _i in &[0, 1, 2] {
         _x = 1;
         break;
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir, typeck, promoted_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_iteration_variable_pattern() {
     let mut _x = 0;
     for &_i in &[0, 1, 2] {
@@ -84,7 +96,7 @@ pub fn change_iteration_variable_pattern() {
 
 
 // Change iterable -------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_iterable() {
     let mut _x = 0;
     for _ in &[0, 1, 2] {
@@ -93,9 +105,11 @@ pub fn change_iterable() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, promoted_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, promoted_mir, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_iterable() {
     let mut _x = 0;
     for _ in &[0, 1, 3] {
@@ -107,17 +121,20 @@ pub fn change_iterable() {
 
 
 // Add break -------------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_break() {
     let mut _x = 0;
     for _ in 0..1 {
         _x = 1;
+        // ---
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_break() {
     let mut _x = 0;
     for _ in 0..1 {
@@ -129,18 +146,20 @@ pub fn add_break() {
 
 
 // Add loop label --------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_loop_label() {
     let mut _x = 0;
-    for _ in 0..1 {
+            for _ in 0..1 {
         _x = 1;
         break;
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_loop_label() {
     let mut _x = 0;
     'label: for _ in 0..1 {
@@ -152,18 +171,20 @@ pub fn add_loop_label() {
 
 
 // Add loop label to break -----------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_loop_label_to_break() {
     let mut _x = 0;
     'label: for _ in 0..1 {
         _x = 1;
-        break;
+        break       ;
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_loop_label_to_break() {
     let mut _x = 0;
     'label: for _ in 0..1 {
@@ -175,7 +196,7 @@ pub fn add_loop_label_to_break() {
 
 
 // Change break label ----------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_break_label() {
     let mut _x = 0;
     'outer: for _ in 0..1 {
@@ -186,9 +207,11 @@ pub fn change_break_label() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_break_label() {
     let mut _x = 0;
     'outer: for _ in 0..1 {
@@ -202,18 +225,20 @@ pub fn change_break_label() {
 
 
 // Add loop label to continue --------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_loop_label_to_continue() {
     let mut _x = 0;
     'label: for _ in 0..1 {
         _x = 1;
-        continue;
+        continue       ;
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_loop_label_to_continue() {
     let mut _x = 0;
     'label: for _ in 0..1 {
@@ -225,7 +250,7 @@ pub fn add_loop_label_to_continue() {
 
 
 // Change continue label ----------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_continue_label() {
     let mut _x = 0;
     'outer: for _ in 0..1 {
@@ -236,9 +261,11 @@ pub fn change_continue_label() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_continue_label() {
     let mut _x = 0;
     'outer: for _ in 0..1 {
@@ -252,7 +279,7 @@ pub fn change_continue_label() {
 
 
 // Change continue to break ----------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_continue_to_break() {
     let mut _x = 0;
     for _ in 0..1 {
@@ -261,13 +288,15 @@ pub fn change_continue_to_break() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_continue_to_break() {
     let mut _x = 0;
     for _ in 0..1 {
         _x = 1;
-        break;
+        break   ;
     }
 }
index c8530c70f78d2086e9ae31de93e8d8e1ab3738ec..4124eada188e862e990fc5e3d930c084ba8855c0 100644 (file)
@@ -6,8 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(linkage)]
 
 // Add Parameter ---------------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_parameter() {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(
     cfg = "cfail2",
     except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
 )]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail6")]
 pub fn add_parameter(p: i32) {}
 
 // Add Return Type -------------------------------------------------------------
 
-#[cfg(cfail1)]
-pub fn add_return_type() {}
+#[cfg(any(cfail1,cfail4))]
+pub fn add_return_type()       {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg = "cfail6")]
 pub fn add_return_type() -> () {}
 
 // Change Parameter Type -------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn type_of_parameter(p: i32) {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(
     cfg = "cfail2",
     except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
 )]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail6")]
 pub fn type_of_parameter(p: i64) {}
 
 // Change Parameter Type Reference ---------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn type_of_parameter_ref(p: &i32) {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(
     cfg = "cfail2",
     except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
 )]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail6")]
 pub fn type_of_parameter_ref(p: &mut i32) {}
 
 // Change Parameter Order ------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn order_of_parameters(p1: i32, p2: i64) {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(
     cfg = "cfail2",
     except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
 )]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail6")]
 pub fn order_of_parameters(p2: i64, p1: i32) {}
 
 // Unsafe ----------------------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn make_unsafe() {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(
     cfg = "cfail2",
     except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
 )]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail6")]
 pub unsafe fn make_unsafe() {}
 
 // Extern ----------------------------------------------------------------------
 
-#[cfg(cfail1)]
-pub fn make_extern() {}
+#[cfg(any(cfail1,cfail4))]
+pub            fn make_extern() {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, typeck, fn_sig")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, typeck, fn_sig")]
+#[rustc_clean(cfg = "cfail6")]
 pub extern "C" fn make_extern() {}
 
 // Type Parameter --------------------------------------------------------------
 
-#[cfg(cfail1)]
-pub fn type_parameter() {}
+#[cfg(any(cfail1,cfail4))]
+pub fn type_parameter   () {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(
     cfg = "cfail2",
     except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of"
 )]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of"
+)]
+#[rustc_clean(cfg = "cfail6")]
 pub fn type_parameter<T>() {}
 
 // Lifetime Parameter ----------------------------------------------------------
 
-#[cfg(cfail1)]
-pub fn lifetime_parameter() {}
+#[cfg(any(cfail1,cfail4))]
+pub fn lifetime_parameter    () {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, generics_of,fn_sig")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, generics_of,fn_sig")]
+#[rustc_clean(cfg = "cfail6")]
 pub fn lifetime_parameter<'a>() {}
 
 // Trait Bound -----------------------------------------------------------------
 
-#[cfg(cfail1)]
-pub fn trait_bound<T>() {}
+#[cfg(any(cfail1,cfail4))]
+pub fn trait_bound<T    >() {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, predicates_of")]
 #[rustc_clean(cfg = "cfail3")]
 pub fn trait_bound<T: Eq>() {}
 
 // Builtin Bound ---------------------------------------------------------------
 
-#[cfg(cfail1)]
-pub fn builtin_bound<T>() {}
+#[cfg(any(cfail1,cfail4))]
+pub fn builtin_bound<T      >() {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, predicates_of")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, predicates_of")]
+#[rustc_clean(cfg = "cfail6")]
 pub fn builtin_bound<T: Send>() {}
 
 // Lifetime Bound --------------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn lifetime_bound<'a, T>() {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(
     cfg = "cfail2",
     except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of,fn_sig"
 )]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of,fn_sig,optimized_mir"
+)]
+#[rustc_clean(cfg = "cfail6")]
 pub fn lifetime_bound<'a, T: 'a>() {}
 
 // Second Trait Bound ----------------------------------------------------------
 
-#[cfg(cfail1)]
-pub fn second_trait_bound<T: Eq>() {}
+#[cfg(any(cfail1,cfail4))]
+pub fn second_trait_bound<T: Eq        >() {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, predicates_of")]
 #[rustc_clean(cfg = "cfail3")]
 pub fn second_trait_bound<T: Eq + Clone>() {}
 
 // Second Builtin Bound --------------------------------------------------------
 
-#[cfg(cfail1)]
-pub fn second_builtin_bound<T: Send>() {}
+#[cfg(any(cfail1,cfail4))]
+pub fn second_builtin_bound<T: Send        >() {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, predicates_of")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, predicates_of")]
+#[rustc_clean(cfg = "cfail6")]
 pub fn second_builtin_bound<T: Send + Sized>() {}
 
 // Second Lifetime Bound -------------------------------------------------------
 
-#[cfg(cfail1)]
-pub fn second_lifetime_bound<'a, 'b, T: 'a>() {}
+#[cfg(any(cfail1,cfail4))]
+pub fn second_lifetime_bound<'a, 'b, T: 'a     >() {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(
     cfg = "cfail2",
     except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of,fn_sig"
 )]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of,fn_sig"
+)]
+#[rustc_clean(cfg = "cfail6")]
 pub fn second_lifetime_bound<'a, 'b, T: 'a + 'b>() {}
 
 // Inline ----------------------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn inline() {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
 #[inline]
 pub fn inline() {}
 
 // Inline Never ----------------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 #[inline(always)]
 pub fn inline_never() {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
 #[inline(never)]
 pub fn inline_never() {}
 
 // No Mangle -------------------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn no_mangle() {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
 #[no_mangle]
 pub fn no_mangle() {}
 
 // Linkage ---------------------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn linkage() {}
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
 #[linkage = "weak_odr"]
 pub fn linkage() {}
 
 // Return Impl Trait -----------------------------------------------------------
 
-#[cfg(cfail1)]
-pub fn return_impl_trait() -> i32 {
+#[cfg(any(cfail1,cfail4))]
+pub fn return_impl_trait() -> i32        {
     0
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, typeck, fn_sig")]
 #[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, typeck, fn_sig, optimized_mir")]
+#[rustc_clean(cfg = "cfail6")]
 pub fn return_impl_trait() -> impl Clone {
     0
 }
 
 // Change Return Impl Trait ----------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_return_impl_trait() -> impl Clone {
     0u32
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg = "cfail2")]
 #[rustc_clean(cfg = "cfail3")]
-pub fn change_return_impl_trait() -> impl Copy {
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
+pub fn change_return_impl_trait() -> impl  Copy {
     0u32
 }
 
@@ -267,9 +335,9 @@ pub fn change_return_impl_trait() -> impl Copy {
 pub struct ReferencedType2;
 
 pub mod change_return_type_indirectly {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedType1 as ReturnType;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedType2 as ReturnType;
 
     #[rustc_clean(
@@ -277,6 +345,11 @@ pub mod change_return_type_indirectly {
         except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
     )]
     #[rustc_clean(cfg = "cfail3")]
+    #[rustc_clean(
+        cfg = "cfail5",
+        except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+    )]
+    #[rustc_clean(cfg = "cfail6")]
     pub fn indirect_return_type() -> ReturnType {
         ReturnType {}
     }
@@ -285,9 +358,9 @@ pub fn indirect_return_type() -> ReturnType {
 // Change Parameter Type Indirectly --------------------------------------------
 
 pub mod change_parameter_type_indirectly {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedType1 as ParameterType;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedType2 as ParameterType;
 
     #[rustc_clean(
@@ -295,6 +368,11 @@ pub mod change_parameter_type_indirectly {
         except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
     )]
     #[rustc_clean(cfg = "cfail3")]
+    #[rustc_clean(
+        cfg = "cfail5",
+        except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+    )]
+    #[rustc_clean(cfg = "cfail6")]
     pub fn indirect_parameter_type(p: ParameterType) {}
 }
 
@@ -304,26 +382,30 @@ pub trait ReferencedTrait1 {}
 pub trait ReferencedTrait2 {}
 
 pub mod change_trait_bound_indirectly {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedTrait1 as Trait;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedTrait2 as Trait;
 
     #[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, predicates_of")]
     #[rustc_clean(cfg = "cfail3")]
+    #[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, predicates_of")]
+    #[rustc_clean(cfg = "cfail6")]
     pub fn indirect_trait_bound<T: Trait>(p: T) {}
 }
 
 // Change Trait Bound Indirectly In Where Clause -------------------------------
 
 pub mod change_trait_bound_indirectly_in_where_clause {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedTrait1 as Trait;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedTrait2 as Trait;
 
     #[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, predicates_of")]
     #[rustc_clean(cfg = "cfail3")]
+    #[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, predicates_of")]
+    #[rustc_clean(cfg = "cfail6")]
     pub fn indirect_trait_bound_where<T>(p: T)
     where
         T: Trait,
index ddae9c9f03256473dc1860c578336276f7e9a02c..0c5e73b01077ab593e99d1f1040247691477c936 100644 (file)
@@ -6,27 +6,34 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
-
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
 #![crate_type="rlib"]
 
 // Change condition (if)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_condition(x: bool) -> u32 {
-    if x {
+    if  x {
         return 1
     }
 
     return 0
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_condition(x: bool) -> u32 {
     if !x {
         return 1
@@ -36,7 +43,7 @@ pub fn change_condition(x: bool) -> u32 {
 }
 
 // Change then branch (if)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_then_branch(x: bool) -> u32 {
     if x {
         return 1
@@ -45,9 +52,11 @@ pub fn change_then_branch(x: bool) -> u32 {
     return 0
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_then_branch(x: bool) -> u32 {
     if x {
         return 2
@@ -59,7 +68,7 @@ pub fn change_then_branch(x: bool) -> u32 {
 
 
 // Change else branch (if)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_else_branch(x: bool) -> u32 {
     if x {
         1
@@ -68,9 +77,11 @@ pub fn change_else_branch(x: bool) -> u32 {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_else_branch(x: bool) -> u32 {
     if x {
         1
@@ -82,20 +93,23 @@ pub fn change_else_branch(x: bool) -> u32 {
 
 
 // Add else branch (if)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_else_branch(x: bool) -> u32 {
     let mut ret = 1;
 
     if x {
         ret = 2;
+    /*----*/
     }
 
     ret
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_else_branch(x: bool) -> u32 {
     let mut ret = 1;
 
@@ -110,7 +124,7 @@ pub fn add_else_branch(x: bool) -> u32 {
 
 
 // Change condition (if let)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_condition_if_let(x: Option<u32>) -> u32 {
     if let Some(_x) = x {
         return 1
@@ -119,11 +133,13 @@ pub fn change_condition_if_let(x: Option<u32>) -> u32 {
     0
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_condition_if_let(x: Option<u32>) -> u32 {
-    if let Some(_) = x {
+    if let Some(_ ) = x {
         return 1
     }
 
@@ -133,18 +149,20 @@ pub fn change_condition_if_let(x: Option<u32>) -> u32 {
 
 
 // Change then branch (if let)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_then_branch_if_let(x: Option<u32>) -> u32 {
     if let Some(x) = x {
-        return x
+        return x //-
     }
 
     0
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_then_branch_if_let(x: Option<u32>) -> u32 {
     if let Some(x) = x {
         return x + 1
@@ -156,7 +174,7 @@ pub fn change_then_branch_if_let(x: Option<u32>) -> u32 {
 
 
 // Change else branch (if let)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_else_branch_if_let(x: Option<u32>) -> u32 {
     if let Some(x) = x {
         x
@@ -165,9 +183,11 @@ pub fn change_else_branch_if_let(x: Option<u32>) -> u32 {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_else_branch_if_let(x: Option<u32>) -> u32 {
     if let Some(x) = x {
         x
@@ -179,20 +199,23 @@ pub fn change_else_branch_if_let(x: Option<u32>) -> u32 {
 
 
 // Add else branch (if let)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_else_branch_if_let(x: Option<u32>) -> u32 {
     let mut ret = 1;
 
     if let Some(x) = x {
         ret = x;
+    /*----*/
     }
 
     ret
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_else_branch_if_let(x: Option<u32>) -> u32 {
     let mut ret = 1;
 
index 49ee7a9cac091b2453deb87b33b0c4c99b8c406c..0532f4a0fd65db696327aae877383a683ccd6eb4 100644 (file)
@@ -6,22 +6,30 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
 #![crate_type="rlib"]
 
 // Change simple index
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 fn change_simple_index(slice: &[u32]) -> u32 {
     slice[3]
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 fn change_simple_index(slice: &[u32]) -> u32 {
     slice[4]
 }
@@ -29,14 +37,16 @@ fn change_simple_index(slice: &[u32]) -> u32 {
 
 
 // Change lower bound
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 fn change_lower_bound(slice: &[u32]) -> &[u32] {
     &slice[3..5]
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 fn change_lower_bound(slice: &[u32]) -> &[u32] {
     &slice[2..5]
 }
@@ -44,14 +54,16 @@ fn change_lower_bound(slice: &[u32]) -> &[u32] {
 
 
 // Change upper bound
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 fn change_upper_bound(slice: &[u32]) -> &[u32] {
     &slice[3..5]
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 fn change_upper_bound(slice: &[u32]) -> &[u32] {
     &slice[3..7]
 }
@@ -59,14 +71,16 @@ fn change_upper_bound(slice: &[u32]) -> &[u32] {
 
 
 // Add lower bound
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 fn add_lower_bound(slice: &[u32]) -> &[u32] {
-    &slice[..4]
+    &slice[ ..4]
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 fn add_lower_bound(slice: &[u32]) -> &[u32] {
     &slice[3..4]
 }
@@ -74,14 +88,16 @@ fn add_lower_bound(slice: &[u32]) -> &[u32] {
 
 
 // Add upper bound
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 fn add_upper_bound(slice: &[u32]) -> &[u32] {
-    &slice[3..]
+    &slice[3.. ]
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 fn add_upper_bound(slice: &[u32]) -> &[u32] {
     &slice[3..7]
 }
@@ -89,29 +105,33 @@ fn add_upper_bound(slice: &[u32]) -> &[u32] {
 
 
 // Change mutability
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 fn change_mutability(slice: &mut [u32]) -> u32 {
     (&mut slice[3..5])[0]
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 fn change_mutability(slice: &mut [u32]) -> u32 {
-    (&slice[3..5])[0]
+    (&    slice[3..5])[0]
 }
 
 
 
 // Exclusive to inclusive range
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 fn exclusive_to_inclusive_range(slice: &[u32]) -> &[u32] {
-    &slice[3..7]
+    &slice[3.. 7]
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 fn exclusive_to_inclusive_range(slice: &[u32]) -> &[u32] {
     &slice[3..=7]
 }
index 284a95f1a68b627fff0f3fc14a246e738ed335d4..d711cc20dd70afd78bfac79fabfa79924a741880 100644 (file)
@@ -6,8 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 
 #![allow(warnings)]
 pub struct Foo;
 
 // Change Method Name -----------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Foo {
     pub fn method_name() { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,associated_item_def_ids")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,associated_item_def_ids")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn method_name2() { }
 }
 
 // Change Method Body -----------------------------------------------------------
 //
 // This should affect the method itself, but not the impl.
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Foo {
-    pub fn method_body() { }
+    //--------------------------------------------------------------------------------------
+    //--------------------------
+    //--------------------------------------------------------------------------------------
+    //--------------------------
+    pub fn method_body() {
+        // -----------------------
+    }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
-    #[rustc_clean(
-        cfg="cfail2",
-        except="hir_owner_nodes,optimized_mir,promoted_mir,typeck"
-    )]
+    #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,promoted_mir,typeck")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,promoted_mir,typeck")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn method_body() {
         println!("Hello, world!");
     }
@@ -56,21 +72,40 @@ pub fn method_body() {
 // Change Method Body (inlined) ------------------------------------------------
 //
 // This should affect the method itself, but not the impl.
-#[cfg(cfail1)]
-impl Foo {
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //------------
+    //---------------
+    //------------------------------------------------------------
+    //
+    //--------------------------
+    //------------
+    //---------------
+    //------------------------------------------------------------
+    //
+    //--------------------------
     #[inline]
-    pub fn method_body_inlined() { }
+    pub fn method_body_inlined() {
+        // -----------------------
+    }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     #[rustc_clean(
         cfg="cfail2",
         except="hir_owner_nodes,optimized_mir,promoted_mir,typeck"
     )]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="hir_owner_nodes,optimized_mir,promoted_mir,typeck"
+    )]
+    #[rustc_clean(cfg="cfail6")]
     #[inline]
     pub fn method_body_inlined() {
         println!("Hello, world!");
@@ -79,146 +114,205 @@ pub fn method_body_inlined() {
 
 
 // Change Method Privacy -------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Foo {
     pub fn method_privacy() { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     #[rustc_clean(cfg="cfail2", except="associated_item,hir_owner,hir_owner_nodes")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="associated_item,hir_owner,hir_owner_nodes,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
     fn method_privacy() { }
 }
 
 // Change Method Selfness -----------------------------------------------------------
-#[cfg(cfail1)]
-impl Foo {
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //------------
+    //---------------
+    //---------------------------------------------------------------------------------------------
+    //
+    //--------------------------
+    //------------
+    //---------------
+    //---------------------------------------------------------------------------------------------
+    //
+    //--------------------------
     pub fn method_selfness() { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     #[rustc_clean(
         cfg="cfail2",
         except="hir_owner,hir_owner_nodes,fn_sig,generics_of,typeck,associated_item,optimized_mir",
     )]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="hir_owner,hir_owner_nodes,fn_sig,generics_of,typeck,associated_item,optimized_mir",
+    )]
+    #[rustc_clean(cfg="cfail6")]
     pub fn method_selfness(&self) { }
 }
 
 // Change Method Selfmutness ---------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Foo {
-    pub fn method_selfmutness(&self) { }
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    pub fn method_selfmutness(&    self) { }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
-    #[rustc_clean(
-        cfg="cfail2",
-        except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir"
-    )]
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn method_selfmutness(&mut self) { }
 }
 
 
 
 // Add Method To Impl ----------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Foo {
     pub fn add_method_to_impl1(&self) { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,associated_item_def_ids")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,associated_item_def_ids")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     #[rustc_clean(cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn add_method_to_impl1(&self) { }
 
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn add_method_to_impl2(&self) { }
 }
 
 
 
 // Add Method Parameter --------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Foo {
-    pub fn add_method_parameter(&self) { }
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    pub fn add_method_parameter(&self        ) { }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
-    #[rustc_clean(
-        cfg="cfail2",
-        except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir"
-    )]
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn add_method_parameter(&self, _: i32) { }
 }
 
 
 
 // Change Method Parameter Name ------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Foo {
+    //------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------
+    //--------------------------
     pub fn change_method_parameter_name(&self, a: i64) { }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn change_method_parameter_name(&self, b: i64) { }
 }
 
 
 
 // Change Method Return Type ---------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Foo {
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------------------------------
+    //--------------------------
     pub fn change_method_return_type(&self) -> u16 { 0 }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
-    #[rustc_clean(
-        cfg="cfail2",
-        except="hir_owner,hir_owner_nodes,fn_sig,optimized_mir,typeck")]
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig,optimized_mir,typeck")]
     #[rustc_clean(cfg="cfail3")]
-    pub fn change_method_return_type(&self) -> u8 { 0 }
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,fn_sig,optimized_mir,typeck")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn change_method_return_type(&self) -> u32 { 0 }
 }
 
 
 
 // Make Method #[inline] -------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Foo {
+    //--------------------------
+    //--------------------------
+    //--------------------------
+    //--------------------------
+    //-------
     pub fn make_method_inline(&self) -> u8 { 0 }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     #[rustc_clean(cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     #[inline]
     pub fn make_method_inline(&self) -> u8 { 0 }
 }
@@ -226,85 +320,129 @@ pub fn make_method_inline(&self) -> u8 { 0 }
 
 
 //  Change order of parameters -------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Foo {
+    //------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------
+    //--------------------------
     pub fn change_method_parameter_order(&self, a: i64, b: i64) { }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn change_method_parameter_order(&self, b: i64, a: i64) { }
 }
 
 
 
 // Make method unsafe ----------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Foo {
-    pub fn make_method_unsafe(&self) { }
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    pub        fn make_method_unsafe(&self) { }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
-    #[rustc_clean(
-        cfg="cfail2",
-        except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir"
-    )]
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
     pub unsafe fn make_method_unsafe(&self) { }
 }
 
 
 
 // Make method extern ----------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Foo {
-    pub fn make_method_extern(&self) { }
+    //----------------------------------------------------------------------------
+    //--------------------------
+    //----------------------------------------------------------------------------
+    //--------------------------
+    pub            fn make_method_extern(&self) { }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig,typeck")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,fn_sig,typeck")]
+    #[rustc_clean(cfg="cfail6")]
     pub extern "C" fn make_method_extern(&self) { }
 }
 
 
 
 // Change method calling convention --------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Foo {
-    pub extern "C" fn change_method_calling_convention(&self) { }
+    //----------------------------------------------------------------------------
+    //--------------------------
+    //----------------------------------------------------------------------------
+    //--------------------------
+    pub extern "C"      fn change_method_calling_convention(&self) { }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig,typeck")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,fn_sig,typeck")]
+    #[rustc_clean(cfg="cfail6")]
     pub extern "system" fn change_method_calling_convention(&self) { }
 }
 
 
 
 // Add Lifetime Parameter to Method --------------------------------------------
-#[cfg(cfail1)]
-impl Foo {
-    pub fn add_lifetime_parameter_to_method(&self) { }
-}
-
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    // -----------------------------------------------------
+    // ---------------------------------------------------------
+    // ----------------------------------------------------------
+    // -------------------------------------------------------
+    // -------------------------------------------------------
+    // --------------------------------------------------------
+    // ----------------------------------------------------------
+    // -----------------------------------------------------------
+    // ----------------------------------------------------------
+    // --------------------------------------------------------------------
+    // -------------------------
+    // --------------------------------------------------------------------------------
+    // -------------------------
+    pub fn add_lifetime_parameter_to_method    (&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     // Warning: Note that `typeck` are coming up clean here.
     // The addition or removal of lifetime parameters that don't
@@ -317,20 +455,43 @@ impl Foo {
     // `typeck` appear dirty, that might be the cause. -nmatsakis
     #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,fn_sig,generics_of")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn add_lifetime_parameter_to_method<'a>(&self) { }
 }
 
 
 
 // Add Type Parameter To Method ------------------------------------------------
-#[cfg(cfail1)]
-impl Foo {
-    pub fn add_type_parameter_to_method(&self) { }
-}
-
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    // -----------------------------------------------------
+    // ---------------------------------------------------------------
+    // -------------------------------------------------------------
+    // -----------------------------------------------------
+    // -------------------------------------------------------------
+    // ---------------------------------------------------
+    // ------------------------------------------------------------
+    // ------------------------------------------------------
+    // -------------------------------------------------
+    // -----------
+    // --------------
+    // ----------------------------------------------------------------------
+    //
+    // -------------------------
+    // -----------
+    // --------------
+    // ----------------------------------------------------------------------
+    //
+    // -------------------------
+    pub fn add_type_parameter_to_method   (&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     // Warning: Note that `typeck` are coming up clean here.
     // The addition or removal of type parameters that don't appear in
@@ -346,40 +507,83 @@ impl Foo {
         except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of",
     )]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of",
+    )]
+    #[rustc_clean(cfg="cfail6")]
     pub fn add_type_parameter_to_method<T>(&self) { }
 }
 
 
 
 // Add Lifetime Bound to Lifetime Parameter of Method --------------------------
-#[cfg(cfail1)]
-impl Foo {
-    pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b>(&self) { }
-}
-
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //------------
+    //---------------
+    //-----------------------------------------------------------------------------
+    //
+    //--------------------------
+    //------------
+    //---------------
+    //-----------------------------------------------------------------------------
+    //
+    //--------------------------
+    pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b    >(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     #[rustc_clean(
         cfg="cfail2",
         except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of,fn_sig"
     )]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of,fn_sig"
+    )]
+    #[rustc_clean(cfg="cfail6")]
     pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b: 'a>(&self) { }
 }
 
 
 
 // Add Lifetime Bound to Type Parameter of Method ------------------------------
-#[cfg(cfail1)]
-impl Foo {
-    pub fn add_lifetime_bound_to_type_param_of_method<'a, T>(&self) { }
-}
-
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    // -----------------------------------------------------
+    // ----------------------------------------------------------
+    // -------------------------------------------------------------
+    // -------------------------------------------------
+    // -------------------------------------------------------------
+    // ---------------------------------------------------
+    // ------------------------------------------------------------
+    // ------------------------------------------------------
+    // -------------------------------------------------
+    // -----------
+    // --------------
+    // ----------------------------------------------------------------------------
+    //
+    // -------------------------
+    // -----------
+    // --------------
+    // ----------------------------------------------------------------------------
+    //
+    // -------------------------
+    pub fn add_lifetime_bound_to_type_param_of_method<'a, T    >(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     // Warning: Note that `typeck` are coming up clean here.
     // The addition or removal of bounds that don't appear in the
@@ -390,23 +594,45 @@ impl Foo {
     // generics before the body, then the `HirId` for things in the
     // body will be affected. So if you start to see `typeck`
     // appear dirty, that might be the cause. -nmatsakis
-    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,\
-                                        type_of,fn_sig")]
+    #[rustc_clean(
+        cfg="cfail2",
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of,fn_sig"
+    )]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of,fn_sig"
+    )]
+    #[rustc_clean(cfg="cfail6")]
     pub fn add_lifetime_bound_to_type_param_of_method<'a, T: 'a>(&self) { }
 }
 
 
 
 // Add Trait Bound to Type Parameter of Method ------------------------------
-#[cfg(cfail1)]
-impl Foo {
-    pub fn add_trait_bound_to_type_param_of_method<T>(&self) { }
-}
-
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    // -----------------------------------------------------
+    // ----------------------------------------------------------
+    // -------------------------------------------------------------
+    // -------------------------------------------------
+    // -------------------------------------------------------------
+    // ---------------------------------------------------
+    // ------------------------------------------------------------
+    // ------------------------------------------------------
+    // -------------------------------------------------
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    pub fn add_trait_bound_to_type_param_of_method<T       >(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     // Warning: Note that `typeck` are coming up clean here.
     // The addition or removal of bounds that don't appear in the
@@ -419,23 +645,34 @@ impl Foo {
     // appear dirty, that might be the cause. -nmatsakis
     #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn add_trait_bound_to_type_param_of_method<T: Clone>(&self) { }
 }
 
 
 
 // Add #[no_mangle] to Method --------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Foo {
+    //--------------------------
+    //--------------------------
+    //--------------------------
+    //--------------------------
+    //----------
     pub fn add_no_mangle_to_method(&self) { }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl Foo {
     #[rustc_clean(cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     #[no_mangle]
     pub fn add_no_mangle_to_method(&self) { }
 }
@@ -445,71 +682,90 @@ pub fn add_no_mangle_to_method(&self) { }
 struct Bar<T>(T);
 
 // Add Type Parameter To Impl --------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Bar<u32> {
     pub fn add_type_parameter_to_impl(&self) { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of")]
+#[rustc_clean(cfg="cfail6")]
 impl<T> Bar<T> {
     #[rustc_clean(
         cfg="cfail2",
         except="generics_of,fn_sig,typeck,type_of,optimized_mir"
     )]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="generics_of,fn_sig,typeck,type_of,optimized_mir"
+    )]
+    #[rustc_clean(cfg="cfail6")]
     pub fn add_type_parameter_to_impl(&self) { }
 }
 
 
 
 // Change Self Type of Impl ----------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl Bar<u32> {
     pub fn change_impl_self_type(&self) { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner")]
+#[rustc_clean(cfg="cfail6")]
 impl Bar<u64> {
     #[rustc_clean(cfg="cfail2", except="fn_sig,optimized_mir,typeck")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="fn_sig,optimized_mir,typeck")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn change_impl_self_type(&self) { }
 }
 
 
 
 // Add Lifetime Bound to Impl --------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl<T> Bar<T> {
     pub fn add_lifetime_bound_to_impl_parameter(&self) { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl<T: 'static> Bar<T> {
     #[rustc_clean(cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn add_lifetime_bound_to_impl_parameter(&self) { }
 }
 
 
 
 // Add Trait Bound to Impl Parameter -------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl<T> Bar<T> {
     pub fn add_trait_bound_to_impl_parameter(&self) { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 impl<T: Clone> Bar<T> {
     #[rustc_clean(cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     pub fn add_trait_bound_to_impl_parameter(&self) { }
 }
 
@@ -518,12 +774,12 @@ pub fn add_trait_bound_to_impl_parameter(&self) { }
 pub fn instantiation_root() {
     Foo::method_privacy();
 
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     {
         Bar(0u32).change_impl_self_type();
     }
 
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     {
         Bar(0u64).change_impl_self_type();
     }
index 7fd9975bc22a93366d1840596c2977a598ea060c..a5d53258a7bd007fba5a131e4cc106cb31124395 100644 (file)
@@ -6,8 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
@@ -17,7 +23,7 @@
 
 
 // Change template
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_template(a: i32) -> i32 {
     let c: i32;
@@ -32,9 +38,11 @@ pub fn change_template(a: i32) -> i32 {
     c
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_template(a: i32) -> i32 {
     let c: i32;
@@ -52,7 +60,7 @@ pub fn change_template(a: i32) -> i32 {
 
 
 // Change output
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_output(a: i32) -> i32 {
     let mut _out1: i32 = 0;
@@ -68,9 +76,11 @@ pub fn change_output(a: i32) -> i32 {
     _out1
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_output(a: i32) -> i32 {
     let mut _out1: i32 = 0;
@@ -89,7 +99,7 @@ pub fn change_output(a: i32) -> i32 {
 
 
 // Change input
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_input(_a: i32, _b: i32) -> i32 {
     let _out;
@@ -104,9 +114,11 @@ pub fn change_input(_a: i32, _b: i32) -> i32 {
     _out
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_input(_a: i32, _b: i32) -> i32 {
     let _out;
@@ -124,7 +136,7 @@ pub fn change_input(_a: i32, _b: i32) -> i32 {
 
 
 // Change input constraint
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_input_constraint(_a: i32, _b: i32) -> i32 {
     let _out;
@@ -139,9 +151,11 @@ pub fn change_input_constraint(_a: i32, _b: i32) -> i32 {
     _out
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_input_constraint(_a: i32, _b: i32) -> i32 {
     let _out;
@@ -159,7 +173,7 @@ pub fn change_input_constraint(_a: i32, _b: i32) -> i32 {
 
 
 // Change clobber
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_clobber(_a: i32) -> i32 {
     let _out;
@@ -167,16 +181,18 @@ pub fn change_clobber(_a: i32) -> i32 {
         llvm_asm!("add 1, $0"
                   : "=r"(_out)
                   : "0"(_a)
-                  :
+                  :/*--*/
                   :
                   );
     }
     _out
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_clobber(_a: i32) -> i32 {
     let _out;
@@ -194,7 +210,7 @@ pub fn change_clobber(_a: i32) -> i32 {
 
 
 // Change options
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_options(_a: i32) -> i32 {
     let _out;
@@ -203,15 +219,17 @@ pub fn change_options(_a: i32) -> i32 {
                   : "=r"(_out)
                   : "0"(_a)
                   :
-                  :
+                  :/*-------*/
                   );
     }
     _out
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_options(_a: i32) -> i32 {
     let _out;
index 918e72582d6978289c736000f5d769463f933372..a9f90ca9fed81ba359acddb381884fc9a473bfec 100644 (file)
@@ -6,24 +6,30 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
-
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
 #![crate_type="rlib"]
 
 // Change Name -----------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_name() {
     let _x = 2u64;
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_name() {
     let _y = 2u64;
 }
@@ -31,15 +37,16 @@ pub fn change_name() {
 
 
 // Add Type --------------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_type() {
-    let _x = 2u32;
+    let _x      = 2u32;
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,typeck")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_type() {
     let _x: u32 = 2u32;
 }
@@ -47,31 +54,33 @@ pub fn add_type() {
 
 
 // Change Type -----------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_type() {
     let _x: u64 = 2;
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,typeck,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_type() {
-    let _x: u8 = 2;
+    let _x: u8  = 2;
 }
 
 
 
 // Change Mutability of Reference Type -----------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_mutability_of_reference_type() {
-    let _x: &u64;
+    let _x: &    u64;
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,typeck,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_mutability_of_reference_type() {
     let _x: &mut u64;
 }
@@ -79,31 +88,33 @@ pub fn change_mutability_of_reference_type() {
 
 
 // Change Mutability of Slot ---------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_mutability_of_slot() {
     let mut _x: u64 = 0;
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,typeck,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_mutability_of_slot() {
-    let _x: u64 = 0;
+    let     _x: u64 = 0;
 }
 
 
 
 // Change Simple Binding to Pattern --------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_simple_binding_to_pattern() {
-    let _x = (0u8, 'x');
+    let  _x      = (0u8, 'x');
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,typeck,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_simple_binding_to_pattern() {
     let (_a, _b) = (0u8, 'x');
 }
@@ -111,15 +122,16 @@ pub fn change_simple_binding_to_pattern() {
 
 
 // Change Name in Pattern ------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_name_in_pattern() {
     let (_a, _b) = (1u8, 'y');
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_name_in_pattern() {
     let (_a, _c) = (1u8, 'y');
 }
@@ -127,15 +139,16 @@ pub fn change_name_in_pattern() {
 
 
 // Add `ref` in Pattern --------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_ref_in_pattern() {
-    let (_a, _b) = (1u8, 'y');
+    let (    _a, _b) = (1u8, 'y');
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,typeck,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_ref_in_pattern() {
     let (ref _a, _b) = (1u8, 'y');
 }
@@ -143,15 +156,16 @@ pub fn add_ref_in_pattern() {
 
 
 // Add `&` in Pattern ----------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_amp_in_pattern() {
-    let (_a, _b) = (&1u8, 'y');
+    let ( _a, _b) = (&1u8, 'y');
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,typeck,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_amp_in_pattern() {
     let (&_a, _b) = (&1u8, 'y');
 }
@@ -159,15 +173,16 @@ pub fn add_amp_in_pattern() {
 
 
 // Change Mutability of Binding in Pattern -------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_mutability_of_binding_in_pattern() {
-    let (_a, _b) = (99u8, 'q');
+    let (    _a, _b) = (99u8, 'q');
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,typeck,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_mutability_of_binding_in_pattern() {
     let (mut _a, _b) = (99u8, 'q');
 }
@@ -175,15 +190,16 @@ pub fn change_mutability_of_binding_in_pattern() {
 
 
 // Add Initializer -------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_initializer() {
-    let _x: i16;
+    let _x: i16       ;
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,typeck,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_initializer() {
     let _x: i16 = 3i16;
 }
@@ -191,15 +207,16 @@ pub fn add_initializer() {
 
 
 // Change Initializer ----------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_initializer() {
     let _x = 4u16;
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_initializer() {
     let _x = 5u16;
 }
index 178def016a25f0ed607100204add86289fa9f475..6fef31f5b32104ed758b7193ca62c759ec18c9c4 100644 (file)
@@ -6,8 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
@@ -15,7 +21,7 @@
 
 
 // Change loop body
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_loop_body() {
     let mut _x = 0;
     loop {
@@ -24,9 +30,11 @@ pub fn change_loop_body() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_loop_body() {
     let mut _x = 0;
     loop {
@@ -38,17 +46,20 @@ pub fn change_loop_body() {
 
 
 // Add break
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_break() {
     let mut _x = 0;
     loop {
         _x = 1;
+        //----
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_break() {
     let mut _x = 0;
     loop {
@@ -60,18 +71,20 @@ pub fn add_break() {
 
 
 // Add loop label
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_loop_label() {
     let mut _x = 0;
-    loop {
+    /*---*/ loop {
         _x = 1;
         break;
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_loop_label() {
     let mut _x = 0;
     'label: loop {
@@ -83,18 +96,20 @@ pub fn add_loop_label() {
 
 
 // Add loop label to break
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_loop_label_to_break() {
     let mut _x = 0;
     'label: loop {
         _x = 1;
-        break;
+        break       ;
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_loop_label_to_break() {
     let mut _x = 0;
     'label: loop {
@@ -106,7 +121,7 @@ pub fn add_loop_label_to_break() {
 
 
 // Change break label
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_break_label() {
     let mut _x = 0;
     'outer: loop {
@@ -117,9 +132,11 @@ pub fn change_break_label() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_break_label() {
     let mut _x = 0;
     'outer: loop {
@@ -133,18 +150,20 @@ pub fn change_break_label() {
 
 
 // Add loop label to continue
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_loop_label_to_continue() {
     let mut _x = 0;
     'label: loop {
         _x = 1;
-        continue;
+        continue       ;
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_loop_label_to_continue() {
     let mut _x = 0;
     'label: loop {
@@ -156,7 +175,7 @@ pub fn add_loop_label_to_continue() {
 
 
 // Change continue label
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_continue_label() {
     let mut _x = 0;
     'outer: loop {
@@ -167,9 +186,11 @@ pub fn change_continue_label() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, typeck, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_continue_label() {
     let mut _x = 0;
     'outer: loop {
@@ -183,7 +204,7 @@ pub fn change_continue_label() {
 
 
 // Change continue to break
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_continue_to_break() {
     let mut _x = 0;
     loop {
@@ -192,13 +213,15 @@ pub fn change_continue_to_break() {
     }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, typeck, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, typeck, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_continue_to_break() {
     let mut _x = 0;
     loop {
         _x = 1;
-        break;
+        break   ;
     }
 }
index 969f930f57bdfb2f675b978fc199befd240a69fa..314461b5909f7e36292c313b7ed9c001b671d0db 100644 (file)
@@ -6,28 +6,35 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
-
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
 #![crate_type="rlib"]
 
 // Add Arm ---------------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_arm(x: u32) -> u32 {
     match x {
         0 => 0,
         1 => 1,
+        /*---*/
         _ => 100,
     }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir,typeck")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_arm(x: u32) -> u32 {
     match x {
         0 => 0,
@@ -40,7 +47,7 @@ pub fn add_arm(x: u32) -> u32 {
 
 
 // Change Order Of Arms --------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_order_of_arms(x: u32) -> u32 {
     match x {
         0 => 0,
@@ -49,10 +56,11 @@ pub fn change_order_of_arms(x: u32) -> u32 {
     }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_order_of_arms(x: u32) -> u32 {
     match x {
         1 => 1,
@@ -64,19 +72,20 @@ pub fn change_order_of_arms(x: u32) -> u32 {
 
 
 // Add Guard Clause ------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_guard_clause(x: u32, y: bool) -> u32 {
     match x {
         0 => 0,
-        1 => 1,
+        1      => 1,
         _ => 100,
     }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir,typeck")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_guard_clause(x: u32, y: bool) -> u32 {
     match x {
         0 => 0,
@@ -88,19 +97,20 @@ pub fn add_guard_clause(x: u32, y: bool) -> u32 {
 
 
 // Change Guard Clause ------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_guard_clause(x: u32, y: bool) -> u32 {
     match x {
         0 => 0,
-        1 if y => 1,
+        1 if  y => 1,
         _ => 100,
     }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir,typeck")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_guard_clause(x: u32, y: bool) -> u32 {
     match x {
         0 => 0,
@@ -112,19 +122,20 @@ pub fn change_guard_clause(x: u32, y: bool) -> u32 {
 
 
 // Add @-Binding ---------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_at_binding(x: u32) -> u32 {
     match x {
         0 => 0,
         1 => 1,
-        _ => x,
+            _ => x,
     }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir,typeck")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_at_binding(x: u32) -> u32 {
     match x {
         0 => 0,
@@ -136,7 +147,7 @@ pub fn add_at_binding(x: u32) -> u32 {
 
 
 // Change Name of @-Binding ----------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_name_of_at_binding(x: u32) -> u32 {
     match x {
         0 => 0,
@@ -145,10 +156,11 @@ pub fn change_name_of_at_binding(x: u32) -> u32 {
     }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_name_of_at_binding(x: u32) -> u32 {
     match x {
         0 => 0,
@@ -160,18 +172,19 @@ pub fn change_name_of_at_binding(x: u32) -> u32 {
 
 
 // Change Simple Binding To Pattern --------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_simple_name_to_pattern(x: u32) -> u32 {
     match (x, x & 1) {
         (0, 0) => 0,
-        a => 1,
+         a     => 1,
     }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir,typeck")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_simple_name_to_pattern(x: u32) -> u32 {
     match (x, x & 1) {
         (0, 0) => 0,
@@ -182,7 +195,7 @@ pub fn change_simple_name_to_pattern(x: u32) -> u32 {
 
 
 // Change Name In Pattern ------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_name_in_pattern(x: u32) -> u32 {
     match (x, x & 1) {
         (a, 0) => 0,
@@ -191,10 +204,11 @@ pub fn change_name_in_pattern(x: u32) -> u32 {
     }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_name_in_pattern(x: u32) -> u32 {
     match (x, x & 1) {
         (b, 0) => 0,
@@ -206,18 +220,19 @@ pub fn change_name_in_pattern(x: u32) -> u32 {
 
 
 // Change Mutability Of Binding In Pattern -------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
     match (x, x & 1) {
-        (a, 0) => 0,
+        (    a, 0) => 0,
         _ => 1,
     }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir,typeck")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
     match (x, x & 1) {
         (mut a, 0) => 0,
@@ -228,18 +243,19 @@ pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
 
 
 // Add `ref` To Binding In Pattern -------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
     match (x, x & 1) {
-        (a, 0) => 0,
+        (    a, 0) => 0,
         _ => 1,
     }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir,typeck")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
     match (x, x & 1) {
         (ref a, 0) => 0,
@@ -250,18 +266,19 @@ pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
 
 
 // Add `&` To Binding In Pattern -------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
     match (&x, x & 1) {
-        (a, 0) => 0,
+        ( a, 0) => 0,
         _ => 1,
     }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-except="hir_owner_nodes,optimized_mir,typeck")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
     match (&x, x & 1) {
         (&a, 0) => 0,
@@ -272,7 +289,7 @@ pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
 
 
 // Change RHS Of Arm -----------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_rhs_of_arm(x: u32) -> u32 {
     match x {
         0 => 0,
@@ -281,10 +298,11 @@ pub fn change_rhs_of_arm(x: u32) -> u32 {
     }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_rhs_of_arm(x: u32) -> u32 {
     match x {
         0 => 0,
@@ -296,19 +314,20 @@ pub fn change_rhs_of_arm(x: u32) -> u32 {
 
 
 // Add Alternative To Arm ------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_alternative_to_arm(x: u32) -> u32 {
     match x {
-        0 => 0,
+        0     => 0,
         1 => 1,
         _ => 2,
     }
 }
 
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2",
-    except="hir_owner_nodes,optimized_mir,typeck")]
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_alternative_to_arm(x: u32) -> u32 {
     match x {
         0 | 7 => 0,
index 6f4089c60fe23669209d847ff5ec1f121d8d22a9..2b2658b2f5f07b8f2107deb8535ab5c40fb24541 100644 (file)
@@ -6,8 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
 
 
 // Change static visibility
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 static STATIC_VISIBILITY: u8 = 0;
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 pub static STATIC_VISIBILITY: u8 = 0;
 
 
 // Change static mutability
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 static STATIC_MUTABILITY: u8 = 0;
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 static mut STATIC_MUTABILITY: u8 = 0;
 
 
 // Add linkage attribute
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 static STATIC_LINKAGE: u8 = 0;
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 #[linkage="weak_odr"]
 static STATIC_LINKAGE: u8 = 0;
 
 
 // Add no_mangle attribute
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 static STATIC_NO_MANGLE: u8 = 0;
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 #[no_mangle]
 static STATIC_NO_MANGLE: u8 = 0;
 
 
 // Add thread_local attribute
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 static STATIC_THREAD_LOCAL: u8 = 0;
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 #[thread_local]
 static STATIC_THREAD_LOCAL: u8 = 0;
 
 
 // Change type from i16 to u64
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 static STATIC_CHANGE_TYPE_1: i16 = 0;
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 static STATIC_CHANGE_TYPE_1: u64 = 0;
 
 
 // Change type from Option<i8> to Option<u16>
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 static STATIC_CHANGE_TYPE_2: Option<i8> = None;
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
 static STATIC_CHANGE_TYPE_2: Option<u16> = None;
 
 
 // Change value between simple literals
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 static STATIC_CHANGE_VALUE_1: i16 = {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     { 1 }
 
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     { 2 }
 };
 
 // Change value between expressions
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 static STATIC_CHANGE_VALUE_2: i16 = {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     { 1 + 1 }
 
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     { 1 + 2 }
 };
 
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 static STATIC_CHANGE_VALUE_3: i16 = {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     { 2 + 3 }
 
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     { 2 * 3 }
 };
 
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 static STATIC_CHANGE_VALUE_4: i16 = {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     { 1 + 2 * 3 }
 
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     { 1 + 2 * 4 }
 };
 
 struct ReferencedType2;
 
 mod static_change_type_indirectly {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedType1 as Type;
 
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedType2 as Type;
 
     #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+    #[rustc_clean(cfg="cfail6")]
     static STATIC_CHANGE_TYPE_INDIRECTLY_1: Type = Type;
 
     #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+    #[rustc_clean(cfg="cfail6")]
     static STATIC_CHANGE_TYPE_INDIRECTLY_2: Option<Type> = None;
 }
index edec03d4f057e01556e4fad11b11db31a211e56a..6a62620463040da7c3de1cda89fe6776afa423a8 100644 (file)
@@ -6,8 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
@@ -21,7 +27,7 @@ pub struct RegularStruct {
 }
 
 // Change field value (regular struct)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_field_value_regular_struct() -> RegularStruct {
     RegularStruct {
         x: 0,
@@ -30,9 +36,11 @@ pub fn change_field_value_regular_struct() -> RegularStruct {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_field_value_regular_struct() -> RegularStruct {
     RegularStruct {
         x: 0,
@@ -44,7 +52,7 @@ pub fn change_field_value_regular_struct() -> RegularStruct {
 
 
 // Change field order (regular struct)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_field_order_regular_struct() -> RegularStruct {
     RegularStruct {
         x: 3,
@@ -53,9 +61,11 @@ pub fn change_field_order_regular_struct() -> RegularStruct {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_field_order_regular_struct() -> RegularStruct {
     RegularStruct {
         y: 4,
@@ -67,7 +77,7 @@ pub fn change_field_order_regular_struct() -> RegularStruct {
 
 
 // Add field (regular struct)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_field_regular_struct() -> RegularStruct {
     let struct1 = RegularStruct {
         x: 3,
@@ -77,13 +87,16 @@ pub fn add_field_regular_struct() -> RegularStruct {
 
     RegularStruct {
         x: 7,
+        // --
         .. struct1
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_field_regular_struct() -> RegularStruct {
     let struct1 = RegularStruct {
         x: 3,
@@ -101,7 +114,7 @@ pub fn add_field_regular_struct() -> RegularStruct {
 
 
 // Change field label (regular struct)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_field_label_regular_struct() -> RegularStruct {
     let struct1 = RegularStruct {
         x: 3,
@@ -116,9 +129,11 @@ pub fn change_field_label_regular_struct() -> RegularStruct {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_field_label_regular_struct() -> RegularStruct {
     let struct1 = RegularStruct {
         x: 3,
@@ -142,18 +157,20 @@ pub struct RegularStruct2 {
 }
 
 // Change constructor path (regular struct)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_constructor_path_regular_struct() {
-    let _ = RegularStruct {
+    let _ = RegularStruct  {
         x: 0,
         y: 1,
         z: 2,
     };
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_constructor_path_regular_struct() {
     let _ = RegularStruct2 {
         x: 0,
@@ -166,9 +183,9 @@ pub fn change_constructor_path_regular_struct() {
 
 // Change constructor path indirectly (regular struct)
 pub mod change_constructor_path_indirectly_regular_struct {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::RegularStruct as Struct;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::RegularStruct2 as Struct;
 
     #[rustc_clean(
@@ -176,6 +193,11 @@ pub mod change_constructor_path_indirectly_regular_struct {
         except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,typeck"
     )]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,typeck"
+    )]
+    #[rustc_clean(cfg="cfail6")]
     pub fn function() -> Struct {
         Struct {
             x: 0,
@@ -190,14 +212,16 @@ pub fn function() -> Struct {
 pub struct TupleStruct(i32, i64, i16);
 
 // Change field value (tuple struct)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_field_value_tuple_struct() -> TupleStruct {
     TupleStruct(0, 1, 2)
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_field_value_tuple_struct() -> TupleStruct {
     TupleStruct(0, 1, 3)
 }
@@ -207,14 +231,16 @@ pub fn change_field_value_tuple_struct() -> TupleStruct {
 pub struct TupleStruct2(u16, u16, u16);
 
 // Change constructor path (tuple struct)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_constructor_path_tuple_struct() {
-    let _ = TupleStruct(0, 1, 2);
+    let _ = TupleStruct (0, 1, 2);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_constructor_path_tuple_struct() {
     let _ = TupleStruct2(0, 1, 2);
 }
@@ -223,11 +249,16 @@ pub fn change_constructor_path_tuple_struct() {
 
 // Change constructor path indirectly (tuple struct)
 pub mod change_constructor_path_indirectly_tuple_struct {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::TupleStruct as Struct;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::TupleStruct2 as Struct;
 
+    #[rustc_clean(
+        cfg="cfail5",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,typeck"
+    )]
+    #[rustc_clean(cfg="cfail6")]
     #[rustc_clean(
         cfg="cfail2",
         except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,typeck"
index 0ce5aeaaf5028b43c79a28e48a245f7f8aec408c..b5d8a3ab34103d0d6380ae91cb46e2136a70ef65 100644 (file)
 // the same between rev2 and rev3.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
-
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
 #![crate_type="rlib"]
 
 // Layout ----------------------------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub struct LayoutPacked;
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="type_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="type_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 #[repr(packed)]
 pub struct LayoutPacked;
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct LayoutC;
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="type_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="type_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 #[repr(C)]
 struct LayoutC;
 
 
 // Tuple Struct Change Field Type ----------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct TupleStructFieldType(i32);
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 // Note that changing the type of a field does not change the type of the struct or enum, but
 // adding/removing fields or changing a fields name or visibility does.
 struct TupleStructFieldType(
@@ -56,12 +67,14 @@ struct TupleStructFieldType(
 
 // Tuple Struct Add Field ------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct TupleStructAddField(i32);
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 struct TupleStructAddField(
     i32,
     u32
@@ -70,23 +83,27 @@ struct TupleStructAddField(
 
 // Tuple Struct Field Visibility -----------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct TupleStructFieldVisibility(char);
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 struct TupleStructFieldVisibility(pub char);
 
 
 // Record Struct Field Type ----------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct RecordStructFieldType { x: f32 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 // Note that changing the type of a field does not change the type of the struct or enum, but
 // adding/removing fields or changing a fields name or visibility does.
 struct RecordStructFieldType {
@@ -96,23 +113,27 @@ struct RecordStructFieldType {
 
 // Record Struct Field Name ----------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct RecordStructFieldName { x: f32 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 struct RecordStructFieldName { y: f32 }
 
 
 // Record Struct Add Field -----------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct RecordStructAddField { x: f32 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 struct RecordStructAddField {
     x: f32,
     y: () }
@@ -120,12 +141,14 @@ struct RecordStructAddField {
 
 // Record Struct Field Visibility ----------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct RecordStructFieldVisibility { x: f32 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 struct RecordStructFieldVisibility {
     pub x: f32
 }
@@ -133,34 +156,40 @@ struct RecordStructFieldVisibility {
 
 // Add Lifetime Parameter ------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct AddLifetimeParameter<'a>(&'a f32, &'a f64);
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,type_of,generics_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of,generics_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 struct AddLifetimeParameter<'a, 'b>(&'a f32, &'b f64);
 
 
 // Add Lifetime Parameter Bound ------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct AddLifetimeParameterBound<'a, 'b>(&'a f32, &'b f64);
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 struct AddLifetimeParameterBound<'a, 'b: 'a>(
     &'a f32,
     &'b f64
 );
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct AddLifetimeParameterBoundWhereClause<'a, 'b>(&'a f32, &'b f64);
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 struct AddLifetimeParameterBoundWhereClause<'a, 'b>(
     &'a f32,
     &'b f64)
@@ -169,12 +198,14 @@ struct AddLifetimeParameterBoundWhereClause<'a, 'b>(
 
 // Add Type Parameter ----------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct AddTypeParameter<T1>(T1, T1);
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,type_of,generics_of,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 struct AddTypeParameter<T1, T2>(
      // The field contains the parent's Generics, so it's dirty even though its
      // type hasn't changed.
@@ -185,23 +216,27 @@ struct AddTypeParameter<T1, T2>(
 
 // Add Type Parameter Bound ----------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct AddTypeParameterBound<T>(T);
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 struct AddTypeParameterBound<T: Send>(
     T
 );
 
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct AddTypeParameterBoundWhereClause<T>(T);
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 struct AddTypeParameterBoundWhereClause<T>(
     T
 ) where T: Sync;
@@ -214,17 +249,21 @@ struct AddTypeParameterBoundWhereClause<T>(
 // Note: there is no #[cfg(...)], so this is ALWAYS compiled
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub struct EmptyStruct;
 
 
 // Visibility ------------------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 struct Visibility;
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub struct Visibility;
 
 struct ReferencedType1;
@@ -232,13 +271,15 @@ struct AddTypeParameterBoundWhereClause<T>(
 
 // Tuple Struct Change Field Type Indirectly -----------------------------------
 mod tuple_struct_change_field_type_indirectly {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedType1 as FieldType;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedType2 as FieldType;
 
     #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     struct TupleStruct(
         FieldType
     );
@@ -247,13 +288,15 @@ struct TupleStruct(
 
 // Record Struct Change Field Type Indirectly -----------------------------------
 mod record_struct_change_field_type_indirectly {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedType1 as FieldType;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedType2 as FieldType;
 
     #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     struct RecordStruct {
         _x: FieldType
     }
@@ -267,24 +310,28 @@ trait ReferencedTrait2 {}
 
 // Change Trait Bound Indirectly -----------------------------------------------
 mod change_trait_bound_indirectly {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedTrait1 as Trait;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedTrait2 as Trait;
 
     #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     struct Struct<T: Trait>(T);
 }
 
 // Change Trait Bound Indirectly In Where Clause -------------------------------
 mod change_trait_bound_indirectly_in_where_clause {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedTrait1 as Trait;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedTrait2 as Trait;
 
     #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     struct Struct<T>(T) where T : Trait;
 }
index a604ca5ca82d71c5e25c3a2871d6389cb07c3bac..9cbd110d68aab76aafc5a413534330f5c15f2475 100644 (file)
 // the same between rev2 and rev3.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
 
 
 // Change trait visibility
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitVisibility { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub trait TraitVisibility { }
 
 
 
 // Change trait unsafety
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitUnsafety { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 unsafe trait TraitUnsafety { }
 
 
 
 // Add method
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddMethod {
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,associated_item_def_ids,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub trait TraitAddMethod {
     fn method();
 }
@@ -57,14 +69,16 @@ pub trait TraitAddMethod {
 
 
 // Change name of method
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitChangeMethodName {
     fn method();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitChangeMethodName {
     fn methodChanged();
 }
@@ -72,157 +86,227 @@ trait TraitChangeMethodName {
 
 
 // Add return type to method
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddReturnType {
-    fn method();
+    //-----------------------------------------------------
+    //--------------------------
+    //-----------------------------------------------------
+    //--------------------------
+    fn method()       ;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddReturnType {
     #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method() -> u32;
 }
 
 
 
 // Change return type of method
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitChangeReturnType {
+    // --------------------------------------------------------------------
+    // -------------------------
+    // --------------------------------------------------------------------
+    // -------------------------
     fn method() -> u32;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitChangeReturnType {
     #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method() -> u64;
 }
 
 
 
 // Add parameter to method
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddParameterToMethod {
-    fn method();
+    // ----------------------------------------------------
+    // -------------------------
+    // ----------------------------------------------------
+    // -------------------------
+    fn method(      );
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddParameterToMethod {
     #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method(a: u32);
 }
 
 
 
 // Change name of method parameter
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitChangeMethodParameterName {
+    //------------------------------------------------------
+    //----------------------------------------------
+    //--------------------------
+    //----------------------------------------------
+    //--------------------------
     fn method(a: u32);
+
+    //------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------
+    //--------------------------
     fn with_default(x: i32) {}
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitChangeMethodParameterName {
     // FIXME(#38501) This should preferably always be clean.
     #[rustc_clean(except="hir_owner", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method(b: u32);
 
     #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn with_default(y: i32) {}
 }
 
 
 
 // Change type of method parameter (i32 => i64)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitChangeMethodParameterType {
+    // ----------------------------------------------------
+    // -------------------------
+    // ----------------------------------------------------
+    // -------------------------
     fn method(a: i32);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitChangeMethodParameterType {
     #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method(a: i64);
 }
 
 
 
 // Change type of method parameter (&i32 => &mut i32)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitChangeMethodParameterTypeRef {
-    fn method(a: &i32);
+    // ----------------------------------------------------
+    // -------------------------
+    // ----------------------------------------------------
+    // -------------------------
+    fn method(a: &    i32);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitChangeMethodParameterTypeRef {
     #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method(a: &mut i32);
 }
 
 
 
 // Change order of method parameters
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitChangeMethodParametersOrder {
+    // ----------------------------------------------------
+    // -------------------------
+    // ----------------------------------------------------
+    // -------------------------
     fn method(a: i32, b: i64);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitChangeMethodParametersOrder {
     #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method(b: i64, a: i32);
 }
 
 
 
 // Add default implementation to method
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddMethodAutoImplementation {
     fn method();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddMethodAutoImplementation {
     #[rustc_clean(except="hir_owner,associated_item", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,associated_item", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method() { }
 }
 
 
 
 // Change order of methods
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitChangeOrderOfMethods {
     fn method0();
     fn method1();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitChangeOrderOfMethods {
     fn method1();
     fn method0();
@@ -231,134 +315,198 @@ trait TraitChangeOrderOfMethods {
 
 
 // Change mode of self parameter
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitChangeModeSelfRefToMut {
-    fn method(&self);
+    // ----------------------------------------------------
+    // -------------------------
+    // ----------------------------------------------------
+    // -------------------------
+    fn method(&    self);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitChangeModeSelfRefToMut {
     #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method(&mut self);
 }
 
 
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitChangeModeSelfOwnToMut: Sized {
-    fn method(self) {}
+    // ----------------------------------------------------------------------------------
+    // -------------------------
+    // ----------------------------------------------------------------------------------
+    // -------------------------
+    fn method(    self) {}
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitChangeModeSelfOwnToMut: Sized {
     #[rustc_clean(except="hir_owner,hir_owner_nodes,typeck,optimized_mir", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,typeck,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method(mut self) {}
 }
 
 
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitChangeModeSelfOwnToRef {
-    fn method(self);
+    // ----------------------------------------------------------------
+    // -------------------------
+    // ----------------------------------------------------------------
+    // -------------------------
+    fn method( self);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitChangeModeSelfOwnToRef {
     #[rustc_clean(except="hir_owner,fn_sig,generics_of", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,fn_sig,generics_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method(&self);
 }
 
 
 
 // Add unsafe modifier to method
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddUnsafeModifier {
-    fn method();
+    // ----------------------------------------------------
+    // -------------------------
+    // ----------------------------------------------------
+    // -------------------------
+    fn method()       ;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddUnsafeModifier {
     #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     unsafe fn method();
 }
 
 
 
 // Add extern modifier to method
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddExternModifier {
-    fn method();
+    // ----------------------------------------------------
+    // -------------------------
+    // ----------------------------------------------------
+    // -------------------------
+    fn method()           ;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddExternModifier {
     #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     extern "C" fn method();
 }
 
 
 
 // Change extern "C" to extern "stdcall"
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitChangeExternCToRustIntrinsic {
-    extern "C" fn method();
+    // ----------------------------------------------------
+    // -------------------------
+    // ----------------------------------------------------
+    // -------------------------
+    extern "C"       fn method();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitChangeExternCToRustIntrinsic {
     #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     extern "stdcall" fn method();
 }
 
 
 
 // Add type parameter to method
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddTypeParameterToMethod {
-    fn method();
+    // -------------------------------------------------------------------------------
+    // -------------------------
+    // -------------------------------------------------------------------------------
+    // -------------------------
+    fn method   ();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddTypeParameterToMethod {
     #[rustc_clean(except="hir_owner,generics_of,predicates_of,type_of", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,generics_of,predicates_of,type_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method<T>();
 }
 
 
 
 // Add lifetime parameter to method
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddLifetimeParameterToMethod {
-    fn method();
+    // ----------------------------------------------------------------
+    // -------------------------
+    // ----------------------------------------------------------------
+    // -------------------------
+    fn method    ();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddLifetimeParameterToMethod {
     #[rustc_clean(except="hir_owner,fn_sig,generics_of", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,fn_sig,generics_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method<'a>();
 }
 
@@ -369,137 +517,220 @@ trait ReferencedTrait0 { }
 trait ReferencedTrait1 { }
 
 // Add trait bound to method type parameter
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddTraitBoundToMethodTypeParameter {
-    fn method<T>();
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    fn method<T                  >();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddTraitBoundToMethodTypeParameter {
     #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method<T: ReferencedTrait0>();
 }
 
 
 
 // Add builtin bound to method type parameter
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddBuiltinBoundToMethodTypeParameter {
-    fn method<T>();
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    fn method<T       >();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddBuiltinBoundToMethodTypeParameter {
     #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method<T: Sized>();
 }
 
 
 
 // Add lifetime bound to method lifetime parameter
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddLifetimeBoundToMethodLifetimeParameter {
-    fn method<'a, 'b>(a: &'a u32, b: &'b u32);
-}
-
-#[cfg(not(cfail1))]
+    // -----------
+    // -----------------------------------------------------------------------------
+    // --------------
+    //
+    // -------------------------
+    // -----------
+    // -----------------------------------------------------------------------------
+    // --------------
+    //
+    // -------------------------
+    fn method<'a, 'b    >(a: &'a u32, b: &'b u32);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddLifetimeBoundToMethodLifetimeParameter {
     #[rustc_clean(
         except="hir_owner,hir_owner_nodes,generics_of,predicates_of,fn_sig,type_of",
         cfg="cfail2",
     )]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,fn_sig,type_of",
+        cfg="cfail5",
+    )]
+    #[rustc_clean(cfg="cfail6")]
     fn method<'a, 'b: 'a>(a: &'a u32, b: &'b u32);
 }
 
 
 
 // Add second trait bound to method type parameter
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddSecondTraitBoundToMethodTypeParameter {
-    fn method<T: ReferencedTrait0>();
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    fn method<T: ReferencedTrait0                   >();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddSecondTraitBoundToMethodTypeParameter {
     #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method<T: ReferencedTrait0 + ReferencedTrait1>();
 }
 
 
 
 // Add second builtin bound to method type parameter
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddSecondBuiltinBoundToMethodTypeParameter {
-    fn method<T: Sized>();
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    fn method<T: Sized       >();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddSecondBuiltinBoundToMethodTypeParameter {
     #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method<T: Sized + Sync>();
 }
 
 
 
 // Add second lifetime bound to method lifetime parameter
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddSecondLifetimeBoundToMethodLifetimeParameter {
-    fn method<'a, 'b, 'c: 'a>(a: &'a u32, b: &'b u32, c: &'c u32);
-}
-
-#[cfg(not(cfail1))]
+    // -----------
+    // -----------------------------------------------------------------------------
+    // --------------
+    //
+    // -------------------------
+    // -----------
+    // -----------------------------------------------------------------------------
+    // --------------
+    //
+    // -------------------------
+    fn method<'a, 'b, 'c: 'a     >(a: &'a u32, b: &'b u32, c: &'c u32);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddSecondLifetimeBoundToMethodLifetimeParameter {
     #[rustc_clean(
         except="hir_owner,hir_owner_nodes,generics_of,predicates_of,fn_sig,type_of",
         cfg="cfail2",
     )]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,fn_sig,type_of",
+        cfg="cfail5",
+    )]
+    #[rustc_clean(cfg="cfail6")]
     fn method<'a, 'b, 'c: 'a + 'b>(a: &'a u32, b: &'b u32, c: &'c u32);
 }
 
 
 
 // Add associated type
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddAssociatedType {
-
-    #[rustc_clean(except="hir_owner", cfg="cfail2")]
-    #[rustc_clean(cfg="cfail3")]
+    //--------------------------
+    //--------------------------
+    // -------------
+
+    //--------------------------
+    //--------------------------
+    //--------------------------
+    //--------------------------
     fn method();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddAssociatedType {
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail6")]
     type Associated;
 
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method();
 }
 
 
 
 // Add trait bound to associated type
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddTraitBoundToAssociatedType {
-    type Associated;
+    // ---------------------------------------------
+    // -------------------------
+    // ---------------------------------------------
+    // -------------------------
+    type Associated                  ;
 
     fn method();
 }
@@ -507,12 +738,16 @@ trait TraitAddTraitBoundToAssociatedType {
 
 // Apparently the type bound contributes to the predicates of the trait, but
 // does not change the associated item itself.
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddTraitBoundToAssociatedType {
     #[rustc_clean(except="hir_owner", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     type Associated: ReferencedTrait0;
 
     fn method();
@@ -521,19 +756,27 @@ trait TraitAddTraitBoundToAssociatedType {
 
 
 // Add lifetime bound to associated type
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddLifetimeBoundToAssociatedType<'a> {
-    type Associated;
+    // ---------------------------------------------
+    // -------------------------
+    // ---------------------------------------------
+    // -------------------------
+    type Associated    ;
 
     fn method();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddLifetimeBoundToAssociatedType<'a> {
     #[rustc_clean(except="hir_owner", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     type Associated: 'a;
 
     fn method();
@@ -542,19 +785,23 @@ trait TraitAddLifetimeBoundToAssociatedType<'a> {
 
 
 // Add default to associated type
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddDefaultToAssociatedType {
     type Associated;
 
     fn method();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddDefaultToAssociatedType {
     #[rustc_clean(except="hir_owner,associated_item", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,associated_item", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     type Associated = ReferenceType0;
 
     fn method();
@@ -563,14 +810,16 @@ trait TraitAddDefaultToAssociatedType {
 
 
 // Add associated constant
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddAssociatedConstant {
     fn method();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddAssociatedConstant {
     const Value: u32;
 
@@ -580,269 +829,331 @@ trait TraitAddAssociatedConstant {
 
 
 // Add initializer to associated constant
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddInitializerToAssociatedConstant {
     const Value: u32;
 
     fn method();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddInitializerToAssociatedConstant {
     #[rustc_clean(except="hir_owner,associated_item", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,associated_item", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     const Value: u32 = 1;
 
     #[rustc_clean(cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method();
 }
 
 
 
 // Change type of associated constant
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitChangeTypeOfAssociatedConstant {
+    // -----------------------------------------------------
+    // -------------------------
+    // -----------------------------------------------------
+    // -------------------------
     const Value: u32;
 
+    // -------------------------
+    // -------------------------
+    // -------------------------
+    // -------------------------
     fn method();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitChangeTypeOfAssociatedConstant {
     #[rustc_clean(except="hir_owner,type_of", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,type_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     const Value: f64;
 
     #[rustc_clean(cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method();
 }
 
 
 
 // Add super trait
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddSuperTrait { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddSuperTrait : ReferencedTrait0 { }
 
 
 
 // Add builtin bound (Send or Copy)
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddBuiltiBound { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddBuiltiBound : Send { }
 
 
 
 // Add 'static lifetime bound to trait
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddStaticLifetimeBound { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddStaticLifetimeBound : 'static { }
 
 
 
 // Add super trait as second bound
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddTraitAsSecondBound : ReferencedTrait0 { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddTraitAsSecondBound : ReferencedTrait0 + ReferencedTrait1 { }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddTraitAsSecondBoundFromBuiltin : Send { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddTraitAsSecondBoundFromBuiltin : Send + ReferencedTrait0 { }
 
 
 
 // Add builtin bound as second bound
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddBuiltinBoundAsSecondBound : ReferencedTrait0 { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddBuiltinBoundAsSecondBound : ReferencedTrait0 + Send { }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddBuiltinBoundAsSecondBoundFromBuiltin : Send { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddBuiltinBoundAsSecondBoundFromBuiltin: Send + Copy { }
 
 
 
 // Add 'static bounds as second bound
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddStaticBoundAsSecondBound : ReferencedTrait0 { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddStaticBoundAsSecondBound : ReferencedTrait0 + 'static { }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddStaticBoundAsSecondBoundFromBuiltin : Send { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddStaticBoundAsSecondBoundFromBuiltin : Send + 'static { }
 
 
 
 // Add type parameter to trait
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddTypeParameterToTrait { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,generics_of,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddTypeParameterToTrait<T> { }
 
 
 
 // Add lifetime parameter to trait
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddLifetimeParameterToTrait { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,generics_of,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddLifetimeParameterToTrait<'a> { }
 
 
 
 // Add trait bound to type parameter of trait
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddTraitBoundToTypeParameterOfTrait<T> { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddTraitBoundToTypeParameterOfTrait<T: ReferencedTrait0> { }
 
 
 
 // Add lifetime bound to type parameter of trait
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddLifetimeBoundToTypeParameterOfTrait<'a, T> { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddLifetimeBoundToTypeParameterOfTrait<'a, T: 'a> { }
 
 
 
 // Add lifetime bound to lifetime parameter of trait
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddLifetimeBoundToLifetimeParameterOfTrait<'a, 'b> { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddLifetimeBoundToLifetimeParameterOfTrait<'a: 'b, 'b> { }
 
 
 
 // Add builtin bound to type parameter of trait
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddBuiltinBoundToTypeParameterOfTrait<T> { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddBuiltinBoundToTypeParameterOfTrait<T: Send> { }
 
 
 
 // Add second type parameter to trait
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddSecondTypeParameterToTrait<T> { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddSecondTypeParameterToTrait<T, S> { }
 
 
 
 // Add second lifetime parameter to trait
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddSecondLifetimeParameterToTrait<'a> { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddSecondLifetimeParameterToTrait<'a, 'b> { }
 
 
 
 // Add second trait bound to type parameter of trait
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddSecondTraitBoundToTypeParameterOfTrait<T: ReferencedTrait0> { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddSecondTraitBoundToTypeParameterOfTrait<T: ReferencedTrait0 + ReferencedTrait1> { }
 
 
 
 // Add second lifetime bound to type parameter of trait
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddSecondLifetimeBoundToTypeParameterOfTrait<'a, 'b, T: 'a> { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddSecondLifetimeBoundToTypeParameterOfTrait<'a, 'b, T: 'a + 'b> { }
 
 
 
 // Add second lifetime bound to lifetime parameter of trait
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTrait<'a: 'b, 'b, 'c> { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTrait<'a: 'b + 'c, 'b, 'c> { }
 
 
 
 // Add second builtin bound to type parameter of trait
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddSecondBuiltinBoundToTypeParameterOfTrait<T: Send> { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddSecondBuiltinBoundToTypeParameterOfTrait<T: Send + Sync> { }
 
 
@@ -853,105 +1164,125 @@ struct ReferenceType1 {}
 
 
 // Add trait bound to type parameter of trait in where clause
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddTraitBoundToTypeParameterOfTraitWhere<T> { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddTraitBoundToTypeParameterOfTraitWhere<T> where T: ReferencedTrait0 { }
 
 
 
 // Add lifetime bound to type parameter of trait in where clause
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddLifetimeBoundToTypeParameterOfTraitWhere<'a, T> { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddLifetimeBoundToTypeParameterOfTraitWhere<'a, T> where T: 'a { }
 
 
 
 // Add lifetime bound to lifetime parameter of trait in where clause
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b> { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b> where 'a: 'b { }
 
 
 
 // Add builtin bound to type parameter of trait in where clause
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddBuiltinBoundToTypeParameterOfTraitWhere<T> { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddBuiltinBoundToTypeParameterOfTraitWhere<T> where T: Send { }
 
 
 
 // Add second trait bound to type parameter of trait in where clause
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddSecondTraitBoundToTypeParameterOfTraitWhere<T> where T: ReferencedTrait0 { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddSecondTraitBoundToTypeParameterOfTraitWhere<T>
     where T: ReferencedTrait0 + ReferencedTrait1 { }
 
 
 
 // Add second lifetime bound to type parameter of trait in where clause
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddSecondLifetimeBoundToTypeParameterOfTraitWhere<'a, 'b, T> where T: 'a { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddSecondLifetimeBoundToTypeParameterOfTraitWhere<'a, 'b, T> where T: 'a + 'b { }
 
 
 
 // Add second lifetime bound to lifetime parameter of trait in where clause
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b, 'c> where 'a: 'b { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b, 'c> where 'a: 'b + 'c { }
 
 
 
 // Add second builtin bound to type parameter of trait in where clause
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 trait TraitAddSecondBuiltinBoundToTypeParameterOfTraitWhere<T> where T: Send { }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 trait TraitAddSecondBuiltinBoundToTypeParameterOfTraitWhere<T> where T: Send + Sync { }
 
 
 // Change return type of method indirectly by modifying a use statement
 mod change_return_type_of_method_indirectly_use {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferenceType0 as ReturnType;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferenceType1 as ReturnType;
 
     #[rustc_clean(cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     trait TraitChangeReturnType {
         #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail2")]
         #[rustc_clean(cfg="cfail3")]
+        #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail5")]
+        #[rustc_clean(cfg="cfail6")]
         fn method() -> ReturnType;
     }
 }
@@ -960,9 +1291,9 @@ trait TraitChangeReturnType {
 
 // Change type of method parameter indirectly by modifying a use statement
 mod change_method_parameter_type_indirectly_by_use {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferenceType0 as ArgType;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferenceType1 as ArgType;
 
     #[rustc_clean(cfg="cfail2")]
@@ -978,9 +1309,9 @@ trait TraitChangeArgType {
 
 // Change trait bound of method type parameter indirectly by modifying a use statement
 mod change_method_parameter_type_bound_indirectly_by_use {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedTrait0 as Bound;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedTrait1 as Bound;
 
     #[rustc_clean(cfg="cfail2")]
@@ -997,16 +1328,20 @@ trait TraitChangeBoundOfMethodTypeParameter {
 // Change trait bound of method type parameter in where clause indirectly
 // by modifying a use statement
 mod change_method_parameter_type_bound_indirectly_by_use_where {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedTrait0 as Bound;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedTrait1 as Bound;
 
     #[rustc_clean(cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     trait TraitChangeBoundOfMethodTypeParameterWhere {
         #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
         #[rustc_clean(cfg="cfail3")]
+        #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+        #[rustc_clean(cfg="cfail6")]
         fn method<T>(a: T) where T: Bound;
     }
 }
@@ -1015,9 +1350,9 @@ trait TraitChangeBoundOfMethodTypeParameterWhere {
 
 // Change trait bound of trait type parameter indirectly by modifying a use statement
 mod change_method_type_parameter_bound_indirectly {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedTrait0 as Bound;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedTrait1 as Bound;
 
     #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
@@ -1032,13 +1367,15 @@ trait TraitChangeTraitBound<T: Bound> {
 // Change trait bound of trait type parameter in where clause indirectly
 // by modifying a use statement
 mod change_method_type_parameter_bound_indirectly_where {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1,cfail4))]
     use super::ReferencedTrait0 as Bound;
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1,cfail4)))]
     use super::ReferencedTrait1 as Bound;
 
     #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     trait TraitChangeTraitBoundWhere<T> where T: Bound {
         fn method(a: T);
     }
index 2d547f1748cb4a5ee9815e6a93cfd511117ac726..d623810115ee8c4aec7d303362fe67bad9da94cc 100644 (file)
@@ -6,9 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
-
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
 
 // Change Method Name -----------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub trait ChangeMethodNameTrait {
     fn method_name();
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl ChangeMethodNameTrait for Foo {
     fn method_name() { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub trait ChangeMethodNameTrait {
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail6")]
     fn method_name2();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl ChangeMethodNameTrait for Foo {
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail6")]
     fn method_name2() { }
 }
 
@@ -53,17 +64,27 @@ pub trait ChangeMethodBodyTrait {
     fn method_name();
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl ChangeMethodBodyTrait for Foo {
-    fn method_name() { }
+    // ----------------------------------------------------------
+    // -------------------------
+    // ----------------------------------------------------------
+    // -------------------------
+    fn method_name() {
+        //
+    }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl ChangeMethodBodyTrait for Foo {
     #[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method_name() {
         ()
     }
@@ -77,18 +98,28 @@ pub trait ChangeMethodBodyTraitInlined {
     fn method_name();
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl ChangeMethodBodyTraitInlined for Foo {
+    // ------------------------------------------------------------------------
+    // -------------------------
+    // ------------------------------------------------------------------------
+    // -------------------------
     #[inline]
-    fn method_name() { }
+    fn method_name() {
+        // -----
+    }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl ChangeMethodBodyTraitInlined for Foo {
     #[rustc_clean(except="hir_owner_nodes,typeck,optimized_mir", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner_nodes,typeck,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     #[inline]
     fn method_name() {
         panic!()
@@ -97,30 +128,37 @@ fn method_name() {
 
 // Change Method Selfness ------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub trait ChangeMethodSelfnessTrait {
     fn method_name();
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl ChangeMethodSelfnessTrait for Foo {
     fn method_name() { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 pub trait ChangeMethodSelfnessTrait {
     fn method_name(&self);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl ChangeMethodSelfnessTrait for Foo {
     #[rustc_clean(
         except="hir_owner,hir_owner_nodes,associated_item,generics_of,fn_sig,typeck,optimized_mir",
         cfg="cfail2",
     )]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,associated_item,generics_of,fn_sig,typeck,optimized_mir",
+        cfg="cfail5",
+    )]
+    #[rustc_clean(cfg="cfail6")]
     fn method_name(&self) {
         ()
     }
@@ -128,130 +166,151 @@ fn method_name(&self) {
 
 // Change Method Selfness -----------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub trait RemoveMethodSelfnessTrait {
     fn method_name(&self);
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl RemoveMethodSelfnessTrait for Foo {
     fn method_name(&self) { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 pub trait RemoveMethodSelfnessTrait {
     fn method_name();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl RemoveMethodSelfnessTrait for Foo {
     #[rustc_clean(
         except="hir_owner,hir_owner_nodes,associated_item,generics_of,fn_sig,typeck,optimized_mir",
         cfg="cfail2",
     )]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,associated_item,generics_of,fn_sig,typeck,optimized_mir",
+        cfg="cfail5",
+    )]
+    #[rustc_clean(cfg="cfail6")]
     fn method_name() {}
 }
 
 // Change Method Selfmutness -----------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub trait ChangeMethodSelfmutnessTrait {
     fn method_name(&self);
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl ChangeMethodSelfmutnessTrait for Foo {
-    fn method_name(&self) { }
+    // -----------------------------------------------------------------------------------------
+    // -------------------------
+    // -----------------------------------------------------------------------------------------
+    // -------------------------
+    fn method_name(&    self) {}
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 pub trait ChangeMethodSelfmutnessTrait {
     fn method_name(&mut self);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl ChangeMethodSelfmutnessTrait for Foo {
     #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method_name(&mut self) {}
 }
 
 // Change item kind -----------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub trait ChangeItemKindTrait {
     fn name();
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl ChangeItemKindTrait for Foo {
     fn name() { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 pub trait ChangeItemKindTrait {
     type name;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl ChangeItemKindTrait for Foo {
     type name = ();
 }
 
 // Remove item -----------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub trait RemoveItemTrait {
     type TypeName;
     fn method_name();
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl RemoveItemTrait for Foo {
     type TypeName = ();
     fn method_name() { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 pub trait RemoveItemTrait {
     type TypeName;
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl RemoveItemTrait for Foo {
     type TypeName = ();
 }
 
 // Add item -----------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub trait AddItemTrait {
     type TypeName;
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl AddItemTrait for Foo {
     type TypeName = ();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 pub trait AddItemTrait {
     type TypeName;
     fn method_name();
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl AddItemTrait for Foo {
     type TypeName = ();
     fn method_name() { }
@@ -259,28 +318,34 @@ fn method_name() { }
 
 // Change has-value -----------------------------------------------------------
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub trait ChangeHasValueTrait {
     fn method_name();
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl ChangeHasValueTrait for Foo {
     fn method_name() { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub trait ChangeHasValueTrait {
     #[rustc_clean(except="hir_owner,associated_item", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,associated_item", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method_name() { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl ChangeHasValueTrait for Foo {
     fn method_name() { }
 }
@@ -291,69 +356,91 @@ pub trait AddDefaultTrait {
     fn method_name();
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl AddDefaultTrait for Foo {
-    fn method_name() { }
+    // -------------------------------------------------------------------------------------------
+    // -------------------------
+            fn method_name() { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl AddDefaultTrait for Foo {
     #[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     default fn method_name() { }
 }
 
 // Add arguments
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub trait AddArgumentTrait {
     fn method_name(&self);
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl AddArgumentTrait for Foo {
-    fn method_name(&self) { }
+    // -----------------------------------------------------------------------------------------
+    // -------------------------
+    // -----------------------------------------------------------------------------------------
+    // -------------------------
+    fn method_name(&self         ) { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 pub trait AddArgumentTrait {
     fn method_name(&self, x: u32);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl AddArgumentTrait for Foo {
     #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method_name(&self, _x: u32) { }
 }
 
 // Change argument type
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub trait ChangeArgumentTypeTrait {
     fn method_name(&self, x: u32);
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl ChangeArgumentTypeTrait for Foo {
-    fn method_name(&self, _x: u32) { }
+    // -----------------------------------------------------------------------------------------
+    // -------------------------
+    // -----------------------------------------------------------------------------------------
+    // -------------------------
+    fn method_name(&self, _x: u32 ) { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 pub trait ChangeArgumentTypeTrait {
     fn method_name(&self, x: char);
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl ChangeArgumentTypeTrait for Foo {
     #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn method_name(&self, _x: char) { }
 }
 
@@ -366,21 +453,28 @@ trait AddTypeParameterToImpl<T> {
     fn id(t: T) -> T;
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl AddTypeParameterToImpl<u32> for Bar<u32> {
     fn id(t: u32) -> u32 { t }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,generics_of,impl_trait_ref", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
-impl<T> AddTypeParameterToImpl<T> for Bar<T> {
+#[rustc_clean(except="hir_owner,generics_of,impl_trait_ref", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl<TTT> AddTypeParameterToImpl<TTT> for Bar<TTT> {
     #[rustc_clean(
         except="hir_owner,hir_owner_nodes,generics_of,fn_sig,type_of,typeck,optimized_mir",
         cfg="cfail2",
     )]
     #[rustc_clean(cfg="cfail3")]
-    fn id(t: T) -> T { t }
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,generics_of,fn_sig,type_of,typeck,optimized_mir",
+        cfg="cfail5",
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    fn id(t: TTT) -> TTT { t }
 }
 
 
@@ -390,17 +484,21 @@ trait ChangeSelfTypeOfImpl {
     fn id(self) -> Self;
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl ChangeSelfTypeOfImpl for u32 {
     fn id(self) -> Self { self }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,impl_trait_ref", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,impl_trait_ref", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl ChangeSelfTypeOfImpl for u64 {
     #[rustc_clean(except="fn_sig,typeck,optimized_mir", cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="fn_sig,typeck,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn id(self) -> Self { self }
 }
 
@@ -411,17 +509,21 @@ trait AddLifetimeBoundToImplParameter {
     fn id(self) -> Self;
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl<T> AddLifetimeBoundToImplParameter for T {
     fn id(self) -> Self { self }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl<T: 'static> AddLifetimeBoundToImplParameter for T {
     #[rustc_clean(cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn id(self) -> Self { self }
 }
 
@@ -432,17 +534,21 @@ trait AddTraitBoundToImplParameter {
     fn id(self) -> Self;
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl<T> AddTraitBoundToImplParameter for T {
     fn id(self) -> Self { self }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl<T: Clone> AddTraitBoundToImplParameter for T {
     #[rustc_clean(cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     fn id(self) -> Self { self }
 }
 
@@ -453,17 +559,26 @@ trait AddNoMangleToMethod {
     fn add_no_mangle_to_method(&self) { }
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl AddNoMangleToMethod for Foo {
+    // -------------------------
+    // -------------------------
+    // -------------------------
+    // -------------------------
+    // ---------
     fn add_no_mangle_to_method(&self) { }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl AddNoMangleToMethod for Foo {
     #[rustc_clean(cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     #[no_mangle]
     fn add_no_mangle_to_method(&self) { }
 }
@@ -474,17 +589,26 @@ trait MakeMethodInline {
     fn make_method_inline(&self) -> u8 { 0 }
 }
 
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 impl MakeMethodInline for Foo {
+    // -------------------------
+    // -------------------------
+    // -------------------------
+    // -------------------------
+    // ------
     fn make_method_inline(&self) -> u8 { 0 }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 impl MakeMethodInline for Foo {
     #[rustc_clean(cfg="cfail2")]
     #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
     #[inline]
     fn make_method_inline(&self) -> u8 { 0 }
 }
index d874be060c26a080c8d74fa0bb943450ac31cce0..70c199bc3be7de8f992a88ef5c6bfbf902f8a1f3 100644 (file)
@@ -12,7 +12,7 @@
 
 // build-pass (FIXME(62277): could be check-pass?)
 // revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// compile-flags: -Z query-dep-graph
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
index 687580ec8afb24b10b3ae5ba5e2ce0c95ca674f6..8d8345e10f5553f4b0efb5f0b9435f48e780c2b2 100644 (file)
@@ -6,8 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
 
 
 // Change constant operand of negation -----------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn const_negation() -> i32 {
     -10
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn const_negation() -> i32 {
-    -1
+     -1
 }
 
 
 
 // Change constant operand of bitwise not --------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn const_bitwise_not() -> i32 {
     !100
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn const_bitwise_not() -> i32 {
-    !99
+     !99
 }
 
 
 
 // Change variable operand of negation -----------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn var_negation(x: i32, y: i32) -> i32 {
     -x
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn var_negation(x: i32, y: i32) -> i32 {
     -y
 }
@@ -60,14 +72,16 @@ pub fn var_negation(x: i32, y: i32) -> i32 {
 
 
 // Change variable operand of bitwise not --------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn var_bitwise_not(x: i32, y: i32) -> i32 {
     !x
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn var_bitwise_not(x: i32, y: i32) -> i32 {
     !y
 }
@@ -75,14 +89,16 @@ pub fn var_bitwise_not(x: i32, y: i32) -> i32 {
 
 
 // Change variable operand of deref --------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn var_deref(x: &i32, y: &i32) -> i32 {
     *x
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn var_deref(x: &i32, y: &i32) -> i32 {
     *y
 }
@@ -90,14 +106,16 @@ pub fn var_deref(x: &i32, y: &i32) -> i32 {
 
 
 // Change first constant operand of addition -----------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn first_const_add() -> i32 {
     1 + 3
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn first_const_add() -> i32 {
     2 + 3
 }
@@ -105,14 +123,16 @@ pub fn first_const_add() -> i32 {
 
 
 // Change second constant operand of addition -----------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn second_const_add() -> i32 {
     1 + 2
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn second_const_add() -> i32 {
     1 + 3
 }
@@ -120,14 +140,16 @@ pub fn second_const_add() -> i32 {
 
 
 // Change first variable operand of addition -----------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn first_var_add(a: i32, b: i32) -> i32 {
     a + 2
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn first_var_add(a: i32, b: i32) -> i32 {
     b + 2
 }
@@ -135,14 +157,16 @@ pub fn first_var_add(a: i32, b: i32) -> i32 {
 
 
 // Change second variable operand of addition ----------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn second_var_add(a: i32, b: i32) -> i32 {
     1 + a
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn second_var_add(a: i32, b: i32) -> i32 {
     1 + b
 }
@@ -150,14 +174,16 @@ pub fn second_var_add(a: i32, b: i32) -> i32 {
 
 
 // Change operator from + to - -------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn plus_to_minus(a: i32) -> i32 {
     1 + a
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn plus_to_minus(a: i32) -> i32 {
     1 - a
 }
@@ -165,14 +191,16 @@ pub fn plus_to_minus(a: i32) -> i32 {
 
 
 // Change operator from + to * -------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn plus_to_mult(a: i32) -> i32 {
     1 + a
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn plus_to_mult(a: i32) -> i32 {
     1 * a
 }
@@ -180,14 +208,16 @@ pub fn plus_to_mult(a: i32) -> i32 {
 
 
 // Change operator from + to / -------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn plus_to_div(a: i32) -> i32 {
     1 + a
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn plus_to_div(a: i32) -> i32 {
     1 / a
 }
@@ -195,14 +225,16 @@ pub fn plus_to_div(a: i32) -> i32 {
 
 
 // Change operator from + to % -------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn plus_to_mod(a: i32) -> i32 {
     1 + a
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn plus_to_mod(a: i32) -> i32 {
     1 % a
 }
@@ -210,14 +242,16 @@ pub fn plus_to_mod(a: i32) -> i32 {
 
 
 // Change operator from && to || -----------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn and_to_or(a: bool, b: bool) -> bool {
     a && b
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn and_to_or(a: bool, b: bool) -> bool {
     a || b
 }
@@ -225,14 +259,16 @@ pub fn and_to_or(a: bool, b: bool) -> bool {
 
 
 // Change operator from & to | -------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 {
     1 & a
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 {
     1 | a
 }
@@ -240,14 +276,16 @@ pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 {
 
 
 // Change operator from & to ^ -------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 {
     1 & a
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 {
     1 ^ a
 }
@@ -255,14 +293,16 @@ pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 {
 
 
 // Change operator from & to << ------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn bitwise_and_to_lshift(a: i32) -> i32 {
-    a & 1
+    a  & 1
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn bitwise_and_to_lshift(a: i32) -> i32 {
     a << 1
 }
@@ -270,14 +310,16 @@ pub fn bitwise_and_to_lshift(a: i32) -> i32 {
 
 
 // Change operator from & to >> ------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn bitwise_and_to_rshift(a: i32) -> i32 {
-    a & 1
+    a  & 1
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn bitwise_and_to_rshift(a: i32) -> i32 {
     a >> 1
 }
@@ -285,14 +327,16 @@ pub fn bitwise_and_to_rshift(a: i32) -> i32 {
 
 
 // Change operator from == to != -----------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn eq_to_uneq(a: i32) -> bool {
     a == 1
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn eq_to_uneq(a: i32) -> bool {
     a != 1
 }
@@ -300,44 +344,50 @@ pub fn eq_to_uneq(a: i32) -> bool {
 
 
 // Change operator from == to < ------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn eq_to_lt(a: i32) -> bool {
     a == 1
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn eq_to_lt(a: i32) -> bool {
-    a < 1
+    a  < 1
 }
 
 
 
 // Change operator from == to > ------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn eq_to_gt(a: i32) -> bool {
     a == 1
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn eq_to_gt(a: i32) -> bool {
-    a > 1
+    a  > 1
 }
 
 
 
 // Change operator from == to <= -----------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn eq_to_le(a: i32) -> bool {
     a == 1
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn eq_to_le(a: i32) -> bool {
     a <= 1
 }
@@ -345,14 +395,16 @@ pub fn eq_to_le(a: i32) -> bool {
 
 
 // Change operator from == to >= -----------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn eq_to_ge(a: i32) -> bool {
     a == 1
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn eq_to_ge(a: i32) -> bool {
     a >= 1
 }
@@ -360,16 +412,18 @@ pub fn eq_to_ge(a: i32) -> bool {
 
 
 // Change type in cast expression ----------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn type_cast(a: u8) -> u64 {
     let b = a as i32;
     let c = b as u64;
     c
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir,typeck", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir,typeck", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn type_cast(a: u8) -> u64 {
     let b = a as u32;
     let c = b as u64;
@@ -379,14 +433,16 @@ pub fn type_cast(a: u8) -> u64 {
 
 
 // Change value in cast expression ---------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn value_cast(a: u32) -> i32 {
     1 as i32
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn value_cast(a: u32) -> i32 {
     2 as i32
 }
@@ -394,7 +450,7 @@ pub fn value_cast(a: u32) -> i32 {
 
 
 // Change place in assignment --------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn place() -> i32 {
     let mut x = 10;
     let mut y = 11;
@@ -402,9 +458,11 @@ pub fn place() -> i32 {
     x
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn place() -> i32 {
     let mut x = 10;
     let mut y = 11;
@@ -415,16 +473,18 @@ pub fn place() -> i32 {
 
 
 // Change r-value in assignment ------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn rvalue() -> i32 {
     let mut x = 10;
     x = 9;
     x
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn rvalue() -> i32 {
     let mut x = 10;
     x = 8;
@@ -434,14 +494,16 @@ pub fn rvalue() -> i32 {
 
 
 // Change index into slice -----------------------------------------------------
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 {
     s[i]
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
 pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 {
     s[j]
 }
index d385974893ca3e2f625e0b94c738983fd38df119..64a6517836cd80f708247c23aa893f76ac0b6eba 100644 (file)
@@ -6,8 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
@@ -15,7 +21,7 @@
 
 
 // Change loop body
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_loop_body() {
     let mut _x = 0;
     while let Some(0u32) = None {
@@ -24,9 +30,11 @@ pub fn change_loop_body() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_loop_body() {
     let mut _x = 0;
     while let Some(0u32) = None {
@@ -38,7 +46,7 @@ pub fn change_loop_body() {
 
 
 // Change loop body
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_loop_condition() {
     let mut _x = 0;
     while let Some(0u32) = None {
@@ -47,9 +55,11 @@ pub fn change_loop_condition() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_loop_condition() {
     let mut _x = 0;
     while let Some(1u32) = None {
@@ -61,17 +71,20 @@ pub fn change_loop_condition() {
 
 
 // Add break
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_break() {
     let mut _x = 0;
     while let Some(0u32) = None {
         _x = 1;
+        // ---
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_break() {
     let mut _x = 0;
     while let Some(0u32) = None {
@@ -83,18 +96,20 @@ pub fn add_break() {
 
 
 // Add loop label
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_loop_label() {
     let mut _x = 0;
-    while let Some(0u32) = None {
+            while let Some(0u32) = None {
         _x = 1;
         break;
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_loop_label() {
     let mut _x = 0;
     'label: while let Some(0u32) = None {
@@ -106,18 +121,20 @@ pub fn add_loop_label() {
 
 
 // Add loop label to break
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_loop_label_to_break() {
     let mut _x = 0;
     'label: while let Some(0u32) = None {
         _x = 1;
-        break;
+        break       ;
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_loop_label_to_break() {
     let mut _x = 0;
     'label: while let Some(0u32) = None {
@@ -129,7 +146,7 @@ pub fn add_loop_label_to_break() {
 
 
 // Change break label
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_break_label() {
     let mut _x = 0;
     'outer: while let Some(0u32) = None {
@@ -140,9 +157,11 @@ pub fn change_break_label() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_break_label() {
     let mut _x = 0;
     'outer: while let Some(0u32) = None {
@@ -154,18 +173,20 @@ pub fn change_break_label() {
 }
 
 // Add loop label to continue
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_loop_label_to_continue() {
     let mut _x = 0;
     'label: while let Some(0u32) = None {
         _x = 1;
-        continue;
+        continue       ;
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_loop_label_to_continue() {
     let mut _x = 0;
     'label: while let Some(0u32) = None {
@@ -177,7 +198,7 @@ pub fn add_loop_label_to_continue() {
 
 
 // Change continue label
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_continue_label() {
     let mut _x = 0;
     'outer: while let Some(0u32) = None {
@@ -188,9 +209,11 @@ pub fn change_continue_label() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_continue_label() {
     let mut _x = 0;
     'outer: while let Some(0u32) = None {
@@ -204,7 +227,7 @@ pub fn change_continue_label() {
 
 
 // Change continue to break
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_continue_to_break() {
     let mut _x = 0;
     while let Some(0u32) = None {
@@ -213,13 +236,15 @@ pub fn change_continue_to_break() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_continue_to_break() {
     let mut _x = 0;
     while let Some(0u32) = None {
         _x = 1;
-        break;
+        break   ;
     }
 }
index 299622e45c67b179ecdeba760a6d0032663a3205..b8796d3446be72826328aff7ee9a64c8e3ca87ed 100644 (file)
@@ -6,8 +6,14 @@
 // rev3 and make sure that the hash has not changed.
 
 // build-pass (FIXME(62277): could be check-pass?)
-// revisions: cfail1 cfail2 cfail3
-// compile-flags: -Z query-dep-graph -Zincremental-ignore-spans
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
@@ -15,7 +21,7 @@
 
 
 // Change loop body
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_loop_body() {
     let mut _x = 0;
     while true {
@@ -24,9 +30,11 @@ pub fn change_loop_body() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_loop_body() {
     let mut _x = 0;
     while true {
@@ -38,18 +46,20 @@ pub fn change_loop_body() {
 
 
 // Change loop body
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_loop_condition() {
     let mut _x = 0;
-    while true {
+    while true  {
         _x = 1;
         break;
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_loop_condition() {
     let mut _x = 0;
     while false {
@@ -61,17 +71,20 @@ pub fn change_loop_condition() {
 
 
 // Add break
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_break() {
     let mut _x = 0;
     while true {
         _x = 1;
+        // ---
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_break() {
     let mut _x = 0;
     while true {
@@ -83,18 +96,20 @@ pub fn add_break() {
 
 
 // Add loop label
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_loop_label() {
     let mut _x = 0;
-    while true {
+            while true {
         _x = 1;
         break;
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_loop_label() {
     let mut _x = 0;
     'label: while true {
@@ -106,18 +121,20 @@ pub fn add_loop_label() {
 
 
 // Add loop label to break
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_loop_label_to_break() {
     let mut _x = 0;
     'label: while true {
         _x = 1;
-        break;
+        break       ;
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_loop_label_to_break() {
     let mut _x = 0;
     'label: while true {
@@ -129,7 +146,7 @@ pub fn add_loop_label_to_break() {
 
 
 // Change break label
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_break_label() {
     let mut _x = 0;
     'outer: while true {
@@ -140,9 +157,11 @@ pub fn change_break_label() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_break_label() {
     let mut _x = 0;
     'outer: while true {
@@ -156,18 +175,20 @@ pub fn change_break_label() {
 
 
 // Add loop label to continue
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn add_loop_label_to_continue() {
     let mut _x = 0;
     'label: while true {
         _x = 1;
-        continue;
+        continue       ;
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
 pub fn add_loop_label_to_continue() {
     let mut _x = 0;
     'label: while true {
@@ -179,7 +200,7 @@ pub fn add_loop_label_to_continue() {
 
 
 // Change continue label
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_continue_label() {
     let mut _x = 0;
     'outer: while true {
@@ -190,9 +211,11 @@ pub fn change_continue_label() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_continue_label() {
     let mut _x = 0;
     'outer: while true {
@@ -206,7 +229,7 @@ pub fn change_continue_label() {
 
 
 // Change continue to break
-#[cfg(cfail1)]
+#[cfg(any(cfail1,cfail4))]
 pub fn change_continue_to_break() {
     let mut _x = 0;
     while true {
@@ -215,13 +238,15 @@ pub fn change_continue_to_break() {
     }
 }
 
-#[cfg(not(cfail1))]
+#[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
 pub fn change_continue_to_break() {
     let mut _x = 0;
     while true {
         _x = 1;
-        break;
+        break   ;
     }
 }
index 8506636e22b7be65c7e67063d820e5411b7c6181..639454cc975300dad6299d4a6cf761ad4450e5c7 100644 (file)
@@ -1,16 +1,21 @@
 // This test makes sure that just changing a definition's location in the
 // source file also changes its incr. comp. hash, if debuginfo is enabled.
 
-// revisions:rpass1 rpass2
+// revisions:rpass1 rpass2 rpass3 rpass4
 
 // ignore-asmjs wasm2js does not support source maps yet
 // compile-flags: -g -Z query-dep-graph
+// [rpass3]compile-flags: -Zincremental-relative-spans
+// [rpass4]compile-flags: -Zincremental-relative-spans
 
 #![feature(rustc_attrs)]
+#![rustc_partition_codegened(module = "spans_significant_w_debuginfo", cfg = "rpass2")]
+#![rustc_partition_codegened(module = "spans_significant_w_debuginfo", cfg = "rpass4")]
 
-#[cfg(rpass1)]
+#[cfg(any(rpass1, rpass3))]
 pub fn main() {}
 
-#[cfg(rpass2)]
-#[rustc_clean(except="hir_owner,hir_owner_nodes,optimized_mir", cfg="rpass2")]
+#[cfg(any(rpass2, rpass4))]
+#[rustc_clean(except = "hir_owner,hir_owner_nodes,optimized_mir", cfg = "rpass2")]
+#[rustc_clean(cfg = "rpass4")]
 pub fn main() {}
index a29b61ab153dcb6b4039de0eeb6e7e6a0195d251..e9e35791aa15800988b44f2cd21249ee7b7fce63 100644 (file)
@@ -1,19 +1,29 @@
 // This test makes sure that just changing a definition's location in the
 // source file also changes its incr. comp. hash, if debuginfo is enabled.
 
-// revisions:rpass1 rpass2
+// revisions:rpass1 rpass2 rpass3 rpass4
+// [rpass3]compile-flags: -Zincremental-relative-spans
+// [rpass4]compile-flags: -Zincremental-relative-spans
 
 // compile-flags: -C overflow-checks=on -Z query-dep-graph
 
 #![feature(rustc_attrs)]
+#![feature(bench_black_box)]
+#![rustc_partition_codegened(module = "spans_significant_w_panic", cfg = "rpass2")]
+#![rustc_partition_codegened(module = "spans_significant_w_panic", cfg = "rpass4")]
 
-#[cfg(rpass1)]
+#[cfg(any(rpass1, rpass3))]
 pub fn main() {
-    let _ = 0u8 + 1;
+    if std::hint::black_box(false) {
+        panic!()
+    }
 }
 
-#[cfg(rpass2)]
-#[rustc_clean(except="hir_owner,hir_owner_nodes,optimized_mir", cfg="rpass2")]
+#[cfg(any(rpass2, rpass4))]
+#[rustc_clean(except = "hir_owner,hir_owner_nodes,optimized_mir", cfg = "rpass2")]
+#[rustc_clean(cfg = "rpass4")]
 pub fn main() {
-    let _ = 0u8 + 1;
+    if std::hint::black_box(false) {
+        panic!()
+    }
 }
index 866f51d759ec4d5338b1d66cff40f479ca55f51b..cae7b4aab7565ed60455eec442a1a4de705760e2 100644 (file)
@@ -1,5 +1,7 @@
-// revisions: cfail1 cfail2
+// revisions: cfail1 cfail2 cfail3 cfail4
 // compile-flags: -Z query-dep-graph
+// [cfail3]compile-flags: -Zincremental-relative-spans
+// [cfail4]compile-flags: -Zincremental-relative-spans
 // build-pass (FIXME(62277): could be check-pass?)
 
 #![allow(warnings)]
 // Therefore, the compiler deduces (correctly) that typeck is not
 // needed even for callers of `x`.
 
-
 pub mod x {
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1, cfail3))]
     pub fn x() {
         println!("{}", "1");
     }
 
-    #[cfg(cfail2)]
-    #[rustc_clean(except="hir_owner,hir_owner_nodes,optimized_mir,promoted_mir", cfg="cfail2")]
+    #[cfg(any(cfail2, cfail4))]
+    #[rustc_clean(except = "hir_owner,hir_owner_nodes,optimized_mir,promoted_mir", cfg = "cfail2")]
+    #[rustc_clean(except = "hir_owner_nodes,promoted_mir", cfg = "cfail4")]
     pub fn x() {
         println!("{}", "2");
     }
@@ -27,7 +29,8 @@ pub fn x() {
 pub mod y {
     use x;
 
-    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg = "cfail2")]
+    #[rustc_clean(cfg = "cfail4")]
     pub fn y() {
         x::x();
     }
@@ -36,7 +39,8 @@ pub fn y() {
 pub mod z {
     use y;
 
-    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg = "cfail2")]
+    #[rustc_clean(cfg = "cfail4")]
     pub fn z() {
         y::y();
     }
index 0fd5abee11840996a234b0cd64f732d4f4a17878..31f329a7f726b2083d9b80837fc98a57158038dd 100644 (file)
@@ -3,36 +3,61 @@
 // ends up with any spans in its LLVM bitecode, so LLVM is able to skip
 // re-building any modules which import 'inlined_fn'
 
-// revisions: cfail1 cfail2 cfail3
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// [cfail4]compile-flags: -Zincremental-relative-spans
+// [cfail5]compile-flags: -Zincremental-relative-spans
+// [cfail6]compile-flags: -Zincremental-relative-spans
 // compile-flags: -Z query-dep-graph -O
 // build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(rustc_attrs)]
-#![crate_type="rlib"]
-
-#![rustc_expected_cgu_reuse(module="cgu_keeps_identical_fn-foo",
-                            cfg="cfail2",
-                            kind="no")]
-#![rustc_expected_cgu_reuse(module="cgu_keeps_identical_fn-foo",
-                            cfg="cfail3",
-                            kind="post-lto")]
-
-#![rustc_expected_cgu_reuse(module="cgu_keeps_identical_fn-bar",
-                            cfg="cfail2",
-                            kind="post-lto")]
-#![rustc_expected_cgu_reuse(module="cgu_keeps_identical_fn-bar",
-                            cfg="cfail3",
-                            kind="post-lto")]
+#![crate_type = "rlib"]
+#![rustc_expected_cgu_reuse(module = "cgu_keeps_identical_fn-foo", cfg = "cfail2", kind = "no")]
+#![rustc_expected_cgu_reuse(
+    module = "cgu_keeps_identical_fn-foo",
+    cfg = "cfail3",
+    kind = "post-lto"
+)]
+#![rustc_expected_cgu_reuse(
+    module = "cgu_keeps_identical_fn-foo",
+    cfg = "cfail5",
+    kind = "post-lto"
+)]
+#![rustc_expected_cgu_reuse(
+    module = "cgu_keeps_identical_fn-foo",
+    cfg = "cfail6",
+    kind = "post-lto"
+)]
+#![rustc_expected_cgu_reuse(
+    module = "cgu_keeps_identical_fn-bar",
+    cfg = "cfail2",
+    kind = "post-lto"
+)]
+#![rustc_expected_cgu_reuse(
+    module = "cgu_keeps_identical_fn-bar",
+    cfg = "cfail3",
+    kind = "post-lto"
+)]
+#![rustc_expected_cgu_reuse(
+    module = "cgu_keeps_identical_fn-bar",
+    cfg = "cfail5",
+    kind = "post-lto"
+)]
+#![rustc_expected_cgu_reuse(
+    module = "cgu_keeps_identical_fn-bar",
+    cfg = "cfail6",
+    kind = "post-lto"
+)]
 
 mod foo {
 
     // Trivial functions like this one are imported very reliably by ThinLTO.
-    #[cfg(cfail1)]
+    #[cfg(any(cfail1, cfail4))]
     pub fn inlined_fn() -> u32 {
         1234
     }
 
-    #[cfg(not(cfail1))]
+    #[cfg(not(any(cfail1, cfail4)))]
     pub fn inlined_fn() -> u32 {
         1234
     }
diff --git a/src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.diff
new file mode 100644 (file)
index 0000000..3f5f71f
--- /dev/null
@@ -0,0 +1,24 @@
+- // MIR for `align_of` before LowerIntrinsics
++ // MIR for `align_of` after LowerIntrinsics
+  
+  fn align_of() -> usize {
+      let mut _0: usize;                   // return place in scope 0 at $DIR/lower_intrinsics.rs:18:25: 18:30
+  
+      bb0: {
+-         _0 = std::intrinsics::min_align_of::<T>() -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:19:5: 19:42
+-                                          // mir::Constant
+-                                          // + span: $DIR/lower_intrinsics.rs:19:5: 19:40
+-                                          // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::min_align_of::<T>}, val: Value(Scalar(<ZST>)) }
++         _0 = AlignOf(T);                 // scope 0 at $DIR/lower_intrinsics.rs:19:5: 19:42
++         goto -> bb1;                     // scope 0 at $DIR/lower_intrinsics.rs:19:5: 19:42
+      }
+  
+      bb1: {
+          return;                          // scope 0 at $DIR/lower_intrinsics.rs:20:2: 20:2
+      }
+  
+      bb2 (cleanup): {
+          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:18:1: 20:2
+      }
+  }
+  
index f427375e5a624ddbf9d5afd66e973362d980a02e..d9b441a470c1ee921d9a1b1d51b0bf9699d3e853 100644 (file)
 + // MIR for `discriminant` after LowerIntrinsics
   
   fn discriminant(_1: T) -> () {
-      debug t => _1;                       // in scope 0 at $DIR/lower_intrinsics.rs:68:24: 68:25
-      let mut _0: ();                      // return place in scope 0 at $DIR/lower_intrinsics.rs:68:30: 68:30
-      let _2: <T as std::marker::DiscriminantKind>::Discriminant; // in scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45
-      let mut _3: &T;                      // in scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44
-      let _4: &T;                          // in scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44
-      let _5: u8;                          // in scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45
-      let mut _6: &i32;                    // in scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
-      let _7: &i32;                        // in scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
-      let _8: i32;                         // in scope 0 at $DIR/lower_intrinsics.rs:70:43: 70:44
-      let _9: u8;                          // in scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46
-      let mut _10: &();                    // in scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
-      let _11: &();                        // in scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
-      let _12: ();                         // in scope 0 at $DIR/lower_intrinsics.rs:71:43: 71:45
-      let _13: isize;                      // in scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48
-      let mut _14: &E;                     // in scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
-      let _15: &E;                         // in scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
-      let _16: E;                          // in scope 0 at $DIR/lower_intrinsics.rs:72:43: 72:47
-      let mut _17: &E;                     // in scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
-      let mut _18: &();                    // in scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
-      let mut _19: &i32;                   // in scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
+      debug t => _1;                       // in scope 0 at $DIR/lower_intrinsics.rs:73:24: 73:25
+      let mut _0: ();                      // return place in scope 0 at $DIR/lower_intrinsics.rs:73:30: 73:30
+      let _2: <T as std::marker::DiscriminantKind>::Discriminant; // in scope 0 at $DIR/lower_intrinsics.rs:74:5: 74:45
+      let mut _3: &T;                      // in scope 0 at $DIR/lower_intrinsics.rs:74:42: 74:44
+      let _4: &T;                          // in scope 0 at $DIR/lower_intrinsics.rs:74:42: 74:44
+      let _5: u8;                          // in scope 0 at $DIR/lower_intrinsics.rs:75:5: 75:45
+      let mut _6: &i32;                    // in scope 0 at $DIR/lower_intrinsics.rs:75:42: 75:44
+      let _7: &i32;                        // in scope 0 at $DIR/lower_intrinsics.rs:75:42: 75:44
+      let _8: i32;                         // in scope 0 at $DIR/lower_intrinsics.rs:75:43: 75:44
+      let _9: u8;                          // in scope 0 at $DIR/lower_intrinsics.rs:76:5: 76:46
+      let mut _10: &();                    // in scope 0 at $DIR/lower_intrinsics.rs:76:42: 76:45
+      let _11: &();                        // in scope 0 at $DIR/lower_intrinsics.rs:76:42: 76:45
+      let _12: ();                         // in scope 0 at $DIR/lower_intrinsics.rs:76:43: 76:45
+      let _13: isize;                      // in scope 0 at $DIR/lower_intrinsics.rs:77:5: 77:48
+      let mut _14: &E;                     // in scope 0 at $DIR/lower_intrinsics.rs:77:42: 77:47
+      let _15: &E;                         // in scope 0 at $DIR/lower_intrinsics.rs:77:42: 77:47
+      let _16: E;                          // in scope 0 at $DIR/lower_intrinsics.rs:77:43: 77:47
+      let mut _17: &E;                     // in scope 0 at $DIR/lower_intrinsics.rs:77:42: 77:47
+      let mut _18: &();                    // in scope 0 at $DIR/lower_intrinsics.rs:76:42: 76:45
+      let mut _19: &i32;                   // in scope 0 at $DIR/lower_intrinsics.rs:75:42: 75:44
   
       bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45
-          StorageLive(_3);                 // scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44
-          StorageLive(_4);                 // scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44
-          _4 = &_1;                        // scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44
-          _3 = &(*_4);                     // scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44
--         _2 = discriminant_value::<T>(move _3) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45
+          StorageLive(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:74:5: 74:45
+          StorageLive(_3);                 // scope 0 at $DIR/lower_intrinsics.rs:74:42: 74:44
+          StorageLive(_4);                 // scope 0 at $DIR/lower_intrinsics.rs:74:42: 74:44
+          _4 = &_1;                        // scope 0 at $DIR/lower_intrinsics.rs:74:42: 74:44
+          _3 = &(*_4);                     // scope 0 at $DIR/lower_intrinsics.rs:74:42: 74:44
+-         _2 = discriminant_value::<T>(move _3) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:74:5: 74:45
 -                                          // mir::Constant
--                                          // + span: $DIR/lower_intrinsics.rs:69:5: 69:41
+-                                          // + span: $DIR/lower_intrinsics.rs:74:5: 74:41
 -                                          // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r T) -> <T as std::marker::DiscriminantKind>::Discriminant {std::intrinsics::discriminant_value::<T>}, val: Value(Scalar(<ZST>)) }
-+         _2 = discriminant((*_3));        // scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45
-+         goto -> bb1;                     // scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45
++         _2 = discriminant((*_3));        // scope 0 at $DIR/lower_intrinsics.rs:74:5: 74:45
++         goto -> bb1;                     // scope 0 at $DIR/lower_intrinsics.rs:74:5: 74:45
       }
   
       bb1: {
-          StorageDead(_3);                 // scope 0 at $DIR/lower_intrinsics.rs:69:44: 69:45
-          StorageDead(_4);                 // scope 0 at $DIR/lower_intrinsics.rs:69:45: 69:46
-          StorageDead(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:69:45: 69:46
-          StorageLive(_5);                 // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45
-          StorageLive(_6);                 // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
-          StorageLive(_7);                 // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
-          _19 = const discriminant::<T>::promoted[2]; // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
+          StorageDead(_3);                 // scope 0 at $DIR/lower_intrinsics.rs:74:44: 74:45
+          StorageDead(_4);                 // scope 0 at $DIR/lower_intrinsics.rs:74:45: 74:46
+          StorageDead(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:74:45: 74:46
+          StorageLive(_5);                 // scope 0 at $DIR/lower_intrinsics.rs:75:5: 75:45
+          StorageLive(_6);                 // scope 0 at $DIR/lower_intrinsics.rs:75:42: 75:44
+          StorageLive(_7);                 // scope 0 at $DIR/lower_intrinsics.rs:75:42: 75:44
+          _19 = const discriminant::<T>::promoted[2]; // scope 0 at $DIR/lower_intrinsics.rs:75:42: 75:44
                                            // ty::Const
                                            // + ty: &i32
                                            // + val: Unevaluated(discriminant, [T], Some(promoted[2]))
                                            // mir::Constant
-                                           // + span: $DIR/lower_intrinsics.rs:70:42: 70:44
-                                           // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[2872]::discriminant), const_param_did: None }, substs_: Some([T]), promoted: Some(promoted[2]) }) }
-          _7 = &(*_19);                    // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
-          _6 = &(*_7);                     // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
--         _5 = discriminant_value::<i32>(move _6) -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45
+                                           // + span: $DIR/lower_intrinsics.rs:75:42: 75:44
+                                           // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:29 ~ lower_intrinsics[2872]::discriminant), const_param_did: None }, substs_: Some([T]), promoted: Some(promoted[2]) }) }
+          _7 = &(*_19);                    // scope 0 at $DIR/lower_intrinsics.rs:75:42: 75:44
+          _6 = &(*_7);                     // scope 0 at $DIR/lower_intrinsics.rs:75:42: 75:44
+-         _5 = discriminant_value::<i32>(move _6) -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:75:5: 75:45
 -                                          // mir::Constant
--                                          // + span: $DIR/lower_intrinsics.rs:70:5: 70:41
+-                                          // + span: $DIR/lower_intrinsics.rs:75:5: 75:41
 -                                          // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r i32) -> <i32 as std::marker::DiscriminantKind>::Discriminant {std::intrinsics::discriminant_value::<i32>}, val: Value(Scalar(<ZST>)) }
-+         _5 = discriminant((*_6));        // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45
-+         goto -> bb2;                     // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45
++         _5 = discriminant((*_6));        // scope 0 at $DIR/lower_intrinsics.rs:75:5: 75:45
++         goto -> bb2;                     // scope 0 at $DIR/lower_intrinsics.rs:75:5: 75:45
       }
   
       bb2: {
-          StorageDead(_6);                 // scope 0 at $DIR/lower_intrinsics.rs:70:44: 70:45
-          StorageDead(_7);                 // scope 0 at $DIR/lower_intrinsics.rs:70:45: 70:46
-          StorageDead(_5);                 // scope 0 at $DIR/lower_intrinsics.rs:70:45: 70:46
-          StorageLive(_9);                 // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46
-          StorageLive(_10);                // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
-          StorageLive(_11);                // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
-          _18 = const discriminant::<T>::promoted[1]; // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
+          StorageDead(_6);                 // scope 0 at $DIR/lower_intrinsics.rs:75:44: 75:45
+          StorageDead(_7);                 // scope 0 at $DIR/lower_intrinsics.rs:75:45: 75:46
+          StorageDead(_5);                 // scope 0 at $DIR/lower_intrinsics.rs:75:45: 75:46
+          StorageLive(_9);                 // scope 0 at $DIR/lower_intrinsics.rs:76:5: 76:46
+          StorageLive(_10);                // scope 0 at $DIR/lower_intrinsics.rs:76:42: 76:45
+          StorageLive(_11);                // scope 0 at $DIR/lower_intrinsics.rs:76:42: 76:45
+          _18 = const discriminant::<T>::promoted[1]; // scope 0 at $DIR/lower_intrinsics.rs:76:42: 76:45
                                            // ty::Const
                                            // + ty: &()
                                            // + val: Unevaluated(discriminant, [T], Some(promoted[1]))
                                            // mir::Constant
-                                           // + span: $DIR/lower_intrinsics.rs:71:42: 71:45
-                                           // + literal: Const { ty: &(), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[2872]::discriminant), const_param_did: None }, substs_: Some([T]), promoted: Some(promoted[1]) }) }
-          _11 = &(*_18);                   // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
-          _10 = &(*_11);                   // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
--         _9 = discriminant_value::<()>(move _10) -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46
+                                           // + span: $DIR/lower_intrinsics.rs:76:42: 76:45
+                                           // + literal: Const { ty: &(), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:29 ~ lower_intrinsics[2872]::discriminant), const_param_did: None }, substs_: Some([T]), promoted: Some(promoted[1]) }) }
+          _11 = &(*_18);                   // scope 0 at $DIR/lower_intrinsics.rs:76:42: 76:45
+          _10 = &(*_11);                   // scope 0 at $DIR/lower_intrinsics.rs:76:42: 76:45
+-         _9 = discriminant_value::<()>(move _10) -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:76:5: 76:46
 -                                          // mir::Constant
--                                          // + span: $DIR/lower_intrinsics.rs:71:5: 71:41
+-                                          // + span: $DIR/lower_intrinsics.rs:76:5: 76:41
 -                                          // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r ()) -> <() as std::marker::DiscriminantKind>::Discriminant {std::intrinsics::discriminant_value::<()>}, val: Value(Scalar(<ZST>)) }
-+         _9 = discriminant((*_10));       // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46
-+         goto -> bb3;                     // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46
++         _9 = discriminant((*_10));       // scope 0 at $DIR/lower_intrinsics.rs:76:5: 76:46
++         goto -> bb3;                     // scope 0 at $DIR/lower_intrinsics.rs:76:5: 76:46
       }
   
       bb3: {
-          StorageDead(_10);                // scope 0 at $DIR/lower_intrinsics.rs:71:45: 71:46
-          StorageDead(_11);                // scope 0 at $DIR/lower_intrinsics.rs:71:46: 71:47
-          StorageDead(_9);                 // scope 0 at $DIR/lower_intrinsics.rs:71:46: 71:47
-          StorageLive(_13);                // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48
-          StorageLive(_14);                // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
-          StorageLive(_15);                // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
-          _17 = const discriminant::<T>::promoted[0]; // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
+          StorageDead(_10);                // scope 0 at $DIR/lower_intrinsics.rs:76:45: 76:46
+          StorageDead(_11);                // scope 0 at $DIR/lower_intrinsics.rs:76:46: 76:47
+          StorageDead(_9);                 // scope 0 at $DIR/lower_intrinsics.rs:76:46: 76:47
+          StorageLive(_13);                // scope 0 at $DIR/lower_intrinsics.rs:77:5: 77:48
+          StorageLive(_14);                // scope 0 at $DIR/lower_intrinsics.rs:77:42: 77:47
+          StorageLive(_15);                // scope 0 at $DIR/lower_intrinsics.rs:77:42: 77:47
+          _17 = const discriminant::<T>::promoted[0]; // scope 0 at $DIR/lower_intrinsics.rs:77:42: 77:47
                                            // ty::Const
                                            // + ty: &E
                                            // + val: Unevaluated(discriminant, [T], Some(promoted[0]))
                                            // mir::Constant
-                                           // + span: $DIR/lower_intrinsics.rs:72:42: 72:47
-                                           // + literal: Const { ty: &E, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[2872]::discriminant), const_param_did: None }, substs_: Some([T]), promoted: Some(promoted[0]) }) }
-          _15 = &(*_17);                   // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
-          _14 = &(*_15);                   // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
--         _13 = discriminant_value::<E>(move _14) -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48
+                                           // + span: $DIR/lower_intrinsics.rs:77:42: 77:47
+                                           // + literal: Const { ty: &E, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:29 ~ lower_intrinsics[2872]::discriminant), const_param_did: None }, substs_: Some([T]), promoted: Some(promoted[0]) }) }
+          _15 = &(*_17);                   // scope 0 at $DIR/lower_intrinsics.rs:77:42: 77:47
+          _14 = &(*_15);                   // scope 0 at $DIR/lower_intrinsics.rs:77:42: 77:47
+-         _13 = discriminant_value::<E>(move _14) -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:77:5: 77:48
 -                                          // mir::Constant
--                                          // + span: $DIR/lower_intrinsics.rs:72:5: 72:41
+-                                          // + span: $DIR/lower_intrinsics.rs:77:5: 77:41
 -                                          // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r E) -> <E as std::marker::DiscriminantKind>::Discriminant {std::intrinsics::discriminant_value::<E>}, val: Value(Scalar(<ZST>)) }
-+         _13 = discriminant((*_14));      // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48
-+         goto -> bb4;                     // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48
++         _13 = discriminant((*_14));      // scope 0 at $DIR/lower_intrinsics.rs:77:5: 77:48
++         goto -> bb4;                     // scope 0 at $DIR/lower_intrinsics.rs:77:5: 77:48
       }
   
       bb4: {
-          StorageDead(_14);                // scope 0 at $DIR/lower_intrinsics.rs:72:47: 72:48
-          StorageDead(_15);                // scope 0 at $DIR/lower_intrinsics.rs:72:48: 72:49
-          StorageDead(_13);                // scope 0 at $DIR/lower_intrinsics.rs:72:48: 72:49
-          _0 = const ();                   // scope 0 at $DIR/lower_intrinsics.rs:68:30: 73:2
-          drop(_1) -> bb5;                 // scope 0 at $DIR/lower_intrinsics.rs:73:1: 73:2
+          StorageDead(_14);                // scope 0 at $DIR/lower_intrinsics.rs:77:47: 77:48
+          StorageDead(_15);                // scope 0 at $DIR/lower_intrinsics.rs:77:48: 77:49
+          StorageDead(_13);                // scope 0 at $DIR/lower_intrinsics.rs:77:48: 77:49
+          _0 = const ();                   // scope 0 at $DIR/lower_intrinsics.rs:73:30: 78:2
+          drop(_1) -> bb5;                 // scope 0 at $DIR/lower_intrinsics.rs:78:1: 78:2
       }
   
       bb5: {
-          return;                          // scope 0 at $DIR/lower_intrinsics.rs:73:2: 73:2
+          return;                          // scope 0 at $DIR/lower_intrinsics.rs:78:2: 78:2
       }
   
       bb6 (cleanup): {
-          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:68:1: 73:2
+          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:73:1: 78:2
       }
   }
   
index 380f6ce9ba73ed6ddbf25e400260200ae489e441..2f3fd9ad28565568944a25129191fe1b8b498438 100644 (file)
@@ -1,32 +1,32 @@
 // MIR for `f_u64` before PreCodegen
 
 fn f_u64() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/lower_intrinsics.rs:34:16: 34:16
-    let mut _1: u64;                     // in scope 0 at $DIR/lower_intrinsics.rs:35:5: 35:21
-    scope 1 (inlined f_dispatch::<u64>) { // at $DIR/lower_intrinsics.rs:35:5: 35:21
-        debug t => _1;                   // in scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21
-        let _2: ();                      // in scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21
-        let mut _3: u64;                 // in scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21
-        scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/lower_intrinsics.rs:35:5: 35:21
+    let mut _0: ();                      // return place in scope 0 at $DIR/lower_intrinsics.rs:39:16: 39:16
+    let mut _1: u64;                     // in scope 0 at $DIR/lower_intrinsics.rs:40:5: 40:21
+    scope 1 (inlined f_dispatch::<u64>) { // at $DIR/lower_intrinsics.rs:40:5: 40:21
+        debug t => _1;                   // in scope 1 at $DIR/lower_intrinsics.rs:40:5: 40:21
+        let _2: ();                      // in scope 1 at $DIR/lower_intrinsics.rs:40:5: 40:21
+        let mut _3: u64;                 // in scope 1 at $DIR/lower_intrinsics.rs:40:5: 40:21
+        scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/lower_intrinsics.rs:40:5: 40:21
         }
     }
 
     bb0: {
-        StorageLive(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:35:5: 35:21
-        _1 = const 0_u64;                // scope 0 at $DIR/lower_intrinsics.rs:35:5: 35:21
-        StorageLive(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21
-        StorageLive(_3);                 // scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21
-        _3 = move _1;                    // scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21
-        _2 = f_non_zst::<u64>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21
+        StorageLive(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:40:5: 40:21
+        _1 = const 0_u64;                // scope 0 at $DIR/lower_intrinsics.rs:40:5: 40:21
+        StorageLive(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:40:5: 40:21
+        StorageLive(_3);                 // scope 1 at $DIR/lower_intrinsics.rs:40:5: 40:21
+        _3 = move _1;                    // scope 1 at $DIR/lower_intrinsics.rs:40:5: 40:21
+        _2 = f_non_zst::<u64>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:40:5: 40:21
                                          // mir::Constant
-                                         // + span: $DIR/lower_intrinsics.rs:35:5: 35:21
+                                         // + span: $DIR/lower_intrinsics.rs:40:5: 40:21
                                          // + literal: Const { ty: fn(u64) {f_non_zst::<u64>}, val: Value(Scalar(<ZST>)) }
     }
 
     bb1: {
-        StorageDead(_3);                 // scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21
-        StorageDead(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:35:5: 35:21
-        StorageDead(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:35:5: 35:21
-        return;                          // scope 0 at $DIR/lower_intrinsics.rs:36:2: 36:2
+        StorageDead(_3);                 // scope 1 at $DIR/lower_intrinsics.rs:40:5: 40:21
+        StorageDead(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:40:5: 40:21
+        StorageDead(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:40:5: 40:21
+        return;                          // scope 0 at $DIR/lower_intrinsics.rs:41:2: 41:2
     }
 }
index 2b9ffaaf971087b52fdb34606170765885862268..690405c4748eee5c95874af4eab805865b1e4d74 100644 (file)
@@ -1,27 +1,27 @@
 // MIR for `f_unit` before PreCodegen
 
 fn f_unit() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/lower_intrinsics.rs:28:17: 28:17
-    let mut _1: ();                      // in scope 0 at $DIR/lower_intrinsics.rs:29:16: 29:18
-    scope 1 (inlined f_dispatch::<()>) { // at $DIR/lower_intrinsics.rs:29:5: 29:19
-        debug t => _1;                   // in scope 1 at $DIR/lower_intrinsics.rs:29:5: 29:19
-        let _2: ();                      // in scope 1 at $DIR/lower_intrinsics.rs:29:5: 29:19
-        scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/lower_intrinsics.rs:29:5: 29:19
+    let mut _0: ();                      // return place in scope 0 at $DIR/lower_intrinsics.rs:33:17: 33:17
+    let mut _1: ();                      // in scope 0 at $DIR/lower_intrinsics.rs:34:16: 34:18
+    scope 1 (inlined f_dispatch::<()>) { // at $DIR/lower_intrinsics.rs:34:5: 34:19
+        debug t => _1;                   // in scope 1 at $DIR/lower_intrinsics.rs:34:5: 34:19
+        let _2: ();                      // in scope 1 at $DIR/lower_intrinsics.rs:34:5: 34:19
+        scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/lower_intrinsics.rs:34:5: 34:19
         }
     }
 
     bb0: {
-        StorageLive(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:29:16: 29:18
-        StorageLive(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:29:5: 29:19
-        _2 = f_zst::<()>(const ()) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:29:5: 29:19
+        StorageLive(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:34:16: 34:18
+        StorageLive(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:34:5: 34:19
+        _2 = f_zst::<()>(const ()) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:34:5: 34:19
                                          // mir::Constant
-                                         // + span: $DIR/lower_intrinsics.rs:29:5: 29:19
+                                         // + span: $DIR/lower_intrinsics.rs:34:5: 34:19
                                          // + literal: Const { ty: fn(()) {f_zst::<()>}, val: Value(Scalar(<ZST>)) }
     }
 
     bb1: {
-        StorageDead(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:29:5: 29:19
-        StorageDead(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:29:18: 29:19
-        return;                          // scope 0 at $DIR/lower_intrinsics.rs:30:2: 30:2
+        StorageDead(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:34:5: 34:19
+        StorageDead(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:34:18: 34:19
+        return;                          // scope 0 at $DIR/lower_intrinsics.rs:35:2: 35:2
     }
 }
index 096bba64c0bb882522373957cc04aa07f3df9440..7e1e066366c1151b651267536593065507143ed1 100644 (file)
@@ -2,32 +2,32 @@
 + // MIR for `forget` after LowerIntrinsics
   
   fn forget(_1: T) -> () {
-      debug t => _1;                       // in scope 0 at $DIR/lower_intrinsics.rs:18:18: 18:19
-      let mut _0: ();                      // return place in scope 0 at $DIR/lower_intrinsics.rs:18:24: 18:24
-      let mut _2: T;                       // in scope 0 at $DIR/lower_intrinsics.rs:19:30: 19:31
+      debug t => _1;                       // in scope 0 at $DIR/lower_intrinsics.rs:23:18: 23:19
+      let mut _0: ();                      // return place in scope 0 at $DIR/lower_intrinsics.rs:23:24: 23:24
+      let mut _2: T;                       // in scope 0 at $DIR/lower_intrinsics.rs:24:30: 24:31
   
       bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:19:30: 19:31
-          _2 = move _1;                    // scope 0 at $DIR/lower_intrinsics.rs:19:30: 19:31
--         _0 = std::intrinsics::forget::<T>(move _2) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:19:5: 19:32
+          StorageLive(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:24:30: 24:31
+          _2 = move _1;                    // scope 0 at $DIR/lower_intrinsics.rs:24:30: 24:31
+-         _0 = std::intrinsics::forget::<T>(move _2) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:24:5: 24:32
 -                                          // mir::Constant
--                                          // + span: $DIR/lower_intrinsics.rs:19:5: 19:29
+-                                          // + span: $DIR/lower_intrinsics.rs:24:5: 24:29
 -                                          // + literal: Const { ty: extern "rust-intrinsic" fn(T) {std::intrinsics::forget::<T>}, val: Value(Scalar(<ZST>)) }
-+         _0 = const ();                   // scope 0 at $DIR/lower_intrinsics.rs:19:5: 19:32
-+         goto -> bb1;                     // scope 0 at $DIR/lower_intrinsics.rs:19:5: 19:32
++         _0 = const ();                   // scope 0 at $DIR/lower_intrinsics.rs:24:5: 24:32
++         goto -> bb1;                     // scope 0 at $DIR/lower_intrinsics.rs:24:5: 24:32
       }
   
       bb1: {
-          StorageDead(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:19:31: 19:32
-          goto -> bb2;                     // scope 0 at $DIR/lower_intrinsics.rs:20:1: 20:2
+          StorageDead(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:24:31: 24:32
+          goto -> bb2;                     // scope 0 at $DIR/lower_intrinsics.rs:25:1: 25:2
       }
   
       bb2: {
-          return;                          // scope 0 at $DIR/lower_intrinsics.rs:20:2: 20:2
+          return;                          // scope 0 at $DIR/lower_intrinsics.rs:25:2: 25:2
       }
   
       bb3 (cleanup): {
-          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:18:1: 20:2
+          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:23:1: 25:2
       }
   }
   
index 218b1c964334525ac622f6d12fe1ddee158ac905..276227d8c018a0c97387c6c477a8a5bc12329f25 100644 (file)
@@ -2,34 +2,34 @@
 + // MIR for `non_const` after LowerIntrinsics
   
   fn non_const() -> usize {
-      let mut _0: usize;                   // return place in scope 0 at $DIR/lower_intrinsics.rs:55:26: 55:31
-      let _1: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}; // in scope 0 at $DIR/lower_intrinsics.rs:57:9: 57:18
-      let mut _2: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}; // in scope 0 at $DIR/lower_intrinsics.rs:58:5: 58:14
+      let mut _0: usize;                   // return place in scope 0 at $DIR/lower_intrinsics.rs:60:26: 60:31
+      let _1: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}; // in scope 0 at $DIR/lower_intrinsics.rs:62:9: 62:18
+      let mut _2: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}; // in scope 0 at $DIR/lower_intrinsics.rs:63:5: 63:14
       scope 1 {
-          debug size_of_t => _1;           // in scope 1 at $DIR/lower_intrinsics.rs:57:9: 57:18
+          debug size_of_t => _1;           // in scope 1 at $DIR/lower_intrinsics.rs:62:9: 62:18
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:57:9: 57:18
-          _1 = std::intrinsics::size_of::<T>; // scope 0 at $DIR/lower_intrinsics.rs:57:21: 57:51
+          StorageLive(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:62:9: 62:18
+          _1 = std::intrinsics::size_of::<T>; // scope 0 at $DIR/lower_intrinsics.rs:62:21: 62:51
                                            // mir::Constant
-                                           // + span: $DIR/lower_intrinsics.rs:57:21: 57:51
+                                           // + span: $DIR/lower_intrinsics.rs:62:21: 62:51
                                            // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}, val: Value(Scalar(<ZST>)) }
-          StorageLive(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:58:5: 58:14
-          _2 = _1;                         // scope 1 at $DIR/lower_intrinsics.rs:58:5: 58:14
--         _0 = move _2() -> bb1;           // scope 1 at $DIR/lower_intrinsics.rs:58:5: 58:16
-+         _0 = SizeOf(T);                  // scope 1 at $DIR/lower_intrinsics.rs:58:5: 58:16
-+         goto -> bb1;                     // scope 1 at $DIR/lower_intrinsics.rs:58:5: 58:16
+          StorageLive(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:63:5: 63:14
+          _2 = _1;                         // scope 1 at $DIR/lower_intrinsics.rs:63:5: 63:14
+-         _0 = move _2() -> bb1;           // scope 1 at $DIR/lower_intrinsics.rs:63:5: 63:16
++         _0 = SizeOf(T);                  // scope 1 at $DIR/lower_intrinsics.rs:63:5: 63:16
++         goto -> bb1;                     // scope 1 at $DIR/lower_intrinsics.rs:63:5: 63:16
       }
   
       bb1: {
-          StorageDead(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:58:15: 58:16
-          StorageDead(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:59:1: 59:2
-          return;                          // scope 0 at $DIR/lower_intrinsics.rs:59:2: 59:2
+          StorageDead(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:63:15: 63:16
+          StorageDead(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:64:1: 64:2
+          return;                          // scope 0 at $DIR/lower_intrinsics.rs:64:2: 64:2
       }
   
       bb2 (cleanup): {
-          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:55:1: 59:2
+          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:60:1: 64:2
       }
   }
   
index d9891465dabb743fc4afd282f76549e7b2205f4c..8a8880dad02e5032aab3b7bbad2422ee44f48c65 100644 (file)
@@ -14,6 +14,11 @@ pub fn size_of<T>() -> usize {
     core::intrinsics::size_of::<T>()
 }
 
+// EMIT_MIR lower_intrinsics.align_of.LowerIntrinsics.diff
+pub fn align_of<T>() -> usize {
+    core::intrinsics::min_align_of::<T>()
+}
+
 // EMIT_MIR lower_intrinsics.forget.LowerIntrinsics.diff
 pub fn forget<T>(t: T) {
     core::intrinsics::forget(t)
index a04b79d47d4ce59fe62deaeef8676b98c9b3cae4..50711f574f1c1e597ad88f97b6b033ee763fedcf 100644 (file)
@@ -2,25 +2,25 @@
 + // MIR for `unreachable` after LowerIntrinsics
   
   fn unreachable() -> ! {
-      let mut _0: !;                       // return place in scope 0 at $DIR/lower_intrinsics.rs:23:25: 23:26
-      let mut _1: !;                       // in scope 0 at $DIR/lower_intrinsics.rs:23:27: 25:2
-      let _2: ();                          // in scope 0 at $DIR/lower_intrinsics.rs:24:14: 24:45
-      let mut _3: !;                       // in scope 0 at $DIR/lower_intrinsics.rs:24:14: 24:45
+      let mut _0: !;                       // return place in scope 0 at $DIR/lower_intrinsics.rs:28:25: 28:26
+      let mut _1: !;                       // in scope 0 at $DIR/lower_intrinsics.rs:28:27: 30:2
+      let _2: ();                          // in scope 0 at $DIR/lower_intrinsics.rs:29:14: 29:45
+      let mut _3: !;                       // in scope 0 at $DIR/lower_intrinsics.rs:29:14: 29:45
       scope 1 {
       }
   
       bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:24:5: 24:47
-          StorageLive(_3);                 // scope 1 at $DIR/lower_intrinsics.rs:24:14: 24:45
--         std::intrinsics::unreachable();  // scope 1 at $DIR/lower_intrinsics.rs:24:14: 24:45
+          StorageLive(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:29:5: 29:47
+          StorageLive(_3);                 // scope 1 at $DIR/lower_intrinsics.rs:29:14: 29:45
+-         std::intrinsics::unreachable();  // scope 1 at $DIR/lower_intrinsics.rs:29:14: 29:45
 -                                          // mir::Constant
--                                          // + span: $DIR/lower_intrinsics.rs:24:14: 24:43
+-                                          // + span: $DIR/lower_intrinsics.rs:29:14: 29:43
 -                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> ! {std::intrinsics::unreachable}, val: Value(Scalar(<ZST>)) }
-+         unreachable;                     // scope 1 at $DIR/lower_intrinsics.rs:24:14: 24:45
++         unreachable;                     // scope 1 at $DIR/lower_intrinsics.rs:29:14: 29:45
       }
   
       bb1 (cleanup): {
-          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:23:1: 25:2
+          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:28:1: 30:2
       }
   }
   
index 6d6c2721973f80374c489324889c8d7f2f9fb097..02f6e55a9a8b6b56e098eaa3c01eaf22ebfbee56 100644 (file)
@@ -80,7 +80,7 @@
 -         StorageDead(_7);                 // scope 3 at $DIR/remove_storage_markers.rs:8:18: 8:19
 -         StorageDead(_6);                 // scope 2 at $DIR/remove_storage_markers.rs:10:5: 10:6
 -         StorageDead(_4);                 // scope 1 at $DIR/remove_storage_markers.rs:10:5: 10:6
--         StorageDead(_2);                 // scope 1 at $DIR/remove_storage_markers.rs:8:18: 8:19
+-         StorageDead(_2);                 // scope 1 at $DIR/remove_storage_markers.rs:10:5: 10:6
 -         StorageDead(_1);                 // scope 0 at $DIR/remove_storage_markers.rs:11:1: 11:2
           return;                          // scope 0 at $DIR/remove_storage_markers.rs:11:2: 11:2
       }
index 9ab7cd0fa07b04c4dd2ad746e5380c9884af8e63..10f516d2dae06703003c3a1336ad0da560207867 100644 (file)
@@ -7,3 +7,11 @@ compare-elements-property: (".top-doc .docblock", ".top-doc .docblock > p", ["sc
 assert-property: (".top-doc .docblock", {"scrollWidth": "816"})
 // However, since there is overflow in the <table>, its scroll width is bigger.
 assert-property: (".top-doc .docblock table", {"scrollWidth": "1573"})
+
+// Checking it works on other doc blocks as well...
+
+// Logically, the ".docblock" and the "<p>" should have the same scroll width.
+compare-elements-property: ("#implementations + details .docblock", "#implementations + details .docblock > p", ["scrollWidth"])
+assert-property: ("#implementations + details .docblock", {"scrollWidth": "816"})
+// However, since there is overflow in the <table>, its scroll width is bigger.
+assert-property: ("#implementations + details .docblock table", {"scrollWidth": "1573"})
index cb63a9f60022702881b01a86ac23d0299b5226f0..d5835b78d2fcf17a5d9457c0c9de39a691cd80af 100644 (file)
@@ -67,6 +67,15 @@ pub mod long_table {
     ///
     /// I wanna sqdkfnqds f dsqf qds f dsqf dsq f dsq f qds f qds f qds f dsqq f dsf sqdf dsq fds f dsq f dq f ds fq sd fqds f dsq f sqd fsq df sd fdsqfqsd fdsq f dsq f dsqfd s dfq
     pub struct Foo;
+
+    /// | This::is::a::kinda::very::long::header::number::one | This::is::a::kinda::very::long::header::number::two | This::is::a::kinda::very::long::header::number::one | This::is::a::kinda::very::long::header::number::two |
+    /// | ----------- | ----------- | ----------- | ----------- |
+    /// | This::is::a::kinda::long::content::number::one | This::is::a::kinda::very::long::content::number::two | This::is::a::kinda::long::content::number::one | This::is::a::kinda::very::long::content::number::two |
+    ///
+    /// I wanna sqdkfnqds f dsqf qds f dsqf dsq f dsq f qds f qds f qds f dsqq f dsf sqdf dsq fds f dsq f dq f ds fq sd fqds f dsq f sqd fsq df sd fdsqfqsd fdsq f dsq f dsqfd s dfq
+    impl Foo {
+        pub fn foo(&self) {}
+    }
 }
 
 pub mod summary_table {
index 01e54065189c54e592c4a5281b1c246c896b20b2..1c92d019606b673f056ecd613478c877eb6d8afc 100644 (file)
@@ -2,8 +2,9 @@ const QUERY = 'str,u8';
 
 const EXPECTED = {
     'others': [
-        { 'path': 'std', 'name': 'str' },
-        { 'path': 'std', 'name': 'u8' },
-        { 'path': 'std::ffi', 'name': 'CStr' },
+        { 'path': 'std', 'name': 'str', 'href': '../std/primitive.str.html' },
+        { 'path': 'std', 'name': 'u8', 'href': '../std/primitive.u8.html'  },
+        { 'path': 'std', 'name': 'str', 'href': '../std/str/index.html' },
+        { 'path': 'std', 'name': 'u8', 'href': '../std/u8/index.html' },
     ],
 };
diff --git a/src/test/rustdoc-ui/coverage/enum-tuple-documented.rs b/src/test/rustdoc-ui/coverage/enum-tuple-documented.rs
new file mode 100644 (file)
index 0000000..e9c165b
--- /dev/null
@@ -0,0 +1,37 @@
+// compile-flags:-Z unstable-options --show-coverage
+// check-pass
+
+// The point of this test is to ensure that the number of "documented" items
+// is higher than in `enum-tuple.rs`.
+
+//! (remember the crate root is still a module)
+
+/// so check out this enum here
+pub enum ThisEnum {
+    /// VarOne.
+    VarOne(
+        /// hello!
+        String,
+    ),
+    /// Var Two.
+    VarTwo(
+        /// Hello
+        String,
+        /// Bis repetita.
+        String,
+    ),
+}
+
+/// Struct.
+pub struct ThisStruct(
+    /// hello
+    u32,
+);
+
+/// Struct.
+pub struct ThisStruct2(
+    /// hello
+    u32,
+    /// Bis repetita.
+    u8,
+);
diff --git a/src/test/rustdoc-ui/coverage/enum-tuple-documented.stdout b/src/test/rustdoc-ui/coverage/enum-tuple-documented.stdout
new file mode 100644 (file)
index 0000000..82c98f4
--- /dev/null
@@ -0,0 +1,7 @@
++-------------------------------------+------------+------------+------------+------------+
+| File                                | Documented | Percentage |   Examples | Percentage |
++-------------------------------------+------------+------------+------------+------------+
+| ...overage/enum-tuple-documented.rs |          9 |     100.0% |          0 |       0.0% |
++-------------------------------------+------------+------------+------------+------------+
+| Total                               |          9 |     100.0% |          0 |       0.0% |
++-------------------------------------+------------+------------+------------+------------+
diff --git a/src/test/rustdoc-ui/coverage/enum-tuple.rs b/src/test/rustdoc-ui/coverage/enum-tuple.rs
new file mode 100644 (file)
index 0000000..5fb2054
--- /dev/null
@@ -0,0 +1,18 @@
+// compile-flags:-Z unstable-options --show-coverage
+// check-pass
+
+//! (remember the crate root is still a module)
+
+/// so check out this enum here
+pub enum ThisEnum {
+    /// No need to document the field if there is only one in a tuple variant!
+    VarOne(String),
+    /// But if there is more than one... still fine!
+    VarTwo(String, String),
+}
+
+/// Struct.
+pub struct ThisStruct(u32);
+
+/// Struct.
+pub struct ThisStruct2(u32, u8);
diff --git a/src/test/rustdoc-ui/coverage/enum-tuple.stdout b/src/test/rustdoc-ui/coverage/enum-tuple.stdout
new file mode 100644 (file)
index 0000000..a3377d5
--- /dev/null
@@ -0,0 +1,7 @@
++-------------------------------------+------------+------------+------------+------------+
+| File                                | Documented | Percentage |   Examples | Percentage |
++-------------------------------------+------------+------------+------------+------------+
+| ...ustdoc-ui/coverage/enum-tuple.rs |          6 |     100.0% |          0 |       0.0% |
++-------------------------------------+------------+------------+------------+------------+
+| Total                               |          6 |     100.0% |          0 |       0.0% |
++-------------------------------------+------------+------------+------------+------------+
index 414d60c86d3083b80d9558f659823b01d7ec106a..64c012c1f66e3dfea1eea7a743511b78a08e0f5f 100644 (file)
@@ -1,7 +1,7 @@
 +-------------------------------------+------------+------------+------------+------------+
 | File                                | Documented | Percentage |   Examples | Percentage |
 +-------------------------------------+------------+------------+------------+------------+
-| ...est/rustdoc-ui/coverage/enums.rs |          6 |      66.7% |          0 |       0.0% |
+| ...est/rustdoc-ui/coverage/enums.rs |          6 |      75.0% |          0 |       0.0% |
 +-------------------------------------+------------+------------+------------+------------+
-| Total                               |          6 |      66.7% |          0 |       0.0% |
+| Total                               |          6 |      75.0% |          0 |       0.0% |
 +-------------------------------------+------------+------------+------------+------------+
index 6785cb7abeaee3ea26bc305e606fba6b7a995a90..34e11c7c7b7cf6ca06f7dc47bafb2f7ffcbb5c28 100644 (file)
@@ -37,13 +37,3 @@ pub fn bar() {}
 /// Damn enum's variants: [Enum::A#whatever].
 //~^ ERROR `Enum::A#whatever` contains an anchor
 pub fn enum_link() {}
-
-/// Primitives?
-///
-/// [u32#hello]
-//~^ ERROR `u32#hello` contains an anchor
-pub fn x() {}
-
-/// [prim@usize#x]
-//~^ ERROR `prim@usize#x` contains an anchor
-pub mod usize {}
index d63e1ee60b3c5754db791ac38ed27345a59ee1bc..0d226b277535ce047702b5690a8e3645d099fb59 100644 (file)
@@ -1,19 +1,3 @@
-error: `prim@usize#x` contains an anchor, but links to builtin types are already anchored
-  --> $DIR/anchors.rs:47:6
-   |
-LL | /// [prim@usize#x]
-   |      ^^^^^^^^^^--
-   |                |
-   |                invalid anchor
-   |
-note: the lint level is defined here
-  --> $DIR/anchors.rs:1:9
-   |
-LL | #![deny(rustdoc::broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: this restriction may be lifted in a future release
-   = note: see https://github.com/rust-lang/rust/issues/83083 for more information
-
 error: `Foo::f#hola` contains an anchor, but links to fields are already anchored
   --> $DIR/anchors.rs:25:15
    |
@@ -21,6 +5,12 @@ LL | /// Or maybe [Foo::f#hola].
    |               ^^^^^^-----
    |                     |
    |                     invalid anchor
+   |
+note: the lint level is defined here
+  --> $DIR/anchors.rs:1:9
+   |
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `hello#people#!` contains multiple anchors
   --> $DIR/anchors.rs:31:28
@@ -38,16 +28,5 @@ LL | /// Damn enum's variants: [Enum::A#whatever].
    |                                   |
    |                                   invalid anchor
 
-error: `u32#hello` contains an anchor, but links to builtin types are already anchored
-  --> $DIR/anchors.rs:43:6
-   |
-LL | /// [u32#hello]
-   |      ^^^------
-   |         |
-   |         invalid anchor
-   |
-   = note: this restriction may be lifted in a future release
-   = note: see https://github.com/rust-lang/rust/issues/83083 for more information
-
-error: aborting due to 5 previous errors
+error: aborting due to 3 previous errors
 
index 83cc31b587c29674b9f96ab96a4c89979ce8b3cc..695fa58ef1d55e500eae3c71fabe2f545cfb15be 100644 (file)
@@ -1,6 +1,15 @@
+// no-prefer-dynamic
 // compile-flags: -Cmetadata=aux
-
+#![crate_type = "rlib"]
 #![doc(html_root_url = "http://example.com/")]
+#![feature(lang_items)]
+#![no_std]
+
+#[lang = "eh_personality"]
+fn foo() {}
+
+#[panic_handler]
+fn bar(_: &core::panic::PanicInfo) -> ! { loop {} }
 
 /// dox
 #[doc(primitive = "pointer")]
index a5b69740dd447c9e99944eafb0d4ad278f4e5de8..e8da852a57e631fd32a5938a7a2e4c939e3a36d7 100644 (file)
@@ -1,5 +1,8 @@
 // compile-flags: --crate-type lib --edition 2018
 
+#![feature(no_core)]
+#![no_core]
+
 #[doc(primitive = "usize")]
 /// This is the built-in type `usize`.
 mod usize {
index 05376e4680ec4d5477ba8667835a3ce4baa1f213..120b6e9747f4aef1f8f1da144f5e6365f38b6dd0 100644 (file)
@@ -1,9 +1,13 @@
 // aux-build:primitive-doc.rs
 // compile-flags: --extern-html-root-url=primitive_doc=../ -Z unstable-options
+// ignore-windows
 
-#![no_std]
+#![feature(no_core)]
+#![no_core]
 
 extern crate primitive_doc;
 
 // @has 'cross_crate_primitive_doc/fn.foo.html' '//a[@href="../primitive_doc/primitive.usize.html"]' 'usize'
+// @has 'cross_crate_primitive_doc/fn.foo.html' '//a[@href="../primitive_doc/primitive.usize.html"]' 'link'
+/// [link](usize)
 pub fn foo() -> usize { 0 }
index 8ec1a7b4f9056381784dda314f1537252061b2bd..3d4c464960bbce203dfe03debacbb40a5317802e 100644 (file)
 ///
 /// To link to [Something#Anchor!]
 pub struct SomeOtherType;
+
+/// Primitives?
+///
+/// [u32#hello]
+// @has anchors/fn.x.html
+// @has - '//a/@href' '{{channel}}/std/primitive.u32.html#hello'
+pub fn x() {}
+
+/// [prim@usize#x]
+// @has anchors/usize/index.html
+// @has - '//a/@href' '{{channel}}/std/primitive.usize.html#x'
+pub mod usize {}
index 54e986be9eccf2b2094796f2e68a9471070a3ebb..92cfd46188b015eba5d86c5d2420b0f976abc562 100644 (file)
@@ -2,6 +2,10 @@
 #![no_core]
 #![crate_type="rlib"]
 
+#[doc(primitive = "char")]
+/// Some char docs
+mod char {}
+
 #[lang = "char"]
 impl char {
     pub fn len_utf8(self) -> usize {
index 9347d7bb42819fed336d62de936f83f16a62276d..5a92a28556eded64fb62281464527a128d3027af 100644 (file)
@@ -9,8 +9,8 @@
 #![crate_type = "rlib"]
 
 // @has prim_methods_external_core/index.html
-// @has - '//*[@id="main"]//a[@href="{{channel}}/std/primitive.char.html"]' 'char'
-// @has - '//*[@id="main"]//a[@href="{{channel}}/std/primitive.char.html#method.len_utf8"]' 'char::len_utf8'
+// @has - '//*[@id="main"]//a[@href="../my_core/primitive.char.html"]' 'char'
+// @has - '//*[@id="main"]//a[@href="../my_core/primitive.char.html#method.len_utf8"]' 'char::len_utf8'
 
 //! A [`char`] and its [`char::len_utf8`].
 
index 124faa9a636ffb9d3b3e979c3a21689b2a5f7b16..cfb3c3842ab161694f954813ddfa9823269ce9bf 100644 (file)
@@ -5,10 +5,13 @@
 
 
 // @has prim_methods_local/index.html
-// @has - '//*[@id="main"]//a[@href="{{channel}}/std/primitive.char.html"]' 'char'
-// @has - '//*[@id="main"]//a[@href="{{channel}}/std/primitive.char.html#method.len_utf8"]' 'char::len_utf8'
+// @has - '//*[@id="main"]//a[@href="primitive.char.html"]' 'char'
+// @has - '//*[@id="main"]//a[@href="primitive.char.html#method.len_utf8"]' 'char::len_utf8'
 
-//! A [`char`] and its [`char::len_utf8`].
+//! A [prim@`char`] and its [`char::len_utf8`].
+
+#[doc(primitive = "char")]
+mod char {}
 
 #[lang = "char"]
 impl char {
index 4744c84b6226db03b33a6b890fdb3e128878d34e..8c47f7ef77e5181e2d88e9d1d58aba86f9682ccf 100644 (file)
@@ -7,8 +7,8 @@
 /// [Self::f]
 /// [Self::MAX]
 // @has intra_link_prim_self/primitive.usize.html
-// @has - '//a[@href="{{channel}}/std/primitive.usize.html#method.f"]' 'Self::f'
-// @has - '//a[@href="{{channel}}/std/primitive.usize.html#associatedconstant.MAX"]' 'Self::MAX'
+// @has - '//a[@href="primitive.usize.html#method.f"]' 'Self::f'
+// @has - '//a[@href="primitive.usize.html#associatedconstant.MAX"]' 'Self::MAX'
 impl usize {
     /// Some docs
     pub fn f() {}
index 2af811ad5bbe8de6b320ab952f7f63be278649e3..f7f5052a36dd34329d3c218c0ad7a2c4fe183e7d 100644 (file)
@@ -1,5 +1,6 @@
 // aux-build:issue-15318.rs
 // ignore-cross-compile
+#![no_std]
 
 extern crate issue_15318;
 
diff --git a/src/test/rustdoc/issue-88600.rs b/src/test/rustdoc/issue-88600.rs
new file mode 100644 (file)
index 0000000..3761805
--- /dev/null
@@ -0,0 +1,34 @@
+// This test ensure that #[doc(hidden)] is applied correctly in enum variant fields.
+
+// Denotes a field which should be hidden.
+pub struct H;
+
+// Denotes a field which should not be hidden (shown).
+pub struct S;
+
+// @has issue_88600/enum.FooEnum.html
+pub enum FooEnum {
+    // @has - '//*[@id="variant.HiddenTupleItem"]//code' 'HiddenTupleItem(_)'
+    // @count - '//*[@id="variant.HiddenTupleItem.field.0"]' 0
+    HiddenTupleItem(#[doc(hidden)] H),
+    // @has - '//*[@id="variant.MultipleHidden"]//code' 'MultipleHidden(_, _)'
+    // @count - '//*[@id="variant.MultipleHidden.field.0"]' 0
+    // @count - '//*[@id="variant.MultipleHidden.field.1"]' 0
+    MultipleHidden(#[doc(hidden)] H, #[doc(hidden)] H),
+    // @has - '//*[@id="variant.MixedHiddenFirst"]//code' 'MixedHiddenFirst(_, S)'
+    // @count - '//*[@id="variant.MixedHiddenFirst.field.0"]' 0
+    // @has - '//*[@id="variant.MixedHiddenFirst.field.1"]' '1: S'
+    MixedHiddenFirst(#[doc(hidden)] H, S),
+    // @has - '//*[@id="variant.MixedHiddenLast"]//code' 'MixedHiddenLast(S, _)'
+    // @has - '//*[@id="variant.MixedHiddenLast.field.0"]' '0: S'
+    // @count - '//*[@id="variant.MixedHiddenLast.field.1"]' 0
+    MixedHiddenLast(S, #[doc(hidden)] H),
+    // @has - '//*[@id="variant.HiddenStruct"]//code' 'HiddenStruct'
+    // @count - '//*[@id="variant.HiddenStruct.field.h"]' 0
+    // @has - '//*[@id="variant.HiddenStruct.field.s"]' 's: S'
+    HiddenStruct {
+        #[doc(hidden)]
+        h: H,
+        s: S,
+    },
+}
diff --git a/src/test/rustdoc/no_std-primitive.rs b/src/test/rustdoc/no_std-primitive.rs
new file mode 100644 (file)
index 0000000..22fd392
--- /dev/null
@@ -0,0 +1,6 @@
+#![no_std]
+
+/// Link to [intra-doc link][u8]
+// @has 'no_std_primitive/fn.foo.html' '//a[@href="{{channel}}/core/primitive.u8.html"]' 'intra-doc link'
+// @has - '//a[@href="{{channel}}/core/primitive.u8.html"]' 'u8'
+pub fn foo() -> u8 {}
diff --git a/src/test/rustdoc/primitive/no_std.rs b/src/test/rustdoc/primitive/no_std.rs
new file mode 100644 (file)
index 0000000..f0f70cb
--- /dev/null
@@ -0,0 +1,16 @@
+#![no_std]
+#![deny(warnings)]
+#![deny(rustdoc::broken_intra_doc_links)]
+
+// @has no_std/fn.foo.html '//a/[@href="{{channel}}/core/primitive.u8.html"]' 'u8'
+// @has no_std/fn.foo.html '//a/[@href="{{channel}}/core/primitive.u8.html"]' 'primitive link'
+/// Link to [primitive link][u8]
+pub fn foo() -> u8 {}
+
+// Test that all primitives can be linked to.
+/// [isize] [i8] [i16] [i32] [i64] [i128]
+/// [usize] [u8] [u16] [u32] [u64] [u128]
+/// [f32] [f64]
+/// [char] [bool] [str] [slice] [array] [tuple] [unit]
+/// [pointer] [reference] [fn] [never]
+pub fn bar() {}
index f727c9a47f2687095f84cf8929affbc71a57a515..16ab876e829ef8f25f4d82d79529e4c89c84f3ca 100644 (file)
@@ -10,7 +10,7 @@ unsafe impl<T> Send for Inner<T>
 
 // @has no_redundancy/struct.Outer.html
 // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
-// "impl<T> Send for Outer<T> where T: Copy + Send"
+// "impl<T> Send for Outer<T> where T: Send + Copy"
 pub struct Outer<T> {
     inner_field: Inner<T>,
 }
diff --git a/src/test/rustdoc/table-in-docblock.rs b/src/test/rustdoc/table-in-docblock.rs
new file mode 100644 (file)
index 0000000..858b589
--- /dev/null
@@ -0,0 +1,16 @@
+#![crate_name = "foo"]
+
+// @has foo/struct.Foo.html
+// @count - '//*[@class="docblock"]/div/table' 2
+// @!has - '//*[@class="docblock"]/table'
+/// | hello | hello2 |
+/// | ----- | ------ |
+/// | data  | data2  |
+pub struct Foo;
+
+impl Foo {
+    /// | hello | hello2 |
+    /// | ----- | ------ |
+    /// | data  | data2  |
+    pub fn foo(&self) {}
+}
index 12236960179e9f57c9fb9b8501031eebfeee7255..4d8022ecba73c5d3744a31d1ffd3f8ed298e1ec3 100644 (file)
@@ -2,6 +2,7 @@
 
 // Test binary_search_by_key lifetime. Issue #34683
 
+#[allow(dead_code)]
 #[derive(Debug)]
 struct Assignment {
     topic: String,
index 3ec3c72d38d72c53277581d6267fdaf353e898db..fa14c52cf0ad7f9fcd43549989d2bbf52d14b4e1 100644 (file)
@@ -76,6 +76,12 @@ fn main() {
         //~^ ERROR asm template must be a string literal
         asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar);
         //~^ ERROR asm template must be a string literal
+        asm!("{}", in(reg) _);
+        //~^ ERROR _ cannot be used for input operands
+        asm!("{}", inout(reg) _);
+        //~^ ERROR _ cannot be used for input operands
+        asm!("{}", inlateout(reg) _);
+        //~^ ERROR _ cannot be used for input operands
     }
 }
 
index 423003c99d42c93fd4fe759a85312e059c040965..78d342cc1daf79f6fbf455b234501276d0a83858 100644 (file)
@@ -214,62 +214,80 @@ LL |         asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar);
    |
    = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
 
+error: _ cannot be used for input operands
+  --> $DIR/parse-error.rs:79:28
+   |
+LL |         asm!("{}", in(reg) _);
+   |                            ^
+
+error: _ cannot be used for input operands
+  --> $DIR/parse-error.rs:81:31
+   |
+LL |         asm!("{}", inout(reg) _);
+   |                               ^
+
+error: _ cannot be used for input operands
+  --> $DIR/parse-error.rs:83:35
+   |
+LL |         asm!("{}", inlateout(reg) _);
+   |                                   ^
+
 error: requires at least a template string argument
-  --> $DIR/parse-error.rs:84:1
+  --> $DIR/parse-error.rs:90:1
    |
 LL | global_asm!();
    | ^^^^^^^^^^^^^^
 
 error: asm template must be a string literal
-  --> $DIR/parse-error.rs:86:13
+  --> $DIR/parse-error.rs:92:13
    |
 LL | global_asm!(FOO);
    |             ^^^
 
 error: expected token: `,`
-  --> $DIR/parse-error.rs:88:18
+  --> $DIR/parse-error.rs:94:18
    |
 LL | global_asm!("{}" FOO);
    |                  ^^^ expected `,`
 
 error: expected operand, options, or additional template string
-  --> $DIR/parse-error.rs:90:19
+  --> $DIR/parse-error.rs:96:19
    |
 LL | global_asm!("{}", FOO);
    |                   ^^^ expected operand, options, or additional template string
 
 error: expected expression, found end of macro arguments
-  --> $DIR/parse-error.rs:92:24
+  --> $DIR/parse-error.rs:98:24
    |
 LL | global_asm!("{}", const);
    |                        ^ expected expression
 
 error: expected one of `,`, `.`, `?`, or an operator, found `FOO`
-  --> $DIR/parse-error.rs:94:30
+  --> $DIR/parse-error.rs:100:30
    |
 LL | global_asm!("{}", const(reg) FOO);
    |                              ^^^ expected one of `,`, `.`, `?`, or an operator
 
 error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
-  --> $DIR/parse-error.rs:96:25
+  --> $DIR/parse-error.rs:102:25
    |
 LL | global_asm!("", options(FOO));
    |                         ^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
-  --> $DIR/parse-error.rs:98:25
+  --> $DIR/parse-error.rs:104:25
    |
 LL | global_asm!("", options(nomem FOO));
    |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
-  --> $DIR/parse-error.rs:100:25
+  --> $DIR/parse-error.rs:106:25
    |
 LL | global_asm!("", options(nomem, FOO));
    |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: arguments are not allowed after options
-  --> $DIR/parse-error.rs:102:30
+  --> $DIR/parse-error.rs:108:30
    |
 LL | global_asm!("{}", options(), const FOO);
    |                   ---------  ^^^^^^^^^ argument
@@ -277,25 +295,25 @@ LL | global_asm!("{}", options(), const FOO);
    |                   previous options
 
 error: expected string literal
-  --> $DIR/parse-error.rs:104:29
+  --> $DIR/parse-error.rs:110:29
    |
 LL | global_asm!("", clobber_abi(FOO));
    |                             ^^^ not a string literal
 
 error: expected `)`, found `FOO`
-  --> $DIR/parse-error.rs:106:33
+  --> $DIR/parse-error.rs:112:33
    |
 LL | global_asm!("", clobber_abi("C" FOO));
    |                                 ^^^ expected `)`
 
 error: expected `)`, found `,`
-  --> $DIR/parse-error.rs:108:32
+  --> $DIR/parse-error.rs:114:32
    |
 LL | global_asm!("", clobber_abi("C", FOO));
    |                                ^ expected `)`
 
 error: arguments are not allowed after clobber_abi
-  --> $DIR/parse-error.rs:110:37
+  --> $DIR/parse-error.rs:116:37
    |
 LL | global_asm!("{}", clobber_abi("C"), const FOO);
    |                   ----------------  ^^^^^^^^^ argument
@@ -303,13 +321,13 @@ LL | global_asm!("{}", clobber_abi("C"), const FOO);
    |                   clobber_abi
 
 error: `clobber_abi` cannot be used with `global_asm!`
-  --> $DIR/parse-error.rs:110:19
+  --> $DIR/parse-error.rs:116:19
    |
 LL | global_asm!("{}", clobber_abi("C"), const FOO);
    |                   ^^^^^^^^^^^^^^^^
 
 error: clobber_abi is not allowed after options
-  --> $DIR/parse-error.rs:113:28
+  --> $DIR/parse-error.rs:119:28
    |
 LL | global_asm!("", options(), clobber_abi("C"));
    |                 ---------  ^^^^^^^^^^^^^^^^
@@ -317,7 +335,7 @@ LL | global_asm!("", options(), clobber_abi("C"));
    |                 options
 
 error: clobber_abi is not allowed after options
-  --> $DIR/parse-error.rs:115:30
+  --> $DIR/parse-error.rs:121:30
    |
 LL | global_asm!("{}", options(), clobber_abi("C"), const FOO);
    |                   ---------  ^^^^^^^^^^^^^^^^
@@ -325,7 +343,7 @@ LL | global_asm!("{}", options(), clobber_abi("C"), const FOO);
    |                   options
 
 error: clobber_abi specified multiple times
-  --> $DIR/parse-error.rs:117:35
+  --> $DIR/parse-error.rs:123:35
    |
 LL | global_asm!("", clobber_abi("C"), clobber_abi("C"));
    |                 ----------------  ^^^^^^^^^^^^^^^^
@@ -333,7 +351,7 @@ LL | global_asm!("", clobber_abi("C"), clobber_abi("C"));
    |                 clobber_abi previously specified here
 
 error: duplicate argument named `a`
-  --> $DIR/parse-error.rs:119:35
+  --> $DIR/parse-error.rs:125:35
    |
 LL | global_asm!("{a}", a = const FOO, a = const BAR);
    |                    -------------  ^^^^^^^^^^^^^ duplicate argument
@@ -341,7 +359,7 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
    |                    previously here
 
 error: argument never used
-  --> $DIR/parse-error.rs:119:35
+  --> $DIR/parse-error.rs:125:35
    |
 LL | global_asm!("{a}", a = const FOO, a = const BAR);
    |                                   ^^^^^^^^^^^^^ argument never used
@@ -349,19 +367,19 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
 
 error: expected one of `clobber_abi`, `const`, or `options`, found `""`
-  --> $DIR/parse-error.rs:122:28
+  --> $DIR/parse-error.rs:128:28
    |
 LL | global_asm!("", options(), "");
    |                            ^^ expected one of `clobber_abi`, `const`, or `options`
 
 error: expected one of `clobber_abi`, `const`, or `options`, found `"{}"`
-  --> $DIR/parse-error.rs:124:30
+  --> $DIR/parse-error.rs:130:30
    |
 LL | global_asm!("{}", const FOO, "{}", const FOO);
    |                              ^^^^ expected one of `clobber_abi`, `const`, or `options`
 
 error: asm template must be a string literal
-  --> $DIR/parse-error.rs:126:13
+  --> $DIR/parse-error.rs:132:13
    |
 LL | global_asm!(format!("{{{}}}", 0), const FOO);
    |             ^^^^^^^^^^^^^^^^^^^^
@@ -369,7 +387,7 @@ LL | global_asm!(format!("{{{}}}", 0), const FOO);
    = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: asm template must be a string literal
-  --> $DIR/parse-error.rs:128:20
+  --> $DIR/parse-error.rs:134:20
    |
 LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
    |                    ^^^^^^^^^^^^^^^^^^^^
@@ -439,6 +457,6 @@ LL |     let mut bar = 0;
 LL |         asm!("{1}", in("eax") foo, const bar);
    |                                          ^^^ non-constant value
 
-error: aborting due to 63 previous errors
+error: aborting due to 66 previous errors
 
 For more information about this error, try `rustc --explain E0435`.
index e39a049e2d30483e34ea8e9368f49ceff1249acb..0aea56ddb702b0386cec7e45011e04f1c4ec90bd 100644 (file)
@@ -2,9 +2,14 @@ warning: unnecessary parentheses around assigned value
   --> $DIR/issue-54752-async-block.rs:6:22
    |
 LL | fn main() { let _a = (async  { }); }
-   |                      ^^^^^^^^^^^^ help: remove these parentheses
+   |                      ^          ^
    |
    = note: `#[warn(unused_parens)]` on by default
+help: remove these parentheses
+   |
+LL - fn main() { let _a = (async  { }); }
+LL + fn main() { let _a = async  { }; }
+   | 
 
 warning: 1 warning emitted
 
index fd0e346e2b42dee204376dcdd467c13bd0c46037..23ef975cbbca1a8b985f3c2bc77dc27dbd76f9dc 100644 (file)
@@ -1,4 +1,5 @@
 // run-pass
+#![allow(dead_code)]
 #![deny(unused_mut)]
 
 #[derive(Debug)]
diff --git a/src/test/ui/borrowck/issue-82462.nll.stderr b/src/test/ui/borrowck/issue-82462.nll.stderr
new file mode 100644 (file)
index 0000000..10497c3
--- /dev/null
@@ -0,0 +1,22 @@
+error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
+  --> $DIR/issue-82462.rs:18:9
+   |
+LL |     for x in DroppingSlice(&*v).iter() {
+   |              ------------------
+   |              |               |
+   |              |               immutable borrow occurs here
+   |              a temporary with access to the immutable borrow is created here ...
+LL |         v.push(*x);
+   |         ^ mutable borrow occurs here
+LL |         break;
+LL |     }
+   |     - ... and the immutable borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `DroppingSlice`
+   |
+help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
+   |
+LL |     };
+   |      +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0502`.
diff --git a/src/test/ui/borrowck/issue-82462.rs b/src/test/ui/borrowck/issue-82462.rs
new file mode 100644 (file)
index 0000000..5a3c642
--- /dev/null
@@ -0,0 +1,21 @@
+struct DroppingSlice<'a>(&'a [i32]);
+
+impl Drop for DroppingSlice<'_> {
+    fn drop(&mut self) {
+        println!("hi from slice");
+    }
+}
+
+impl DroppingSlice<'_> {
+    fn iter(&self) -> std::slice::Iter<'_, i32> {
+        self.0.iter()
+    }
+}
+
+fn main() {
+    let mut v = vec![1, 2, 3, 4];
+    for x in DroppingSlice(&*v).iter() {
+        v.push(*x); //~ERROR
+        break;
+    }
+}
diff --git a/src/test/ui/borrowck/issue-82462.stderr b/src/test/ui/borrowck/issue-82462.stderr
new file mode 100644 (file)
index 0000000..a2c291f
--- /dev/null
@@ -0,0 +1,22 @@
+error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
+  --> $DIR/issue-82462.rs:18:9
+   |
+LL |     for x in DroppingSlice(&*v).iter() {
+   |              ------------------
+   |              |               |
+   |              |               immutable borrow occurs here
+   |              a temporary with access to the immutable borrow is created here ...
+LL |         v.push(*x);
+   |         ^^^^^^^^^^ mutable borrow occurs here
+LL |         break;
+LL |     }
+   |     - ... and the immutable borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `DroppingSlice`
+   |
+help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
+   |
+LL |     };
+   |      +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0502`.
index 1cc22fac35282217cf9a121bc11222a220e9fa66..3399bc0018e54526e78acde295f432ab094dcdec 100644 (file)
@@ -3,6 +3,7 @@
 // check-pass
 #![allow(unreachable_code)]
 #![warn(unused)]
+#![allow(dead_code)]
 
 #[derive(Debug)]
 struct Point {
index 4eac5a2d282b07b527e6cbe8f3fe0841e57591e2..74109772724a4ddd7f55f4161d2671378f7c7c0d 100644 (file)
@@ -1,5 +1,5 @@
 warning: value captured by `a` is never read
-  --> $DIR/liveness.rs:23:9
+  --> $DIR/liveness.rs:24:9
    |
 LL |         a = 1;
    |         ^
@@ -13,7 +13,7 @@ LL | #![warn(unused)]
    = help: did you mean to capture by reference instead?
 
 warning: unused variable: `a`
-  --> $DIR/liveness.rs:32:9
+  --> $DIR/liveness.rs:33:9
    |
 LL |         a += 1;
    |         ^
@@ -27,7 +27,7 @@ LL | #![warn(unused)]
    = help: did you mean to capture by reference instead?
 
 warning: value assigned to `a` is never read
-  --> $DIR/liveness.rs:52:9
+  --> $DIR/liveness.rs:53:9
    |
 LL |         a += 1;
    |         ^
@@ -35,7 +35,7 @@ LL |         a += 1;
    = help: maybe it is overwritten before being read?
 
 warning: value assigned to `a` is never read
-  --> $DIR/liveness.rs:76:13
+  --> $DIR/liveness.rs:77:13
    |
 LL |             a = Some("d1");
    |             ^
@@ -43,7 +43,7 @@ LL |             a = Some("d1");
    = help: maybe it is overwritten before being read?
 
 warning: value assigned to `b` is never read
-  --> $DIR/liveness.rs:84:13
+  --> $DIR/liveness.rs:85:13
    |
 LL |             b = Some("e1");
    |             ^
@@ -51,7 +51,7 @@ LL |             b = Some("e1");
    = help: maybe it is overwritten before being read?
 
 warning: value assigned to `b` is never read
-  --> $DIR/liveness.rs:86:13
+  --> $DIR/liveness.rs:87:13
    |
 LL |             b = Some("e2");
    |             ^
@@ -59,7 +59,7 @@ LL |             b = Some("e2");
    = help: maybe it is overwritten before being read?
 
 warning: unused variable: `b`
-  --> $DIR/liveness.rs:84:13
+  --> $DIR/liveness.rs:85:13
    |
 LL |             b = Some("e1");
    |             ^
index 10a7d07a1df99937e38e1a7aa4d05a62862f9e4d..465c9476ba65b1636532ab50c9b3650543242747 100644 (file)
@@ -2,6 +2,7 @@
 
 // check-pass
 #![warn(unused)]
+#![allow(dead_code)]
 
 #[derive(Debug)]
 struct MyStruct {
index f74303e3dd682672d8d13cdba48d6669ee40ad9f..11a440554f759b4a60a9ea096cba8eda9746fdfd 100644 (file)
@@ -1,5 +1,5 @@
 warning: value assigned to `a` is never read
-  --> $DIR/liveness_unintentional_copy.rs:19:9
+  --> $DIR/liveness_unintentional_copy.rs:20:9
    |
 LL |         a = s;
    |         ^
@@ -13,7 +13,7 @@ LL | #![warn(unused)]
    = help: maybe it is overwritten before being read?
 
 warning: unused variable: `a`
-  --> $DIR/liveness_unintentional_copy.rs:19:9
+  --> $DIR/liveness_unintentional_copy.rs:20:9
    |
 LL |         a = s;
    |         ^
@@ -27,7 +27,7 @@ LL | #![warn(unused)]
    = help: did you mean to capture by reference instead?
 
 warning: unused variable: `a`
-  --> $DIR/liveness_unintentional_copy.rs:35:9
+  --> $DIR/liveness_unintentional_copy.rs:36:9
    |
 LL |         a += x;
    |         ^
index 045fe78040a922e330fb926908e33ba64ec74f9a..ed222b3148f410c45433e7aa671e1f526707d1d8 100644 (file)
@@ -1,6 +1,7 @@
 // edition:2021
 //check-pass
 #![warn(unused)]
+#![allow(dead_code)]
 #![feature(rustc_attrs)]
 
 #[derive(Debug, Clone, Copy)]
index 8e4f91c27e224d5c82405b91621700c7193fd917..3f7ddf93f0697c821feeccdb47c6a0eccc4da1eb 100644 (file)
@@ -3,6 +3,8 @@
 
 // Test that we can use raw ptrs when using `capture_disjoint_fields`.
 
+#![allow(dead_code)]
+
 #[derive(Debug)]
 struct S {
     s: String,
diff --git a/src/test/ui/coercion/issue-88097.rs b/src/test/ui/coercion/issue-88097.rs
new file mode 100644 (file)
index 0000000..e543e1b
--- /dev/null
@@ -0,0 +1,31 @@
+// In #88097, the compiler attempted to coerce a closure type to itself via
+// a function pointer, which caused an unnecessary error. Check that this
+// behavior has been fixed.
+
+// check-pass
+
+fn peculiar() -> impl Fn(u8) -> u8 {
+    return |x| x + 1
+}
+
+fn peculiar2() -> impl Fn(u8) -> u8 {
+    return |x| x + 1;
+}
+
+fn peculiar3() -> impl Fn(u8) -> u8 {
+    let f = |x| x + 1;
+    return f
+}
+
+fn peculiar4() -> impl Fn(u8) -> u8 {
+    let f = |x| x + 1;
+    f
+}
+
+fn peculiar5() -> impl Fn(u8) -> u8 {
+    let f = |x| x + 1;
+    let g = |x| x + 2;
+    return if true { f } else { g }
+}
+
+fn main() {}
index f9e03151374a2190040f8d4d949c09436db6a90b..9d62281178c48c689b5900ebd0c105255b1420a8 100644 (file)
@@ -1,4 +1,7 @@
 // run-pass
+
+#![allow(dead_code)]
+
 use std::fmt::Debug;
 
 #[derive(Debug)]
diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs b/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs
new file mode 100644 (file)
index 0000000..916d60c
--- /dev/null
@@ -0,0 +1,11 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+fn foo<const N: u8>(a: [(); N as usize]) {
+    bar::<{ N as usize as usize }>();
+    //~^ error: unconstrained generic constant
+}
+
+fn bar<const N: usize>() {}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr
new file mode 100644 (file)
index 0000000..d48b639
--- /dev/null
@@ -0,0 +1,10 @@
+error: unconstrained generic constant
+  --> $DIR/abstract-consts-as-cast-5.rs:5:11
+   |
+LL |     bar::<{ N as usize as usize }>();
+   |           ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); { N as usize as usize }]:`
+
+error: aborting due to previous error
+
index deb6f3bd12c1dfd7e558c361831298977299a1c3..9b3c32a93977906a7900691bc744ffb3c7fc4a7e 100644 (file)
@@ -10,7 +10,7 @@ error: overly complex generic constant
   --> $DIR/array-size-in-generic-struct-param.rs:19:15
    |
 LL |     arr: [u8; CFG.arr_size],
-   |               ^^^^^^^^^^^^ unsupported projection
+   |               ^^^^^^^^^^^^ unsupported operation in generic constant, this may be supported in the future
    |
    = help: consider moving this anonymous constant into a `const` function
 
index 9f0b7252e8326ff2893c633d2ea735670ed8de3c..95dae4ecc0431c50915ae669d481376177510eac 100644 (file)
@@ -4,7 +4,7 @@ error: overly complex generic constant
 LL | fn test<const N: usize>() -> [u8; N + (|| 42)()] {}
    |                                   ^^^^-------^^
    |                                       |
-   |                                       unsupported rvalue
+   |                                       unsupported operation in generic constant, this may be supported in the future
    |
    = help: consider moving this anonymous constant into a `const` function
 
index 5749defb3e12c679227424fb7eef06d8bf66ad61..c9f847995223abd909743e26980a13488c04b7c3 100644 (file)
@@ -2,9 +2,7 @@ error: overly complex generic constant
   --> $DIR/let-bindings.rs:6:68
    |
 LL | fn test<const N: usize>() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default {
-   |                                                                    ^^^^^^-^^^^^^^^^^^^^
-   |                                                                          |
-   |                                                                          unsupported statement
+   |                                                                    ^^^^^^^^^^^^^^^^^^^^ unsupported operation in generic constant, this may be supported in the future
    |
    = help: consider moving this anonymous constant into a `const` function
 
@@ -12,9 +10,7 @@ error: overly complex generic constant
   --> $DIR/let-bindings.rs:6:35
    |
 LL | fn test<const N: usize>() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default {
-   |                                   ^^^^^^-^^^^^^^^^^^^^
-   |                                         |
-   |                                         unsupported statement
+   |                                   ^^^^^^^^^^^^^^^^^^^^ unsupported operation in generic constant, this may be supported in the future
    |
    = help: consider moving this anonymous constant into a `const` function
 
diff --git a/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs b/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs
new file mode 100644 (file)
index 0000000..c0404d3
--- /dev/null
@@ -0,0 +1,35 @@
+#![feature(generic_const_exprs, adt_const_params, const_trait_impl)]
+#![allow(incomplete_features)]
+
+// test `N + N` unifies with explicit function calls for non-builtin-types
+#[derive(PartialEq, Eq)]
+struct Foo(u8);
+
+impl const std::ops::Add for Foo {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self::Output {
+        self
+    }
+}
+
+struct Evaluatable<const N: Foo>;
+
+fn foo<const N: Foo>(a: Evaluatable<{ N + N }>) {
+    bar::<{ std::ops::Add::add(N, N) }>();
+}
+
+fn bar<const N: Foo>() {}
+
+// test that `N + N` unifies with explicit function calls for builin-types
+struct Evaluatable2<const N: usize>;
+
+fn foo2<const N: usize>(a: Evaluatable2<{ N + N }>) {
+    bar2::<{ std::ops::Add::add(N, N) }>();
+    //~^ error: unconstrained generic constant
+    // FIXME(generic_const_exprs) make this not an error
+}
+
+fn bar2<const N: usize>() {}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
new file mode 100644 (file)
index 0000000..d18c791
--- /dev/null
@@ -0,0 +1,10 @@
+error: unconstrained generic constant
+  --> $DIR/unify-op-with-fn-call.rs:28:12
+   |
+LL |     bar2::<{ std::ops::Add::add(N, N) }>();
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); { std::ops::Add::add(N, N) }]:`
+
+error: aborting due to previous error
+
index 1687dbbcbe3f8c3fedef497409a5aec01dfb0586..3da91b19a5ed95c95dc85830599f0972d10a7de3 100644 (file)
@@ -2,9 +2,7 @@ error: overly complex generic constant
   --> $DIR/unused_expr.rs:4:34
    |
 LL | fn add<const N: usize>() -> [u8; { N + 1; 5 }] {
-   |                                  ^^-----^^^^^
-   |                                    |
-   |                                    dead code
+   |                                  ^^^^^^^^^^^^ unsupported operation in generic constant, this may be supported in the future
    |
    = help: consider moving this anonymous constant into a `const` function
 
@@ -12,9 +10,7 @@ error: overly complex generic constant
   --> $DIR/unused_expr.rs:9:34
    |
 LL | fn div<const N: usize>() -> [u8; { N / 1; 5 }] {
-   |                                  ^^-----^^^^^
-   |                                    |
-   |                                    dead code
+   |                                  ^^^^^^^^^^^^ unsupported operation in generic constant, this may be supported in the future
    |
    = help: consider moving this anonymous constant into a `const` function
 
@@ -22,9 +18,7 @@ error: overly complex generic constant
   --> $DIR/unused_expr.rs:16:38
    |
 LL | fn fn_call<const N: usize>() -> [u8; { foo(N); 5 }] {
-   |                                      ^^------^^^^^
-   |                                        |
-   |                                        dead code
+   |                                      ^^^^^^^^^^^^^ unsupported operation in generic constant, this may be supported in the future
    |
    = help: consider moving this anonymous constant into a `const` function
 
index 5386ef56a245a8b1df56bb7e458bbc96dfe4625d..d7b52063dc4db24c8bfea069cb12a9a6b54a15c3 100644 (file)
@@ -2,9 +2,9 @@ error: overly complex generic constant
   --> $DIR/issue-67375.rs:7:17
    |
 LL |     inner: [(); { [|_: &T| {}; 0].len() }],
-   |                 ^^^----------^^^^^^^^^^^^
-   |                    |
-   |                    unsupported rvalue
+   |                 ^^---------------^^^^^^^^
+   |                   |
+   |                   unsupported operation in generic constant
    |
    = help: consider moving this anonymous constant into a `const` function
 
index 118cf447c01e2aefaed3a6f0eef4986570fb875f..fe0351a829220368f24a0aaab9d6f0e40d93f76f 100644 (file)
@@ -5,11 +5,10 @@ LL |       A: [(); {
    |  _____________^
 LL | |
 LL | |         let x: Option<Box<Self>> = None;
-   | |                                    ---- unsupported rvalue
 LL | |
 LL | |         0
 LL | |     }],
-   | |_____^
+   | |_____^ unsupported operation in generic constant, this may be supported in the future
    |
    = help: consider moving this anonymous constant into a `const` function
 
index 5e1bace549241d30e94aa316f457865706e95153..533fcabd418228734b6a9d46dfb121ae6d643a09 100644 (file)
@@ -2,13 +2,18 @@ warning: unnecessary braces around const expression
   --> $DIR/unused_braces.rs:9:14
    |
 LL |     let _: A<{ 7 }>;
-   |              ^^^^^ help: remove these braces
+   |              ^^ ^^
    |
 note: the lint level is defined here
   --> $DIR/unused_braces.rs:3:9
    |
 LL | #![warn(unused_braces)]
    |         ^^^^^^^^^^^^^
+help: remove these braces
+   |
+LL -     let _: A<{ 7 }>;
+LL +     let _: A<7>;
+   | 
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/derives/clone-debug-dead-code.rs b/src/test/ui/derives/clone-debug-dead-code.rs
new file mode 100644 (file)
index 0000000..80e9132
--- /dev/null
@@ -0,0 +1,45 @@
+// Checks that derived implementations of Clone and Debug do not
+// contribute to dead code analysis (issue #84647).
+
+#![forbid(dead_code)]
+
+struct A { f: () }
+//~^ ERROR: field is never read: `f`
+
+#[derive(Clone)]
+struct B { f: () }
+//~^ ERROR: field is never read: `f`
+
+#[derive(Debug)]
+struct C { f: () }
+//~^ ERROR: field is never read: `f`
+
+#[derive(Debug,Clone)]
+struct D { f: () }
+//~^ ERROR: field is never read: `f`
+
+struct E { f: () }
+//~^ ERROR: field is never read: `f`
+// Custom impl, still doesn't read f
+impl Clone for E {
+    fn clone(&self) -> Self {
+        Self { f: () }
+    }
+}
+
+struct F { f: () }
+// Custom impl that actually reads f
+impl Clone for F {
+    fn clone(&self) -> Self {
+        Self { f: self.f }
+    }
+}
+
+fn main() {
+    let _ = A { f: () };
+    let _ = B { f: () };
+    let _ = C { f: () };
+    let _ = D { f: () };
+    let _ = E { f: () };
+    let _ = F { f: () };
+}
diff --git a/src/test/ui/derives/clone-debug-dead-code.stderr b/src/test/ui/derives/clone-debug-dead-code.stderr
new file mode 100644 (file)
index 0000000..226007f
--- /dev/null
@@ -0,0 +1,38 @@
+error: field is never read: `f`
+  --> $DIR/clone-debug-dead-code.rs:6:12
+   |
+LL | struct A { f: () }
+   |            ^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/clone-debug-dead-code.rs:4:11
+   |
+LL | #![forbid(dead_code)]
+   |           ^^^^^^^^^
+
+error: field is never read: `f`
+  --> $DIR/clone-debug-dead-code.rs:10:12
+   |
+LL | struct B { f: () }
+   |            ^^^^^
+
+error: field is never read: `f`
+  --> $DIR/clone-debug-dead-code.rs:14:12
+   |
+LL | struct C { f: () }
+   |            ^^^^^
+
+error: field is never read: `f`
+  --> $DIR/clone-debug-dead-code.rs:18:12
+   |
+LL | struct D { f: () }
+   |            ^^^^^
+
+error: field is never read: `f`
+  --> $DIR/clone-debug-dead-code.rs:21:12
+   |
+LL | struct E { f: () }
+   |            ^^^^^
+
+error: aborting due to 5 previous errors
+
index f6e105555fd9d739e88c7931b242216c6bb27c6b..4374d1594e4655272a53e3ffd9c7961fd430d574 100644 (file)
@@ -1,6 +1,8 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
+#![allow(dead_code)]
+
 #[derive(Clone)]
 struct S<T> {
     foo: (),
index 7b0a1d20260d4565a221c714101386c7a81dfd95..b93cbe5f8b6fd2b15a0a96f9f6467cf315f32af0 100644 (file)
@@ -1,6 +1,8 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
+#![allow(dead_code)]
+
 #[derive(Clone)]
 struct S {
     _int: isize,
index 166f1be55e02afd2d4f55e2cdacdd8113aa40da8..7ad3f03471324e6b179a29a5629c6b44d49e61c8 100644 (file)
@@ -1,6 +1,8 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
+#![allow(dead_code)]
+
 #[derive(Clone)]
 struct S((), ());
 
index 8931e94a4f8d2487e06782c341c38b336f5db6a4..07f91d059735623a416b00b41898211089c05bbb 100644 (file)
@@ -1,4 +1,7 @@
 // run-pass
+
+#![allow(dead_code)]
+
 pub fn main() {
     #[derive(Debug)]
     struct Foo {
diff --git a/src/test/ui/expr/malformed_closure/missing_braces_around_block.fixed b/src/test/ui/expr/malformed_closure/missing_braces_around_block.fixed
new file mode 100644 (file)
index 0000000..c50b9a1
--- /dev/null
@@ -0,0 +1,19 @@
+// This snippet ensures that no attempt to recover on a semicolon instead of
+// comma is made next to a closure body.
+//
+// If this recovery happens, then plenty of errors are emitted. Here, we expect
+// only one error.
+//
+// This is part of issue #88065:
+// https://github.com/rust-lang/rust/issues/88065
+
+// run-rustfix
+
+fn main() {
+    let num = 5;
+    (1..num).reduce(|a, b| {
+        //~^ ERROR: closure bodies that contain statements must be surrounded by braces
+        println!("{}", a);
+        a * b
+    }).unwrap();
+}
diff --git a/src/test/ui/expr/malformed_closure/missing_braces_around_block.rs b/src/test/ui/expr/malformed_closure/missing_braces_around_block.rs
new file mode 100644 (file)
index 0000000..58c81f3
--- /dev/null
@@ -0,0 +1,19 @@
+// This snippet ensures that no attempt to recover on a semicolon instead of
+// comma is made next to a closure body.
+//
+// If this recovery happens, then plenty of errors are emitted. Here, we expect
+// only one error.
+//
+// This is part of issue #88065:
+// https://github.com/rust-lang/rust/issues/88065
+
+// run-rustfix
+
+fn main() {
+    let num = 5;
+    (1..num).reduce(|a, b|
+        //~^ ERROR: closure bodies that contain statements must be surrounded by braces
+        println!("{}", a);
+        a * b
+    ).unwrap();
+}
diff --git a/src/test/ui/expr/malformed_closure/missing_braces_around_block.stderr b/src/test/ui/expr/malformed_closure/missing_braces_around_block.stderr
new file mode 100644 (file)
index 0000000..dac9a8c
--- /dev/null
@@ -0,0 +1,38 @@
+error: closure bodies that contain statements must be surrounded by braces
+  --> $DIR/missing_braces_around_block.rs:14:26
+   |
+LL |     (1..num).reduce(|a, b|
+   |                          ^
+...
+LL |     ).unwrap();
+   |     ^
+   |
+note: statement found outside of a block
+  --> $DIR/missing_braces_around_block.rs:16:26
+   |
+LL |         println!("{}", a);
+   |         -----------------^ this `;` turns the preceding closure into a statement
+   |         |
+   |         this expression is a statement because of the trailing semicolon
+note: the closure body may be incorrectly delimited
+  --> $DIR/missing_braces_around_block.rs:14:21
+   |
+LL |       (1..num).reduce(|a, b|
+   |  _____________________^
+LL | |
+LL | |         println!("{}", a);
+   | |_________________________^ this is the parsed closure...
+LL |           a * b
+LL |       ).unwrap();
+   |       - ...but likely you meant the closure to end here
+help: try adding braces
+   |
+LL ~     (1..num).reduce(|a, b| {
+LL |
+LL |         println!("{}", a);
+LL |         a * b
+LL ~     }).unwrap();
+   |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/expr/malformed_closure/ruby_style_closure.rs b/src/test/ui/expr/malformed_closure/ruby_style_closure.rs
new file mode 100644 (file)
index 0000000..e4341e1
--- /dev/null
@@ -0,0 +1,16 @@
+// Part of issue #27300.
+// The problem here is that ruby-style closures are parsed as blocks whose
+// first statement is a closure. See the issue for more details:
+// https://github.com/rust-lang/rust/issues/27300
+
+// Note: this test represents what the compiler currently emits. The error
+// message will be improved later.
+
+fn main() {
+    let p = Some(45).and_then({
+        //~^ expected a `FnOnce<({integer},)>` closure, found `Option<_>`
+        |x| println!("doubling {}", x);
+        Some(x * 2)
+        //~^ ERROR: cannot find value `x` in this scope
+    });
+}
diff --git a/src/test/ui/expr/malformed_closure/ruby_style_closure.stderr b/src/test/ui/expr/malformed_closure/ruby_style_closure.stderr
new file mode 100644 (file)
index 0000000..99df063
--- /dev/null
@@ -0,0 +1,18 @@
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/ruby_style_closure.rs:13:14
+   |
+LL |         Some(x * 2)
+   |              ^ not found in this scope
+
+error[E0277]: expected a `FnOnce<({integer},)>` closure, found `Option<_>`
+  --> $DIR/ruby_style_closure.rs:10:22
+   |
+LL |     let p = Some(45).and_then({
+   |                      ^^^^^^^^ expected an `FnOnce<({integer},)>` closure, found `Option<_>`
+   |
+   = help: the trait `FnOnce<({integer},)>` is not implemented for `Option<_>`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0425.
+For more information about an error, try `rustc --explain E0277`.
index 01edad00a89f15408d93c5ae018360b569fb16b8..27c135cb7cf82abd5d9a41d7d61576ead8a8ab15 100644 (file)
@@ -15,7 +15,7 @@ impl<T> Foo for Fooy<T> {
     type A<'a> where Self: 'static = (&'a ());
     //~^ ERROR the parameter type `T` may not live long enough
     type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
-    //~^ ERROR lifetime bound not satisfied
+    //~^ ERROR `impl` associated type
     //~| ERROR lifetime bound not satisfied
     type C where Self: Copy = String;
     //~^ ERROR the trait bound `T: Copy` is not satisfied
index 8cf923ca3ac0c4f0763029fc2da03b6f43ccd9ce..73415e0faac88898b8a28fe0958b0154206150f4 100644 (file)
@@ -5,24 +5,16 @@ LL |     type A<'a> where Self: 'static = (&'a ());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `T: 'static`...
-   = note: ...so that the type `Fooy<T>` will meet its required lifetime bounds
+   = note: ...so that the definition in impl matches the definition from the trait
 
-error[E0478]: lifetime bound not satisfied
+error: `impl` associated type signature for `B` doesn't match `trait` associated type signature
   --> $DIR/impl_bounds.rs:17:5
    |
+LL |     type B<'a, 'b> where 'a: 'b;
+   |     ---------------------------- expected
+...
 LL |     type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: lifetime parameter instantiated with the lifetime `'b` as defined on the associated item at 17:16
-  --> $DIR/impl_bounds.rs:17:16
-   |
-LL |     type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
-   |                ^^
-note: but lifetime parameter must outlive the lifetime `'a` as defined on the associated item at 17:12
-  --> $DIR/impl_bounds.rs:17:12
-   |
-LL |     type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
-   |            ^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found
 
 error[E0478]: lifetime bound not satisfied
   --> $DIR/impl_bounds.rs:17:5
index 04cd84b08011c4c0aa56640767816d355081c25b..e1ff772921104a1cc506b48eb784dfdec5fa03f1 100644 (file)
@@ -9,7 +9,7 @@ LL | |     <Left as HasChildrenOf>::T: 'a,
 LL | |     <Right as HasChildrenOf>::T: 'a
    | |                                    - help: consider adding a where clause: `, <Left as HasChildrenOf>::T: 'a`
 LL | |     = Either<&'a Left::T, &'a Right::T>;
-   | |________________________________________^ ...so that the type `<Left as HasChildrenOf>::T` will meet its required lifetime bounds
+   | |________________________________________^ ...so that the definition in impl matches the definition from the trait
 
 error[E0309]: the associated type `<Right as HasChildrenOf>::T` may not live long enough
   --> $DIR/issue-86787.rs:23:5
@@ -22,7 +22,7 @@ LL | |     <Left as HasChildrenOf>::T: 'a,
 LL | |     <Right as HasChildrenOf>::T: 'a
    | |                                    - help: consider adding a where clause: `, <Right as HasChildrenOf>::T: 'a`
 LL | |     = Either<&'a Left::T, &'a Right::T>;
-   | |________________________________________^ ...so that the type `<Right as HasChildrenOf>::T` will meet its required lifetime bounds
+   | |________________________________________^ ...so that the definition in impl matches the definition from the trait
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/generic-associated-types/missing-where-clause-on-trait.rs b/src/test/ui/generic-associated-types/missing-where-clause-on-trait.rs
new file mode 100644 (file)
index 0000000..ad9f2e3
--- /dev/null
@@ -0,0 +1,13 @@
+// check-fail
+
+#![feature(generic_associated_types)]
+
+trait Foo {
+    type Assoc<'a, 'b>;
+}
+impl Foo for () {
+    type Assoc<'a, 'b> where 'a: 'b = ();
+    //~^ `impl` associated type
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/missing-where-clause-on-trait.stderr b/src/test/ui/generic-associated-types/missing-where-clause-on-trait.stderr
new file mode 100644 (file)
index 0000000..0e183c8
--- /dev/null
@@ -0,0 +1,11 @@
+error: `impl` associated type signature for `Assoc` doesn't match `trait` associated type signature
+  --> $DIR/missing-where-clause-on-trait.rs:9:5
+   |
+LL |     type Assoc<'a, 'b>;
+   |     ------------------- expected
+...
+LL |     type Assoc<'a, 'b> where 'a: 'b = ();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/hrtb/issue-88446.rs b/src/test/ui/hrtb/issue-88446.rs
new file mode 100644 (file)
index 0000000..571b853
--- /dev/null
@@ -0,0 +1,35 @@
+// check-pass
+
+trait Yokeable<'a> {
+    type Output: 'a;
+}
+impl<'a> Yokeable<'a> for () {
+    type Output = ();
+}
+
+trait DataMarker<'data> {
+    type Yokeable: for<'a> Yokeable<'a>;
+}
+impl<'data> DataMarker<'data> for () {
+    type Yokeable = ();
+}
+
+struct DataPayload<'data, M>(&'data M);
+
+impl DataPayload<'static, ()> {
+    pub fn map_project_with_capture<M2, T>(
+        _: for<'a> fn(
+            capture: T,
+            std::marker::PhantomData<&'a ()>,
+        ) -> <M2::Yokeable as Yokeable<'a>>::Output,
+    ) -> DataPayload<'static, M2>
+    where
+        M2: DataMarker<'static>,
+    {
+        todo!()
+    }
+}
+
+fn main() {
+    let _: DataPayload<()> = DataPayload::<()>::map_project_with_capture::<_, &()>(|_, _| todo!());
+}
index f66e0a1c07841b6f80ce0767e251abd6a9f42ff2..3970a4155e95c2ec53f4c110a0f347520bc48aed 100644 (file)
@@ -1,4 +1,7 @@
 // run-pass
+
+#![allow(dead_code)]
+
 trait Trait { fn dummy(&self) { } }
 
 #[derive(Debug)]
index 25a90df45613b9b8e2777a9965c2b1b90c46f045..ce3ab6b599864ded9ba9cf5b66316137b0af37da 100644 (file)
@@ -2,9 +2,12 @@ error[E0277]: the size for values of type `dyn Iterator<Item = &'a mut u8>` cann
   --> $DIR/issue-20605.rs:2:17
    |
 LL |     for item in *things { *item = 0 }
-   |                 ^^^^^^^ doesn't have a size known at compile-time
+   |                 ^^^^^^^
+   |                 |
+   |                 expected an implementor of trait `IntoIterator`
+   |                 help: consider mutably borrowing here: `&mut *things`
    |
-   = help: the trait `Sized` is not implemented for `dyn Iterator<Item = &'a mut u8>`
+   = note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
    = note: required because of the requirements on the impl of `IntoIterator` for `dyn Iterator<Item = &'a mut u8>`
 note: required by `into_iter`
   --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
index 408d8d866d862efdfb7989f471d0be0e00aa6dfb..1809e822c54213d4dbdc222bbac07f17d90fbf4b 100644 (file)
@@ -1,5 +1,6 @@
 // run-pass
 #![feature(box_syntax)]
+#![allow(dead_code)]
 
 trait T {
     fn print(&self);
diff --git a/src/test/ui/issues/issue-86865.rs b/src/test/ui/issues/issue-86865.rs
new file mode 100644 (file)
index 0000000..01e0a20
--- /dev/null
@@ -0,0 +1,11 @@
+use std::fmt::Write;
+
+fn main() {
+    println!(b"foo");
+    //~^ ERROR format argument must be a string literal
+    //~| HELP consider removing the leading `b`
+    let mut s = String::new();
+    write!(s, b"foo{}", "bar");
+    //~^ ERROR format argument must be a string literal
+    //~| HELP consider removing the leading `b`
+}
diff --git a/src/test/ui/issues/issue-86865.stderr b/src/test/ui/issues/issue-86865.stderr
new file mode 100644 (file)
index 0000000..eed7553
--- /dev/null
@@ -0,0 +1,18 @@
+error: format argument must be a string literal
+  --> $DIR/issue-86865.rs:4:14
+   |
+LL |     println!(b"foo");
+   |              -^^^^^
+   |              |
+   |              help: consider removing the leading `b`
+
+error: format argument must be a string literal
+  --> $DIR/issue-86865.rs:8:15
+   |
+LL |     write!(s, b"foo{}", "bar");
+   |               -^^^^^^^
+   |               |
+   |               help: consider removing the leading `b`
+
+error: aborting due to 2 previous errors
+
index 9eae7da90047e5ea3e019bf98b83ef9bc80df69f..1d5f9ebb5e5c5e3ba1558e1ab559c4261e347e5b 100644 (file)
@@ -2,109 +2,210 @@ error: unnecessary parentheses around `return` value
   --> $DIR/lint-unnecessary-parens.rs:13:12
    |
 LL |     return (1);
-   |            ^^^ help: remove these parentheses
+   |            ^ ^
    |
 note: the lint level is defined here
   --> $DIR/lint-unnecessary-parens.rs:3:9
    |
 LL | #![deny(unused_parens)]
    |         ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     return (1);
+LL +     return 1;
+   | 
 
 error: unnecessary parentheses around `return` value
   --> $DIR/lint-unnecessary-parens.rs:16:12
    |
 LL |     return (X { y });
-   |            ^^^^^^^^^ help: remove these parentheses
+   |            ^       ^
+   |
+help: remove these parentheses
+   |
+LL -     return (X { y });
+LL +     return X { y };
+   | 
 
 error: unnecessary parentheses around type
   --> $DIR/lint-unnecessary-parens.rs:19:46
    |
 LL | pub fn unused_parens_around_return_type() -> (u32) {
-   |                                              ^^^^^ help: remove these parentheses
+   |                                              ^   ^
+   |
+help: remove these parentheses
+   |
+LL - pub fn unused_parens_around_return_type() -> (u32) {
+LL + pub fn unused_parens_around_return_type() -> u32 {
+   | 
 
 error: unnecessary parentheses around block return value
   --> $DIR/lint-unnecessary-parens.rs:25:9
    |
 LL |         (5)
-   |         ^^^ help: remove these parentheses
+   |         ^ ^
+   |
+help: remove these parentheses
+   |
+LL -         (5)
+LL +         5
+   | 
 
 error: unnecessary parentheses around block return value
   --> $DIR/lint-unnecessary-parens.rs:27:5
    |
 LL |     (5)
-   |     ^^^ help: remove these parentheses
+   |     ^ ^
+   |
+help: remove these parentheses
+   |
+LL -     (5)
+LL +     5
+   | 
 
 error: unnecessary parentheses around assigned value
   --> $DIR/lint-unnecessary-parens.rs:44:31
    |
 LL | pub const CONST_ITEM: usize = (10);
-   |                               ^^^^ help: remove these parentheses
+   |                               ^  ^
+   |
+help: remove these parentheses
+   |
+LL - pub const CONST_ITEM: usize = (10);
+LL + pub const CONST_ITEM: usize = 10;
+   | 
 
 error: unnecessary parentheses around assigned value
   --> $DIR/lint-unnecessary-parens.rs:45:33
    |
 LL | pub static STATIC_ITEM: usize = (10);
-   |                                 ^^^^ help: remove these parentheses
+   |                                 ^  ^
+   |
+help: remove these parentheses
+   |
+LL - pub static STATIC_ITEM: usize = (10);
+LL + pub static STATIC_ITEM: usize = 10;
+   | 
 
 error: unnecessary parentheses around function argument
   --> $DIR/lint-unnecessary-parens.rs:49:9
    |
 LL |     bar((true));
-   |         ^^^^^^ help: remove these parentheses
+   |         ^    ^
+   |
+help: remove these parentheses
+   |
+LL -     bar((true));
+LL +     bar(true);
+   | 
 
 error: unnecessary parentheses around `if` condition
   --> $DIR/lint-unnecessary-parens.rs:51:8
    |
 LL |     if (true) {}
-   |        ^^^^^^ help: remove these parentheses
+   |        ^    ^
+   |
+help: remove these parentheses
+   |
+LL -     if (true) {}
+LL +     if true {}
+   | 
 
 error: unnecessary parentheses around `while` condition
   --> $DIR/lint-unnecessary-parens.rs:52:11
    |
 LL |     while (true) {}
-   |           ^^^^^^ help: remove these parentheses
+   |           ^    ^
+   |
+help: remove these parentheses
+   |
+LL -     while (true) {}
+LL +     while true {}
+   | 
 
 error: unnecessary parentheses around `match` scrutinee expression
   --> $DIR/lint-unnecessary-parens.rs:53:11
    |
 LL |     match (true) {
-   |           ^^^^^^ help: remove these parentheses
+   |           ^    ^
+   |
+help: remove these parentheses
+   |
+LL -     match (true) {
+LL +     match true {
+   | 
 
 error: unnecessary parentheses around `let` scrutinee expression
   --> $DIR/lint-unnecessary-parens.rs:56:16
    |
 LL |     if let 1 = (1) {}
-   |                ^^^ help: remove these parentheses
+   |                ^ ^
+   |
+help: remove these parentheses
+   |
+LL -     if let 1 = (1) {}
+LL +     if let 1 = 1 {}
+   | 
 
 error: unnecessary parentheses around `let` scrutinee expression
   --> $DIR/lint-unnecessary-parens.rs:57:19
    |
 LL |     while let 1 = (2) {}
-   |                   ^^^ help: remove these parentheses
+   |                   ^ ^
+   |
+help: remove these parentheses
+   |
+LL -     while let 1 = (2) {}
+LL +     while let 1 = 2 {}
+   | 
 
 error: unnecessary parentheses around method argument
   --> $DIR/lint-unnecessary-parens.rs:73:24
    |
 LL |     X { y: false }.foo((true));
-   |                        ^^^^^^ help: remove these parentheses
+   |                        ^    ^
+   |
+help: remove these parentheses
+   |
+LL -     X { y: false }.foo((true));
+LL +     X { y: false }.foo(true);
+   | 
 
 error: unnecessary parentheses around assigned value
   --> $DIR/lint-unnecessary-parens.rs:75:18
    |
 LL |     let mut _a = (0);
-   |                  ^^^ help: remove these parentheses
+   |                  ^ ^
+   |
+help: remove these parentheses
+   |
+LL -     let mut _a = (0);
+LL +     let mut _a = 0;
+   | 
 
 error: unnecessary parentheses around assigned value
   --> $DIR/lint-unnecessary-parens.rs:76:10
    |
 LL |     _a = (0);
-   |          ^^^ help: remove these parentheses
+   |          ^ ^
+   |
+help: remove these parentheses
+   |
+LL -     _a = (0);
+LL +     _a = 0;
+   | 
 
 error: unnecessary parentheses around assigned value
   --> $DIR/lint-unnecessary-parens.rs:77:11
    |
 LL |     _a += (1);
-   |           ^^^ help: remove these parentheses
+   |           ^ ^
+   |
+help: remove these parentheses
+   |
+LL -     _a += (1);
+LL +     _a += 1;
+   | 
 
 error: aborting due to 17 previous errors
 
index cad2514625588e36c89a9de4c127459f0aebf332..255772ff40261160a1874bd94642806d32bb9357 100644 (file)
@@ -10,13 +10,18 @@ warning: unnecessary parentheses around assigned value
   --> $DIR/suggestions.rs:48:31
    |
 LL |         let mut registry_no = (format!("NX-{}", 74205));
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses
+   |                               ^                       ^
    |
 note: the lint level is defined here
   --> $DIR/suggestions.rs:4:21
    |
 LL | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
    |                     ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -         let mut registry_no = (format!("NX-{}", 74205));
+LL +         let mut registry_no = format!("NX-{}", 74205);
+   | 
 
 warning: variable does not need to be mutable
   --> $DIR/suggestions.rs:48:13
index e6d0a359c5ca7d857e935ca3004cc4039e54b4c5..677b96d3f32f082cee633cb9b8631b5241844ce7 100644 (file)
@@ -2,151 +2,294 @@ error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:16:9
    |
 LL |     let (a) = 0;
-   |         ^^^ help: remove these parentheses
+   |         ^ ^
    |
 note: the lint level is defined here
   --> $DIR/issue-54538-unused-parens-lint.rs:13:9
    |
 LL | #![deny(unused_parens)]
    |         ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     let (a) = 0;
+LL +     let a = 0;
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:17:9
    |
 LL |     for (a) in 0..1 {}
-   |         ^^^ help: remove these parentheses
+   |         ^ ^
+   |
+help: remove these parentheses
+   |
+LL -     for (a) in 0..1 {}
+LL +     for a in 0..1 {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:18:12
    |
 LL |     if let (a) = 0 {}
-   |            ^^^ help: remove these parentheses
+   |            ^ ^
+   |
+help: remove these parentheses
+   |
+LL -     if let (a) = 0 {}
+LL +     if let a = 0 {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:19:15
    |
 LL |     while let (a) = 0 {}
-   |               ^^^ help: remove these parentheses
+   |               ^ ^
+   |
+help: remove these parentheses
+   |
+LL -     while let (a) = 0 {}
+LL +     while let a = 0 {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:20:12
    |
 LL |     fn foo((a): u8) {}
-   |            ^^^ help: remove these parentheses
+   |            ^ ^
+   |
+help: remove these parentheses
+   |
+LL -     fn foo((a): u8) {}
+LL +     fn foo(a: u8) {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:21:14
    |
 LL |     let _ = |(a): u8| 0;
-   |              ^^^ help: remove these parentheses
+   |              ^ ^
+   |
+help: remove these parentheses
+   |
+LL -     let _ = |(a): u8| 0;
+LL +     let _ = |a: u8| 0;
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:49:12
    |
 LL |     if let (0 | 1) = 0 {}
-   |            ^^^^^^^ help: remove these parentheses
+   |            ^     ^
+   |
+help: remove these parentheses
+   |
+LL -     if let (0 | 1) = 0 {}
+LL +     if let 0 | 1 = 0 {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:50:13
    |
 LL |     if let ((0 | 1),) = (0,) {}
-   |             ^^^^^^^ help: remove these parentheses
+   |             ^     ^
+   |
+help: remove these parentheses
+   |
+LL -     if let ((0 | 1),) = (0,) {}
+LL +     if let (0 | 1,) = (0,) {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:51:13
    |
 LL |     if let [(0 | 1)] = [0] {}
-   |             ^^^^^^^ help: remove these parentheses
+   |             ^     ^
+   |
+help: remove these parentheses
+   |
+LL -     if let [(0 | 1)] = [0] {}
+LL +     if let [0 | 1] = [0] {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:52:16
    |
 LL |     if let 0 | (1 | 2) = 0 {}
-   |                ^^^^^^^ help: remove these parentheses
+   |                ^     ^
+   |
+help: remove these parentheses
+   |
+LL -     if let 0 | (1 | 2) = 0 {}
+LL +     if let 0 | 1 | 2 = 0 {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:54:15
    |
 LL |     if let TS((0 | 1)) = TS(0) {}
-   |               ^^^^^^^ help: remove these parentheses
+   |               ^     ^
+   |
+help: remove these parentheses
+   |
+LL -     if let TS((0 | 1)) = TS(0) {}
+LL +     if let TS(0 | 1) = TS(0) {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:56:20
    |
 LL |     if let NS { f: (0 | 1) } = (NS { f: 0 }) {}
-   |                    ^^^^^^^ help: remove these parentheses
+   |                    ^     ^
+   |
+help: remove these parentheses
+   |
+LL -     if let NS { f: (0 | 1) } = (NS { f: 0 }) {}
+LL +     if let NS { f: 0 | 1 } = (NS { f: 0 }) {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:66:9
    |
 LL |         (_) => {}
-   |         ^^^ help: remove these parentheses
+   |         ^ ^
+   |
+help: remove these parentheses
+   |
+LL -         (_) => {}
+LL +         _ => {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:67:9
    |
 LL |         (y) => {}
-   |         ^^^ help: remove these parentheses
+   |         ^ ^
+   |
+help: remove these parentheses
+   |
+LL -         (y) => {}
+LL +         y => {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:68:9
    |
 LL |         (ref r) => {}
-   |         ^^^^^^^ help: remove these parentheses
+   |         ^     ^
+   |
+help: remove these parentheses
+   |
+LL -         (ref r) => {}
+LL +         ref r => {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:69:9
    |
 LL |         (e @ 1...2) => {}
-   |         ^^^^^^^^^^^ help: remove these parentheses
+   |         ^         ^
+   |
+help: remove these parentheses
+   |
+LL -         (e @ 1...2) => {}
+LL +         e @ 1...2 => {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:75:9
    |
 LL |         (e @ &(1...2)) => {}
-   |         ^^^^^^^^^^^^^^ help: remove these parentheses
+   |         ^            ^
+   |
+help: remove these parentheses
+   |
+LL -         (e @ &(1...2)) => {}
+LL +         e @ &(1...2) => {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:76:10
    |
 LL |         &(_) => {}
-   |          ^^^ help: remove these parentheses
+   |          ^ ^
+   |
+help: remove these parentheses
+   |
+LL -         &(_) => {}
+LL +         &_ => {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:87:9
    |
 LL |         (_) => {}
-   |         ^^^ help: remove these parentheses
+   |         ^ ^
+   |
+help: remove these parentheses
+   |
+LL -         (_) => {}
+LL +         _ => {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:88:9
    |
 LL |         (y) => {}
-   |         ^^^ help: remove these parentheses
+   |         ^ ^
+   |
+help: remove these parentheses
+   |
+LL -         (y) => {}
+LL +         y => {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:89:9
    |
 LL |         (ref r) => {}
-   |         ^^^^^^^ help: remove these parentheses
+   |         ^     ^
+   |
+help: remove these parentheses
+   |
+LL -         (ref r) => {}
+LL +         ref r => {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:90:9
    |
 LL |         (e @ 1..=2) => {}
-   |         ^^^^^^^^^^^ help: remove these parentheses
+   |         ^         ^
+   |
+help: remove these parentheses
+   |
+LL -         (e @ 1..=2) => {}
+LL +         e @ 1..=2 => {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:96:9
    |
 LL |         (e @ &(1..=2)) => {}
-   |         ^^^^^^^^^^^^^^ help: remove these parentheses
+   |         ^            ^
+   |
+help: remove these parentheses
+   |
+LL -         (e @ &(1..=2)) => {}
+LL +         e @ &(1..=2) => {}
+   | 
 
 error: unnecessary parentheses around pattern
   --> $DIR/issue-54538-unused-parens-lint.rs:97:10
    |
 LL |         &(_) => {}
-   |          ^^^ help: remove these parentheses
+   |          ^ ^
+   |
+help: remove these parentheses
+   |
+LL -         &(_) => {}
+LL +         &_ => {}
+   | 
 
 error: aborting due to 24 previous errors
 
index 3f6260dc6e19e29211f9207c03d0f306857a0a80..a715093df4c329c34e40fc372b49e948b1b0bfbc 100644 (file)
@@ -2,49 +2,83 @@ error: unnecessary parentheses around `let` scrutinee expression
   --> $DIR/issue-74883-unused-paren-baren-yield.rs:14:29
    |
 LL |         while let Some(_) = ({yield}) {}
-   |                             ^^^^^^^^^ help: remove these parentheses
+   |                             ^       ^
    |
 note: the lint level is defined here
   --> $DIR/issue-74883-unused-paren-baren-yield.rs:3:24
    |
 LL | #![deny(unused_braces, unused_parens)]
    |                        ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -         while let Some(_) = ({yield}) {}
+LL +         while let Some(_) = {yield} {}
+   | 
 
 error: unnecessary parentheses around `let` scrutinee expression
   --> $DIR/issue-74883-unused-paren-baren-yield.rs:15:29
    |
 LL |         while let Some(_) = ((yield)) {}
-   |                             ^^^^^^^^^ help: remove these parentheses
+   |                             ^       ^
+   |
+help: remove these parentheses
+   |
+LL -         while let Some(_) = ((yield)) {}
+LL +         while let Some(_) = (yield) {}
+   | 
 
 error: unnecessary braces around block return value
   --> $DIR/issue-74883-unused-paren-baren-yield.rs:16:10
    |
 LL |         {{yield}};
-   |          ^^^^^^^ help: remove these braces
+   |          ^     ^
    |
 note: the lint level is defined here
   --> $DIR/issue-74883-unused-paren-baren-yield.rs:3:9
    |
 LL | #![deny(unused_braces, unused_parens)]
    |         ^^^^^^^^^^^^^
+help: remove these braces
+   |
+LL -         {{yield}};
+LL +         {yield};
+   | 
 
 error: unnecessary parentheses around block return value
   --> $DIR/issue-74883-unused-paren-baren-yield.rs:17:10
    |
 LL |         {( yield )};
-   |          ^^^^^^^^^ help: remove these parentheses
+   |          ^^     ^^
+   |
+help: remove these parentheses
+   |
+LL -         {( yield )};
+LL +         {yield};
+   | 
 
 error: unnecessary parentheses around block return value
   --> $DIR/issue-74883-unused-paren-baren-yield.rs:18:30
    |
 LL |         while let Some(_) = {(yield)} {}
-   |                              ^^^^^^^ help: remove these parentheses
+   |                              ^     ^
+   |
+help: remove these parentheses
+   |
+LL -         while let Some(_) = {(yield)} {}
+LL +         while let Some(_) = {yield} {}
+   | 
 
 error: unnecessary braces around block return value
   --> $DIR/issue-74883-unused-paren-baren-yield.rs:19:30
    |
 LL |         while let Some(_) = {{yield}} {}
-   |                              ^^^^^^^ help: remove these braces
+   |                              ^     ^
+   |
+help: remove these braces
+   |
+LL -         while let Some(_) = {{yield}} {}
+LL +         while let Some(_) = {yield} {}
+   | 
 
 error: aborting due to 6 previous errors
 
index 8fa5dfde61db06eba3999604f7b2629ef8f52b8c..7d6fef00ac1a4078357771226ddb4d6e0ed8955a 100644 (file)
@@ -2,43 +2,71 @@ warning: unnecessary parentheses around assigned value
   --> $DIR/unused_braces.rs:10:13
    |
 LL |     let _ = (7);
-   |             ^^^ help: remove these parentheses
+   |             ^ ^
    |
 note: the lint level is defined here
   --> $DIR/unused_braces.rs:4:24
    |
 LL | #![warn(unused_braces, unused_parens)]
    |                        ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     let _ = (7);
+LL +     let _ = 7;
+   | 
 
 warning: unnecessary braces around `if` condition
   --> $DIR/unused_braces.rs:26:8
    |
 LL |     if { true } {
-   |        ^^^^^^^^ help: remove these braces
+   |        ^^    ^^
    |
 note: the lint level is defined here
   --> $DIR/unused_braces.rs:4:9
    |
 LL | #![warn(unused_braces, unused_parens)]
    |         ^^^^^^^^^^^^^
+help: remove these braces
+   |
+LL -     if { true } {
+LL +     if true {
+   | 
 
 warning: unnecessary braces around `while` condition
   --> $DIR/unused_braces.rs:30:11
    |
 LL |     while { false } {
-   |           ^^^^^^^^^ help: remove these braces
+   |           ^^     ^^
+   |
+help: remove these braces
+   |
+LL -     while { false } {
+LL +     while false {
+   | 
 
 warning: unnecessary braces around const expression
   --> $DIR/unused_braces.rs:34:17
    |
 LL |     let _: [u8; { 3 }];
-   |                 ^^^^^ help: remove these braces
+   |                 ^^ ^^
+   |
+help: remove these braces
+   |
+LL -     let _: [u8; { 3 }];
+LL +     let _: [u8; 3];
+   | 
 
 warning: unnecessary braces around function argument
   --> $DIR/unused_braces.rs:37:13
    |
 LL |     consume({ 7 });
-   |             ^^^^^ help: remove these braces
+   |             ^^ ^^
+   |
+help: remove these braces
+   |
+LL -     consume({ 7 });
+LL +     consume(7);
+   | 
 
 warning: 5 warnings emitted
 
index f018c46fcd3c6ae3772d60b184e2267c3f61fd77..5a5326cab3b1de5391d1d2c7f5eec0144337ba43 100644 (file)
@@ -2,13 +2,18 @@ warning: unnecessary braces around function argument
   --> $DIR/unused_braces_borrow.rs:24:13
    |
 LL |     consume({ a.b });
-   |             ^^^^^^^ help: remove these braces
+   |             ^^   ^^
    |
 note: the lint level is defined here
   --> $DIR/unused_braces_borrow.rs:4:9
    |
 LL | #![warn(unused_braces)]
    |         ^^^^^^^^^^^^^
+help: remove these braces
+   |
+LL -     consume({ a.b });
+LL +     consume(a.b);
+   | 
 
 warning: 1 warning emitted
 
index 09f0fc90032dc1402a29c9e9bb07262552d46254..498c25d2e1c44ed4a2318ef21f6170e9861a2b0c 100644 (file)
@@ -1,14 +1,19 @@
-{"message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":596,"byte_end":609,"line_start":16,"line_end":16,"column_start":14,"column_end":27,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));
+{"message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":596,"byte_end":597,"line_start":16,"line_end":16,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));
   --> $DIR/unused_parens_json_suggestion.rs:16:14
    |
 LL |     let _a = (1 / (2 + 3));
-   |              ^^^^^^^^^^^^^ help: remove these parentheses
+   |              ^           ^
    |
 note: the lint level is defined here
   --> $DIR/unused_parens_json_suggestion.rs:10:9
    |
 LL | #![deny(unused_parens)]
    |         ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     let _a = (1 / (2 + 3));
+LL +     let _a = 1 / (2 + 3);
+   | 
 
 "}
 {"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error
index 5fb67fd7c95a3a99a8ff0cbbd4c7c9cbab1f4c97..08291b10fcc204f284fe3347f193846bc10c1b51 100644 (file)
-{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":500,"byte_end":504,"line_start":17,"line_end":17,"column_start":8,"column_end":12,"is_primary":true,"text":[{"text":"    if (_b) {
+{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":500,"byte_end":501,"line_start":17,"line_end":17,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (_b) {
   --> $DIR/unused_parens_remove_json_suggestion.rs:17:8
    |
 LL |     if (_b) {
-   |        ^^^^ help: remove these parentheses
+   |        ^  ^
    |
 note: the lint level is defined here
   --> $DIR/unused_parens_remove_json_suggestion.rs:10:9
    |
 LL | #![deny(unused_parens)]
    |         ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     if (_b) {
+LL +     if _b {
+   | 
 
 "}
-{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":631,"byte_end":634,"line_start":28,"line_end":28,"column_start":7,"column_end":10,"is_primary":true,"text":[{"text":"    if(c) {
+{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":631,"byte_end":632,"line_start":28,"line_end":28,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":"    if(c) {
   --> $DIR/unused_parens_remove_json_suggestion.rs:28:7
    |
 LL |     if(c) {
-   |       ^^^ help: remove these parentheses
+   |       ^ ^
+   |
+help: remove these parentheses
+   |
+LL -     if(c) {
+LL +     if c {
+   | 
 
 "}
-{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":711,"byte_end":714,"line_start":32,"line_end":32,"column_start":8,"column_end":11,"is_primary":true,"text":[{"text":"    if (c){
+{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":711,"byte_end":712,"line_start":32,"line_end":32,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":"    if (c){
   --> $DIR/unused_parens_remove_json_suggestion.rs:32:8
    |
 LL |     if (c){
-   |        ^^^ help: remove these parentheses
+   |        ^ ^
+   |
+help: remove these parentheses
+   |
+LL -     if (c){
+LL +     if c {
+   | 
 
 "}
-{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":793,"byte_end":808,"line_start":36,"line_end":36,"column_start":11,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":793,"byte_end":808,"line_start":36,"line_end":36,"column_start":11,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":26}],"label":null,"suggested_replacement":"false && true ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
+{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":793,"byte_end":794,"line_start":36,"line_end":36,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":807,"byte_end":808,"line_start":36,"line_end":36,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":793,"byte_end":794,"line_start":36,"line_end":36,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":807,"byte_end":808,"line_start":36,"line_end":36,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":"    while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition
   --> $DIR/unused_parens_remove_json_suggestion.rs:36:11
    |
 LL |     while (false && true){
-   |           ^^^^^^^^^^^^^^^ help: remove these parentheses
+   |           ^             ^
+   |
+help: remove these parentheses
+   |
+LL -     while (false && true){
+LL +     while false && true {
+   | 
 
 "}
-{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":821,"byte_end":824,"line_start":37,"line_end":37,"column_start":12,"column_end":15,"is_primary":true,"text":[{"text":"        if (c) {
+{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":821,"byte_end":822,"line_start":37,"line_end":37,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":"        if (c) {
   --> $DIR/unused_parens_remove_json_suggestion.rs:37:12
    |
 LL |         if (c) {
-   |            ^^^ help: remove these parentheses
+   |            ^ ^
+   |
+help: remove these parentheses
+   |
+LL -         if (c) {
+LL +         if c {
+   | 
 
 "}
-{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":918,"byte_end":933,"line_start":43,"line_end":43,"column_start":10,"column_end":25,"is_primary":true,"text":[{"text":"    while(true && false) {
+{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":918,"byte_end":919,"line_start":43,"line_end":43,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":"    while(true && false) {
   --> $DIR/unused_parens_remove_json_suggestion.rs:43:10
    |
 LL |     while(true && false) {
-   |          ^^^^^^^^^^^^^^^ help: remove these parentheses
+   |          ^             ^
+   |
+help: remove these parentheses
+   |
+LL -     while(true && false) {
+LL +     while true && false {
+   | 
 
 "}
-{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":987,"byte_end":995,"line_start":44,"line_end":44,"column_start":18,"column_end":26,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){
+{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":987,"byte_end":988,"line_start":44,"line_end":44,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":"        for _ in (0 .. 3){
   --> $DIR/unused_parens_remove_json_suggestion.rs:44:18
    |
 LL |         for _ in (0 .. 3){
-   |                  ^^^^^^^^ help: remove these parentheses
+   |                  ^      ^
+   |
+help: remove these parentheses
+   |
+LL -         for _ in (0 .. 3){
+LL +         for _ in 0 .. 3 {
+   | 
 
 "}
-{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1088,"byte_end":1096,"line_start":49,"line_end":49,"column_start":14,"column_end":22,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {
+{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1088,"byte_end":1089,"line_start":49,"line_end":49,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"    for _ in (0 .. 3) {
   --> $DIR/unused_parens_remove_json_suggestion.rs:49:14
    |
 LL |     for _ in (0 .. 3) {
-   |              ^^^^^^^^ help: remove these parentheses
+   |              ^      ^
+   |
+help: remove these parentheses
+   |
+LL -     for _ in (0 .. 3) {
+LL +     for _ in 0 .. 3 {
+   | 
 
 "}
-{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1147,"byte_end":1162,"line_start":50,"line_end":50,"column_start":15,"column_end":30,"is_primary":true,"text":[{"text":"        while (true && false) {
+{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1147,"byte_end":1148,"line_start":50,"line_end":50,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":"        while (true && false) {
   --> $DIR/unused_parens_remove_json_suggestion.rs:50:15
    |
 LL |         while (true && false) {
-   |               ^^^^^^^^^^^^^^^ help: remove these parentheses
+   |               ^             ^
+   |
+help: remove these parentheses
+   |
+LL -         while (true && false) {
+LL +         while true && false {
+   | 
 
 "}
 {"message":"aborting due to 9 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 9 previous errors
index 637b09fc04e5f38fab90fe70d0670bcd6fee4f7d..a8d8bd1d5fd008ed1785479ba47ca2f7ce8be75c 100644 (file)
@@ -1,6 +1,7 @@
 // run-pass
 
 #![allow(non_upper_case_globals)]
+#![allow(dead_code)]
 /*!
  * On x86_64-linux-gnu and possibly other platforms, structs get 8-byte "preferred" alignment,
  * but their "ABI" alignment (i.e., what actually matters for data layout) is the largest alignment
index 48baead074ac7d5e2442af585c2c0d95e24c0c22..7d3987f65608715ce3147fdbf44295120869b968 100644 (file)
@@ -1,5 +1,6 @@
 // run-pass
 #![allow(unused_mut)]
+#![allow(dead_code)]
 #![feature(box_syntax)]
 
 #[derive(Clone)]
index 55b10e057d88cce761e898320d3adc27d6d684d1..d23a852433f4f9b478312061d6a78d16a9eacc5c 100644 (file)
@@ -1,5 +1,6 @@
 // run-pass
 #![allow(unused_mut)]
+#![allow(dead_code)]
 #![feature(box_syntax)]
 
 #[derive(Clone)]
index 1ae16d2a7fc66eed75fc62d3836343cbca404223..f48bae55f5f1e820063df9c290b47ef4ce53b5c6 100644 (file)
@@ -1,5 +1,7 @@
 // run-pass
 
+#![allow(dead_code)]
+
 use std::rc::Rc;
 use std::ops::Deref;
 
index 5f5e25991e0cc732dffa898cf5ede8fe6785476c..101959d6da0e0ae36daffadaecd581aac2af43db 100644 (file)
@@ -32,4 +32,9 @@ fn moo(x: u32) -> bool {
     }) > 0 //~ ERROR expected expression
 }
 
+fn qux() -> u32 {
+    ({2}) - 2 //~ ERROR cannot apply unary operator `-` to type `u32`
+    //~^ ERROR mismatched types
+}
+
 fn main() {}
index 5428e1c32fed3edbe0a9bef2cf7c890b3ce6246e..45c4f977502d24fc0414b854c5fb843792cf331c 100644 (file)
@@ -32,4 +32,9 @@ fn moo(x: u32) -> bool {
     } > 0 //~ ERROR expected expression
 }
 
+fn qux() -> u32 {
+    {2} - 2 //~ ERROR cannot apply unary operator `-` to type `u32`
+    //~^ ERROR mismatched types
+}
+
 fn main() {}
index d99e9be0000c312ef65101aef774f070e78f8cd2..cae775099e0a03ced8306d34efbe54a3df257290 100644 (file)
@@ -99,7 +99,29 @@ help: parentheses are required to parse this as an expression
 LL |     ({ 3 }) * 3
    |     +     +
 
-error: aborting due to 9 previous errors
+error[E0308]: mismatched types
+  --> $DIR/expr-as-stmt.rs:36:6
+   |
+LL |     {2} - 2
+   |      ^ expected `()`, found integer
+   |
+help: you might have meant to return this value
+   |
+LL |     {return 2;} - 2
+   |      ++++++  +
+
+error[E0600]: cannot apply unary operator `-` to type `u32`
+  --> $DIR/expr-as-stmt.rs:36:9
+   |
+LL |     {2} - 2
+   |         ^^^ cannot apply unary operator `-`
+   |
+help: parentheses are required to parse this as an expression
+   |
+LL |     ({2}) - 2
+   |     +   +
+
+error: aborting due to 11 previous errors
 
-Some errors have detailed explanations: E0308, E0614.
+Some errors have detailed explanations: E0308, E0600, E0614.
 For more information about an error, try `rustc --explain E0308`.
index dcf235a9e277455079318ec30f933f6ae57a03da..8adf02b150b874cf2577068fae6e0c9bd5502327 100644 (file)
@@ -2,13 +2,18 @@ warning: unnecessary parentheses around `return` value
   --> $DIR/path-lookahead.rs:10:12
    |
 LL |     return (<T as ToString>::to_string(&arg));
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses
+   |            ^                                ^
    |
 note: the lint level is defined here
   --> $DIR/path-lookahead.rs:5:9
    |
 LL | #![warn(unused_parens)]
    |         ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     return (<T as ToString>::to_string(&arg));
+LL +     return <T as ToString>::to_string(&arg);
+   | 
 
 warning: 1 warning emitted
 
index 4e2405504f0cb0b65bd4f7b5836dc63eaed15909..0aaaa7d47c3c1eef0bcf8066e2e08218136a495b 100644 (file)
@@ -1,5 +1,6 @@
 // run-pass
 #![feature(box_syntax)]
+#![allow(dead_code)]
 
 #[derive(Copy, Clone)]
 struct Foo {
index 55975cbdb5342ee491a78f37fe9d95017b9985f7..ca35a615d214774124cf33a6dd71f41dfe9186ad 100644 (file)
@@ -1,5 +1,6 @@
 // run-pass
 #![allow(non_camel_case_types)]
+#![allow(dead_code)]
 
 trait noisy {
   fn speak(&mut self) -> isize;
index c9e98e21b9eb4411316b83cd75866ec8e27f13f2..732aa146ce446ee2e99161d5fa61290c624e75e5 100644 (file)
@@ -1,5 +1,6 @@
 // run-pass
 #![allow(non_camel_case_types)]
+#![allow(dead_code)]
 
 trait noisy {
     fn speak(&mut self);
index 51c6b6d7e4ffe236994a6bec788cf33ec883dc7a..68ff73a0805921446b7c3b5ce9788857246218d4 100644 (file)
@@ -1,4 +1,7 @@
 // run-pass
+
+#![allow(dead_code)]
+
 #[derive(Debug)]
 struct Foo {
     x: isize,
index 87282ddbcca52d863b2275a344d4ff3ba474930c..ce599582378176d32670515d0c20643e644137ad 100644 (file)
@@ -1,5 +1,6 @@
 // run-pass
 #![allow(non_camel_case_types)]
+#![allow(dead_code)]
 
 #[derive(Debug)]
 enum a_tag {
diff --git a/src/test/ui/suggestions/slice-issue-87994.rs b/src/test/ui/suggestions/slice-issue-87994.rs
new file mode 100644 (file)
index 0000000..ecb7f54
--- /dev/null
@@ -0,0 +1,16 @@
+fn main() {
+  let v = vec![1i32, 2, 3];
+  for _ in v[1..] {
+    //~^ ERROR [i32]` is not an iterator [E0277]
+    //~^^ ERROR known at compilation time
+  }
+  struct K {
+    n: i32,
+  }
+  let mut v2 = vec![K { n: 1 }, K { n: 1 }, K { n: 1 }];
+  for i2 in v2[1..] {
+    //~^ ERROR [K]` is not an iterator [E0277]
+    //~^^ ERROR known at compilation time
+    i2.n = 2;
+  }
+}
diff --git a/src/test/ui/suggestions/slice-issue-87994.stderr b/src/test/ui/suggestions/slice-issue-87994.stderr
new file mode 100644 (file)
index 0000000..018f62e
--- /dev/null
@@ -0,0 +1,71 @@
+error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
+  --> $DIR/slice-issue-87994.rs:3:12
+   |
+LL |   for _ in v[1..] {
+   |            ^^^^^^
+   |            |
+   |            expected an implementor of trait `IntoIterator`
+   |            help: consider borrowing here: `&v[1..]`
+   |
+   = note: the trait bound `[i32]: IntoIterator` is not satisfied
+   = note: required because of the requirements on the impl of `IntoIterator` for `[i32]`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: `[i32]` is not an iterator
+  --> $DIR/slice-issue-87994.rs:3:12
+   |
+LL |   for _ in v[1..] {
+   |            ^^^^^^
+   |            |
+   |            expected an implementor of trait `IntoIterator`
+   |            help: consider borrowing here: `&v[1..]`
+   |
+   = note: the trait bound `[i32]: IntoIterator` is not satisfied
+   = note: required because of the requirements on the impl of `IntoIterator` for `[i32]`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the size for values of type `[K]` cannot be known at compilation time
+  --> $DIR/slice-issue-87994.rs:11:13
+   |
+LL |   for i2 in v2[1..] {
+   |             ^^^^^^^
+   |             |
+   |             expected an implementor of trait `IntoIterator`
+   |             help: consider borrowing here: `&v2[1..]`
+   |
+   = note: the trait bound `[K]: IntoIterator` is not satisfied
+   = note: required because of the requirements on the impl of `IntoIterator` for `[K]`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: `[K]` is not an iterator
+  --> $DIR/slice-issue-87994.rs:11:13
+   |
+LL |   for i2 in v2[1..] {
+   |             ^^^^^^^
+   |             |
+   |             expected an implementor of trait `IntoIterator`
+   |             help: consider borrowing here: `&v2[1..]`
+   |
+   = note: the trait bound `[K]: IntoIterator` is not satisfied
+   = note: required because of the requirements on the impl of `IntoIterator` for `[K]`
+note: required by `into_iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
index c5a2405462932dad56d491348e71c97f63c38e0e..d8dd31645e06162f37987f06b87d04fc2a3a4773 100644 (file)
@@ -2,43 +2,71 @@ warning: unnecessary parentheses around function argument
   --> $DIR/try-block-unused-delims.rs:11:13
    |
 LL |     consume((try {}));
-   |             ^^^^^^^^ help: remove these parentheses
+   |             ^      ^
    |
 note: the lint level is defined here
   --> $DIR/try-block-unused-delims.rs:6:9
    |
 LL | #![warn(unused_parens, unused_braces)]
    |         ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     consume((try {}));
+LL +     consume(try {});
+   | 
 
 warning: unnecessary braces around function argument
   --> $DIR/try-block-unused-delims.rs:14:13
    |
 LL |     consume({ try {} });
-   |             ^^^^^^^^^^ help: remove these braces
+   |             ^^      ^^
    |
 note: the lint level is defined here
   --> $DIR/try-block-unused-delims.rs:6:24
    |
 LL | #![warn(unused_parens, unused_braces)]
    |                        ^^^^^^^^^^^^^
+help: remove these braces
+   |
+LL -     consume({ try {} });
+LL +     consume(try {});
+   | 
 
 warning: unnecessary parentheses around `match` scrutinee expression
   --> $DIR/try-block-unused-delims.rs:17:11
    |
 LL |     match (try {}) {
-   |           ^^^^^^^^ help: remove these parentheses
+   |           ^      ^
+   |
+help: remove these parentheses
+   |
+LL -     match (try {}) {
+LL +     match try {} {
+   | 
 
 warning: unnecessary parentheses around `let` scrutinee expression
   --> $DIR/try-block-unused-delims.rs:22:22
    |
 LL |     if let Err(()) = (try {}) {}
-   |                      ^^^^^^^^ help: remove these parentheses
+   |                      ^      ^
+   |
+help: remove these parentheses
+   |
+LL -     if let Err(()) = (try {}) {}
+LL +     if let Err(()) = try {} {}
+   | 
 
 warning: unnecessary parentheses around `match` scrutinee expression
   --> $DIR/try-block-unused-delims.rs:25:11
    |
 LL |     match (try {}) {
-   |           ^^^^^^^^ help: remove these parentheses
+   |           ^      ^
+   |
+help: remove these parentheses
+   |
+LL -     match (try {}) {
+LL +     match try {} {
+   | 
 
 warning: 5 warnings emitted
 
diff --git a/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs
new file mode 100644 (file)
index 0000000..e50cc58
--- /dev/null
@@ -0,0 +1,12 @@
+macro_rules! many_args {
+    ([$($t:tt)*]#$($h:tt)*) => {
+        many_args!{[$($t)*$($t)*]$($h)*}
+    };
+    ([$($t:tt)*]) => {
+        fn _f($($t: ()),*) {} //~ ERROR function can not have more than 65535 arguments
+    }
+}
+
+many_args!{[_]########## ######}
+
+fn main() {}
diff --git a/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr
new file mode 100644 (file)
index 0000000..615fd2c
--- /dev/null
@@ -0,0 +1,13 @@
+error: function can not have more than 65535 arguments
+  --> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:24
+   |
+LL |           fn _f($($t: ()),*) {}
+   |  ________________________^
+LL | |     }
+LL | | }
+LL | |
+LL | | many_args!{[_]########## ######}
+   | |____________^
+
+error: aborting due to previous error
+
index 2310370fb9fbe7eaed80f888f40633a2f8151fd3..40aaa5924df5b391862f379c8fd159920f5b061d 100644 (file)
@@ -21,37 +21,35 @@ name = "clippy-driver"
 path = "src/driver.rs"
 
 [dependencies]
-# begin automatic update
-clippy_lints = { version = "0.1.50", path = "clippy_lints" }
-# end automatic update
+clippy_lints = { version = "0.1", path = "clippy_lints" }
 semver = "0.11"
-rustc_tools_util = { version = "0.2.0", path = "rustc_tools_util" }
-tempfile = { version = "3.1.0", optional = true }
+rustc_tools_util = { version = "0.2", path = "rustc_tools_util" }
+tempfile = { version = "3.2", optional = true }
 
 [dev-dependencies]
 cargo_metadata = "0.12"
-compiletest_rs = { version = "0.6.0", features = ["tmp"] }
+compiletest_rs = { version = "0.7", features = ["tmp"] }
 tester = "0.9"
-regex = "1.4"
+regex = "1.5"
 # This is used by the `collect-metadata` alias.
 filetime = "0.2"
 
 # A noop dependency that changes in the Rust repository, it's a bit of a hack.
 # See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`
 # for more information.
-rustc-workspace-hack = "1.0.0"
+rustc-workspace-hack = "1.0"
 
 # UI test dependencies
 clippy_utils = { path = "clippy_utils" }
 derive-new = "0.5"
 if_chain = "1.0"
-itertools = "0.10.1"
-quote = "1"
+itertools = "0.10"
+quote = "1.0"
 serde = { version = "1.0", features = ["derive"] }
-syn = { version = "1", features = ["full"] }
+syn = { version = "1.0", features = ["full"] }
 
 [build-dependencies]
-rustc_tools_util = { version = "0.2.0", path = "rustc_tools_util" }
+rustc_tools_util = { version = "0.2", path = "rustc_tools_util" }
 
 [features]
 deny-warnings = ["clippy_lints/deny-warnings"]
index 0fae8c7b9afcfbf47778d814f47815d9391d7d89..d7d2655026b4bc941ea2d54bf219bc173e091083 100644 (file)
@@ -6,11 +6,11 @@ edition = "2018"
 [dependencies]
 bytecount = "0.6"
 clap = "2.33"
-itertools = "0.9"
+itertools = "0.10"
 opener = "0.5"
-regex = "1"
+regex = "1.5"
 shell-escape = "0.1"
-walkdir = "2"
+walkdir = "2.3"
 
 [features]
 deny-warnings = []
index a1707bad5c2680bf266a59284aa26e4c6ffad368..c206a1eb07b500a28c114936e7a27af2879cd3a0 100644 (file)
@@ -13,4 +13,4 @@ keywords = ["clippy", "lint", "plugin"]
 categories = ["development-tools", "development-tools::cargo-plugins"]
 
 [build-dependencies]
-term = "0.6"
+term = "0.7"
index 3c28024bf926a4e1243ce0d52910223d28da0562..e59175a55e184e9eaedfaecd76c79580c4d55383 100644 (file)
@@ -11,21 +11,21 @@ edition = "2018"
 [dependencies]
 cargo_metadata = "0.12"
 clippy_utils = { path = "../clippy_utils" }
-if_chain = "1.0.0"
-itertools = "0.9"
+if_chain = "1.0"
+itertools = "0.10"
 pulldown-cmark = { version = "0.8", default-features = false }
-quine-mc_cluskey = "0.2.2"
+quine-mc_cluskey = "0.2"
 regex-syntax = "0.6"
 serde = { version = "1.0", features = ["derive"] }
 serde_json = { version = "1.0", optional = true }
-toml = "0.5.3"
+toml = "0.5"
 unicode-normalization = "0.1"
-unicode-script = { version = "0.5.3", default-features = false }
+unicode-script = { version = "0.5", default-features = false }
 semver = "0.11"
-rustc-semver = "1.1.0"
+rustc-semver = "1.1"
 # NOTE: cargo requires serde feat in its url dep
 # see <https://github.com/rust-lang/rust/pull/63587#issuecomment-522343864>
-url = { version = "2.1.0", features = ["serde"] }
+url = { version = "2.2", features = ["serde"] }
 
 [features]
 deny-warnings = ["clippy_utils/deny-warnings"]
index c9ff468874b58e953b66dfd03c65204b3cfeb010..2ef7dcc1775a6bfe9d6bf2d6784389c7839ff993 100644 (file)
@@ -527,8 +527,8 @@ fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::It
                 return;
             }
 
-            let begin_of_attr_to_item = Span::new(attr.span.lo(), item.span.lo(), item.span.ctxt());
-            let end_of_attr_to_item = Span::new(attr.span.hi(), item.span.lo(), item.span.ctxt());
+            let begin_of_attr_to_item = Span::new(attr.span.lo(), item.span.lo(), item.span.ctxt(), item.span.parent());
+            let end_of_attr_to_item = Span::new(attr.span.hi(), item.span.lo(), item.span.ctxt(), item.span.parent());
 
             if let Some(snippet) = snippet_opt(cx, end_of_attr_to_item) {
                 let lines = snippet.split('\n').collect::<Vec<_>>();
index bd5426ba707a8b2624dd4ed905c9a0f9b25ec063..162911b77d6153b6f02fc7b8d6e5ada56fcfe2a1 100644 (file)
@@ -1,7 +1,5 @@
 //! lint on missing cargo common metadata
 
-use std::path::PathBuf;
-
 use clippy_utils::{diagnostics::span_lint, is_lint_allowed};
 use rustc_hir::{hir_id::CRATE_HIR_ID, Crate};
 use rustc_lint::{LateContext, LateLintPass};
@@ -69,12 +67,8 @@ fn missing_warning(cx: &LateContext<'_>, package: &cargo_metadata::Package, fiel
     span_lint(cx, CARGO_COMMON_METADATA, DUMMY_SP, &message);
 }
 
-fn is_empty_str(value: &Option<String>) -> bool {
-    value.as_ref().map_or(true, String::is_empty)
-}
-
-fn is_empty_path(value: &Option<PathBuf>) -> bool {
-    value.as_ref().and_then(|x| x.to_str()).map_or(true, str::is_empty)
+fn is_empty_str<T: AsRef<std::ffi::OsStr>>(value: &Option<T>) -> bool {
+    value.as_ref().map_or(true, |s| s.as_ref().is_empty())
 }
 
 fn is_empty_vec(value: &[String]) -> bool {
@@ -98,7 +92,7 @@ fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
                     missing_warning(cx, &package, "package.description");
                 }
 
-                if is_empty_str(&package.license) && is_empty_path(&package.license_file) {
+                if is_empty_str(&package.license) && is_empty_str(&package.license_file) {
                     missing_warning(cx, &package, "either package.license or package.license_file");
                 }
 
@@ -106,7 +100,7 @@ fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
                     missing_warning(cx, &package, "package.repository");
                 }
 
-                if is_empty_path(&package.readme) {
+                if is_empty_str(&package.readme) {
                     missing_warning(cx, &package, "package.readme");
                 }
 
index 96c30d57ee198c54d2b6688ec84bbc7e8a5e8ed5..2203d1c39f1793e6c517b7db92f3baf19c6d691f 100644 (file)
@@ -95,7 +95,7 @@ fn check<'tcx>(
                     });
 
                     if let Some((low, high)) = pos {
-                        Span::new(low, high, header_span.ctxt())
+                        Span::new(low, high, header_span.ctxt(), header_span.parent())
                     } else {
                         return;
                     }
index d58e49491203c1da290327d0af845d72d2018024..6ded2f233efea615f800800a41ffd3fda50a563a 100644 (file)
@@ -472,7 +472,7 @@ fn emit_branches_sharing_code_lint(
 
         let mut span = moved_start.to(span_end);
         // Improve formatting if the inner block has indention (i.e. normal Rust formatting)
-        let test_span = Span::new(span.lo() - BytePos(4), span.lo(), span.ctxt());
+        let test_span = Span::new(span.lo() - BytePos(4), span.lo(), span.ctxt(), span.parent());
         if snippet_opt(cx, test_span)
             .map(|snip| snip == "    ")
             .unwrap_or_default()
index cb2b7f5be70addb065d7efb2196ec96290275fd2..0b61909ddd82d5f7df7a29342aad3eaeabf2a893 100644 (file)
@@ -665,6 +665,7 @@ fn check_text(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, text: &str
             span.lo() + BytePos::from_usize(offset),
             span.lo() + BytePos::from_usize(offset + word.len()),
             span.ctxt(),
+            span.parent(),
         );
 
         check_word(cx, word, span);
index 6b407c7bb6724b5d288ab5dbb61d2af55960c941..2fe32fcf6651a8b67420a4fc798d8b2326f9aba4 100644 (file)
@@ -130,7 +130,7 @@ fn suggestion<'tcx>(
                         let pos = snippet_opt(cx, item.span.until(target.span()))
                             .and_then(|snip| Some(item.span.lo() + BytePos(snip.find("impl")? as u32 + 4)));
                         if let Some(pos) = pos {
-                            Span::new(pos, pos, item.span.data().ctxt)
+                            Span::new(pos, pos, item.span.ctxt(), item.span.parent())
                         } else {
                             return;
                         }
@@ -173,7 +173,7 @@ fn suggestion<'tcx>(
                                     Some(item.span.lo() + BytePos((i + (&snip[i..]).find('(')?) as u32))
                                 })
                                 .expect("failed to create span for type parameters");
-                            Span::new(pos, pos, item.span.data().ctxt)
+                            Span::new(pos, pos, item.span.ctxt(), item.span.parent())
                         });
 
                         let mut ctr_vis = ImplicitHasherConstructorVisitor::new(cx, target);
index 10281496c11cbb4e65887c6ea5e17447d17a2ab3..fe6814e35d0ca1da4475f6428eb0c3fcd8186ec9 100644 (file)
@@ -63,6 +63,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
                     hi_pos - BytePos::from_usize("const".len()),
                     hi_pos,
                     item.span.ctxt(),
+                    item.span.parent(),
                 );
                 span_lint_and_then(
                     cx,
index 68bef2f4c8bbb351e808dcd6c78193e8896a5bc6..12ffe7a136457d67219c83c78a2f443cae616b6b 100644 (file)
@@ -15,7 +15,6 @@ pub(super) fn check<'tcx>(
     pat: &'tcx Pat<'_>,
     arg: &'tcx Expr<'_>,
     body: &'tcx Expr<'_>,
-    expr: &'tcx Expr<'_>,
 ) {
     let pat_span = pat.span;
 
@@ -43,7 +42,7 @@ pub(super) fn check<'tcx>(
                 span_lint_and_then(
                     cx,
                     FOR_KV_MAP,
-                    expr.span,
+                    arg_span,
                     &format!("you seem to want to iterate on a map's {}s", kind),
                     |diag| {
                         let map = sugg::Sugg::hir(cx, arg, "map");
index 9148fbfd497af3e1c4de607ff583296135995e35..e640c62ebdaceabc102d798869f804e7a1d203b0 100644 (file)
@@ -5,12 +5,12 @@
 use rustc_lint::LateContext;
 use rustc_span::sym;
 
-pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>, expr: &Expr<'_>) -> bool {
+pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>) -> bool {
     if is_trait_method(cx, arg, sym::Iterator) {
         span_lint(
             cx,
             ITER_NEXT_LOOP,
-            expr.span,
+            arg.span,
             "you are iterating over `Iterator::next()` which is an Option; this will compile but is \
             probably not what you want",
         );
index 2860cb68f42f2c5bc74a371aa2a68ef2fb78209d..5df1b79640164302d2a8532175486208942569e4 100644 (file)
@@ -616,15 +616,15 @@ fn check_for_loop<'tcx>(
         needless_range_loop::check(cx, pat, arg, body, expr);
         explicit_counter_loop::check(cx, pat, arg, body, expr);
     }
-    check_for_loop_arg(cx, pat, arg, expr);
-    for_kv_map::check(cx, pat, arg, body, expr);
+    check_for_loop_arg(cx, pat, arg);
+    for_kv_map::check(cx, pat, arg, body);
     mut_range_bound::check(cx, arg, body);
     single_element_loop::check(cx, pat, arg, body, expr);
     same_item_push::check(cx, pat, arg, body, expr);
     manual_flatten::check(cx, pat, arg, body, span);
 }
 
-fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>, expr: &Expr<'_>) {
+fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>) {
     let mut next_loop_linted = false; // whether or not ITER_NEXT_LOOP lint was used
 
     if let ExprKind::MethodCall(method, _, [self_arg], _) = arg.kind {
@@ -637,7 +637,7 @@ fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>, expr:
                 explicit_into_iter_loop::check(cx, self_arg, arg);
             },
             "next" => {
-                next_loop_linted = iter_next_loop::check(cx, arg, expr);
+                next_loop_linted = iter_next_loop::check(cx, arg);
             },
             _ => {},
         }
index e8f3550283a49c85e1411ed9106619dda5e1d8d8..7157b80118558b889cc41556e071dd71891a903e 100644 (file)
@@ -144,7 +144,7 @@ pub(super) fn check<'tcx>(
                     span_lint_and_then(
                         cx,
                         NEEDLESS_RANGE_LOOP,
-                        expr.span,
+                        arg.span,
                         &format!("the loop variable `{}` is used to index `{}`", ident.name, indexed),
                         |diag| {
                             multispan_sugg(
@@ -170,7 +170,7 @@ pub(super) fn check<'tcx>(
                     span_lint_and_then(
                         cx,
                         NEEDLESS_RANGE_LOOP,
-                        expr.span,
+                        arg.span,
                         &format!("the loop variable `{}` is only used to index `{}`", ident.name, indexed),
                         |diag| {
                             multispan_sugg(
index 7627e0fb28956f3a61a0c8f513d03dad7c29033b..41e6ad12d058923a9af3d1a1b616bd7d650ced23 100644 (file)
     "#[macro_use] is no longer needed"
 }
 
-const BRACKETS: &[char] = &['<', '>'];
-
 #[derive(Clone, Debug, PartialEq, Eq)]
 struct PathAndSpan {
     path: String,
     span: Span,
 }
 
-/// `MacroRefData` includes the name of the macro
-/// and the path from `SourceMap::span_to_filename`.
+/// `MacroRefData` includes the name of the macro.
 #[derive(Debug, Clone)]
 pub struct MacroRefData {
     name: String,
-    path: String,
 }
 
 impl MacroRefData {
-    pub fn new(name: String, callee: Span, cx: &LateContext<'_>) -> Self {
-        let sm = cx.sess().source_map();
-        let mut path = sm.filename_for_diagnostics(&sm.span_to_filename(callee)).to_string();
-
-        // std lib paths are <::std::module::file type>
-        // so remove brackets, space and type.
-        if path.contains('<') {
-            path = path.replace(BRACKETS, "");
-        }
-        if path.contains(' ') {
-            path = path.split(' ').next().unwrap().to_string();
-        }
-        Self { name, path }
+    pub fn new(name: String) -> Self {
+        Self { name }
     }
 }
 
@@ -78,7 +63,7 @@ impl MacroUseImports {
     fn push_unique_macro(&mut self, cx: &LateContext<'_>, span: Span) {
         let call_site = span.source_callsite();
         let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), "_");
-        if let Some(callee) = span.source_callee() {
+        if let Some(_callee) = span.source_callee() {
             if !self.collected.contains(&call_site) {
                 let name = if name.contains("::") {
                     name.split("::").last().unwrap().to_string()
@@ -86,7 +71,7 @@ fn push_unique_macro(&mut self, cx: &LateContext<'_>, span: Span) {
                     name.to_string()
                 };
 
-                self.mac_refs.push(MacroRefData::new(name, callee.def_site, cx));
+                self.mac_refs.push(MacroRefData::new(name));
                 self.collected.insert(call_site);
             }
         }
@@ -95,10 +80,10 @@ fn push_unique_macro(&mut self, cx: &LateContext<'_>, span: Span) {
     fn push_unique_macro_pat_ty(&mut self, cx: &LateContext<'_>, span: Span) {
         let call_site = span.source_callsite();
         let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), "_");
-        if let Some(callee) = span.source_callee() {
+        if let Some(_callee) = span.source_callee() {
             if !self.collected.contains(&call_site) {
                 self.mac_refs
-                    .push(MacroRefData::new(name.to_string(), callee.def_site, cx));
+                    .push(MacroRefData::new(name.to_string()));
                 self.collected.insert(call_site);
             }
         }
index e273186d0519022d5a7c1a9219cf1aa9625fd4a7..001676503242b50b3b7e01b69ebb75896646afac 100644 (file)
@@ -182,7 +182,7 @@ fn parse_iter_usage(
                 },
                 _,
             ) => {
-                let parent_span = e.span.parent().unwrap();
+                let parent_span = e.span.parent_callsite().unwrap();
                 if parent_span.ctxt() == ctxt {
                     (Some(UnwrapKind::QuestionMark), parent_span)
                 } else {
index 80a930d0c547b368460ba8e0e965261b1f7da7d9..f351d0098b7509cf6abdddfef53c21a29cc7a663 100644 (file)
@@ -120,7 +120,7 @@ fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
                     correct.push("mod.rs");
                     cx.struct_span_lint(
                         SELF_NAMED_MODULE_FILES,
-                        Span::new(file.start_pos, file.start_pos, SyntaxContext::root()),
+                        Span::new(file.start_pos, file.start_pos, SyntaxContext::root(), None),
                         |build| {
                             let mut lint =
                                 build.build(&format!("`mod.rs` files are required, found `{}`", path.display()));
@@ -167,7 +167,7 @@ fn check_self_named_mod_exists(cx: &EarlyContext<'_>, path: &Path, file: &Source
 
         cx.struct_span_lint(
             MOD_MODULE_FILES,
-            Span::new(file.start_pos, file.start_pos, SyntaxContext::root()),
+            Span::new(file.start_pos, file.start_pos, SyntaxContext::root(), None),
             |build| {
                 let mut lint = build.build(&format!("`mod.rs` files are not allowed, found `{}`", path.display()));
                 lint.help(&format!("move `{}` to `{}`", path.display(), mod_file.display(),));
index eab097337306be0e8090451909adff8152effe35..947c25ac880565cb946c4872e40e95641e2e293c 100644 (file)
@@ -3,8 +3,7 @@
 use clippy_utils::{match_def_path, paths};
 use if_chain::if_chain;
 use rustc_ast::ast::{LitKind, StrStyle};
-use rustc_data_structures::fx::FxHashSet;
-use rustc_hir::{BorrowKind, Expr, ExprKind, HirId};
+use rustc_hir::{BorrowKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::{BytePos, Span};
 }
 
 #[derive(Clone, Default)]
-pub struct Regex {
-    spans: FxHashSet<Span>,
-    last: Option<HirId>,
-}
+pub struct Regex {}
 
 impl_lint_pass!(Regex => [INVALID_REGEX, TRIVIAL_REGEX]);
 
@@ -91,7 +87,7 @@ fn str_span(base: Span, c: regex_syntax::ast::Span, offset: u16) -> Span {
     let end = base.lo() + BytePos(u32::try_from(c.end.offset).expect("offset too large") + offset);
     let start = base.lo() + BytePos(u32::try_from(c.start.offset).expect("offset too large") + offset);
     assert!(start <= end);
-    Span::new(start, end, base.ctxt())
+    Span::new(start, end, base.ctxt(), base.parent())
 }
 
 fn const_str<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option<String> {
index 6a73b94d87e488ec6feaaa24f2d0119a637438a9..4a67cabf323a6a1489f84d485bce350acc98a8cf 100644 (file)
@@ -69,6 +69,7 @@ fn warn_if_tabs_in_doc(cx: &EarlyContext<'_>, attr: &ast::Attribute) {
                     attr.span.lo() + BytePos(3 + lo),
                     attr.span.lo() + BytePos(3 + hi),
                     attr.span.ctxt(),
+                    attr.span.parent(),
                 );
                 span_lint_and_sugg(
                     cx,
index 4c038a997952aba3ff2fd6a14384e17d077badba..7c24e830e71dc406e2c081b77dcc09a47eb08d57 100644 (file)
@@ -5,8 +5,8 @@ edition = "2018"
 publish = false
 
 [dependencies]
-if_chain = "1.0.0"
-rustc-semver="1.1.0"
+if_chain = "1.0"
+rustc-semver = "1.1"
 
 [features]
 deny-warnings = []
index da259511fe0b927c94ecbce6de5105ecd249ca2a..3a94f47298390a22ef1fc51459b443691fffc70c 100644 (file)
@@ -520,7 +520,7 @@ macro_rules! try_res {
             }
         };
     }
-    fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Option<&'tcx Export<HirId>> {
+    fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Option<&'tcx Export> {
         tcx.item_children(def_id)
             .iter()
             .find(|item| item.ident.name.as_str() == name)
@@ -557,7 +557,7 @@ fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Opt
                 None
             }
         });
-    try_res!(last).res
+    try_res!(last).res.expect_non_local()
 }
 
 /// Convenience function to get the `DefId` of a trait by path.
index 8f14b590d27455cbc1fc334e2b80313fab579601..e9a9895cb746f39a6abece6de0aa7df4aa26ca92 100644 (file)
@@ -192,7 +192,7 @@ fn check_rvalue(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId, rvalue: &Rv
                 ))
             }
         },
-        Rvalue::NullaryOp(NullOp::SizeOf, _) => Ok(()),
+        Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => Ok(()),
         Rvalue::NullaryOp(NullOp::Box, _) => Err((span, "heap allocations are not allowed in const fn".into())),
         Rvalue::UnaryOp(_, operand) => {
             let ty = operand.ty(body, tcx);
index ada033de6e3abe08ea16c946228514b4f95298ff..f33f1b65eabdba1a45c3859f9ea941c18cd7bf4e 100644 (file)
@@ -11,15 +11,15 @@ publish = false
 
 [dependencies]
 clap = "2.33"
-flate2 = {version = "1.0.19"}
-fs_extra = {version = "1.2.0"}
-rayon = {version = "1.5.0"}
-serde = {version = "1.0", features = ["derive"]}
-serde_json = {version = "1.0"}
-tar = {version = "0.4.30"}
-toml = {version = "0.5"}
-ureq = {version = "2.0.0-rc3"}
-walkdir = {version = "2.3.2"}
+flate2 = "1.0"
+fs_extra = "1.2"
+rayon = "1.5"
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
+tar = "0.4"
+toml = "0.5"
+ureq = "2.2"
+walkdir = "2.3"
 
 [features]
 deny-warnings = []
index 4c80cabc72305df9371c2854536d7195c7157279..f1f9c123dc842880683a14584d5c63f7bb7aa9c1 100644 (file)
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![allow(unused_imports)]
+#![allow(unused_imports,dead_code)]
 #![deny(clippy::default_trait_access)]
 
 use std::default;
index a68b6455c04165f683f4678aae1978a876b4725f..7f3dfc7f01366e0d39b23d59350a2428fe6b0e7c 100644 (file)
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![allow(unused_imports)]
+#![allow(unused_imports,dead_code)]
 #![deny(clippy::default_trait_access)]
 
 use std::default;
index 8cbe0a0c2e8e1736329b4033775ede5a4b8e0f01..94ebbb33e8d8ffad075cd6d06d3248e13e5ecf48 100644 (file)
@@ -30,6 +30,7 @@
 // If at all possible you should use intra-doc links to avoid linkcheck issues. These
 // are cases where that does not work
 // [(generated_documentation_page, &[broken_links])]
+#[rustfmt::skip]
 const LINKCHECK_EXCEPTIONS: &[(&str, &[&str])] = &[
     // These try to link to std::collections, but are defined in alloc
     // https://github.com/rust-lang/rust/issues/74481
     ("std/collections/btree_set/struct.BTreeSet.html", &["#insert-and-complex-keys"]),
     ("alloc/collections/btree_map/struct.BTreeMap.html", &["#insert-and-complex-keys"]),
     ("alloc/collections/btree_set/struct.BTreeSet.html", &["#insert-and-complex-keys"]),
+
+    // These try to link to various things in std, but are defined in core.
+    // The docs in std::primitive use proper intra-doc links, so these seem fine to special-case.
+    // Most these are broken because liballoc uses `#[lang_item]` magic to define things on
+    // primitives that aren't available in core.
+    ("alloc/slice/trait.Join.html", &["#method.join"]),
+    ("alloc/slice/trait.Concat.html", &["#method.concat"]),
+    ("alloc/slice/index.html", &["#method.concat", "#method.join"]),
+    ("alloc/vec/struct.Vec.html", &["#method.sort_by_key", "#method.sort_by_cached_key"]),
+    ("core/primitive.str.html", &["#method.to_ascii_uppercase", "#method.to_ascii_lowercase"]),
+    ("core/primitive.slice.html", &["#method.to_ascii_uppercase", "#method.to_ascii_lowercase",
+                                    "core/slice::sort_by_key", "core\\slice::sort_by_key",
+                                    "#method.sort_by_cached_key"]),
 ];
 
 #[rustfmt::skip]
@@ -376,6 +390,10 @@ fn check(&mut self, file: &Path, report: &mut Report) {
 
     /// Load a file from disk, or from the cache if available.
     fn load_file(&mut self, file: &Path, report: &mut Report) -> (String, &FileEntry) {
+        // https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
+        #[cfg(windows)]
+        const ERROR_INVALID_NAME: i32 = 123;
+
         let pretty_path =
             file.strip_prefix(&self.root).unwrap_or(&file).to_str().unwrap().to_string();
 
@@ -392,6 +410,14 @@ fn load_file(&mut self, file: &Path, report: &mut Report) -> (String, &FileEntry
                 }
                 Err(e) if e.kind() == ErrorKind::NotFound => FileEntry::Missing,
                 Err(e) => {
+                    // If a broken intra-doc link contains `::`, on windows, it will cause `ERROR_INVALID_NAME` rather than `NotFound`.
+                    // Explicitly check for that so that the broken link can be allowed in `LINKCHECK_EXCEPTIONS`.
+                    #[cfg(windows)]
+                    if e.raw_os_error() == Some(ERROR_INVALID_NAME)
+                        && file.as_os_str().to_str().map_or(false, |s| s.contains("::"))
+                    {
+                        return FileEntry::Missing;
+                    }
                     panic!("unexpected read error for {}: {}", file.display(), e);
                 }
             });
index 7a2f1cadcd5120c44eda3596053de767cd8173a2..035933186957cf81c488261fb48a98bf523e8006 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 7a2f1cadcd5120c44eda3596053de767cd8173a2
+Subproject commit 035933186957cf81c488261fb48a98bf523e8006
index a9bc89544d820cd5c0b592fdc9ee4d74c0057ff3..927187dfd8a2336b20220dd9e794bc04171f0eff 100644 (file)
@@ -762,7 +762,6 @@ fn rewrite(
 #[derive(Debug, Clone)]
 struct ParsedMacroArg {
     kind: MacroArgKind,
-    span: Span,
 }
 
 impl ParsedMacroArg {
@@ -780,14 +779,10 @@ fn rewrite(
 struct MacroArgParser {
     /// Either a name of the next metavariable, a separator, or junk.
     buf: String,
-    /// The start position on the current buffer.
-    lo: BytePos,
     /// The first token of the current buffer.
     start_tok: Token,
     /// `true` if we are parsing a metavariable or a repeat.
     is_meta_var: bool,
-    /// The position of the last token.
-    hi: BytePos,
     /// The last token parsed.
     last_tok: Token,
     /// Holds the parsed arguments.
@@ -807,8 +802,6 @@ fn last_tok(tt: &TokenTree) -> Token {
 impl MacroArgParser {
     fn new() -> MacroArgParser {
         MacroArgParser {
-            lo: BytePos(0),
-            hi: BytePos(0),
             buf: String::new(),
             is_meta_var: false,
             last_tok: Token {
@@ -824,7 +817,6 @@ fn new() -> MacroArgParser {
     }
 
     fn set_last_tok(&mut self, tok: &TokenTree) {
-        self.hi = tok.span().hi();
         self.last_tok = last_tok(tok);
     }
 
@@ -836,7 +828,6 @@ fn add_separator(&mut self) {
         };
         self.result.push(ParsedMacroArg {
             kind: MacroArgKind::Separator(self.buf.clone(), prefix),
-            span: mk_sp(self.lo, self.hi),
         });
         self.buf.clear();
     }
@@ -849,7 +840,6 @@ fn add_other(&mut self) {
         };
         self.result.push(ParsedMacroArg {
             kind: MacroArgKind::Other(self.buf.clone(), prefix),
-            span: mk_sp(self.lo, self.hi),
         });
         self.buf.clear();
     }
@@ -858,11 +848,10 @@ fn add_meta_variable(&mut self, iter: &mut Cursor) -> Option<()> {
         match iter.next() {
             Some(TokenTree::Token(Token {
                 kind: TokenKind::Ident(name, _),
-                span,
+                ..
             })) => {
                 self.result.push(ParsedMacroArg {
                     kind: MacroArgKind::MetaVariable(name, self.buf.clone()),
-                    span: mk_sp(self.lo, span.hi()),
                 });
 
                 self.buf.clear();
@@ -873,10 +862,9 @@ fn add_meta_variable(&mut self, iter: &mut Cursor) -> Option<()> {
         }
     }
 
-    fn add_delimited(&mut self, inner: Vec<ParsedMacroArg>, delim: DelimToken, span: Span) {
+    fn add_delimited(&mut self, inner: Vec<ParsedMacroArg>, delim: DelimToken) {
         self.result.push(ParsedMacroArg {
             kind: MacroArgKind::Delimited(delim, inner),
-            span,
         });
     }
 
@@ -886,19 +874,15 @@ fn add_repeat(
         inner: Vec<ParsedMacroArg>,
         delim: DelimToken,
         iter: &mut Cursor,
-        span: Span,
     ) -> Option<()> {
         let mut buffer = String::new();
         let mut first = true;
-        let mut lo = span.lo();
-        let mut hi = span.hi();
 
         // Parse '*', '+' or '?.
         for tok in iter {
             self.set_last_tok(&tok);
             if first {
                 first = false;
-                lo = tok.span().lo();
             }
 
             match tok {
@@ -918,7 +902,6 @@ fn add_repeat(
                 }
                 TokenTree::Token(ref t) => {
                     buffer.push_str(&pprust::token_to_string(&t));
-                    hi = t.span.hi();
                 }
                 _ => return None,
             }
@@ -930,20 +913,17 @@ fn add_repeat(
         } else {
             Some(Box::new(ParsedMacroArg {
                 kind: MacroArgKind::Other(buffer, "".to_owned()),
-                span: mk_sp(lo, hi),
             }))
         };
 
         self.result.push(ParsedMacroArg {
             kind: MacroArgKind::Repeat(delim, inner, another, self.last_tok.clone()),
-            span: mk_sp(self.lo, self.hi),
         });
         Some(())
     }
 
     fn update_buffer(&mut self, t: &Token) {
         if self.buf.is_empty() {
-            self.lo = t.span.lo();
             self.start_tok = t.clone();
         } else {
             let needs_space = match next_space(&self.last_tok.kind) {
@@ -999,7 +979,6 @@ fn parse(mut self, tokens: TokenStream) -> Option<Vec<ParsedMacroArg>> {
 
                     // Start keeping the name of this metavariable in the buffer.
                     self.is_meta_var = true;
-                    self.lo = span.lo();
                     self.start_tok = Token {
                         kind: TokenKind::Dollar,
                         span,
@@ -1012,7 +991,7 @@ fn parse(mut self, tokens: TokenStream) -> Option<Vec<ParsedMacroArg>> {
                     self.add_meta_variable(&mut iter)?;
                 }
                 TokenTree::Token(ref t) => self.update_buffer(t),
-                TokenTree::Delimited(delimited_span, delimited, ref tts) => {
+                TokenTree::Delimited(_delimited_span, delimited, ref tts) => {
                     if !self.buf.is_empty() {
                         if next_space(&self.last_tok.kind) == SpaceState::Always {
                             self.add_separator();
@@ -1022,16 +1001,14 @@ fn parse(mut self, tokens: TokenStream) -> Option<Vec<ParsedMacroArg>> {
                     }
 
                     // Parse the stuff inside delimiters.
-                    let mut parser = MacroArgParser::new();
-                    parser.lo = delimited_span.open.lo();
+                    let parser = MacroArgParser::new();
                     let delimited_arg = parser.parse(tts.clone())?;
 
-                    let span = delimited_span.entire();
                     if self.is_meta_var {
-                        self.add_repeat(delimited_arg, delimited, &mut iter, span)?;
+                        self.add_repeat(delimited_arg, delimited, &mut iter)?;
                         self.is_meta_var = false;
                     } else {
-                        self.add_delimited(delimited_arg, delimited, span);
+                        self.add_delimited(delimited_arg, delimited);
                     }
                 }
             }
@@ -1270,7 +1247,12 @@ fn parse_branch(&mut self) -> Option<MacroBranch> {
                 let data = delimited_span.entire().data();
                 (
                     data.hi,
-                    Span::new(data.lo + BytePos(1), data.hi - BytePos(1), data.ctxt),
+                    Span::new(
+                        data.lo + BytePos(1),
+                        data.hi - BytePos(1),
+                        data.ctxt,
+                        data.parent,
+                    ),
                     delimited_span.entire(),
                 )
             }
index 5de0575b5cd66a56a466466608cdf47b9b8600a9..ded34d9032f91f188c11c9437b41691cdcce75b5 100644 (file)
@@ -27,7 +27,6 @@
 pub(crate) struct Module<'a> {
     ast_mod_kind: Option<Cow<'a, ast::ModKind>>,
     pub(crate) items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>,
-    attrs: Cow<'a, Vec<ast::Attribute>>,
     inner_attr: Vec<ast::Attribute>,
     pub(crate) span: Span,
 }
@@ -46,7 +45,6 @@ pub(crate) fn new(
             .collect();
         Module {
             items: mod_items,
-            attrs: mod_attrs,
             inner_attr,
             span: mod_span,
             ast_mod_kind,
index 06159a1b26e8698cdf0102b7c95514c7354e8ebc..29e1e070d41114079921683fea87f7cd62ec941f 100644 (file)
@@ -356,11 +356,11 @@ macro_rules! source {
 }
 
 pub(crate) fn mk_sp(lo: BytePos, hi: BytePos) -> Span {
-    Span::new(lo, hi, SyntaxContext::root())
+    Span::new(lo, hi, SyntaxContext::root(), None)
 }
 
 pub(crate) fn mk_sp_lo_plus_one(lo: BytePos) -> Span {
-    Span::new(lo, lo + BytePos(1), SyntaxContext::root())
+    Span::new(lo, lo + BytePos(1), SyntaxContext::root(), None)
 }
 
 // Returns `true` if the given span does not intersect with file lines.
index a1c41eb99810e8c51b247b6b6dcb47f9604fb981..35809e599266c8111e6758f84307b1371838ea69 100644 (file)
@@ -46,6 +46,7 @@ macro_rules! tidy_error {
 pub mod extdeps;
 pub mod features;
 pub mod pal;
+pub mod primitive_docs;
 pub mod style;
 pub mod target_specific_tests;
 pub mod ui_tests;
index 440c352ea5320de9319e91c01525929028e3b96f..d555f7c8e34fffbaefb5158ddc5e2b815bf77ea3 100644 (file)
@@ -71,6 +71,7 @@ macro_rules! check {
 
         // Checks that only make sense for the std libs.
         check!(pal, &library_path);
+        check!(primitive_docs, &library_path);
 
         // Checks that need to be done for both the compiler and std libraries.
         check!(unit_tests, &src_path);
diff --git a/src/tools/tidy/src/primitive_docs.rs b/src/tools/tidy/src/primitive_docs.rs
new file mode 100644 (file)
index 0000000..8476650
--- /dev/null
@@ -0,0 +1,17 @@
+//! Tidy check to make sure `library/{std,core}/src/primitive_docs.rs` are the same file.  These are
+//! different files so that relative links work properly without having to have `CARGO_PKG_NAME`
+//! set, but conceptually they should always be the same.
+
+use std::path::Path;
+
+pub fn check(library_path: &Path, bad: &mut bool) {
+    let std_name = "std/src/primitive_docs.rs";
+    let core_name = "core/src/primitive_docs.rs";
+    let std_contents = std::fs::read_to_string(library_path.join(std_name))
+        .unwrap_or_else(|e| panic!("failed to read library/{}: {}", std_name, e));
+    let core_contents = std::fs::read_to_string(library_path.join(core_name))
+        .unwrap_or_else(|e| panic!("failed to read library/{}: {}", core_name, e));
+    if std_contents != core_contents {
+        tidy_error!(bad, "library/{} and library/{} have different contents", core_name, std_name);
+    }
+}