summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules2
-rw-r--r--Cargo.lock23
-rw-r--r--RELEASES.md2
-rw-r--r--compiler/rustc_borrowck/src/borrowck_errors.rs7
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs2
-rw-r--r--compiler/rustc_borrowck/src/lib.rs1
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs4
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs6
-rw-r--r--compiler/rustc_borrowck/src/renumber.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs8
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/input_output.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs4
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs96
-rw-r--r--compiler/rustc_builtin_macros/src/cfg.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/debug.rs205
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/decodable.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs83
-rw-r--r--compiler/rustc_const_eval/src/interpret/mod.rs2
-rw-r--r--compiler/rustc_data_structures/src/profiling.rs18
-rw-r--r--compiler/rustc_data_structures/src/sync.rs7
-rw-r--r--compiler/rustc_driver/src/lib.rs2
-rw-r--r--compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl4
-rw-r--r--compiler/rustc_error_messages/locales/en-US/privacy.ftl12
-rw-r--r--compiler/rustc_error_messages/src/lib.rs39
-rw-r--r--compiler/rustc_errors/src/emitter.rs5
-rw-r--r--compiler/rustc_expand/src/base.rs3
-rw-r--r--compiler/rustc_expand/src/build.rs31
-rw-r--r--compiler/rustc_expand/src/lib.rs1
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs30
-rw-r--r--compiler/rustc_hir/src/intravisit.rs24
-rw-r--r--compiler/rustc_hir/src/itemlikevisit.rs9
-rw-r--r--compiler/rustc_hir/src/lib.rs1
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs2
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs14
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs13
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs9
-rw-r--r--compiler/rustc_lint/src/internal.rs9
-rw-r--r--compiler/rustc_lint/src/types.rs148
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs1
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic.rs460
-rw-r--r--compiler/rustc_macros/src/diagnostics/error.rs37
-rw-r--r--compiler/rustc_macros/src/diagnostics/fluent.rs11
-rw-r--r--compiler/rustc_macros/src/diagnostics/mod.rs10
-rw-r--r--compiler/rustc_macros/src/diagnostics/subdiagnostic.rs84
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs21
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs17
-rw-r--r--compiler/rustc_middle/src/query/mod.rs19
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs69
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs8
-rw-r--r--compiler/rustc_parse/src/lib.rs1
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs26
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs30
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs6
-rw-r--r--compiler/rustc_privacy/Cargo.toml7
-rw-r--r--compiler/rustc_privacy/src/errors.rs75
-rw-r--r--compiler/rustc_privacy/src/lib.rs92
-rw-r--r--compiler/rustc_session/src/session.rs23
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_target/src/lib.rs1
-rw-r--r--compiler/rustc_target/src/spec/aarch64_apple_darwin.rs2
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs11
-rw-r--r--compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs12
-rw-r--r--compiler/rustc_target/src/spec/armv7_linux_androideabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs6
-rw-r--r--compiler/rustc_target/src/spec/avr_gnu_base.rs9
-rw-r--r--compiler/rustc_target/src/spec/avr_unknown_gnu_atmega328.rs2
-rw-r--r--compiler/rustc_target/src/spec/fuchsia_base.rs33
-rw-r--r--compiler/rustc_target/src/spec/hermit_base.rs9
-rw-r--r--compiler/rustc_target/src/spec/i686_apple_darwin.rs2
-rw-r--r--compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs9
-rw-r--r--compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs28
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_freebsd.rs4
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_haiku.rs2
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_openbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs9
-rw-r--r--compiler/rustc_target/src/spec/i686_wrs_vxworks.rs2
-rw-r--r--compiler/rustc_target/src/spec/illumos_base.rs11
-rw-r--r--compiler/rustc_target/src/spec/mipsel_sony_psp.rs6
-rw-r--r--compiler/rustc_target/src/spec/mod.rs38
-rw-r--r--compiler/rustc_target/src/spec/msvc_base.rs13
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs6
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs3
-rw-r--r--compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs2
-rw-r--r--compiler/rustc_target/src/spec/tests/tests_impl.rs97
-rw-r--r--compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs9
-rw-r--r--compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/uefi_msvc_base.rs40
-rw-r--r--compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs23
-rw-r--r--compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs45
-rw-r--r--compiler/rustc_target/src/spec/wasm32_wasi.rs6
-rw-r--r--compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs30
-rw-r--r--compiler/rustc_target/src/spec/wasm_base.rs105
-rw-r--r--compiler/rustc_target/src/spec/windows_gnu_base.rs82
-rw-r--r--compiler/rustc_target/src/spec/windows_gnullvm_base.rs33
-rw-r--r--compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs31
-rw-r--r--compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs9
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_darwin.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs73
-rw-r--r--compiler/rustc_target/src/spec/x86_64_linux_android.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_pc_solaris.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs9
-rw-r--r--compiler/rustc_target/src/spec/x86_64_pc_windows_gnullvm.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_sun_solaris.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_redox.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs9
-rw-r--r--compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs78
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs21
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs2
-rw-r--r--compiler/rustc_type_ir/src/lib.rs1
-rw-r--r--compiler/rustc_type_ir/src/sty.rs162
-rw-r--r--compiler/rustc_typeck/src/check/check.rs13
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior.rs2
-rw-r--r--compiler/rustc_typeck/src/check/mod.rs10
-rw-r--r--compiler/rustc_typeck/src/check/regionck.rs1
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs174
-rw-r--r--compiler/rustc_typeck/src/coherence/mod.rs19
-rw-r--r--compiler/rustc_typeck/src/coherence/orphan.rs176
-rw-r--r--compiler/rustc_typeck/src/coherence/unsafety.rs35
-rw-r--r--compiler/rustc_typeck/src/collect.rs4
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs2
-rw-r--r--compiler/rustc_typeck/src/errors.rs70
-rw-r--r--compiler/rustc_typeck/src/impl_wf_check.rs54
-rw-r--r--compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs41
-rw-r--r--compiler/rustc_typeck/src/lib.rs18
-rw-r--r--library/alloc/src/boxed/thin.rs8
-rw-r--r--library/alloc/tests/fmt.rs2
-rw-r--r--library/core/src/fmt/mod.rs228
-rw-r--r--library/core/src/iter/adapters/chain.rs72
-rw-r--r--library/core/src/iter/adapters/flatten.rs41
-rw-r--r--library/core/src/iter/adapters/fuse.rs60
-rw-r--r--library/core/src/num/nonzero.rs56
-rw-r--r--library/core/tests/alloc.rs4
-rw-r--r--library/core/tests/hash/mod.rs5
-rw-r--r--library/core/tests/ptr.rs26
-rw-r--r--library/core/tests/waker.rs4
-rw-r--r--library/proc_macro/src/bridge/client.rs140
-rw-r--r--library/proc_macro/src/bridge/mod.rs50
-rw-r--r--library/proc_macro/src/bridge/selfless_reify.rs11
-rw-r--r--library/proc_macro/src/bridge/server.rs37
-rw-r--r--library/proc_macro/src/lib.rs2
-rw-r--r--library/std/src/alloc.rs2
-rw-r--r--library/std/src/io/cursor.rs126
-rw-r--r--library/std/src/io/cursor/tests.rs48
-rw-r--r--library/std/src/sys/hermit/condvar.rs19
-rw-r--r--library/std/src/sys/hermit/mutex.rs4
-rw-r--r--library/std/src/sys/hermit/rwlock.rs11
-rw-r--r--library/std/src/sys/itron/abi.rs48
-rw-r--r--library/std/src/sys/itron/wait_flag.rs72
-rw-r--r--library/std/src/sys/solid/mod.rs2
-rw-r--r--library/std/src/sys_common/thread_parker/mod.rs7
-rw-r--r--library/std/src/sys_common/thread_parker/wait_flag.rs102
-rw-r--r--src/bootstrap/bootstrap.py10
-rw-r--r--src/bootstrap/native.rs2
-rw-r--r--src/librustdoc/config.rs24
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css74
-rw-r--r--src/librustdoc/html/static/css/settings.css21
-rw-r--r--src/librustdoc/html/static/css/themes/ayu.css9
-rw-r--r--src/librustdoc/html/static/css/themes/dark.css9
-rw-r--r--src/librustdoc/html/static/css/themes/light.css9
-rw-r--r--src/librustdoc/html/static/js/main.js177
-rw-r--r--src/librustdoc/html/static/js/settings.js40
-rw-r--r--src/librustdoc/html/templates/page.html4
-rw-r--r--src/librustdoc/json/conversions.rs7
-rw-r--r--src/librustdoc/lib.rs2
m---------src/llvm-project0
-rw-r--r--src/test/run-make/issue-88756-default-output/Makefile4
-rw-r--r--src/test/run-make/issue-88756-default-output/README.md1
-rw-r--r--src/test/run-make/issue-88756-default-output/output-default.stdout193
-rw-r--r--src/test/run-make/issue-88756-default-output/x.rs1
-rw-r--r--src/test/run-make/issue-88756-opt-help/Makefile4
-rw-r--r--src/test/run-make/issue-88756-opt-help/README.md1
-rw-r--r--src/test/run-make/issue-88756-opt-help/output-default.stdout193
-rw-r--r--src/test/run-make/issue-88756-opt-help/x.rs1
-rw-r--r--src/test/rustdoc-gui/escape-key.goml12
-rw-r--r--src/test/rustdoc-gui/pocket-menu.goml72
-rw-r--r--src/test/rustdoc-gui/shortcuts.goml5
-rw-r--r--src/test/rustdoc-json/assoc_items.rs29
-rw-r--r--src/test/rustdoc-json/assoc_type.rs22
-rw-r--r--src/test/rustdoc-ui/issue-83883-describe-lints.stdout216
-rw-r--r--src/test/rustdoc/generic_const_exprs.rs24
-rw-r--r--src/test/ui-fulldeps/internal-lints/diagnostics.rs4
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs241
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr287
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs159
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr207
-rw-r--r--src/test/ui/array-slice-vec/array_const_index-0.stderr13
-rw-r--r--src/test/ui/array-slice-vec/array_const_index-1.stderr13
-rw-r--r--src/test/ui/associated-consts/defaults-not-assumed-fail.stderr25
-rw-r--r--src/test/ui/associated-item/associated-item-duplicate-names-2.stderr2
-rw-r--r--src/test/ui/associated-item/issue-48027.stderr24
-rw-r--r--src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr12
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-2.rs2
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-2.stderr17
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-param-2.stderr12
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-1.rs4
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-1.stderr34
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-2.rs3
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-2.stderr16
-rw-r--r--src/test/ui/associated-types/issue-59324.stderr12
-rw-r--r--src/test/ui/borrowck/issue-81899.stderr13
-rw-r--r--src/test/ui/borrowck/issue-88434-minimal-example.stderr13
-rw-r--r--src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr13
-rw-r--r--src/test/ui/chalkify/bugs/async.rs2
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr24
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr24
-rw-r--r--src/test/ui/coherence/coherence-impls-copy.stderr42
-rw-r--r--src/test/ui/coherence/coherence-impls-send.stderr22
-rw-r--r--src/test/ui/coherence/coherence-impls-sized.stderr66
-rw-r--r--src/test/ui/coherence/coherence-with-closure.stderr18
-rw-r--r--src/test/ui/coherence/coherence-with-generator.stderr18
-rw-r--r--src/test/ui/const-generics/const-param-elided-lifetime.min.stderr18
-rw-r--r--src/test/ui/consts/assert-type-intrinsics.stderr42
-rw-r--r--src/test/ui/consts/assoc_const_generic_impl.stderr17
-rw-r--r--src/test/ui/consts/const-err-early.stderr85
-rw-r--r--src/test/ui/consts/const-err-multi.stderr68
-rw-r--r--src/test/ui/consts/const-err.stderr17
-rw-r--r--src/test/ui/consts/const-eval/conditional_array_execution.stderr33
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow-2.stderr17
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow2.stderr150
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow2b.stderr150
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow2c.stderr150
-rw-r--r--src/test/ui/consts/const-eval/const-eval-query-stack.stderr28
-rw-r--r--src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr351
-rw-r--r--src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr76
-rw-r--r--src/test/ui/consts/const-eval/erroneous-const.stderr17
-rw-r--r--src/test/ui/consts/const-eval/erroneous-const2.stderr17
-rw-r--r--src/test/ui/consts/const-eval/format.stderr46
-rw-r--r--src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr17
-rw-r--r--src/test/ui/consts/const-eval/issue-43197.stderr66
-rw-r--r--src/test/ui/consts/const-eval/issue-44578.stderr33
-rw-r--r--src/test/ui/consts/const-eval/issue-50814-2.stderr13
-rw-r--r--src/test/ui/consts/const-eval/issue-50814.stderr13
-rw-r--r--src/test/ui/consts/const-eval/issue-85907.rs7
-rw-r--r--src/test/ui/consts/const-eval/issue-85907.stderr10
-rw-r--r--src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr19
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors.noopt.stderr50
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors.opt.stderr51
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr50
-rw-r--r--src/test/ui/consts/const-eval/pub_const_err.stderr17
-rw-r--r--src/test/ui/consts/const-eval/pub_const_err_bin.stderr17
-rw-r--r--src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr13
-rw-r--r--src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr13
-rw-r--r--src/test/ui/consts/const-eval/ub-enum.32bit.stderr55
-rw-r--r--src/test/ui/consts/const-eval/ub-enum.64bit.stderr55
-rw-r--r--src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr63
-rw-r--r--src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr63
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr83
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr83
-rw-r--r--src/test/ui/consts/const-eval/unused-broken-const.stderr13
-rw-r--r--src/test/ui/consts/const-external-macro-const-err.stderr12
-rw-r--r--src/test/ui/consts/const-float-bits-reject-conv.stderr112
-rw-r--r--src/test/ui/consts/const-len-underflow-separate-spans.stderr13
-rw-r--r--src/test/ui/consts/const-prop-read-static-in-const.stderr13
-rw-r--r--src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr26
-rw-r--r--src/test/ui/consts/const-slice-oob.stderr13
-rw-r--r--src/test/ui/consts/const_limit/const_eval_limit_reached.stderr18
-rw-r--r--src/test/ui/consts/invalid-union.32bit.stderr11
-rw-r--r--src/test/ui/consts/invalid-union.64bit.stderr11
-rw-r--r--src/test/ui/consts/issue-56164.stderr11
-rw-r--r--src/test/ui/consts/issue-66693.stderr11
-rw-r--r--src/test/ui/consts/issue-miri-1910.stderr25
-rw-r--r--src/test/ui/consts/miri_unleashed/assoc_const.stderr25
-rw-r--r--src/test/ui/consts/miri_unleashed/assoc_const_2.stderr17
-rw-r--r--src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr55
-rw-r--r--src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr42
-rw-r--r--src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr42
-rw-r--r--src/test/ui/consts/ptr_comparisons.stderr26
-rw-r--r--src/test/ui/consts/recursive.stderr19
-rw-r--r--src/test/ui/consts/uninhabited-const-issue-61744.stderr144
-rw-r--r--src/test/ui/error-codes/E0201.stderr8
-rw-r--r--src/test/ui/feature-gates/feature-gate-arbitrary-self-types.stderr20
-rw-r--r--src/test/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr12
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-80626.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-80626.stderr13
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-86218.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87735.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87748.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87755.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87803.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88382.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88460.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88526.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-89008.rs2
-rw-r--r--src/test/ui/generic-associated-types/issue-91883.rs42
-rw-r--r--src/test/ui/generic-associated-types/issue-91883.stderr26
-rw-r--r--src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr36
-rw-r--r--src/test/ui/hrtb/issue-95034.rs2
-rw-r--r--src/test/ui/impl-duplicate-methods.stderr4
-rw-r--r--src/test/ui/impl-trait/auto-trait.stderr18
-rw-r--r--src/test/ui/impl-trait/negative-reasoning.stderr22
-rw-r--r--src/test/ui/impl-trait/nested-return-type2.rs8
-rw-r--r--src/test/ui/impl-trait/nested-return-type2.stderr16
-rw-r--r--src/test/ui/issues/issue-20413.rs9
-rw-r--r--src/test/ui/issues/issue-20413.stderr69
-rw-r--r--src/test/ui/issues/issue-4265.stderr13
-rw-r--r--src/test/ui/issues/issue-47511.rs2
-rw-r--r--src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr44
-rw-r--r--src/test/ui/limits/issue-55878.stderr12
-rw-r--r--src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr13
-rw-r--r--src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr13
-rw-r--r--src/test/ui/lint/force-warn/deny-by-default-lint.stderr13
-rw-r--r--src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.rs32
-rw-r--r--src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr126
-rw-r--r--src/test/ui/lint/lint-invalid-atomic-ordering-exchange.rs32
-rw-r--r--src/test/ui/lint/lint-invalid-atomic-ordering-exchange.stderr126
-rw-r--r--src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.rs32
-rw-r--r--src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr126
-rw-r--r--src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.rs9
-rw-r--r--src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.stdout29
-rw-r--r--src/test/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.rs32
-rw-r--r--src/test/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout147
-rw-r--r--src/test/ui/methods/method-macro-backtrace.stderr4
-rw-r--r--src/test/ui/mir/issue-92893.rs3
-rw-r--r--src/test/ui/mir/issue-92893.stderr8
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/feature-gate.rs2
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr20
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs88
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr442
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs1
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr26
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/feature-gate.rs3
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr18
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs17
-rw-r--r--src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr52
-rw-r--r--src/test/ui/suggestions/auxiliary/not-object-safe.rs6
-rw-r--r--src/test/ui/suggestions/issue-98500.rs14
-rw-r--r--src/test/ui/suggestions/issue-98500.stderr24
-rw-r--r--src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed2
-rw-r--r--src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr22
-rw-r--r--src/test/ui/trait-bounds/select-param-env-instead-of-blanket.rs2
-rw-r--r--src/test/ui/traits/alias/issue-83613.stderr16
-rw-r--r--src/test/ui/traits/issue-78372.rs1
-rw-r--r--src/test/ui/traits/issue-78372.stderr15
-rw-r--r--src/test/ui/traits/issue-8153.stderr4
-rw-r--r--src/test/ui/traits/issue-87558.rs9
-rw-r--r--src/test/ui/traits/issue-87558.stderr24
-rw-r--r--src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs2
-rw-r--r--src/test/ui/union/issue-81199.stderr20
-rw-r--r--src/test/ui/wf/issue-96810.rs12
-rw-r--r--src/test/ui/wf/issue-96810.stderr19
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_flatten.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs1
-rw-r--r--src/tools/clippy/clippy_utils/src/diagnostics.rs91
-rw-r--r--src/tools/clippy/tests/ui/map_flatten.stderr25
-rw-r--r--src/tools/clippy/tests/ui/map_flatten_fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/map_flatten_fixable.stderr54
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.fixed6
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.stderr46
-rw-r--r--src/tools/compiletest/src/header.rs24
m---------src/tools/miri21
-rwxr-xr-xsrc/tools/publish_toolstate.py2
-rw-r--r--triagebot.toml105
391 files changed, 8727 insertions, 3760 deletions
diff --git a/.gitmodules b/.gitmodules
index 21bce3c7fa0..a524098845a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -34,7 +34,7 @@
[submodule "src/llvm-project"]
path = src/llvm-project
url = https://github.com/rust-lang/llvm-project.git
- branch = rustc/14.0-2022-03-22
+ branch = rustc/14.0-2022-06-20
[submodule "src/doc/embedded-book"]
path = src/doc/embedded-book
url = https://github.com/rust-embedded/book.git
diff --git a/Cargo.lock b/Cargo.lock
index 633eeb3d3bd..96d9449db57 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2332,20 +2332,6 @@ dependencies = [
[[package]]
name = "measureme"
-version = "9.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78f7a41bc6f856a2cf0e95094ad5121f82500e2d9a0f3c0171d98f6566d8117d"
-dependencies = [
- "log",
- "memmap2",
- "parking_lot 0.11.2",
- "perf-event-open-sys",
- "rustc-hash",
- "smallvec",
-]
-
-[[package]]
-name = "measureme"
version = "10.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd460fad6e55ca82fa0cd9dab0d315294188fd9ec6efbf4105e5635d4872ef9c"
@@ -2442,7 +2428,7 @@ dependencies = [
"lazy_static",
"libc",
"log",
- "measureme 9.1.2",
+ "measureme",
"rand 0.8.5",
"regex",
"rustc-workspace-hack",
@@ -3652,7 +3638,7 @@ dependencies = [
"cstr",
"libc",
"libloading",
- "measureme 10.0.0",
+ "measureme",
"rustc-demangle",
"rustc_ast",
"rustc_attr",
@@ -3750,7 +3736,7 @@ dependencies = [
"indexmap",
"jobserver",
"libc",
- "measureme 10.0.0",
+ "measureme",
"memmap2",
"parking_lot 0.11.2",
"rustc-hash",
@@ -4294,6 +4280,7 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_hir",
+ "rustc_macros",
"rustc_middle",
"rustc_session",
"rustc_span",
@@ -4306,7 +4293,7 @@ dependencies = [
name = "rustc_query_impl"
version = "0.0.0"
dependencies = [
- "measureme 10.0.0",
+ "measureme",
"rustc-rayon-core",
"rustc_ast",
"rustc_data_structures",
diff --git a/RELEASES.md b/RELEASES.md
index 3d88891ad21..7479735012c 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -29,7 +29,6 @@ Compiler
Libraries
---------
-- [Move `CStr` to libcore, and `CString` to liballoc][94079]
- [Windows: Use a pipe relay for chaining pipes][95841]
- [Replace Linux Mutex and Condvar with futex based ones.][95035]
- [Replace RwLock by a futex based one on Linux][95801]
@@ -90,7 +89,6 @@ and related tools.
[93313]: https://github.com/rust-lang/rust/pull/93313/
[93969]: https://github.com/rust-lang/rust/pull/93969/
-[94079]: https://github.com/rust-lang/rust/pull/94079/
[94206]: https://github.com/rust-lang/rust/pull/94206/
[94457]: https://github.com/rust-lang/rust/pull/94457/
[94775]: https://github.com/rust-lang/rust/pull/94775/
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index a1233d62cb0..708fe8719a1 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -1,4 +1,6 @@
-use rustc_errors::{struct_span_err, DiagnosticBuilder, DiagnosticId, ErrorGuaranteed, MultiSpan};
+use rustc_errors::{
+ struct_span_err, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
+};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span;
@@ -476,10 +478,11 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
struct_span_err!(self, span, E0716, "temporary value dropped while borrowed",)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
fn struct_span_err_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
- msg: &str,
+ msg: impl Into<DiagnosticMessage>,
code: DiagnosticId,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
self.infcx.tcx.sess.struct_span_err_with_code(sp, msg, code)
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 8f3699553d9..e60e11f11df 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -879,7 +879,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
}
let mut found = false;
- tcx.fold_regions(tcx.type_of(body_parent_did), &mut true, |r: ty::Region<'tcx>, _| {
+ tcx.fold_regions(tcx.type_of(body_parent_did), |r: ty::Region<'tcx>, _| {
if *r == ty::ReEarlyBound(region) {
found = true;
}
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 8ef2974c372..a2df072aa31 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -6,6 +6,7 @@
#![feature(let_else)]
#![feature(min_specialization)]
#![feature(never_type)]
+#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
#![feature(trusted_step)]
#![feature(try_blocks)]
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 0fe3b45bc7c..f5c9392948b 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -1009,7 +1009,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
debug!("try_promote_type_test_subject(ty = {:?})", ty);
- let ty = tcx.fold_regions(ty, &mut false, |r, _depth| {
+ let ty = tcx.fold_regions(ty, |r, _depth| {
let region_vid = self.to_region_vid(r);
// The challenge if this. We have some region variable `r`
@@ -1289,7 +1289,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
where
T: TypeFoldable<'tcx>,
{
- tcx.fold_regions(value, &mut false, |r, _db| {
+ tcx.fold_regions(value, |r, _db| {
let vid = self.to_region_vid(r);
let scc = self.constraint_sccs.scc(vid);
let repr = self.scc_representatives[scc];
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 81073758791..d182c0cf4e8 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -59,7 +59,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
debug!(?concrete_type, ?substs);
let mut subst_regions = vec![self.universal_regions.fr_static];
- let universal_substs = infcx.tcx.fold_regions(substs, &mut false, |region, _| {
+ let universal_substs = infcx.tcx.fold_regions(substs, |region, _| {
if let ty::RePlaceholder(..) = region.kind() {
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
return region;
@@ -91,7 +91,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
subst_regions.dedup();
let universal_concrete_type =
- infcx.tcx.fold_regions(concrete_type, &mut false, |region, _| match *region {
+ infcx.tcx.fold_regions(concrete_type, |region, _| match *region {
ty::ReVar(vid) => subst_regions
.iter()
.find(|ur_vid| self.eval_equal(vid, **ur_vid))
@@ -146,7 +146,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
where
T: TypeFoldable<'tcx>,
{
- tcx.fold_regions(ty, &mut false, |region, _| match *region {
+ tcx.fold_regions(ty, |region, _| match *region {
ty::ReVar(vid) => {
// Find something that we can name
let upper_bound = self.approx_universal_upper_bound(vid);
diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs
index 2876d60527f..7a8ce621c5d 100644
--- a/compiler/rustc_borrowck/src/renumber.rs
+++ b/compiler/rustc_borrowck/src/renumber.rs
@@ -31,7 +31,7 @@ pub fn renumber_regions<'tcx, T>(infcx: &InferCtxt<'_, 'tcx>, value: T) -> T
where
T: TypeFoldable<'tcx>,
{
- infcx.tcx.fold_regions(value, &mut false, |_region, _depth| {
+ infcx.tcx.fold_regions(value, |_region, _depth| {
let origin = NllRegionVariableOrigin::Existential { from_forall: false };
infcx.next_nll_region_var(origin)
})
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index 3c9e3870aea..5e33d9d25c2 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -23,7 +23,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
universal_regions: &'a UniversalRegions<'tcx>,
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
- implicit_region_bound: Option<ty::Region<'tcx>>,
+ implicit_region_bound: ty::Region<'tcx>,
param_env: ty::ParamEnv<'tcx>,
locations: Locations,
span: Span,
@@ -36,7 +36,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
infcx: &'a InferCtxt<'a, 'tcx>,
universal_regions: &'a UniversalRegions<'tcx>,
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
- implicit_region_bound: Option<ty::Region<'tcx>>,
+ implicit_region_bound: ty::Region<'tcx>,
param_env: ty::ParamEnv<'tcx>,
locations: Locations,
span: Span,
@@ -108,7 +108,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
// create new region variables, which can't be done later when
// verifying these bounds.
if t1.has_placeholders() {
- t1 = tcx.fold_regions(t1, &mut false, |r, _| match *r {
+ t1 = tcx.fold_regions(t1, |r, _| match *r {
ty::RePlaceholder(placeholder) => {
self.constraints.placeholder_region(self.infcx, placeholder)
}
@@ -120,7 +120,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
&mut *self,
tcx,
region_bound_pairs,
- implicit_region_bound,
+ Some(implicit_region_bound),
param_env,
)
.type_must_outlive(origin, t1, r2);
diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
index 813307356c4..421ef5be812 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -61,7 +61,7 @@ pub(crate) struct CreateResult<'tcx> {
pub(crate) fn create<'tcx>(
infcx: &InferCtxt<'_, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
- implicit_region_bound: Option<ty::Region<'tcx>>,
+ implicit_region_bound: ty::Region<'tcx>,
universal_regions: &Rc<UniversalRegions<'tcx>>,
constraints: &mut MirTypeckRegionConstraints<'tcx>,
) -> CreateResult<'tcx> {
@@ -223,7 +223,7 @@ struct UniversalRegionRelationsBuilder<'this, 'tcx> {
infcx: &'this InferCtxt<'this, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
universal_regions: Rc<UniversalRegions<'tcx>>,
- implicit_region_bound: Option<ty::Region<'tcx>>,
+ implicit_region_bound: ty::Region<'tcx>,
constraints: &'this mut MirTypeckRegionConstraints<'tcx>,
// outputs:
diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs
index 2259a59e195..2a6ca5246da 100644
--- a/compiler/rustc_borrowck/src/type_check/input_output.rs
+++ b/compiler/rustc_borrowck/src/type_check/input_output.rs
@@ -230,7 +230,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.infcx,
&self.borrowck_context.universal_regions,
&self.region_bound_pairs,
- Some(self.implicit_region_bound),
+ self.implicit_region_bound,
self.param_env,
Locations::All(DUMMY_SP),
DUMMY_SP,
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 355254fe942..542fc6b0f48 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -157,7 +157,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
} = free_region_relations::create(
infcx,
param_env,
- Some(implicit_region_bound),
+ implicit_region_bound,
universal_regions,
&mut constraints,
);
@@ -1142,7 +1142,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.infcx,
self.borrowck_context.universal_regions,
self.region_bound_pairs,
- Some(self.implicit_region_bound),
+ self.implicit_region_bound,
self.param_env,
locations,
locations.span(self.body),
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index c2c093f9f2f..89d84fcf09c 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -725,7 +725,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
where
T: TypeFoldable<'tcx>,
{
- self.tcx.fold_regions(value, &mut false, |_region, _depth| self.next_nll_region_var(origin))
+ self.tcx.fold_regions(value, |_region, _depth| self.next_nll_region_var(origin))
}
#[instrument(level = "debug", skip(self, indices))]
@@ -817,9 +817,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
where
T: TypeFoldable<'tcx>,
{
- tcx.fold_regions(value, &mut false, |region, _| {
- tcx.mk_region(ty::ReVar(self.to_region_vid(region)))
- })
+ tcx.fold_regions(value, |region, _| tcx.mk_region(ty::ReVar(self.to_region_vid(region))))
}
}
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index cad30181212..9e50d33486c 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -1,11 +1,10 @@
-use crate::assert::expr_if_not;
use rustc_ast::{
attr,
ptr::P,
token,
tokenstream::{DelimSpan, TokenStream, TokenTree},
- BorrowKind, Expr, ExprKind, ItemKind, MacArgs, MacCall, MacDelimiter, Mutability, Path,
- PathSegment, Stmt, StructRest, UseTree, UseTreeKind, DUMMY_NODE_ID,
+ BinOpKind, BorrowKind, Expr, ExprKind, ItemKind, MacArgs, MacCall, MacDelimiter, Mutability,
+ Path, PathSegment, Stmt, StructRest, UnOp, UseTree, UseTreeKind, DUMMY_NODE_ID,
};
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet;
@@ -16,11 +15,19 @@ use rustc_span::{
};
pub(super) struct Context<'cx, 'a> {
+ // An optimization.
+ //
+ // Elements that aren't consumed (PartialEq, PartialOrd, ...) can be copied **after** the
+ // `assert!` expression fails rather than copied on-the-fly.
+ best_case_captures: Vec<Stmt>,
// Top-level `let captureN = Capture::new()` statements
capture_decls: Vec<Capture>,
cx: &'cx ExtCtxt<'a>,
// Formatting string used for debugging
fmt_string: String,
+ // If the current expression being visited consumes itself. Used to construct
+ // `best_case_captures`.
+ is_consumed: bool,
// Top-level `let __local_bindN = &expr` statements
local_bind_decls: Vec<Stmt>,
// Used to avoid capturing duplicated paths
@@ -36,9 +43,11 @@ pub(super) struct Context<'cx, 'a> {
impl<'cx, 'a> Context<'cx, 'a> {
pub(super) fn new(cx: &'cx ExtCtxt<'a>, span: Span) -> Self {
Self {
+ best_case_captures: <_>::default(),
capture_decls: <_>::default(),
cx,
fmt_string: <_>::default(),
+ is_consumed: true,
local_bind_decls: <_>::default(),
paths: <_>::default(),
span,
@@ -69,14 +78,22 @@ impl<'cx, 'a> Context<'cx, 'a> {
self.manage_cond_expr(&mut cond_expr);
let initial_imports = self.build_initial_imports();
let panic = self.build_panic(&expr_str, panic_path);
+ let cond_expr_with_unlikely = self.build_unlikely(cond_expr);
+
+ let Self { best_case_captures, capture_decls, cx, local_bind_decls, span, .. } = self;
- let Self { capture_decls, cx, local_bind_decls, span, .. } = self;
+ let mut assert_then_stmts = Vec::with_capacity(2);
+ assert_then_stmts.extend(best_case_captures);
+ assert_then_stmts.push(self.cx.stmt_expr(panic));
+ let assert_then = self.cx.block(span, assert_then_stmts);
let mut stmts = Vec::with_capacity(4);
stmts.push(initial_imports);
stmts.extend(capture_decls.into_iter().map(|c| c.decl));
stmts.extend(local_bind_decls);
- stmts.push(cx.stmt_expr(expr_if_not(cx, span, cond_expr, panic, None)));
+ stmts.push(
+ cx.stmt_expr(cx.expr(span, ExprKind::If(cond_expr_with_unlikely, assert_then, None))),
+ );
cx.expr_block(cx.block(span, stmts))
}
@@ -115,6 +132,16 @@ impl<'cx, 'a> Context<'cx, 'a> {
)
}
+ /// Takes the conditional expression of `assert!` and then wraps it inside `unlikely`
+ fn build_unlikely(&self, cond_expr: P<Expr>) -> P<Expr> {
+ let unlikely_path = self.cx.std_path(&[sym::intrinsics, sym::unlikely]);
+ self.cx.expr_call(
+ self.span,
+ self.cx.expr_path(self.cx.path(self.span, unlikely_path)),
+ vec![self.cx.expr(self.span, ExprKind::Unary(UnOp::Not, cond_expr))],
+ )
+ }
+
/// The necessary custom `panic!(...)` expression.
///
/// panic!(
@@ -167,17 +194,39 @@ impl<'cx, 'a> Context<'cx, 'a> {
/// See [Self::manage_initial_capture] and [Self::manage_try_capture]
fn manage_cond_expr(&mut self, expr: &mut P<Expr>) {
match (*expr).kind {
- ExprKind::AddrOf(_, _, ref mut local_expr) => {
- self.manage_cond_expr(local_expr);
+ ExprKind::AddrOf(_, mutability, ref mut local_expr) => {
+ self.with_is_consumed_management(
+ matches!(mutability, Mutability::Mut),
+ |this| this.manage_cond_expr(local_expr)
+ );
}
ExprKind::Array(ref mut local_exprs) => {
for local_expr in local_exprs {
self.manage_cond_expr(local_expr);
}
}
- ExprKind::Binary(_, ref mut lhs, ref mut rhs) => {
- self.manage_cond_expr(lhs);
- self.manage_cond_expr(rhs);
+ ExprKind::Binary(ref op, ref mut lhs, ref mut rhs) => {
+ self.with_is_consumed_management(
+ matches!(
+ op.node,
+ BinOpKind::Add
+ | BinOpKind::And
+ | BinOpKind::BitAnd
+ | BinOpKind::BitOr
+ | BinOpKind::BitXor
+ | BinOpKind::Div
+ | BinOpKind::Mul
+ | BinOpKind::Or
+ | BinOpKind::Rem
+ | BinOpKind::Shl
+ | BinOpKind::Shr
+ | BinOpKind::Sub
+ ),
+ |this| {
+ this.manage_cond_expr(lhs);
+ this.manage_cond_expr(rhs);
+ }
+ );
}
ExprKind::Call(_, ref mut local_exprs) => {
for local_expr in local_exprs {
@@ -228,8 +277,11 @@ impl<'cx, 'a> Context<'cx, 'a> {
self.manage_cond_expr(local_expr);
}
}
- ExprKind::Unary(_, ref mut local_expr) => {
- self.manage_cond_expr(local_expr);
+ ExprKind::Unary(un_op, ref mut local_expr) => {
+ self.with_is_consumed_management(
+ matches!(un_op, UnOp::Neg | UnOp::Not),
+ |this| this.manage_cond_expr(local_expr)
+ );
}
// Expressions that are not worth or can not be captured.
//
@@ -337,9 +389,23 @@ impl<'cx, 'a> Context<'cx, 'a> {
))
.add_trailing_semicolon();
let local_bind_path = self.cx.expr_path(Path::from_ident(local_bind));
- let ret = self.cx.stmt_expr(local_bind_path);
- let block = self.cx.expr_block(self.cx.block(self.span, vec![try_capture_call, ret]));
- *expr = self.cx.expr_deref(self.span, block);
+ let rslt = if self.is_consumed {
+ let ret = self.cx.stmt_expr(local_bind_path);
+ self.cx.expr_block(self.cx.block(self.span, vec![try_capture_call, ret]))
+ } else {
+ self.best_case_captures.push(try_capture_call);
+ local_bind_path
+ };
+ *expr = self.cx.expr_deref(self.span, rslt);
+ }
+
+ // Calls `f` with the internal `is_consumed` set to `curr_is_consumed` and then
+ // sets the internal `is_consumed` back to its original value.
+ fn with_is_consumed_management(&mut self, curr_is_consumed: bool, f: impl FnOnce(&mut Self)) {
+ let prev_is_consumed = self.is_consumed;
+ self.is_consumed = curr_is_consumed;
+ f(self);
+ self.is_consumed = prev_is_consumed;
}
}
diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs
index c75d83bd0a0..aa355150b4f 100644
--- a/compiler/rustc_builtin_macros/src/cfg.rs
+++ b/compiler/rustc_builtin_macros/src/cfg.rs
@@ -36,7 +36,7 @@ pub fn expand_cfg(
}
#[derive(SessionDiagnostic)]
-#[error(slug = "builtin-macros-requires-cfg-pattern")]
+#[error(builtin_macros::requires_cfg_pattern)]
struct RequiresCfgPattern {
#[primary_span]
#[label]
@@ -44,7 +44,7 @@ struct RequiresCfgPattern {
}
#[derive(SessionDiagnostic)]
-#[error(slug = "builtin-macros-expected-one-cfg-pattern")]
+#[error(builtin_macros::expected_one_cfg_pattern)]
struct OneCfgPattern {
#[primary_span]
span: Span,
diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs
index ecf70da6d96..1fffd6f9727 100644
--- a/compiler/rustc_builtin_macros/src/deriving/debug.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs
@@ -3,14 +3,10 @@ use crate::deriving::generic::*;
use crate::deriving::path_std;
use rustc_ast::ptr::P;
-use rustc_ast::{self as ast, Expr, LocalKind, MetaItem};
+use rustc_ast::{self as ast, Expr, MetaItem};
use rustc_expand::base::{Annotatable, ExtCtxt};
-use rustc_span::symbol::{sym, Ident};
-use rustc_span::{Span, DUMMY_SP};
-
-fn make_mut_borrow(cx: &mut ExtCtxt<'_>, sp: Span, expr: P<Expr>) -> P<Expr> {
- cx.expr(sp, ast::ExprKind::AddrOf(ast::BorrowKind::Ref, ast::Mutability::Mut, expr))
-}
+use rustc_span::symbol::{sym, Ident, Symbol};
+use rustc_span::Span;
pub fn expand_deriving_debug(
cx: &mut ExtCtxt<'_>,
@@ -49,11 +45,7 @@ pub fn expand_deriving_debug(
trait_def.expand(cx, mitem, item, push)
}
-/// We use the debug builders to do the heavy lifting here
fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
- // build fmt.debug_struct(<name>).field(<fieldname>, &<fieldval>)....build()
- // or fmt.debug_tuple(<name>).field(&<fieldval>)....build()
- // based on the "shape".
let (ident, vdata, fields) = match substr.fields {
Struct(vdata, fields) => (substr.type_ident, *vdata, fields),
EnumMatching(_, _, v, fields) => (v.ident, &v.data, fields),
@@ -67,93 +59,130 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
let fmt = substr.nonself_args[0].clone();
- // Special fast path for unit variants. In the common case of an enum that is entirely unit
- // variants (i.e. a C-like enum), this fast path allows LLVM to eliminate the entire switch in
- // favor of a lookup table.
- if let ast::VariantData::Unit(..) = vdata {
- let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]);
- let expr = cx.expr_call_global(span, fn_path_write_str, vec![fmt, name]);
- let stmts = vec![cx.stmt_expr(expr)];
- let block = cx.block(span, stmts);
- return cx.expr_block(block);
- }
-
- let builder = Ident::new(sym::debug_trait_builder, span);
- let builder_expr = cx.expr_ident(span, builder);
-
- let mut stmts = Vec::with_capacity(fields.len() + 2);
- let fn_path_finish;
- match vdata {
+ // Struct and tuples are similar enough that we use the same code for both,
+ // with some extra pieces for structs due to the field names.
+ let (is_struct, args_per_field) = match vdata {
ast::VariantData::Unit(..) => {
- cx.span_bug(span, "unit variants should have been handled above");
+ // Special fast path for unit variants.
+ //let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]);
+ //return cx.expr_call_global(span, fn_path_write_str, vec![fmt, name]);
+ assert!(fields.is_empty());
+ (false, 0)
}
- ast::VariantData::Tuple(..) => {
- // tuple struct/"normal" variant
- let fn_path_debug_tuple = cx.std_path(&[sym::fmt, sym::Formatter, sym::debug_tuple]);
- let expr = cx.expr_call_global(span, fn_path_debug_tuple, vec![fmt, name]);
- let expr = make_mut_borrow(cx, span, expr);
- stmts.push(cx.stmt_let(span, false, builder, expr));
-
- for field in fields {
- // Use double indirection to make sure this works for unsized types
- let field = cx.expr_addr_of(field.span, field.self_.clone());
- let field = cx.expr_addr_of(field.span, field);
-
- let fn_path_field = cx.std_path(&[sym::fmt, sym::DebugTuple, sym::field]);
- let expr =
- cx.expr_call_global(span, fn_path_field, vec![builder_expr.clone(), field]);
-
- // Use `let _ = expr;` to avoid triggering the
- // unused_results lint.
- stmts.push(stmt_let_underscore(cx, span, expr));
- }
+ ast::VariantData::Tuple(..) => (false, 1),
+ ast::VariantData::Struct(..) => (true, 2),
+ };
- fn_path_finish = cx.std_path(&[sym::fmt, sym::DebugTuple, sym::finish]);
- }
- ast::VariantData::Struct(..) => {
- // normal struct/struct variant
- let fn_path_debug_struct = cx.std_path(&[sym::fmt, sym::Formatter, sym::debug_struct]);
- let expr = cx.expr_call_global(span, fn_path_debug_struct, vec![fmt, name]);
- let expr = make_mut_borrow(cx, span, expr);
- stmts.push(cx.stmt_let(DUMMY_SP, false, builder, expr));
-
- for field in fields {
+ // The number of fields that can be handled without an array.
+ const CUTOFF: usize = 5;
+
+ if fields.is_empty() {
+ // Special case for no fields.
+ let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]);
+ cx.expr_call_global(span, fn_path_write_str, vec![fmt, name])
+ } else if fields.len() <= CUTOFF {
+ // Few enough fields that we can use a specific-length method.
+ let debug = if is_struct {
+ format!("debug_struct_field{}_finish", fields.len())
+ } else {
+ format!("debug_tuple_field{}_finish", fields.len())
+ };
+ let fn_path_debug = cx.std_path(&[sym::fmt, sym::Formatter, Symbol::intern(&debug)]);
+
+ let mut args = Vec::with_capacity(2 + fields.len() * args_per_field);
+ args.extend([fmt, name]);
+ for i in 0..fields.len() {
+ let field = &fields[i];
+ if is_struct {
let name = cx.expr_lit(
field.span,
ast::LitKind::Str(field.name.unwrap().name, ast::StrStyle::Cooked),
);
-
- // Use double indirection to make sure this works for unsized types
- let fn_path_field = cx.std_path(&[sym::fmt, sym::DebugStruct, sym::field]);
- let field = cx.expr_addr_of(field.span, field.self_.clone());
- let field = cx.expr_addr_of(field.span, field);
- let expr = cx.expr_call_global(
- span,
- fn_path_field,
- vec![builder_expr.clone(), name, field],
- );
- stmts.push(stmt_let_underscore(cx, span, expr));
+ args.push(name);
}
- fn_path_finish = cx.std_path(&[sym::fmt, sym::DebugStruct, sym::finish]);
+ // Use double indirection to make sure this works for unsized types
+ let field = cx.expr_addr_of(field.span, field.self_.clone());
+ let field = cx.expr_addr_of(field.span, field);
+ args.push(field);
}
- }
+ cx.expr_call_global(span, fn_path_debug, args)
+ } else {
+ // Enough fields that we must use the any-length method.
+ let mut name_exprs = Vec::with_capacity(fields.len());
+ let mut value_exprs = Vec::with_capacity(fields.len());
+
+ for field in fields {
+ if is_struct {
+ name_exprs.push(cx.expr_lit(
+ field.span,
+ ast::LitKind::Str(field.name.unwrap().name, ast::StrStyle::Cooked),
+ ));
+ }
- let expr = cx.expr_call_global(span, fn_path_finish, vec![builder_expr]);
+ // Use double indirection to make sure this works for unsized types
+ let value_ref = cx.expr_addr_of(field.span, field.self_.clone());
+ value_exprs.push(cx.expr_addr_of(field.span, value_ref));
+ }
- stmts.push(cx.stmt_expr(expr));
- let block = cx.block(span, stmts);
- cx.expr_block(block)
-}
+ // `let names: &'static _ = &["field1", "field2"];`
+ let names_let = if is_struct {
+ let lt_static = Some(cx.lifetime_static(span));
+ let ty_static_ref =
+ cx.ty_rptr(span, cx.ty_infer(span), lt_static, ast::Mutability::Not);
+ Some(cx.stmt_let_ty(
+ span,
+ false,
+ Ident::new(sym::names, span),
+ Some(ty_static_ref),
+ cx.expr_array_ref(span, name_exprs),
+ ))
+ } else {
+ None
+ };
+
+ // `let values: &[&dyn Debug] = &[&&self.field1, &&self.field2];`
+ let path_debug = cx.path_global(span, cx.std_path(&[sym::fmt, sym::Debug]));
+ let ty_dyn_debug = cx.ty(
+ span,
+ ast::TyKind::TraitObject(vec![cx.trait_bound(path_debug)], ast::TraitObjectSyntax::Dyn),
+ );
+ let ty_slice = cx.ty(
+ span,
+ ast::TyKind::Slice(cx.ty_rptr(span, ty_dyn_debug, None, ast::Mutability::Not)),
+ );
+ let values_let = cx.stmt_let_ty(
+ span,
+ false,
+ Ident::new(sym::values, span),
+ Some(cx.ty_rptr(span, ty_slice, None, ast::Mutability::Not)),
+ cx.expr_array_ref(span, value_exprs),
+ );
+
+ // `fmt::Formatter::debug_struct_fields_finish(fmt, name, names, values)` or
+ // `fmt::Formatter::debug_tuple_fields_finish(fmt, name, values)`
+ let sym_debug = if is_struct {
+ sym::debug_struct_fields_finish
+ } else {
+ sym::debug_tuple_fields_finish
+ };
+ let fn_path_debug_internal = cx.std_path(&[sym::fmt, sym::Formatter, sym_debug]);
+
+ let mut args = Vec::with_capacity(4);
+ args.push(fmt);
+ args.push(name);
+ if is_struct {
+ args.push(cx.expr_ident(span, Ident::new(sym::names, span)));
+ }
+ args.push(cx.expr_ident(span, Ident::new(sym::values, span)));
+ let expr = cx.expr_call_global(span, fn_path_debug_internal, args);
-fn stmt_let_underscore(cx: &mut ExtCtxt<'_>, sp: Span, expr: P<ast::Expr>) -> ast::Stmt {
- let local = P(ast::Local {
- pat: cx.pat_wild(sp),
- ty: None,
- id: ast::DUMMY_NODE_ID,
- kind: LocalKind::Init(expr),
- span: sp,
- attrs: ast::AttrVec::new(),
- tokens: None,
- });
- ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span: sp }
+ let mut stmts = Vec::with_capacity(3);
+ if is_struct {
+ stmts.push(names_let.unwrap());
+ }
+ stmts.push(values_let);
+ stmts.push(cx.stmt_expr(expr));
+
+ cx.expr_block(cx.block(span, stmts))
+ }
}
diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
index 1d892b20729..b39f35a9d40 100644
--- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
@@ -162,14 +162,13 @@ fn decodable_substructure(
cx.expr_match(trait_span, cx.expr_ident(trait_span, variant), arms),
);
let lambda = cx.lambda(trait_span, vec![blkarg, variant], result);
- let variant_vec = cx.expr_vec(trait_span, variants);
- let variant_vec = cx.expr_addr_of(trait_span, variant_vec);
+ let variant_array_ref = cx.expr_array_ref(trait_span, variants);
let fn_read_enum_variant_path: Vec<_> =
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum_variant]);
let result = cx.expr_call_global(
trait_span,
fn_read_enum_variant_path,
- vec![blkdecoder, variant_vec, lambda],
+ vec![blkdecoder, variant_array_ref, lambda],
);
let fn_read_enum_path: Vec<_> =
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum]);
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 10348c4967c..6c2ac343544 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -776,7 +776,7 @@ impl<'a, 'b> Context<'a, 'b> {
// First, build up the static array which will become our precompiled
// format "string"
- let pieces = self.ecx.expr_vec_slice(self.fmtsp, self.str_pieces);
+ let pieces = self.ecx.expr_array_ref(self.fmtsp, self.str_pieces);
// We need to construct a &[ArgumentV1] to pass into the fmt::Arguments
// constructor. In general the expressions in this slice might be
@@ -849,7 +849,7 @@ impl<'a, 'b> Context<'a, 'b> {
fmt_args.push(Context::format_arg(self.ecx, self.macsp, span, arg_ty, arg));
}
- let args_array = self.ecx.expr_vec(self.macsp, fmt_args);
+ let args_array = self.ecx.expr_array(self.macsp, fmt_args);
let args_slice = self.ecx.expr_addr_of(
self.macsp,
if no_need_for_match {
@@ -879,7 +879,7 @@ impl<'a, 'b> Context<'a, 'b> {
} else {
// Build up the static array which will store our precompiled
// nonstandard placeholders, if there are any.
- let fmt = self.ecx.expr_vec_slice(self.macsp, self.pieces);
+ let fmt = self.ecx.expr_array_ref(self.macsp, self.pieces);
let path = self.ecx.std_path(&[sym::fmt, sym::UnsafeArg, sym::new]);
let unsafe_arg = self.ecx.expr_call_global(self.macsp, path, Vec::new());
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index 03159d43950..5cfda33491d 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -317,7 +317,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
proc_macro_ty_method_path(cx, custom_derive),
vec![
cx.expr_str(span, cd.trait_name),
- cx.expr_vec_slice(
+ cx.expr_array_ref(
span,
cd.attrs.iter().map(|&s| cx.expr_str(span, s)).collect::<Vec<_>>(),
),
@@ -362,7 +362,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
ast::Mutability::Not,
),
ast::Mutability::Not,
- cx.expr_vec_slice(span, decls),
+ cx.expr_array_ref(span, decls),
)
.map(|mut i| {
let attr = cx.meta_word(span, sym::rustc_proc_macro_decls);
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index a08495f7671..e2a6e77ab44 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -352,7 +352,7 @@ fn mk_tests_slice(cx: &TestCtxt<'_>, sp: Span) -> P<ast::Expr> {
debug!("building test vector from {} tests", cx.test_cases.len());
let ecx = &cx.ext_cx;
- ecx.expr_vec_slice(
+ ecx.expr_array_ref(
sp,
cx.test_cases
.iter()
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index d46f2f38d3a..d5e68dbd5b7 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -56,15 +56,14 @@ impl<T: fmt::Display> fmt::Display for MemoryKind<T> {
}
}
-/// Used by `get_size_and_align` to indicate whether the allocation needs to be live.
-#[derive(Debug, Copy, Clone)]
-pub enum AllocCheck {
- /// Allocation must be live and not a function pointer.
- Dereferenceable,
- /// Allocations needs to be live, but may be a function pointer.
- Live,
- /// Allocation may be dead.
- MaybeDead,
+/// The return value of `get_alloc_info` indicates the "kind" of the allocation.
+pub enum AllocKind {
+ /// A regular live data allocation.
+ LiveData,
+ /// A function allocation (that fn ptrs point to).
+ Function,
+ /// A dead allocation.
+ Dead,
}
/// The value of a function pointer.
@@ -360,8 +359,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
align,
CheckInAllocMsg::MemoryAccessTest,
|alloc_id, offset, tag| {
- let (size, align) =
- self.get_alloc_size_and_align(alloc_id, AllocCheck::Dereferenceable)?;
+ let (size, align) = self.get_live_alloc_size_and_align(alloc_id)?;
Ok((size, align, (alloc_id, offset, tag)))
},
)
@@ -379,15 +377,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
msg: CheckInAllocMsg,
) -> InterpResult<'tcx> {
self.check_and_deref_ptr(ptr, size, Some(align), msg, |alloc_id, _, _| {
- let check = match msg {
- CheckInAllocMsg::DerefTest | CheckInAllocMsg::MemoryAccessTest => {
- AllocCheck::Dereferenceable
- }
- CheckInAllocMsg::PointerArithmeticTest
- | CheckInAllocMsg::OffsetFromTest
- | CheckInAllocMsg::InboundsTest => AllocCheck::Live,
- };
- let (size, align) = self.get_alloc_size_and_align(alloc_id, check)?;
+ let (size, align) = self.get_live_alloc_size_and_align(alloc_id)?;
Ok((size, align, ()))
})?;
Ok(())
@@ -655,30 +645,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// Obtain the size and alignment of an allocation, even if that allocation has
/// been deallocated.
- ///
- /// If `liveness` is `AllocCheck::MaybeDead`, this function always returns `Ok`.
- pub fn get_alloc_size_and_align(
- &self,
- id: AllocId,
- liveness: AllocCheck,
- ) -> InterpResult<'tcx, (Size, Align)> {
+ pub fn get_alloc_info(&self, id: AllocId) -> (Size, Align, AllocKind) {
// # Regular allocations
// Don't use `self.get_raw` here as that will
// a) cause cycles in case `id` refers to a static
// b) duplicate a global's allocation in miri
if let Some((_, alloc)) = self.memory.alloc_map.get(id) {
- return Ok((alloc.size(), alloc.align));
+ return (alloc.size(), alloc.align, AllocKind::LiveData);
}
// # Function pointers
// (both global from `alloc_map` and local from `extra_fn_ptr_map`)
if self.get_fn_alloc(id).is_some() {
- return if let AllocCheck::Dereferenceable = liveness {
- // The caller requested no function pointers.
- throw_ub!(DerefFunctionPointer(id))
- } else {
- Ok((Size::ZERO, Align::ONE))
- };
+ return (Size::ZERO, Align::ONE, AllocKind::Function);
}
// # Statics
@@ -690,32 +669,38 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Use size and align of the type.
let ty = self.tcx.type_of(did);
let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
- Ok((layout.size, layout.align.abi))
+ (layout.size, layout.align.abi, AllocKind::LiveData)
}
Some(GlobalAlloc::Memory(alloc)) => {
// Need to duplicate the logic here, because the global allocations have
// different associated types than the interpreter-local ones.
let alloc = alloc.inner();
- Ok((alloc.size(), alloc.align))
+ (alloc.size(), alloc.align, AllocKind::LiveData)
}
Some(GlobalAlloc::Function(_)) => bug!("We already checked function pointers above"),
// The rest must be dead.
None => {
- if let AllocCheck::MaybeDead = liveness {
- // Deallocated pointers are allowed, we should be able to find
- // them in the map.
- Ok(*self
- .memory
- .dead_alloc_map
- .get(&id)
- .expect("deallocated pointers should all be recorded in `dead_alloc_map`"))
- } else {
- throw_ub!(PointerUseAfterFree(id))
- }
+ // Deallocated pointers are allowed, we should be able to find
+ // them in the map.
+ let (size, align) = *self
+ .memory
+ .dead_alloc_map
+ .get(&id)
+ .expect("deallocated pointers should all be recorded in `dead_alloc_map`");
+ (size, align, AllocKind::Dead)
}
}
}
+ /// Obtain the size and alignment of a live allocation.
+ pub fn get_live_alloc_size_and_align(&self, id: AllocId) -> InterpResult<'tcx, (Size, Align)> {
+ let (size, align, kind) = self.get_alloc_info(id);
+ if matches!(kind, AllocKind::Dead) {
+ throw_ub!(PointerUseAfterFree(id))
+ }
+ Ok((size, align))
+ }
+
fn get_fn_alloc(&self, id: AllocId) -> Option<FnVal<'tcx, M::ExtraFnVal>> {
if let Some(extra) = self.memory.extra_fn_ptr_map.get(&id) {
Some(FnVal::Other(*extra))
@@ -1187,9 +1172,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let ptr = self.scalar_to_ptr(scalar)?;
match self.ptr_try_get_alloc_id(ptr) {
Ok((alloc_id, offset, _)) => {
- let (size, _align) = self
- .get_alloc_size_and_align(alloc_id, AllocCheck::MaybeDead)
- .expect("alloc info with MaybeDead cannot fail");
+ let (size, _align, _kind) = self.get_alloc_info(alloc_id);
// If the pointer is out-of-bounds, it may be null.
// Note that one-past-the-end (offset == size) is still inbounds, and never null.
offset > size
diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs
index 2b73ad568e0..92f0a7498e3 100644
--- a/compiler/rustc_const_eval/src/interpret/mod.rs
+++ b/compiler/rustc_const_eval/src/interpret/mod.rs
@@ -23,7 +23,7 @@ pub use self::eval_context::{
};
pub use self::intern::{intern_const_alloc_recursive, InternKind};
pub use self::machine::{compile_time_machine, AllocMap, Machine, MayLeak, StackPopJump};
-pub use self::memory::{AllocCheck, AllocRef, AllocRefMut, FnVal, Memory, MemoryKind};
+pub use self::memory::{AllocKind, AllocRef, AllocRefMut, FnVal, Memory, MemoryKind};
pub use self::operand::{ImmTy, Immediate, OpTy, Operand};
pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy};
pub use self::validity::{CtfeValidationMode, RefTracking};
diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs
index 88ff33b4d09..d8b26f9840b 100644
--- a/compiler/rustc_data_structures/src/profiling.rs
+++ b/compiler/rustc_data_structures/src/profiling.rs
@@ -826,6 +826,24 @@ cfg_if! {
}
}
}
+ } else if #[cfg(target_os = "macos")] {
+ pub fn get_resident_set_size() -> Option<usize> {
+ use libc::{c_int, c_void, getpid, proc_pidinfo, proc_taskinfo, PROC_PIDTASKINFO};
+ use std::mem;
+ const PROC_TASKINFO_SIZE: c_int = mem::size_of::<proc_taskinfo>() as c_int;
+
+ unsafe {
+ let mut info: proc_taskinfo = mem::zeroed();
+ let info_ptr = &mut info as *mut proc_taskinfo as *mut c_void;
+ let pid = getpid() as c_int;
+ let ret = proc_pidinfo(pid, PROC_PIDTASKINFO, 0, info_ptr, PROC_TASKINFO_SIZE);
+ if ret == PROC_TASKINFO_SIZE {
+ Some(info.pti_resident_size as usize)
+ } else {
+ None
+ }
+ }
+ }
} else if #[cfg(unix)] {
pub fn get_resident_set_size() -> Option<usize> {
let field = 1;
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index feb82cb0938..4437c0b1b69 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -21,6 +21,7 @@ use crate::owning_ref::{Erased, OwningRef};
use std::collections::HashMap;
use std::hash::{BuildHasher, Hash};
use std::ops::{Deref, DerefMut};
+use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};
pub use std::sync::atomic::Ordering;
pub use std::sync::atomic::Ordering::SeqCst;
@@ -41,7 +42,6 @@ cfg_if! {
}
use std::ops::Add;
- use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe};
/// This is a single threaded variant of `AtomicU64`, `AtomicUsize`, etc.
/// It has explicit ordering arguments and is only intended for use with
@@ -339,7 +339,10 @@ cfg_if! {
t: T,
for_each: impl Fn(T::Item) + Sync + Send,
) {
- t.into_par_iter().for_each(for_each)
+ let ps: Vec<_> = t.into_par_iter().map(|i| catch_unwind(AssertUnwindSafe(|| for_each(i)))).collect();
+ ps.into_iter().for_each(|p| if let Err(panic) = p {
+ resume_unwind(panic)
+ });
}
pub type MetadataRef = OwningRef<Box<dyn Erased + Send + Sync>, [u8]>;
diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs
index caa92e74808..3096af90d47 100644
--- a/compiler/rustc_driver/src/lib.rs
+++ b/compiler/rustc_driver/src/lib.rs
@@ -932,7 +932,7 @@ fn describe_codegen_flags() {
print_flag_list("-C", config::CG_OPTIONS);
}
-fn print_flag_list<T>(
+pub fn print_flag_list<T>(
cmdline_opt: &str,
flag_list: &[(&'static str, T, &'static str, &'static str)],
) {
diff --git a/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl b/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl
index 1d3e33c8185..4a42d52f710 100644
--- a/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl
@@ -1,5 +1,5 @@
-builtin-macros-requires-cfg-pattern =
+builtin_macros-requires-cfg-pattern =
macro requires a cfg-pattern as an argument
.label = cfg-pattern required
-builtin-macros-expected-one-cfg-pattern = expected 1 cfg-pattern
+builtin_macros-expected-one-cfg-pattern = expected 1 cfg-pattern
diff --git a/compiler/rustc_error_messages/locales/en-US/privacy.ftl b/compiler/rustc_error_messages/locales/en-US/privacy.ftl
new file mode 100644
index 00000000000..2b0778f48ca
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/privacy.ftl
@@ -0,0 +1,12 @@
+privacy-field-is-private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
+privacy-field-is-private-is-update-syntax-label = field `{$field_name}` is private
+privacy-field-is-private-label = private field
+
+privacy-item-is-private = {$kind} `{$descr}` is private
+ .label = private {$kind}
+privacy-unnamed-item-is-private = {$kind} is private
+ .label = private {$kind}
+
+privacy-in-public-interface = {$vis_descr} {$kind} `{$descr}` in public interface
+ .label = can't leak {$vis_descr} {$kind}
+ .visibility-label = `{$descr}` declared as {$vis_descr}
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 7211c054326..90eb5ef5446 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -32,6 +32,7 @@ pub use unic_langid::{langid, LanguageIdentifier};
// Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module.
fluent_messages! {
parser => "../locales/en-US/parser.ftl",
+ privacy => "../locales/en-US/privacy.ftl",
typeck => "../locales/en-US/typeck.ftl",
builtin_macros => "../locales/en-US/builtin_macros.ftl",
}
@@ -258,18 +259,6 @@ pub enum SubdiagnosticMessage {
FluentAttr(FluentId),
}
-impl SubdiagnosticMessage {
- /// Create a `SubdiagnosticMessage` for the provided Fluent attribute.
- pub fn attr(id: impl Into<FluentId>) -> Self {
- SubdiagnosticMessage::FluentAttr(id.into())
- }
-
- /// Create a `SubdiagnosticMessage` for the provided Fluent identifier.
- pub fn message(id: impl Into<FluentId>) -> Self {
- SubdiagnosticMessage::FluentIdentifier(id.into())
- }
-}
-
/// `From` impl that enables existing diagnostic calls to functions which now take
/// `impl Into<SubdiagnosticMessage>` to continue to work as before.
impl<S: Into<String>> From<S> for SubdiagnosticMessage {
@@ -332,11 +321,6 @@ impl DiagnosticMessage {
_ => panic!("expected non-translatable diagnostic message"),
}
}
-
- /// Create a `DiagnosticMessage` for the provided Fluent identifier.
- pub fn new(id: impl Into<FluentId>) -> Self {
- DiagnosticMessage::FluentIdentifier(id.into(), None)
- }
}
/// `From` impl that enables existing diagnostic calls to functions which now take
@@ -347,6 +331,27 @@ impl<S: Into<String>> From<S> for DiagnosticMessage {
}
}
+/// Translating *into* a subdiagnostic message from a diagnostic message is a little strange - but
+/// the subdiagnostic functions (e.g. `span_label`) take a `SubdiagnosticMessage` and the
+/// subdiagnostic derive refers to typed identifiers that are `DiagnosticMessage`s, so need to be
+/// able to convert between these, as much as they'll be converted back into `DiagnosticMessage`
+/// using `with_subdiagnostic_message` eventually. Don't use this other than for the derive.
+impl Into<SubdiagnosticMessage> for DiagnosticMessage {
+ fn into(self) -> SubdiagnosticMessage {
+ match self {
+ DiagnosticMessage::Str(s) => SubdiagnosticMessage::Str(s),
+ DiagnosticMessage::FluentIdentifier(id, None) => {
+ SubdiagnosticMessage::FluentIdentifier(id)
+ }
+ // There isn't really a sensible behaviour for this because it loses information but
+ // this is the most sensible of the behaviours.
+ DiagnosticMessage::FluentIdentifier(_, Some(attr)) => {
+ SubdiagnosticMessage::FluentAttr(attr)
+ }
+ }
+ }
+}
+
/// A span together with some additional data.
#[derive(Clone, Debug)]
pub struct SpanLabel {
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index a4cbc73978d..8b2a995f1c5 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -656,11 +656,6 @@ impl Emitter for SilentEmitter {
}
}
-/// Maximum number of lines we will print for a multiline suggestion; arbitrary.
-///
-/// This should be replaced with a more involved mechanism to output multiline suggestions that
-/// more closely mimics the regular diagnostic output, where irrelevant code lines are elided.
-pub const MAX_SUGGESTION_HIGHLIGHT_LINES: usize = 6;
/// Maximum number of suggestions to be shown
///
/// Arbitrary, but taken from trait import suggestion limit
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 245719bff12..1e57d66dd9f 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -1077,6 +1077,7 @@ impl<'a> ExtCtxt<'a> {
self.current_expansion.id.expansion_cause()
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_span_err<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -1101,9 +1102,11 @@ impl<'a> ExtCtxt<'a> {
///
/// Compilation will be stopped in the near future (at the end of
/// the macro expansion phase).
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
self.sess.parse_sess.span_diagnostic.span_err(sp, msg);
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
self.sess.parse_sess.span_diagnostic.span_warn(sp, msg);
}
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index e73c31c98fe..1694a8865dd 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -57,6 +57,10 @@ impl<'a> ExtCtxt<'a> {
P(ast::Ty { id: ast::DUMMY_NODE_ID, span, kind, tokens: None })
}
+ pub fn ty_infer(&self, span: Span) -> P<ast::Ty> {
+ self.ty(span, ast::TyKind::Infer)
+ }
+
pub fn ty_path(&self, path: ast::Path) -> P<ast::Ty> {
self.ty(path.span, ast::TyKind::Path(None, path))
}
@@ -140,11 +144,26 @@ impl<'a> ExtCtxt<'a> {
ast::Lifetime { id: ast::DUMMY_NODE_ID, ident: ident.with_span_pos(span) }
}
+ pub fn lifetime_static(&self, span: Span) -> ast::Lifetime {
+ self.lifetime(span, Ident::new(kw::StaticLifetime, span))
+ }
+
pub fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt {
ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) }
}
pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P<ast::Expr>) -> ast::Stmt {
+ self.stmt_let_ty(sp, mutbl, ident, None, ex)
+ }
+
+ pub fn stmt_let_ty(
+ &self,
+ sp: Span,
+ mutbl: bool,
+ ident: Ident,
+ ty: Option<P<ast::Ty>>,
+ ex: P<ast::Expr>,
+ ) -> ast::Stmt {
let pat = if mutbl {
let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Mut);
self.pat_ident_binding_mode(sp, ident, binding_mode)
@@ -153,7 +172,7 @@ impl<'a> ExtCtxt<'a> {
};
let local = P(ast::Local {
pat,
- ty: None,
+ ty,
id: ast::DUMMY_NODE_ID,
kind: LocalKind::Init(ex),
span: sp,
@@ -315,12 +334,16 @@ impl<'a> ExtCtxt<'a> {
self.expr_lit(sp, ast::LitKind::Bool(value))
}
- pub fn expr_vec(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
+ /// `[expr1, expr2, ...]`
+ pub fn expr_array(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
self.expr(sp, ast::ExprKind::Array(exprs))
}
- pub fn expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
- self.expr_addr_of(sp, self.expr_vec(sp, exprs))
+
+ /// `&[expr1, expr2, ...]`
+ pub fn expr_array_ref(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
+ self.expr_addr_of(sp, self.expr_array(sp, exprs))
}
+
pub fn expr_str(&self, sp: Span, s: Symbol) -> P<ast::Expr> {
self.expr_lit(sp, ast::LitKind::Str(s, ast::StrStyle::Cooked))
}
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index 86ff110eec1..c18147592dc 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -9,6 +9,7 @@
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_internals)]
#![feature(proc_macro_span)]
+#![feature(rustc_attrs)]
#![feature(try_blocks)]
#![recursion_limit = "256"]
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 1e4193a5a16..6b9bc0ab54b 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -14,7 +14,7 @@ use rustc_span::def_id::CrateNum;
use rustc_span::symbol::{self, kw, sym, Symbol};
use rustc_span::{BytePos, FileName, Pos, SourceFile, Span};
-use pm::bridge::{server, TokenTree};
+use pm::bridge::{server, ExpnGlobals, TokenTree};
use pm::{Delimiter, Level, LineColumn, Spacing};
use std::ops::Bound;
use std::{ascii, panic};
@@ -370,7 +370,7 @@ impl<'a, 'b> Rustc<'a, 'b> {
}
fn lit(&mut self, kind: token::LitKind, symbol: Symbol, suffix: Option<Symbol>) -> Literal {
- Literal { lit: token::Lit::new(kind, symbol, suffix), span: server::Span::call_site(self) }
+ Literal { lit: token::Lit::new(kind, symbol, suffix), span: self.call_site }
}
}
@@ -547,7 +547,7 @@ impl server::Group for Rustc<'_, '_> {
Group {
delimiter,
stream: stream.unwrap_or_default(),
- span: DelimSpan::from_single(server::Span::call_site(self)),
+ span: DelimSpan::from_single(self.call_site),
flatten: false,
}
}
@@ -579,7 +579,7 @@ impl server::Group for Rustc<'_, '_> {
impl server::Punct for Rustc<'_, '_> {
fn new(&mut self, ch: char, spacing: Spacing) -> Self::Punct {
- Punct::new(ch, spacing == Spacing::Joint, server::Span::call_site(self))
+ Punct::new(ch, spacing == Spacing::Joint, self.call_site)
}
fn as_char(&mut self, punct: Self::Punct) -> char {
@@ -829,18 +829,6 @@ impl server::Span for Rustc<'_, '_> {
}
}
- fn def_site(&mut self) -> Self::Span {
- self.def_site
- }
-
- fn call_site(&mut self) -> Self::Span {
- self.call_site
- }
-
- fn mixed_site(&mut self) -> Self::Span {
- self.mixed_site
- }
-
fn source_file(&mut self, span: Self::Span) -> Self::SourceFile {
self.sess().source_map().lookup_char_pos(span.lo()).file
}
@@ -926,3 +914,13 @@ impl server::Span for Rustc<'_, '_> {
})
}
}
+
+impl server::Server for Rustc<'_, '_> {
+ fn globals(&mut self) -> ExpnGlobals<Self::Span> {
+ ExpnGlobals {
+ def_site: self.def_site,
+ call_site: self.call_site,
+ mixed_site: self.mixed_site,
+ }
+ }
+}
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index e68274e2ad9..384a0f9c225 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -65,7 +65,6 @@
//! example generator inference, and possibly also HIR borrowck.
use crate::hir::*;
-use crate::itemlikevisit::ParItemLikeVisitor;
use rustc_ast::walk_list;
use rustc_ast::{Attribute, Label};
use rustc_span::symbol::{Ident, Symbol};
@@ -76,29 +75,6 @@ pub trait IntoVisitor<'hir> {
fn into_visitor(&self) -> Self::Visitor;
}
-pub struct ParDeepVisitor<V>(pub V);
-
-impl<'hir, V> ParItemLikeVisitor<'hir> for ParDeepVisitor<V>
-where
- V: IntoVisitor<'hir>,
-{
- fn visit_item(&self, item: &'hir Item<'hir>) {
- self.0.into_visitor().visit_item(item);
- }
-
- fn visit_trait_item(&self, trait_item: &'hir TraitItem<'hir>) {
- self.0.into_visitor().visit_trait_item(trait_item);
- }
-
- fn visit_impl_item(&self, impl_item: &'hir ImplItem<'hir>) {
- self.0.into_visitor().visit_impl_item(impl_item);
- }
-
- fn visit_foreign_item(&self, foreign_item: &'hir ForeignItem<'hir>) {
- self.0.into_visitor().visit_foreign_item(foreign_item);
- }
-}
-
#[derive(Copy, Clone, Debug)]
pub enum FnKind<'a> {
/// `#[xxx] pub async/const/extern "Abi" fn foo()`
diff --git a/compiler/rustc_hir/src/itemlikevisit.rs b/compiler/rustc_hir/src/itemlikevisit.rs
deleted file mode 100644
index a490268dc9f..00000000000
--- a/compiler/rustc_hir/src/itemlikevisit.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-use super::{ForeignItem, ImplItem, Item, TraitItem};
-
-/// A parallel variant of `ItemLikeVisitor`.
-pub trait ParItemLikeVisitor<'hir> {
- fn visit_item(&self, item: &'hir Item<'hir>);
- fn visit_trait_item(&self, trait_item: &'hir TraitItem<'hir>);
- fn visit_impl_item(&self, impl_item: &'hir ImplItem<'hir>);
- fn visit_foreign_item(&self, foreign_item: &'hir ForeignItem<'hir>);
-}
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index d845c433d8c..9f32a7da159 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -27,7 +27,6 @@ pub use rustc_span::def_id;
mod hir;
pub mod hir_id;
pub mod intravisit;
-pub mod itemlikevisit;
pub mod lang_items;
pub mod pat_util;
mod stable_hash_impls;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
index b9596cd10ed..42d52446ab6 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
@@ -79,7 +79,7 @@ pub fn find_param_with_region<'tcx>(
// May return None; sometimes the tables are not yet populated.
let ty = fn_sig.inputs()[index];
let mut found_anon_region = false;
- let new_param_ty = tcx.fold_regions(ty, &mut false, |r, _| {
+ let new_param_ty = tcx.fold_regions(ty, |r, _| {
if r == anon_region {
found_anon_region = true;
replace_region
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index 455de47acef..68c709a2e24 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -868,7 +868,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> {
where
T: TypeFoldable<'tcx>,
{
- tcx.fold_regions(value, &mut false, |r, _db| match *r {
+ tcx.fold_regions(value, |r, _db| match *r {
ty::ReVar(rid) => self.resolve_var(rid),
_ => r,
})
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 7684d861f3c..ebb8d443421 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -39,21 +39,19 @@ pub struct OpaqueTypeDecl<'tcx> {
}
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
- /// This is a backwards compatibility hack to prevent breaking changes from
- /// lazy TAIT around RPIT handling.
- pub fn replace_opaque_types_with_inference_vars<T: TypeFoldable<'tcx>>(
+ pub fn replace_opaque_types_with_inference_vars(
&self,
- value: T,
+ ty: Ty<'tcx>,
body_id: HirId,
span: Span,
code: ObligationCauseCode<'tcx>,
param_env: ty::ParamEnv<'tcx>,
- ) -> InferOk<'tcx, T> {
- if !value.has_opaque_types() {
- return InferOk { value, obligations: vec![] };
+ ) -> InferOk<'tcx, Ty<'tcx>> {
+ if !ty.has_opaque_types() {
+ return InferOk { value: ty, obligations: vec![] };
}
let mut obligations = vec![];
- let value = value.fold_with(&mut ty::fold::BottomUpFolder {
+ let value = ty.fold_with(&mut ty::fold::BottomUpFolder {
tcx: self.tcx,
lt_op: |lt| lt,
ct_op: |ct| ct,
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index a268493b28f..1c1906f3375 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -141,9 +141,6 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
/// `('a, K)` in this list tells us that the bounds in scope
/// indicate that `K: 'a`, where `K` is either a generic
/// parameter like `T` or a projection like `T::Item`.
- /// - `implicit_region_bound`: if some, this is a region bound
- /// that is considered to hold for all type parameters (the
- /// function body).
/// - `param_env` is the parameter environment for the enclosing function.
/// - `body_id` is the body-id whose region obligations are being
/// processed.
@@ -151,7 +148,6 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
pub fn process_registered_region_obligations(
&self,
region_bound_pairs_map: &FxHashMap<hir::HirId, RegionBoundPairs<'tcx>>,
- implicit_region_bound: Option<ty::Region<'tcx>>,
param_env: ty::ParamEnv<'tcx>,
) {
assert!(
@@ -170,13 +166,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
let sup_type = self.resolve_vars_if_possible(sup_type);
if let Some(region_bound_pairs) = region_bound_pairs_map.get(&body_id) {
- let outlives = &mut TypeOutlives::new(
- self,
- self.tcx,
- &region_bound_pairs,
- implicit_region_bound,
- param_env,
- );
+ let outlives =
+ &mut TypeOutlives::new(self, self.tcx, &region_bound_pairs, None, param_env);
outlives.type_must_outlive(origin, sup_type, sub_region);
} else {
self.tcx.sess.delay_span_bug(
diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index 191f5f18ec2..86b025dce5e 100644
--- a/compiler/rustc_infer/src/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
@@ -16,6 +16,11 @@ use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt};
pub struct VerifyBoundCx<'cx, 'tcx> {
tcx: TyCtxt<'tcx>,
region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
+ /// During borrowck, if there are no outlives bounds on a generic
+ /// parameter `T`, we assume that `T: 'in_fn_body` holds.
+ ///
+ /// Outside of borrowck the only way to prove `T: '?0` is by
+ /// setting `'?0` to `'empty`.
implicit_region_bound: Option<ty::Region<'tcx>>,
param_env: ty::ParamEnv<'tcx>,
}
@@ -263,8 +268,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
// fn foo<'a, A>(x: &'a A) { x.bar() }
//
// The problem is that the type of `x` is `&'a A`. To be
- // well-formed, then, A must be lower-generic by `'a`, but we
- // don't know that this holds from first principles.
+ // well-formed, then, A must outlive `'a`, but we don't know that
+ // this holds from first principles.
let from_region_bound_pairs = self.region_bound_pairs.iter().filter_map(|&(r, p)| {
debug!(
"declared_generic_bounds_from_env_for_erased_ty: region_bound_pair = {:?}",
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index fadb1c87933..56c8635a189 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -406,9 +406,12 @@ impl LateLintPass<'_> for Diagnostics {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
let Some((span, def_id, substs)) = typeck_results_of_method_fn(cx, expr) else { return };
debug!(?span, ?def_id, ?substs);
- if let Ok(Some(instance)) = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, substs) &&
- !cx.tcx.has_attr(instance.def_id(), sym::rustc_lint_diagnostics)
- {
+ let has_attr = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, substs)
+ .ok()
+ .and_then(|inst| inst)
+ .map(|inst| cx.tcx.has_attr(inst.def_id(), sym::rustc_lint_diagnostics))
+ .unwrap_or(false);
+ if !has_attr {
return;
}
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 2a2dc6822ce..5579e4d19cf 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -4,7 +4,6 @@ use rustc_attr as attr;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
use rustc_hir::{is_range_literal, Expr, ExprKind, Node};
use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton};
use rustc_middle::ty::subst::SubstsRef;
@@ -1483,39 +1482,32 @@ impl InvalidAtomicOrdering {
None
}
- fn matches_ordering(cx: &LateContext<'_>, did: DefId, orderings: &[Symbol]) -> bool {
+ fn match_ordering(cx: &LateContext<'_>, ord_arg: &Expr<'_>) -> Option<Symbol> {
+ let ExprKind::Path(ref ord_qpath) = ord_arg.kind else { return None };
+ let did = cx.qpath_res(ord_qpath, ord_arg.hir_id).opt_def_id()?;
let tcx = cx.tcx;
let atomic_ordering = tcx.get_diagnostic_item(sym::Ordering);
- orderings.iter().any(|ordering| {
- tcx.item_name(did) == *ordering && {
- let parent = tcx.parent(did);
- Some(parent) == atomic_ordering
- // needed in case this is a ctor, not a variant
- || tcx.opt_parent(parent) == atomic_ordering
- }
- })
- }
-
- fn opt_ordering_defid(cx: &LateContext<'_>, ord_arg: &Expr<'_>) -> Option<DefId> {
- if let ExprKind::Path(ref ord_qpath) = ord_arg.kind {
- cx.qpath_res(ord_qpath, ord_arg.hir_id).opt_def_id()
- } else {
- None
- }
+ let name = tcx.item_name(did);
+ let parent = tcx.parent(did);
+ [sym::Relaxed, sym::Release, sym::Acquire, sym::AcqRel, sym::SeqCst].into_iter().find(
+ |&ordering| {
+ name == ordering
+ && (Some(parent) == atomic_ordering
+ // needed in case this is a ctor, not a variant
+ || tcx.opt_parent(parent) == atomic_ordering)
+ },
+ )
}
fn check_atomic_load_store(cx: &LateContext<'_>, expr: &Expr<'_>) {
- use rustc_hir::def::{DefKind, Res};
- use rustc_hir::QPath;
if let Some((method, args)) = Self::inherent_atomic_method_call(cx, expr, &[sym::load, sym::store])
&& let Some((ordering_arg, invalid_ordering)) = match method {
sym::load => Some((&args[1], sym::Release)),
sym::store => Some((&args[2], sym::Acquire)),
_ => None,
}
- && let ExprKind::Path(QPath::Resolved(_, path)) = ordering_arg.kind
- && let Res::Def(DefKind::Ctor(..), ctor_id) = path.res
- && Self::matches_ordering(cx, ctor_id, &[invalid_ordering, sym::AcqRel])
+ && let Some(ordering) = Self::match_ordering(cx, ordering_arg)
+ && (ordering == invalid_ordering || ordering == sym::AcqRel)
{
cx.struct_span_lint(INVALID_ATOMIC_ORDERING, ordering_arg.span, |diag| {
if method == sym::load {
@@ -1537,9 +1529,7 @@ impl InvalidAtomicOrdering {
&& let ExprKind::Path(ref func_qpath) = func.kind
&& let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id()
&& matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::fence | sym::compiler_fence))
- && let ExprKind::Path(ref ordering_qpath) = &args[0].kind
- && let Some(ordering_def_id) = cx.qpath_res(ordering_qpath, args[0].hir_id).opt_def_id()
- && Self::matches_ordering(cx, ordering_def_id, &[sym::Relaxed])
+ && Self::match_ordering(cx, &args[0]) == Some(sym::Relaxed)
{
cx.struct_span_lint(INVALID_ATOMIC_ORDERING, args[0].span, |diag| {
diag.build("memory fences cannot have `Relaxed` ordering")
@@ -1550,62 +1540,56 @@ impl InvalidAtomicOrdering {
}
fn check_atomic_compare_exchange(cx: &LateContext<'_>, expr: &Expr<'_>) {
- if let Some((method, args)) = Self::inherent_atomic_method_call(cx, expr, &[sym::fetch_update, sym::compare_exchange, sym::compare_exchange_weak])
- && let Some((success_order_arg, failure_order_arg)) = match method {
- sym::fetch_update => Some((&args[1], &args[2])),
- sym::compare_exchange | sym::compare_exchange_weak => Some((&args[3], &args[4])),
- _ => None,
- }
- && let Some(fail_ordering_def_id) = Self::opt_ordering_defid(cx, failure_order_arg)
- {
- // Helper type holding on to some checking and error reporting data. Has
- // - (success ordering,
- // - list of failure orderings forbidden by the success order,
- // - suggestion message)
- type OrdLintInfo = (Symbol, &'static [Symbol], &'static str);
- const RELAXED: OrdLintInfo = (sym::Relaxed, &[sym::SeqCst, sym::Acquire], "ordering mode `Relaxed`");
- const ACQUIRE: OrdLintInfo = (sym::Acquire, &[sym::SeqCst], "ordering modes `Acquire` or `Relaxed`");
- const SEQ_CST: OrdLintInfo = (sym::SeqCst, &[], "ordering modes `Acquire`, `SeqCst` or `Relaxed`");
- const RELEASE: OrdLintInfo = (sym::Release, RELAXED.1, RELAXED.2);
- const ACQREL: OrdLintInfo = (sym::AcqRel, ACQUIRE.1, ACQUIRE.2);
- const SEARCH: [OrdLintInfo; 5] = [RELAXED, ACQUIRE, SEQ_CST, RELEASE, ACQREL];
-
- let success_lint_info = Self::opt_ordering_defid(cx, success_order_arg)
- .and_then(|success_ord_def_id| -> Option<OrdLintInfo> {
- SEARCH
- .iter()
- .copied()
- .find(|(ordering, ..)| {
- Self::matches_ordering(cx, success_ord_def_id, &[*ordering])
- })
- });
- if Self::matches_ordering(cx, fail_ordering_def_id, &[sym::Release, sym::AcqRel]) {
- // If we don't know the success order is, use what we'd suggest
- // if it were maximally permissive.
- let suggested = success_lint_info.unwrap_or(SEQ_CST).2;
- cx.struct_span_lint(INVALID_ATOMIC_ORDERING, failure_order_arg.span, |diag| {
- let msg = format!(
- "{}'s failure ordering may not be `Release` or `AcqRel`",
- method,
- );
- diag.build(&msg)
- .help(&format!("consider using {} instead", suggested))
- .emit();
- });
- } else if let Some((success_ord, bad_ords_given_success, suggested)) = success_lint_info {
- if Self::matches_ordering(cx, fail_ordering_def_id, bad_ords_given_success) {
- cx.struct_span_lint(INVALID_ATOMIC_ORDERING, failure_order_arg.span, |diag| {
- let msg = format!(
- "{}'s failure ordering may not be stronger than the success ordering of `{}`",
- method,
- success_ord,
- );
- diag.build(&msg)
- .help(&format!("consider using {} instead", suggested))
- .emit();
- });
- }
- }
+ let Some((method, args)) = Self::inherent_atomic_method_call(cx, expr, &[sym::fetch_update, sym::compare_exchange, sym::compare_exchange_weak])
+ else {return };
+
+ let (success_order_arg, fail_order_arg) = match method {
+ sym::fetch_update => (&args[1], &args[2]),
+ sym::compare_exchange | sym::compare_exchange_weak => (&args[3], &args[4]),
+ _ => return,
+ };
+
+ let Some(fail_ordering) = Self::match_ordering(cx, fail_order_arg) else { return };
+
+ if matches!(fail_ordering, sym::Release | sym::AcqRel) {
+ cx.struct_span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg.span, |diag| {
+ diag.build(&format!(
+ "`{method}`'s failure ordering may not be `Release` or `AcqRel`, \
+ since a failed `{method}` does not result in a write",
+ ))
+ .span_label(fail_order_arg.span, "invalid failure ordering")
+ .help("consider using `Acquire` or `Relaxed` failure ordering instead")
+ .emit();
+ });
+ }
+
+ let Some(success_ordering) = Self::match_ordering(cx, success_order_arg) else { return };
+
+ if matches!(
+ (success_ordering, fail_ordering),
+ (sym::Relaxed | sym::Release, sym::Acquire)
+ | (sym::Relaxed | sym::Release | sym::Acquire | sym::AcqRel, sym::SeqCst)
+ ) {
+ let success_suggestion =
+ if success_ordering == sym::Release && fail_ordering == sym::Acquire {
+ sym::AcqRel
+ } else {
+ fail_ordering
+ };
+ cx.struct_span_lint(INVALID_ATOMIC_ORDERING, success_order_arg.span, |diag| {
+ diag.build(&format!(
+ "`{method}`'s success ordering must be at least as strong as its failure ordering"
+ ))
+ .span_label(fail_order_arg.span, format!("`{fail_ordering}` failure ordering"))
+ .span_label(success_order_arg.span, format!("`{success_ordering}` success ordering"))
+ .span_suggestion_short(
+ success_order_arg.span,
+ format!("consider using `{success_suggestion}` success ordering instead"),
+ format!("std::sync::atomic::Ordering::{success_suggestion}"),
+ Applicability::MaybeIncorrect,
+ )
+ .emit();
+ });
}
}
}
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index b1bfd612b90..d52455e2576 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -289,6 +289,7 @@ declare_lint! {
"constant evaluation encountered erroneous expression",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #71800 <https://github.com/rust-lang/rust/issues/71800>",
+ reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow,
};
report_in_external_macro
}
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
index 95ee0d4a060..d0c86527189 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
@@ -12,7 +12,9 @@ use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote};
use std::collections::HashMap;
use std::str::FromStr;
-use syn::{spanned::Spanned, Attribute, Meta, MetaList, MetaNameValue, Type};
+use syn::{
+ parse_quote, spanned::Spanned, Attribute, Meta, MetaList, MetaNameValue, NestedMeta, Path, Type,
+};
use synstructure::{BindingInfo, Structure};
/// The central struct for constructing the `into_diagnostic` method from an annotated struct.
@@ -118,23 +120,23 @@ impl<'a> SessionDiagnosticDerive<'a> {
return SessionDiagnosticDeriveError::ErrorHandled.to_compile_error();
}
(Some((kind, _)), None) => {
- span_err(span, "`slug` not specified")
- .help(&format!("use the `#[{}(slug = \"...\")]` attribute to set this diagnostic's slug", kind.descr()))
+ span_err(span, "diagnostic slug not specified")
+ .help(&format!(
+ "specify the slug as the first argument to the attribute, such as \
+ `#[{}(typeck::example_error)]`",
+ kind.descr()
+ ))
.emit();
return SessionDiagnosticDeriveError::ErrorHandled.to_compile_error();
}
(Some((SessionDiagnosticKind::Error, _)), Some((slug, _))) => {
quote! {
- let mut #diag = #sess.struct_err(
- rustc_errors::DiagnosticMessage::new(#slug),
- );
+ let mut #diag = #sess.struct_err(rustc_errors::fluent::#slug);
}
}
(Some((SessionDiagnosticKind::Warn, _)), Some((slug, _))) => {
quote! {
- let mut #diag = #sess.struct_warn(
- rustc_errors::DiagnosticMessage::new(#slug),
- );
+ let mut #diag = #sess.struct_warn(rustc_errors::fluent::#slug);
}
}
};
@@ -226,7 +228,7 @@ struct SessionDiagnosticDeriveBuilder {
kind: Option<(SessionDiagnosticKind, proc_macro::Span)>,
/// Slug is a mandatory part of the struct attribute as corresponds to the Fluent message that
/// has the actual diagnostic message.
- slug: Option<(String, proc_macro::Span)>,
+ slug: Option<(Path, proc_macro::Span)>,
/// Error codes are a optional part of the struct attribute - this is only set to detect
/// multiple specifications.
code: Option<(String, proc_macro::Span)>,
@@ -240,50 +242,79 @@ impl HasFieldMap for SessionDiagnosticDeriveBuilder {
impl SessionDiagnosticDeriveBuilder {
/// Establishes state in the `SessionDiagnosticDeriveBuilder` resulting from the struct
- /// attributes like `#[error(..)#`, such as the diagnostic kind and slug. Generates
+ /// attributes like `#[error(..)`, such as the diagnostic kind and slug. Generates
/// diagnostic builder calls for setting error code and creating note/help messages.
fn generate_structure_code(
&mut self,
attr: &Attribute,
) -> Result<TokenStream, SessionDiagnosticDeriveError> {
+ let diag = &self.diag;
let span = attr.span().unwrap();
let name = attr.path.segments.last().unwrap().ident.to_string();
let name = name.as_str();
let meta = attr.parse_meta()?;
- if matches!(name, "help" | "note") && matches!(meta, Meta::Path(_) | Meta::NameValue(_)) {
- let diag = &self.diag;
- let id = match meta {
- Meta::Path(..) => quote! { #name },
- Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) => {
- quote! { #s }
- }
- _ => unreachable!(),
- };
- let fn_name = proc_macro2::Ident::new(name, attr.span());
-
- return Ok(quote! {
- #diag.#fn_name(rustc_errors::SubdiagnosticMessage::attr(#id));
- });
- }
+ let is_help_or_note = matches!(name, "help" | "note");
let nested = match meta {
+ // Most attributes are lists, like `#[error(..)]`/`#[warning(..)]` for most cases or
+ // `#[help(..)]`/`#[note(..)]` when the user is specifying a alternative slug.
Meta::List(MetaList { ref nested, .. }) => nested,
+ // Subdiagnostics without spans can be applied to the type too, and these are just
+ // paths: `#[help]` and `#[note]`
+ Meta::Path(_) if is_help_or_note => {
+ let fn_name = proc_macro2::Ident::new(name, attr.span());
+ return Ok(quote! { #diag.#fn_name(rustc_errors::fluent::_subdiag::#fn_name); });
+ }
_ => throw_invalid_attr!(attr, &meta),
};
- let kind = match name {
- "error" => SessionDiagnosticKind::Error,
- "warning" => SessionDiagnosticKind::Warn,
+ // Check the kind before doing any further processing so that there aren't misleading
+ // "no kind specified" errors if there are failures later.
+ match name {
+ "error" => self.kind.set_once((SessionDiagnosticKind::Error, span)),
+ "warning" => self.kind.set_once((SessionDiagnosticKind::Warn, span)),
+ "help" | "note" => (),
_ => throw_invalid_attr!(attr, &meta, |diag| {
- diag.help("only `error` and `warning` are valid attributes")
+ diag.help("only `error`, `warning`, `help` and `note` are valid attributes")
}),
- };
- self.kind.set_once((kind, span));
+ }
+
+ // First nested element should always be the path, e.g. `#[error(typeck::invalid)]` or
+ // `#[help(typeck::another_help)]`.
+ let mut nested_iter = nested.into_iter();
+ if let Some(nested_attr) = nested_iter.next() {
+ // Report an error if there are any other list items after the path.
+ if is_help_or_note && nested_iter.next().is_some() {
+ throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
+ diag.help("`help` and `note` struct attributes can only have one argument")
+ });
+ }
+ match nested_attr {
+ NestedMeta::Meta(Meta::Path(path)) if is_help_or_note => {
+ let fn_name = proc_macro2::Ident::new(name, attr.span());
+ return Ok(quote! { #diag.#fn_name(rustc_errors::fluent::#path); });
+ }
+ NestedMeta::Meta(Meta::Path(path)) => {
+ self.slug.set_once((path.clone(), span));
+ }
+ NestedMeta::Meta(meta @ Meta::NameValue(_))
+ if !is_help_or_note
+ && meta.path().segments.last().unwrap().ident.to_string() == "code" =>
+ {
+ // don't error for valid follow-up attributes
+ }
+ nested_attr => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
+ diag.help("first argument of the attribute should be the diagnostic slug")
+ }),
+ };
+ }
+
+ // Remaining attributes are optional, only `code = ".."` at the moment.
let mut tokens = Vec::new();
- for nested_attr in nested {
+ for nested_attr in nested_iter {
let meta = match nested_attr {
syn::NestedMeta::Meta(meta) => meta,
_ => throw_invalid_nested_attr!(attr, &nested_attr),
@@ -291,28 +322,24 @@ impl SessionDiagnosticDeriveBuilder {
let path = meta.path();
let nested_name = path.segments.last().unwrap().ident.to_string();
- match &meta {
- // Struct attributes are only allowed to be applied once, and the diagnostic
- // changes will be set in the initialisation code.
- Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) => {
- let span = s.span().unwrap();
- match nested_name.as_str() {
- "slug" => {
- self.slug.set_once((s.value(), span));
- }
- "code" => {
- self.code.set_once((s.value(), span));
- let (diag, code) = (&self.diag, &self.code.as_ref().map(|(v, _)| v));
- tokens.push(quote! {
- #diag.code(rustc_errors::DiagnosticId::Error(#code.to_string()));
- });
- }
- _ => invalid_nested_attr(attr, &nested_attr)
- .help("only `slug` and `code` are valid nested attributes")
- .emit(),
+ // Struct attributes are only allowed to be applied once, and the diagnostic
+ // changes will be set in the initialisation code.
+ if let Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) = &meta {
+ let span = s.span().unwrap();
+ match nested_name.as_str() {
+ "code" => {
+ self.code.set_once((s.value(), span));
+ let code = &self.code.as_ref().map(|(v, _)| v);
+ tokens.push(quote! {
+ #diag.code(rustc_errors::DiagnosticId::Error(#code.to_string()));
+ });
}
+ _ => invalid_nested_attr(attr, &nested_attr)
+ .help("only `code` is a valid nested attributes following the slug")
+ .emit(),
}
- _ => invalid_nested_attr(attr, &nested_attr).emit(),
+ } else {
+ invalid_nested_attr(attr, &nested_attr).emit()
}
}
@@ -382,142 +409,215 @@ impl SessionDiagnosticDeriveBuilder {
info: FieldInfo<'_>,
binding: TokenStream,
) -> Result<TokenStream, SessionDiagnosticDeriveError> {
+ let meta = attr.parse_meta()?;
+ match meta {
+ Meta::Path(_) => self.generate_inner_field_code_path(attr, info, binding),
+ Meta::List(MetaList { .. }) => self.generate_inner_field_code_list(attr, info, binding),
+ _ => throw_invalid_attr!(attr, &meta),
+ }
+ }
+
+ fn generate_inner_field_code_path(
+ &mut self,
+ attr: &Attribute,
+ info: FieldInfo<'_>,
+ binding: TokenStream,
+ ) -> Result<TokenStream, SessionDiagnosticDeriveError> {
+ assert!(matches!(attr.parse_meta()?, Meta::Path(_)));
let diag = &self.diag;
+ let meta = attr.parse_meta()?;
+
let ident = &attr.path.segments.last().unwrap().ident;
let name = ident.to_string();
let name = name.as_str();
+ match name {
+ "skip_arg" => {
+ // Don't need to do anything - by virtue of the attribute existing, the
+ // `set_arg` call will not be generated.
+ Ok(quote! {})
+ }
+ "primary_span" => {
+ report_error_if_not_applied_to_span(attr, &info)?;
+ Ok(quote! {
+ #diag.set_span(#binding);
+ })
+ }
+ "label" => {
+ report_error_if_not_applied_to_span(attr, &info)?;
+ Ok(self.add_spanned_subdiagnostic(binding, ident, parse_quote! { _subdiag::label }))
+ }
+ "note" | "help" => {
+ let path = match name {
+ "note" => parse_quote! { _subdiag::note },
+ "help" => parse_quote! { _subdiag::help },
+ _ => unreachable!(),
+ };
+ if type_matches_path(&info.ty, &["rustc_span", "Span"]) {
+ Ok(self.add_spanned_subdiagnostic(binding, ident, path))
+ } else if type_is_unit(&info.ty) {
+ Ok(self.add_subdiagnostic(ident, path))
+ } else {
+ report_type_error(attr, "`Span` or `()`")?;
+ }
+ }
+ "subdiagnostic" => Ok(quote! { #diag.subdiagnostic(#binding); }),
+ _ => throw_invalid_attr!(attr, &meta, |diag| {
+ diag.help(
+ "only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` \
+ are valid field attributes",
+ )
+ }),
+ }
+ }
+ fn generate_inner_field_code_list(
+ &mut self,
+ attr: &Attribute,
+ info: FieldInfo<'_>,
+ binding: TokenStream,
+ ) -> Result<TokenStream, SessionDiagnosticDeriveError> {
let meta = attr.parse_meta()?;
- match meta {
- Meta::Path(_) => match name {
- "skip_arg" => {
- // Don't need to do anything - by virtue of the attribute existing, the
- // `set_arg` call will not be generated.
- Ok(quote! {})
- }
- "primary_span" => {
- report_error_if_not_applied_to_span(attr, &info)?;
- Ok(quote! {
- #diag.set_span(#binding);
- })
- }
- "label" => {
- report_error_if_not_applied_to_span(attr, &info)?;
- Ok(self.add_spanned_subdiagnostic(binding, ident, name))
- }
- "note" | "help" => {
- if type_matches_path(&info.ty, &["rustc_span", "Span"]) {
- Ok(self.add_spanned_subdiagnostic(binding, ident, name))
- } else if type_is_unit(&info.ty) {
- Ok(self.add_subdiagnostic(ident, name))
- } else {
- report_type_error(attr, "`Span` or `()`")?;
- }
- }
- "subdiagnostic" => Ok(quote! { #diag.subdiagnostic(#binding); }),
- _ => throw_invalid_attr!(attr, &meta, |diag| {
- diag
- .help("only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` are valid field attributes")
- }),
- },
- Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(ref s), .. }) => match name {
- "label" => {
- report_error_if_not_applied_to_span(attr, &info)?;
- Ok(self.add_spanned_subdiagnostic(binding, ident, &s.value()))
- }
- "note" | "help" => {
- if type_matches_path(&info.ty, &["rustc_span", "Span"]) {
- Ok(self.add_spanned_subdiagnostic(binding, ident, &s.value()))
- } else if type_is_unit(&info.ty) {
- Ok(self.add_subdiagnostic(ident, &s.value()))
- } else {
- report_type_error(attr, "`Span` or `()`")?;
- }
- }
- _ => throw_invalid_attr!(attr, &meta, |diag| {
- diag.help("only `label`, `note` and `help` are valid field attributes")
- }),
- },
- Meta::List(MetaList { ref path, ref nested, .. }) => {
- let name = path.segments.last().unwrap().ident.to_string();
- let name = name.as_ref();
-
- match name {
- "suggestion" | "suggestion_short" | "suggestion_hidden"
- | "suggestion_verbose" => (),
- _ => throw_invalid_attr!(attr, &meta, |diag| {
- diag
- .help("only `suggestion{,_short,_hidden,_verbose}` are valid field attributes")
- }),
- };
+ let Meta::List(MetaList { ref path, ref nested, .. }) = meta else { unreachable!() };
- let (span_field, mut applicability) = self.span_and_applicability_of_ty(info)?;
+ let ident = &attr.path.segments.last().unwrap().ident;
+ let name = path.segments.last().unwrap().ident.to_string();
+ let name = name.as_ref();
+ match name {
+ "suggestion" | "suggestion_short" | "suggestion_hidden" | "suggestion_verbose" => {
+ return self.generate_inner_field_code_suggestion(attr, info);
+ }
+ "label" | "help" | "note" => (),
+ _ => throw_invalid_attr!(attr, &meta, |diag| {
+ diag.help(
+ "only `label`, `note`, `help` or `suggestion{,_short,_hidden,_verbose}` are \
+ valid field attributes",
+ )
+ }),
+ }
- let mut msg = None;
- let mut code = None;
+ // For `#[label(..)]`, `#[note(..)]` and `#[help(..)]`, the first nested element must be a
+ // path, e.g. `#[label(typeck::label)]`.
+ let mut nested_iter = nested.into_iter();
+ let msg = match nested_iter.next() {
+ Some(NestedMeta::Meta(Meta::Path(path))) => path.clone(),
+ Some(nested_attr) => throw_invalid_nested_attr!(attr, &nested_attr),
+ None => throw_invalid_attr!(attr, &meta),
+ };
- for nested_attr in nested {
- let meta = match nested_attr {
- syn::NestedMeta::Meta(ref meta) => meta,
- syn::NestedMeta::Lit(_) => throw_invalid_nested_attr!(attr, &nested_attr),
- };
+ // None of these attributes should have anything following the slug.
+ if nested_iter.next().is_some() {
+ throw_invalid_attr!(attr, &meta);
+ }
- let nested_name = meta.path().segments.last().unwrap().ident.to_string();
- let nested_name = nested_name.as_str();
- match meta {
- Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) => {
- let span = meta.span().unwrap();
- match nested_name {
- "message" => {
- msg = Some(s.value());
- }
- "code" => {
- let formatted_str = self.build_format(&s.value(), s.span());
- code = Some(formatted_str);
+ match name {
+ "label" => {
+ report_error_if_not_applied_to_span(attr, &info)?;
+ Ok(self.add_spanned_subdiagnostic(binding, ident, msg))
+ }
+ "note" | "help" if type_matches_path(&info.ty, &["rustc_span", "Span"]) => {
+ Ok(self.add_spanned_subdiagnostic(binding, ident, msg))
+ }
+ "note" | "help" if type_is_unit(&info.ty) => Ok(self.add_subdiagnostic(ident, msg)),
+ "note" | "help" => {
+ report_type_error(attr, "`Span` or `()`")?;
+ }
+ _ => unreachable!(),
+ }
+ }
+
+ fn generate_inner_field_code_suggestion(
+ &mut self,
+ attr: &Attribute,
+ info: FieldInfo<'_>,
+ ) -> Result<TokenStream, SessionDiagnosticDeriveError> {
+ let diag = &self.diag;
+
+ let mut meta = attr.parse_meta()?;
+ let Meta::List(MetaList { ref path, ref mut nested, .. }) = meta else { unreachable!() };
+
+ let (span_field, mut applicability) = self.span_and_applicability_of_ty(info)?;
+
+ let mut msg = None;
+ let mut code = None;
+
+ let mut nested_iter = nested.into_iter().peekable();
+ if let Some(nested_attr) = nested_iter.peek() {
+ if let NestedMeta::Meta(Meta::Path(path)) = nested_attr {
+ msg = Some(path.clone());
+ }
+ };
+ // Move the iterator forward if a path was found (don't otherwise so that
+ // code/applicability can be found or an error emitted).
+ if msg.is_some() {
+ let _ = nested_iter.next();
+ }
+
+ for nested_attr in nested_iter {
+ let meta = match nested_attr {
+ syn::NestedMeta::Meta(ref meta) => meta,
+ syn::NestedMeta::Lit(_) => throw_invalid_nested_attr!(attr, &nested_attr),
+ };
+
+ let nested_name = meta.path().segments.last().unwrap().ident.to_string();
+ let nested_name = nested_name.as_str();
+ match meta {
+ Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) => {
+ let span = meta.span().unwrap();
+ match nested_name {
+ "code" => {
+ let formatted_str = self.build_format(&s.value(), s.span());
+ code = Some(formatted_str);
+ }
+ "applicability" => {
+ applicability = match applicability {
+ Some(v) => {
+ span_err(
+ span,
+ "applicability cannot be set in both the field and \
+ attribute",
+ )
+ .emit();
+ Some(v)
}
- "applicability" => {
- applicability = match applicability {
- Some(v) => {
- span_err(
- span,
- "applicability cannot be set in both the field and attribute"
- ).emit();
- Some(v)
- }
- None => match Applicability::from_str(&s.value()) {
- Ok(v) => Some(quote! { #v }),
- Err(()) => {
- span_err(span, "invalid applicability").emit();
- None
- }
- },
+ None => match Applicability::from_str(&s.value()) {
+ Ok(v) => Some(quote! { #v }),
+ Err(()) => {
+ span_err(span, "invalid applicability").emit();
+ None
}
- }
- _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
- diag.help(
- "only `message`, `code` and `applicability` are valid field attributes",
- )
- }),
+ },
}
}
- _ => throw_invalid_nested_attr!(attr, &nested_attr),
+ _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
+ diag.help(
+ "only `message`, `code` and `applicability` are valid field \
+ attributes",
+ )
+ }),
}
}
+ _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
+ if matches!(meta, Meta::Path(_)) {
+ diag.help("a diagnostic slug must be the first argument to the attribute")
+ } else {
+ diag
+ }
+ }),
+ }
+ }
- let applicability = applicability
- .unwrap_or_else(|| quote!(rustc_errors::Applicability::Unspecified));
+ let applicability =
+ applicability.unwrap_or_else(|| quote!(rustc_errors::Applicability::Unspecified));
- let method = format_ident!("span_{}", name);
+ let name = path.segments.last().unwrap().ident.to_string();
+ let method = format_ident!("span_{}", name);
- let msg = msg.as_deref().unwrap_or("suggestion");
- let msg = quote! { rustc_errors::SubdiagnosticMessage::attr(#msg) };
- let code = code.unwrap_or_else(|| quote! { String::new() });
+ let msg = msg.unwrap_or_else(|| parse_quote! { _subdiag::suggestion });
+ let msg = quote! { rustc_errors::fluent::#msg };
+ let code = code.unwrap_or_else(|| quote! { String::new() });
- Ok(quote! { #diag.#method(#span_field, #msg, #code, #applicability); })
- }
- _ => throw_invalid_attr!(attr, &meta),
- }
+ Ok(quote! { #diag.#method(#span_field, #msg, #code, #applicability); })
}
/// Adds a spanned subdiagnostic by generating a `diag.span_$kind` call with the current slug
@@ -526,24 +626,24 @@ impl SessionDiagnosticDeriveBuilder {
&self,
field_binding: TokenStream,
kind: &Ident,
- fluent_attr_identifier: &str,
+ fluent_attr_identifier: Path,
) -> TokenStream {
let diag = &self.diag;
let fn_name = format_ident!("span_{}", kind);
quote! {
#diag.#fn_name(
#field_binding,
- rustc_errors::SubdiagnosticMessage::attr(#fluent_attr_identifier)
+ rustc_errors::fluent::#fluent_attr_identifier
);
}
}
/// Adds a subdiagnostic by generating a `diag.span_$kind` call with the current slug
/// and `fluent_attr_identifier`.
- fn add_subdiagnostic(&self, kind: &Ident, fluent_attr_identifier: &str) -> TokenStream {
+ fn add_subdiagnostic(&self, kind: &Ident, fluent_attr_identifier: Path) -> TokenStream {
let diag = &self.diag;
quote! {
- #diag.#kind(rustc_errors::SubdiagnosticMessage::attr(#fluent_attr_identifier));
+ #diag.#kind(rustc_errors::fluent::#fluent_attr_identifier);
}
}
@@ -569,7 +669,8 @@ impl SessionDiagnosticDeriveBuilder {
} else {
throw_span_err!(
info.span.unwrap(),
- "type of field annotated with `#[suggestion(...)]` contains more than one `Span`"
+ "type of field annotated with `#[suggestion(...)]` contains more \
+ than one `Span`"
);
}
} else if type_matches_path(elem, &["rustc_errors", "Applicability"]) {
@@ -578,7 +679,8 @@ impl SessionDiagnosticDeriveBuilder {
} else {
throw_span_err!(
info.span.unwrap(),
- "type of field annotated with `#[suggestion(...)]` contains more than one Applicability"
+ "type of field annotated with `#[suggestion(...)]` contains more \
+ than one Applicability"
);
}
}
@@ -595,12 +697,18 @@ impl SessionDiagnosticDeriveBuilder {
}
throw_span_err!(info.span.unwrap(), "wrong types for suggestion", |diag| {
- diag.help("`#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)`")
+ diag.help(
+ "`#[suggestion(...)]` on a tuple field must be applied to fields of type \
+ `(Span, Applicability)`",
+ )
});
}
// If `ty` isn't a `Span` or `(Span, Applicability)` then emit an error.
_ => throw_span_err!(info.span.unwrap(), "wrong field type for suggestion", |diag| {
- diag.help("`#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)`")
+ diag.help(
+ "`#[suggestion(...)]` should be applied to fields of type `Span` or \
+ `(Span, Applicability)`",
+ )
}),
}
}
diff --git a/compiler/rustc_macros/src/diagnostics/error.rs b/compiler/rustc_macros/src/diagnostics/error.rs
index fd1dc2f3073..d088402abc6 100644
--- a/compiler/rustc_macros/src/diagnostics/error.rs
+++ b/compiler/rustc_macros/src/diagnostics/error.rs
@@ -39,6 +39,19 @@ pub(crate) fn _throw_err(
SessionDiagnosticDeriveError::ErrorHandled
}
+/// Helper function for printing `syn::Path` - doesn't handle arguments in paths and these are
+/// unlikely to come up much in use of the macro.
+fn path_to_string(path: &syn::Path) -> String {
+ let mut out = String::new();
+ for (i, segment) in path.segments.iter().enumerate() {
+ if i > 0 || path.leading_colon.is_some() {
+ out.push_str("::");
+ }
+ out.push_str(&segment.ident.to_string());
+ }
+ out
+}
+
/// Returns an error diagnostic on span `span` with msg `msg`.
pub(crate) fn span_err(span: impl MultiSpan, msg: &str) -> Diagnostic {
Diagnostic::spanned(span, Level::Error, msg)
@@ -61,15 +74,13 @@ pub(crate) use throw_span_err;
/// Returns an error diagnostic for an invalid attribute.
pub(crate) fn invalid_attr(attr: &Attribute, meta: &Meta) -> Diagnostic {
let span = attr.span().unwrap();
- let name = attr.path.segments.last().unwrap().ident.to_string();
- let name = name.as_str();
-
+ let path = path_to_string(&attr.path);
match meta {
- Meta::Path(_) => span_err(span, &format!("`#[{}]` is not a valid attribute", name)),
+ Meta::Path(_) => span_err(span, &format!("`#[{}]` is not a valid attribute", path)),
Meta::NameValue(_) => {
- span_err(span, &format!("`#[{} = ...]` is not a valid attribute", name))
+ span_err(span, &format!("`#[{} = ...]` is not a valid attribute", path))
}
- Meta::List(_) => span_err(span, &format!("`#[{}(...)]` is not a valid attribute", name)),
+ Meta::List(_) => span_err(span, &format!("`#[{}(...)]` is not a valid attribute", path)),
}
}
@@ -101,18 +112,16 @@ pub(crate) fn invalid_nested_attr(attr: &Attribute, nested: &NestedMeta) -> Diag
};
let span = meta.span().unwrap();
- let nested_name = meta.path().segments.last().unwrap().ident.to_string();
- let nested_name = nested_name.as_str();
+ let path = path_to_string(meta.path());
match meta {
- Meta::NameValue(..) => span_err(
- span,
- &format!("`#[{}({} = ...)]` is not a valid attribute", name, nested_name),
- ),
+ Meta::NameValue(..) => {
+ span_err(span, &format!("`#[{}({} = ...)]` is not a valid attribute", name, path))
+ }
Meta::Path(..) => {
- span_err(span, &format!("`#[{}({})]` is not a valid attribute", name, nested_name))
+ span_err(span, &format!("`#[{}({})]` is not a valid attribute", name, path))
}
Meta::List(..) => {
- span_err(span, &format!("`#[{}({}(...))]` is not a valid attribute", name, nested_name))
+ span_err(span, &format!("`#[{}({}(...))]` is not a valid attribute", name, path))
}
}
}
diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs
index 42a9bf477a4..2317186e655 100644
--- a/compiler/rustc_macros/src/diagnostics/fluent.rs
+++ b/compiler/rustc_macros/src/diagnostics/fluent.rs
@@ -254,6 +254,17 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
];
#generated
+
+ pub mod _subdiag {
+ pub const note: crate::SubdiagnosticMessage =
+ crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("note"));
+ pub const help: crate::SubdiagnosticMessage =
+ crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("help"));
+ pub const label: crate::SubdiagnosticMessage =
+ crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("label"));
+ pub const suggestion: crate::SubdiagnosticMessage =
+ crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("suggestion"));
+ }
}
}
.into()
diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs
index 69573d904d4..2eee4bfb5dd 100644
--- a/compiler/rustc_macros/src/diagnostics/mod.rs
+++ b/compiler/rustc_macros/src/diagnostics/mod.rs
@@ -22,14 +22,14 @@ use synstructure::Structure;
/// # extern crate rust_middle;
/// # use rustc_middle::ty::Ty;
/// #[derive(SessionDiagnostic)]
-/// #[error(code = "E0505", slug = "borrowck-move-out-of-borrow")]
+/// #[error(borrowck::move_out_of_borrow, code = "E0505")]
/// pub struct MoveOutOfBorrowError<'tcx> {
/// pub name: Ident,
/// pub ty: Ty<'tcx>,
/// #[primary_span]
/// #[label]
/// pub span: Span,
-/// #[label = "first-borrow-label"]
+/// #[label(borrowck::first_borrow_label)]
/// pub first_borrow_span: Span,
/// #[suggestion(code = "{name}.clone()")]
/// pub clone_sugg: Option<(Span, Applicability)>
@@ -72,12 +72,12 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
/// ```ignore (rust)
/// #[derive(SessionSubdiagnostic)]
/// pub enum ExpectedIdentifierLabel<'tcx> {
-/// #[label(slug = "parser-expected-identifier")]
+/// #[label(parser::expected_identifier)]
/// WithoutFound {
/// #[primary_span]
/// span: Span,
/// }
-/// #[label(slug = "parser-expected-identifier-found")]
+/// #[label(parser::expected_identifier_found)]
/// WithFound {
/// #[primary_span]
/// span: Span,
@@ -86,7 +86,7 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
/// }
///
/// #[derive(SessionSubdiagnostic)]
-/// #[suggestion_verbose(slug = "parser-raw-identifier")]
+/// #[suggestion_verbose(parser::raw_identifier)]
/// pub struct RawIdentifierSuggestion<'tcx> {
/// #[primary_span]
/// span: Span,
diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
index 9aeb484bfd5..eab954a9c1b 100644
--- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
@@ -13,7 +13,7 @@ use quote::{format_ident, quote};
use std::collections::HashMap;
use std::fmt;
use std::str::FromStr;
-use syn::{spanned::Spanned, Meta, MetaList, MetaNameValue};
+use syn::{parse_quote, spanned::Spanned, Meta, MetaList, MetaNameValue, NestedMeta, Path};
use synstructure::{BindingInfo, Structure, VariantInfo};
/// Which kind of suggestion is being created?
@@ -194,8 +194,8 @@ struct SessionSubdiagnosticDeriveBuilder<'a> {
kind: Option<(SubdiagnosticKind, proc_macro::Span)>,
/// Slug of the subdiagnostic - corresponds to the Fluent identifier for the message - from the
- /// `#[kind(slug = "...")]` attribute on the type or variant.
- slug: Option<(String, proc_macro::Span)>,
+ /// `#[kind(slug)]` attribute on the type or variant.
+ slug: Option<(Path, proc_macro::Span)>,
/// If a suggestion, the code to suggest as a replacement - from the `#[kind(code = "...")]`
/// attribute on the type or variant.
code: Option<(TokenStream, proc_macro::Span)>,
@@ -224,9 +224,34 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
let meta = attr.parse_meta()?;
let kind = match meta {
Meta::List(MetaList { ref nested, .. }) => {
- for nested_attr in nested {
+ let mut nested_iter = nested.into_iter();
+ if let Some(nested_attr) = nested_iter.next() {
+ match nested_attr {
+ NestedMeta::Meta(Meta::Path(path)) => {
+ self.slug.set_once((path.clone(), span));
+ }
+ NestedMeta::Meta(meta @ Meta::NameValue(_))
+ if matches!(
+ meta.path().segments.last().unwrap().ident.to_string().as_str(),
+ "code" | "applicability"
+ ) =>
+ {
+ // don't error for valid follow-up attributes
+ }
+ nested_attr => {
+ throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
+ diag.help(
+ "first argument of the attribute should be the diagnostic \
+ slug",
+ )
+ })
+ }
+ };
+ }
+
+ for nested_attr in nested_iter {
let meta = match nested_attr {
- syn::NestedMeta::Meta(ref meta) => meta,
+ NestedMeta::Meta(ref meta) => meta,
_ => throw_invalid_nested_attr!(attr, &nested_attr),
};
@@ -241,7 +266,6 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
let formatted_str = self.build_format(&s.value(), s.span());
self.code.set_once((formatted_str, span));
}
- "slug" => self.slug.set_once((s.value(), span)),
"applicability" => {
let value = match Applicability::from_str(&s.value()) {
Ok(v) => v,
@@ -253,11 +277,23 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
self.applicability.set_once((quote! { #value }, span));
}
_ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
- diag.help("only `code`, `slug` and `applicability` are valid nested attributes")
+ diag.help(
+ "only `code` and `applicability` are valid nested \
+ attributes",
+ )
}),
}
}
- _ => throw_invalid_nested_attr!(attr, &nested_attr),
+ _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
+ if matches!(meta, Meta::Path(_)) {
+ diag.help(
+ "a diagnostic slug must be the first argument to the \
+ attribute",
+ )
+ } else {
+ diag
+ }
+ }),
}
}
@@ -281,10 +317,27 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
);
}
+ if matches!(
+ kind,
+ SubdiagnosticKind::Label | SubdiagnosticKind::Help | SubdiagnosticKind::Note
+ ) && self.applicability.is_some()
+ {
+ throw_span_err!(
+ span,
+ &format!(
+ "`applicability` is not a valid nested attribute of a `{}` attribute",
+ name
+ )
+ );
+ }
+
if self.slug.is_none() {
throw_span_err!(
span,
- &format!("`slug` must be set in a `#[{}(...)]` attribute", name)
+ &format!(
+ "diagnostic slug must be first argument of a `#[{}(...)]` attribute",
+ name
+ )
);
}
@@ -335,7 +388,10 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
return Ok(quote! {});
}
_ => throw_invalid_attr!(attr, &meta, |diag| {
- diag.help("only `primary_span`, `applicability` and `skip_arg` are valid field attributes")
+ diag.help(
+ "only `primary_span`, `applicability` and `skip_arg` are valid field \
+ attributes",
+ )
}),
},
_ => throw_invalid_attr!(attr, &meta),
@@ -375,7 +431,11 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
}
// Missing slug errors will already have been reported.
- let slug = self.slug.as_ref().map(|(slug, _)| &**slug).unwrap_or("missing-slug");
+ let slug = self
+ .slug
+ .as_ref()
+ .map(|(slug, _)| slug.clone())
+ .unwrap_or_else(|| parse_quote! { you::need::to::specify::a::slug });
let code = match self.code.as_ref() {
Some((code, _)) => Some(quote! { #code }),
None if is_suggestion => {
@@ -397,7 +457,7 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
let diag = &self.diag;
let name = format_ident!("{}{}", if span_field.is_some() { "span_" } else { "" }, kind);
- let message = quote! { rustc_errors::SubdiagnosticMessage::message(#slug) };
+ let message = quote! { rustc_errors::fluent::#slug };
let call = if matches!(kind, SubdiagnosticKind::Suggestion(..)) {
if let Some(span) = span_field {
quote! { #diag.#name(#span, #message, #code, #applicability); }
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 738d47ba296..a27b8470e95 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -612,23 +612,6 @@ impl<'hir> Map<'hir> {
}
}
- /// A parallel version of `visit_all_item_likes`.
- pub fn par_visit_all_item_likes<V>(self, visitor: &V)
- where
- V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send,
- {
- let krate = self.krate();
- par_for_each_in(&krate.owners.raw, |owner| match owner.map(OwnerInfo::node) {
- MaybeOwner::Owner(OwnerNode::Item(item)) => visitor.visit_item(item),
- MaybeOwner::Owner(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item),
- MaybeOwner::Owner(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item),
- MaybeOwner::Owner(OwnerNode::TraitItem(item)) => visitor.visit_trait_item(item),
- MaybeOwner::Owner(OwnerNode::Crate(_))
- | MaybeOwner::NonOwner(_)
- | MaybeOwner::Phantom => {}
- })
- }
-
/// If you don't care about nesting, you should use the
/// `tcx.hir_module_items()` query or `module_items()` instead.
/// Please see notes in `deep_visit_all_item_likes`.
@@ -867,6 +850,10 @@ impl<'hir> Map<'hir> {
)
}
+ pub fn expect_owner(self, id: LocalDefId) -> OwnerNode<'hir> {
+ self.tcx.hir_owner(id).unwrap_or_else(|| bug!("expected owner for {:?}", id)).node
+ }
+
pub fn expect_item(self, id: LocalDefId) -> &'hir Item<'hir> {
match self.tcx.hir_owner(id) {
Some(Owner { node: OwnerNode::Item(item), .. }) => item,
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index 09b142e0c41..8622a620721 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -10,6 +10,7 @@ use crate::ty::query::Providers;
use crate::ty::{DefIdTree, ImplSubject, TyCtxt};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::*;
use rustc_query_system::ich::StableHashingContext;
@@ -61,6 +62,22 @@ impl ModuleItems {
pub fn foreign_items(&self) -> impl Iterator<Item = ForeignItemId> + '_ {
self.foreign_items.iter().copied()
}
+
+ pub fn par_items(&self, f: impl Fn(ItemId) + Send + Sync) {
+ par_for_each_in(&self.items[..], |&id| f(id))
+ }
+
+ pub fn par_trait_items(&self, f: impl Fn(TraitItemId) + Send + Sync) {
+ par_for_each_in(&self.trait_items[..], |&id| f(id))
+ }
+
+ pub fn par_impl_items(&self, f: impl Fn(ImplItemId) + Send + Sync) {
+ par_for_each_in(&self.impl_items[..], |&id| f(id))
+ }
+
+ pub fn par_foreign_items(&self, f: impl Fn(ForeignItemId) + Send + Sync) {
+ par_for_each_in(&self.foreign_items[..], |&id| f(id))
+ }
}
impl<'tcx> TyCtxt<'tcx> {
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index ca2c03cb614..2e68fc8a7c0 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -826,6 +826,10 @@ rustc_queries! {
desc { |tcx| "checking that impls are well-formed in {}", describe_as_module(key, tcx) }
}
+ query check_mod_type_wf(key: LocalDefId) -> () {
+ desc { |tcx| "checking that types are well-formed in {}", describe_as_module(key, tcx) }
+ }
+
query collect_mod_item_types(key: LocalDefId) -> () {
desc { |tcx| "collecting item types in {}", describe_as_module(key, tcx) }
}
@@ -906,9 +910,10 @@ rustc_queries! {
/// Checks whether all impls in the crate pass the overlap check, returning
/// which impls fail it. If all impls are correct, the returned slice is empty.
- query orphan_check_crate(_: ()) -> &'tcx [LocalDefId] {
- desc {
- "checking whether the immpl in the this crate follow the orphan rules",
+ query orphan_check_impl(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
+ desc { |tcx|
+ "checking whether impl `{}` follows the orphan rules",
+ tcx.def_path_str(key.to_def_id()),
}
}
@@ -1398,13 +1403,7 @@ rustc_queries! {
separate_provide_extern
}
- query check_item_well_formed(key: LocalDefId) -> () {
- desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key.to_def_id()) }
- }
- query check_trait_item_well_formed(key: LocalDefId) -> () {
- desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key.to_def_id()) }
- }
- query check_impl_item_well_formed(key: LocalDefId) -> () {
+ query check_well_formed(key: LocalDefId) -> () {
desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key.to_def_id()) }
}
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 5258d37a14c..ed8de24a65e 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -406,7 +406,7 @@ pub enum ObligationCauseCode<'tcx> {
QuestionMark,
/// Well-formed checking. If a `WellFormedLoc` is provided,
- /// then it will be used to eprform HIR-based wf checking
+ /// then it will be used to perform HIR-based wf checking
/// after an error occurs, in order to generate a more precise error span.
/// This is purely for diagnostic purposes - it is always
/// correct to use `MiscObligation` instead, or to specify
@@ -863,7 +863,7 @@ pub enum ObjectSafetyViolation {
impl ObjectSafetyViolation {
pub fn error_msg(&self) -> Cow<'static, str> {
- match *self {
+ match self {
ObjectSafetyViolation::SizedSelf(_) => "it requires `Self: Sized`".into(),
ObjectSafetyViolation::SupertraitSelf(ref spans) => {
if spans.iter().any(|sp| *sp != DUMMY_SP) {
@@ -873,7 +873,7 @@ impl ObjectSafetyViolation {
.into()
}
}
- ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_, _, _), _) => {
+ ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => {
format!("associated function `{}` has no `self` parameter", name).into()
}
ObjectSafetyViolation::Method(
@@ -897,9 +897,11 @@ impl ObjectSafetyViolation {
ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) => {
format!("method `{}` has generic type parameters", name).into()
}
- ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) => {
- format!("method `{}`'s `self` parameter cannot be dispatched on", name).into()
- }
+ ObjectSafetyViolation::Method(
+ name,
+ MethodViolationCode::UndispatchableReceiver(_),
+ _,
+ ) => format!("method `{}`'s `self` parameter cannot be dispatched on", name).into(),
ObjectSafetyViolation::AssocConst(name, DUMMY_SP) => {
format!("it contains associated `const` `{}`", name).into()
}
@@ -911,51 +913,40 @@ impl ObjectSafetyViolation {
}
pub fn solution(&self, err: &mut Diagnostic) {
- match *self {
+ match self {
ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => {}
ObjectSafetyViolation::Method(
name,
- MethodViolationCode::StaticMethod(sugg, self_span, has_args),
+ MethodViolationCode::StaticMethod(Some((add_self_sugg, make_sized_sugg))),
_,
) => {
err.span_suggestion(
- self_span,
- &format!(
+ add_self_sugg.1,
+ format!(
"consider turning `{}` into a method by giving it a `&self` argument",
name
),
- format!("&self{}", if has_args { ", " } else { "" }),
+ add_self_sugg.0.to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ err.span_suggestion(
+ make_sized_sugg.1,
+ format!(
+ "alternatively, consider constraining `{}` so it does not apply to \
+ trait objects",
+ name
+ ),
+ make_sized_sugg.0.to_string(),
Applicability::MaybeIncorrect,
);
- match sugg {
- Some((sugg, span)) => {
- err.span_suggestion(
- span,
- &format!(
- "alternatively, consider constraining `{}` so it does not apply to \
- trait objects",
- name
- ),
- sugg,
- Applicability::MaybeIncorrect,
- );
- }
- None => {
- err.help(&format!(
- "consider turning `{}` into a method by giving it a `&self` \
- argument or constraining it so it does not apply to trait objects",
- name
- ));
- }
- }
}
ObjectSafetyViolation::Method(
name,
- MethodViolationCode::UndispatchableReceiver,
- span,
+ MethodViolationCode::UndispatchableReceiver(Some(span)),
+ _,
) => {
err.span_suggestion(
- span,
+ *span,
&format!(
"consider changing method `{}`'s `self` parameter to be `&self`",
name
@@ -991,13 +982,13 @@ impl ObjectSafetyViolation {
}
/// Reasons a method might not be object-safe.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
pub enum MethodViolationCode {
/// e.g., `fn foo()`
- StaticMethod(Option<(&'static str, Span)>, Span, bool /* has args */),
+ StaticMethod(Option<(/* add &self */ (String, Span), /* add Self: Sized */ (String, Span))>),
/// e.g., `fn foo(&self, x: Self)`
- ReferencesSelfInput(usize),
+ ReferencesSelfInput(Option<Span>),
/// e.g., `fn foo(&self) -> Self`
ReferencesSelfOutput,
@@ -1009,7 +1000,7 @@ pub enum MethodViolationCode {
Generic,
/// the method's receiver (`self` argument) can't be dispatched on
- UndispatchableReceiver,
+ UndispatchableReceiver(Option<Span>),
}
/// These are the error cases for `codegen_fulfill_obligation`.
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index b1b8bc13e2f..a6310ae5e66 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -465,13 +465,12 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn fold_regions<T>(
self,
value: T,
- skipped_regions: &mut bool,
mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
) -> T
where
T: TypeFoldable<'tcx>,
{
- value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f))
+ value.fold_with(&mut RegionFolder::new(self, &mut f))
}
/// Invoke `callback` on every region appearing free in `value`.
@@ -579,7 +578,6 @@ impl<'tcx> TyCtxt<'tcx> {
pub struct RegionFolder<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
- skipped_regions: &'a mut bool,
/// Stores the index of a binder *just outside* the stuff we have
/// visited. So this begins as INNERMOST; when we pass through a
@@ -597,10 +595,9 @@ impl<'a, 'tcx> RegionFolder<'a, 'tcx> {
#[inline]
pub fn new(
tcx: TyCtxt<'tcx>,
- skipped_regions: &'a mut bool,
fold_region_fn: &'a mut dyn FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
) -> RegionFolder<'a, 'tcx> {
- RegionFolder { tcx, skipped_regions, current_index: ty::INNERMOST, fold_region_fn }
+ RegionFolder { tcx, current_index: ty::INNERMOST, fold_region_fn }
}
}
@@ -624,7 +621,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
match *r {
ty::ReLateBound(debruijn, _) if debruijn < self.current_index => {
debug!(?self.current_index, "skipped bound region");
- *self.skipped_regions = true;
r
}
_ => {
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index f3bdd63ee6d..113af328a91 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -6,6 +6,7 @@
#![feature(let_chains)]
#![feature(let_else)]
#![feature(never_type)]
+#![feature(rustc_attrs)]
#![recursion_limit = "256"]
#[macro_use]
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index ba325d70422..0869ed65ad2 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -244,7 +244,7 @@ impl MultiSugg {
}
#[derive(SessionDiagnostic)]
-#[error(slug = "parser-maybe-report-ambiguous-plus")]
+#[error(parser::maybe_report_ambiguous_plus)]
struct AmbiguousPlus {
pub sum_ty: String,
#[primary_span]
@@ -253,7 +253,7 @@ struct AmbiguousPlus {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0178", slug = "parser-maybe-recover-from-bad-type-plus")]
+#[error(parser::maybe_recover_from_bad_type_plus, code = "E0178")]
struct BadTypePlus {
pub ty: String,
#[primary_span]
@@ -265,7 +265,7 @@ struct BadTypePlus {
#[derive(SessionSubdiagnostic)]
pub enum BadTypePlusSub {
#[suggestion(
- slug = "parser-add-paren",
+ parser::add_paren,
code = "{sum_with_parens}",
applicability = "machine-applicable"
)]
@@ -274,12 +274,12 @@ pub enum BadTypePlusSub {
#[primary_span]
span: Span,
},
- #[label(slug = "parser-forgot-paren")]
+ #[label(parser::forgot_paren)]
ForgotParen {
#[primary_span]
span: Span,
},
- #[label(slug = "parser-expect-path")]
+ #[label(parser::expect_path)]
ExpectPath {
#[primary_span]
span: Span,
@@ -287,7 +287,7 @@ pub enum BadTypePlusSub {
}
#[derive(SessionDiagnostic)]
-#[error(slug = "parser-maybe-recover-from-bad-qpath-stage-2")]
+#[error(parser::maybe_recover_from_bad_qpath_stage_2)]
struct BadQPathStage2 {
#[primary_span]
#[suggestion(applicability = "maybe-incorrect")]
@@ -296,7 +296,7 @@ struct BadQPathStage2 {
}
#[derive(SessionDiagnostic)]
-#[error(slug = "parser-incorrect-semicolon")]
+#[error(parser::incorrect_semicolon)]
struct IncorrectSemicolon<'a> {
#[primary_span]
#[suggestion_short(applicability = "machine-applicable")]
@@ -307,26 +307,26 @@ struct IncorrectSemicolon<'a> {
}
#[derive(SessionDiagnostic)]
-#[error(slug = "parser-incorrect-use-of-await")]
+#[error(parser::incorrect_use_of_await)]
struct IncorrectUseOfAwait {
#[primary_span]
- #[suggestion(message = "parentheses-suggestion", applicability = "machine-applicable")]
+ #[suggestion(parser::parentheses_suggestion, applicability = "machine-applicable")]
span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(slug = "parser-incorrect-use-of-await")]
+#[error(parser::incorrect_use_of_await)]
struct IncorrectAwait {
#[primary_span]
span: Span,
- #[suggestion(message = "postfix-suggestion", code = "{expr}.await{question_mark}")]
+ #[suggestion(parser::postfix_suggestion, code = "{expr}.await{question_mark}")]
sugg_span: (Span, Applicability),
expr: String,
question_mark: &'static str,
}
#[derive(SessionDiagnostic)]
-#[error(slug = "parser-in-in-typo")]
+#[error(parser::in_in_typo)]
struct InInTypo {
#[primary_span]
span: Span,
@@ -357,6 +357,7 @@ impl<'a> DerefMut for SnapshotParser<'a> {
}
impl<'a> Parser<'a> {
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub(super) fn span_err<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -365,6 +366,7 @@ impl<'a> Parser<'a> {
err.span_err(sp, self.diagnostic())
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_span_err<S: Into<MultiSpan>>(
&self,
sp: S,
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 81bab0e3513..2c43563b104 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -7,6 +7,7 @@ use super::{
};
use crate::maybe_recover_from_interpolated_ty_qpath;
+use core::mem;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
use rustc_ast::tokenstream::Spacing;
@@ -26,7 +27,6 @@ use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_span::source_map::{self, Span, Spanned};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{BytePos, Pos};
-use std::mem;
/// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression
/// dropped into the token stream, which happens while parsing the result of
@@ -2343,7 +2343,9 @@ impl<'a> Parser<'a> {
/// Parses the condition of a `if` or `while` expression.
fn parse_cond_expr(&mut self) -> PResult<'a, P<Expr>> {
- let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
+ let cond = self.with_let_management(true, |local_self| {
+ local_self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)
+ })?;
if let ExprKind::Let(..) = cond.kind {
// Remove the last feature gating of a `let` expression since it's stable.
@@ -2356,6 +2358,13 @@ impl<'a> Parser<'a> {
/// Parses a `let $pat = $expr` pseudo-expression.
/// The `let` token has already been eaten.
fn parse_let_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ if !self.let_expr_allowed {
+ self.struct_span_err(
+ self.prev_token.span,
+ "expected expression, found `let` statement",
+ )
+ .emit();
+ }
let lo = self.prev_token.span;
let pat = self.parse_pat_allow_top_alt(
None,
@@ -2672,6 +2681,8 @@ impl<'a> Parser<'a> {
}
pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> {
+ // Used to check the `let_chains` and `if_let_guard` features mostly by scaning
+ // `&&` tokens.
fn check_let_expr(expr: &Expr) -> (bool, bool) {
match expr.kind {
ExprKind::Binary(_, ref lhs, ref rhs) => {
@@ -2694,7 +2705,7 @@ impl<'a> Parser<'a> {
)?;
let guard = if this.eat_keyword(kw::If) {
let if_span = this.prev_token.span;
- let cond = this.parse_expr()?;
+ let cond = this.with_let_management(true, |local_this| local_this.parse_expr())?;
let (has_let_expr, does_not_have_bin_op) = check_let_expr(&cond);
if has_let_expr {
if does_not_have_bin_op {
@@ -3256,4 +3267,17 @@ impl<'a> Parser<'a> {
Ok((res, trailing))
})
}
+
+ // Calls `f` with the internal `let_expr_allowed` set to `let_expr_allowed` and then
+ // sets the internal `let_expr_allowed` back to its original value.
+ fn with_let_management<T>(
+ &mut self,
+ let_expr_allowed: bool,
+ f: impl FnOnce(&mut Self) -> T,
+ ) -> T {
+ let last_let_expr_allowed = mem::replace(&mut self.let_expr_allowed, let_expr_allowed);
+ let rslt = f(self);
+ self.let_expr_allowed = last_let_expr_allowed;
+ rslt
+ }
}
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 6d6667717f0..acdf121522a 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -147,12 +147,15 @@ pub struct Parser<'a> {
/// This allows us to recover when the user forget to add braces around
/// multiple statements in the closure body.
pub current_closure: Option<ClosureSpans>,
+ /// Used to track where `let`s are allowed. For example, `if true && let 1 = 1` is valid
+ /// but `[1, 2, 3][let _ = ()]` is not.
+ let_expr_allowed: bool,
}
// This type is used a lot, e.g. it's cloned when matching many declarative macro rules. Make sure
// it doesn't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(Parser<'_>, 328);
+rustc_data_structures::static_assert_size!(Parser<'_>, 336);
/// Stores span information about a closure.
#[derive(Clone)]
@@ -455,6 +458,7 @@ impl<'a> Parser<'a> {
inner_attr_ranges: Default::default(),
},
current_closure: None,
+ let_expr_allowed: false,
};
// Make parser point to the first token.
diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml
index d952e288a64..5785921fb1e 100644
--- a/compiler/rustc_privacy/Cargo.toml
+++ b/compiler/rustc_privacy/Cargo.toml
@@ -4,14 +4,15 @@ version = "0.0.0"
edition = "2021"
[dependencies]
-rustc_middle = { path = "../rustc_middle" }
rustc_ast = { path = "../rustc_ast" }
rustc_attr = { path = "../rustc_attr" }
+rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_hir = { path = "../rustc_hir" }
-rustc_typeck = { path = "../rustc_typeck" }
+rustc_macros = { path = "../rustc_macros" }
+rustc_middle = { path = "../rustc_middle" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
-rustc_data_structures = { path = "../rustc_data_structures" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
+rustc_typeck = { path = "../rustc_typeck" }
tracing = "0.1"
diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs
new file mode 100644
index 00000000000..482721d373a
--- /dev/null
+++ b/compiler/rustc_privacy/src/errors.rs
@@ -0,0 +1,75 @@
+use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
+use rustc_span::{Span, Symbol};
+
+#[derive(SessionDiagnostic)]
+#[error(privacy::field_is_private, code = "E0451")]
+pub struct FieldIsPrivate {
+ #[primary_span]
+ pub span: Span,
+ pub field_name: Symbol,
+ pub variant_descr: &'static str,
+ pub def_path_str: String,
+ #[subdiagnostic]
+ pub label: FieldIsPrivateLabel,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum FieldIsPrivateLabel {
+ #[label(privacy::field_is_private_is_update_syntax_label)]
+ IsUpdateSyntax {
+ #[primary_span]
+ span: Span,
+ field_name: Symbol,
+ },
+ #[label(privacy::field_is_private_label)]
+ Other {
+ #[primary_span]
+ span: Span,
+ },
+}
+
+#[derive(SessionDiagnostic)]
+#[error(privacy::item_is_private)]
+pub struct ItemIsPrivate<'a> {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ pub kind: &'a str,
+ pub descr: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(privacy::unnamed_item_is_private)]
+pub struct UnnamedItemIsPrivate {
+ #[primary_span]
+ pub span: Span,
+ pub kind: &'static str,
+}
+
+// Duplicate of `InPublicInterface` but with a different error code, shares the same slug.
+#[derive(SessionDiagnostic)]
+#[error(privacy::in_public_interface, code = "E0445")]
+pub struct InPublicInterfaceTraits<'a> {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ pub vis_descr: &'static str,
+ pub kind: &'a str,
+ pub descr: String,
+ #[label(privacy::visibility_label)]
+ pub vis_span: Span,
+}
+
+// Duplicate of `InPublicInterfaceTraits` but with a different error code, shares the same slug.
+#[derive(SessionDiagnostic)]
+#[error(privacy::in_public_interface, code = "E0446")]
+pub struct InPublicInterface<'a> {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ pub vis_descr: &'static str,
+ pub kind: &'a str,
+ pub descr: String,
+ #[label(privacy::visibility_label)]
+ pub vis_span: Span,
+}
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index b27c986d0f9..238c917bbc3 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -1,15 +1,19 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![feature(associated_type_defaults)]
#![feature(control_flow_enum)]
+#![feature(rustc_private)]
#![feature(try_blocks)]
-#![feature(associated_type_defaults)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
+#![cfg_attr(not(bootstrap), deny(rustc::untranslatable_diagnostic))]
+#![cfg_attr(not(bootstrap), deny(rustc::diagnostic_outside_of_impl))]
+
+mod errors;
use rustc_ast::MacroDef;
use rustc_attr as attr;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::intern::Interned;
-use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID};
@@ -34,6 +38,11 @@ use std::marker::PhantomData;
use std::ops::ControlFlow;
use std::{cmp, fmt, mem};
+use errors::{
+ FieldIsPrivate, FieldIsPrivateLabel, InPublicInterface, InPublicInterfaceTraits, ItemIsPrivate,
+ UnnamedItemIsPrivate,
+};
+
////////////////////////////////////////////////////////////////////////////////
/// Generic infrastructure used to implement specific visitors below.
////////////////////////////////////////////////////////////////////////////////
@@ -935,23 +944,17 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
let hir_id = self.tcx.hir().local_def_id_to_hir_id(self.current_item);
let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did(), hir_id).1;
if !field.vis.is_accessible_from(def_id, self.tcx) {
- let label = if in_update_syntax {
- format!("field `{}` is private", field.name)
- } else {
- "private field".to_string()
- };
-
- struct_span_err!(
- self.tcx.sess,
+ self.tcx.sess.emit_err(FieldIsPrivate {
span,
- E0451,
- "field `{}` of {} `{}` is private",
- field.name,
- def.variant_descr(),
- self.tcx.def_path_str(def.did())
- )
- .span_label(span, label)
- .emit();
+ field_name: field.name,
+ variant_descr: def.variant_descr(),
+ def_path_str: self.tcx.def_path_str(def.did()),
+ label: if in_update_syntax {
+ FieldIsPrivateLabel::IsUpdateSyntax { span, field_name: field.name }
+ } else {
+ FieldIsPrivateLabel::Other { span }
+ },
+ });
}
}
}
@@ -1075,11 +1078,11 @@ impl<'tcx> TypePrivacyVisitor<'tcx> {
fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool {
let is_error = !self.item_is_accessible(def_id);
if is_error {
- self.tcx
- .sess
- .struct_span_err(self.span, &format!("{} `{}` is private", kind, descr))
- .span_label(self.span, &format!("private {}", kind))
- .emit();
+ self.tcx.sess.emit_err(ItemIsPrivate {
+ span: self.span,
+ kind,
+ descr: descr.to_string(),
+ });
}
is_error
}
@@ -1250,13 +1253,10 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
hir::QPath::TypeRelative(_, segment) => Some(segment.ident.to_string()),
};
let kind = kind.descr(def_id);
- let msg = match name {
- Some(name) => format!("{} `{}` is private", kind, name),
- None => format!("{} is private", kind),
+ let _ = match name {
+ Some(name) => sess.emit_err(ItemIsPrivate { span, kind, descr: name }),
+ None => sess.emit_err(UnnamedItemIsPrivate { span, kind }),
};
- sess.struct_span_err(span, &msg)
- .span_label(span, &format!("private {}", kind))
- .emit();
return;
}
}
@@ -1753,22 +1753,31 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
}
}
};
- let make_msg = || format!("{} {} `{}` in public interface", vis_descr, kind, descr);
let span = self.tcx.def_span(self.item_def_id.to_def_id());
if self.has_old_errors
|| self.in_assoc_ty
|| self.tcx.resolutions(()).has_pub_restricted
{
- let mut err = if kind == "trait" {
- struct_span_err!(self.tcx.sess, span, E0445, "{}", make_msg())
- } else {
- struct_span_err!(self.tcx.sess, span, E0446, "{}", make_msg())
- };
+ let descr = descr.to_string();
let vis_span =
self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id));
- err.span_label(span, format!("can't leak {} {}", vis_descr, kind));
- err.span_label(vis_span, format!("`{}` declared as {}", descr, vis_descr));
- err.emit();
+ if kind == "trait" {
+ self.tcx.sess.emit_err(InPublicInterfaceTraits {
+ span,
+ vis_descr,
+ kind,
+ descr,
+ vis_span,
+ });
+ } else {
+ self.tcx.sess.emit_err(InPublicInterface {
+ span,
+ vis_descr,
+ kind,
+ descr,
+ vis_span,
+ });
+ }
} else {
let err_code = if kind == "trait" { "E0445" } else { "E0446" };
self.tcx.struct_span_lint_hir(
@@ -1776,7 +1785,12 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
hir_id,
span,
|lint| {
- lint.build(&format!("{} (error {})", make_msg(), err_code)).emit();
+ lint.build(&format!(
+ "{} (error {})",
+ format!("{} {} `{}` in public interface", vis_descr, kind, descr),
+ err_code
+ ))
+ .emit();
},
);
}
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index f1814eebfa6..b5058fd699a 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -280,6 +280,7 @@ impl Session {
self.crate_types.set(crate_types).expect("`crate_types` was initialized twice")
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_span_warn<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -287,6 +288,7 @@ impl Session {
) -> DiagnosticBuilder<'_, ()> {
self.diagnostic().struct_span_warn(sp, msg)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_span_warn_with_expectation<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -295,6 +297,7 @@ impl Session {
) -> DiagnosticBuilder<'_, ()> {
self.diagnostic().struct_span_warn_with_expectation(sp, msg, id)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_span_warn_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -303,9 +306,11 @@ impl Session {
) -> DiagnosticBuilder<'_, ()> {
self.diagnostic().struct_span_warn_with_code(sp, msg, code)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_warn(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
self.diagnostic().struct_warn(msg)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_warn_with_expectation(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -313,6 +318,7 @@ impl Session {
) -> DiagnosticBuilder<'_, ()> {
self.diagnostic().struct_warn_with_expectation(msg, id)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_span_allow<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -320,9 +326,11 @@ impl Session {
) -> DiagnosticBuilder<'_, ()> {
self.diagnostic().struct_span_allow(sp, msg)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_allow(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
self.diagnostic().struct_allow(msg)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_expect(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -330,6 +338,7 @@ impl Session {
) -> DiagnosticBuilder<'_, ()> {
self.diagnostic().struct_expect(msg, id)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_span_err<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -337,6 +346,7 @@ impl Session {
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
self.diagnostic().struct_span_err(sp, msg)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_span_err_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -346,12 +356,14 @@ impl Session {
self.diagnostic().struct_span_err_with_code(sp, msg, code)
}
// FIXME: This method should be removed (every error should have an associated error code).
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_err(
&self,
msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
self.parse_sess.struct_err(msg)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_err_with_code(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -359,6 +371,7 @@ impl Session {
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
self.diagnostic().struct_err_with_code(msg, code)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_warn_with_code(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -366,6 +379,7 @@ impl Session {
) -> DiagnosticBuilder<'_, ()> {
self.diagnostic().struct_warn_with_code(msg, code)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_span_fatal<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -373,6 +387,7 @@ impl Session {
) -> DiagnosticBuilder<'_, !> {
self.diagnostic().struct_span_fatal(sp, msg)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_span_fatal_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -381,13 +396,16 @@ impl Session {
) -> DiagnosticBuilder<'_, !> {
self.diagnostic().struct_span_fatal_with_code(sp, msg, code)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> {
self.diagnostic().struct_fatal(msg)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) -> ! {
self.diagnostic().span_fatal(sp, msg)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn span_fatal_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -396,9 +414,11 @@ impl Session {
) -> ! {
self.diagnostic().span_fatal_with_code(sp, msg, code)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn fatal(&self, msg: impl Into<DiagnosticMessage>) -> ! {
self.diagnostic().fatal(msg).raise()
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn span_err_or_warn<S: Into<MultiSpan>>(
&self,
is_warning: bool,
@@ -411,6 +431,7 @@ impl Session {
self.span_err(sp, msg);
}
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn span_err<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -418,6 +439,7 @@ impl Session {
) -> ErrorGuaranteed {
self.diagnostic().span_err(sp, msg)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn span_err_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -426,6 +448,7 @@ impl Session {
) {
self.diagnostic().span_err_with_code(sp, msg, code)
}
+ #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)]
pub fn err(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed {
self.diagnostic().err(msg)
}
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 8a6941a4516..48766c67910 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -567,8 +567,10 @@ symbols! {
debug_assert_ne_macro,
debug_assertions,
debug_struct,
+ debug_struct_fields_finish,
debug_trait_builder,
debug_tuple,
+ debug_tuple_fields_finish,
debugger_visualizer,
decl_macro,
declare_lint_pass,
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index a8ddcc9bfac..59dbea70534 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -8,6 +8,7 @@
//! LLVM.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![feature(assert_matches)]
#![feature(associated_type_bounds)]
#![feature(exhaustive_patterns)]
#![feature(let_else)]
diff --git a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
index 86f76fdb6a7..9d36e37d7b8 100644
--- a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
@@ -8,7 +8,7 @@ pub fn target() -> Target {
// FIXME: The leak sanitizer currently fails the tests, see #88132.
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD;
- base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".into(), "arm64".into()]);
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-arch", "arm64"]);
base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove());
// Clang automatically chooses a more specific target based on
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs b/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs
index 965b254c289..162b091b269 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs
@@ -2,20 +2,13 @@
// uefi-base module for generic UEFI options.
use super::uefi_msvc_base;
-use crate::spec::{LinkerFlavor, LldFlavor, Target};
+use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target {
let mut base = uefi_msvc_base::opts();
base.max_atomic_width = Some(64);
-
- let pre_link_args_msvc = vec!["/machine:arm64".into()];
-
- base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone());
- base.pre_link_args
- .get_mut(&LinkerFlavor::Lld(LldFlavor::Link))
- .unwrap()
- .extend(pre_link_args_msvc);
+ base.add_pre_link_args(LinkerFlavor::Msvc, &["/machine:arm64"]);
Target {
llvm_target: "aarch64-unknown-windows".into(),
diff --git a/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs b/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs
index 67df73fa935..8c2a9bcfde6 100644
--- a/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs
+++ b/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs
@@ -1,19 +1,13 @@
-use crate::spec::{cvs, LinkArgs, LinkerFlavor, RelocModel, Target, TargetOptions};
+use crate::spec::{cvs, LinkerFlavor, 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(
+ let pre_link_args = TargetOptions::link_args(
LinkerFlavor::Gcc,
- vec![
- "-specs=3dsx.specs".into(),
- "-mtune=mpcore".into(),
- "-mfloat-abi=hard".into(),
- "-mtp=soft".into(),
- ],
+ &["-specs=3dsx.specs", "-mtune=mpcore", "-mfloat-abi=hard", "-mtp=soft"],
);
Target {
diff --git a/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs
index 2afd93fcad8..38c117a495e 100644
--- a/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs
@@ -10,7 +10,7 @@ use crate::spec::{LinkerFlavor, SanitizerSet, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::android_base::opts();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-march=armv7-a".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-march=armv7-a"]);
Target {
llvm_target: "armv7-none-linux-android".into(),
pointer_width: 32,
diff --git a/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs b/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs
index 269bf8b8bcd..b4cf2c5ee22 100644
--- a/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs
+++ b/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs
@@ -2,10 +2,6 @@ use super::{wasm32_unknown_emscripten, LinkerFlavor, Target};
pub fn target() -> Target {
let mut target = wasm32_unknown_emscripten::target();
- target.post_link_args.entry(LinkerFlavor::Em).or_default().extend(vec![
- "-sWASM=0".into(),
- "--memory-init-file".into(),
- "0".into(),
- ]);
+ target.add_post_link_args(LinkerFlavor::Em, &["-sWASM=0", "--memory-init-file", "0"]);
target
}
diff --git a/compiler/rustc_target/src/spec/avr_gnu_base.rs b/compiler/rustc_target/src/spec/avr_gnu_base.rs
index c288e8b0e9e..4fd6c06394d 100644
--- a/compiler/rustc_target/src/spec/avr_gnu_base.rs
+++ b/compiler/rustc_target/src/spec/avr_gnu_base.rs
@@ -3,7 +3,8 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
/// A base target for AVR devices using the GNU toolchain.
///
/// Requires GNU avr-gcc and avr-binutils on the host system.
-pub fn target(target_cpu: &'static str) -> Target {
+/// FIXME: Remove the second parameter when const string concatenation is possible.
+pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
Target {
arch: "avr".into(),
data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".into(),
@@ -17,10 +18,8 @@ pub fn target(target_cpu: &'static str) -> Target {
linker: Some("avr-gcc".into()),
executables: true,
eh_frame_header: false,
- pre_link_args: [(LinkerFlavor::Gcc, vec![format!("-mmcu={}", target_cpu).into()])]
- .into_iter()
- .collect(),
- late_link_args: [(LinkerFlavor::Gcc, vec!["-lgcc".into()])].into_iter().collect(),
+ pre_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &[mmcu]),
+ late_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &["-lgcc"]),
max_atomic_width: Some(0),
atomic_cas: false,
..TargetOptions::default()
diff --git a/compiler/rustc_target/src/spec/avr_unknown_gnu_atmega328.rs b/compiler/rustc_target/src/spec/avr_unknown_gnu_atmega328.rs
index 6871ca0f789..6c16b03cc28 100644
--- a/compiler/rustc_target/src/spec/avr_unknown_gnu_atmega328.rs
+++ b/compiler/rustc_target/src/spec/avr_unknown_gnu_atmega328.rs
@@ -1,5 +1,5 @@
use crate::spec::Target;
pub fn target() -> Target {
- super::avr_gnu_base::target("atmega328")
+ super::avr_gnu_base::target("atmega328", "-mmcu=atmega328")
}
diff --git a/compiler/rustc_target/src/spec/fuchsia_base.rs b/compiler/rustc_target/src/spec/fuchsia_base.rs
index b64875e32bd..b02b70f76ee 100644
--- a/compiler/rustc_target/src/spec/fuchsia_base.rs
+++ b/compiler/rustc_target/src/spec/fuchsia_base.rs
@@ -1,23 +1,20 @@
-use crate::spec::{
- crt_objects, cvs, LinkArgs, LinkOutputKind, LinkerFlavor, LldFlavor, TargetOptions,
-};
+use crate::spec::{crt_objects, cvs, LinkOutputKind, LinkerFlavor, LldFlavor, TargetOptions};
pub fn opts() -> TargetOptions {
- let mut pre_link_args = LinkArgs::new();
- pre_link_args.insert(
- LinkerFlavor::Lld(LldFlavor::Ld),
- vec![
- "--build-id".into(),
- "--hash-style=gnu".into(),
- "-z".into(),
- "max-page-size=4096".into(),
- "-z".into(),
- "now".into(),
- "-z".into(),
- "rodynamic".into(),
- "-z".into(),
- "separate-loadable-segments".into(),
- "--pack-dyn-relocs=relr".into(),
+ let pre_link_args = TargetOptions::link_args(
+ LinkerFlavor::Ld,
+ &[
+ "--build-id",
+ "--hash-style=gnu",
+ "-z",
+ "max-page-size=4096",
+ "-z",
+ "now",
+ "-z",
+ "rodynamic",
+ "-z",
+ "separate-loadable-segments",
+ "--pack-dyn-relocs=relr",
],
);
diff --git a/compiler/rustc_target/src/spec/hermit_base.rs b/compiler/rustc_target/src/spec/hermit_base.rs
index 7cbd42417e6..e43153177f0 100644
--- a/compiler/rustc_target/src/spec/hermit_base.rs
+++ b/compiler/rustc_target/src/spec/hermit_base.rs
@@ -1,10 +1,9 @@
-use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions, TlsModel};
+use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions, TlsModel};
pub fn opts() -> TargetOptions {
- let mut pre_link_args = LinkArgs::new();
- pre_link_args.insert(
- LinkerFlavor::Lld(LldFlavor::Ld),
- vec!["--build-id".into(), "--hash-style=gnu".into(), "--Bstatic".into()],
+ let pre_link_args = TargetOptions::link_args(
+ LinkerFlavor::Ld,
+ &["--build-id", "--hash-style=gnu", "--Bstatic"],
);
TargetOptions {
diff --git a/compiler/rustc_target/src/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs
index ad716a6cd5a..1718bd77b86 100644
--- a/compiler/rustc_target/src/spec/i686_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs
@@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::apple_base::opts("macos");
base.cpu = "yonah".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".into()]);
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove());
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
diff --git a/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs
index 554b0f34499..6318654399c 100644
--- a/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs
@@ -1,19 +1,16 @@
-use crate::spec::{FramePointer, LinkerFlavor, LldFlavor, Target};
+use crate::spec::{FramePointer, LinkerFlavor, Target};
pub fn target() -> Target {
let mut base = super::windows_gnu_base::opts();
base.cpu = "pentium4".into();
- base.pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".into(), "i386pe".into()]);
base.max_atomic_width = Some(64);
base.frame_pointer = FramePointer::Always; // Required for backtraces
base.linker = Some("i686-w64-mingw32-gcc".into());
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address
// space available to x86 Windows binaries on x86_64.
- base.pre_link_args
- .entry(LinkerFlavor::Gcc)
- .or_default()
- .push("-Wl,--large-address-aware".into());
+ base.add_pre_link_args(LinkerFlavor::Ld, &["-m", "i386pe", "--large-address-aware"]);
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-Wl,--large-address-aware"]);
Target {
llvm_target: "i686-pc-windows-gnu".into(),
diff --git a/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs
index fb0cb6a6943..f4ceaa1ca4b 100644
--- a/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs
@@ -1,24 +1,22 @@
-use crate::spec::{LinkerFlavor, LldFlavor, Target};
+use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target {
let mut base = super::windows_msvc_base::opts();
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
- let pre_link_args_msvc = vec![
- // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
- // space available to x86 Windows binaries on x86_64.
- "/LARGEADDRESSAWARE".into(),
- // Ensure the linker will only produce an image if it can also produce a table of
- // the image's safe exception handlers.
- // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers
- "/SAFESEH".into(),
- ];
- base.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone());
- base.pre_link_args
- .entry(LinkerFlavor::Lld(LldFlavor::Link))
- .or_default()
- .extend(pre_link_args_msvc);
+ base.add_pre_link_args(
+ LinkerFlavor::Msvc,
+ &[
+ // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
+ // space available to x86 Windows binaries on x86_64.
+ "/LARGEADDRESSAWARE",
+ // Ensure the linker will only produce an image if it can also produce a table of
+ // the image's safe exception handlers.
+ // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers
+ "/SAFESEH",
+ ],
+ );
// Workaround for #95429
base.has_thread_local = false;
diff --git a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs
index 9f0cb04c65d..aff284bf2bc 100644
--- a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs
@@ -4,9 +4,7 @@ pub fn target() -> Target {
let mut base = super::freebsd_base::opts();
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
- let pre_link_args = base.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
- pre_link_args.push("-m32".into());
- pre_link_args.push("-Wl,-znotext".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-Wl,-znotext"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
diff --git a/compiler/rustc_target/src/spec/i686_unknown_haiku.rs b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs
index d1af163f1cf..87aa74e406c 100644
--- a/compiler/rustc_target/src/spec/i686_unknown_haiku.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs
@@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::haiku_base::opts();
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".into()]);
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs
index 0998c618f31..765803d1692 100644
--- a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs
@@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts();
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs
index a697f292da0..d9492804349 100644
--- a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs
@@ -4,8 +4,7 @@ pub fn target() -> Target {
let mut base = super::linux_musl_base::opts();
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into());
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-Wl,-melf_i386".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-Wl,-melf_i386"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
diff --git a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs
index 2807d328205..8de698b51f0 100644
--- a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs
@@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::netbsd_base::opts();
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
diff --git a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs
index 78462eb63b8..7f25a1a16c1 100644
--- a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs
@@ -4,8 +4,7 @@ pub fn target() -> Target {
let mut base = super::openbsd_base::opts();
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into());
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-fuse-ld=lld".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-fuse-ld=lld"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
diff --git a/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs
index 75f7a2209c8..d52810d2fb0 100644
--- a/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs
@@ -1,18 +1,15 @@
-use crate::spec::{FramePointer, LinkerFlavor, LldFlavor, Target};
+use crate::spec::{FramePointer, LinkerFlavor, Target};
pub fn target() -> Target {
let mut base = super::windows_uwp_gnu_base::opts();
base.cpu = "pentium4".into();
- base.pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".into(), "i386pe".into()]);
base.max_atomic_width = Some(64);
base.frame_pointer = FramePointer::Always; // Required for backtraces
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address
// space available to x86 Windows binaries on x86_64.
- base.pre_link_args
- .entry(LinkerFlavor::Gcc)
- .or_default()
- .push("-Wl,--large-address-aware".into());
+ base.add_pre_link_args(LinkerFlavor::Ld, &["-m", "i386pe", "--large-address-aware"]);
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-Wl,--large-address-aware"]);
Target {
llvm_target: "i686-pc-windows-gnu".into(),
diff --git a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs
index d51ed7c1f7a..f62404e8279 100644
--- a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs
@@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::vxworks_base::opts();
base.cpu = "pentium4".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
diff --git a/compiler/rustc_target/src/spec/illumos_base.rs b/compiler/rustc_target/src/spec/illumos_base.rs
index ef8f90a4da8..b0e1b109be1 100644
--- a/compiler/rustc_target/src/spec/illumos_base.rs
+++ b/compiler/rustc_target/src/spec/illumos_base.rs
@@ -1,10 +1,9 @@
-use crate::spec::{cvs, FramePointer, LinkArgs, LinkerFlavor, TargetOptions};
+use crate::spec::{cvs, FramePointer, LinkerFlavor, TargetOptions};
pub fn opts() -> TargetOptions {
- let mut late_link_args = LinkArgs::new();
- late_link_args.insert(
+ let late_link_args = TargetOptions::link_args(
LinkerFlavor::Gcc,
- vec![
+ &[
// The illumos libc contains a stack unwinding implementation, as
// does libgcc_s. The latter implementation includes several
// additional symbols that are not always in base libc. To force
@@ -15,13 +14,13 @@ pub fn opts() -> TargetOptions {
// FIXME: This should be replaced by a more complete and generic
// mechanism for controlling the order of library arguments passed
// to the linker.
- "-lc".into(),
+ "-lc",
// LLVM will insert calls to the stack protector functions
// "__stack_chk_fail" and "__stack_chk_guard" into code in native
// object files. Some platforms include these symbols directly in
// libc, but at least historically these have been provided in
// libssp.so on illumos and Solaris systems.
- "-lssp".into(),
+ "-lssp",
],
);
diff --git a/compiler/rustc_target/src/spec/mipsel_sony_psp.rs b/compiler/rustc_target/src/spec/mipsel_sony_psp.rs
index 03e0934ea5e..e3522de6de0 100644
--- a/compiler/rustc_target/src/spec/mipsel_sony_psp.rs
+++ b/compiler/rustc_target/src/spec/mipsel_sony_psp.rs
@@ -1,13 +1,11 @@
use crate::spec::{cvs, Target, TargetOptions};
-use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, RelocModel};
+use crate::spec::{LinkerFlavor, LldFlavor, RelocModel};
// The PSP has custom linker requirements.
const LINKER_SCRIPT: &str = include_str!("./mipsel_sony_psp_linker_script.ld");
pub fn target() -> Target {
- let mut pre_link_args = LinkArgs::new();
- pre_link_args
- .insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["--emit-relocs".into(), "--nmagic".into()]);
+ let pre_link_args = TargetOptions::link_args(LinkerFlavor::Ld, &["--emit-relocs", "--nmagic"]);
Target {
llvm_target: "mipsel-sony-psp".into(),
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index da0589cdd20..a08603da040 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1459,6 +1459,44 @@ pub struct TargetOptions {
pub supports_stack_protector: bool,
}
+/// Add arguments for the given flavor and also for its "twin" flavors
+/// that have a compatible command line interface.
+fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'static str]) {
+ let mut insert = |flavor| {
+ link_args.entry(flavor).or_default().extend(args.iter().copied().map(Cow::Borrowed))
+ };
+ insert(flavor);
+ match flavor {
+ LinkerFlavor::Ld => insert(LinkerFlavor::Lld(LldFlavor::Ld)),
+ LinkerFlavor::Msvc => insert(LinkerFlavor::Lld(LldFlavor::Link)),
+ LinkerFlavor::Lld(LldFlavor::Wasm) => {}
+ LinkerFlavor::Lld(lld_flavor) => {
+ panic!("add_link_args: use non-LLD flavor for {:?}", lld_flavor)
+ }
+ LinkerFlavor::Gcc
+ | LinkerFlavor::Em
+ | LinkerFlavor::L4Bender
+ | LinkerFlavor::BpfLinker
+ | LinkerFlavor::PtxLinker => {}
+ }
+}
+
+impl TargetOptions {
+ fn link_args(flavor: LinkerFlavor, args: &[&'static str]) -> LinkArgs {
+ let mut link_args = LinkArgs::new();
+ add_link_args(&mut link_args, flavor, args);
+ link_args
+ }
+
+ fn add_pre_link_args(&mut self, flavor: LinkerFlavor, args: &[&'static str]) {
+ add_link_args(&mut self.pre_link_args, flavor, args);
+ }
+
+ fn add_post_link_args(&mut self, flavor: LinkerFlavor, args: &[&'static str]) {
+ add_link_args(&mut self.post_link_args, flavor, args);
+ }
+}
+
impl Default for TargetOptions {
/// Creates a set of "sane defaults" for any target. This is still
/// incomplete, and if used for compilation, will certainly not work.
diff --git a/compiler/rustc_target/src/spec/msvc_base.rs b/compiler/rustc_target/src/spec/msvc_base.rs
index 00cc9620243..c4df4b546e3 100644
--- a/compiler/rustc_target/src/spec/msvc_base.rs
+++ b/compiler/rustc_target/src/spec/msvc_base.rs
@@ -1,14 +1,9 @@
-use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, SplitDebuginfo, TargetOptions};
+use crate::spec::{LinkerFlavor, LldFlavor, SplitDebuginfo, TargetOptions};
pub fn opts() -> TargetOptions {
- let pre_link_args_msvc = vec![
- // Suppress the verbose logo and authorship debugging output, which would needlessly
- // clog any log files.
- "/NOLOGO".into(),
- ];
- let mut pre_link_args = LinkArgs::new();
- pre_link_args.insert(LinkerFlavor::Msvc, pre_link_args_msvc.clone());
- pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_link_args_msvc);
+ // Suppress the verbose logo and authorship debugging output, which would needlessly
+ // clog any log files.
+ let pre_link_args = TargetOptions::link_args(LinkerFlavor::Msvc, &["/NOLOGO"]);
TargetOptions {
linker_flavor: LinkerFlavor::Msvc,
diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs
index 595769c4bfa..803453c4ac4 100644
--- a/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs
@@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::freebsd_base::opts();
base.cpu = "ppc64".into();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64);
Target {
diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs
index 24d5d187e1a..5413c4f33ff 100644
--- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs
@@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, RelroLevel, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts();
base.cpu = "ppc64".into();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64);
// ld.so in at least RHEL6 on ppc64 has a bug related to BIND_NOW, so only enable partial RELRO
diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs
index 0f465ccfe77..159335eb607 100644
--- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs
@@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::linux_musl_base::opts();
base.cpu = "ppc64".into();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64);
Target {
diff --git a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs
index 491d344aedb..b7420d232ca 100644
--- a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs
@@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::vxworks_base::opts();
base.cpu = "ppc64".into();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64);
Target {
diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs
index b198e667ccc..a3d18004371 100644
--- a/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs
@@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::freebsd_base::opts();
base.cpu = "ppc64le".into();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64);
Target {
diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs
index 09e3936db26..e18ff3be448 100644
--- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs
@@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts();
base.cpu = "ppc64le".into();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64);
Target {
diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs
index 8a947b091cb..b84943d23a9 100644
--- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs
@@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::linux_musl_base::opts();
base.cpu = "ppc64le".into();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64);
Target {
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
index c27b84775df..516b2de37ea 100644
--- a/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
@@ -3,12 +3,8 @@ use crate::spec::{LinkerFlavor, RelocModel, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::freebsd_base::opts();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into());
// Extra hint to linker that we are generating secure-PLT code.
- base.pre_link_args
- .entry(LinkerFlavor::Gcc)
- .or_default()
- .push("--target=powerpc-unknown-freebsd13.0".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "--target=powerpc-unknown-freebsd13.0"]);
base.max_atomic_width = Some(32);
Target {
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs
index 88f61500e3c..6686a0bbf04 100644
--- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs
@@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
base.max_atomic_width = Some(32);
Target {
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs
index 3ee548750b9..6a250f4b51c 100644
--- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs
@@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mspe".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-mspe"]);
base.max_atomic_width = Some(32);
Target {
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs
index ce33c787f33..34200c67906 100644
--- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs
@@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::linux_musl_base::opts();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
base.max_atomic_width = Some(32);
Target {
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs
index 998225f4dae..60661ef9b5d 100644
--- a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs
@@ -3,7 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::netbsd_base::opts();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
base.max_atomic_width = Some(32);
Target {
diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs
index 76709cec591..3f24966e06e 100644
--- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs
@@ -3,8 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::vxworks_base::opts();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".into());
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("--secure-plt".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "--secure-plt"]);
base.max_atomic_width = Some(32);
Target {
diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs
index 7b5d1242c52..0f04f41f9e5 100644
--- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs
+++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs
@@ -3,8 +3,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::vxworks_base::opts();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mspe".into());
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("--secure-plt".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-mspe", "--secure-plt"]);
base.max_atomic_width = Some(32);
Target {
diff --git a/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs
index 718303a4b4d..836ab0e3728 100644
--- a/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs
@@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::netbsd_base::opts();
base.cpu = "v9".into();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64);
Target {
diff --git a/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs
index 2aaa0ca6df8..4a192df392f 100644
--- a/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs
@@ -5,7 +5,7 @@ pub fn target() -> Target {
let mut base = super::openbsd_base::opts();
base.endian = Endian::Big;
base.cpu = "v9".into();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64);
Target {
diff --git a/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs
index 71d3de0bfd1..ea4fafa4b06 100644
--- a/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs
@@ -6,7 +6,7 @@ pub fn target() -> Target {
base.endian = Endian::Big;
base.cpu = "v9".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mv8plus".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-mv8plus"]);
Target {
llvm_target: "sparc-unknown-linux-gnu".into(),
diff --git a/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs
index 79ae54aa666..aac09181a74 100644
--- a/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs
+++ b/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs
@@ -4,7 +4,7 @@ use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target {
let mut base = super::solaris_base::opts();
base.endian = Endian::Big;
- base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".into()]);
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// llvm calls this "v9"
base.cpu = "v9".into();
base.vendor = "sun".into();
diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs
index 0865ca7ea7d..c7c5a231901 100644
--- a/compiler/rustc_target/src/spec/tests/tests_impl.rs
+++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs
@@ -1,4 +1,5 @@
use super::super::*;
+use std::assert_matches::assert_matches;
// Test target self-consistency and JSON encoding/decoding roundtrip.
pub(super) fn test_target(target: Target) {
@@ -14,35 +15,105 @@ impl Target {
assert_eq!(self.is_like_wasm, self.arch == "wasm32" || self.arch == "wasm64");
assert!(self.is_like_windows || !self.is_like_msvc);
- // Check that LLD with the given flavor is treated identically to the linker it emulates.
- // If your target really needs to deviate from the rules below, except it and document the
- // reasons.
- assert_eq!(
- self.linker_flavor == LinkerFlavor::Msvc
- || self.linker_flavor == LinkerFlavor::Lld(LldFlavor::Link),
- self.lld_flavor == LldFlavor::Link,
- );
- assert_eq!(self.is_like_msvc, self.lld_flavor == LldFlavor::Link);
- for args in &[
+ // Check that default linker flavor and lld flavor are compatible
+ // with some other key properties.
+ assert_eq!(self.is_like_osx, matches!(self.lld_flavor, LldFlavor::Ld64));
+ assert_eq!(self.is_like_msvc, matches!(self.lld_flavor, LldFlavor::Link));
+ assert_eq!(self.is_like_wasm, matches!(self.lld_flavor, LldFlavor::Wasm));
+ assert_eq!(self.os == "l4re", matches!(self.linker_flavor, LinkerFlavor::L4Bender));
+ assert_eq!(self.os == "emscripten", matches!(self.linker_flavor, LinkerFlavor::Em));
+ assert_eq!(self.arch == "bpf", matches!(self.linker_flavor, LinkerFlavor::BpfLinker));
+ assert_eq!(self.arch == "nvptx64", matches!(self.linker_flavor, LinkerFlavor::PtxLinker));
+
+ for args in [
&self.pre_link_args,
&self.late_link_args,
&self.late_link_args_dynamic,
&self.late_link_args_static,
&self.post_link_args,
] {
+ for (&flavor, flavor_args) in args {
+ assert!(!flavor_args.is_empty());
+ // Check that flavors mentioned in link args are compatible with the default flavor.
+ match (self.linker_flavor, self.lld_flavor) {
+ (
+ LinkerFlavor::Ld | LinkerFlavor::Lld(LldFlavor::Ld) | LinkerFlavor::Gcc,
+ LldFlavor::Ld,
+ ) => {
+ assert_matches!(
+ flavor,
+ LinkerFlavor::Ld | LinkerFlavor::Lld(LldFlavor::Ld) | LinkerFlavor::Gcc
+ )
+ }
+ (LinkerFlavor::Gcc, LldFlavor::Ld64) => {
+ assert_matches!(flavor, LinkerFlavor::Gcc)
+ }
+ (LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link), LldFlavor::Link) => {
+ assert_matches!(
+ flavor,
+ LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link)
+ )
+ }
+ (LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc, LldFlavor::Wasm) => {
+ assert_matches!(
+ flavor,
+ LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc
+ )
+ }
+ (LinkerFlavor::L4Bender, LldFlavor::Ld) => {
+ assert_matches!(flavor, LinkerFlavor::L4Bender)
+ }
+ (LinkerFlavor::Em, LldFlavor::Wasm) => {
+ assert_matches!(flavor, LinkerFlavor::Em)
+ }
+ (LinkerFlavor::BpfLinker, LldFlavor::Ld) => {
+ assert_matches!(flavor, LinkerFlavor::BpfLinker)
+ }
+ (LinkerFlavor::PtxLinker, LldFlavor::Ld) => {
+ assert_matches!(flavor, LinkerFlavor::PtxLinker)
+ }
+ flavors => unreachable!("unexpected flavor combination: {:?}", flavors),
+ }
+
+ // Check that link args for cc and non-cc versions of flavors are consistent.
+ let check_noncc = |noncc_flavor| {
+ if let Some(noncc_args) = args.get(&noncc_flavor) {
+ for arg in flavor_args {
+ if let Some(suffix) = arg.strip_prefix("-Wl,") {
+ assert!(noncc_args.iter().any(|a| a == suffix));
+ }
+ }
+ }
+ };
+ match self.linker_flavor {
+ LinkerFlavor::Gcc => match self.lld_flavor {
+ LldFlavor::Ld => {
+ check_noncc(LinkerFlavor::Ld);
+ check_noncc(LinkerFlavor::Lld(LldFlavor::Ld));
+ }
+ LldFlavor::Wasm => check_noncc(LinkerFlavor::Lld(LldFlavor::Wasm)),
+ LldFlavor::Ld64 | LldFlavor::Link => {}
+ },
+ _ => {}
+ }
+ }
+
+ // Check that link args for lld and non-lld versions of flavors are consistent.
+ assert_eq!(args.get(&LinkerFlavor::Ld), args.get(&LinkerFlavor::Lld(LldFlavor::Ld)));
assert_eq!(
args.get(&LinkerFlavor::Msvc),
args.get(&LinkerFlavor::Lld(LldFlavor::Link)),
);
- if args.contains_key(&LinkerFlavor::Msvc) {
- assert_eq!(self.lld_flavor, LldFlavor::Link);
- }
}
+
assert!(
(self.pre_link_objects_fallback.is_empty()
&& self.post_link_objects_fallback.is_empty())
|| self.crt_objects_fallback.is_some()
);
+
+ // If your target really needs to deviate from the rules below,
+ // except it and document the reasons.
// Keep the default "unknown" vendor instead.
assert_ne!(self.vendor, "");
if !self.can_use_os_unknown() {
diff --git a/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs
index f6cbbd38cf4..4d09d3a4d10 100644
--- a/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs
@@ -1,4 +1,4 @@
-use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::windows_msvc_base::opts();
@@ -9,12 +9,7 @@ pub fn target() -> Target {
// should be smart enough to insert branch islands only
// where necessary, but this is not the observed behavior.
// Disabling the LBR optimization works around the issue.
- let pre_link_args_msvc = "/OPT:NOLBR";
- base.pre_link_args.entry(LinkerFlavor::Msvc).or_default().push(pre_link_args_msvc.into());
- base.pre_link_args
- .entry(LinkerFlavor::Lld(LldFlavor::Link))
- .or_default()
- .push(pre_link_args_msvc.into());
+ base.add_pre_link_args(LinkerFlavor::Msvc, &["/OPT:NOLBR"]);
Target {
llvm_target: "thumbv7a-pc-windows-msvc".into(),
diff --git a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
index 9a3e8b5c5f8..4cad9e18370 100644
--- a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
@@ -10,7 +10,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::android_base::opts();
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-march=armv7-a".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-march=armv7-a"]);
Target {
llvm_target: "armv7-none-linux-android".into(),
pointer_width: 32,
diff --git a/compiler/rustc_target/src/spec/uefi_msvc_base.rs b/compiler/rustc_target/src/spec/uefi_msvc_base.rs
index bc7244b3a45..aee8eb2e31c 100644
--- a/compiler/rustc_target/src/spec/uefi_msvc_base.rs
+++ b/compiler/rustc_target/src/spec/uefi_msvc_base.rs
@@ -14,27 +14,25 @@ use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, StackProbeType, Target
pub fn opts() -> TargetOptions {
let mut base = super::msvc_base::opts();
- let pre_link_args_msvc = vec![
- // Non-standard subsystems have no default entry-point in PE+ files. We have to define
- // one. "efi_main" seems to be a common choice amongst other implementations and the
- // spec.
- "/entry:efi_main".into(),
- // COFF images have a "Subsystem" field in their header, which defines what kind of
- // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
- // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
- // which is very likely the most common option. Individual projects can override this
- // with custom linker flags.
- // The subsystem-type only has minor effects on the application. It defines the memory
- // regions the application is loaded into (runtime-drivers need to be put into
- // reserved areas), as well as whether a return from the entry-point is treated as
- // exit (default for applications).
- "/subsystem:efi_application".into(),
- ];
- base.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone());
- base.pre_link_args
- .entry(LinkerFlavor::Lld(LldFlavor::Link))
- .or_default()
- .extend(pre_link_args_msvc);
+ base.add_pre_link_args(
+ LinkerFlavor::Msvc,
+ &[
+ // Non-standard subsystems have no default entry-point in PE+ files. We have to define
+ // one. "efi_main" seems to be a common choice amongst other implementations and the
+ // spec.
+ "/entry:efi_main",
+ // COFF images have a "Subsystem" field in their header, which defines what kind of
+ // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
+ // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
+ // which is very likely the most common option. Individual projects can override this
+ // with custom linker flags.
+ // The subsystem-type only has minor effects on the application. It defines the memory
+ // regions the application is loaded into (runtime-drivers need to be put into
+ // reserved areas), as well as whether a return from the entry-point is treated as
+ // exit (default for applications).
+ "/subsystem:efi_application",
+ ],
+ );
TargetOptions {
os: "uefi".into(),
diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs
index 1b94c59b55f..c7e7d221086 100644
--- a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs
+++ b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs
@@ -2,21 +2,11 @@ use super::{cvs, wasm_base};
use super::{LinkArgs, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions};
pub fn target() -> Target {
- let mut options = wasm_base::options();
-
- let clang_args = options.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
-
- // Rust really needs a way for users to specify exports and imports in
- // the source code. --export-dynamic isn't the right tool for this job,
- // however it does have the side effect of automatically exporting a lot
- // of symbols, which approximates what people want when compiling for
- // wasm32-unknown-unknown expect, so use it for now.
- clang_args.push("--export-dynamic".into());
-
- let mut post_link_args = LinkArgs::new();
- post_link_args.insert(
+ // Reset flags for non-Em flavors back to empty to satisfy sanity checking tests.
+ let pre_link_args = LinkArgs::new();
+ let post_link_args = TargetOptions::link_args(
LinkerFlavor::Em,
- vec!["-sABORTING_MALLOC=0".into(), "-Wl,--fatal-warnings".into()],
+ &["-sABORTING_MALLOC=0", "-Wl,--fatal-warnings"],
);
let opts = TargetOptions {
@@ -26,12 +16,13 @@ pub fn target() -> Target {
// functionality, and a .wasm file.
exe_suffix: ".js".into(),
linker: None,
+ pre_link_args,
+ post_link_args,
relocation_model: RelocModel::Pic,
panic_strategy: PanicStrategy::Unwind,
no_default_libraries: false,
- post_link_args,
families: cvs!["unix", "wasm"],
- ..options
+ ..wasm_base::options()
};
Target {
llvm_target: "wasm32-unknown-emscripten".into(),
diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs
index 214b5fce5a6..4e2927dd913 100644
--- a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs
+++ b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs
@@ -29,27 +29,30 @@ pub fn target() -> Target {
// code on this target due to this ABI mismatch.
options.default_adjusted_cabi = Some(Abi::Wasm);
- let clang_args = options.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
-
- // Make sure clang uses LLD as its linker and is configured appropriately
- // otherwise
- clang_args.push("--target=wasm32-unknown-unknown".into());
-
- // For now this target just never has an entry symbol no matter the output
- // type, so unconditionally pass this.
- clang_args.push("-Wl,--no-entry".into());
-
- // Rust really needs a way for users to specify exports and imports in
- // the source code. --export-dynamic isn't the right tool for this job,
- // however it does have the side effect of automatically exporting a lot
- // of symbols, which approximates what people want when compiling for
- // wasm32-unknown-unknown expect, so use it for now.
- clang_args.push("-Wl,--export-dynamic".into());
-
- // Add the flags to wasm-ld's args too.
- let lld_args = options.pre_link_args.entry(LinkerFlavor::Lld(LldFlavor::Wasm)).or_default();
- lld_args.push("--no-entry".into());
- lld_args.push("--export-dynamic".into());
+ options.add_pre_link_args(
+ LinkerFlavor::Lld(LldFlavor::Wasm),
+ &[
+ // For now this target just never has an entry symbol no matter the output
+ // type, so unconditionally pass this.
+ "--no-entry",
+ // Rust really needs a way for users to specify exports and imports in
+ // the source code. --export-dynamic isn't the right tool for this job,
+ // however it does have the side effect of automatically exporting a lot
+ // of symbols, which approximates what people want when compiling for
+ // wasm32-unknown-unknown expect, so use it for now.
+ "--export-dynamic",
+ ],
+ );
+ options.add_pre_link_args(
+ LinkerFlavor::Gcc,
+ &[
+ // Make sure clang uses LLD as its linker and is configured appropriately
+ // otherwise
+ "--target=wasm32-unknown-unknown",
+ "-Wl,--no-entry",
+ "-Wl,--export-dynamic",
+ ],
+ );
Target {
llvm_target: "wasm32-unknown-unknown".into(),
diff --git a/compiler/rustc_target/src/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs
index 10eb78e4e25..280457d68b9 100644
--- a/compiler/rustc_target/src/spec/wasm32_wasi.rs
+++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs
@@ -80,11 +80,7 @@ pub fn target() -> Target {
options.os = "wasi".into();
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
- options
- .pre_link_args
- .entry(LinkerFlavor::Gcc)
- .or_insert(Vec::new())
- .push("--target=wasm32-wasi".into());
+ options.add_pre_link_args(LinkerFlavor::Gcc, &["--target=wasm32-wasi"]);
options.pre_link_objects_fallback = crt_objects::pre_wasi_fallback();
options.post_link_objects_fallback = crt_objects::post_wasi_fallback();
diff --git a/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs
index 6826c0ac62b..5211f7707fb 100644
--- a/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs
+++ b/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs
@@ -14,19 +14,25 @@ pub fn target() -> Target {
let mut options = wasm_base::options();
options.os = "unknown".into();
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
- let clang_args = options.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap();
- // Make sure clang uses LLD as its linker and is configured appropriately
- // otherwise
- clang_args.push("--target=wasm64-unknown-unknown".into());
-
- // For now this target just never has an entry symbol no matter the output
- // type, so unconditionally pass this.
- clang_args.push("-Wl,--no-entry".into());
-
- let lld_args = options.pre_link_args.get_mut(&LinkerFlavor::Lld(LldFlavor::Wasm)).unwrap();
- lld_args.push("--no-entry".into());
- lld_args.push("-mwasm64".into());
+ options.add_pre_link_args(
+ LinkerFlavor::Lld(LldFlavor::Wasm),
+ &[
+ // For now this target just never has an entry symbol no matter the output
+ // type, so unconditionally pass this.
+ "--no-entry",
+ "-mwasm64",
+ ],
+ );
+ options.add_pre_link_args(
+ LinkerFlavor::Gcc,
+ &[
+ // Make sure clang uses LLD as its linker and is configured appropriately
+ // otherwise
+ "--target=wasm64-unknown-unknown",
+ "-Wl,--no-entry",
+ ],
+ );
// Any engine that implements wasm64 will surely implement the rest of these
// features since they were all merged into the official spec by the time
diff --git a/compiler/rustc_target/src/spec/wasm_base.rs b/compiler/rustc_target/src/spec/wasm_base.rs
index de7b7374af3..5736402ae14 100644
--- a/compiler/rustc_target/src/spec/wasm_base.rs
+++ b/compiler/rustc_target/src/spec/wasm_base.rs
@@ -1,63 +1,56 @@
use super::crt_objects::CrtObjectsFallback;
use super::{cvs, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel};
-use std::collections::BTreeMap;
pub fn options() -> TargetOptions {
- let mut lld_args = Vec::new();
- let mut clang_args = Vec::new();
- let mut arg = |arg: &'static str| {
- lld_args.push(arg.into());
- clang_args.push(format!("-Wl,{}", arg).into());
- };
-
- // By default LLD only gives us one page of stack (64k) which is a
- // little small. Default to a larger stack closer to other PC platforms
- // (1MB) and users can always inject their own link-args to override this.
- arg("-z");
- arg("stack-size=1048576");
-
- // By default LLD's memory layout is:
- //
- // 1. First, a blank page
- // 2. Next, all static data
- // 3. Finally, the main stack (which grows down)
- //
- // This has the unfortunate consequence that on stack overflows you
- // corrupt static data and can cause some exceedingly weird bugs. To
- // help detect this a little sooner we instead request that the stack is
- // placed before static data.
- //
- // This means that we'll generate slightly larger binaries as references
- // to static data will take more bytes in the ULEB128 encoding, but
- // stack overflow will be guaranteed to trap as it underflows instead of
- // corrupting static data.
- arg("--stack-first");
-
- // FIXME we probably shouldn't pass this but instead pass an explicit list
- // of symbols we'll allow to be undefined. We don't currently have a
- // mechanism of knowing, however, which symbols are intended to be imported
- // from the environment and which are intended to be imported from other
- // objects linked elsewhere. This is a coarse approximation but is sure to
- // hide some bugs and frustrate someone at some point, so we should ideally
- // work towards a world where we can explicitly list symbols that are
- // supposed to be imported and have all other symbols generate errors if
- // they remain undefined.
- arg("--allow-undefined");
-
- // Rust code should never have warnings, and warnings are often
- // indicative of bugs, let's prevent them.
- arg("--fatal-warnings");
-
- // LLD only implements C++-like demangling, which doesn't match our own
- // mangling scheme. Tell LLD to not demangle anything and leave it up to
- // us to demangle these symbols later. Currently rustc does not perform
- // further demangling, but tools like twiggy and wasm-bindgen are intended
- // to do so.
- arg("--no-demangle");
-
- let mut pre_link_args = BTreeMap::new();
- pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Wasm), lld_args);
- pre_link_args.insert(LinkerFlavor::Gcc, clang_args);
+ macro_rules! args {
+ ($prefix:literal) => {
+ &[
+ // By default LLD only gives us one page of stack (64k) which is a
+ // little small. Default to a larger stack closer to other PC platforms
+ // (1MB) and users can always inject their own link-args to override this.
+ concat!($prefix, "-z"),
+ concat!($prefix, "stack-size=1048576"),
+ // By default LLD's memory layout is:
+ //
+ // 1. First, a blank page
+ // 2. Next, all static data
+ // 3. Finally, the main stack (which grows down)
+ //
+ // This has the unfortunate consequence that on stack overflows you
+ // corrupt static data and can cause some exceedingly weird bugs. To
+ // help detect this a little sooner we instead request that the stack is
+ // placed before static data.
+ //
+ // This means that we'll generate slightly larger binaries as references
+ // to static data will take more bytes in the ULEB128 encoding, but
+ // stack overflow will be guaranteed to trap as it underflows instead of
+ // corrupting static data.
+ concat!($prefix, "--stack-first"),
+ // FIXME we probably shouldn't pass this but instead pass an explicit list
+ // of symbols we'll allow to be undefined. We don't currently have a
+ // mechanism of knowing, however, which symbols are intended to be imported
+ // from the environment and which are intended to be imported from other
+ // objects linked elsewhere. This is a coarse approximation but is sure to
+ // hide some bugs and frustrate someone at some point, so we should ideally
+ // work towards a world where we can explicitly list symbols that are
+ // supposed to be imported and have all other symbols generate errors if
+ // they remain undefined.
+ concat!($prefix, "--allow-undefined"),
+ // Rust code should never have warnings, and warnings are often
+ // indicative of bugs, let's prevent them.
+ concat!($prefix, "--fatal-warnings"),
+ // LLD only implements C++-like demangling, which doesn't match our own
+ // mangling scheme. Tell LLD to not demangle anything and leave it up to
+ // us to demangle these symbols later. Currently rustc does not perform
+ // further demangling, but tools like twiggy and wasm-bindgen are intended
+ // to do so.
+ concat!($prefix, "--no-demangle"),
+ ]
+ };
+ }
+
+ let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Lld(LldFlavor::Wasm), args!(""));
+ super::add_link_args(&mut pre_link_args, LinkerFlavor::Gcc, args!("-Wl,"));
TargetOptions {
is_like_wasm: true,
diff --git a/compiler/rustc_target/src/spec/windows_gnu_base.rs b/compiler/rustc_target/src/spec/windows_gnu_base.rs
index d11f1f7d3f8..a0480f386f7 100644
--- a/compiler/rustc_target/src/spec/windows_gnu_base.rs
+++ b/compiler/rustc_target/src/spec/windows_gnu_base.rs
@@ -1,31 +1,35 @@
use crate::spec::crt_objects::{self, CrtObjectsFallback};
-use crate::spec::{cvs, LinkArgs, LinkerFlavor, LldFlavor, TargetOptions};
+use crate::spec::{cvs, LinkerFlavor, TargetOptions};
pub fn opts() -> TargetOptions {
- let mut pre_link_args = LinkArgs::new();
- pre_link_args.insert(
+ let mut pre_link_args = TargetOptions::link_args(
+ LinkerFlavor::Ld,
+ &[
+ // Enable ASLR
+ "--dynamicbase",
+ // ASLR will rebase it anyway so leaving that option enabled only leads to confusion
+ "--disable-auto-image-base",
+ ],
+ );
+ super::add_link_args(
+ &mut pre_link_args,
LinkerFlavor::Gcc,
- vec![
+ &[
// Tell GCC to avoid linker plugins, because we are not bundling
// them with Windows installer, and Rust does its own LTO anyways.
- "-fno-use-linker-plugin".into(),
- // Enable ASLR
- "-Wl,--dynamicbase".into(),
- // ASLR will rebase it anyway so leaving that option enabled only leads to confusion
- "-Wl,--disable-auto-image-base".into(),
+ "-fno-use-linker-plugin",
+ "-Wl,--dynamicbase",
+ "-Wl,--disable-auto-image-base",
],
);
- let mut late_link_args = LinkArgs::new();
- let mut late_link_args_dynamic = LinkArgs::new();
- let mut late_link_args_static = LinkArgs::new();
// Order of `late_link_args*` was found through trial and error to work with various
// mingw-w64 versions (not tested on the CI). It's expected to change from time to time.
- let mingw_libs = vec![
- "-lmsvcrt".into(),
- "-lmingwex".into(),
- "-lmingw32".into(),
- "-lgcc".into(), // alas, mingw* libraries above depend on libgcc
+ let mingw_libs = &[
+ "-lmsvcrt",
+ "-lmingwex",
+ "-lmingw32",
+ "-lgcc", // alas, mingw* libraries above depend on libgcc
// mingw's msvcrt is a weird hybrid import library and static library.
// And it seems that the linker fails to use import symbols from msvcrt
// that are required from functions in msvcrt in certain cases. For example
@@ -33,31 +37,27 @@ pub fn opts() -> TargetOptions {
// The library is purposely listed twice to fix that.
//
// See https://github.com/rust-lang/rust/pull/47483 for some more details.
- "-lmsvcrt".into(),
- "-luser32".into(),
- "-lkernel32".into(),
- ];
- late_link_args.insert(LinkerFlavor::Gcc, mingw_libs.clone());
- late_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), mingw_libs);
- let dynamic_unwind_libs = vec![
- // If any of our crates are dynamically linked then we need to use
- // the shared libgcc_s-dw2-1.dll. This is required to support
- // unwinding across DLL boundaries.
- "-lgcc_s".into(),
- ];
- late_link_args_dynamic.insert(LinkerFlavor::Gcc, dynamic_unwind_libs.clone());
- late_link_args_dynamic.insert(LinkerFlavor::Lld(LldFlavor::Ld), dynamic_unwind_libs);
- let static_unwind_libs = vec![
- // If all of our crates are statically linked then we can get away
- // with statically linking the libgcc unwinding code. This allows
- // binaries to be redistributed without the libgcc_s-dw2-1.dll
- // dependency, but unfortunately break unwinding across DLL
- // boundaries when unwinding across FFI boundaries.
- "-lgcc_eh".into(),
- "-l:libpthread.a".into(),
+ "-lmsvcrt",
+ "-luser32",
+ "-lkernel32",
];
- late_link_args_static.insert(LinkerFlavor::Gcc, static_unwind_libs.clone());
- late_link_args_static.insert(LinkerFlavor::Lld(LldFlavor::Ld), static_unwind_libs);
+ let mut late_link_args = TargetOptions::link_args(LinkerFlavor::Ld, mingw_libs);
+ super::add_link_args(&mut late_link_args, LinkerFlavor::Gcc, mingw_libs);
+ // If any of our crates are dynamically linked then we need to use
+ // the shared libgcc_s-dw2-1.dll. This is required to support
+ // unwinding across DLL boundaries.
+ let dynamic_unwind_libs = &["-lgcc_s"];
+ let mut late_link_args_dynamic =
+ TargetOptions::link_args(LinkerFlavor::Ld, dynamic_unwind_libs);
+ super::add_link_args(&mut late_link_args_dynamic, LinkerFlavor::Gcc, dynamic_unwind_libs);
+ // If all of our crates are statically linked then we can get away
+ // with statically linking the libgcc unwinding code. This allows
+ // binaries to be redistributed without the libgcc_s-dw2-1.dll
+ // dependency, but unfortunately break unwinding across DLL
+ // boundaries when unwinding across FFI boundaries.
+ let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"];
+ let mut late_link_args_static = TargetOptions::link_args(LinkerFlavor::Ld, static_unwind_libs);
+ super::add_link_args(&mut late_link_args_static, LinkerFlavor::Gcc, static_unwind_libs);
TargetOptions {
os: "windows".into(),
diff --git a/compiler/rustc_target/src/spec/windows_gnullvm_base.rs b/compiler/rustc_target/src/spec/windows_gnullvm_base.rs
index 9f9f8be8718..30f995007a9 100644
--- a/compiler/rustc_target/src/spec/windows_gnullvm_base.rs
+++ b/compiler/rustc_target/src/spec/windows_gnullvm_base.rs
@@ -1,28 +1,17 @@
-use crate::spec::{cvs, LinkArgs, LinkerFlavor, TargetOptions};
+use crate::spec::{cvs, LinkerFlavor, TargetOptions};
pub fn opts() -> TargetOptions {
- let pre_link_args = LinkArgs::from([(
+ // We cannot use `-nodefaultlibs` because compiler-rt has to be passed
+ // as a path since it's not added to linker search path by the default.
+ // There were attemts to make it behave like libgcc (so one can just use -l<name>)
+ // but LLVM maintainers rejected it: https://reviews.llvm.org/D51440
+ let pre_link_args =
+ TargetOptions::link_args(LinkerFlavor::Gcc, &["-nolibc", "--unwindlib=none"]);
+ // Order of `late_link_args*` does not matter with LLD.
+ let late_link_args = TargetOptions::link_args(
LinkerFlavor::Gcc,
- vec![
- // We cannot use `-nodefaultlibs` because compiler-rt has to be passed
- // as a path since it's not added to linker search path by the default.
- // There were attemts to make it behave like libgcc (so one can just use -l<name>)
- // but LLVM maintainers rejected it: https://reviews.llvm.org/D51440
- "-nolibc".into(),
- "--unwindlib=none".into(),
- ],
- )]);
- let late_link_args = LinkArgs::from([(
- LinkerFlavor::Gcc,
- // Order of `late_link_args*` does not matter with LLD.
- vec![
- "-lmingw32".into(),
- "-lmingwex".into(),
- "-lmsvcrt".into(),
- "-lkernel32".into(),
- "-luser32".into(),
- ],
- )]);
+ &["-lmingw32", "-lmingwex", "-lmsvcrt", "-lkernel32", "-luser32"],
+ );
TargetOptions {
os: "windows".into(),
diff --git a/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs b/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs
index 11968391776..334dec43ef7 100644
--- a/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs
+++ b/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs
@@ -1,28 +1,25 @@
-use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions};
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
pub fn opts() -> TargetOptions {
let base = super::windows_gnu_base::opts();
// FIXME: This should be updated for the exception machinery changes from #67502
// and inherit from `windows_gnu_base`, at least partially.
- let mut late_link_args = LinkArgs::new();
+ let mingw_libs = &[
+ "-lwinstorecompat",
+ "-lruntimeobject",
+ "-lsynchronization",
+ "-lvcruntime140_app",
+ "-lucrt",
+ "-lwindowsapp",
+ "-lmingwex",
+ "-lmingw32",
+ ];
+ let mut late_link_args = TargetOptions::link_args(LinkerFlavor::Ld, mingw_libs);
+ super::add_link_args(&mut late_link_args, LinkerFlavor::Gcc, mingw_libs);
+ // Reset the flags back to empty until the FIXME above is addressed.
let late_link_args_dynamic = LinkArgs::new();
let late_link_args_static = LinkArgs::new();
- let mingw_libs = vec![
- //"-lwinstorecompat".into(),
- //"-lmingwex".into(),
- //"-lwinstorecompat".into(),
- "-lwinstorecompat".into(),
- "-lruntimeobject".into(),
- "-lsynchronization".into(),
- "-lvcruntime140_app".into(),
- "-lucrt".into(),
- "-lwindowsapp".into(),
- "-lmingwex".into(),
- "-lmingw32".into(),
- ];
- late_link_args.insert(LinkerFlavor::Gcc, mingw_libs.clone());
- late_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), mingw_libs);
TargetOptions {
abi: "uwp".into(),
diff --git a/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs b/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs
index d6b065b529a..f2573fc2d21 100644
--- a/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs
+++ b/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs
@@ -1,16 +1,11 @@
-use crate::spec::{LinkerFlavor, LldFlavor, TargetOptions};
+use crate::spec::{LinkerFlavor, TargetOptions};
pub fn opts() -> TargetOptions {
let mut opts = super::windows_msvc_base::opts();
opts.abi = "uwp".into();
opts.vendor = "uwp".into();
- let pre_link_args_msvc = vec!["/APPCONTAINER".into(), "mincore.lib".into()];
- opts.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone());
- opts.pre_link_args
- .entry(LinkerFlavor::Lld(LldFlavor::Link))
- .or_default()
- .extend(pre_link_args_msvc);
+ opts.add_pre_link_args(LinkerFlavor::Msvc, &["/APPCONTAINER", "mincore.lib"]);
opts
}
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
index 51d14f0403a..dbd26899c18 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
@@ -6,8 +6,7 @@ pub fn target() -> Target {
base.cpu = "core2".into();
base.max_atomic_width = Some(128); // core2 support cmpxchg16b
base.frame_pointer = FramePointer::Always;
- base.pre_link_args
- .insert(LinkerFlavor::Gcc, vec!["-m64".into(), "-arch".into(), "x86_64".into()]);
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-arch", "x86_64"]);
base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove());
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
diff --git a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs
index 47c70513faf..4348d924579 100644
--- a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs
+++ b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs
@@ -1,41 +1,44 @@
-use std::{borrow::Cow, iter};
+use std::borrow::Cow;
use crate::spec::cvs;
use super::{LinkerFlavor, LldFlavor, Target, TargetOptions};
pub fn target() -> Target {
- const PRE_LINK_ARGS: &[&str] = &[
- "-e",
- "elf_entry",
- "-Bstatic",
- "--gc-sections",
- "-z",
- "text",
- "-z",
- "norelro",
- "--no-undefined",
- "--error-unresolved-symbols",
- "--no-undefined-version",
- "-Bsymbolic",
- "--export-dynamic",
- // The following symbols are needed by libunwind, which is linked after
- // libstd. Make sure they're included in the link.
- "-u",
- "__rust_abort",
- "-u",
- "__rust_c_alloc",
- "-u",
- "__rust_c_dealloc",
- "-u",
- "__rust_print_err",
- "-u",
- "__rust_rwlock_rdlock",
- "-u",
- "__rust_rwlock_unlock",
- "-u",
- "__rust_rwlock_wrlock",
- ];
+ let pre_link_args = TargetOptions::link_args(
+ LinkerFlavor::Ld,
+ &[
+ "-e",
+ "elf_entry",
+ "-Bstatic",
+ "--gc-sections",
+ "-z",
+ "text",
+ "-z",
+ "norelro",
+ "--no-undefined",
+ "--error-unresolved-symbols",
+ "--no-undefined-version",
+ "-Bsymbolic",
+ "--export-dynamic",
+ // The following symbols are needed by libunwind, which is linked after
+ // libstd. Make sure they're included in the link.
+ "-u",
+ "__rust_abort",
+ "-u",
+ "__rust_c_alloc",
+ "-u",
+ "__rust_c_dealloc",
+ "-u",
+ "__rust_print_err",
+ "-u",
+ "__rust_rwlock_rdlock",
+ "-u",
+ "__rust_rwlock_unlock",
+ "-u",
+ "__rust_rwlock_wrlock",
+ ],
+ );
const EXPORT_SYMBOLS: &[&str] = &[
"sgx_entry",
@@ -66,11 +69,7 @@ pub fn target() -> Target {
features: "+rdrnd,+rdseed,+lvi-cfi,+lvi-load-hardening".into(),
llvm_args: cvs!["--x86-experimental-lvi-inline-asm-hardening"],
position_independent_executables: true,
- pre_link_args: iter::once((
- LinkerFlavor::Lld(LldFlavor::Ld),
- PRE_LINK_ARGS.iter().cloned().map(Cow::from).collect(),
- ))
- .collect(),
+ pre_link_args,
override_export_symbols: Some(EXPORT_SYMBOLS.iter().cloned().map(Cow::from).collect()),
relax_elf_relocations: true,
..Default::default()
diff --git a/compiler/rustc_target/src/spec/x86_64_linux_android.rs b/compiler/rustc_target/src/spec/x86_64_linux_android.rs
index 049cab0d554..6d19cf26574 100644
--- a/compiler/rustc_target/src/spec/x86_64_linux_android.rs
+++ b/compiler/rustc_target/src/spec/x86_64_linux_android.rs
@@ -6,7 +6,7 @@ pub fn target() -> Target {
// https://developer.android.com/ndk/guides/abis.html#86-64
base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
diff --git a/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs b/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs
index 2a697daeb28..0550b221fd9 100644
--- a/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs
+++ b/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs
@@ -2,7 +2,7 @@ use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target};
pub fn target() -> Target {
let mut base = super::solaris_base::opts();
- base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".into()]);
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.cpu = "x86-64".into();
base.vendor = "pc".into();
base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs
index 0fa43481c9b..59a8cffca48 100644
--- a/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs
@@ -1,14 +1,11 @@
-use crate::spec::{LinkerFlavor, LldFlavor, Target};
+use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target {
let mut base = super::windows_gnu_base::opts();
base.cpu = "x86-64".into();
- let gcc_pre_link_args = base.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
- gcc_pre_link_args.push("-m64".into());
// Use high-entropy 64 bit address space for ASLR
- gcc_pre_link_args.push("-Wl,--high-entropy-va".into());
- base.pre_link_args
- .insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".into(), "i386pep".into()]);
+ base.add_pre_link_args(LinkerFlavor::Ld, &["-m", "i386pep", "--high-entropy-va"]);
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-Wl,--high-entropy-va"]);
base.max_atomic_width = Some(64);
base.linker = Some("x86_64-w64-mingw32-gcc".into());
diff --git a/compiler/rustc_target/src/spec/x86_64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnullvm.rs
index b5ff63e0532..d3909b3895e 100644
--- a/compiler/rustc_target/src/spec/x86_64_pc_windows_gnullvm.rs
+++ b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnullvm.rs
@@ -3,8 +3,7 @@ use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target {
let mut base = super::windows_gnullvm_base::opts();
base.cpu = "x86-64".into();
- let gcc_pre_link_args = base.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
- gcc_pre_link_args.push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64);
base.linker = Some("x86_64-w64-mingw32-clang".into());
diff --git a/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs
index a02018266fb..cbe87589a70 100644
--- a/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs
+++ b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs
@@ -2,7 +2,7 @@ use crate::spec::{LinkerFlavor, StackProbeType, Target};
pub fn target() -> Target {
let mut base = super::solaris_base::opts();
- base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".into()]);
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.cpu = "x86-64".into();
base.vendor = "sun".into();
base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs
index 1f2b998a7ba..746f6478178 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs
@@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::dragonfly_base::opts();
base.cpu = "x86-64".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs
index c9aedd6ea82..b30784ed692 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs
@@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::freebsd_base::opts();
base.cpu = "x86-64".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
base.supported_sanitizers =
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs
index aebbd18c66a..d6d03362982 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs
@@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::haiku_base::opts();
base.cpu = "x86-64".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".into()]);
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
// This option is required to build executables on Haiku x86_64
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs b/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs
index 9529fa9640d..9f19c3a2b2a 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs
@@ -2,7 +2,7 @@ use crate::spec::{LinkerFlavor, SanitizerSet, Target};
pub fn target() -> Target {
let mut base = super::illumos_base::opts();
- base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".into(), "-std=c99".into()]);
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-std=c99"]);
base.cpu = "x86-64".into();
base.max_atomic_width = Some(64);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI;
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs
index e525cfdde14..956be0353fa 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs
@@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts();
base.cpu = "x86-64".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
base.static_position_independent_executables = true;
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs
index 863b41633e2..140882747c2 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs
@@ -5,7 +5,7 @@ pub fn target() -> Target {
base.cpu = "x86-64".into();
base.abi = "x32".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mx32".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-mx32"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
base.has_thread_local = false;
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs
index 8678f06e2cb..87e7784d1f9 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs
@@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::linux_musl_base::opts();
base.cpu = "x86-64".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
base.static_position_independent_executables = true;
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs
index a7115dace1c..d3a67619aa8 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs
@@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::netbsd_base::opts();
base.cpu = "x86-64".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
base.supported_sanitizers = SanitizerSet::ADDRESS
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs b/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs
index 0db88d64ac0..593345a5f1d 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs
@@ -10,7 +10,7 @@ pub fn target() -> Target {
base.features =
"-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float".into();
base.code_model = Some(CodeModel::Kernel);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
Target {
// FIXME: Some dispute, the linux-on-clang folks think this should use
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs
index 11e9cc4abc0..f50c6bceec9 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs
@@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::openbsd_base::opts();
base.cpu = "x86-64".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs
index af8b9673c30..668ae905417 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs
@@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::redox_base::opts();
base.cpu = "x86-64".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
diff --git a/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs
index a94bbbf6ede..76d2013cf7f 100644
--- a/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs
@@ -1,14 +1,11 @@
-use crate::spec::{LinkerFlavor, LldFlavor, Target};
+use crate::spec::{LinkerFlavor, Target};
pub fn target() -> Target {
let mut base = super::windows_uwp_gnu_base::opts();
base.cpu = "x86-64".into();
- let gcc_pre_link_args = base.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
- gcc_pre_link_args.push("-m64".into());
// Use high-entropy 64 bit address space for ASLR
- gcc_pre_link_args.push("-Wl,--high-entropy-va".into());
- base.pre_link_args
- .insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".into(), "i386pep".into()]);
+ base.add_pre_link_args(LinkerFlavor::Ld, &["-m", "i386pep", "--high-entropy-va"]);
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-Wl,--high-entropy-va"]);
base.max_atomic_width = Some(64);
Target {
diff --git a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs
index 16d29753e7d..1298974952f 100644
--- a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs
@@ -4,7 +4,7 @@ pub fn target() -> Target {
let mut base = super::vxworks_base::opts();
base.cpu = "x86-64".into();
base.max_atomic_width = Some(64);
- base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".into());
+ base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
base.disable_redzone = true;
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index a63790b594d..90ff07cba02 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -220,7 +220,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
.map(|&(id, _)| (id, vec![]))
.collect();
- infcx.process_registered_region_obligations(&body_id_map, None, full_env);
+ infcx.process_registered_region_obligations(&body_id_map, full_env);
let region_data = infcx
.inner
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index b37db4b9e18..2b26b916d32 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -407,11 +407,7 @@ fn resolve_negative_obligation<'cx, 'tcx>(
// function bodies with closures).
outlives_env.save_implied_bounds(CRATE_HIR_ID);
- infcx.process_registered_region_obligations(
- outlives_env.region_bound_pairs_map(),
- Some(tcx.lifetimes.re_root_empty),
- param_env,
- );
+ infcx.process_registered_region_obligations(outlives_env.region_bound_pairs_map(), param_env);
let errors = infcx.resolve_regions(region_context, &outlives_env);
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 132c335a7e6..8d344591915 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -366,15 +366,9 @@ fn object_safety_violation_for_method(
// Get an accurate span depending on the violation.
violation.map(|v| {
let node = tcx.hir().get_if_local(method.def_id);
- let span = match (v, node) {
- (MethodViolationCode::ReferencesSelfInput(arg), Some(node)) => node
- .fn_decl()
- .and_then(|decl| decl.inputs.get(arg + 1))
- .map_or(method.ident(tcx).span, |arg| arg.span),
- (MethodViolationCode::UndispatchableReceiver, Some(node)) => node
- .fn_decl()
- .and_then(|decl| decl.inputs.get(0))
- .map_or(method.ident(tcx).span, |arg| arg.span),
+ let span = match (&v, node) {
+ (MethodViolationCode::ReferencesSelfInput(Some(span)), _) => *span,
+ (MethodViolationCode::UndispatchableReceiver(Some(span)), _) => *span,
(MethodViolationCode::ReferencesSelfOutput, Some(node)) => {
node.fn_decl().map_or(method.ident(tcx).span, |decl| decl.output.span())
}
@@ -397,32 +391,41 @@ fn virtual_call_violation_for_method<'tcx>(
// The method's first parameter must be named `self`
if !method.fn_has_self_parameter {
- // We'll attempt to provide a structured suggestion for `Self: Sized`.
- let sugg =
- tcx.hir().get_if_local(method.def_id).as_ref().and_then(|node| node.generics()).map(
- |generics| match generics.predicates {
- [] => (" where Self: Sized", generics.where_clause_span),
- [.., pred] => (", Self: Sized", pred.span().shrink_to_hi()),
- },
- );
- // Get the span pointing at where the `self` receiver should be.
- let sm = tcx.sess.source_map();
- let self_span = method.ident(tcx).span.to(tcx
- .hir()
- .span_if_local(method.def_id)
- .unwrap_or_else(|| sm.next_point(method.ident(tcx).span))
- .shrink_to_hi());
- let self_span = sm.span_through_char(self_span, '(').shrink_to_hi();
- return Some(MethodViolationCode::StaticMethod(
- sugg,
- self_span,
- !sig.inputs().skip_binder().is_empty(),
- ));
+ let sugg = if let Some(hir::Node::TraitItem(hir::TraitItem {
+ generics,
+ kind: hir::TraitItemKind::Fn(sig, _),
+ ..
+ })) = tcx.hir().get_if_local(method.def_id).as_ref()
+ {
+ let sm = tcx.sess.source_map();
+ Some((
+ (
+ format!("&self{}", if sig.decl.inputs.is_empty() { "" } else { ", " }),
+ sm.span_through_char(sig.span, '(').shrink_to_hi(),
+ ),
+ (
+ format!("{} Self: Sized", generics.add_where_or_trailing_comma()),
+ generics.tail_span_for_predicate_suggestion(),
+ ),
+ ))
+ } else {
+ None
+ };
+ return Some(MethodViolationCode::StaticMethod(sugg));
}
- for (i, &input_ty) in sig.skip_binder().inputs()[1..].iter().enumerate() {
+ for (i, &input_ty) in sig.skip_binder().inputs().iter().enumerate().skip(1) {
if contains_illegal_self_type_reference(tcx, trait_def_id, sig.rebind(input_ty)) {
- return Some(MethodViolationCode::ReferencesSelfInput(i));
+ let span = if let Some(hir::Node::TraitItem(hir::TraitItem {
+ kind: hir::TraitItemKind::Fn(sig, _),
+ ..
+ })) = tcx.hir().get_if_local(method.def_id).as_ref()
+ {
+ Some(sig.decl.inputs[i].span)
+ } else {
+ None
+ };
+ return Some(MethodViolationCode::ReferencesSelfInput(span));
}
}
if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) {
@@ -456,7 +459,16 @@ fn virtual_call_violation_for_method<'tcx>(
// `Receiver: Unsize<Receiver[Self => dyn Trait]>`.
if receiver_ty != tcx.types.self_param {
if !receiver_is_dispatchable(tcx, method, receiver_ty) {
- return Some(MethodViolationCode::UndispatchableReceiver);
+ let span = if let Some(hir::Node::TraitItem(hir::TraitItem {
+ kind: hir::TraitItemKind::Fn(sig, _),
+ ..
+ })) = tcx.hir().get_if_local(method.def_id).as_ref()
+ {
+ Some(sig.decl.inputs[0].span)
+ } else {
+ None
+ };
+ return Some(MethodViolationCode::UndispatchableReceiver(span));
} else {
// Do sanity check to make sure the receiver actually has the layout of a pointer.
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 82c54291a5d..aba4f144d4b 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -28,7 +28,6 @@ use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
-use rustc_infer::traits::ObligationCauseCode;
use rustc_middle::traits::select::OverflowError;
use rustc_middle::ty::fold::{MaxUniverse, TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::subst::Subst;
@@ -252,22 +251,10 @@ fn project_and_unify_type<'cx, 'tcx>(
Err(InProgress) => return ProjectAndUnifyResult::Recursive,
};
debug!(?normalized, ?obligations, "project_and_unify_type result");
- let actual = obligation.predicate.term;
- // HACK: lazy TAIT would regress src/test/ui/impl-trait/nested-return-type2.rs, so we add
- // a back-compat hack hat converts the RPITs into inference vars, just like they were before
- // lazy TAIT.
- // This does not affect TAITs in general, as tested in the nested-return-type-tait* tests.
- let InferOk { value: actual, obligations: new } =
- selcx.infcx().replace_opaque_types_with_inference_vars(
- actual,
- obligation.cause.body_id,
- obligation.cause.span,
- ObligationCauseCode::MiscObligation,
- obligation.param_env,
- );
- obligations.extend(new);
-
- match infcx.at(&obligation.cause, obligation.param_env).eq(normalized, actual) {
+ match infcx
+ .at(&obligation.cause, obligation.param_env)
+ .eq(normalized, obligation.predicate.term)
+ {
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
obligations.extend(inferred_obligations);
ProjectAndUnifyResult::Holds(obligations)
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 95f1e224a4c..a1861529b59 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -452,7 +452,7 @@ fn report_conflicting_impls(
match used_to_be_allowed {
None => {
let reported = if overlap.with_impl.is_local()
- || !tcx.orphan_check_crate(()).contains(&impl_def_id)
+ || tcx.orphan_check_impl(impl_def_id).is_ok()
{
let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
Some(decorate(
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index cb1602816ae..f9708d6d919 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -1,3 +1,4 @@
+#![feature(fmt_helpers_for_derive)]
#![feature(min_specialization)]
#![feature(rustc_attrs)]
diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs
index 5cd2901324a..74737e30bb4 100644
--- a/compiler/rustc_type_ir/src/sty.rs
+++ b/compiler/rustc_type_ir/src/sty.rs
@@ -554,137 +554,37 @@ impl<I: Interner> hash::Hash for TyKind<I> {
// This is manually implemented because a derive would require `I: Debug`
impl<I: Interner> fmt::Debug for TyKind<I> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match (&*self,) {
- (&Bool,) => fmt::Formatter::write_str(f, "Bool"),
- (&Char,) => fmt::Formatter::write_str(f, "Char"),
- (&Int(ref __self_0),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Int");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Uint(ref __self_0),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Uint");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Float(ref __self_0),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Float");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Adt(ref __self_0, ref __self_1),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Adt");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_1);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Foreign(ref __self_0),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Foreign");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Str,) => fmt::Formatter::write_str(f, "Str"),
- (&Array(ref __self_0, ref __self_1),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Array");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_1);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Slice(ref __self_0),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Slice");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&RawPtr(ref __self_0),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "RawPtr");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Ref(ref __self_0, ref __self_1, ref __self_2),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Ref");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_1);
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_2);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&FnDef(ref __self_0, ref __self_1),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "FnDef");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_1);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&FnPtr(ref __self_0),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "FnPtr");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Dynamic(ref __self_0, ref __self_1),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Dynamic");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_1);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Closure(ref __self_0, ref __self_1),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Closure");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_1);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Generator(ref __self_0, ref __self_1, ref __self_2),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Generator");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_1);
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_2);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&GeneratorWitness(ref __self_0),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "GeneratorWitness");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Never,) => fmt::Formatter::write_str(f, "Never"),
- (&Tuple(ref __self_0),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Tuple");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Projection(ref __self_0),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Projection");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Opaque(ref __self_0, ref __self_1),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Opaque");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_1);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Param(ref __self_0),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Param");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Bound(ref __self_0, ref __self_1),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Bound");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_1);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Placeholder(ref __self_0),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Placeholder");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Infer(ref __self_0),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Infer");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
- (&Error(ref __self_0),) => {
- let debug_trait_builder = &mut fmt::Formatter::debug_tuple(f, "Error");
- let _ = fmt::DebugTuple::field(debug_trait_builder, &__self_0);
- fmt::DebugTuple::finish(debug_trait_builder)
- }
+ use std::fmt::*;
+ match self {
+ Bool => Formatter::write_str(f, "Bool"),
+ Char => Formatter::write_str(f, "Char"),
+ Int(f0) => Formatter::debug_tuple_field1_finish(f, "Int", f0),
+ Uint(f0) => Formatter::debug_tuple_field1_finish(f, "Uint", f0),
+ Float(f0) => Formatter::debug_tuple_field1_finish(f, "Float", f0),
+ Adt(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Adt", f0, f1),
+ Foreign(f0) => Formatter::debug_tuple_field1_finish(f, "Foreign", f0),
+ Str => Formatter::write_str(f, "Str"),
+ Array(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Array", f0, f1),
+ Slice(f0) => Formatter::debug_tuple_field1_finish(f, "Slice", f0),
+ RawPtr(f0) => Formatter::debug_tuple_field1_finish(f, "RawPtr", f0),
+ Ref(f0, f1, f2) => Formatter::debug_tuple_field3_finish(f, "Ref", f0, f1, f2),
+ FnDef(f0, f1) => Formatter::debug_tuple_field2_finish(f, "FnDef", f0, f1),
+ FnPtr(f0) => Formatter::debug_tuple_field1_finish(f, "FnPtr", f0),
+ Dynamic(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Dynamic", f0, f1),
+ Closure(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Closure", f0, f1),
+ Generator(f0, f1, f2) => {
+ Formatter::debug_tuple_field3_finish(f, "Generator", f0, f1, f2)
+ }
+ GeneratorWitness(f0) => Formatter::debug_tuple_field1_finish(f, "GeneratorWitness", f0),
+ Never => Formatter::write_str(f, "Never"),
+ Tuple(f0) => Formatter::debug_tuple_field1_finish(f, "Tuple", f0),
+ Projection(f0) => Formatter::debug_tuple_field1_finish(f, "Projection", f0),
+ Opaque(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Opaque", f0, f1),
+ Param(f0) => Formatter::debug_tuple_field1_finish(f, "Param", f0),
+ Bound(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Bound", f0, f1),
+ Placeholder(f0) => Formatter::debug_tuple_field1_finish(f, "Placeholder", f0),
+ Infer(f0) => Formatter::debug_tuple_field1_finish(f, "Infer", f0),
+ TyKind::Error(f0) => Formatter::debug_tuple_field1_finish(f, "Error", f0),
}
}
}
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 45c011b78e3..8ffffbed93c 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -32,11 +32,6 @@ use rustc_ty_utils::representability::{self, Representability};
use std::iter;
use std::ops::ControlFlow;
-pub fn check_wf_new(tcx: TyCtxt<'_>) {
- let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
- tcx.hir().par_visit_all_item_likes(&visit);
-}
-
pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
match tcx.sess.target.is_abi_supported(abi) {
Some(true) => (),
@@ -754,7 +749,7 @@ fn check_opaque_meets_bounds<'tcx>(
});
}
-pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
+fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
debug!(
"check_item_type(it.def_id={:?}, it.name={})",
id.def_id,
@@ -1543,12 +1538,6 @@ pub(super) fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
}
}
-pub(super) use wfcheck::check_item_well_formed;
-
-pub(super) use wfcheck::check_trait_item as check_trait_item_well_formed;
-
-pub(super) use wfcheck::check_impl_item as check_impl_item_well_formed;
-
fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) -> ErrorGuaranteed {
struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing")
.span_label(span, "recursive `async fn`")
diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs
index f09c7f51f47..6ee989070b4 100644
--- a/compiler/rustc_typeck/src/check/generator_interior.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior.rs
@@ -225,7 +225,7 @@ pub fn resolve_interior<'a, 'tcx>(
// Note that each region slot in the types gets a new fresh late bound region,
// which means that none of the regions inside relate to any other, even if
// typeck had previously found constraints that would cause them to be related.
- let folded = fcx.tcx.fold_regions(erased, &mut false, |_, current_depth| {
+ let folded = fcx.tcx.fold_regions(erased, |_, current_depth| {
let br = ty::BoundRegion {
var: ty::BoundVar::from_u32(counter),
kind: ty::BrAnon(counter),
diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs
index e26f211c1c1..0ede9ef7756 100644
--- a/compiler/rustc_typeck/src/check/mod.rs
+++ b/compiler/rustc_typeck/src/check/mod.rs
@@ -93,11 +93,7 @@ mod upvar;
mod wfcheck;
pub mod writeback;
-use check::{
- check_abi, check_fn, check_impl_item_well_formed, check_item_well_formed, check_mod_item_types,
- check_trait_item_well_formed,
-};
-pub use check::{check_item_type, check_wf_new};
+use check::{check_abi, check_fn, check_mod_item_types};
pub use diverges::Diverges;
pub use expectation::Expectation;
pub use fn_ctxt::*;
@@ -245,6 +241,7 @@ impl<'tcx> EnclosingBreakables<'tcx> {
pub fn provide(providers: &mut Providers) {
method::provide(providers);
+ wfcheck::provide(providers);
*providers = Providers {
typeck_item_bodies,
typeck_const_arg,
@@ -253,9 +250,6 @@ pub fn provide(providers: &mut Providers) {
has_typeck_results,
adt_destructor,
used_trait_imports,
- check_item_well_formed,
- check_trait_item_well_formed,
- check_impl_item_well_formed,
check_mod_item_types,
region_scope_tree,
..*providers
diff --git a/compiler/rustc_typeck/src/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs
index 161ec31793d..0ce63922098 100644
--- a/compiler/rustc_typeck/src/check/regionck.rs
+++ b/compiler/rustc_typeck/src/check/regionck.rs
@@ -366,7 +366,6 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
fn resolve_regions_and_report_errors(&self) {
self.infcx.process_registered_region_obligations(
self.outlives_environment.region_bound_pairs_map(),
- Some(self.tcx.lifetimes.re_root_empty),
self.param_env,
);
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index 79312153895..67eb88b73fd 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -7,21 +7,18 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::intravisit as hir_visit;
-use rustc_hir::intravisit::Visitor;
-use rustc_hir::itemlikevisit::ParItemLikeVisitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir::ItemKind;
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::outlives::obligations::TypeOutlives;
use rustc_infer::infer::region_constraints::GenericKind;
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
-use rustc_middle::hir::nested_filter;
+use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{
- self, AdtKind, EarlyBinder, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable,
- TypeSuperFoldable, TypeVisitor,
+ self, AdtKind, DefIdTree, EarlyBinder, GenericParamDefKind, ToPredicate, Ty, TyCtxt,
+ TypeFoldable, TypeSuperFoldable, TypeVisitor,
};
use rustc_session::parse::feature_err;
use rustc_span::symbol::{sym, Ident, Symbol};
@@ -70,6 +67,23 @@ impl<'tcx> CheckWfFcxBuilder<'tcx> {
}
}
+fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
+ let node = tcx.hir().expect_owner(def_id);
+ match node {
+ hir::OwnerNode::Crate(_) => {}
+ hir::OwnerNode::Item(item) => check_item(tcx, item),
+ hir::OwnerNode::TraitItem(item) => check_trait_item(tcx, item),
+ hir::OwnerNode::ImplItem(item) => check_impl_item(tcx, item),
+ hir::OwnerNode::ForeignItem(item) => check_foreign_item(tcx, item),
+ }
+
+ if let Some(generics) = node.generics() {
+ for param in generics.params {
+ check_param_wf(tcx, param)
+ }
+ }
+}
+
/// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
/// well-formed, meaning that they do not require any constraints not declared in the struct
/// definition itself. For example, this definition would be illegal:
@@ -84,8 +98,8 @@ impl<'tcx> CheckWfFcxBuilder<'tcx> {
/// not included it frequently leads to confusing errors in fn bodies. So it's better to check
/// the types first.
#[instrument(skip(tcx), level = "debug")]
-pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
- let item = tcx.hir().expect_item(def_id);
+fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
+ let def_id = item.def_id;
debug!(
?item.def_id,
@@ -156,20 +170,6 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
hir::ItemKind::Const(ty, ..) => {
check_item_type(tcx, item.def_id, ty.span, false);
}
- hir::ItemKind::ForeignMod { items, .. } => {
- for it in items.iter() {
- let it = tcx.hir().foreign_item(it.id);
- match it.kind {
- hir::ForeignItemKind::Fn(decl, ..) => {
- check_item_fn(tcx, it.def_id, it.ident, it.span, decl)
- }
- hir::ForeignItemKind::Static(ty, ..) => {
- check_item_type(tcx, it.def_id, ty.span, true)
- }
- hir::ForeignItemKind::Type => (),
- }
- }
- }
hir::ItemKind::Struct(ref struct_def, ref ast_generics) => {
check_type_defn(tcx, item, false, |fcx| vec![fcx.non_enum_variant(struct_def)]);
@@ -191,13 +191,31 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
hir::ItemKind::TraitAlias(..) => {
check_trait(tcx, item);
}
+ // `ForeignItem`s are handled separately.
+ hir::ItemKind::ForeignMod { .. } => {}
_ => {}
}
}
-pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
- let trait_item = tcx.hir().expect_trait_item(def_id);
+fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) {
+ let def_id = item.def_id;
+
+ debug!(
+ ?item.def_id,
+ item.name = ? tcx.def_path_str(def_id.to_def_id())
+ );
+
+ match item.kind {
+ hir::ForeignItemKind::Fn(decl, ..) => {
+ check_item_fn(tcx, item.def_id, item.ident, item.span, decl)
+ }
+ hir::ForeignItemKind::Static(ty, ..) => check_item_type(tcx, item.def_id, ty.span, true),
+ hir::ForeignItemKind::Type => (),
+ }
+}
+
+fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
+ let def_id = trait_item.def_id;
let (method_sig, span) = match trait_item.kind {
hir::TraitItemKind::Fn(ref sig, _) => (Some(sig), trait_item.span),
@@ -207,7 +225,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
check_object_unsafe_self_trait_by_name(tcx, trait_item);
check_associated_item(tcx, trait_item.def_id, span, method_sig);
- let encl_trait_def_id = tcx.hir().get_parent_item(hir_id);
+ let encl_trait_def_id = tcx.local_parent(def_id);
let encl_trait = tcx.hir().expect_item(encl_trait_def_id);
let encl_trait_def_id = encl_trait.def_id.to_def_id();
let fn_lang_item_name = if Some(encl_trait_def_id) == tcx.lang_items().fn_trait() {
@@ -596,13 +614,7 @@ fn ty_known_to_outlive<'tcx>(
) -> bool {
resolve_regions_with_wf_tys(tcx, id, param_env, &wf_tys, |infcx, region_bound_pairs| {
let origin = infer::RelateParamBound(DUMMY_SP, ty, None);
- let outlives = &mut TypeOutlives::new(
- infcx,
- tcx,
- region_bound_pairs,
- Some(infcx.tcx.lifetimes.re_root_empty),
- param_env,
- );
+ let outlives = &mut TypeOutlives::new(infcx, tcx, region_bound_pairs, None, param_env);
outlives.type_must_outlive(origin, ty, region);
})
}
@@ -770,8 +782,8 @@ fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem
}
}
-pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
- let impl_item = tcx.hir().expect_impl_item(def_id);
+fn check_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) {
+ let def_id = impl_item.def_id;
let (method_sig, span) = match impl_item.kind {
hir::ImplItemKind::Fn(ref sig, _) => (Some(sig), impl_item.span),
@@ -780,7 +792,7 @@ pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
_ => (None, impl_item.span),
};
- check_associated_item(tcx, impl_item.def_id, span, method_sig);
+ check_associated_item(tcx, def_id, span, method_sig);
}
fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
@@ -990,6 +1002,15 @@ fn check_type_defn<'tcx, F>(
let packed = tcx.adt_def(item.def_id).repr().packed();
for variant in &variants {
+ // All field types must be well-formed.
+ for field in &variant.fields {
+ fcx.register_wf_obligation(
+ field.ty.into(),
+ field.span,
+ ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(field.def_id))),
+ )
+ }
+
// For DST, or when drop needs to copy things around, all
// intermediate types must be sized.
let needs_drop_copy = || {
@@ -1006,6 +1027,7 @@ fn check_type_defn<'tcx, F>(
}
}
};
+ // All fields (except for possibly the last) should be sized.
let all_sized = all_sized || variant.fields.is_empty() || needs_drop_copy();
let unsized_len = if all_sized { 0 } else { 1 };
for (idx, field) in
@@ -1030,15 +1052,6 @@ fn check_type_defn<'tcx, F>(
);
}
- // All field types must be well-formed.
- for field in &variant.fields {
- fcx.register_wf_obligation(
- field.ty.into(),
- field.span,
- ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(field.def_id))),
- )
- }
-
// Explicit `enum` discriminant values must const-evaluate successfully.
if let Some(discr_def_id) = variant.explicit_discr {
let discr_substs = InternalSubsts::identity_for_item(tcx, discr_def_id.to_def_id());
@@ -1827,67 +1840,12 @@ fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, mut span: Span, id: hir::HirI
fcx.select_all_obligations_or_error();
}
-#[derive(Clone, Copy)]
-pub struct CheckTypeWellFormedVisitor<'tcx> {
- tcx: TyCtxt<'tcx>,
-}
-
-impl<'tcx> CheckTypeWellFormedVisitor<'tcx> {
- pub fn new(tcx: TyCtxt<'tcx>) -> CheckTypeWellFormedVisitor<'tcx> {
- CheckTypeWellFormedVisitor { tcx }
- }
-}
-
-impl<'tcx> ParItemLikeVisitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> {
- fn visit_item(&self, i: &'tcx hir::Item<'tcx>) {
- Visitor::visit_item(&mut self.clone(), i);
- }
-
- fn visit_trait_item(&self, trait_item: &'tcx hir::TraitItem<'tcx>) {
- Visitor::visit_trait_item(&mut self.clone(), trait_item);
- }
-
- fn visit_impl_item(&self, impl_item: &'tcx hir::ImplItem<'tcx>) {
- Visitor::visit_impl_item(&mut self.clone(), impl_item);
- }
-
- fn visit_foreign_item(&self, foreign_item: &'tcx hir::ForeignItem<'tcx>) {
- Visitor::visit_foreign_item(&mut self.clone(), foreign_item)
- }
-}
-
-impl<'tcx> Visitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> {
- type NestedFilter = nested_filter::OnlyBodies;
-
- fn nested_visit_map(&mut self) -> Self::Map {
- self.tcx.hir()
- }
-
- #[instrument(skip(self, i), level = "debug")]
- fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
- trace!(?i);
- self.tcx.ensure().check_item_well_formed(i.def_id);
- hir_visit::walk_item(self, i);
- }
-
- #[instrument(skip(self, trait_item), level = "debug")]
- fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
- trace!(?trait_item);
- self.tcx.ensure().check_trait_item_well_formed(trait_item.def_id);
- hir_visit::walk_trait_item(self, trait_item);
- }
-
- #[instrument(skip(self, impl_item), level = "debug")]
- fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
- trace!(?impl_item);
- self.tcx.ensure().check_impl_item_well_formed(impl_item.def_id);
- hir_visit::walk_impl_item(self, impl_item);
- }
-
- fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
- check_param_wf(self.tcx, p);
- hir_visit::walk_generic_param(self, p);
- }
+fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalDefId) {
+ let items = tcx.hir_module_items(module);
+ items.par_items(|item| tcx.ensure().check_well_formed(item.def_id));
+ items.par_impl_items(|item| tcx.ensure().check_well_formed(item.def_id));
+ items.par_trait_items(|item| tcx.ensure().check_well_formed(item.def_id));
+ items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.def_id));
}
///////////////////////////////////////////////////////////////////////////
@@ -1972,3 +1930,7 @@ fn error_392(
err.span_label(span, "unused parameter");
err
}
+
+pub fn provide(providers: &mut Providers) {
+ *providers = Providers { check_mod_type_wf, check_well_formed, ..*providers };
+}
diff --git a/compiler/rustc_typeck/src/coherence/mod.rs b/compiler/rustc_typeck/src/coherence/mod.rs
index 3903448a007..447ec87f302 100644
--- a/compiler/rustc_typeck/src/coherence/mod.rs
+++ b/compiler/rustc_typeck/src/coherence/mod.rs
@@ -146,7 +146,7 @@ pub fn provide(providers: &mut Providers) {
use self::builtin::coerce_unsized_info;
use self::inherent_impls::{crate_incoherent_impls, crate_inherent_impls, inherent_impls};
use self::inherent_impls_overlap::crate_inherent_impls_overlap_check;
- use self::orphan::orphan_check_crate;
+ use self::orphan::orphan_check_impl;
*providers = Providers {
coherent_trait,
@@ -155,7 +155,7 @@ pub fn provide(providers: &mut Providers) {
inherent_impls,
crate_inherent_impls_overlap_check,
coerce_unsized_info,
- orphan_check_crate,
+ orphan_check_impl,
..*providers
};
}
@@ -171,21 +171,12 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) {
check_impl(tcx, impl_def_id, trait_ref);
check_object_overlap(tcx, impl_def_id, trait_ref);
- }
- builtin::check_trait(tcx, def_id);
-}
-pub fn check_coherence(tcx: TyCtxt<'_>) {
- tcx.sess.time("unsafety_checking", || unsafety::check(tcx));
- tcx.ensure().orphan_check_crate(());
-
- for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
- tcx.ensure().coherent_trait(trait_def_id);
+ tcx.sess.time("unsafety_checking", || unsafety::check_item(tcx, impl_def_id));
+ tcx.sess.time("orphan_checking", || tcx.ensure().orphan_check_impl(impl_def_id));
}
- // these queries are executed for side-effects (error reporting):
- tcx.ensure().crate_inherent_impls(());
- tcx.ensure().crate_inherent_impls_overlap_check(());
+ builtin::check_trait(tcx, def_id);
}
/// Checks whether an impl overlaps with the automatic `impl Trait for dyn Trait`.
diff --git a/compiler/rustc_typeck/src/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs
index 9ddfc8d5cc8..f3a043a08a3 100644
--- a/compiler/rustc_typeck/src/coherence/orphan.rs
+++ b/compiler/rustc_typeck/src/coherence/orphan.rs
@@ -18,26 +18,29 @@ use rustc_span::Span;
use rustc_trait_selection::traits;
use std::ops::ControlFlow;
-pub(super) fn orphan_check_crate(tcx: TyCtxt<'_>, (): ()) -> &[LocalDefId] {
- let mut errors = Vec::new();
- for (&trait_def_id, impls_of_trait) in tcx.all_local_trait_impls(()) {
- for &impl_of_trait in impls_of_trait {
- match orphan_check_impl(tcx, impl_of_trait) {
- Ok(()) => {}
- Err(_) => errors.push(impl_of_trait),
- }
- }
+#[instrument(skip(tcx), level = "debug")]
+pub(crate) fn orphan_check_impl(
+ tcx: TyCtxt<'_>,
+ impl_def_id: LocalDefId,
+) -> Result<(), ErrorGuaranteed> {
+ let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
+ if let Some(err) = trait_ref.error_reported() {
+ return Err(err);
+ }
- if tcx.trait_is_auto(trait_def_id) {
- lint_auto_trait_impls(tcx, trait_def_id, impls_of_trait);
- }
+ let ret = do_orphan_check_impl(tcx, trait_ref, impl_def_id);
+ if tcx.trait_is_auto(trait_ref.def_id) {
+ lint_auto_trait_impl(tcx, trait_ref, impl_def_id);
}
- tcx.arena.alloc_slice(&errors)
+
+ ret
}
-#[instrument(skip(tcx), level = "debug")]
-fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
- let trait_ref = tcx.impl_trait_ref(def_id).unwrap();
+fn do_orphan_check_impl<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ trait_ref: ty::TraitRef<'tcx>,
+ def_id: LocalDefId,
+) -> Result<(), ErrorGuaranteed> {
let trait_def_id = trait_ref.def_id;
let item = tcx.hir().item(hir::ItemId { def_id });
@@ -329,89 +332,82 @@ fn emit_orphan_check_error<'tcx>(
/// Lint impls of auto traits if they are likely to have
/// unsound or surprising effects on auto impls.
-fn lint_auto_trait_impls(tcx: TyCtxt<'_>, trait_def_id: DefId, impls: &[LocalDefId]) {
- let mut non_covering_impls = Vec::new();
- for &impl_def_id in impls {
- let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
- if trait_ref.references_error() {
- return;
- }
+fn lint_auto_trait_impl<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ trait_ref: ty::TraitRef<'tcx>,
+ impl_def_id: LocalDefId,
+) {
+ if tcx.impl_polarity(impl_def_id) != ImplPolarity::Positive {
+ return;
+ }
- if tcx.impl_polarity(impl_def_id) != ImplPolarity::Positive {
+ assert_eq!(trait_ref.substs.len(), 1);
+ let self_ty = trait_ref.self_ty();
+ let (self_type_did, substs) = match self_ty.kind() {
+ ty::Adt(def, substs) => (def.did(), substs),
+ _ => {
+ // FIXME: should also lint for stuff like `&i32` but
+ // considering that auto traits are unstable, that
+ // isn't too important for now as this only affects
+ // crates using `nightly`, and std.
return;
}
+ };
- assert_eq!(trait_ref.substs.len(), 1);
- let self_ty = trait_ref.self_ty();
- let (self_type_did, substs) = match self_ty.kind() {
- ty::Adt(def, substs) => (def.did(), substs),
- _ => {
- // FIXME: should also lint for stuff like `&i32` but
- // considering that auto traits are unstable, that
- // isn't too important for now as this only affects
- // crates using `nightly`, and std.
- continue;
- }
- };
+ // Impls which completely cover a given root type are fine as they
+ // disable auto impls entirely. So only lint if the substs
+ // are not a permutation of the identity substs.
+ let Err(arg) = tcx.uses_unique_generic_params(substs, IgnoreRegions::Yes) else {
+ // ok
+ return;
+ };
- // Impls which completely cover a given root type are fine as they
- // disable auto impls entirely. So only lint if the substs
- // are not a permutation of the identity substs.
- match tcx.uses_unique_generic_params(substs, IgnoreRegions::Yes) {
- Ok(()) => {} // ok
- Err(arg) => {
- // Ideally:
- //
- // - compute the requirements for the auto impl candidate
- // - check whether these are implied by the non covering impls
- // - if not, emit the lint
- //
- // What we do here is a bit simpler:
- //
- // - badly check if an auto impl candidate definitely does not apply
- // for the given simplified type
- // - if so, do not lint
- if fast_reject_auto_impl(tcx, trait_def_id, self_ty) {
- // ok
- } else {
- non_covering_impls.push((impl_def_id, self_type_did, arg));
- }
- }
- }
+ // Ideally:
+ //
+ // - compute the requirements for the auto impl candidate
+ // - check whether these are implied by the non covering impls
+ // - if not, emit the lint
+ //
+ // What we do here is a bit simpler:
+ //
+ // - badly check if an auto impl candidate definitely does not apply
+ // for the given simplified type
+ // - if so, do not lint
+ if fast_reject_auto_impl(tcx, trait_ref.def_id, self_ty) {
+ // ok
+ return;
}
- for &(impl_def_id, self_type_did, arg) in &non_covering_impls {
- tcx.struct_span_lint_hir(
- lint::builtin::SUSPICIOUS_AUTO_TRAIT_IMPLS,
- tcx.hir().local_def_id_to_hir_id(impl_def_id),
- tcx.def_span(impl_def_id),
- |err| {
- let item_span = tcx.def_span(self_type_did);
- let self_descr = tcx.def_kind(self_type_did).descr(self_type_did);
- let mut err = err.build(&format!(
- "cross-crate traits with a default impl, like `{}`, \
+ tcx.struct_span_lint_hir(
+ lint::builtin::SUSPICIOUS_AUTO_TRAIT_IMPLS,
+ tcx.hir().local_def_id_to_hir_id(impl_def_id),
+ tcx.def_span(impl_def_id),
+ |err| {
+ let item_span = tcx.def_span(self_type_did);
+ let self_descr = tcx.def_kind(self_type_did).descr(self_type_did);
+ let mut err = err.build(&format!(
+ "cross-crate traits with a default impl, like `{}`, \
should not be specialized",
- tcx.def_path_str(trait_def_id),
- ));
- match arg {
- ty::util::NotUniqueParam::DuplicateParam(arg) => {
- err.note(&format!("`{}` is mentioned multiple times", arg));
- }
- ty::util::NotUniqueParam::NotParam(arg) => {
- err.note(&format!("`{}` is not a generic parameter", arg));
- }
+ tcx.def_path_str(trait_ref.def_id),
+ ));
+ match arg {
+ ty::util::NotUniqueParam::DuplicateParam(arg) => {
+ err.note(&format!("`{}` is mentioned multiple times", arg));
}
- err.span_note(
- item_span,
- &format!(
- "try using the same sequence of generic parameters as the {} definition",
- self_descr,
- ),
- );
- err.emit();
- },
- );
- }
+ ty::util::NotUniqueParam::NotParam(arg) => {
+ err.note(&format!("`{}` is not a generic parameter", arg));
+ }
+ }
+ err.span_note(
+ item_span,
+ &format!(
+ "try using the same sequence of generic parameters as the {} definition",
+ self_descr,
+ ),
+ );
+ err.emit();
+ },
+ );
}
fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty: Ty<'tcx>) -> bool {
diff --git a/compiler/rustc_typeck/src/coherence/unsafety.rs b/compiler/rustc_typeck/src/coherence/unsafety.rs
index 3cfc96ccbfd..e45fb5fe41c 100644
--- a/compiler/rustc_typeck/src/coherence/unsafety.rs
+++ b/compiler/rustc_typeck/src/coherence/unsafety.rs
@@ -6,37 +6,18 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::Unsafety;
use rustc_middle::ty::TyCtxt;
+use rustc_span::def_id::LocalDefId;
-pub fn check(tcx: TyCtxt<'_>) {
- for id in tcx.hir().items() {
- if matches!(tcx.def_kind(id.def_id), DefKind::Impl) {
- let item = tcx.hir().item(id);
- if let hir::ItemKind::Impl(ref impl_) = item.kind {
- check_unsafety_coherence(
- tcx,
- item,
- Some(&impl_.generics),
- impl_.unsafety,
- impl_.polarity,
- );
- }
- }
- }
-}
+pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
+ debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Impl));
+ let item = tcx.hir().expect_item(def_id);
+ let hir::ItemKind::Impl(ref impl_) = item.kind else { bug!() };
-fn check_unsafety_coherence<'tcx>(
- tcx: TyCtxt<'tcx>,
- item: &hir::Item<'_>,
- impl_generics: Option<&hir::Generics<'_>>,
- unsafety: hir::Unsafety,
- polarity: hir::ImplPolarity,
-) {
if let Some(trait_ref) = tcx.impl_trait_ref(item.def_id) {
let trait_def = tcx.trait_def(trait_ref.def_id);
- let unsafe_attr = impl_generics.and_then(|generics| {
- generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle")
- });
- match (trait_def.unsafety, unsafe_attr, unsafety, polarity) {
+ let unsafe_attr =
+ impl_.generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle");
+ match (trait_def.unsafety, unsafe_attr, impl_.unsafety, impl_.polarity) {
(Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => {
struct_span_err!(
tcx.sess,
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 1f2e6ad86bd..2a52167c597 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -393,7 +393,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
}
fn ct_infer(&self, ty: Ty<'tcx>, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
- let ty = self.tcx.fold_regions(ty, &mut false, |r, _| match *r {
+ let ty = self.tcx.fold_regions(ty, |r, _| match *r {
ty::ReErased => self.tcx.lifetimes.re_static,
_ => r,
});
@@ -1917,7 +1917,7 @@ fn infer_return_ty_for_fn_sig<'tcx>(
Some(ty) => {
let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id];
// Typeck doesn't expect erased regions to be returned from `type_of`.
- let fn_sig = tcx.fold_regions(fn_sig, &mut false, |r, _| match *r {
+ let fn_sig = tcx.fold_regions(fn_sig, |r, _| match *r {
ty::ReErased => tcx.lifetimes.re_static,
_ => r,
});
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 7011dd6e15c..6ee2b544916 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -772,7 +772,7 @@ fn infer_placeholder_type<'a>(
}
// Typeck doesn't expect erased regions to be returned from `type_of`.
- tcx.fold_regions(ty, &mut false, |r, _| match *r {
+ tcx.fold_regions(ty, |r, _| match *r {
ty::ReErased => tcx.lifetimes.re_static,
_ => r,
})
diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs
index 67a3d4a4d02..4cdec615d82 100644
--- a/compiler/rustc_typeck/src/errors.rs
+++ b/compiler/rustc_typeck/src/errors.rs
@@ -6,18 +6,18 @@ use rustc_session::{parse::ParseSess, SessionDiagnostic};
use rustc_span::{symbol::Ident, Span, Symbol};
#[derive(SessionDiagnostic)]
-#[error(code = "E0062", slug = "typeck-field-multiply-specified-in-initializer")]
+#[error(typeck::field_multiply_specified_in_initializer, code = "E0062")]
pub struct FieldMultiplySpecifiedInInitializer {
#[primary_span]
#[label]
pub span: Span,
- #[label = "previous-use-label"]
+ #[label(typeck::previous_use_label)]
pub prev_span: Span,
pub ident: Ident,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0092", slug = "typeck-unrecognized-atomic-operation")]
+#[error(typeck::unrecognized_atomic_operation, code = "E0092")]
pub struct UnrecognizedAtomicOperation<'a> {
#[primary_span]
#[label]
@@ -26,7 +26,7 @@ pub struct UnrecognizedAtomicOperation<'a> {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0094", slug = "typeck-wrong-number-of-generic-arguments-to-intrinsic")]
+#[error(typeck::wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")]
pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
#[primary_span]
#[label]
@@ -37,7 +37,7 @@ pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0093", slug = "typeck-unrecognized-intrinsic-function")]
+#[error(typeck::unrecognized_intrinsic_function, code = "E0093")]
pub struct UnrecognizedIntrinsicFunction {
#[primary_span]
#[label]
@@ -46,19 +46,19 @@ pub struct UnrecognizedIntrinsicFunction {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0195", slug = "typeck-lifetimes-or-bounds-mismatch-on-trait")]
+#[error(typeck::lifetimes_or_bounds_mismatch_on_trait, code = "E0195")]
pub struct LifetimesOrBoundsMismatchOnTrait {
#[primary_span]
#[label]
pub span: Span,
- #[label = "generics-label"]
+ #[label(typeck::generics_label)]
pub generics_span: Option<Span>,
pub item_kind: &'static str,
pub ident: Ident,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0120", slug = "typeck-drop-impl-on-wrong-item")]
+#[error(typeck::drop_impl_on_wrong_item, code = "E0120")]
pub struct DropImplOnWrongItem {
#[primary_span]
#[label]
@@ -66,18 +66,18 @@ pub struct DropImplOnWrongItem {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0124", slug = "typeck-field-already-declared")]
+#[error(typeck::field_already_declared, code = "E0124")]
pub struct FieldAlreadyDeclared {
pub field_name: Ident,
#[primary_span]
#[label]
pub span: Span,
- #[label = "previous-decl-label"]
+ #[label(typeck::previous_decl_label)]
pub prev_span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0184", slug = "typeck-copy-impl-on-type-with-dtor")]
+#[error(typeck::copy_impl_on_type_with_dtor, code = "E0184")]
pub struct CopyImplOnTypeWithDtor {
#[primary_span]
#[label]
@@ -85,14 +85,14 @@ pub struct CopyImplOnTypeWithDtor {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0203", slug = "typeck-multiple-relaxed-default-bounds")]
+#[error(typeck::multiple_relaxed_default_bounds, code = "E0203")]
pub struct MultipleRelaxedDefaultBounds {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0206", slug = "typeck-copy-impl-on-non-adt")]
+#[error(typeck::copy_impl_on_non_adt, code = "E0206")]
pub struct CopyImplOnNonAdt {
#[primary_span]
#[label]
@@ -100,23 +100,23 @@ pub struct CopyImplOnNonAdt {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0224", slug = "typeck-trait-object-declared-with-no-traits")]
+#[error(typeck::trait_object_declared_with_no_traits, code = "E0224")]
pub struct TraitObjectDeclaredWithNoTraits {
#[primary_span]
pub span: Span,
- #[label = "alias-span"]
+ #[label(typeck::alias_span)]
pub trait_alias_span: Option<Span>,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0227", slug = "typeck-ambiguous-lifetime-bound")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0227")]
pub struct AmbiguousLifetimeBound {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0229", slug = "typeck-assoc-type-binding-not-allowed")]
+#[error(typeck::assoc_type_binding_not_allowed, code = "E0229")]
pub struct AssocTypeBindingNotAllowed {
#[primary_span]
#[label]
@@ -124,14 +124,14 @@ pub struct AssocTypeBindingNotAllowed {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0436", slug = "typeck-functional-record-update-on-non-struct")]
+#[error(typeck::functional_record_update_on_non_struct, code = "E0436")]
pub struct FunctionalRecordUpdateOnNonStruct {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0516", slug = "typeck-typeof-reserved-keyword-used")]
+#[error(typeck::typeof_reserved_keyword_used, code = "E0516")]
pub struct TypeofReservedKeywordUsed<'tcx> {
pub ty: Ty<'tcx>,
#[primary_span]
@@ -142,25 +142,25 @@ pub struct TypeofReservedKeywordUsed<'tcx> {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0572", slug = "typeck-return-stmt-outside-of-fn-body")]
+#[error(typeck::return_stmt_outside_of_fn_body, code = "E0572")]
pub struct ReturnStmtOutsideOfFnBody {
#[primary_span]
pub span: Span,
- #[label = "encl-body-label"]
+ #[label(typeck::encl_body_label)]
pub encl_body_span: Option<Span>,
- #[label = "encl-fn-label"]
+ #[label(typeck::encl_fn_label)]
pub encl_fn_span: Option<Span>,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0627", slug = "typeck-yield-expr-outside-of-generator")]
+#[error(typeck::yield_expr_outside_of_generator, code = "E0627")]
pub struct YieldExprOutsideOfGenerator {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0639", slug = "typeck-struct-expr-non-exhaustive")]
+#[error(typeck::struct_expr_non_exhaustive, code = "E0639")]
pub struct StructExprNonExhaustive {
#[primary_span]
pub span: Span,
@@ -168,26 +168,26 @@ pub struct StructExprNonExhaustive {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0699", slug = "typeck-method-call-on-unknown-type")]
+#[error(typeck::method_call_on_unknown_type, code = "E0699")]
pub struct MethodCallOnUnknownType {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0719", slug = "typeck-value-of-associated-struct-already-specified")]
+#[error(typeck::value_of_associated_struct_already_specified, code = "E0719")]
pub struct ValueOfAssociatedStructAlreadySpecified {
#[primary_span]
#[label]
pub span: Span,
- #[label = "previous-bound-label"]
+ #[label(typeck::previous_bound_label)]
pub prev_span: Span,
pub item_name: Ident,
pub def_path: String,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0745", slug = "typeck-address-of-temporary-taken")]
+#[error(typeck::address_of_temporary_taken, code = "E0745")]
pub struct AddressOfTemporaryTaken {
#[primary_span]
#[label]
@@ -197,7 +197,7 @@ pub struct AddressOfTemporaryTaken {
#[derive(SessionSubdiagnostic)]
pub enum AddReturnTypeSuggestion<'tcx> {
#[suggestion(
- slug = "typeck-add-return-type-add",
+ typeck::add_return_type_add,
code = "-> {found} ",
applicability = "machine-applicable"
)]
@@ -207,7 +207,7 @@ pub enum AddReturnTypeSuggestion<'tcx> {
found: Ty<'tcx>,
},
#[suggestion(
- slug = "typeck-add-return-type-missing-here",
+ typeck::add_return_type_missing_here,
code = "-> _ ",
applicability = "has-placeholders"
)]
@@ -219,12 +219,12 @@ pub enum AddReturnTypeSuggestion<'tcx> {
#[derive(SessionSubdiagnostic)]
pub enum ExpectedReturnTypeLabel<'tcx> {
- #[label(slug = "typeck-expected-default-return-type")]
+ #[label(typeck::expected_default_return_type)]
Unit {
#[primary_span]
span: Span,
},
- #[label(slug = "typeck-expected-return-type")]
+ #[label(typeck::expected_return_type)]
Other {
#[primary_span]
span: Span,
@@ -233,7 +233,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> {
}
#[derive(SessionDiagnostic)]
-#[error(slug = "typeck-unconstrained-opaque-type")]
+#[error(typeck::unconstrained_opaque_type)]
#[note]
pub struct UnconstrainedOpaqueType {
#[primary_span]
@@ -301,7 +301,7 @@ impl<'a> SessionDiagnostic<'a> for MissingTypeParams {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0183", slug = "typeck-manual-implementation")]
+#[error(typeck::manual_implementation, code = "E0183")]
#[help]
pub struct ManualImplementation {
#[primary_span]
@@ -311,7 +311,7 @@ pub struct ManualImplementation {
}
#[derive(SessionDiagnostic)]
-#[error(slug = "typeck-substs-on-overridden-impl")]
+#[error(typeck::substs_on_overridden_impl)]
pub struct SubstsOnOverriddenImpl {
#[primary_span]
pub span: Span,
diff --git a/compiler/rustc_typeck/src/impl_wf_check.rs b/compiler/rustc_typeck/src/impl_wf_check.rs
index c089d25d222..981c35e184b 100644
--- a/compiler/rustc_typeck/src/impl_wf_check.rs
+++ b/compiler/rustc_typeck/src/impl_wf_check.rs
@@ -13,7 +13,6 @@ use min_specialization::check_min_specialization;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::struct_span_err;
-use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::query::Providers;
@@ -54,25 +53,15 @@ mod min_specialization;
/// impl<'a> Trait<Foo> for Bar { type X = &'a i32; }
/// // ^ 'a is unused and appears in assoc type, error
/// ```
-pub fn impl_wf_check(tcx: TyCtxt<'_>) {
- // We will tag this as part of the WF check -- logically, it is,
- // but it's one that we must perform earlier than the rest of
- // WfCheck.
- tcx.hir().for_each_module(|module| tcx.ensure().check_mod_impl_wf(module))
-}
-
fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
let min_specialization = tcx.features().min_specialization;
let module = tcx.hir_module_items(module_def_id);
for id in module.items() {
if matches!(tcx.def_kind(id.def_id), DefKind::Impl) {
- let item = tcx.hir().item(id);
- if let hir::ItemKind::Impl(ref impl_) = item.kind {
- enforce_impl_params_are_constrained(tcx, item.def_id, impl_.items);
- enforce_impl_items_are_distinct(tcx, impl_.items);
- if min_specialization {
- check_min_specialization(tcx, item.def_id.to_def_id(), item.span);
- }
+ enforce_impl_params_are_constrained(tcx, id.def_id);
+ enforce_impl_items_are_distinct(tcx, id.def_id);
+ if min_specialization {
+ check_min_specialization(tcx, id.def_id);
}
}
}
@@ -82,11 +71,7 @@ pub fn provide(providers: &mut Providers) {
*providers = Providers { check_mod_impl_wf, ..*providers };
}
-fn enforce_impl_params_are_constrained(
- tcx: TyCtxt<'_>,
- impl_def_id: LocalDefId,
- impl_item_refs: &[hir::ImplItemRef],
-) {
+fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
// Every lifetime used in an associated type must be constrained.
let impl_self_ty = tcx.type_of(impl_def_id);
if impl_self_ty.references_error() {
@@ -114,9 +99,9 @@ fn enforce_impl_params_are_constrained(
);
// Disallow unconstrained lifetimes, but only if they appear in assoc types.
- let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs
+ let lifetimes_in_associated_types: FxHashSet<_> = tcx
+ .associated_item_def_ids(impl_def_id)
.iter()
- .map(|item_ref| item_ref.id.def_id)
.flat_map(|def_id| {
let item = tcx.associated_item(def_id);
match item.kind {
@@ -216,33 +201,32 @@ fn report_unused_parameter(tcx: TyCtxt<'_>, span: Span, kind: &str, name: &str)
}
/// Enforce that we do not have two items in an impl with the same name.
-fn enforce_impl_items_are_distinct(tcx: TyCtxt<'_>, impl_item_refs: &[hir::ImplItemRef]) {
+fn enforce_impl_items_are_distinct(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
let mut seen_type_items = FxHashMap::default();
let mut seen_value_items = FxHashMap::default();
- for impl_item_ref in impl_item_refs {
- let impl_item = tcx.hir().impl_item(impl_item_ref.id);
+ for &impl_item_ref in tcx.associated_item_def_ids(impl_def_id) {
+ let impl_item = tcx.associated_item(impl_item_ref);
let seen_items = match impl_item.kind {
- hir::ImplItemKind::TyAlias(_) => &mut seen_type_items,
+ ty::AssocKind::Type => &mut seen_type_items,
_ => &mut seen_value_items,
};
- match seen_items.entry(impl_item.ident.normalize_to_macros_2_0()) {
+ let span = tcx.def_span(impl_item_ref);
+ let ident = impl_item.ident(tcx);
+ match seen_items.entry(ident.normalize_to_macros_2_0()) {
Occupied(entry) => {
let mut err = struct_span_err!(
tcx.sess,
- impl_item.span,
+ span,
E0201,
"duplicate definitions with name `{}`:",
- impl_item.ident
- );
- err.span_label(
- *entry.get(),
- format!("previous definition of `{}` here", impl_item.ident),
+ ident
);
- err.span_label(impl_item.span, "duplicate definition");
+ err.span_label(*entry.get(), format!("previous definition of `{}` here", ident));
+ err.span_label(span, "duplicate definition");
err.emit();
}
Vacant(entry) => {
- entry.insert(impl_item.span);
+ entry.insert(span);
}
}
}
diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
index 0ecc28e6054..f07396ce74f 100644
--- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
@@ -79,19 +79,19 @@ use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
use rustc_span::Span;
use rustc_trait_selection::traits::{self, translate_substs, wf};
-pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: DefId, span: Span) {
+pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
if let Some(node) = parent_specialization_node(tcx, impl_def_id) {
tcx.infer_ctxt().enter(|infcx| {
- check_always_applicable(&infcx, impl_def_id, node, span);
+ check_always_applicable(&infcx, impl_def_id, node);
});
}
}
-fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: DefId) -> Option<Node> {
+fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId) -> Option<Node> {
let trait_ref = tcx.impl_trait_ref(impl1_def_id)?;
let trait_def = tcx.trait_def(trait_ref.def_id);
- let impl2_node = trait_def.ancestors(tcx, impl1_def_id).ok()?.nth(1)?;
+ let impl2_node = trait_def.ancestors(tcx, impl1_def_id.to_def_id()).ok()?.nth(1)?;
let always_applicable_trait =
matches!(trait_def.specialization_kind, TraitSpecializationKind::AlwaysApplicable);
@@ -103,15 +103,8 @@ fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: DefId) -> Option<No
}
/// Check that `impl1` is a sound specialization
-fn check_always_applicable(
- infcx: &InferCtxt<'_, '_>,
- impl1_def_id: DefId,
- impl2_node: Node,
- span: Span,
-) {
- if let Some((impl1_substs, impl2_substs)) =
- get_impl_substs(infcx, impl1_def_id, impl2_node, span)
- {
+fn check_always_applicable(infcx: &InferCtxt<'_, '_>, impl1_def_id: LocalDefId, impl2_node: Node) {
+ if let Some((impl1_substs, impl2_substs)) = get_impl_substs(infcx, impl1_def_id, impl2_node) {
let impl2_def_id = impl2_node.def_id();
debug!(
"check_always_applicable(\nimpl1_def_id={:?},\nimpl2_def_id={:?},\nimpl2_substs={:?}\n)",
@@ -126,17 +119,10 @@ fn check_always_applicable(
unconstrained_parent_impl_substs(tcx, impl2_def_id, impl2_substs)
};
+ let span = tcx.def_span(impl1_def_id);
check_static_lifetimes(tcx, &parent_substs, span);
check_duplicate_params(tcx, impl1_substs, &parent_substs, span);
-
- check_predicates(
- infcx,
- impl1_def_id.expect_local(),
- impl1_substs,
- impl2_node,
- impl2_substs,
- span,
- );
+ check_predicates(infcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span);
}
}
@@ -152,20 +138,21 @@ fn check_always_applicable(
/// Would return `S1 = [C]` and `S2 = [Vec<C>, C]`.
fn get_impl_substs<'tcx>(
infcx: &InferCtxt<'_, 'tcx>,
- impl1_def_id: DefId,
+ impl1_def_id: LocalDefId,
impl2_node: Node,
- span: Span,
) -> Option<(SubstsRef<'tcx>, SubstsRef<'tcx>)> {
let tcx = infcx.tcx;
let param_env = tcx.param_env(impl1_def_id);
- let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id);
- let impl2_substs = translate_substs(infcx, param_env, impl1_def_id, impl1_substs, impl2_node);
+ let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id.to_def_id());
+ let impl2_substs =
+ translate_substs(infcx, param_env, impl1_def_id.to_def_id(), impl1_substs, impl2_node);
// Conservatively use an empty `ParamEnv`.
let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty());
- infcx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env);
+ infcx.resolve_regions_and_report_errors(impl1_def_id.to_def_id(), &outlives_env);
let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else {
+ let span = tcx.def_span(impl1_def_id);
tcx.sess.emit_err(SubstsOnOverriddenImpl { span });
return None;
};
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index d613edf0ab0..b6d4f5fcda6 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -509,11 +509,21 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
}
tcx.sess.track_errors(|| {
- tcx.sess.time("impl_wf_inference", || impl_wf_check::impl_wf_check(tcx));
+ tcx.sess.time("impl_wf_inference", || {
+ tcx.hir().for_each_module(|module| tcx.ensure().check_mod_impl_wf(module))
+ });
})?;
tcx.sess.track_errors(|| {
- tcx.sess.time("coherence_checking", || coherence::check_coherence(tcx));
+ tcx.sess.time("coherence_checking", || {
+ for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
+ tcx.ensure().coherent_trait(trait_def_id);
+ }
+
+ // these queries are executed for side-effects (error reporting):
+ tcx.ensure().crate_inherent_impls(());
+ tcx.ensure().crate_inherent_impls_overlap_check(());
+ });
})?;
if tcx.features().rustc_attrs {
@@ -523,7 +533,9 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
}
tcx.sess.track_errors(|| {
- tcx.sess.time("wf_checking", || check::check_wf_new(tcx));
+ tcx.sess.time("wf_checking", || {
+ tcx.hir().par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
+ });
})?;
// NOTE: This is copy/pasted in librustdoc/core.rs and should be kept in sync.
diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs
index 807c035fdbd..203e5dff0c7 100644
--- a/library/alloc/src/boxed/thin.rs
+++ b/library/alloc/src/boxed/thin.rs
@@ -33,6 +33,14 @@ pub struct ThinBox<T: ?Sized> {
_marker: PhantomData<T>,
}
+/// `ThinBox<T>` is `Send` if `T` is `Send` because the data is owned.
+#[unstable(feature = "thin_box", issue = "92791")]
+unsafe impl<T: ?Sized + Send> Send for ThinBox<T> {}
+
+/// `ThinBox<T>` is `Sync` if `T` is `Sync` because the data is owned.
+#[unstable(feature = "thin_box", issue = "92791")]
+unsafe impl<T: ?Sized + Sync> Sync for ThinBox<T> {}
+
#[unstable(feature = "thin_box", issue = "92791")]
impl<T> ThinBox<T> {
/// Moves a type to the heap with its `Metadata` stored in the heap allocation instead of on
diff --git a/library/alloc/tests/fmt.rs b/library/alloc/tests/fmt.rs
index 67e12c612db..5ee6db43fda 100644
--- a/library/alloc/tests/fmt.rs
+++ b/library/alloc/tests/fmt.rs
@@ -207,7 +207,7 @@ fn test_format_macro_interface() {
{
let val = usize::MAX;
let exp = format!("{val:#x}");
- t!(format!("{:p}", val as *const isize), exp);
+ t!(format!("{:p}", std::ptr::invalid::<isize>(val)), exp);
}
// Escaping
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 9e4a574818a..1d4be42b4a2 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -4,6 +4,7 @@
use crate::cell::{Cell, Ref, RefCell, RefMut, SyncUnsafeCell, UnsafeCell};
use crate::char::EscapeDebugExtArgs;
+use crate::iter;
use crate::marker::PhantomData;
use crate::mem;
use crate::num::fmt as numfmt;
@@ -693,7 +694,7 @@ pub(crate) mod macros {
/// Derive macro generating an impl of the trait `Debug`.
#[rustc_builtin_macro]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
- #[allow_internal_unstable(core_intrinsics)]
+ #[allow_internal_unstable(core_intrinsics, fmt_helpers_for_derive)]
pub macro Debug($item:item) {
/* compiler built-in */
}
@@ -1964,6 +1965,129 @@ impl<'a> Formatter<'a> {
builders::debug_struct_new(self, name)
}
+ /// Used to shrink `derive(Debug)` code, for faster compilation and smaller binaries.
+ /// `debug_struct_fields_finish` is more general, but this is faster for 1 field.
+ #[doc(hidden)]
+ #[unstable(feature = "fmt_helpers_for_derive", issue = "none")]
+ pub fn debug_struct_field1_finish<'b>(
+ &'b mut self,
+ name: &str,
+ name1: &str,
+ value1: &dyn Debug,
+ ) -> Result {
+ let mut builder = builders::debug_struct_new(self, name);
+ builder.field(name1, value1);
+ builder.finish()
+ }
+
+ /// Used to shrink `derive(Debug)` code, for faster compilation and smaller binaries.
+ /// `debug_struct_fields_finish` is more general, but this is faster for 2 fields.
+ #[doc(hidden)]
+ #[unstable(feature = "fmt_helpers_for_derive", issue = "none")]
+ pub fn debug_struct_field2_finish<'b>(
+ &'b mut self,
+ name: &str,
+ name1: &str,
+ value1: &dyn Debug,
+ name2: &str,
+ value2: &dyn Debug,
+ ) -> Result {
+ let mut builder = builders::debug_struct_new(self, name);
+ builder.field(name1, value1);
+ builder.field(name2, value2);
+ builder.finish()
+ }
+
+ /// Used to shrink `derive(Debug)` code, for faster compilation and smaller binaries.
+ /// `debug_struct_fields_finish` is more general, but this is faster for 3 fields.
+ #[doc(hidden)]
+ #[unstable(feature = "fmt_helpers_for_derive", issue = "none")]
+ pub fn debug_struct_field3_finish<'b>(
+ &'b mut self,
+ name: &str,
+ name1: &str,
+ value1: &dyn Debug,
+ name2: &str,
+ value2: &dyn Debug,
+ name3: &str,
+ value3: &dyn Debug,
+ ) -> Result {
+ let mut builder = builders::debug_struct_new(self, name);
+ builder.field(name1, value1);
+ builder.field(name2, value2);
+ builder.field(name3, value3);
+ builder.finish()
+ }
+
+ /// Used to shrink `derive(Debug)` code, for faster compilation and smaller binaries.
+ /// `debug_struct_fields_finish` is more general, but this is faster for 4 fields.
+ #[doc(hidden)]
+ #[unstable(feature = "fmt_helpers_for_derive", issue = "none")]
+ pub fn debug_struct_field4_finish<'b>(
+ &'b mut self,
+ name: &str,
+ name1: &str,
+ value1: &dyn Debug,
+ name2: &str,
+ value2: &dyn Debug,
+ name3: &str,
+ value3: &dyn Debug,
+ name4: &str,
+ value4: &dyn Debug,
+ ) -> Result {
+ let mut builder = builders::debug_struct_new(self, name);
+ builder.field(name1, value1);
+ builder.field(name2, value2);
+ builder.field(name3, value3);
+ builder.field(name4, value4);
+ builder.finish()
+ }
+
+ /// Used to shrink `derive(Debug)` code, for faster compilation and smaller binaries.
+ /// `debug_struct_fields_finish` is more general, but this is faster for 5 fields.
+ #[doc(hidden)]
+ #[unstable(feature = "fmt_helpers_for_derive", issue = "none")]
+ pub fn debug_struct_field5_finish<'b>(
+ &'b mut self,
+ name: &str,
+ name1: &str,
+ value1: &dyn Debug,
+ name2: &str,
+ value2: &dyn Debug,
+ name3: &str,
+ value3: &dyn Debug,
+ name4: &str,
+ value4: &dyn Debug,
+ name5: &str,
+ value5: &dyn Debug,
+ ) -> Result {
+ let mut builder = builders::debug_struct_new(self, name);
+ builder.field(name1, value1);
+ builder.field(name2, value2);
+ builder.field(name3, value3);
+ builder.field(name4, value4);
+ builder.field(name5, value5);
+ builder.finish()
+ }
+
+ /// Used to shrink `derive(Debug)` code, for faster compilation and smaller binaries.
+ /// For the cases not covered by `debug_struct_field[12345]_finish`.
+ #[doc(hidden)]
+ #[unstable(feature = "fmt_helpers_for_derive", issue = "none")]
+ pub fn debug_struct_fields_finish<'b>(
+ &'b mut self,
+ name: &str,
+ names: &[&str],
+ values: &[&dyn Debug],
+ ) -> Result {
+ assert_eq!(names.len(), values.len());
+ let mut builder = builders::debug_struct_new(self, name);
+ for (name, value) in iter::zip(names, values) {
+ builder.field(name, value);
+ }
+ builder.finish()
+ }
+
/// Creates a `DebugTuple` builder designed to assist with creation of
/// `fmt::Debug` implementations for tuple structs.
///
@@ -1995,6 +2119,108 @@ impl<'a> Formatter<'a> {
builders::debug_tuple_new(self, name)
}
+ /// Used to shrink `derive(Debug)` code, for faster compilation and smaller binaries.
+ /// `debug_tuple_fields_finish` is more general, but this is faster for 1 field.
+ #[doc(hidden)]
+ #[unstable(feature = "fmt_helpers_for_derive", issue = "none")]
+ pub fn debug_tuple_field1_finish<'b>(&'b mut self, name: &str, value1: &dyn Debug) -> Result {
+ let mut builder = builders::debug_tuple_new(self, name);
+ builder.field(value1);
+ builder.finish()
+ }
+
+ /// Used to shrink `derive(Debug)` code, for faster compilation and smaller binaries.
+ /// `debug_tuple_fields_finish` is more general, but this is faster for 2 fields.
+ #[doc(hidden)]
+ #[unstable(feature = "fmt_helpers_for_derive", issue = "none")]
+ pub fn debug_tuple_field2_finish<'b>(
+ &'b mut self,
+ name: &str,
+ value1: &dyn Debug,
+ value2: &dyn Debug,
+ ) -> Result {
+ let mut builder = builders::debug_tuple_new(self, name);
+ builder.field(value1);
+ builder.field(value2);
+ builder.finish()
+ }
+
+ /// Used to shrink `derive(Debug)` code, for faster compilation and smaller binaries.
+ /// `debug_tuple_fields_finish` is more general, but this is faster for 3 fields.
+ #[doc(hidden)]
+ #[unstable(feature = "fmt_helpers_for_derive", issue = "none")]
+ pub fn debug_tuple_field3_finish<'b>(
+ &'b mut self,
+ name: &str,
+ value1: &dyn Debug,
+ value2: &dyn Debug,
+ value3: &dyn Debug,
+ ) -> Result {
+ let mut builder = builders::debug_tuple_new(self, name);
+ builder.field(value1);
+ builder.field(value2);
+ builder.field(value3);
+ builder.finish()
+ }
+
+ /// Used to shrink `derive(Debug)` code, for faster compilation and smaller binaries.
+ /// `debug_tuple_fields_finish` is more general, but this is faster for 4 fields.
+ #[doc(hidden)]
+ #[unstable(feature = "fmt_helpers_for_derive", issue = "none")]
+ pub fn debug_tuple_field4_finish<'b>(
+ &'b mut self,
+ name: &str,
+ value1: &dyn Debug,
+ value2: &dyn Debug,
+ value3: &dyn Debug,
+ value4: &dyn Debug,
+ ) -> Result {
+ let mut builder = builders::debug_tuple_new(self, name);
+ builder.field(value1);
+ builder.field(value2);
+ builder.field(value3);
+ builder.field(value4);
+ builder.finish()
+ }
+
+ /// Used to shrink `derive(Debug)` code, for faster compilation and smaller binaries.
+ /// `debug_tuple_fields_finish` is more general, but this is faster for 5 fields.
+ #[doc(hidden)]
+ #[unstable(feature = "fmt_helpers_for_derive", issue = "none")]
+ pub fn debug_tuple_field5_finish<'b>(
+ &'b mut self,
+ name: &str,
+ value1: &dyn Debug,
+ value2: &dyn Debug,
+ value3: &dyn Debug,
+ value4: &dyn Debug,
+ value5: &dyn Debug,
+ ) -> Result {
+ let mut builder = builders::debug_tuple_new(self, name);
+ builder.field(value1);
+ builder.field(value2);
+ builder.field(value3);
+ builder.field(value4);
+ builder.field(value5);
+ builder.finish()
+ }
+
+ /// Used to shrink `derive(Debug)` code, for faster compilation and smaller binaries.
+ /// For the cases not covered by `debug_tuple_field[12345]_finish`.
+ #[doc(hidden)]
+ #[unstable(feature = "fmt_helpers_for_derive", issue = "none")]
+ pub fn debug_tuple_fields_finish<'b>(
+ &'b mut self,
+ name: &str,
+ values: &[&dyn Debug],
+ ) -> Result {
+ let mut builder = builders::debug_tuple_new(self, name);
+ for value in values {
+ builder.field(value);
+ }
+ builder.finish()
+ }
+
/// Creates a `DebugList` builder designed to assist with creation of
/// `fmt::Debug` implementations for list-like structures.
///
diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs
index 53e48500e3b..60eb3a6da3a 100644
--- a/library/core/src/iter/adapters/chain.rs
+++ b/library/core/src/iter/adapters/chain.rs
@@ -37,33 +37,6 @@ impl<A, B> Chain<A, B> {
}
}
-/// Fuse the iterator if the expression is `None`.
-macro_rules! fuse {
- ($self:ident . $iter:ident . $($call:tt)+) => {
- match $self.$iter {
- Some(ref mut iter) => match iter.$($call)+ {
- None => {
- $self.$iter = None;
- None
- }
- item => item,
- },
- None => None,
- }
- };
-}
-
-/// Try an iterator method without fusing,
-/// like an inline `.as_mut().and_then(...)`
-macro_rules! maybe {
- ($self:ident . $iter:ident . $($call:tt)+) => {
- match $self.$iter {
- Some(ref mut iter) => iter.$($call)+,
- None => None,
- }
- };
-}
-
#[stable(feature = "rust1", since = "1.0.0")]
impl<A, B> Iterator for Chain<A, B>
where
@@ -74,10 +47,7 @@ where
#[inline]
fn next(&mut self) -> Option<A::Item> {
- match fuse!(self.a.next()) {
- None => maybe!(self.b.next()),
- item => item,
- }
+ and_then_or_clear(&mut self.a, Iterator::next).or_else(|| self.b.as_mut()?.next())
}
#[inline]
@@ -161,7 +131,7 @@ where
self.a = None;
}
- maybe!(self.b.nth(n))
+ self.b.as_mut()?.nth(n)
}
#[inline]
@@ -169,23 +139,15 @@ where
where
P: FnMut(&Self::Item) -> bool,
{
- match fuse!(self.a.find(&mut predicate)) {
- None => maybe!(self.b.find(predicate)),
- item => item,
- }
+ and_then_or_clear(&mut self.a, |a| a.find(&mut predicate))
+ .or_else(|| self.b.as_mut()?.find(predicate))
}
#[inline]
fn last(self) -> Option<A::Item> {
// Must exhaust a before b.
- let a_last = match self.a {
- Some(a) => a.last(),
- None => None,
- };
- let b_last = match self.b {
- Some(b) => b.last(),
- None => None,
- };
+ let a_last = self.a.and_then(Iterator::last);
+ let b_last = self.b.and_then(Iterator::last);
b_last.or(a_last)
}
@@ -220,10 +182,7 @@ where
{
#[inline]
fn next_back(&mut self) -> Option<A::Item> {
- match fuse!(self.b.next_back()) {
- None => maybe!(self.a.next_back()),
- item => item,
- }
+ and_then_or_clear(&mut self.b, |b| b.next_back()).or_else(|| self.a.as_mut()?.next_back())
}
#[inline]
@@ -263,7 +222,7 @@ where
self.b = None;
}
- maybe!(self.a.nth_back(n))
+ self.a.as_mut()?.nth_back(n)
}
#[inline]
@@ -271,10 +230,8 @@ where
where
P: FnMut(&Self::Item) -> bool,
{
- match fuse!(self.b.rfind(&mut predicate)) {
- None => maybe!(self.a.rfind(predicate)),
- item => item,
- }
+ and_then_or_clear(&mut self.b, |b| b.rfind(&mut predicate))
+ .or_else(|| self.a.as_mut()?.rfind(predicate))
}
fn try_rfold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
@@ -324,3 +281,12 @@ where
B: TrustedLen<Item = A::Item>,
{
}
+
+#[inline]
+fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
+ let x = f(opt.as_mut()?);
+ if x.is_none() {
+ *opt = None;
+ }
+ x
+}
diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs
index 351fd569d8a..15a120e35a2 100644
--- a/library/core/src/iter/adapters/flatten.rs
+++ b/library/core/src/iter/adapters/flatten.rs
@@ -290,20 +290,11 @@ where
#[inline]
fn next(&mut self) -> Option<U::Item> {
loop {
- if let Some(ref mut inner) = self.frontiter {
- match inner.next() {
- None => self.frontiter = None,
- elt @ Some(_) => return elt,
- }
+ if let elt @ Some(_) = and_then_or_clear(&mut self.frontiter, Iterator::next) {
+ return elt;
}
match self.iter.next() {
- None => match self.backiter.as_mut()?.next() {
- None => {
- self.backiter = None;
- return None;
- }
- elt @ Some(_) => return elt,
- },
+ None => return and_then_or_clear(&mut self.backiter, Iterator::next),
Some(inner) => self.frontiter = Some(inner.into_iter()),
}
}
@@ -436,21 +427,12 @@ where
#[inline]
fn next_back(&mut self) -> Option<U::Item> {
loop {
- if let Some(ref mut inner) = self.backiter {
- match inner.next_back() {
- None => self.backiter = None,
- elt @ Some(_) => return elt,
- }
+ if let elt @ Some(_) = and_then_or_clear(&mut self.backiter, |b| b.next_back()) {
+ return elt;
}
match self.iter.next_back() {
- None => match self.frontiter.as_mut()?.next_back() {
- None => {
- self.frontiter = None;
- return None;
- }
- elt @ Some(_) => return elt,
- },
- next => self.backiter = next.map(IntoIterator::into_iter),
+ None => return and_then_or_clear(&mut self.frontiter, |f| f.next_back()),
+ Some(inner) => self.backiter = Some(inner.into_iter()),
}
}
}
@@ -606,3 +588,12 @@ unsafe impl<T, const N: usize> TrustedConstSize for [T; N] {}
unsafe impl<T, const N: usize> TrustedConstSize for &'_ [T; N] {}
#[unstable(feature = "std_internals", issue = "none")]
unsafe impl<T, const N: usize> TrustedConstSize for &'_ mut [T; N] {}
+
+#[inline]
+fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
+ let x = f(opt.as_mut()?);
+ if x.is_none() {
+ *opt = None;
+ }
+ x
+}
diff --git a/library/core/src/iter/adapters/fuse.rs b/library/core/src/iter/adapters/fuse.rs
index 8adb53c6714..c9314454203 100644
--- a/library/core/src/iter/adapters/fuse.rs
+++ b/library/core/src/iter/adapters/fuse.rs
@@ -29,33 +29,6 @@ impl<I> Fuse<I> {
#[stable(feature = "fused", since = "1.26.0")]
impl<I> FusedIterator for Fuse<I> where I: Iterator {}
-/// Fuse the iterator if the expression is `None`.
-macro_rules! fuse {
- ($self:ident . iter . $($call:tt)+) => {
- match $self.iter {
- Some(ref mut iter) => match iter.$($call)+ {
- None => {
- $self.iter = None;
- None
- }
- item => item,
- },
- None => None,
- }
- };
-}
-
-/// Specialized macro that doesn't check if the expression is `None`.
-/// (We trust that a `FusedIterator` will fuse itself.)
-macro_rules! spec {
- ($self:ident . iter . $($call:tt)+) => {
- match $self.iter {
- Some(ref mut iter) => iter.$($call)+,
- None => None,
- }
- };
-}
-
// Any specialized implementation here is made internal
// to avoid exposing default fns outside this trait.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -281,12 +254,12 @@ where
#[inline]
default fn next(&mut self) -> Option<<I as Iterator>::Item> {
- fuse!(self.iter.next())
+ and_then_or_clear(&mut self.iter, Iterator::next)
}
#[inline]
default fn nth(&mut self, n: usize) -> Option<I::Item> {
- fuse!(self.iter.nth(n))
+ and_then_or_clear(&mut self.iter, |iter| iter.nth(n))
}
#[inline]
@@ -308,7 +281,7 @@ where
where
P: FnMut(&Self::Item) -> bool,
{
- fuse!(self.iter.find(predicate))
+ and_then_or_clear(&mut self.iter, |iter| iter.find(predicate))
}
#[inline]
@@ -316,7 +289,7 @@ where
where
I: DoubleEndedIterator,
{
- fuse!(self.iter.next_back())
+ and_then_or_clear(&mut self.iter, |iter| iter.next_back())
}
#[inline]
@@ -324,7 +297,7 @@ where
where
I: DoubleEndedIterator,
{
- fuse!(self.iter.nth_back(n))
+ and_then_or_clear(&mut self.iter, |iter| iter.nth_back(n))
}
#[inline]
@@ -348,7 +321,7 @@ where
P: FnMut(&Self::Item) -> bool,
I: DoubleEndedIterator,
{
- fuse!(self.iter.rfind(predicate))
+ and_then_or_clear(&mut self.iter, |iter| iter.rfind(predicate))
}
}
@@ -361,12 +334,12 @@ where
{
#[inline]
fn next(&mut self) -> Option<<I as Iterator>::Item> {
- spec!(self.iter.next())
+ self.iter.as_mut()?.next()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<I::Item> {
- spec!(self.iter.nth(n))
+ self.iter.as_mut()?.nth(n)
}
#[inline]
@@ -387,7 +360,7 @@ where
where
P: FnMut(&Self::Item) -> bool,
{
- spec!(self.iter.find(predicate))
+ self.iter.as_mut()?.find(predicate)
}
#[inline]
@@ -395,7 +368,7 @@ where
where
I: DoubleEndedIterator,
{
- spec!(self.iter.next_back())
+ self.iter.as_mut()?.next_back()
}
#[inline]
@@ -403,7 +376,7 @@ where
where
I: DoubleEndedIterator,
{
- spec!(self.iter.nth_back(n))
+ self.iter.as_mut()?.nth_back(n)
}
#[inline]
@@ -426,6 +399,15 @@ where
P: FnMut(&Self::Item) -> bool,
I: DoubleEndedIterator,
{
- spec!(self.iter.rfind(predicate))
+ self.iter.as_mut()?.rfind(predicate)
+ }
+}
+
+#[inline]
+fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
+ let x = f(opt.as_mut()?);
+ if x.is_none() {
+ *opt = None;
}
+ x
}
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 70969edd6ea..92d03b724b4 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -213,7 +213,7 @@ macro_rules! nonzero_leading_trailing_zeros {
without modifying the original"]
#[inline]
pub const fn leading_zeros(self) -> u32 {
- // SAFETY: since `self` can not be zero it is safe to call ctlz_nonzero
+ // SAFETY: since `self` cannot be zero, it is safe to call `ctlz_nonzero`.
unsafe { intrinsics::ctlz_nonzero(self.0 as $Uint) as u32 }
}
@@ -237,7 +237,7 @@ macro_rules! nonzero_leading_trailing_zeros {
without modifying the original"]
#[inline]
pub const fn trailing_zeros(self) -> u32 {
- // SAFETY: since `self` can not be zero it is safe to call cttz_nonzero
+ // SAFETY: since `self` cannot be zero, it is safe to call `cttz_nonzero`.
unsafe { intrinsics::cttz_nonzero(self.0 as $Uint) as u32 }
}
@@ -316,7 +316,6 @@ macro_rules! nonzero_unsigned_operations {
/// # Examples
///
/// ```
- /// #![feature(nonzero_ops)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
/// # fn main() { test().unwrap(); }
@@ -331,7 +330,8 @@ macro_rules! nonzero_unsigned_operations {
/// # Some(())
/// # }
/// ```
- #[unstable(feature = "nonzero_ops", issue = "84186")]
+ #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+ #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -351,7 +351,6 @@ macro_rules! nonzero_unsigned_operations {
/// # Examples
///
/// ```
- /// #![feature(nonzero_ops)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
/// # fn main() { test().unwrap(); }
@@ -366,7 +365,8 @@ macro_rules! nonzero_unsigned_operations {
/// # Some(())
/// # }
/// ```
- #[unstable(feature = "nonzero_ops", issue = "84186")]
+ #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+ #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -415,7 +415,6 @@ macro_rules! nonzero_unsigned_operations {
/// # Examples
///
/// ```
- /// #![feature(nonzero_ops)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
/// # fn main() { test().unwrap(); }
@@ -432,7 +431,8 @@ macro_rules! nonzero_unsigned_operations {
/// # Some(())
/// # }
/// ```
- #[unstable(feature = "nonzero_ops", issue = "84186")]
+ #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+ #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -521,7 +521,6 @@ macro_rules! nonzero_signed_operations {
/// # Example
///
/// ```
- /// #![feature(nonzero_ops)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
/// # fn main() { test().unwrap(); }
@@ -534,7 +533,8 @@ macro_rules! nonzero_signed_operations {
/// # Some(())
/// # }
/// ```
- #[unstable(feature = "nonzero_ops", issue = "84186")]
+ #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+ #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -551,7 +551,6 @@ macro_rules! nonzero_signed_operations {
/// # Example
///
/// ```
- /// #![feature(nonzero_ops)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
/// # fn main() { test().unwrap(); }
@@ -566,7 +565,8 @@ macro_rules! nonzero_signed_operations {
/// # Some(())
/// # }
/// ```
- #[unstable(feature = "nonzero_ops", issue = "84186")]
+ #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+ #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -586,7 +586,6 @@ macro_rules! nonzero_signed_operations {
/// # Example
///
/// ```
- /// #![feature(nonzero_ops)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
/// # fn main() { test().unwrap(); }
@@ -602,7 +601,8 @@ macro_rules! nonzero_signed_operations {
/// # Some(())
/// # }
/// ```
- #[unstable(feature = "nonzero_ops", issue = "84186")]
+ #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+ #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -621,7 +621,6 @@ macro_rules! nonzero_signed_operations {
/// # Example
///
/// ```
- /// #![feature(nonzero_ops)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
/// # fn main() { test().unwrap(); }
@@ -642,7 +641,8 @@ macro_rules! nonzero_signed_operations {
/// # Some(())
/// # }
/// ```
- #[unstable(feature = "nonzero_ops", issue = "84186")]
+ #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+ #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -657,7 +657,6 @@ macro_rules! nonzero_signed_operations {
/// # Example
///
/// ```
- /// #![feature(nonzero_ops)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
/// # fn main() { test().unwrap(); }
@@ -677,7 +676,8 @@ macro_rules! nonzero_signed_operations {
/// # Some(())
/// # }
/// ```
- #[unstable(feature = "nonzero_ops", issue = "84186")]
+ #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+ #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -692,7 +692,6 @@ macro_rules! nonzero_signed_operations {
/// # Example
///
/// ```
- /// #![feature(nonzero_ops)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
#[doc = concat!("# use std::num::", stringify!($Uty), ";")]
///
@@ -712,7 +711,8 @@ macro_rules! nonzero_signed_operations {
/// # Some(())
/// # }
/// ```
- #[unstable(feature = "nonzero_ops", issue = "84186")]
+ #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+ #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -746,7 +746,6 @@ macro_rules! nonzero_unsigned_signed_operations {
/// # Examples
///
/// ```
- /// #![feature(nonzero_ops)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
/// # fn main() { test().unwrap(); }
@@ -761,7 +760,8 @@ macro_rules! nonzero_unsigned_signed_operations {
/// # Some(())
/// # }
/// ```
- #[unstable(feature = "nonzero_ops", issue = "84186")]
+ #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+ #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -782,7 +782,6 @@ macro_rules! nonzero_unsigned_signed_operations {
/// # Examples
///
/// ```
- /// #![feature(nonzero_ops)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
/// # fn main() { test().unwrap(); }
@@ -797,7 +796,8 @@ macro_rules! nonzero_unsigned_signed_operations {
/// # Some(())
/// # }
/// ```
- #[unstable(feature = "nonzero_ops", issue = "84186")]
+ #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+ #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -855,7 +855,6 @@ macro_rules! nonzero_unsigned_signed_operations {
/// # Examples
///
/// ```
- /// #![feature(nonzero_ops)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
/// # fn main() { test().unwrap(); }
@@ -870,7 +869,8 @@ macro_rules! nonzero_unsigned_signed_operations {
/// # Some(())
/// # }
/// ```
- #[unstable(feature = "nonzero_ops", issue = "84186")]
+ #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+ #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
@@ -899,7 +899,6 @@ macro_rules! nonzero_unsigned_signed_operations {
/// # Examples
///
/// ```
- /// #![feature(nonzero_ops)]
#[doc = concat!("# use std::num::", stringify!($Ty), ";")]
///
/// # fn main() { test().unwrap(); }
@@ -914,7 +913,8 @@ macro_rules! nonzero_unsigned_signed_operations {
/// # Some(())
/// # }
/// ```
- #[unstable(feature = "nonzero_ops", issue = "84186")]
+ #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+ #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
diff --git a/library/core/tests/alloc.rs b/library/core/tests/alloc.rs
index 6762c0319e5..8a5a06b3440 100644
--- a/library/core/tests/alloc.rs
+++ b/library/core/tests/alloc.rs
@@ -1,5 +1,5 @@
use core::alloc::Layout;
-use core::ptr::NonNull;
+use core::ptr::{self, NonNull};
#[test]
fn const_unchecked_layout() {
@@ -9,7 +9,7 @@ fn const_unchecked_layout() {
const DANGLING: NonNull<u8> = LAYOUT.dangling();
assert_eq!(LAYOUT.size(), SIZE);
assert_eq!(LAYOUT.align(), ALIGN);
- assert_eq!(Some(DANGLING), NonNull::new(ALIGN as *mut u8));
+ assert_eq!(Some(DANGLING), NonNull::new(ptr::invalid_mut(ALIGN)));
}
#[test]
diff --git a/library/core/tests/hash/mod.rs b/library/core/tests/hash/mod.rs
index 5bc6aac1778..f7934d062a3 100644
--- a/library/core/tests/hash/mod.rs
+++ b/library/core/tests/hash/mod.rs
@@ -2,6 +2,7 @@ mod sip;
use std::default::Default;
use std::hash::{BuildHasher, Hash, Hasher};
+use std::ptr;
use std::rc::Rc;
struct MyHasher {
@@ -69,10 +70,10 @@ fn test_writer_hasher() {
let cs: Rc<[u8]> = Rc::new([1, 2, 3]);
assert_eq!(hash(&cs), 9);
- let ptr = 5_usize as *const i32;
+ let ptr = ptr::invalid::<i32>(5_usize);
assert_eq!(hash(&ptr), 5);
- let ptr = 5_usize as *mut i32;
+ let ptr = ptr::invalid_mut::<i32>(5_usize);
assert_eq!(hash(&ptr), 5);
if cfg!(miri) {
diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs
index 3e2956eac87..187a7db7fcb 100644
--- a/library/core/tests/ptr.rs
+++ b/library/core/tests/ptr.rs
@@ -353,9 +353,9 @@ fn align_offset_zst() {
// all, because no amount of elements will align the pointer.
let mut p = 1;
while p < 1024 {
- assert_eq!((p as *const ()).align_offset(p), 0);
+ assert_eq!(ptr::invalid::<()>(p).align_offset(p), 0);
if p != 1 {
- assert_eq!(((p + 1) as *const ()).align_offset(p), !0);
+ assert_eq!(ptr::invalid::<()>(p + 1).align_offset(p), !0);
}
p = (p + 1).next_power_of_two();
}
@@ -371,7 +371,7 @@ fn align_offset_stride1() {
let expected = ptr % align;
let offset = if expected == 0 { 0 } else { align - expected };
assert_eq!(
- (ptr as *const u8).align_offset(align),
+ ptr::invalid::<u8>(ptr).align_offset(align),
offset,
"ptr = {}, align = {}, size = 1",
ptr,
@@ -434,14 +434,14 @@ fn align_offset_weird_strides() {
while align < limit {
for ptr in 1usize..4 * align {
unsafe {
- x |= test_weird_stride::<A3>(ptr as *const A3, align);
- x |= test_weird_stride::<A4>(ptr as *const A4, align);
- x |= test_weird_stride::<A5>(ptr as *const A5, align);
- x |= test_weird_stride::<A6>(ptr as *const A6, align);
- x |= test_weird_stride::<A7>(ptr as *const A7, align);
- x |= test_weird_stride::<A8>(ptr as *const A8, align);
- x |= test_weird_stride::<A9>(ptr as *const A9, align);
- x |= test_weird_stride::<A10>(ptr as *const A10, align);
+ x |= test_weird_stride::<A3>(ptr::invalid::<A3>(ptr), align);
+ x |= test_weird_stride::<A4>(ptr::invalid::<A4>(ptr), align);
+ x |= test_weird_stride::<A5>(ptr::invalid::<A5>(ptr), align);
+ x |= test_weird_stride::<A6>(ptr::invalid::<A6>(ptr), align);
+ x |= test_weird_stride::<A7>(ptr::invalid::<A7>(ptr), align);
+ x |= test_weird_stride::<A8>(ptr::invalid::<A8>(ptr), align);
+ x |= test_weird_stride::<A9>(ptr::invalid::<A9>(ptr), align);
+ x |= test_weird_stride::<A10>(ptr::invalid::<A10>(ptr), align);
}
}
align = (align + 1).next_power_of_two();
@@ -479,8 +479,8 @@ fn ptr_metadata() {
let () = metadata(&[4, 7]);
let () = metadata(&(4, String::new()));
let () = metadata(&Pair(4, String::new()));
- let () = metadata(0 as *const Extern);
- let () = metadata(0 as *const <&u32 as std::ops::Deref>::Target);
+ let () = metadata(ptr::null::<()>() as *const Extern);
+ let () = metadata(ptr::null::<()>() as *const <&u32 as std::ops::Deref>::Target);
assert_eq!(metadata("foo"), 3_usize);
assert_eq!(metadata(&[4, 7][..]), 2_usize);
diff --git a/library/core/tests/waker.rs b/library/core/tests/waker.rs
index 6602ab36ba7..38a3a0adad9 100644
--- a/library/core/tests/waker.rs
+++ b/library/core/tests/waker.rs
@@ -3,7 +3,7 @@ use std::task::{RawWaker, RawWakerVTable, Waker};
#[test]
fn test_waker_getters() {
- let raw_waker = RawWaker::new(42usize as *mut (), &WAKER_VTABLE);
+ let raw_waker = RawWaker::new(ptr::invalid_mut(42usize), &WAKER_VTABLE);
assert_eq!(raw_waker.data() as usize, 42);
assert!(ptr::eq(raw_waker.vtable(), &WAKER_VTABLE));
@@ -15,7 +15,7 @@ fn test_waker_getters() {
}
static WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(
- |data| RawWaker::new((data as usize + 1) as *mut (), &WAKER_VTABLE),
+ |data| RawWaker::new(ptr::invalid_mut(data as usize + 1), &WAKER_VTABLE),
|_| {},
|_| {},
|_| {},
diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs
index d7cc700495b..74b4a91662b 100644
--- a/library/proc_macro/src/bridge/client.rs
+++ b/library/proc_macro/src/bridge/client.rs
@@ -230,6 +230,20 @@ impl Clone for SourceFile {
}
}
+impl Span {
+ pub(crate) fn def_site() -> Span {
+ Bridge::with(|bridge| bridge.globals.def_site)
+ }
+
+ pub(crate) fn call_site() -> Span {
+ Bridge::with(|bridge| bridge.globals.call_site)
+ }
+
+ pub(crate) fn mixed_site() -> Span {
+ Bridge::with(|bridge| bridge.globals.mixed_site)
+ }
+}
+
impl fmt::Debug for Span {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.debug())
@@ -263,6 +277,21 @@ macro_rules! define_client_side {
}
with_api!(self, self, define_client_side);
+struct Bridge<'a> {
+ /// Reusable buffer (only `clear`-ed, never shrunk), primarily
+ /// used for making requests.
+ cached_buffer: Buffer,
+
+ /// Server-side function that the client uses to make requests.
+ dispatch: closure::Closure<'a, Buffer, Buffer>,
+
+ /// Provided globals for this macro expansion.
+ globals: ExpnGlobals<Span>,
+}
+
+impl<'a> !Send for Bridge<'a> {}
+impl<'a> !Sync for Bridge<'a> {}
+
enum BridgeState<'a> {
/// No server is currently connected to this client.
NotConnected,
@@ -305,34 +334,6 @@ impl BridgeState<'_> {
}
impl Bridge<'_> {
- pub(crate) fn is_available() -> bool {
- BridgeState::with(|state| match state {
- BridgeState::Connected(_) | BridgeState::InUse => true,
- BridgeState::NotConnected => false,
- })
- }
-
- fn enter<R>(self, f: impl FnOnce() -> R) -> R {
- let force_show_panics = self.force_show_panics;
- // Hide the default panic output within `proc_macro` expansions.
- // NB. the server can't do this because it may use a different libstd.
- static HIDE_PANICS_DURING_EXPANSION: Once = Once::new();
- HIDE_PANICS_DURING_EXPANSION.call_once(|| {
- let prev = panic::take_hook();
- panic::set_hook(Box::new(move |info| {
- let show = BridgeState::with(|state| match state {
- BridgeState::NotConnected => true,
- BridgeState::Connected(_) | BridgeState::InUse => force_show_panics,
- });
- if show {
- prev(info)
- }
- }));
- });
-
- BRIDGE_STATE.with(|state| state.set(BridgeState::Connected(self), f))
- }
-
fn with<R>(f: impl FnOnce(&mut Bridge<'_>) -> R) -> R {
BridgeState::with(|state| match state {
BridgeState::NotConnected => {
@@ -346,6 +347,13 @@ impl Bridge<'_> {
}
}
+pub(crate) fn is_available() -> bool {
+ BridgeState::with(|state| match state {
+ BridgeState::Connected(_) | BridgeState::InUse => true,
+ BridgeState::NotConnected => false,
+ })
+}
+
/// A client-side RPC entry-point, which may be using a different `proc_macro`
/// from the one used by the server, but can be invoked compatibly.
///
@@ -363,7 +371,7 @@ pub struct Client<I, O> {
// a wrapper `fn` pointer, once `const fn` can reference `static`s.
pub(super) get_handle_counters: extern "C" fn() -> &'static HandleCounters,
- pub(super) run: extern "C" fn(Bridge<'_>) -> Buffer,
+ pub(super) run: extern "C" fn(BridgeConfig<'_>) -> Buffer,
pub(super) _marker: PhantomData<fn(I) -> O>,
}
@@ -375,40 +383,62 @@ impl<I, O> Clone for Client<I, O> {
}
}
+fn maybe_install_panic_hook(force_show_panics: bool) {
+ // Hide the default panic output within `proc_macro` expansions.
+ // NB. the server can't do this because it may use a different libstd.
+ static HIDE_PANICS_DURING_EXPANSION: Once = Once::new();
+ HIDE_PANICS_DURING_EXPANSION.call_once(|| {
+ let prev = panic::take_hook();
+ panic::set_hook(Box::new(move |info| {
+ let show = BridgeState::with(|state| match state {
+ BridgeState::NotConnected => true,
+ BridgeState::Connected(_) | BridgeState::InUse => force_show_panics,
+ });
+ if show {
+ prev(info)
+ }
+ }));
+ });
+}
+
/// Client-side helper for handling client panics, entering the bridge,
/// deserializing input and serializing output.
// FIXME(eddyb) maybe replace `Bridge::enter` with this?
fn run_client<A: for<'a, 's> DecodeMut<'a, 's, ()>, R: Encode<()>>(
- mut bridge: Bridge<'_>,
+ config: BridgeConfig<'_>,
f: impl FnOnce(A) -> R,
) -> Buffer {
- // The initial `cached_buffer` contains the input.
- let mut buf = bridge.cached_buffer.take();
+ let BridgeConfig { input: mut buf, dispatch, force_show_panics, .. } = config;
panic::catch_unwind(panic::AssertUnwindSafe(|| {
- bridge.enter(|| {
- let reader = &mut &buf[..];
- let input = A::decode(reader, &mut ());
-
- // Put the `cached_buffer` back in the `Bridge`, for requests.
- Bridge::with(|bridge| bridge.cached_buffer = buf.take());
-
- let output = f(input);
-
- // Take the `cached_buffer` back out, for the output value.
- buf = Bridge::with(|bridge| bridge.cached_buffer.take());
-
- // HACK(eddyb) Separate encoding a success value (`Ok(output)`)
- // from encoding a panic (`Err(e: PanicMessage)`) to avoid
- // having handles outside the `bridge.enter(|| ...)` scope, and
- // to catch panics that could happen while encoding the success.
- //
- // Note that panics should be impossible beyond this point, but
- // this is defensively trying to avoid any accidental panicking
- // reaching the `extern "C"` (which should `abort` but might not
- // at the moment, so this is also potentially preventing UB).
- buf.clear();
- Ok::<_, ()>(output).encode(&mut buf, &mut ());
+ maybe_install_panic_hook(force_show_panics);
+
+ let reader = &mut &buf[..];
+ let (globals, input) = <(ExpnGlobals<Span>, A)>::decode(reader, &mut ());
+
+ // Put the buffer we used for input back in the `Bridge` for requests.
+ let new_state =
+ BridgeState::Connected(Bridge { cached_buffer: buf.take(), dispatch, globals });
+
+ BRIDGE_STATE.with(|state| {
+ state.set(new_state, || {
+ let output = f(input);
+
+ // Take the `cached_buffer` back out, for the output value.
+ buf = Bridge::with(|bridge| bridge.cached_buffer.take());
+
+ // HACK(eddyb) Separate encoding a success value (`Ok(output)`)
+ // from encoding a panic (`Err(e: PanicMessage)`) to avoid
+ // having handles outside the `bridge.enter(|| ...)` scope, and
+ // to catch panics that could happen while encoding the success.
+ //
+ // Note that panics should be impossible beyond this point, but
+ // this is defensively trying to avoid any accidental panicking
+ // reaching the `extern "C"` (which should `abort` but might not
+ // at the moment, so this is also potentially preventing UB).
+ buf.clear();
+ Ok::<_, ()>(output).encode(&mut buf, &mut ());
+ })
})
}))
.map_err(PanicMessage::from)
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index 4e931569ef6..3bdc9007cd2 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -151,9 +151,6 @@ macro_rules! with_api {
},
Span {
fn debug($self: $S::Span) -> String;
- fn def_site() -> $S::Span;
- fn call_site() -> $S::Span;
- fn mixed_site() -> $S::Span;
fn source_file($self: $S::Span) -> $S::SourceFile;
fn parent($self: $S::Span) -> Option<$S::Span>;
fn source($self: $S::Span) -> $S::Span;
@@ -213,16 +210,15 @@ use buffer::Buffer;
pub use rpc::PanicMessage;
use rpc::{Decode, DecodeMut, Encode, Reader, Writer};
-/// An active connection between a server and a client.
-/// The server creates the bridge (`Bridge::run_server` in `server.rs`),
-/// then passes it to the client through the function pointer in the `run`
-/// field of `client::Client`. The client holds its copy of the `Bridge`
+/// Configuration for establishing an active connection between a server and a
+/// client. The server creates the bridge config (`run_server` in `server.rs`),
+/// then passes it to the client through the function pointer in the `run` field
+/// of `client::Client`. The client constructs a local `Bridge` from the config
/// in TLS during its execution (`Bridge::{enter, with}` in `client.rs`).
#[repr(C)]
-pub struct Bridge<'a> {
- /// Reusable buffer (only `clear`-ed, never shrunk), primarily
- /// used for making requests, but also for passing input to client.
- cached_buffer: Buffer,
+pub struct BridgeConfig<'a> {
+ /// Buffer used to pass initial input to the client.
+ input: Buffer,
/// Server-side function that the client uses to make requests.
dispatch: closure::Closure<'a, Buffer, Buffer>,
@@ -379,6 +375,25 @@ rpc_encode_decode!(
);
macro_rules! mark_compound {
+ (struct $name:ident <$($T:ident),+> { $($field:ident),* $(,)? }) => {
+ impl<$($T: Mark),+> Mark for $name <$($T),+> {
+ type Unmarked = $name <$($T::Unmarked),+>;
+ fn mark(unmarked: Self::Unmarked) -> Self {
+ $name {
+ $($field: Mark::mark(unmarked.$field)),*
+ }
+ }
+ }
+
+ impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
+ type Unmarked = $name <$($T::Unmarked),+>;
+ fn unmark(self) -> Self::Unmarked {
+ $name {
+ $($field: Unmark::unmark(self.$field)),*
+ }
+ }
+ }
+ };
(enum $name:ident <$($T:ident),+> { $($variant:ident $(($field:ident))?),* $(,)? }) => {
impl<$($T: Mark),+> Mark for $name <$($T),+> {
type Unmarked = $name <$($T::Unmarked),+>;
@@ -449,3 +464,16 @@ compound_traits!(
Literal(tt),
}
);
+
+/// Globals provided alongside the initial inputs for a macro expansion.
+/// Provides values such as spans which are used frequently to avoid RPC.
+#[derive(Clone)]
+pub struct ExpnGlobals<S> {
+ pub def_site: S,
+ pub call_site: S,
+ pub mixed_site: S,
+}
+
+compound_traits!(
+ struct ExpnGlobals<Sp> { def_site, call_site, mixed_site }
+);
diff --git a/library/proc_macro/src/bridge/selfless_reify.rs b/library/proc_macro/src/bridge/selfless_reify.rs
index 4ee4bb87c2b..907ad256e4b 100644
--- a/library/proc_macro/src/bridge/selfless_reify.rs
+++ b/library/proc_macro/src/bridge/selfless_reify.rs
@@ -75,9 +75,10 @@ macro_rules! define_reify_functions {
define_reify_functions! {
fn _reify_to_extern_c_fn_unary<A, R> for extern "C" fn(arg: A) -> R;
- // HACK(eddyb) this abstraction is used with `for<'a> fn(Bridge<'a>) -> T`
- // but that doesn't work with just `reify_to_extern_c_fn_unary` because of
- // the `fn` pointer type being "higher-ranked" (i.e. the `for<'a>` binder).
- // FIXME(eddyb) try to remove the lifetime from `Bridge`, that'd help.
- fn reify_to_extern_c_fn_hrt_bridge<R> for extern "C" fn(bridge: super::Bridge<'_>) -> R;
+ // HACK(eddyb) this abstraction is used with `for<'a> fn(BridgeConfig<'a>)
+ // -> T` but that doesn't work with just `reify_to_extern_c_fn_unary`
+ // because of the `fn` pointer type being "higher-ranked" (i.e. the
+ // `for<'a>` binder).
+ // FIXME(eddyb) try to remove the lifetime from `BridgeConfig`, that'd help.
+ fn reify_to_extern_c_fn_hrt_bridge<R> for extern "C" fn(bridge: super::BridgeConfig<'_>) -> R;
}
diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs
index 3672299f18f..1b7657eab70 100644
--- a/library/proc_macro/src/bridge/server.rs
+++ b/library/proc_macro/src/bridge/server.rs
@@ -38,14 +38,21 @@ macro_rules! declare_server_traits {
$(associated_fn!(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?);)*
})*
- pub trait Server: Types $(+ $name)* {}
- impl<S: Types $(+ $name)*> Server for S {}
+ pub trait Server: Types $(+ $name)* {
+ fn globals(&mut self) -> ExpnGlobals<Self::Span>;
+ }
}
}
with_api!(Self, self_, declare_server_traits);
pub(super) struct MarkedTypes<S: Types>(S);
+impl<S: Server> Server for MarkedTypes<S> {
+ fn globals(&mut self) -> ExpnGlobals<Self::Span> {
+ <_>::mark(Server::globals(&mut self.0))
+ }
+}
+
macro_rules! define_mark_types_impls {
($($name:ident {
$(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
@@ -120,7 +127,7 @@ pub trait ExecutionStrategy {
&self,
dispatcher: &mut impl DispatcherTrait,
input: Buffer,
- run_client: extern "C" fn(Bridge<'_>) -> Buffer,
+ run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
force_show_panics: bool,
) -> Buffer;
}
@@ -132,13 +139,13 @@ impl ExecutionStrategy for SameThread {
&self,
dispatcher: &mut impl DispatcherTrait,
input: Buffer,
- run_client: extern "C" fn(Bridge<'_>) -> Buffer,
+ run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
force_show_panics: bool,
) -> Buffer {
let mut dispatch = |buf| dispatcher.dispatch(buf);
- run_client(Bridge {
- cached_buffer: input,
+ run_client(BridgeConfig {
+ input,
dispatch: (&mut dispatch).into(),
force_show_panics,
_marker: marker::PhantomData,
@@ -156,7 +163,7 @@ impl ExecutionStrategy for CrossThread1 {
&self,
dispatcher: &mut impl DispatcherTrait,
input: Buffer,
- run_client: extern "C" fn(Bridge<'_>) -> Buffer,
+ run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
force_show_panics: bool,
) -> Buffer {
use std::sync::mpsc::channel;
@@ -170,8 +177,8 @@ impl ExecutionStrategy for CrossThread1 {
res_rx.recv().unwrap()
};
- run_client(Bridge {
- cached_buffer: input,
+ run_client(BridgeConfig {
+ input,
dispatch: (&mut dispatch).into(),
force_show_panics,
_marker: marker::PhantomData,
@@ -193,7 +200,7 @@ impl ExecutionStrategy for CrossThread2 {
&self,
dispatcher: &mut impl DispatcherTrait,
input: Buffer,
- run_client: extern "C" fn(Bridge<'_>) -> Buffer,
+ run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
force_show_panics: bool,
) -> Buffer {
use std::sync::{Arc, Mutex};
@@ -219,8 +226,8 @@ impl ExecutionStrategy for CrossThread2 {
}
};
- let r = run_client(Bridge {
- cached_buffer: input,
+ let r = run_client(BridgeConfig {
+ input,
dispatch: (&mut dispatch).into(),
force_show_panics,
_marker: marker::PhantomData,
@@ -258,14 +265,16 @@ fn run_server<
handle_counters: &'static client::HandleCounters,
server: S,
input: I,
- run_client: extern "C" fn(Bridge<'_>) -> Buffer,
+ run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
force_show_panics: bool,
) -> Result<O, PanicMessage> {
let mut dispatcher =
Dispatcher { handle_store: HandleStore::new(handle_counters), server: MarkedTypes(server) };
+ let globals = dispatcher.server.globals();
+
let mut buf = Buffer::new();
- input.encode(&mut buf, &mut dispatcher.handle_store);
+ (globals, input).encode(&mut buf, &mut dispatcher.handle_store);
buf = strategy.run_bridge_and_client(&mut dispatcher, buf, run_client, force_show_panics);
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 5e1289ec79d..771ee50e138 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -60,7 +60,7 @@ use std::{error, fmt, iter};
/// inside of a procedural macro, false if invoked from any other binary.
#[stable(feature = "proc_macro_is_available", since = "1.57.0")]
pub fn is_available() -> bool {
- bridge::Bridge::is_available()
+ bridge::client::is_available()
}
/// The main type provided by this crate, representing an abstract stream of
diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs
index d554ec59035..a05e0db3af7 100644
--- a/library/std/src/alloc.rs
+++ b/library/std/src/alloc.rs
@@ -102,7 +102,7 @@ pub use alloc_crate::alloc::*;
/// if !ret.is_null() {
/// ALLOCATED.fetch_add(layout.size(), SeqCst);
/// }
-/// return ret
+/// ret
/// }
///
/// unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs
index 0ce6ae00ee2..f3fbfc44789 100644
--- a/library/std/src/io/cursor.rs
+++ b/library/std/src/io/cursor.rs
@@ -396,38 +396,99 @@ fn slice_write_vectored(
Ok(nwritten)
}
-// Resizing write implementation
-fn vec_write<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
-where
- A: Allocator,
-{
+/// Reserves the required space, and pads the vec with 0s if necessary.
+fn reserve_and_pad<A: Allocator>(
+ pos_mut: &mut u64,
+ vec: &mut Vec<u8, A>,
+ buf_len: usize,
+) -> io::Result<usize> {
let pos: usize = (*pos_mut).try_into().map_err(|_| {
io::const_io_error!(
ErrorKind::InvalidInput,
"cursor position exceeds maximum possible vector length",
)
})?;
- // Make sure the internal buffer is as least as big as where we
- // currently are
- let len = vec.len();
- if len < pos {
- // use `resize` so that the zero filling is as efficient as possible
- vec.resize(pos, 0);
- }
- // Figure out what bytes will be used to overwrite what's currently
- // there (left), and what will be appended on the end (right)
- {
- let space = vec.len() - pos;
- let (left, right) = buf.split_at(cmp::min(space, buf.len()));
- vec[pos..pos + left.len()].copy_from_slice(left);
- vec.extend_from_slice(right);
+
+ // For safety reasons, we don't want these numbers to overflow
+ // otherwise our allocation won't be enough
+ let desired_cap = pos.saturating_add(buf_len);
+ if desired_cap > vec.capacity() {
+ // We want our vec's total capacity
+ // to have room for (pos+buf_len) bytes. Reserve allocates
+ // based on additional elements from the length, so we need to
+ // reserve the difference
+ vec.reserve(desired_cap - vec.len());
+ }
+ // Pad if pos is above the current len.
+ if pos > vec.len() {
+ let diff = pos - vec.len();
+ // Unfortunately, `resize()` would suffice but the optimiser does not
+ // realise the `reserve` it does can be eliminated. So we do it manually
+ // to eliminate that extra branch
+ let spare = vec.spare_capacity_mut();
+ debug_assert!(spare.len() >= diff);
+ // Safety: we have allocated enough capacity for this.
+ // And we are only writing, not reading
+ unsafe {
+ spare.get_unchecked_mut(..diff).fill(core::mem::MaybeUninit::new(0));
+ vec.set_len(pos);
+ }
}
+ Ok(pos)
+}
+
+/// Writes the slice to the vec without allocating
+/// # Safety: vec must have buf.len() spare capacity
+unsafe fn vec_write_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -> usize
+where
+ A: Allocator,
+{
+ debug_assert!(vec.capacity() >= pos + buf.len());
+ vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len());
+ pos + buf.len()
+}
+
+/// Resizing write implementation for [`Cursor`]
+///
+/// Cursor is allowed to have a pre-allocated and initialised
+/// vector body, but with a position of 0. This means the [`Write`]
+/// will overwrite the contents of the vec.
+///
+/// This also allows for the vec body to be empty, but with a position of N.
+/// This means that [`Write`] will pad the vec with 0 initially,
+/// before writing anything from that point
+fn vec_write<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
+where
+ A: Allocator,
+{
+ let buf_len = buf.len();
+ let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
+
+ // Write the buf then progress the vec forward if necessary
+ // Safety: we have ensured that the capacity is available
+ // and that all bytes get written up to pos
+ unsafe {
+ pos = vec_write_unchecked(pos, vec, buf);
+ if pos > vec.len() {
+ vec.set_len(pos);
+ }
+ };
+
// Bump us forward
- *pos_mut = (pos + buf.len()) as u64;
- Ok(buf.len())
+ *pos_mut += buf_len as u64;
+ Ok(buf_len)
}
+/// Resizing write_vectored implementation for [`Cursor`]
+///
+/// Cursor is allowed to have a pre-allocated and initialised
+/// vector body, but with a position of 0. This means the [`Write`]
+/// will overwrite the contents of the vec.
+///
+/// This also allows for the vec body to be empty, but with a position of N.
+/// This means that [`Write`] will pad the vec with 0 initially,
+/// before writing anything from that point
fn vec_write_vectored<A>(
pos_mut: &mut u64,
vec: &mut Vec<u8, A>,
@@ -436,11 +497,26 @@ fn vec_write_vectored<A>(
where
A: Allocator,
{
- let mut nwritten = 0;
- for buf in bufs {
- nwritten += vec_write(pos_mut, vec, buf)?;
+ // For safety reasons, we don't want this sum to overflow ever.
+ // If this saturates, the reserve should panic to avoid any unsound writing.
+ let buf_len = bufs.iter().fold(0usize, |a, b| a.saturating_add(b.len()));
+ let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
+
+ // Write the buf then progress the vec forward if necessary
+ // Safety: we have ensured that the capacity is available
+ // and that all bytes get written up to the last pos
+ unsafe {
+ for buf in bufs {
+ pos = vec_write_unchecked(pos, vec, buf);
+ }
+ if pos > vec.len() {
+ vec.set_len(pos);
+ }
}
- Ok(nwritten)
+
+ // Bump us forward
+ *pos_mut += buf_len as u64;
+ Ok(buf_len)
}
#[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/io/cursor/tests.rs b/library/std/src/io/cursor/tests.rs
index f1ee177b7f3..d7c203c297f 100644
--- a/library/std/src/io/cursor/tests.rs
+++ b/library/std/src/io/cursor/tests.rs
@@ -20,6 +20,7 @@ fn test_vec_writer() {
#[test]
fn test_mem_writer() {
let mut writer = Cursor::new(Vec::new());
+ writer.set_position(10);
assert_eq!(writer.write(&[0]).unwrap(), 1);
assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
@@ -30,6 +31,17 @@ fn test_mem_writer() {
3
);
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ assert_eq!(&writer.get_ref()[..10], &[0; 10]);
+ assert_eq!(&writer.get_ref()[10..], b);
+}
+
+#[test]
+fn test_mem_writer_preallocated() {
+ let mut writer = Cursor::new(vec![0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 10]);
+ assert_eq!(writer.write(&[0]).unwrap(), 1);
+ assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
+ assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
+ let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
assert_eq!(&writer.get_ref()[..], b);
}
@@ -517,3 +529,39 @@ fn const_cursor() {
const _: &&[u8] = CURSOR.get_ref();
const _: u64 = CURSOR.position();
}
+
+#[bench]
+fn bench_write_vec(b: &mut test::Bencher) {
+ let slice = &[1; 128];
+
+ b.iter(|| {
+ let mut buf = b"some random data to overwrite".to_vec();
+ let mut cursor = Cursor::new(&mut buf);
+
+ let _ = cursor.write_all(slice);
+ test::black_box(&cursor);
+ })
+}
+
+#[bench]
+fn bench_write_vec_vectored(b: &mut test::Bencher) {
+ let slices = [
+ IoSlice::new(&[1; 128]),
+ IoSlice::new(&[2; 256]),
+ IoSlice::new(&[3; 512]),
+ IoSlice::new(&[4; 1024]),
+ IoSlice::new(&[5; 2048]),
+ IoSlice::new(&[6; 4096]),
+ IoSlice::new(&[7; 8192]),
+ IoSlice::new(&[8; 8192 * 2]),
+ ];
+
+ b.iter(|| {
+ let mut buf = b"some random data to overwrite".to_vec();
+ let mut cursor = Cursor::new(&mut buf);
+
+ let mut slices = slices;
+ let _ = cursor.write_all_vectored(&mut slices);
+ test::black_box(&cursor);
+ })
+}
diff --git a/library/std/src/sys/hermit/condvar.rs b/library/std/src/sys/hermit/condvar.rs
index 3f00160e55a..22059ca0dbe 100644
--- a/library/std/src/sys/hermit/condvar.rs
+++ b/library/std/src/sys/hermit/condvar.rs
@@ -3,6 +3,7 @@ use crate::ptr;
use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use crate::sys::hermit::abi;
use crate::sys::locks::Mutex;
+use crate::sys_common::lazy_box::{LazyBox, LazyInit};
use crate::time::Duration;
// The implementation is inspired by Andrew D. Birrell's paper
@@ -14,14 +15,26 @@ pub struct Condvar {
sem2: *const c_void,
}
-pub type MovableCondvar = Condvar;
+pub(crate) type MovableCondvar = LazyBox<Condvar>;
+
+impl LazyInit for Condvar {
+ fn init() -> Box<Self> {
+ Box::new(Self::new())
+ }
+}
unsafe impl Send for Condvar {}
unsafe impl Sync for Condvar {}
impl Condvar {
- pub const fn new() -> Condvar {
- Condvar { counter: AtomicUsize::new(0), sem1: ptr::null(), sem2: ptr::null() }
+ pub fn new() -> Self {
+ let mut condvar =
+ Self { counter: AtomicUsize::new(0), sem1: ptr::null(), sem2: ptr::null() };
+ unsafe {
+ let _ = abi::sem_init(&mut condvar.sem1, 0);
+ let _ = abi::sem_init(&mut condvar.sem2, 0);
+ }
+ condvar
}
pub unsafe fn notify_one(&self) {
diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs
index ef44bf411fb..eb15a04ffcf 100644
--- a/library/std/src/sys/hermit/mutex.rs
+++ b/library/std/src/sys/hermit/mutex.rs
@@ -175,9 +175,7 @@ impl Mutex {
}
#[inline]
- pub unsafe fn init(&mut self) {
- self.inner = Spinlock::new(MutexInner::new());
- }
+ pub unsafe fn init(&mut self) {}
#[inline]
pub unsafe fn lock(&self) {
diff --git a/library/std/src/sys/hermit/rwlock.rs b/library/std/src/sys/hermit/rwlock.rs
index d43fa08a171..9701bab1f66 100644
--- a/library/std/src/sys/hermit/rwlock.rs
+++ b/library/std/src/sys/hermit/rwlock.rs
@@ -1,9 +1,10 @@
use crate::cell::UnsafeCell;
-use crate::sys::locks::{Condvar, Mutex};
+use crate::sys::locks::{MovableCondvar, Mutex};
+use crate::sys_common::lazy_box::{LazyBox, LazyInit};
pub struct RwLock {
lock: Mutex,
- cond: Condvar,
+ cond: MovableCondvar,
state: UnsafeCell<State>,
}
@@ -28,7 +29,11 @@ unsafe impl Sync for RwLock {}
impl RwLock {
pub const fn new() -> RwLock {
- RwLock { lock: Mutex::new(), cond: Condvar::new(), state: UnsafeCell::new(State::Unlocked) }
+ RwLock {
+ lock: Mutex::new(),
+ cond: MovableCondvar::new(),
+ state: UnsafeCell::new(State::Unlocked),
+ }
}
#[inline]
diff --git a/library/std/src/sys/itron/abi.rs b/library/std/src/sys/itron/abi.rs
index f99ee4fa897..5eb14bb7e53 100644
--- a/library/std/src/sys/itron/abi.rs
+++ b/library/std/src/sys/itron/abi.rs
@@ -30,15 +30,32 @@ pub type ER = int_t;
/// Error code type, `ID` on success
pub type ER_ID = int_t;
+/// Service call operational mode
+pub type MODE = uint_t;
+
+/// OR waiting condition for an eventflag
+pub const TWF_ORW: MODE = 0x01;
+
+/// Object attributes
+pub type ATR = uint_t;
+
+/// FIFO wait order
+pub const TA_FIFO: ATR = 0;
+/// Only one task is allowed to be in the waiting state for the eventflag
+pub const TA_WSGL: ATR = 0;
+/// The eventflag’s bit pattern is cleared when a task is released from the
+/// waiting state for that eventflag.
+pub const TA_CLR: ATR = 0x04;
+
+/// Bit pattern of an eventflag
+pub type FLGPTN = uint_t;
+
/// Task or interrupt priority
pub type PRI = int_t;
/// The special value of `PRI` representing the current task's priority.
pub const TPRI_SELF: PRI = 0;
-/// Object attributes
-pub type ATR = uint_t;
-
/// Use the priority inheritance protocol
#[cfg(target_os = "solid_asp3")]
pub const TA_INHERIT: ATR = 0x02;
@@ -92,6 +109,13 @@ pub struct T_CSEM {
#[derive(Clone, Copy)]
#[repr(C)]
+pub struct T_CFLG {
+ pub flgatr: ATR,
+ pub iflgptn: FLGPTN,
+}
+
+#[derive(Clone, Copy)]
+#[repr(C)]
pub struct T_CMTX {
pub mtxatr: ATR,
pub ceilpri: PRI,
@@ -139,6 +163,24 @@ extern "C" {
pub fn sns_dsp() -> bool_t;
#[link_name = "__asp3_get_tim"]
pub fn get_tim(p_systim: *mut SYSTIM) -> ER;
+ #[link_name = "__asp3_acre_flg"]
+ pub fn acre_flg(pk_cflg: *const T_CFLG) -> ER_ID;
+ #[link_name = "__asp3_del_flg"]
+ pub fn del_flg(flgid: ID) -> ER;
+ #[link_name = "__asp3_set_flg"]
+ pub fn set_flg(flgid: ID, setptn: FLGPTN) -> ER;
+ #[link_name = "__asp3_clr_flg"]
+ pub fn clr_flg(flgid: ID, clrptn: FLGPTN) -> ER;
+ #[link_name = "__asp3_wai_flg"]
+ pub fn wai_flg(flgid: ID, waiptn: FLGPTN, wfmode: MODE, p_flgptn: *mut FLGPTN) -> ER;
+ #[link_name = "__asp3_twai_flg"]
+ pub fn twai_flg(
+ flgid: ID,
+ waiptn: FLGPTN,
+ wfmode: MODE,
+ p_flgptn: *mut FLGPTN,
+ tmout: TMO,
+ ) -> ER;
#[link_name = "__asp3_acre_mtx"]
pub fn acre_mtx(pk_cmtx: *const T_CMTX) -> ER_ID;
#[link_name = "__asp3_del_mtx"]
diff --git a/library/std/src/sys/itron/wait_flag.rs b/library/std/src/sys/itron/wait_flag.rs
new file mode 100644
index 00000000000..e432edd2077
--- /dev/null
+++ b/library/std/src/sys/itron/wait_flag.rs
@@ -0,0 +1,72 @@
+use crate::mem::MaybeUninit;
+use crate::time::Duration;
+
+use super::{
+ abi,
+ error::{expect_success, fail},
+ time::with_tmos,
+};
+
+const CLEAR: abi::FLGPTN = 0;
+const RAISED: abi::FLGPTN = 1;
+
+/// A thread parking primitive that is not susceptible to race conditions,
+/// but provides no atomic ordering guarantees and allows only one `raise` per wait.
+pub struct WaitFlag {
+ flag: abi::ID,
+}
+
+impl WaitFlag {
+ /// Creates a new wait flag.
+ pub fn new() -> WaitFlag {
+ let flag = expect_success(
+ unsafe {
+ abi::acre_flg(&abi::T_CFLG {
+ flgatr: abi::TA_FIFO | abi::TA_WSGL | abi::TA_CLR,
+ iflgptn: CLEAR,
+ })
+ },
+ &"acre_flg",
+ );
+
+ WaitFlag { flag }
+ }
+
+ /// Wait for the wait flag to be raised.
+ pub fn wait(&self) {
+ let mut token = MaybeUninit::uninit();
+ expect_success(
+ unsafe { abi::wai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr()) },
+ &"wai_flg",
+ );
+ }
+
+ /// Wait for the wait flag to be raised or the timeout to occur.
+ ///
+ /// Returns whether the flag was raised (`true`) or the operation timed out (`false`).
+ pub fn wait_timeout(&self, dur: Duration) -> bool {
+ let mut token = MaybeUninit::uninit();
+ let res = with_tmos(dur, |tmout| unsafe {
+ abi::twai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr(), tmout)
+ });
+
+ match res {
+ abi::E_OK => true,
+ abi::E_TMOUT => false,
+ error => fail(error, &"twai_flg"),
+ }
+ }
+
+ /// Raise the wait flag.
+ ///
+ /// Calls to this function should be balanced with the number of successful waits.
+ pub fn raise(&self) {
+ expect_success(unsafe { abi::set_flg(self.flag, RAISED) }, &"set_flg");
+ }
+}
+
+impl Drop for WaitFlag {
+ fn drop(&mut self) {
+ expect_success(unsafe { abi::del_flg(self.flag) }, &"del_flg");
+ }
+}
diff --git a/library/std/src/sys/solid/mod.rs b/library/std/src/sys/solid/mod.rs
index 5ffa381f2e5..2d21e4764fc 100644
--- a/library/std/src/sys/solid/mod.rs
+++ b/library/std/src/sys/solid/mod.rs
@@ -15,6 +15,7 @@ mod itron {
pub mod thread;
pub(super) mod time;
use super::unsupported;
+ pub mod wait_flag;
}
pub mod alloc;
@@ -43,6 +44,7 @@ pub mod memchr;
pub mod thread_local_dtor;
pub mod thread_local_key;
pub mod time;
+pub use self::itron::wait_flag;
mod rwlock;
diff --git a/library/std/src/sys_common/thread_parker/mod.rs b/library/std/src/sys_common/thread_parker/mod.rs
index 7e8bfb2565e..cbd7832eb7a 100644
--- a/library/std/src/sys_common/thread_parker/mod.rs
+++ b/library/std/src/sys_common/thread_parker/mod.rs
@@ -10,9 +10,10 @@ cfg_if::cfg_if! {
))] {
mod futex;
pub use futex::Parker;
- } else if #[cfg(windows)] {
- pub use crate::sys::thread_parker::Parker;
- } else if #[cfg(target_family = "unix")] {
+ } else if #[cfg(target_os = "solid_asp3")] {
+ mod wait_flag;
+ pub use wait_flag::Parker;
+ } else if #[cfg(any(windows, target_family = "unix"))] {
pub use crate::sys::thread_parker::Parker;
} else {
mod generic;
diff --git a/library/std/src/sys_common/thread_parker/wait_flag.rs b/library/std/src/sys_common/thread_parker/wait_flag.rs
new file mode 100644
index 00000000000..6561c186655
--- /dev/null
+++ b/library/std/src/sys_common/thread_parker/wait_flag.rs
@@ -0,0 +1,102 @@
+//! A wait-flag-based thread parker.
+//!
+//! Some operating systems provide low-level parking primitives like wait counts,
+//! event flags or semaphores which are not susceptible to race conditions (meaning
+//! the wakeup can occur before the wait operation). To implement the `std` thread
+//! parker on top of these primitives, we only have to ensure that parking is fast
+//! when the thread token is available, the atomic ordering guarantees are maintained
+//! and spurious wakeups are minimized.
+//!
+//! To achieve this, this parker uses an atomic variable with three states: `EMPTY`,
+//! `PARKED` and `NOTIFIED`:
+//! * `EMPTY` means the token has not been made available, but the thread is not
+//! currently waiting on it.
+//! * `PARKED` means the token is not available and the thread is parked.
+//! * `NOTIFIED` means the token is available.
+//!
+//! `park` and `park_timeout` change the state from `EMPTY` to `PARKED` and from
+//! `NOTIFIED` to `EMPTY`. If the state was `NOTIFIED`, the thread was unparked and
+//! execution can continue without calling into the OS. If the state was `EMPTY`,
+//! the token is not available and the thread waits on the primitive (here called
+//! "wait flag").
+//!
+//! `unpark` changes the state to `NOTIFIED`. If the state was `PARKED`, the thread
+//! is or will be sleeping on the wait flag, so we raise it.
+
+use crate::pin::Pin;
+use crate::sync::atomic::AtomicI8;
+use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
+use crate::sys::wait_flag::WaitFlag;
+use crate::time::Duration;
+
+const EMPTY: i8 = 0;
+const PARKED: i8 = -1;
+const NOTIFIED: i8 = 1;
+
+pub struct Parker {
+ state: AtomicI8,
+ wait_flag: WaitFlag,
+}
+
+impl Parker {
+ /// Construct a parker for the current thread. The UNIX parker
+ /// implementation requires this to happen in-place.
+ pub unsafe fn new(parker: *mut Parker) {
+ parker.write(Parker { state: AtomicI8::new(EMPTY), wait_flag: WaitFlag::new() })
+ }
+
+ // This implementation doesn't require `unsafe` and `Pin`, but other implementations do.
+ pub unsafe fn park(self: Pin<&Self>) {
+ match self.state.fetch_sub(1, Acquire) {
+ // NOTIFIED => EMPTY
+ NOTIFIED => return,
+ // EMPTY => PARKED
+ EMPTY => (),
+ _ => panic!("inconsistent park state"),
+ }
+
+ // Avoid waking up from spurious wakeups (these are quite likely, see below).
+ loop {
+ self.wait_flag.wait();
+
+ match self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Relaxed) {
+ Ok(_) => return,
+ Err(PARKED) => (),
+ Err(_) => panic!("inconsistent park state"),
+ }
+ }
+ }
+
+ // This implementation doesn't require `unsafe` and `Pin`, but other implementations do.
+ pub unsafe fn park_timeout(self: Pin<&Self>, dur: Duration) {
+ match self.state.fetch_sub(1, Acquire) {
+ NOTIFIED => return,
+ EMPTY => (),
+ _ => panic!("inconsistent park state"),
+ }
+
+ self.wait_flag.wait_timeout(dur);
+
+ // Either a wakeup or a timeout occurred. Wakeups may be spurious, as there can be
+ // a race condition when `unpark` is performed between receiving the timeout and
+ // resetting the state, resulting in the eventflag being set unnecessarily. `park`
+ // is protected against this by looping until the token is actually given, but
+ // here we cannot easily tell.
+
+ // Use `swap` to provide acquire ordering.
+ match self.state.swap(EMPTY, Acquire) {
+ NOTIFIED => (),
+ PARKED => (),
+ _ => panic!("inconsistent park state"),
+ }
+ }
+
+ // This implementation doesn't require `Pin`, but other implementations do.
+ pub fn unpark(self: Pin<&Self>) {
+ let state = self.state.swap(NOTIFIED, Release);
+
+ if state == PARKED {
+ self.wait_flag.raise();
+ }
+ }
+}
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 457fedd2d8a..8000e60f64d 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -743,7 +743,7 @@ class RustBuild(object):
"""
return os.path.join(self.build_dir, "bootstrap", "debug", "bootstrap")
- def build_bootstrap(self):
+ def build_bootstrap(self, color):
"""Build bootstrap"""
print("Building rustbuild")
build_dir = os.path.join(self.build_dir, "bootstrap")
@@ -800,6 +800,11 @@ class RustBuild(object):
if self.get_toml("metrics", "build"):
args.append("--features")
args.append("build-metrics")
+ if color == "always":
+ args.append("--color=always")
+ elif color == "never":
+ args.append("--color=never")
+
run(args, env=env, verbose=self.verbose)
def build_triple(self):
@@ -862,6 +867,7 @@ def bootstrap(help_triggered):
parser = argparse.ArgumentParser(description='Build rust')
parser.add_argument('--config')
parser.add_argument('--build')
+ parser.add_argument('--color', choices=['always', 'never', 'auto'])
parser.add_argument('--clean', action='store_true')
parser.add_argument('-v', '--verbose', action='count', default=0)
@@ -930,7 +936,7 @@ def bootstrap(help_triggered):
# Fetch/build the bootstrap
build.download_toolchain()
sys.stdout.flush()
- build.build_bootstrap()
+ build.build_bootstrap(args.color)
sys.stdout.flush()
# Run the bootstrap
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index ea410849694..9cd8b6d1455 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -160,7 +160,7 @@ pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) {
// files in the tarball are in the past, so it doesn't trigger a
// rebuild.
let now = filetime::FileTime::from_system_time(std::time::SystemTime::now());
- let llvm_config = llvm_root.join("bin/llvm-config");
+ let llvm_config = llvm_root.join("bin").join(exe("llvm-config", builder.config.build));
t!(filetime::set_file_times(&llvm_config, now, now));
let llvm_lib = llvm_root.join("lib");
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index e59324331ae..6e3651665c8 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -6,6 +6,7 @@ use std::path::PathBuf;
use std::str::FromStr;
use rustc_data_structures::fx::FxHashMap;
+use rustc_driver::print_flag_list;
use rustc_session::config::{
self, parse_crate_types_from_list, parse_externs, parse_target_triple, CrateType,
};
@@ -310,11 +311,15 @@ impl RenderOptions {
impl Options {
/// Parses the given command-line for options. If an error message or other early-return has
/// been printed, returns `Err` with the exit code.
- pub(crate) fn from_matches(matches: &getopts::Matches) -> Result<Options, i32> {
+ pub(crate) fn from_matches(
+ matches: &getopts::Matches,
+ args: Vec<String>,
+ ) -> Result<Options, i32> {
+ let args = &args[1..];
// Check for unstable options.
nightly_options::check_nightly_options(matches, &opts());
- if matches.opt_present("h") || matches.opt_present("help") {
+ if args.is_empty() || matches.opt_present("h") || matches.opt_present("help") {
crate::usage("rustdoc");
return Err(0);
} else if matches.opt_present("version") {
@@ -335,6 +340,21 @@ impl Options {
// check for deprecated options
check_deprecated_options(matches, &diag);
+ let z_flags = matches.opt_strs("Z");
+ if z_flags.iter().any(|x| *x == "help") {
+ print_flag_list("-Z", config::DB_OPTIONS);
+ return Err(0);
+ }
+ let c_flags = matches.opt_strs("C");
+ if c_flags.iter().any(|x| *x == "help") {
+ print_flag_list("-C", config::CG_OPTIONS);
+ return Err(0);
+ }
+ let w_flags = matches.opt_strs("W");
+ if w_flags.iter().any(|x| *x == "help") {
+ print_flag_list("-W", config::DB_OPTIONS);
+ return Err(0);
+ }
if matches.opt_strs("passes") == ["list"] {
println!("Available passes for running rustdoc:");
for pass in passes::PASSES {
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index b4b7790eebb..5d0756d30fb 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -983,42 +983,51 @@ table,
font-weight: normal;
}
-body.blur > :not(#help) {
- filter: blur(8px);
- -webkit-filter: blur(8px);
- opacity: .7;
+.popover {
+ font-size: 1rem;
+ position: absolute;
+ right: 0;
+ z-index: 2;
+ display: block;
+ margin-top: 7px;
+ border-radius: 3px;
+ border: 1px solid;
+ font-size: 1rem;
}
-#help {
- width: 100%;
- height: 100vh;
- position: fixed;
- top: 0;
- left: 0;
- display: flex;
- justify-content: center;
- align-items: center;
+/* This rule is to draw the little arrow connecting the settings menu to the gear icon. */
+.popover::before {
+ content: '';
+ position: absolute;
+ right: 11px;
+ border: solid;
+ border-width: 1px 1px 0 0;
+ display: inline-block;
+ padding: 4px;
+ transform: rotate(-45deg);
+ top: -5px;
}
-#help > div {
- flex: 0 0 auto;
- box-shadow: 0 0 6px rgba(0,0,0,.2);
- width: 550px;
- height: auto;
- border: 1px solid;
+
+#help-button .popover {
+ max-width: 600px;
}
-#help dt {
+
+#help-button .popover::before {
+ right: 48px;
+}
+
+#help-button dt {
float: left;
clear: left;
display: block;
margin-right: 0.5rem;
}
-#help span.top, #help span.bottom {
+#help-button span.top, #help-button span.bottom {
text-align: center;
display: block;
font-size: 1.125rem;
-
}
-#help span.top {
+#help-button span.top {
text-align: center;
display: block;
margin: 10px 0;
@@ -1026,17 +1035,17 @@ body.blur > :not(#help) {
padding-bottom: 4px;
margin-bottom: 6px;
}
-#help span.bottom {
+#help-button span.bottom {
clear: both;
border-top: 1px solid;
}
-#help dd { margin: 5px 35px; }
-#help .infos { padding-left: 0; }
-#help h1, #help h2 { margin-top: 0; }
-#help > div div {
+.side-by-side {
+ text-align: initial;
+}
+.side-by-side > div {
width: 50%;
float: left;
- padding: 0 20px 20px 17px;;
+ padding: 0 20px 20px 17px;
}
.item-info .stab {
@@ -1391,7 +1400,7 @@ pre.rust {
#copy-path {
height: 34px;
}
-#settings-menu > a, #help-button, #copy-path {
+#settings-menu > a, #help-button > button, #copy-path {
padding: 5px;
width: 33px;
border: 1px solid;
@@ -1401,9 +1410,8 @@ pre.rust {
#settings-menu {
padding: 0;
}
-#settings-menu > a {
+#settings-menu > a, #help-button > button {
padding: 5px;
- width: 100%;
height: 100%;
display: block;
}
@@ -1420,7 +1428,7 @@ pre.rust {
animation: rotating 2s linear infinite;
}
-#help-button {
+#help-button > button {
font-family: "Fira Sans", Arial, sans-serif;
text-align: center;
/* Rare exception to specifying font sizes in rem. Since this is acting
diff --git a/src/librustdoc/html/static/css/settings.css b/src/librustdoc/html/static/css/settings.css
index 1cd8e39e036..e531e6ce6bb 100644
--- a/src/librustdoc/html/static/css/settings.css
+++ b/src/librustdoc/html/static/css/settings.css
@@ -86,27 +86,6 @@ input:checked + .slider:before {
display: block;
}
-div#settings {
- position: absolute;
- right: 0;
- z-index: 1;
- display: block;
- margin-top: 7px;
- border-radius: 3px;
- border: 1px solid;
-}
#settings .setting-line {
margin: 1.2em 0.6em;
}
-/* This rule is to draw the little arrow connecting the settings menu to the gear icon. */
-div#settings::before {
- content: '';
- position: absolute;
- right: 11px;
- border: solid;
- border-width: 1px 1px 0 0;
- display: inline-block;
- padding: 4px;
- transform: rotate(-45deg);
- top: -5px;
-}
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index 5b37ecf19da..b7d0db1f002 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -5,7 +5,7 @@ Original by Dempfi (https://github.com/dempfi/ayu)
/* General structure and fonts */
-body, #settings-menu #settings, #settings-menu #settings::before {
+body, .popover, .popover::before {
background-color: #0f1419;
color: #c5c5c5;
}
@@ -567,7 +567,7 @@ kbd {
box-shadow: inset 0 -1px 0 #5c6773;
}
-#settings-menu > a, #help-button {
+#settings-menu > a, #help-button > button {
border-color: #5c6773;
background-color: #0f1419;
color: #fff;
@@ -577,7 +577,8 @@ kbd {
filter: invert(100);
}
-#settings-menu #settings, #settings-menu #settings::before {
+.popover, .popover::before,
+#help-button span.top, #help-button span.bottom {
border-color: #5c6773;
}
@@ -592,7 +593,7 @@ kbd {
}
#settings-menu > a:hover, #settings-menu > a:focus,
-#help-button:hover, #help-button:focus {
+#help-button > button:hover, #help-button > button:focus {
border-color: #e0e0e0;
}
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index ffb59f7762b..eb64ef3e771 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -1,4 +1,4 @@
-body, #settings-menu #settings, #settings-menu #settings::before {
+body, .popover, .popover::before {
background-color: #353535;
color: #ddd;
}
@@ -442,18 +442,19 @@ kbd {
box-shadow: inset 0 -1px 0 #c6cbd1;
}
-#settings-menu > a, #help-button {
+#settings-menu > a, #help-button > button {
border-color: #e0e0e0;
background: #f0f0f0;
color: #000;
}
#settings-menu > a:hover, #settings-menu > a:focus,
-#help-button:hover, #help-button:focus {
+#help-button > button:hover, #help-button > button:focus {
border-color: #ffb900;
}
-#settings-menu #settings, #settings-menu #settings::before {
+.popover, .popover::before,
+#help-button span.top, #help-button span.bottom {
border-color: #d2d2d2;
}
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index ba798ee2a0e..00cdf835897 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -1,6 +1,6 @@
/* General structure and fonts */
-body, #settings-menu #settings, #settings-menu #settings::before {
+body, .popover, .popover::before {
background-color: white;
color: black;
}
@@ -427,17 +427,18 @@ kbd {
box-shadow: inset 0 -1px 0 #c6cbd1;
}
-#settings-menu > a, #help-button {
+#settings-menu > a, #help-button > button {
border-color: #e0e0e0;
background-color: #fff;
}
#settings-menu > a:hover, #settings-menu > a:focus,
-#help-button:hover, #help-button:focus {
+#help-button > button:hover, #help-button > button:focus {
border-color: #717171;
}
-#settings-menu #settings, #settings-menu #settings::before {
+.popover, .popover::before,
+#help-button span.top, #help-button span.bottom {
border-color: #DDDDDD;
}
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index b320db91046..70dbfd44425 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -63,6 +63,24 @@ function showMain() {
removeClass(document.getElementById(MAIN_ID), "hidden");
}
+function elemIsInParent(elem, parent) {
+ while (elem && elem !== document.body) {
+ if (elem === parent) {
+ return true;
+ }
+ elem = elem.parentElement;
+ }
+ return false;
+}
+
+function blurHandler(event, parentElem, hideCallback) {
+ if (!elemIsInParent(document.activeElement, parentElem) &&
+ !elemIsInParent(event.relatedTarget, parentElem)
+ ) {
+ hideCallback();
+ }
+}
+
(function() {
window.rootPath = getVar("root-path");
window.currentCrate = getVar("current-crate");
@@ -104,20 +122,21 @@ const MAIN_ID = "main-content";
const SETTINGS_BUTTON_ID = "settings-menu";
const ALTERNATIVE_DISPLAY_ID = "alternative-display";
const NOT_DISPLAYED_ID = "not-displayed";
+const HELP_BUTTON_ID = "help-button";
function getSettingsButton() {
return document.getElementById(SETTINGS_BUTTON_ID);
}
+function getHelpButton() {
+ return document.getElementById(HELP_BUTTON_ID);
+}
+
// Returns the current URL without any query parameter or hash.
function getNakedUrl() {
return window.location.href.split("?")[0].split("#")[0];
}
-window.hideSettings = () => {
- // Does nothing by default.
-};
-
/**
* This function inserts `newNode` after `referenceNode`. It doesn't work if `referenceNode`
* doesn't have a parent node.
@@ -381,55 +400,16 @@ function loadCss(cssFileName) {
openParentDetails(document.getElementById(id));
}
- function getHelpElement(build) {
- if (build) {
- buildHelperPopup();
- }
- return document.getElementById("help");
- }
-
- /**
- * Show the help popup.
- *
- * @param {boolean} display - Whether to show or hide the popup
- * @param {Event} ev - The event that triggered this call
- * @param {Element} [help] - The help element if it already exists
- */
- function displayHelp(display, ev, help) {
- if (display) {
- help = help ? help : getHelpElement(true);
- if (hasClass(help, "hidden")) {
- ev.preventDefault();
- removeClass(help, "hidden");
- addClass(document.body, "blur");
- }
- } else {
- // No need to build the help popup if we want to hide it in case it hasn't been
- // built yet...
- help = help ? help : getHelpElement(false);
- if (help && !hasClass(help, "hidden")) {
- ev.preventDefault();
- addClass(help, "hidden");
- removeClass(document.body, "blur");
- }
- }
- }
-
function handleEscape(ev) {
searchState.clearInputTimeout();
- const help = getHelpElement(false);
- if (help && !hasClass(help, "hidden")) {
- displayHelp(false, ev, help);
- } else {
- switchDisplayedElement(null);
- if (browserSupportsHistoryApi()) {
- history.replaceState(null, window.currentCrate + " - Rust",
- getNakedUrl() + window.location.hash);
- }
- ev.preventDefault();
+ switchDisplayedElement(null);
+ if (browserSupportsHistoryApi()) {
+ history.replaceState(null, window.currentCrate + " - Rust",
+ getNakedUrl() + window.location.hash);
}
+ ev.preventDefault();
searchState.defocus();
- window.hideSettings();
+ window.hidePopoverMenus();
}
const disableShortcuts = getSettingValue("disable-shortcuts") === "true";
@@ -453,7 +433,6 @@ function loadCss(cssFileName) {
case "s":
case "S":
- displayHelp(false, ev);
ev.preventDefault();
searchState.focus();
break;
@@ -465,7 +444,7 @@ function loadCss(cssFileName) {
break;
case "?":
- displayHelp(true, ev);
+ showHelp();
break;
default:
@@ -796,9 +775,6 @@ function loadCss(cssFileName) {
elem.addEventListener("click", f);
}
}
- handleClick("help-button", ev => {
- displayHelp(true, ev);
- });
handleClick(MAIN_ID, () => {
hideSidebar();
});
@@ -842,24 +818,16 @@ function loadCss(cssFileName) {
});
}
- let buildHelperPopup = () => {
- const popup = document.createElement("aside");
- addClass(popup, "hidden");
- popup.id = "help";
-
- popup.addEventListener("click", ev => {
- if (ev.target === popup) {
- // Clicked the blurred zone outside the help popup; dismiss help.
- displayHelp(false, ev);
- }
- });
+ function helpBlurHandler(event) {
+ blurHandler(event, getHelpButton(), window.hidePopoverMenus);
+ }
+ function buildHelpMenu() {
const book_info = document.createElement("span");
book_info.className = "top";
book_info.innerHTML = "You can find more information in \
<a href=\"https://doc.rust-lang.org/rustdoc/\">the rustdoc book</a>.";
- const container = document.createElement("div");
const shortcuts = [
["?", "Show this help dialog"],
["S", "Focus the search field"],
@@ -895,24 +863,85 @@ function loadCss(cssFileName) {
addClass(div_infos, "infos");
div_infos.innerHTML = "<h2>Search Tricks</h2>" + infos;
- container.appendChild(book_info);
- container.appendChild(div_shortcuts);
- container.appendChild(div_infos);
-
const rustdoc_version = document.createElement("span");
rustdoc_version.className = "bottom";
const rustdoc_version_code = document.createElement("code");
rustdoc_version_code.innerText = "rustdoc " + getVar("rustdoc-version");
rustdoc_version.appendChild(rustdoc_version_code);
+ const container = document.createElement("div");
+ container.className = "popover";
+ container.style.display = "none";
+
+ const side_by_side = document.createElement("div");
+ side_by_side.className = "side-by-side";
+ side_by_side.appendChild(div_shortcuts);
+ side_by_side.appendChild(div_infos);
+
+ container.appendChild(book_info);
+ container.appendChild(side_by_side);
container.appendChild(rustdoc_version);
- popup.appendChild(container);
- insertAfter(popup, document.querySelector("main"));
- // So that it's only built once and then it'll do nothing when called!
- buildHelperPopup = () => {};
+ const help_button = getHelpButton();
+ help_button.appendChild(container);
+
+ container.onblur = helpBlurHandler;
+ container.onclick = event => {
+ event.preventDefault();
+ };
+ help_button.onblur = helpBlurHandler;
+ help_button.children[0].onblur = helpBlurHandler;
+
+ return container;
+ }
+
+ /**
+ * Hide all the popover menus.
+ */
+ window.hidePopoverMenus = function() {
+ onEachLazy(document.querySelectorAll(".search-container .popover"), elem => {
+ elem.style.display = "none";
+ });
};
+ /**
+ * Returns the help menu element (not the button).
+ *
+ * @param {boolean} buildNeeded - If this argument is `false`, the help menu element won't be
+ * built if it doesn't exist.
+ *
+ * @return {HTMLElement}
+ */
+ function getHelpMenu(buildNeeded) {
+ let menu = getHelpButton().querySelector(".popover");
+ if (!menu && buildNeeded) {
+ menu = buildHelpMenu();
+ }
+ return menu;
+ }
+
+ /**
+ * Show the help popup menu.
+ */
+ function showHelp() {
+ const menu = getHelpMenu(true);
+ if (menu.style.display === "none") {
+ menu.style.display = "";
+ }
+ }
+
+ document.querySelector(`#${HELP_BUTTON_ID} > button`).addEventListener("click", event => {
+ const target = event.target;
+ if (target.tagName !== "BUTTON" || target.parentElement.id !== HELP_BUTTON_ID) {
+ return;
+ }
+ const menu = getHelpMenu(true);
+ const shouldShowHelp = menu.style.display === "none";
+ if (shouldShowHelp) {
+ showHelp();
+ }
+ });
+
setMobileTopbar();
addSidebarItems();
addSidebarCrates();
diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js
index 41bf0ec8955..797b931afc6 100644
--- a/src/librustdoc/html/static/js/settings.js
+++ b/src/librustdoc/html/static/js/settings.js
@@ -1,6 +1,6 @@
// Local js definitions:
/* global getSettingValue, getVirtualKey, updateLocalStorage, updateSystemTheme */
-/* global addClass, removeClass, onEach, onEachLazy */
+/* global addClass, removeClass, onEach, onEachLazy, blurHandler, elemIsInParent */
/* global MAIN_ID, getVar, getSettingsButton */
"use strict";
@@ -209,6 +209,7 @@
const innerHTML = `<div class="settings">${buildSettingsPageSections(settings)}</div>`;
const el = document.createElement(elementKind);
el.id = "settings";
+ el.className = "popover";
el.innerHTML = innerHTML;
if (isSettingsPage) {
@@ -226,23 +227,8 @@
settingsMenu.style.display = "";
}
- function elemIsInParent(elem, parent) {
- while (elem && elem !== document.body) {
- if (elem === parent) {
- return true;
- }
- elem = elem.parentElement;
- }
- return false;
- }
-
- function blurHandler(event) {
- const settingsButton = getSettingsButton();
- if (!elemIsInParent(document.activeElement, settingsButton) &&
- !elemIsInParent(event.relatedTarget, settingsButton)
- ) {
- window.hideSettings();
- }
+ function settingsBlurHandler(event) {
+ blurHandler(event, getSettingsButton(), window.hidePopoverMenus);
}
if (isSettingsPage) {
@@ -254,26 +240,24 @@
// We replace the existing "onclick" callback.
const settingsButton = getSettingsButton();
const settingsMenu = document.getElementById("settings");
- window.hideSettings = function() {
- settingsMenu.style.display = "none";
- };
settingsButton.onclick = function(event) {
if (elemIsInParent(event.target, settingsMenu)) {
return;
}
event.preventDefault();
- if (settingsMenu.style.display !== "none") {
- window.hideSettings();
- } else {
+ const shouldDisplaySettings = settingsMenu.style.display === "none";
+
+ window.hidePopoverMenus();
+ if (shouldDisplaySettings) {
displaySettings();
}
};
- settingsButton.onblur = blurHandler;
- settingsButton.querySelector("a").onblur = blurHandler;
+ settingsButton.onblur = settingsBlurHandler;
+ settingsButton.querySelector("a").onblur = settingsBlurHandler;
onEachLazy(settingsMenu.querySelectorAll("input"), el => {
- el.onblur = blurHandler;
+ el.onblur = settingsBlurHandler;
});
- settingsMenu.onblur = blurHandler;
+ settingsMenu.onblur = settingsBlurHandler;
}
// We now wait a bit for the web browser to end re-computing the DOM...
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index c4999e2c74f..dfb3e4e6a2c 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -119,7 +119,9 @@
spellcheck="false" {# -#}
placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#}
type="search"> {#- -#}
- <button type="button" id="help-button" title="help">?</button> {#- -#}
+ <div id="help-button" title="help" tabindex="-1"> {#- -#}
+ <button type="button">?</button> {#- -#}
+ </div> {#- -#}
<div id="settings-menu" tabindex="-1">
<a href="{{page.root_path|safe}}settings.html" title="settings"> {#- -#}
<img width="22" height="22" alt="Change settings" {# -#}
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index c627dcc30d6..428519dbc16 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -252,8 +252,11 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
bounds: b.into_iter().map(|x| x.into_tcx(tcx)).collect(),
default: None,
},
- // FIXME: do not map to Typedef but to a custom variant
- AssocTypeItem(t, _) => ItemEnum::Typedef(t.into_tcx(tcx)),
+ AssocTypeItem(t, b) => ItemEnum::AssocType {
+ generics: t.generics.into_tcx(tcx),
+ bounds: b.into_iter().map(|x| x.into_tcx(tcx)).collect(),
+ default: t.item_type.map(|ty| ty.into_tcx(tcx)),
+ },
// `convert_item` early returns `None` for striped items and keywords.
StrippedItem(_) | KeywordItem(_) => unreachable!(),
ExternCrateItem { ref src } => ItemEnum::ExternCrate {
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 54b85166041..db4c3d10237 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -686,7 +686,7 @@ fn main_args(at_args: &[String]) -> MainResult {
// Note that we discard any distinction between different non-zero exit
// codes from `from_matches` here.
- let options = match config::Options::from_matches(&matches) {
+ let options = match config::Options::from_matches(&matches, args) {
Ok(opts) => opts,
Err(code) => {
return if code == 0 {
diff --git a/src/llvm-project b/src/llvm-project
-Subproject c9e2e89ed3aa5a3be77143aa0c86906b4138374
+Subproject d1ddc34c4b23468f6d2bf553084834b104e16dd
diff --git a/src/test/run-make/issue-88756-default-output/Makefile b/src/test/run-make/issue-88756-default-output/Makefile
new file mode 100644
index 00000000000..cacbcbf3933
--- /dev/null
+++ b/src/test/run-make/issue-88756-default-output/Makefile
@@ -0,0 +1,4 @@
+-include ../../run-make-fulldeps/tools.mk
+
+all:
+ $(BARE_RUSTDOC) 2>&1 | sed -E 's@/nightly/|/beta/|/stable/|/1\.[0-9]+\.[0-9]+/@/$$CHANNEL/@g' | diff - output-default.stdout
diff --git a/src/test/run-make/issue-88756-default-output/README.md b/src/test/run-make/issue-88756-default-output/README.md
new file mode 100644
index 00000000000..8cbfac4f7d2
--- /dev/null
+++ b/src/test/run-make/issue-88756-default-output/README.md
@@ -0,0 +1 @@
+This is a test to verify that the default behavior of `rustdoc` is printing out help output instead of erroring out (#88756).
diff --git a/src/test/run-make/issue-88756-default-output/output-default.stdout b/src/test/run-make/issue-88756-default-output/output-default.stdout
new file mode 100644
index 00000000000..6d16fe5673b
--- /dev/null
+++ b/src/test/run-make/issue-88756-default-output/output-default.stdout
@@ -0,0 +1,193 @@
+rustdoc [options] <input>
+
+Options:
+ -h, --help show this help message
+ -V, --version print rustdoc's version
+ -v, --verbose use verbose output
+ -w, --output-format [html]
+ the output type to write
+ --output PATH Which directory to place the output. This option is
+ deprecated, use --out-dir instead.
+ -o, --out-dir PATH which directory to place the output
+ --crate-name NAME
+ specify the name of this crate
+ --crate-type [bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]
+ Comma separated list of types of crates
+ for the compiler to emit
+ -L, --library-path DIR
+ directory to add to crate search path
+ --cfg pass a --cfg to rustc
+ --check-cfg pass a --check-cfg to rustc
+ --extern NAME[=PATH]
+ pass an --extern to rustc
+ --extern-html-root-url NAME=URL
+ base URL to use for dependencies; for example,
+ "std=/doc" links std::vec::Vec to
+ /doc/std/vec/struct.Vec.html
+ --extern-html-root-takes-precedence
+ give precedence to `--extern-html-root-url`, not
+ `html_root_url`
+ -C, --codegen OPT[=VALUE]
+ pass a codegen option to rustc
+ --document-private-items
+ document private items
+ --document-hidden-items
+ document items that have doc(hidden)
+ --test run code examples as tests
+ --test-args ARGS
+ arguments to pass to the test runner
+ --test-run-directory PATH
+ The working directory in which to run tests
+ --target TRIPLE target triple to document
+ --markdown-css FILES
+ CSS files to include via <link> in a rendered Markdown
+ file
+ --html-in-header FILES
+ files to include inline in the <head> section of a
+ rendered Markdown file or generated documentation
+ --html-before-content FILES
+ files to include inline between <body> and the content
+ of a rendered Markdown file or generated documentation
+ --html-after-content FILES
+ files to include inline between the content and
+ </body> of a rendered Markdown file or generated
+ documentation
+ --markdown-before-content FILES
+ files to include inline between <body> and the content
+ of a rendered Markdown file or generated documentation
+ --markdown-after-content FILES
+ files to include inline between the content and
+ </body> of a rendered Markdown file or generated
+ documentation
+ --markdown-playground-url URL
+ URL to send code snippets to
+ --markdown-no-toc
+ don't include table of contents
+ -e, --extend-css PATH
+ To add some CSS rules with a given file to generate
+ doc with your own theme. However, your theme might
+ break if the rustdoc's generated HTML changes, so be
+ careful!
+ -Z FLAG internal and debugging options (only on nightly build)
+ --sysroot PATH Override the system root
+ --playground-url URL
+ URL to send code snippets to, may be reset by
+ --markdown-playground-url or
+ `#![doc(html_playground_url=...)]`
+ --display-doctest-warnings
+ show warnings that originate in doctests
+ --crate-version VERSION
+ crate version to print into documentation
+ --sort-modules-by-appearance
+ sort modules by where they appear in the program,
+ rather than alphabetically
+ --default-theme THEME
+ Set the default theme. THEME should be the theme name,
+ generally lowercase. If an unknown default theme is
+ specified, the builtin default is used. The set of
+ themes, and the rustdoc built-in default, are not
+ stable.
+ --default-setting SETTING[=VALUE]
+ Default value for a rustdoc setting (used when
+ "rustdoc-SETTING" is absent from web browser Local
+ Storage). If VALUE is not supplied, "true" is used.
+ Supported SETTINGs and VALUEs are not documented and
+ not stable.
+ --theme FILES additional themes which will be added to the generated
+ docs
+ --check-theme FILES
+ check if given theme is valid
+ --resource-suffix PATH
+ suffix to add to CSS and JavaScript files, e.g.,
+ "light.css" will become "light-suffix.css"
+ --edition EDITION
+ edition to use when compiling rust code (default:
+ 2015)
+ --color auto|always|never
+ Configure coloring of output:
+ auto = colorize, if output goes to a tty (default);
+ always = always colorize output;
+ never = never colorize output
+ --error-format human|json|short
+ How errors and other messages are produced
+ --json CONFIG Configure the structure of JSON diagnostics
+ --disable-minification
+ Disable minification applied on JS files
+ -A, --allow LINT Set lint allowed
+ -W, --warn LINT Set lint warnings
+ --force-warn LINT
+ Set lint force-warn
+ -D, --deny LINT Set lint denied
+ -F, --forbid LINT Set lint forbidden
+ --cap-lints LEVEL
+ Set the most restrictive lint level. More restrictive
+ lints are capped at this level. By default, it is at
+ `forbid` level.
+ --index-page PATH
+ Markdown file to be used as index page
+ --enable-index-page
+ To enable generation of the index page
+ --static-root-path PATH
+ Path string to force loading static files from in
+ output pages. If not set, uses combinations of '../'
+ to reach the documentation root.
+ --disable-per-crate-search
+ disables generating the crate selector on the search
+ box
+ --persist-doctests PATH
+ Directory to persist doctest executables into
+ --show-coverage
+ calculate percentage of public items with
+ documentation
+ --enable-per-target-ignores
+ parse ignore-foo for ignoring doctests on a per-target
+ basis
+ --runtool The tool to run tests with when building for a different target than host
+
+ --runtool-arg One (of possibly many) arguments to pass to the runtool
+
+ --test-builder PATH
+ The rustc-like binary to use as the test builder
+ --check Run rustdoc checks
+ --generate-redirect-map
+ Generate JSON file at the top level instead of
+ generating HTML redirection files
+ --emit [unversioned-shared-resources,toolchain-shared-resources,invocation-specific]
+ Comma separated list of types of output for rustdoc to
+ emit
+ --no-run Compile doctests without running them
+ --show-type-layout
+ Include the memory layout of types in the docs
+ --nocapture Don't capture stdout and stderr of tests
+ --generate-link-to-definition
+ Make the identifiers in the HTML source code pages
+ navigable
+ --scrape-examples-output-path collect function call information and output at the given path
+
+ --scrape-examples-target-crate collect function call information for functions from the target crate
+
+ --scrape-tests Include test code when scraping examples
+ --with-examples path to function call information (for displaying examples in the documentation)
+
+ --plugin-path DIR
+ removed, see issue #44136
+ <https://github.com/rust-lang/rust/issues/44136> for
+ more information
+ --passes PASSES removed, see issue #44136
+ <https://github.com/rust-lang/rust/issues/44136> for
+ more information
+ --plugins PLUGINS
+ removed, see issue #44136
+ <https://github.com/rust-lang/rust/issues/44136> for
+ more information
+ --no-defaults removed, see issue #44136
+ <https://github.com/rust-lang/rust/issues/44136> for
+ more information
+ -r, --input-format [rust]
+ removed, see issue #44136
+ <https://github.com/rust-lang/rust/issues/44136> for
+ more information
+
+ @path Read newline separated options from `path`
+
+More information available at https://doc.rust-lang.org/$CHANNEL/rustdoc/what-is-rustdoc.html
diff --git a/src/test/run-make/issue-88756-default-output/x.rs b/src/test/run-make/issue-88756-default-output/x.rs
new file mode 100644
index 00000000000..5df7576133a
--- /dev/null
+++ b/src/test/run-make/issue-88756-default-output/x.rs
@@ -0,0 +1 @@
+// nothing to see here
diff --git a/src/test/run-make/issue-88756-opt-help/Makefile b/src/test/run-make/issue-88756-opt-help/Makefile
new file mode 100644
index 00000000000..8ababbf5b4e
--- /dev/null
+++ b/src/test/run-make/issue-88756-opt-help/Makefile
@@ -0,0 +1,4 @@
+-include ../../run-make-fulldeps/tools.mk
+
+all:
+ $(RUSTDOC) -W help 2>&1 | diff - output-default.stdout
diff --git a/src/test/run-make/issue-88756-opt-help/README.md b/src/test/run-make/issue-88756-opt-help/README.md
new file mode 100644
index 00000000000..9b742753f25
--- /dev/null
+++ b/src/test/run-make/issue-88756-opt-help/README.md
@@ -0,0 +1 @@
+This is a test to verify that `rustdoc` behaves the same as rustc and prints out help output for its options like -W (#88756).
diff --git a/src/test/run-make/issue-88756-opt-help/output-default.stdout b/src/test/run-make/issue-88756-opt-help/output-default.stdout
new file mode 100644
index 00000000000..5cb7ecb649a
--- /dev/null
+++ b/src/test/run-make/issue-88756-opt-help/output-default.stdout
@@ -0,0 +1,193 @@
+ -W allow-features=val -- only allow the listed language features to be enabled in code (space separated)
+ -W always-encode-mir=val -- encode MIR of all functions into the crate metadata (default: no)
+ -W assume-incomplete-release=val -- make cfg(version) treat the current version as incomplete (default: no)
+ -W asm-comments=val -- generate comments into the assembly (may change behavior) (default: no)
+ -W assert-incr-state=val -- assert that the incremental cache is in given state: either `loaded` or `not-loaded`.
+ -W binary-dep-depinfo=val -- include artifacts (sysroot, crate dependencies) used during compilation in dep-info (default: no)
+ -W branch-protection=val -- set options for branch target identification and pointer authentication on AArch64
+ -W cf-protection=val -- instrument control-flow architecture protection
+ -W cgu-partitioning-strategy=val -- the codegen unit partitioning strategy to use
+ -W chalk=val -- enable the experimental Chalk-based trait solving engine
+ -W codegen-backend=val -- the backend to use
+ -W combine-cgu=val -- combine CGUs into a single one
+ -W crate-attr=val -- inject the given attribute in the crate
+ -W debug-info-for-profiling=val -- emit discriminators and other data necessary for AutoFDO
+ -W debug-macros=val -- emit line numbers debug info inside macros (default: no)
+ -W deduplicate-diagnostics=val -- deduplicate identical diagnostics (default: yes)
+ -W dep-info-omit-d-target=val -- in dep-info output, omit targets for tracking dependencies of the dep-info files themselves (default: no)
+ -W dep-tasks=val -- print tasks that execute and the color their dep node gets (requires debug build) (default: no)
+ -W dlltool=val -- import library generation tool (windows-gnu only)
+ -W dont-buffer-diagnostics=val -- emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) (default: no)
+ -W drop-tracking=val -- enables drop tracking in generators (default: no)
+ -W dual-proc-macros=val -- load proc macros for both target and host, but only link to the target (default: no)
+ -W dump-dep-graph=val -- dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) (default: no)
+ -W dump-mir=val -- dump MIR state to file.
+ `val` is used to select which passes and functions to dump. For example:
+ `all` matches all passes and functions,
+ `foo` matches all passes for functions whose name contains 'foo',
+ `foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo',
+ `foo | bar` all passes for function names containing 'foo' or 'bar'.
+ -W dump-mir-dataflow=val -- in addition to `.mir` files, create graphviz `.dot` files with dataflow results (default: no)
+ -W dump-mir-dir=val -- the directory the MIR is dumped into (default: `mir_dump`)
+ -W dump-mir-exclude-pass-number=val -- exclude the pass number when dumping MIR (used in tests) (default: no)
+ -W dump-mir-graphviz=val -- in addition to `.mir` files, create graphviz `.dot` files (and with `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived coverage graph) (default: no)
+ -W dump-mir-spanview=val -- in addition to `.mir` files, create `.html` files to view spans for all `statement`s (including terminators), only `terminator` spans, or computed `block` spans (one span encompassing a block's terminator and all statements). If `-Z instrument-coverage` is also enabled, create an additional `.html` file showing the computed coverage spans.
+ -W emit-stack-sizes=val -- emit a section containing stack size metadata (default: no)
+ -W fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no)
+ -W force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no)
+ -W fuel=val -- set the optimization fuel quota for a crate
+ -W function-sections=val -- whether each function should go in its own section
+ -W future-incompat-test=val -- forces all lints to be future incompatible, used for internal testing (default: no)
+ -W gcc-ld=val -- implementation of ld used by cc
+ -W graphviz-dark-mode=val -- use dark-themed colors in graphviz output (default: no)
+ -W graphviz-font=val -- use the given `fontname` in graphviz output; can be overridden by setting environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)
+ -W hir-stats=val -- print some statistics about AST and HIR (default: no)
+ -W human-readable-cgu-names=val -- generate human-readable, predictable names for codegen units (default: no)
+ -W identify-regions=val -- display unnamed regions as `'<id>`, using a non-ident unique id (default: no)
+ -W incremental-ignore-spans=val -- ignore spans during ICH computation -- used for testing (default: no)
+ -W incremental-info=val -- print high-level information about incremental reuse (or the lack thereof) (default: no)
+ -W incremental-relative-spans=val -- hash spans relative to their parent item for incr. comp. (default: no)
+ -W incremental-verify-ich=val -- verify incr. comp. hashes of green query instances (default: no)
+ -W inline-mir=val -- enable MIR inlining (default: no)
+ -W inline-mir-threshold=val -- a default MIR inlining threshold (default: 50)
+ -W inline-mir-hint-threshold=val -- inlining threshold for functions with inline hint (default: 100)
+ -W inline-in-all-cgus=val -- control whether `#[inline]` functions are in all CGUs
+ -W input-stats=val -- gather statistics about the input (default: no)
+ -W instrument-coverage=val -- instrument the generated code to support LLVM source-based code coverage reports (note, the compiler build config must include `profiler = true`); implies `-C symbol-mangling-version=v0`. Optional values are:
+ `=all` (implicit value)
+ `=except-unused-generics`
+ `=except-unused-functions`
+ `=off` (default)
+ -W instrument-mcount=val -- insert function instrument code for mcount-based tracing (default: no)
+ -W keep-hygiene-data=val -- keep hygiene data after analysis (default: no)
+ -W link-native-libraries=val -- link native libraries in the linker invocation (default: yes)
+ -W link-only=val -- link the `.rlink` file generated by `-Z no-link` (default: no)
+ -W llvm-plugins=val -- a list LLVM plugins to enable (space separated)
+ -W llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no)
+ -W location-detail=val -- comma separated list of location details to be tracked when using caller_location valid options are `file`, `line`, and `column` (default: all)
+ -W ls=val -- list the symbols defined by a library crate (default: no)
+ -W macro-backtrace=val -- show macro backtraces (default: no)
+ -W merge-functions=val -- control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name
+ -W meta-stats=val -- gather metadata statistics (default: no)
+ -W mir-emit-retag=val -- emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no)
+ -W mir-enable-passes=val -- use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be enabled, overriding all other checks. Passes that are not specified are enabled or disabled by other flags as usual.
+ -W mir-opt-level=val -- MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)
+ -W move-size-limit=val -- the size at which the `large_assignments` lint starts to be emitted
+ -W mutable-noalias=val -- emit noalias metadata for mutable references (default: yes)
+ -W new-llvm-pass-manager=val -- use new LLVM pass manager (default: no)
+ -W nll-facts=val -- dump facts from NLL analysis into side files (default: no)
+ -W nll-facts-dir=val -- the directory the NLL facts are dumped into (default: `nll-facts`)
+ -W no-analysis=val -- parse and expand the source, but run no analysis
+ -W no-codegen=val -- run all passes except codegen; no output
+ -W no-generate-arange-section=val -- omit DWARF address ranges that give faster lookups
+ -W no-interleave-lints=val -- execute lints separately; allows benchmarking individual lints
+ -W no-leak-check=val -- disable the 'leak check' for subtyping; unsound, but useful for tests
+ -W no-link=val -- compile without linking
+ -W no-parallel-llvm=val -- run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)
+ -W no-unique-section-names=val -- do not use unique names for text and data sections when -Z function-sections is used
+ -W no-profiler-runtime=val -- prevent automatic injection of the profiler_builtins crate
+ -W normalize-docs=val -- normalize associated items in rustdoc when generating documentation
+ -W oom=val -- panic strategy for out-of-memory handling
+ -W osx-rpath-install-name=val -- pass `-install_name @rpath/...` to the macOS linker (default: no)
+ -W panic-abort-tests=val -- support compiling tests with panic=abort (default: no)
+ -W panic-in-drop=val -- panic strategy for panics in drops
+ -W parse-only=val -- parse only; do not compile, assemble, or link (default: no)
+ -W perf-stats=val -- print some performance-related statistics (default: no)
+ -W pick-stable-methods-before-any-unstable=val -- try to pick stable methods first before picking any unstable methods (default: yes)
+ -W plt=val -- whether to use the PLT when calling into shared libraries;
+ only has effect for PIC code on systems with ELF binaries
+ (default: PLT is disabled if full relro is enabled)
+ -W polonius=val -- enable polonius-based borrow-checker (default: no)
+ -W polymorphize=val -- perform polymorphization analysis
+ -W pre-link-arg=val -- a single extra argument to prepend the linker invocation (can be used several times)
+ -W pre-link-args=val -- extra arguments to prepend to the linker invocation (space separated)
+ -W precise-enum-drop-elaboration=val -- use a more precise version of drop elaboration for matches on enums (default: yes). This results in better codegen, but has caused miscompilations on some tier 2 platforms. See #77382 and #74551.
+ -W print-fuel=val -- make rustc print the total optimization fuel used by a crate
+ -W print-llvm-passes=val -- print the LLVM optimization passes being run (default: no)
+ -W print-mono-items=val -- print the result of the monomorphization collection pass
+ -W print-type-sizes=val -- print layout information for each type encountered (default: no)
+ -W proc-macro-backtrace=val -- show backtraces for panics during proc-macro execution (default: no)
+ -W profile=val -- insert profiling code (default: no)
+ -W profile-closures=val -- profile size of closures
+ -W profile-emit=val -- file path to emit profiling data at runtime when using 'profile' (default based on relative source path)
+ -W profiler-runtime=val -- name of the profiler runtime crate to automatically inject (default: `profiler_builtins`)
+ -W profile-sample-use=val -- use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)
+ -W query-dep-graph=val -- enable queries of the dependency graph for regression testing (default: no)
+ -W randomize-layout=val -- randomize the layout of types (default: no)
+ -W layout-seed=val -- seed layout randomization
+ -W relax-elf-relocations=val -- whether ELF relocations can be relaxed
+ -W relro-level=val -- choose which RELRO level to use
+ -W remap-cwd-prefix=val -- remap paths under the current working directory to this path prefix
+ -W simulate-remapped-rust-src-base=val -- simulate the effect of remap-debuginfo = true at bootstrapping by remapping path to rust's source base directory. only meant for testing purposes
+ -W report-delayed-bugs=val -- immediately print bugs registered with `delay_span_bug` (default: no)
+ -W sanitizer=val -- use a sanitizer
+ -W sanitizer-memory-track-origins=val -- enable origins tracking in MemorySanitizer
+ -W sanitizer-recover=val -- enable recovery for selected sanitizers
+ -W saturating-float-casts=val -- make float->int casts UB-free: numbers outside the integer type's range are clipped to the max/min integer respectively, and NaN is mapped to 0 (default: yes)
+ -W save-analysis=val -- write syntax and type analysis (in JSON format) information, in addition to normal output (default: no)
+ -W self-profile=val -- run the self profiler and output the raw event data
+ -W self-profile-events=val -- specify the events recorded by the self profiler;
+ for example: `-Z self-profile-events=default,query-keys`
+ all options: none, all, default, generic-activity, query-provider, query-cache-hit
+ query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes
+ -W self-profile-counter=val -- counter used by the self profiler (default: `wall-time`), one of:
+ `wall-time` (monotonic clock, i.e. `std::time::Instant`)
+ `instructions:u` (retired instructions, userspace-only)
+ `instructions-minus-irqs:u` (subtracting hardware interrupt counts for extra accuracy)
+ -W share-generics=val -- make the current crate share its generic instantiations
+ -W show-span=val -- show spans for compiler debugging (expr|pat|ty)
+ -W span-debug=val -- forward proc_macro::Span's `Debug` impl to `Span`
+ -W span-free-formats=val -- exclude spans when debug-printing compiler state (default: no)
+ -W src-hash-algorithm=val -- hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)
+ -W stack-protector=val -- control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)
+ -W strict-init-checks=val -- control if mem::uninitialized and mem::zeroed panic on more UB
+ -W strip=val -- tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)
+ -W split-dwarf-kind=val -- split dwarf variant (only if -Csplit-debuginfo is enabled and on relevant platform)
+ (default: `split`)
+
+ `split`: sections which do not require relocation are written into a DWARF object (`.dwo`)
+ file which is ignored by the linker
+ `single`: sections which do not require relocation are written into object file but ignored
+ by the linker
+ -W split-dwarf-inlining=val -- provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF
+ -W symbol-mangling-version=val -- which mangling version to use for symbol names ('legacy' (default) or 'v0')
+ -W teach=val -- show extended diagnostic help (default: no)
+ -W temps-dir=val -- the directory the intermediate files are written to
+ -W terminal-width=val -- set the current terminal width
+ -W translate-lang=val -- language identifier for diagnostic output
+ -W translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation)
+ -W translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics
+ -W tune-cpu=val -- select processor to schedule for (`rustc --print target-cpus` for details)
+ -W thinlto=val -- enable ThinLTO when possible
+ -W thir-unsafeck=val -- use the THIR unsafety checker (default: no)
+ -W threads=val -- use a thread pool with N threads
+ -W time=val -- measure time of rustc processes (default: no)
+ -W time-llvm-passes=val -- measure time of each LLVM pass (default: no)
+ -W time-passes=val -- measure time of each rustc pass (default: no)
+ -W tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details)
+ -W trace-macros=val -- for every macro invocation, print its name and arguments (default: no)
+ -W translate-remapped-path-to-local-path=val -- translate remapped paths into local paths when possible (default: yes)
+ -W trap-unreachable=val -- generate trap instructions for unreachable intrinsics (default: use target setting, usually yes)
+ -W treat-err-as-bug=val -- treat error number `val` that occurs as bug
+ -W trim-diagnostic-paths=val -- in diagnostics, use heuristics to shorten paths referring to items
+ -W ui-testing=val -- emit compiler diagnostics in a form suitable for UI testing (default: no)
+ -W uninit-const-chunk-threshold=val -- allow generating const initializers with mixed init/uninit chunks, and set the maximum number of chunks for which this is allowed (default: 16)
+ -W unleash-the-miri-inside-of-you=val -- take the brakes off const evaluation. NOTE: this is unsound (default: no)
+ -W unpretty=val -- present the input source, unstable (and less-pretty) variants;
+ `normal`, `identified`,
+ `expanded`, `expanded,identified`,
+ `expanded,hygiene` (with internal representations),
+ `ast-tree` (raw AST before expansion),
+ `ast-tree,expanded` (raw AST after expansion),
+ `hir` (the HIR), `hir,identified`,
+ `hir,typed` (HIR with types for each node),
+ `hir-tree` (dump the raw HIR),
+ `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)
+ -W unsound-mir-opts=val -- enable unsound and buggy MIR optimizations (default: no)
+ -W unstable-options=val -- adds unstable command line options to rustc interface (default: no)
+ -W use-ctors-section=val -- use legacy .ctors section for initializers rather than .init_array
+ -W validate-mir=val -- validate MIR after each transformation
+ -W verbose=val -- in general, enable more debug printouts (default: no)
+ -W verify-llvm-ir=val -- verify LLVM IR (default: no)
+ -W virtual-function-elimination=val -- enables dead virtual function elimination optimization. Requires `-Clto[=[fat,yes]]`
+ -W wasi-exec-model=val -- whether to build a wasi command or reactor
diff --git a/src/test/run-make/issue-88756-opt-help/x.rs b/src/test/run-make/issue-88756-opt-help/x.rs
new file mode 100644
index 00000000000..5df7576133a
--- /dev/null
+++ b/src/test/run-make/issue-88756-opt-help/x.rs
@@ -0,0 +1 @@
+// nothing to see here
diff --git a/src/test/rustdoc-gui/escape-key.goml b/src/test/rustdoc-gui/escape-key.goml
index 8713bf65c84..d083b0ae0c9 100644
--- a/src/test/rustdoc-gui/escape-key.goml
+++ b/src/test/rustdoc-gui/escape-key.goml
@@ -21,17 +21,6 @@ wait-for: "#alternative-display #search"
assert-attribute: ("#main-content", {"class": "content hidden"})
assert-document-property: ({"URL": "index.html?search=test"}, ENDS_WITH)
-// Now let's check that when the help popup is displayed and we press Escape, it doesn't
-// hide the search results too.
-click: "#help-button"
-assert-document-property: ({"URL": "index.html?search=test"}, [ENDS_WITH])
-assert-attribute: ("#help", {"class": ""})
-press-key: "Escape"
-wait-for: "#alternative-display #search"
-assert-attribute: ("#help", {"class": "hidden"})
-assert-attribute: ("#main-content", {"class": "content hidden"})
-assert-document-property: ({"URL": "index.html?search=test"}, [ENDS_WITH])
-
// Check that Escape hides the search results when a search result is focused.
focus: ".search-input"
assert: ".search-input:focus"
@@ -39,7 +28,6 @@ press-key: "ArrowDown"
assert-false: ".search-input:focus"
assert: "#results a:focus"
press-key: "Escape"
-assert-attribute: ("#help", {"class": "hidden"})
wait-for: "#not-displayed #search"
assert-false: "#alternative-display #search"
assert-attribute: ("#main-content", {"class": "content"})
diff --git a/src/test/rustdoc-gui/pocket-menu.goml b/src/test/rustdoc-gui/pocket-menu.goml
new file mode 100644
index 00000000000..ba2986e969a
--- /dev/null
+++ b/src/test/rustdoc-gui/pocket-menu.goml
@@ -0,0 +1,72 @@
+// This test ensures that the "pocket menus" are working as expected.
+goto: file://|DOC_PATH|/test_docs/index.html
+// First we check that the help menu doesn't exist yet.
+assert-false: "#help-button .popover"
+// Then we display the help menu.
+click: "#help-button"
+assert: "#help-button .popover"
+assert-css: ("#help-button .popover", {"display": "block"})
+
+// Now we click somewhere else on the page to ensure it is handling the blur event
+// correctly.
+click: ".sidebar"
+assert-css: ("#help-button .popover", {"display": "none"})
+
+// Now we will check that we cannot have two "pocket menus" displayed at the same time.
+click: "#help-button"
+assert-css: ("#help-button .popover", {"display": "block"})
+click: "#settings-menu"
+assert-css: ("#help-button .popover", {"display": "none"})
+assert-css: ("#settings-menu .popover", {"display": "block"})
+
+// Now the other way.
+click: "#help-button"
+assert-css: ("#help-button .popover", {"display": "block"})
+assert-css: ("#settings-menu .popover", {"display": "none"})
+
+// We check the borders color now:
+
+// Ayu theme
+local-storage: {
+ "rustdoc-theme": "ayu",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+click: "#help-button"
+assert-css: (
+ "#help-button .popover",
+ {"display": "block", "border-color": "rgb(92, 103, 115)"},
+)
+compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"])
+compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"])
+
+// Dark theme
+local-storage: {
+ "rustdoc-theme": "dark",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+click: "#help-button"
+assert-css: (
+ "#help-button .popover",
+ {"display": "block", "border-color": "rgb(210, 210, 210)"},
+)
+compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"])
+compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"])
+
+// Light theme
+local-storage: {
+ "rustdoc-theme": "light",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+click: "#help-button"
+assert-css: (
+ "#help-button .popover",
+ {"display": "block", "border-color": "rgb(221, 221, 221)"},
+)
+compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"])
+compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"])
diff --git a/src/test/rustdoc-gui/shortcuts.goml b/src/test/rustdoc-gui/shortcuts.goml
index 37a7c166294..1f20a0eaa99 100644
--- a/src/test/rustdoc-gui/shortcuts.goml
+++ b/src/test/rustdoc-gui/shortcuts.goml
@@ -8,7 +8,6 @@ press-key: "Escape"
assert-false: "input.search-input:focus"
// We now check for the help popup.
press-key: "?"
-assert-css: ("#help", {"display": "flex"})
-assert-false: "#help.hidden"
+assert-css: ("#help-button .popover", {"display": "block"})
press-key: "Escape"
-assert-css: ("#help.hidden", {"display": "none"})
+assert-css: ("#help-button .popover", {"display": "none"})
diff --git a/src/test/rustdoc-json/assoc_items.rs b/src/test/rustdoc-json/assoc_items.rs
new file mode 100644
index 00000000000..2ee64c9f6eb
--- /dev/null
+++ b/src/test/rustdoc-json/assoc_items.rs
@@ -0,0 +1,29 @@
+#![no_std]
+
+// @has assoc_items.json
+
+pub struct Simple;
+
+impl Simple {
+ // @has - "$.index[*][?(@.name=='CONSTANT')].kind" \"assoc_const\"
+ pub const CONSTANT: usize = 0;
+}
+
+pub trait EasyToImpl {
+ // @has - "$.index[*][?(@.name=='ToDeclare')].kind" \"assoc_type\"
+ // @has - "$.index[*][?(@.name=='ToDeclare')].inner.default" null
+ type ToDeclare;
+ // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].kind" \"assoc_const\"
+ // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.default" null
+ const AN_ATTRIBUTE: usize;
+}
+
+impl EasyToImpl for Simple {
+ // @has - "$.index[*][?(@.name=='ToDeclare')].inner.default.kind" \"primitive\"
+ // @has - "$.index[*][?(@.name=='ToDeclare')].inner.default.inner" \"usize\"
+ type ToDeclare = usize;
+ // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.type.kind" \"primitive\"
+ // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.type.inner" \"usize\"
+ // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.default" \"12\"
+ const AN_ATTRIBUTE: usize = 12;
+}
diff --git a/src/test/rustdoc-json/assoc_type.rs b/src/test/rustdoc-json/assoc_type.rs
new file mode 100644
index 00000000000..716bb3d2848
--- /dev/null
+++ b/src/test/rustdoc-json/assoc_type.rs
@@ -0,0 +1,22 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/98547>.
+
+// @has assoc_type.json
+// @has - "$.index[*][?(@.name=='Trait')]"
+// @has - "$.index[*][?(@.name=='AssocType')]"
+// @has - "$.index[*][?(@.name=='S')]"
+// @has - "$.index[*][?(@.name=='S2')]"
+
+pub trait Trait {
+ type AssocType;
+}
+
+impl<T> Trait for T {
+ type AssocType = Self;
+}
+
+pub struct S;
+
+/// Not needed for the #98547 ICE to occur, but added to maximize the chance of
+/// getting an ICE in the future. See
+/// <https://github.com/rust-lang/rust/pull/98548#discussion_r908219164>
+pub struct S2;
diff --git a/src/test/rustdoc-ui/issue-83883-describe-lints.stdout b/src/test/rustdoc-ui/issue-83883-describe-lints.stdout
index 651faf5761f..5cb7ecb649a 100644
--- a/src/test/rustdoc-ui/issue-83883-describe-lints.stdout
+++ b/src/test/rustdoc-ui/issue-83883-describe-lints.stdout
@@ -1,25 +1,193 @@
+ -W allow-features=val -- only allow the listed language features to be enabled in code (space separated)
+ -W always-encode-mir=val -- encode MIR of all functions into the crate metadata (default: no)
+ -W assume-incomplete-release=val -- make cfg(version) treat the current version as incomplete (default: no)
+ -W asm-comments=val -- generate comments into the assembly (may change behavior) (default: no)
+ -W assert-incr-state=val -- assert that the incremental cache is in given state: either `loaded` or `not-loaded`.
+ -W binary-dep-depinfo=val -- include artifacts (sysroot, crate dependencies) used during compilation in dep-info (default: no)
+ -W branch-protection=val -- set options for branch target identification and pointer authentication on AArch64
+ -W cf-protection=val -- instrument control-flow architecture protection
+ -W cgu-partitioning-strategy=val -- the codegen unit partitioning strategy to use
+ -W chalk=val -- enable the experimental Chalk-based trait solving engine
+ -W codegen-backend=val -- the backend to use
+ -W combine-cgu=val -- combine CGUs into a single one
+ -W crate-attr=val -- inject the given attribute in the crate
+ -W debug-info-for-profiling=val -- emit discriminators and other data necessary for AutoFDO
+ -W debug-macros=val -- emit line numbers debug info inside macros (default: no)
+ -W deduplicate-diagnostics=val -- deduplicate identical diagnostics (default: yes)
+ -W dep-info-omit-d-target=val -- in dep-info output, omit targets for tracking dependencies of the dep-info files themselves (default: no)
+ -W dep-tasks=val -- print tasks that execute and the color their dep node gets (requires debug build) (default: no)
+ -W dlltool=val -- import library generation tool (windows-gnu only)
+ -W dont-buffer-diagnostics=val -- emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) (default: no)
+ -W drop-tracking=val -- enables drop tracking in generators (default: no)
+ -W dual-proc-macros=val -- load proc macros for both target and host, but only link to the target (default: no)
+ -W dump-dep-graph=val -- dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) (default: no)
+ -W dump-mir=val -- dump MIR state to file.
+ `val` is used to select which passes and functions to dump. For example:
+ `all` matches all passes and functions,
+ `foo` matches all passes for functions whose name contains 'foo',
+ `foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo',
+ `foo | bar` all passes for function names containing 'foo' or 'bar'.
+ -W dump-mir-dataflow=val -- in addition to `.mir` files, create graphviz `.dot` files with dataflow results (default: no)
+ -W dump-mir-dir=val -- the directory the MIR is dumped into (default: `mir_dump`)
+ -W dump-mir-exclude-pass-number=val -- exclude the pass number when dumping MIR (used in tests) (default: no)
+ -W dump-mir-graphviz=val -- in addition to `.mir` files, create graphviz `.dot` files (and with `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived coverage graph) (default: no)
+ -W dump-mir-spanview=val -- in addition to `.mir` files, create `.html` files to view spans for all `statement`s (including terminators), only `terminator` spans, or computed `block` spans (one span encompassing a block's terminator and all statements). If `-Z instrument-coverage` is also enabled, create an additional `.html` file showing the computed coverage spans.
+ -W emit-stack-sizes=val -- emit a section containing stack size metadata (default: no)
+ -W fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no)
+ -W force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no)
+ -W fuel=val -- set the optimization fuel quota for a crate
+ -W function-sections=val -- whether each function should go in its own section
+ -W future-incompat-test=val -- forces all lints to be future incompatible, used for internal testing (default: no)
+ -W gcc-ld=val -- implementation of ld used by cc
+ -W graphviz-dark-mode=val -- use dark-themed colors in graphviz output (default: no)
+ -W graphviz-font=val -- use the given `fontname` in graphviz output; can be overridden by setting environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)
+ -W hir-stats=val -- print some statistics about AST and HIR (default: no)
+ -W human-readable-cgu-names=val -- generate human-readable, predictable names for codegen units (default: no)
+ -W identify-regions=val -- display unnamed regions as `'<id>`, using a non-ident unique id (default: no)
+ -W incremental-ignore-spans=val -- ignore spans during ICH computation -- used for testing (default: no)
+ -W incremental-info=val -- print high-level information about incremental reuse (or the lack thereof) (default: no)
+ -W incremental-relative-spans=val -- hash spans relative to their parent item for incr. comp. (default: no)
+ -W incremental-verify-ich=val -- verify incr. comp. hashes of green query instances (default: no)
+ -W inline-mir=val -- enable MIR inlining (default: no)
+ -W inline-mir-threshold=val -- a default MIR inlining threshold (default: 50)
+ -W inline-mir-hint-threshold=val -- inlining threshold for functions with inline hint (default: 100)
+ -W inline-in-all-cgus=val -- control whether `#[inline]` functions are in all CGUs
+ -W input-stats=val -- gather statistics about the input (default: no)
+ -W instrument-coverage=val -- instrument the generated code to support LLVM source-based code coverage reports (note, the compiler build config must include `profiler = true`); implies `-C symbol-mangling-version=v0`. Optional values are:
+ `=all` (implicit value)
+ `=except-unused-generics`
+ `=except-unused-functions`
+ `=off` (default)
+ -W instrument-mcount=val -- insert function instrument code for mcount-based tracing (default: no)
+ -W keep-hygiene-data=val -- keep hygiene data after analysis (default: no)
+ -W link-native-libraries=val -- link native libraries in the linker invocation (default: yes)
+ -W link-only=val -- link the `.rlink` file generated by `-Z no-link` (default: no)
+ -W llvm-plugins=val -- a list LLVM plugins to enable (space separated)
+ -W llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no)
+ -W location-detail=val -- comma separated list of location details to be tracked when using caller_location valid options are `file`, `line`, and `column` (default: all)
+ -W ls=val -- list the symbols defined by a library crate (default: no)
+ -W macro-backtrace=val -- show macro backtraces (default: no)
+ -W merge-functions=val -- control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name
+ -W meta-stats=val -- gather metadata statistics (default: no)
+ -W mir-emit-retag=val -- emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no)
+ -W mir-enable-passes=val -- use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be enabled, overriding all other checks. Passes that are not specified are enabled or disabled by other flags as usual.
+ -W mir-opt-level=val -- MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)
+ -W move-size-limit=val -- the size at which the `large_assignments` lint starts to be emitted
+ -W mutable-noalias=val -- emit noalias metadata for mutable references (default: yes)
+ -W new-llvm-pass-manager=val -- use new LLVM pass manager (default: no)
+ -W nll-facts=val -- dump facts from NLL analysis into side files (default: no)
+ -W nll-facts-dir=val -- the directory the NLL facts are dumped into (default: `nll-facts`)
+ -W no-analysis=val -- parse and expand the source, but run no analysis
+ -W no-codegen=val -- run all passes except codegen; no output
+ -W no-generate-arange-section=val -- omit DWARF address ranges that give faster lookups
+ -W no-interleave-lints=val -- execute lints separately; allows benchmarking individual lints
+ -W no-leak-check=val -- disable the 'leak check' for subtyping; unsound, but useful for tests
+ -W no-link=val -- compile without linking
+ -W no-parallel-llvm=val -- run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)
+ -W no-unique-section-names=val -- do not use unique names for text and data sections when -Z function-sections is used
+ -W no-profiler-runtime=val -- prevent automatic injection of the profiler_builtins crate
+ -W normalize-docs=val -- normalize associated items in rustdoc when generating documentation
+ -W oom=val -- panic strategy for out-of-memory handling
+ -W osx-rpath-install-name=val -- pass `-install_name @rpath/...` to the macOS linker (default: no)
+ -W panic-abort-tests=val -- support compiling tests with panic=abort (default: no)
+ -W panic-in-drop=val -- panic strategy for panics in drops
+ -W parse-only=val -- parse only; do not compile, assemble, or link (default: no)
+ -W perf-stats=val -- print some performance-related statistics (default: no)
+ -W pick-stable-methods-before-any-unstable=val -- try to pick stable methods first before picking any unstable methods (default: yes)
+ -W plt=val -- whether to use the PLT when calling into shared libraries;
+ only has effect for PIC code on systems with ELF binaries
+ (default: PLT is disabled if full relro is enabled)
+ -W polonius=val -- enable polonius-based borrow-checker (default: no)
+ -W polymorphize=val -- perform polymorphization analysis
+ -W pre-link-arg=val -- a single extra argument to prepend the linker invocation (can be used several times)
+ -W pre-link-args=val -- extra arguments to prepend to the linker invocation (space separated)
+ -W precise-enum-drop-elaboration=val -- use a more precise version of drop elaboration for matches on enums (default: yes). This results in better codegen, but has caused miscompilations on some tier 2 platforms. See #77382 and #74551.
+ -W print-fuel=val -- make rustc print the total optimization fuel used by a crate
+ -W print-llvm-passes=val -- print the LLVM optimization passes being run (default: no)
+ -W print-mono-items=val -- print the result of the monomorphization collection pass
+ -W print-type-sizes=val -- print layout information for each type encountered (default: no)
+ -W proc-macro-backtrace=val -- show backtraces for panics during proc-macro execution (default: no)
+ -W profile=val -- insert profiling code (default: no)
+ -W profile-closures=val -- profile size of closures
+ -W profile-emit=val -- file path to emit profiling data at runtime when using 'profile' (default based on relative source path)
+ -W profiler-runtime=val -- name of the profiler runtime crate to automatically inject (default: `profiler_builtins`)
+ -W profile-sample-use=val -- use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)
+ -W query-dep-graph=val -- enable queries of the dependency graph for regression testing (default: no)
+ -W randomize-layout=val -- randomize the layout of types (default: no)
+ -W layout-seed=val -- seed layout randomization
+ -W relax-elf-relocations=val -- whether ELF relocations can be relaxed
+ -W relro-level=val -- choose which RELRO level to use
+ -W remap-cwd-prefix=val -- remap paths under the current working directory to this path prefix
+ -W simulate-remapped-rust-src-base=val -- simulate the effect of remap-debuginfo = true at bootstrapping by remapping path to rust's source base directory. only meant for testing purposes
+ -W report-delayed-bugs=val -- immediately print bugs registered with `delay_span_bug` (default: no)
+ -W sanitizer=val -- use a sanitizer
+ -W sanitizer-memory-track-origins=val -- enable origins tracking in MemorySanitizer
+ -W sanitizer-recover=val -- enable recovery for selected sanitizers
+ -W saturating-float-casts=val -- make float->int casts UB-free: numbers outside the integer type's range are clipped to the max/min integer respectively, and NaN is mapped to 0 (default: yes)
+ -W save-analysis=val -- write syntax and type analysis (in JSON format) information, in addition to normal output (default: no)
+ -W self-profile=val -- run the self profiler and output the raw event data
+ -W self-profile-events=val -- specify the events recorded by the self profiler;
+ for example: `-Z self-profile-events=default,query-keys`
+ all options: none, all, default, generic-activity, query-provider, query-cache-hit
+ query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes
+ -W self-profile-counter=val -- counter used by the self profiler (default: `wall-time`), one of:
+ `wall-time` (monotonic clock, i.e. `std::time::Instant`)
+ `instructions:u` (retired instructions, userspace-only)
+ `instructions-minus-irqs:u` (subtracting hardware interrupt counts for extra accuracy)
+ -W share-generics=val -- make the current crate share its generic instantiations
+ -W show-span=val -- show spans for compiler debugging (expr|pat|ty)
+ -W span-debug=val -- forward proc_macro::Span's `Debug` impl to `Span`
+ -W span-free-formats=val -- exclude spans when debug-printing compiler state (default: no)
+ -W src-hash-algorithm=val -- hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)
+ -W stack-protector=val -- control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)
+ -W strict-init-checks=val -- control if mem::uninitialized and mem::zeroed panic on more UB
+ -W strip=val -- tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)
+ -W split-dwarf-kind=val -- split dwarf variant (only if -Csplit-debuginfo is enabled and on relevant platform)
+ (default: `split`)
-Available lint options:
- -W <foo> Warn about <foo>
- -A <foo> Allow <foo>
- -D <foo> Deny <foo>
- -F <foo> Forbid <foo> (deny <foo> and all attempts to override)
-
-
-Lint checks provided by rustc:
-
- $NAMES $LEVELS $MEANINGS
-
-Lint groups provided by rustc:
-
- $NAMES $SUB_LINTS
-
-Lint checks provided by plugins loaded by this crate:
-
- $NAMES $LEVELS $MEANINGS
-
-Lint groups provided by plugins loaded by this crate:
-
- rustdoc::all $GROUPS
-
-
+ `split`: sections which do not require relocation are written into a DWARF object (`.dwo`)
+ file which is ignored by the linker
+ `single`: sections which do not require relocation are written into object file but ignored
+ by the linker
+ -W split-dwarf-inlining=val -- provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF
+ -W symbol-mangling-version=val -- which mangling version to use for symbol names ('legacy' (default) or 'v0')
+ -W teach=val -- show extended diagnostic help (default: no)
+ -W temps-dir=val -- the directory the intermediate files are written to
+ -W terminal-width=val -- set the current terminal width
+ -W translate-lang=val -- language identifier for diagnostic output
+ -W translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation)
+ -W translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics
+ -W tune-cpu=val -- select processor to schedule for (`rustc --print target-cpus` for details)
+ -W thinlto=val -- enable ThinLTO when possible
+ -W thir-unsafeck=val -- use the THIR unsafety checker (default: no)
+ -W threads=val -- use a thread pool with N threads
+ -W time=val -- measure time of rustc processes (default: no)
+ -W time-llvm-passes=val -- measure time of each LLVM pass (default: no)
+ -W time-passes=val -- measure time of each rustc pass (default: no)
+ -W tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details)
+ -W trace-macros=val -- for every macro invocation, print its name and arguments (default: no)
+ -W translate-remapped-path-to-local-path=val -- translate remapped paths into local paths when possible (default: yes)
+ -W trap-unreachable=val -- generate trap instructions for unreachable intrinsics (default: use target setting, usually yes)
+ -W treat-err-as-bug=val -- treat error number `val` that occurs as bug
+ -W trim-diagnostic-paths=val -- in diagnostics, use heuristics to shorten paths referring to items
+ -W ui-testing=val -- emit compiler diagnostics in a form suitable for UI testing (default: no)
+ -W uninit-const-chunk-threshold=val -- allow generating const initializers with mixed init/uninit chunks, and set the maximum number of chunks for which this is allowed (default: 16)
+ -W unleash-the-miri-inside-of-you=val -- take the brakes off const evaluation. NOTE: this is unsound (default: no)
+ -W unpretty=val -- present the input source, unstable (and less-pretty) variants;
+ `normal`, `identified`,
+ `expanded`, `expanded,identified`,
+ `expanded,hygiene` (with internal representations),
+ `ast-tree` (raw AST before expansion),
+ `ast-tree,expanded` (raw AST after expansion),
+ `hir` (the HIR), `hir,identified`,
+ `hir,typed` (HIR with types for each node),
+ `hir-tree` (dump the raw HIR),
+ `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)
+ -W unsound-mir-opts=val -- enable unsound and buggy MIR optimizations (default: no)
+ -W unstable-options=val -- adds unstable command line options to rustc interface (default: no)
+ -W use-ctors-section=val -- use legacy .ctors section for initializers rather than .init_array
+ -W validate-mir=val -- validate MIR after each transformation
+ -W verbose=val -- in general, enable more debug printouts (default: no)
+ -W verify-llvm-ir=val -- verify LLVM IR (default: no)
+ -W virtual-function-elimination=val -- enables dead virtual function elimination optimization. Requires `-Clto[=[fat,yes]]`
+ -W wasi-exec-model=val -- whether to build a wasi command or reactor
diff --git a/src/test/rustdoc/generic_const_exprs.rs b/src/test/rustdoc/generic_const_exprs.rs
new file mode 100644
index 00000000000..6ff59163975
--- /dev/null
+++ b/src/test/rustdoc/generic_const_exprs.rs
@@ -0,0 +1,24 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/92859>.
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+#![crate_name = "foo"]
+
+// @has 'foo/trait.Foo.html'
+
+pub trait Foo: Sized {
+ const WIDTH: usize;
+
+ fn arrayify(self) -> [Self; Self::WIDTH];
+}
+
+impl<T: Sized> Foo for T {
+ const WIDTH: usize = 1;
+
+ // @has - '//*[@id="tymethod.arrayify"]/*[@class="code-header"]' \
+ // 'fn arrayify(self) -> [Self; Self::WIDTH]'
+ fn arrayify(self) -> [Self; Self::WIDTH] {
+ [self]
+ }
+}
diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.rs b/src/test/ui-fulldeps/internal-lints/diagnostics.rs
index 817d8531da9..d6f63d44ba6 100644
--- a/src/test/ui-fulldeps/internal-lints/diagnostics.rs
+++ b/src/test/ui-fulldeps/internal-lints/diagnostics.rs
@@ -16,14 +16,14 @@ use rustc_session::{parse::ParseSess, SessionDiagnostic};
use rustc_span::Span;
#[derive(SessionDiagnostic)]
-#[error(slug = "parser-expect-path")]
+#[error(parser::expect_path)]
struct DeriveSessionDiagnostic {
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
-#[note(slug = "note")]
+#[note(parser::add_paren)]
struct Note {
#[primary_span]
span: Span,
diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
index 84d5de17309..7bec1897fa5 100644
--- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
+++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
@@ -26,15 +26,15 @@ use rustc_errors::Applicability;
extern crate rustc_session;
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "hello-world")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct Hello {}
#[derive(SessionDiagnostic)]
-#[warning(code = "E0123", slug = "hello-world")]
+#[warning(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct HelloWarn {}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
//~^ ERROR `#[derive(SessionDiagnostic)]` can only be used on structs
enum SessionDiagnosticOnEnum {
Foo,
@@ -42,13 +42,13 @@ enum SessionDiagnosticOnEnum {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
#[error = "E0123"]
//~^ ERROR `#[error = ...]` is not a valid attribute
struct WrongStructAttrStyle {}
#[derive(SessionDiagnostic)]
-#[nonsense(code = "E0123", slug = "foo")]
+#[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
//~^ ERROR `#[nonsense(...)]` is not a valid attribute
//~^^ ERROR diagnostic kind not specified
//~^^^ ERROR cannot find attribute `nonsense` in this scope
@@ -57,31 +57,39 @@ struct InvalidStructAttr {}
#[derive(SessionDiagnostic)]
#[error("E0123")]
//~^ ERROR `#[error("...")]` is not a valid attribute
-//~^^ ERROR `slug` not specified
+//~^^ ERROR diagnostic slug not specified
struct InvalidLitNestedAttr {}
#[derive(SessionDiagnostic)]
-#[error(nonsense, code = "E0123", slug = "foo")]
-//~^ ERROR `#[error(nonsense)]` is not a valid attribute
+#[error(nonsense, code = "E0123")]
+//~^ ERROR cannot find value `nonsense` in module `rustc_errors::fluent`
struct InvalidNestedStructAttr {}
#[derive(SessionDiagnostic)]
#[error(nonsense("foo"), code = "E0123", slug = "foo")]
//~^ ERROR `#[error(nonsense(...))]` is not a valid attribute
+//~^^ ERROR diagnostic slug not specified
struct InvalidNestedStructAttr1 {}
#[derive(SessionDiagnostic)]
#[error(nonsense = "...", code = "E0123", slug = "foo")]
//~^ ERROR `#[error(nonsense = ...)]` is not a valid attribute
+//~^^ ERROR diagnostic slug not specified
struct InvalidNestedStructAttr2 {}
#[derive(SessionDiagnostic)]
#[error(nonsense = 4, code = "E0123", slug = "foo")]
//~^ ERROR `#[error(nonsense = ...)]` is not a valid attribute
+//~^^ ERROR diagnostic slug not specified
struct InvalidNestedStructAttr3 {}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
+//~^ ERROR `#[error(slug = ...)]` is not a valid attribute
+struct InvalidNestedStructAttr4 {}
+
+#[derive(SessionDiagnostic)]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct WrongPlaceField {
#[suggestion = "bar"]
//~^ ERROR `#[suggestion = ...]` is not a valid attribute
@@ -89,44 +97,45 @@ struct WrongPlaceField {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
-#[error(code = "E0456", slug = "bar")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
//~^ ERROR specified multiple times
//~^^ ERROR specified multiple times
//~^^^ ERROR specified multiple times
struct ErrorSpecifiedTwice {}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
-#[warning(code = "E0293", slug = "bar")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
//~^ ERROR specified multiple times
//~^^ ERROR specified multiple times
//~^^^ ERROR specified multiple times
struct WarnSpecifiedAfterError {}
#[derive(SessionDiagnostic)]
-#[error(code = "E0456", code = "E0457", slug = "bar")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
//~^ ERROR specified multiple times
struct CodeSpecifiedTwice {}
#[derive(SessionDiagnostic)]
-#[error(code = "E0456", slug = "foo", slug = "bar")]
-//~^ ERROR specified multiple times
+#[error(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")]
+//~^ ERROR `#[error(typeck::ambiguous_lifetime_bound)]` is not a valid attribute
struct SlugSpecifiedTwice {}
#[derive(SessionDiagnostic)]
struct KindNotProvided {} //~ ERROR diagnostic kind not specified
#[derive(SessionDiagnostic)]
-#[error(code = "E0456")] //~ ERROR `slug` not specified
+#[error(code = "E0456")]
+//~^ ERROR diagnostic slug not specified
struct SlugNotProvided {}
#[derive(SessionDiagnostic)]
-#[error(slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound)]
struct CodeNotProvided {}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct MessageWrongType {
#[primary_span]
//~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span`
@@ -134,7 +143,7 @@ struct MessageWrongType {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct InvalidPathFieldAttr {
#[nonsense]
//~^ ERROR `#[nonsense]` is not a valid attribute
@@ -143,34 +152,34 @@ struct InvalidPathFieldAttr {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithField {
name: String,
- #[label = "bar"]
+ #[label(typeck::label)]
span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithMessageAppliedToField {
- #[label = "bar"]
- //~^ ERROR the `#[label = ...]` attribute can only be applied to fields of type `Span`
+ #[label(typeck::label)]
+ //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span`
name: String,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithNonexistentField {
- #[suggestion(message = "bar", code = "{name}")]
+ #[suggestion(typeck::suggestion, code = "{name}")]
//~^ ERROR `name` doesn't refer to a field on this type
suggestion: (Span, Applicability),
}
#[derive(SessionDiagnostic)]
//~^ ERROR invalid format string: expected `'}'`
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorMissingClosingBrace {
- #[suggestion(message = "bar", code = "{name")]
+ #[suggestion(typeck::suggestion, code = "{name")]
suggestion: (Span, Applicability),
name: String,
val: usize,
@@ -178,48 +187,48 @@ struct ErrorMissingClosingBrace {
#[derive(SessionDiagnostic)]
//~^ ERROR invalid format string: unmatched `}`
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorMissingOpeningBrace {
- #[suggestion(message = "bar", code = "name}")]
+ #[suggestion(typeck::suggestion, code = "name}")]
suggestion: (Span, Applicability),
name: String,
val: usize,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct LabelOnSpan {
- #[label = "bar"]
+ #[label(typeck::label)]
sp: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct LabelOnNonSpan {
- #[label = "bar"]
- //~^ ERROR the `#[label = ...]` attribute can only be applied to fields of type `Span`
+ #[label(typeck::label)]
+ //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span`
id: u32,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct Suggest {
- #[suggestion(message = "bar", code = "This is the suggested code")]
- #[suggestion_short(message = "qux", code = "This is the suggested code")]
- #[suggestion_hidden(message = "foobar", code = "This is the suggested code")]
- #[suggestion_verbose(message = "fooqux", code = "This is the suggested code")]
+ #[suggestion(typeck::suggestion, code = "This is the suggested code")]
+ #[suggestion_short(typeck::suggestion, code = "This is the suggested code")]
+ #[suggestion_hidden(typeck::suggestion, code = "This is the suggested code")]
+ #[suggestion_verbose(typeck::suggestion, code = "This is the suggested code")]
suggestion: (Span, Applicability),
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithoutCode {
- #[suggestion(message = "bar")]
+ #[suggestion(typeck::suggestion)]
suggestion: (Span, Applicability),
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithBadKey {
#[suggestion(nonsense = "bar")]
//~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid attribute
@@ -227,7 +236,7 @@ struct SuggestWithBadKey {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithShorthandMsg {
#[suggestion(msg = "bar")]
//~^ ERROR `#[suggestion(msg = ...)]` is not a valid attribute
@@ -235,91 +244,91 @@ struct SuggestWithShorthandMsg {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithoutMsg {
#[suggestion(code = "bar")]
suggestion: (Span, Applicability),
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithTypesSwapped {
- #[suggestion(message = "bar", code = "This is suggested code")]
+ #[suggestion(typeck::suggestion, code = "This is suggested code")]
suggestion: (Applicability, Span),
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithWrongTypeApplicabilityOnly {
- #[suggestion(message = "bar", code = "This is suggested code")]
+ #[suggestion(typeck::suggestion, code = "This is suggested code")]
//~^ ERROR wrong field type for suggestion
suggestion: Applicability,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithSpanOnly {
- #[suggestion(message = "bar", code = "This is suggested code")]
+ #[suggestion(typeck::suggestion, code = "This is suggested code")]
suggestion: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithDuplicateSpanAndApplicability {
- #[suggestion(message = "bar", code = "This is suggested code")]
+ #[suggestion(typeck::suggestion, code = "This is suggested code")]
//~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one `Span`
suggestion: (Span, Span, Applicability),
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct SuggestWithDuplicateApplicabilityAndSpan {
- #[suggestion(message = "bar", code = "This is suggested code")]
+ #[suggestion(typeck::suggestion, code = "This is suggested code")]
//~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one
suggestion: (Applicability, Applicability, Span),
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct WrongKindOfAnnotation {
- #[label("bar")]
- //~^ ERROR `#[label(...)]` is not a valid attribute
+ #[label = "bar"]
+ //~^ ERROR `#[label = ...]` is not a valid attribute
z: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct OptionsInErrors {
- #[label = "bar"]
+ #[label(typeck::label)]
label: Option<Span>,
- #[suggestion(message = "bar")]
+ #[suggestion(typeck::suggestion)]
opt_sugg: Option<(Span, Applicability)>,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0456", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
struct MoveOutOfBorrowError<'tcx> {
name: Ident,
ty: Ty<'tcx>,
#[primary_span]
- #[label = "bar"]
+ #[label(typeck::label)]
span: Span,
- #[label = "qux"]
+ #[label(typeck::label)]
other_span: Span,
- #[suggestion(message = "bar", code = "{name}.clone()")]
+ #[suggestion(typeck::suggestion, code = "{name}.clone()")]
opt_sugg: Option<(Span, Applicability)>,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithLifetime<'a> {
- #[label = "bar"]
+ #[label(typeck::label)]
span: Span,
name: &'a str,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithDefaultLabelAttr<'a> {
#[label]
span: Span,
@@ -328,7 +337,7 @@ struct ErrorWithDefaultLabelAttr<'a> {
#[derive(SessionDiagnostic)]
//~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ArgFieldWithoutSkip {
#[primary_span]
span: Span,
@@ -336,7 +345,7 @@ struct ArgFieldWithoutSkip {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ArgFieldWithSkip {
#[primary_span]
span: Span,
@@ -347,132 +356,132 @@ struct ArgFieldWithSkip {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithSpannedNote {
#[note]
span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithSpannedNoteCustom {
- #[note = "bar"]
+ #[note(typeck::note)]
span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
#[note]
struct ErrorWithNote {
val: String,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
-#[note = "bar"]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[note(typeck::note)]
struct ErrorWithNoteCustom {
val: String,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithSpannedHelp {
#[help]
span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithSpannedHelpCustom {
- #[help = "bar"]
+ #[help(typeck::help)]
span: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
#[help]
struct ErrorWithHelp {
val: String,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
-#[help = "bar"]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[help(typeck::help)]
struct ErrorWithHelpCustom {
val: String,
}
#[derive(SessionDiagnostic)]
#[help]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithHelpWrongOrder {
val: String,
}
#[derive(SessionDiagnostic)]
-#[help = "bar"]
-#[error(code = "E0123", slug = "foo")]
+#[help(typeck::help)]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithHelpCustomWrongOrder {
val: String,
}
#[derive(SessionDiagnostic)]
#[note]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithNoteWrongOrder {
val: String,
}
#[derive(SessionDiagnostic)]
-#[note = "bar"]
-#[error(code = "E0123", slug = "foo")]
+#[note(typeck::note)]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ErrorWithNoteCustomWrongOrder {
val: String,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ApplicabilityInBoth {
- #[suggestion(message = "bar", code = "...", applicability = "maybe-incorrect")]
+ #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
//~^ ERROR applicability cannot be set in both the field and attribute
suggestion: (Span, Applicability),
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct InvalidApplicability {
- #[suggestion(message = "bar", code = "...", applicability = "batman")]
+ #[suggestion(typeck::suggestion, code = "...", applicability = "batman")]
//~^ ERROR invalid applicability
suggestion: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ValidApplicability {
- #[suggestion(message = "bar", code = "...", applicability = "maybe-incorrect")]
+ #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
suggestion: Span,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct NoApplicability {
- #[suggestion(message = "bar", code = "...")]
+ #[suggestion(typeck::suggestion, code = "...")]
suggestion: Span,
}
#[derive(SessionSubdiagnostic)]
-#[note(slug = "note")]
+#[note(parser::add_paren)]
struct Note;
#[derive(SessionDiagnostic)]
-#[error(slug = "subdiagnostic")]
+#[error(typeck::ambiguous_lifetime_bound)]
struct Subdiagnostic {
#[subdiagnostic]
note: Note,
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct VecField {
#[primary_span]
#[label]
@@ -480,23 +489,47 @@ struct VecField {
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct UnitField {
#[primary_span]
spans: Span,
#[help]
foo: (),
- #[help = "a"]
+ #[help(typeck::help)]
bar: (),
}
#[derive(SessionDiagnostic)]
-#[error(code = "E0123", slug = "foo")]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct OptUnitField {
#[primary_span]
spans: Span,
#[help]
foo: Option<()>,
- #[help = "a"]
+ #[help(typeck::help)]
bar: Option<()>,
}
+
+#[derive(SessionDiagnostic)]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+struct LabelWithTrailingPath {
+ #[label(typeck::label, foo)]
+ //~^ ERROR `#[label(...)]` is not a valid attribute
+ span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+struct LabelWithTrailingNameValue {
+ #[label(typeck::label, foo = "...")]
+ //~^ ERROR `#[label(...)]` is not a valid attribute
+ span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+struct LabelWithTrailingList {
+ #[label(typeck::label, foo("..."))]
+ //~^ ERROR `#[label(...)]` is not a valid attribute
+ span: Span,
+}
diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
index 85ea44ec278..0d9690e1f5a 100644
--- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
+++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
@@ -1,7 +1,7 @@
error: `#[derive(SessionDiagnostic)]` can only be used on structs
--> $DIR/diagnostic-derive.rs:37:1
|
-LL | / #[error(code = "E0123", slug = "foo")]
+LL | / #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
LL | |
LL | | enum SessionDiagnosticOnEnum {
LL | | Foo,
@@ -18,15 +18,15 @@ LL | #[error = "E0123"]
error: `#[nonsense(...)]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:51:1
|
-LL | #[nonsense(code = "E0123", slug = "foo")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = help: only `error` and `warning` are valid attributes
+ = help: only `error`, `warning`, `help` and `note` are valid attributes
error: diagnostic kind not specified
--> $DIR/diagnostic-derive.rs:51:1
|
-LL | / #[nonsense(code = "E0123", slug = "foo")]
+LL | / #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
LL | |
LL | |
LL | |
@@ -40,8 +40,10 @@ error: `#[error("...")]` is not a valid attribute
|
LL | #[error("E0123")]
| ^^^^^^^
+ |
+ = help: first argument of the attribute should be the diagnostic slug
-error: `slug` not specified
+error: diagnostic slug not specified
--> $DIR/diagnostic-derive.rs:58:1
|
LL | / #[error("E0123")]
@@ -50,183 +52,215 @@ LL | |
LL | | struct InvalidLitNestedAttr {}
| |______________________________^
|
- = help: use the `#[error(slug = "...")]` attribute to set this diagnostic's slug
-
-error: `#[error(nonsense)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:64:9
- |
-LL | #[error(nonsense, code = "E0123", slug = "foo")]
- | ^^^^^^^^
+ = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
error: `#[error(nonsense(...))]` is not a valid attribute
--> $DIR/diagnostic-derive.rs:69:9
|
LL | #[error(nonsense("foo"), code = "E0123", slug = "foo")]
| ^^^^^^^^^^^^^^^
+ |
+ = help: first argument of the attribute should be the diagnostic slug
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:69:1
+ |
+LL | / #[error(nonsense("foo"), code = "E0123", slug = "foo")]
+LL | |
+LL | |
+LL | | struct InvalidNestedStructAttr1 {}
+ | |__________________________________^
+ |
+ = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
error: `#[error(nonsense = ...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:74:9
+ --> $DIR/diagnostic-derive.rs:75:9
|
LL | #[error(nonsense = "...", code = "E0123", slug = "foo")]
| ^^^^^^^^^^^^^^^^
|
- = help: only `slug` and `code` are valid nested attributes
+ = help: first argument of the attribute should be the diagnostic slug
+
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:75:1
+ |
+LL | / #[error(nonsense = "...", code = "E0123", slug = "foo")]
+LL | |
+LL | |
+LL | | struct InvalidNestedStructAttr2 {}
+ | |__________________________________^
+ |
+ = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
error: `#[error(nonsense = ...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:79:9
+ --> $DIR/diagnostic-derive.rs:81:9
|
LL | #[error(nonsense = 4, code = "E0123", slug = "foo")]
| ^^^^^^^^^^^^
+ |
+ = help: first argument of the attribute should be the diagnostic slug
-error: `#[suggestion = ...]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:86:5
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:81:1
|
-LL | #[suggestion = "bar"]
- | ^^^^^^^^^^^^^^^^^^^^^
+LL | / #[error(nonsense = 4, code = "E0123", slug = "foo")]
+LL | |
+LL | |
+LL | | struct InvalidNestedStructAttr3 {}
+ | |__________________________________^
|
- = help: only `label`, `note` and `help` are valid field attributes
+ = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
-error: specified multiple times
- --> $DIR/diagnostic-derive.rs:93:1
+error: `#[error(slug = ...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:87:59
|
-LL | #[error(code = "E0456", slug = "bar")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
+ | ^^^^^^^^^^^^
|
-note: previously specified here
- --> $DIR/diagnostic-derive.rs:92:1
+ = help: only `code` is a valid nested attributes following the slug
+
+error: `#[suggestion = ...]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:94:5
|
-LL | #[error(code = "E0123", slug = "foo")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[suggestion = "bar"]
+ | ^^^^^^^^^^^^^^^^^^^^^
error: specified multiple times
- --> $DIR/diagnostic-derive.rs:93:16
+ --> $DIR/diagnostic-derive.rs:101:1
|
-LL | #[error(code = "E0456", slug = "bar")]
- | ^^^^^^^
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/diagnostic-derive.rs:92:16
+ --> $DIR/diagnostic-derive.rs:100:1
|
-LL | #[error(code = "E0123", slug = "foo")]
- | ^^^^^^^
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: specified multiple times
- --> $DIR/diagnostic-derive.rs:93:32
+ --> $DIR/diagnostic-derive.rs:101:1
|
-LL | #[error(code = "E0456", slug = "bar")]
- | ^^^^^
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/diagnostic-derive.rs:92:32
+ --> $DIR/diagnostic-derive.rs:100:1
|
-LL | #[error(code = "E0123", slug = "foo")]
- | ^^^^^
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: specified multiple times
- --> $DIR/diagnostic-derive.rs:101:1
+ --> $DIR/diagnostic-derive.rs:101:50
|
-LL | #[warning(code = "E0293", slug = "bar")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
+ | ^^^^^^^
|
note: previously specified here
- --> $DIR/diagnostic-derive.rs:100:1
+ --> $DIR/diagnostic-derive.rs:100:50
|
-LL | #[error(code = "E0123", slug = "foo")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^^^
error: specified multiple times
- --> $DIR/diagnostic-derive.rs:101:18
+ --> $DIR/diagnostic-derive.rs:109:1
|
-LL | #[warning(code = "E0293", slug = "bar")]
- | ^^^^^^^
+LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/diagnostic-derive.rs:100:16
+ --> $DIR/diagnostic-derive.rs:108:1
|
-LL | #[error(code = "E0123", slug = "foo")]
- | ^^^^^^^
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: specified multiple times
- --> $DIR/diagnostic-derive.rs:101:34
+ --> $DIR/diagnostic-derive.rs:109:1
|
-LL | #[warning(code = "E0293", slug = "bar")]
- | ^^^^^
+LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/diagnostic-derive.rs:100:32
+ --> $DIR/diagnostic-derive.rs:108:1
|
-LL | #[error(code = "E0123", slug = "foo")]
- | ^^^^^
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: specified multiple times
- --> $DIR/diagnostic-derive.rs:108:32
+ --> $DIR/diagnostic-derive.rs:109:52
|
-LL | #[error(code = "E0456", code = "E0457", slug = "bar")]
- | ^^^^^^^
+LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
+ | ^^^^^^^
|
note: previously specified here
- --> $DIR/diagnostic-derive.rs:108:16
+ --> $DIR/diagnostic-derive.rs:108:50
|
-LL | #[error(code = "E0456", code = "E0457", slug = "bar")]
- | ^^^^^^^
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+ | ^^^^^^^
error: specified multiple times
- --> $DIR/diagnostic-derive.rs:113:46
+ --> $DIR/diagnostic-derive.rs:116:66
|
-LL | #[error(code = "E0456", slug = "foo", slug = "bar")]
- | ^^^^^
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
+ | ^^^^^^^
|
note: previously specified here
- --> $DIR/diagnostic-derive.rs:113:32
+ --> $DIR/diagnostic-derive.rs:116:50
|
-LL | #[error(code = "E0456", slug = "foo", slug = "bar")]
- | ^^^^^
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
+ | ^^^^^^^
+
+error: `#[error(typeck::ambiguous_lifetime_bound)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:121:43
+ |
+LL | #[error(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: diagnostic kind not specified
- --> $DIR/diagnostic-derive.rs:118:1
+ --> $DIR/diagnostic-derive.rs:126:1
|
LL | struct KindNotProvided {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: use the `#[error(...)]` attribute to create an error
-error: `slug` not specified
- --> $DIR/diagnostic-derive.rs:121:1
+error: diagnostic slug not specified
+ --> $DIR/diagnostic-derive.rs:129:1
|
LL | / #[error(code = "E0456")]
+LL | |
LL | | struct SlugNotProvided {}
| |_________________________^
|
- = help: use the `#[error(slug = "...")]` attribute to set this diagnostic's slug
+ = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
error: the `#[primary_span]` attribute can only be applied to fields of type `Span`
- --> $DIR/diagnostic-derive.rs:131:5
+ --> $DIR/diagnostic-derive.rs:140:5
|
LL | #[primary_span]
| ^^^^^^^^^^^^^^^
error: `#[nonsense]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:139:5
+ --> $DIR/diagnostic-derive.rs:148:5
|
LL | #[nonsense]
| ^^^^^^^^^^^
|
= help: only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` are valid field attributes
-error: the `#[label = ...]` attribute can only be applied to fields of type `Span`
- --> $DIR/diagnostic-derive.rs:156:5
+error: the `#[label(...)]` attribute can only be applied to fields of type `Span`
+ --> $DIR/diagnostic-derive.rs:165:5
|
-LL | #[label = "bar"]
- | ^^^^^^^^^^^^^^^^
+LL | #[label(typeck::label)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
error: `name` doesn't refer to a field on this type
- --> $DIR/diagnostic-derive.rs:164:42
+ --> $DIR/diagnostic-derive.rs:173:45
|
-LL | #[suggestion(message = "bar", code = "{name}")]
- | ^^^^^^^^
+LL | #[suggestion(typeck::suggestion, code = "{name}")]
+ | ^^^^^^^^
error: invalid format string: expected `'}'` but string was terminated
- --> $DIR/diagnostic-derive.rs:169:16
+ --> $DIR/diagnostic-derive.rs:178:16
|
LL | #[derive(SessionDiagnostic)]
| - ^ expected `'}'` in format string
@@ -237,7 +271,7 @@ LL | #[derive(SessionDiagnostic)]
= note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: invalid format string: unmatched `}` found
- --> $DIR/diagnostic-derive.rs:179:15
+ --> $DIR/diagnostic-derive.rs:188:15
|
LL | #[derive(SessionDiagnostic)]
| ^ unmatched `}` in format string
@@ -245,14 +279,14 @@ LL | #[derive(SessionDiagnostic)]
= note: if you intended to print `}`, you can escape it using `}}`
= note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: the `#[label = ...]` attribute can only be applied to fields of type `Span`
- --> $DIR/diagnostic-derive.rs:199:5
+error: the `#[label(...)]` attribute can only be applied to fields of type `Span`
+ --> $DIR/diagnostic-derive.rs:208:5
|
-LL | #[label = "bar"]
- | ^^^^^^^^^^^^^^^^
+LL | #[label(typeck::label)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
error: `#[suggestion(nonsense = ...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:224:18
+ --> $DIR/diagnostic-derive.rs:233:18
|
LL | #[suggestion(nonsense = "bar")]
| ^^^^^^^^^^^^^^^^
@@ -260,7 +294,7 @@ LL | #[suggestion(nonsense = "bar")]
= help: only `message`, `code` and `applicability` are valid field attributes
error: `#[suggestion(msg = ...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:232:18
+ --> $DIR/diagnostic-derive.rs:241:18
|
LL | #[suggestion(msg = "bar")]
| ^^^^^^^^^^^
@@ -268,9 +302,9 @@ LL | #[suggestion(msg = "bar")]
= help: only `message`, `code` and `applicability` are valid field attributes
error: wrong field type for suggestion
- --> $DIR/diagnostic-derive.rs:254:5
+ --> $DIR/diagnostic-derive.rs:263:5
|
-LL | / #[suggestion(message = "bar", code = "This is suggested code")]
+LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")]
LL | |
LL | | suggestion: Applicability,
| |_____________________________^
@@ -278,55 +312,77 @@ LL | | suggestion: Applicability,
= help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)`
error: type of field annotated with `#[suggestion(...)]` contains more than one `Span`
- --> $DIR/diagnostic-derive.rs:269:5
+ --> $DIR/diagnostic-derive.rs:278:5
|
-LL | / #[suggestion(message = "bar", code = "This is suggested code")]
+LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")]
LL | |
LL | | suggestion: (Span, Span, Applicability),
| |___________________________________________^
error: type of field annotated with `#[suggestion(...)]` contains more than one Applicability
- --> $DIR/diagnostic-derive.rs:277:5
+ --> $DIR/diagnostic-derive.rs:286:5
|
-LL | / #[suggestion(message = "bar", code = "This is suggested code")]
+LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")]
LL | |
LL | | suggestion: (Applicability, Applicability, Span),
| |____________________________________________________^
-error: `#[label(...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:285:5
- |
-LL | #[label("bar")]
- | ^^^^^^^^^^^^^^^
+error: `#[label = ...]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:294:5
|
- = help: only `suggestion{,_short,_hidden,_verbose}` are valid field attributes
+LL | #[label = "bar"]
+ | ^^^^^^^^^^^^^^^^
error: applicability cannot be set in both the field and attribute
- --> $DIR/diagnostic-derive.rs:436:49
+ --> $DIR/diagnostic-derive.rs:445:52
|
-LL | #[suggestion(message = "bar", code = "...", applicability = "maybe-incorrect")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: invalid applicability
- --> $DIR/diagnostic-derive.rs:444:49
+ --> $DIR/diagnostic-derive.rs:453:52
+ |
+LL | #[suggestion(typeck::suggestion, code = "...", applicability = "batman")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[label(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:516:5
+ |
+LL | #[label(typeck::label, foo)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[label(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:524:5
+ |
+LL | #[label(typeck::label, foo = "...")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[label(...)]` is not a valid attribute
+ --> $DIR/diagnostic-derive.rs:532:5
|
-LL | #[suggestion(message = "bar", code = "...", applicability = "batman")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[label(typeck::label, foo("..."))]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: cannot find attribute `nonsense` in this scope
--> $DIR/diagnostic-derive.rs:51:3
|
-LL | #[nonsense(code = "E0123", slug = "foo")]
+LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
| ^^^^^^^^
error: cannot find attribute `nonsense` in this scope
- --> $DIR/diagnostic-derive.rs:139:7
+ --> $DIR/diagnostic-derive.rs:148:7
|
LL | #[nonsense]
| ^^^^^^^^
+error[E0425]: cannot find value `nonsense` in module `rustc_errors::fluent`
+ --> $DIR/diagnostic-derive.rs:64:9
+ |
+LL | #[error(nonsense, code = "E0123")]
+ | ^^^^^^^^ not found in `rustc_errors::fluent`
+
error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied
- --> $DIR/diagnostic-derive.rs:329:10
+ --> $DIR/diagnostic-derive.rs:338:10
|
LL | #[derive(SessionDiagnostic)]
| ^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello`
@@ -345,6 +401,7 @@ LL | arg: impl IntoDiagnosticArg,
| ^^^^^^^^^^^^^^^^^ required by this bound in `DiagnosticBuilder::<'a, G>::set_arg`
= note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: aborting due to 39 previous errors
+error: aborting due to 46 previous errors
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0277, E0425.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
index bb406c35c0e..6f4b6105b3e 100644
--- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
+++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
@@ -20,7 +20,7 @@ use rustc_span::Span;
use rustc_macros::SessionSubdiagnostic;
#[derive(SessionSubdiagnostic)]
-#[label(slug = "label-a")]
+#[label(parser::add_paren)]
struct A {
#[primary_span]
span: Span,
@@ -29,13 +29,13 @@ struct A {
#[derive(SessionSubdiagnostic)]
enum B {
- #[label(slug = "label-b-a")]
+ #[label(parser::add_paren)]
A {
#[primary_span]
span: Span,
var: String,
},
- #[label(slug = "label-b-b")]
+ #[label(parser::add_paren)]
B {
#[primary_span]
span: Span,
@@ -44,7 +44,7 @@ enum B {
}
#[derive(SessionSubdiagnostic)]
-#[label(slug = "label-c")]
+#[label(parser::add_paren)]
//~^ ERROR label without `#[primary_span]` field
struct C {
var: String,
@@ -116,7 +116,8 @@ struct K {
#[derive(SessionSubdiagnostic)]
#[label(slug)]
-//~^ ERROR `#[label(slug)]` is not a valid attribute
+//~^ ERROR cannot find value `slug` in module `rustc_errors::fluent`
+//~^^ NOTE not found in `rustc_errors::fluent`
struct L {
#[primary_span]
span: Span,
@@ -125,7 +126,7 @@ struct L {
#[derive(SessionSubdiagnostic)]
#[label()]
-//~^ ERROR `slug` must be set in a `#[label(...)]` attribute
+//~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute
struct M {
#[primary_span]
span: Span,
@@ -133,7 +134,7 @@ struct M {
}
#[derive(SessionSubdiagnostic)]
-#[label(code = "...")]
+#[label(parser::add_paren, code = "...")]
//~^ ERROR `code` is not a valid nested attribute of a `label` attribute
struct N {
#[primary_span]
@@ -142,11 +143,20 @@ struct N {
}
#[derive(SessionSubdiagnostic)]
+#[label(parser::add_paren, applicability = "machine-applicable")]
+//~^ ERROR `applicability` is not a valid nested attribute of a `label` attribute
+struct O {
+ #[primary_span]
+ span: Span,
+ var: String,
+}
+
+#[derive(SessionSubdiagnostic)]
#[foo]
//~^ ERROR cannot find attribute `foo` in this scope
//~^^ ERROR unsupported type attribute for subdiagnostic enum
-enum O {
- #[label(slug = "...")]
+enum P {
+ #[label(parser::add_paren)]
A {
#[primary_span]
span: Span,
@@ -155,7 +165,7 @@ enum O {
}
#[derive(SessionSubdiagnostic)]
-enum P {
+enum Q {
#[bar]
//~^ ERROR `#[bar]` is not a valid attribute
//~^^ ERROR cannot find attribute `bar` in this scope
@@ -167,7 +177,7 @@ enum P {
}
#[derive(SessionSubdiagnostic)]
-enum Q {
+enum R {
#[bar = "..."]
//~^ ERROR `#[bar = ...]` is not a valid attribute
//~^^ ERROR cannot find attribute `bar` in this scope
@@ -179,7 +189,7 @@ enum Q {
}
#[derive(SessionSubdiagnostic)]
-enum R {
+enum S {
#[bar = 4]
//~^ ERROR `#[bar = ...]` is not a valid attribute
//~^^ ERROR cannot find attribute `bar` in this scope
@@ -191,7 +201,7 @@ enum R {
}
#[derive(SessionSubdiagnostic)]
-enum S {
+enum T {
#[bar("...")]
//~^ ERROR `#[bar("...")]` is not a valid attribute
//~^^ ERROR cannot find attribute `bar` in this scope
@@ -203,9 +213,9 @@ enum S {
}
#[derive(SessionSubdiagnostic)]
-enum T {
+enum U {
#[label(code = "...")]
-//~^ ERROR `code` is not a valid nested attribute of a `label`
+//~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute
A {
#[primary_span]
span: Span,
@@ -214,8 +224,8 @@ enum T {
}
#[derive(SessionSubdiagnostic)]
-enum U {
- #[label(slug = "label-u")]
+enum V {
+ #[label(parser::add_paren)]
A {
#[primary_span]
span: Span,
@@ -230,17 +240,17 @@ enum U {
}
#[derive(SessionSubdiagnostic)]
-#[label(slug = "...")]
+#[label(parser::add_paren)]
//~^ ERROR label without `#[primary_span]` field
-struct V {
+struct W {
#[primary_span]
//~^ ERROR the `#[primary_span]` attribute can only be applied to fields of type `Span`
span: String,
}
#[derive(SessionSubdiagnostic)]
-#[label(slug = "...")]
-struct W {
+#[label(parser::add_paren)]
+struct X {
#[primary_span]
span: Span,
#[applicability]
@@ -249,8 +259,8 @@ struct W {
}
#[derive(SessionSubdiagnostic)]
-#[label(slug = "...")]
-struct X {
+#[label(parser::add_paren)]
+struct Y {
#[primary_span]
span: Span,
#[bar]
@@ -260,8 +270,8 @@ struct X {
}
#[derive(SessionSubdiagnostic)]
-#[label(slug = "...")]
-struct Y {
+#[label(parser::add_paren)]
+struct Z {
#[primary_span]
span: Span,
#[bar = "..."]
@@ -271,8 +281,8 @@ struct Y {
}
#[derive(SessionSubdiagnostic)]
-#[label(slug = "...")]
-struct Z {
+#[label(parser::add_paren)]
+struct AA {
#[primary_span]
span: Span,
#[bar("...")]
@@ -282,8 +292,8 @@ struct Z {
}
#[derive(SessionSubdiagnostic)]
-#[label(slug = "label-aa")]
-struct AA {
+#[label(parser::add_paren)]
+struct AB {
#[primary_span]
span: Span,
#[skip_arg]
@@ -291,36 +301,35 @@ struct AA {
}
#[derive(SessionSubdiagnostic)]
-union AB {
+union AC {
//~^ ERROR unexpected unsupported untagged union
span: u32,
b: u64
}
#[derive(SessionSubdiagnostic)]
-#[label(slug = "label-ac-1")]
+#[label(parser::add_paren)]
//~^ NOTE previously specified here
//~^^ NOTE previously specified here
-#[label(slug = "label-ac-2")]
+#[label(parser::add_paren)]
//~^ ERROR specified multiple times
//~^^ ERROR specified multiple times
-struct AC {
+struct AD {
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
-#[label(slug = "label-ad-1", slug = "label-ad-2")]
-//~^ ERROR specified multiple times
-//~^^ NOTE previously specified here
-struct AD {
+#[label(parser::add_paren, parser::add_paren)]
+//~^ ERROR `#[label(parser::add_paren)]` is not a valid attribute
+struct AE {
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
-#[label(slug = "label-ad-1")]
-struct AE {
+#[label(parser::add_paren)]
+struct AF {
#[primary_span]
//~^ NOTE previously specified here
span_a: Span,
@@ -330,15 +339,15 @@ struct AE {
}
#[derive(SessionSubdiagnostic)]
-struct AF {
+struct AG {
//~^ ERROR subdiagnostic kind not specified
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
-#[suggestion(slug = "suggestion-af", code = "...")]
-struct AG {
+#[suggestion(parser::add_paren, code = "...")]
+struct AH {
#[primary_span]
span: Span,
#[applicability]
@@ -347,8 +356,8 @@ struct AG {
}
#[derive(SessionSubdiagnostic)]
-enum AH {
- #[suggestion(slug = "suggestion-ag-a", code = "...")]
+enum AI {
+ #[suggestion(parser::add_paren, code = "...")]
A {
#[primary_span]
span: Span,
@@ -356,7 +365,7 @@ enum AH {
applicability: Applicability,
var: String,
},
- #[suggestion(slug = "suggestion-ag-b", code = "...")]
+ #[suggestion(parser::add_paren, code = "...")]
B {
#[primary_span]
span: Span,
@@ -367,10 +376,10 @@ enum AH {
}
#[derive(SessionSubdiagnostic)]
-#[suggestion(slug = "...", code = "...", code = "...")]
+#[suggestion(parser::add_paren, code = "...", code = "...")]
//~^ ERROR specified multiple times
//~^^ NOTE previously specified here
-struct AI {
+struct AJ {
#[primary_span]
span: Span,
#[applicability]
@@ -378,8 +387,8 @@ struct AI {
}
#[derive(SessionSubdiagnostic)]
-#[suggestion(slug = "...", code = "...")]
-struct AJ {
+#[suggestion(parser::add_paren, code = "...")]
+struct AK {
#[primary_span]
span: Span,
#[applicability]
@@ -391,9 +400,9 @@ struct AJ {
}
#[derive(SessionSubdiagnostic)]
-#[suggestion(slug = "...", code = "...")]
+#[suggestion(parser::add_paren, code = "...")]
//~^ ERROR suggestion without `applicability`
-struct AK {
+struct AL {
#[primary_span]
span: Span,
#[applicability]
@@ -402,17 +411,17 @@ struct AK {
}
#[derive(SessionSubdiagnostic)]
-#[suggestion(slug = "...", code = "...")]
+#[suggestion(parser::add_paren, code = "...")]
//~^ ERROR suggestion without `applicability`
-struct AL {
+struct AM {
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
-#[suggestion(slug = "...")]
+#[suggestion(parser::add_paren)]
//~^ ERROR suggestion without `code = "..."`
-struct AM {
+struct AN {
#[primary_span]
span: Span,
#[applicability]
@@ -420,34 +429,34 @@ struct AM {
}
#[derive(SessionSubdiagnostic)]
-#[suggestion(slug = "...", code ="...", applicability = "foo")]
+#[suggestion(parser::add_paren, code ="...", applicability = "foo")]
//~^ ERROR invalid applicability
-struct AN {
+struct AO {
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
-#[help(slug = "label-am")]
-struct AO {
+#[help(parser::add_paren)]
+struct AP {
var: String
}
#[derive(SessionSubdiagnostic)]
-#[note(slug = "label-an")]
-struct AP;
+#[note(parser::add_paren)]
+struct AQ;
#[derive(SessionSubdiagnostic)]
-#[suggestion(slug = "...", code = "...")]
+#[suggestion(parser::add_paren, code = "...")]
//~^ ERROR suggestion without `applicability`
//~^^ ERROR suggestion without `#[primary_span]` field
-struct AQ {
+struct AR {
var: String,
}
#[derive(SessionSubdiagnostic)]
-#[suggestion(slug = "...", code ="...", applicability = "machine-applicable")]
-struct AR {
+#[suggestion(parser::add_paren, code ="...", applicability = "machine-applicable")]
+struct AS {
#[primary_span]
span: Span,
}
@@ -455,8 +464,8 @@ struct AR {
#[derive(SessionSubdiagnostic)]
#[label]
//~^ ERROR unsupported type attribute for subdiagnostic enum
-enum AS {
- #[label(slug = "...")]
+enum AT {
+ #[label(parser::add_paren)]
A {
#[primary_span]
span: Span,
@@ -465,24 +474,24 @@ enum AS {
}
#[derive(SessionSubdiagnostic)]
-#[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")]
-struct AT {
+#[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
+struct AU {
#[primary_span]
span: Span,
var: String,
}
#[derive(SessionSubdiagnostic)]
-#[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")]
+#[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
//~^ ERROR `var` doesn't refer to a field on this type
-struct AU {
+struct AV {
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
-enum AV {
- #[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")]
+enum AW {
+ #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
A {
#[primary_span]
span: Span,
@@ -491,8 +500,8 @@ enum AV {
}
#[derive(SessionSubdiagnostic)]
-enum AW {
- #[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")]
+enum AX {
+ #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
//~^ ERROR `var` doesn't refer to a field on this type
A {
#[primary_span]
diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
index 4984cc4b318..f833bd210f7 100644
--- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
+++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
@@ -1,7 +1,7 @@
error: label without `#[primary_span]` field
--> $DIR/subdiagnostic-derive.rs:47:1
|
-LL | / #[label(slug = "label-c")]
+LL | / #[label(parser::add_paren)]
LL | |
LL | | struct C {
LL | | var: String,
@@ -32,98 +32,106 @@ error: `#[label(bug = ...)]` is not a valid attribute
LL | #[label(bug = "...")]
| ^^^^^^^^^^^
|
- = help: only `code`, `slug` and `applicability` are valid nested attributes
+ = help: first argument of the attribute should be the diagnostic slug
error: `#[label("...")]` is not a valid attribute
--> $DIR/subdiagnostic-derive.rs:91:9
|
LL | #[label("...")]
| ^^^^^
+ |
+ = help: first argument of the attribute should be the diagnostic slug
error: `#[label(slug = ...)]` is not a valid attribute
--> $DIR/subdiagnostic-derive.rs:100:9
|
LL | #[label(slug = 4)]
| ^^^^^^^^
+ |
+ = help: first argument of the attribute should be the diagnostic slug
error: `#[label(slug(...))]` is not a valid attribute
--> $DIR/subdiagnostic-derive.rs:109:9
|
LL | #[label(slug("..."))]
| ^^^^^^^^^^^
-
-error: `#[label(slug)]` is not a valid attribute
- --> $DIR/subdiagnostic-derive.rs:118:9
|
-LL | #[label(slug)]
- | ^^^^
+ = help: first argument of the attribute should be the diagnostic slug
-error: `slug` must be set in a `#[label(...)]` attribute
- --> $DIR/subdiagnostic-derive.rs:127:1
+error: diagnostic slug must be first argument of a `#[label(...)]` attribute
+ --> $DIR/subdiagnostic-derive.rs:128:1
|
LL | #[label()]
| ^^^^^^^^^^
error: `code` is not a valid nested attribute of a `label` attribute
- --> $DIR/subdiagnostic-derive.rs:136:1
+ --> $DIR/subdiagnostic-derive.rs:137:1
+ |
+LL | #[label(parser::add_paren, code = "...")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `applicability` is not a valid nested attribute of a `label` attribute
+ --> $DIR/subdiagnostic-derive.rs:146:1
|
-LL | #[label(code = "...")]
- | ^^^^^^^^^^^^^^^^^^^^^^
+LL | #[label(parser::add_paren, applicability = "machine-applicable")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unsupported type attribute for subdiagnostic enum
- --> $DIR/subdiagnostic-derive.rs:145:1
+ --> $DIR/subdiagnostic-derive.rs:155:1
|
LL | #[foo]
| ^^^^^^
error: `#[bar]` is not a valid attribute
- --> $DIR/subdiagnostic-derive.rs:159:5
+ --> $DIR/subdiagnostic-derive.rs:169:5
|
LL | #[bar]
| ^^^^^^
error: `#[bar = ...]` is not a valid attribute
- --> $DIR/subdiagnostic-derive.rs:171:5
+ --> $DIR/subdiagnostic-derive.rs:181:5
|
LL | #[bar = "..."]
| ^^^^^^^^^^^^^^
error: `#[bar = ...]` is not a valid attribute
- --> $DIR/subdiagnostic-derive.rs:183:5
+ --> $DIR/subdiagnostic-derive.rs:193:5
|
LL | #[bar = 4]
| ^^^^^^^^^^
error: `#[bar("...")]` is not a valid attribute
- --> $DIR/subdiagnostic-derive.rs:195:11
+ --> $DIR/subdiagnostic-derive.rs:205:11
|
LL | #[bar("...")]
| ^^^^^
+ |
+ = help: first argument of the attribute should be the diagnostic slug
-error: `code` is not a valid nested attribute of a `label` attribute
- --> $DIR/subdiagnostic-derive.rs:207:5
+error: diagnostic slug must be first argument of a `#[label(...)]` attribute
+ --> $DIR/subdiagnostic-derive.rs:217:5
|
LL | #[label(code = "...")]
| ^^^^^^^^^^^^^^^^^^^^^^
error: subdiagnostic kind not specified
- --> $DIR/subdiagnostic-derive.rs:224:5
+ --> $DIR/subdiagnostic-derive.rs:234:5
|
LL | B {
| ^
error: the `#[primary_span]` attribute can only be applied to fields of type `Span`
- --> $DIR/subdiagnostic-derive.rs:236:5
+ --> $DIR/subdiagnostic-derive.rs:246:5
|
LL | #[primary_span]
| ^^^^^^^^^^^^^^^
error: label without `#[primary_span]` field
- --> $DIR/subdiagnostic-derive.rs:233:1
+ --> $DIR/subdiagnostic-derive.rs:243:1
|
-LL | / #[label(slug = "...")]
+LL | / #[label(parser::add_paren)]
LL | |
-LL | | struct V {
+LL | | struct W {
LL | | #[primary_span]
LL | |
LL | | span: String,
@@ -131,13 +139,13 @@ LL | | }
| |_^
error: `#[applicability]` is only valid on suggestions
- --> $DIR/subdiagnostic-derive.rs:246:5
+ --> $DIR/subdiagnostic-derive.rs:256:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
error: `#[bar]` is not a valid attribute
- --> $DIR/subdiagnostic-derive.rs:256:5
+ --> $DIR/subdiagnostic-derive.rs:266:5
|
LL | #[bar]
| ^^^^^^
@@ -145,21 +153,21 @@ LL | #[bar]
= help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
error: `#[bar = ...]` is not a valid attribute
- --> $DIR/subdiagnostic-derive.rs:267:5
+ --> $DIR/subdiagnostic-derive.rs:277:5
|
LL | #[bar = "..."]
| ^^^^^^^^^^^^^^
error: `#[bar(...)]` is not a valid attribute
- --> $DIR/subdiagnostic-derive.rs:278:5
+ --> $DIR/subdiagnostic-derive.rs:288:5
|
LL | #[bar("...")]
| ^^^^^^^^^^^^^
error: unexpected unsupported untagged union
- --> $DIR/subdiagnostic-derive.rs:294:1
+ --> $DIR/subdiagnostic-derive.rs:304:1
|
-LL | / union AB {
+LL | / union AC {
LL | |
LL | | span: u32,
LL | | b: u64
@@ -167,95 +175,91 @@ LL | | }
| |_^
error: specified multiple times
- --> $DIR/subdiagnostic-derive.rs:304:9
+ --> $DIR/subdiagnostic-derive.rs:314:1
|
-LL | #[label(slug = "label-ac-2")]
- | ^^^^^^^^^^^^^^^^^^^
+LL | #[label(parser::add_paren)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/subdiagnostic-derive.rs:301:9
+ --> $DIR/subdiagnostic-derive.rs:311:1
|
-LL | #[label(slug = "label-ac-1")]
- | ^^^^^^^^^^^^^^^^^^^
+LL | #[label(parser::add_paren)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: specified multiple times
- --> $DIR/subdiagnostic-derive.rs:304:1
+ --> $DIR/subdiagnostic-derive.rs:314:1
|
-LL | #[label(slug = "label-ac-2")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[label(parser::add_paren)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/subdiagnostic-derive.rs:301:1
+ --> $DIR/subdiagnostic-derive.rs:311:1
|
-LL | #[label(slug = "label-ac-1")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[label(parser::add_paren)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: specified multiple times
- --> $DIR/subdiagnostic-derive.rs:313:30
+error: `#[label(parser::add_paren)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:323:28
|
-LL | #[label(slug = "label-ad-1", slug = "label-ad-2")]
- | ^^^^^^^^^^^^^^^^^^^
+LL | #[label(parser::add_paren, parser::add_paren)]
+ | ^^^^^^^^^^^^^^^^^
|
-note: previously specified here
- --> $DIR/subdiagnostic-derive.rs:313:9
- |
-LL | #[label(slug = "label-ad-1", slug = "label-ad-2")]
- | ^^^^^^^^^^^^^^^^^^^
+ = help: a diagnostic slug must be the first argument to the attribute
error: specified multiple times
- --> $DIR/subdiagnostic-derive.rs:327:5
+ --> $DIR/subdiagnostic-derive.rs:336:5
|
LL | #[primary_span]
| ^^^^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/subdiagnostic-derive.rs:324:5
+ --> $DIR/subdiagnostic-derive.rs:333:5
|
LL | #[primary_span]
| ^^^^^^^^^^^^^^^
error: subdiagnostic kind not specified
- --> $DIR/subdiagnostic-derive.rs:333:8
+ --> $DIR/subdiagnostic-derive.rs:342:8
|
-LL | struct AF {
+LL | struct AG {
| ^^
error: specified multiple times
- --> $DIR/subdiagnostic-derive.rs:370:42
+ --> $DIR/subdiagnostic-derive.rs:379:47
|
-LL | #[suggestion(slug = "...", code = "...", code = "...")]
- | ^^^^^^^^^^^^
+LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
+ | ^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/subdiagnostic-derive.rs:370:28
+ --> $DIR/subdiagnostic-derive.rs:379:33
|
-LL | #[suggestion(slug = "...", code = "...", code = "...")]
- | ^^^^^^^^^^^^
+LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
+ | ^^^^^^^^^^^^
error: specified multiple times
- --> $DIR/subdiagnostic-derive.rs:388:5
+ --> $DIR/subdiagnostic-derive.rs:397:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/subdiagnostic-derive.rs:385:5
+ --> $DIR/subdiagnostic-derive.rs:394:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
error: the `#[applicability]` attribute can only be applied to fields of type `Applicability`
- --> $DIR/subdiagnostic-derive.rs:399:5
+ --> $DIR/subdiagnostic-derive.rs:408:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
error: suggestion without `applicability`
- --> $DIR/subdiagnostic-derive.rs:394:1
+ --> $DIR/subdiagnostic-derive.rs:403:1
|
-LL | / #[suggestion(slug = "...", code = "...")]
+LL | / #[suggestion(parser::add_paren, code = "...")]
LL | |
-LL | | struct AK {
+LL | | struct AL {
LL | | #[primary_span]
... |
LL | | applicability: Span,
@@ -263,22 +267,22 @@ LL | | }
| |_^
error: suggestion without `applicability`
- --> $DIR/subdiagnostic-derive.rs:405:1
+ --> $DIR/subdiagnostic-derive.rs:414:1
|
-LL | / #[suggestion(slug = "...", code = "...")]
+LL | / #[suggestion(parser::add_paren, code = "...")]
LL | |
-LL | | struct AL {
+LL | | struct AM {
LL | | #[primary_span]
LL | | span: Span,
LL | | }
| |_^
error: suggestion without `code = "..."`
- --> $DIR/subdiagnostic-derive.rs:413:1
+ --> $DIR/subdiagnostic-derive.rs:422:1
|
-LL | / #[suggestion(slug = "...")]
+LL | / #[suggestion(parser::add_paren)]
LL | |
-LL | | struct AM {
+LL | | struct AN {
LL | | #[primary_span]
... |
LL | | applicability: Applicability,
@@ -286,50 +290,50 @@ LL | | }
| |_^
error: invalid applicability
- --> $DIR/subdiagnostic-derive.rs:423:41
+ --> $DIR/subdiagnostic-derive.rs:432:46
|
-LL | #[suggestion(slug = "...", code ="...", applicability = "foo")]
- | ^^^^^^^^^^^^^^^^^^^^^
+LL | #[suggestion(parser::add_paren, code ="...", applicability = "foo")]
+ | ^^^^^^^^^^^^^^^^^^^^^
error: suggestion without `applicability`
- --> $DIR/subdiagnostic-derive.rs:441:1
+ --> $DIR/subdiagnostic-derive.rs:450:1
|
-LL | / #[suggestion(slug = "...", code = "...")]
+LL | / #[suggestion(parser::add_paren, code = "...")]
LL | |
LL | |
-LL | | struct AQ {
+LL | | struct AR {
LL | | var: String,
LL | | }
| |_^
error: suggestion without `#[primary_span]` field
- --> $DIR/subdiagnostic-derive.rs:441:1
+ --> $DIR/subdiagnostic-derive.rs:450:1
|
-LL | / #[suggestion(slug = "...", code = "...")]
+LL | / #[suggestion(parser::add_paren, code = "...")]
LL | |
LL | |
-LL | | struct AQ {
+LL | | struct AR {
LL | | var: String,
LL | | }
| |_^
error: unsupported type attribute for subdiagnostic enum
- --> $DIR/subdiagnostic-derive.rs:456:1
+ --> $DIR/subdiagnostic-derive.rs:465:1
|
LL | #[label]
| ^^^^^^^^
error: `var` doesn't refer to a field on this type
- --> $DIR/subdiagnostic-derive.rs:476:34
+ --> $DIR/subdiagnostic-derive.rs:485:39
|
-LL | #[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")]
- | ^^^^^^^
+LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
+ | ^^^^^^^
error: `var` doesn't refer to a field on this type
- --> $DIR/subdiagnostic-derive.rs:495:38
+ --> $DIR/subdiagnostic-derive.rs:504:43
|
-LL | #[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")]
- | ^^^^^^^
+LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
+ | ^^^^^^^
error: cannot find attribute `foo` in this scope
--> $DIR/subdiagnostic-derive.rs:63:3
@@ -338,52 +342,59 @@ LL | #[foo]
| ^^^
error: cannot find attribute `foo` in this scope
- --> $DIR/subdiagnostic-derive.rs:145:3
+ --> $DIR/subdiagnostic-derive.rs:155:3
|
LL | #[foo]
| ^^^
error: cannot find attribute `bar` in this scope
- --> $DIR/subdiagnostic-derive.rs:159:7
+ --> $DIR/subdiagnostic-derive.rs:169:7
|
LL | #[bar]
| ^^^
error: cannot find attribute `bar` in this scope
- --> $DIR/subdiagnostic-derive.rs:171:7
+ --> $DIR/subdiagnostic-derive.rs:181:7
|
LL | #[bar = "..."]
| ^^^
error: cannot find attribute `bar` in this scope
- --> $DIR/subdiagnostic-derive.rs:183:7
+ --> $DIR/subdiagnostic-derive.rs:193:7
|
LL | #[bar = 4]
| ^^^
error: cannot find attribute `bar` in this scope
- --> $DIR/subdiagnostic-derive.rs:195:7
+ --> $DIR/subdiagnostic-derive.rs:205:7
|
LL | #[bar("...")]
| ^^^
error: cannot find attribute `bar` in this scope
- --> $DIR/subdiagnostic-derive.rs:256:7
+ --> $DIR/subdiagnostic-derive.rs:266:7
|
LL | #[bar]
| ^^^
error: cannot find attribute `bar` in this scope
- --> $DIR/subdiagnostic-derive.rs:267:7
+ --> $DIR/subdiagnostic-derive.rs:277:7
|
LL | #[bar = "..."]
| ^^^
error: cannot find attribute `bar` in this scope
- --> $DIR/subdiagnostic-derive.rs:278:7
+ --> $DIR/subdiagnostic-derive.rs:288:7
|
LL | #[bar("...")]
| ^^^
-error: aborting due to 51 previous errors
+error[E0425]: cannot find value `slug` in module `rustc_errors::fluent`
+ --> $DIR/subdiagnostic-derive.rs:118:9
+ |
+LL | #[label(slug)]
+ | ^^^^ not found in `rustc_errors::fluent`
+
+error: aborting due to 52 previous errors
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/array-slice-vec/array_const_index-0.stderr b/src/test/ui/array-slice-vec/array_const_index-0.stderr
index 641705e1c68..b44251efdea 100644
--- a/src/test/ui/array-slice-vec/array_const_index-0.stderr
+++ b/src/test/ui/array-slice-vec/array_const_index-0.stderr
@@ -12,3 +12,16 @@ LL | const B: i32 = (&A)[1];
error: aborting due to previous error
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/array_const_index-0.rs:2:16
+ |
+LL | const B: i32 = (&A)[1];
+ | ---------------^^^^^^^-
+ | |
+ | index out of bounds: the length is 0 but the index is 1
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/array-slice-vec/array_const_index-1.stderr b/src/test/ui/array-slice-vec/array_const_index-1.stderr
index 4d52d38af5e..8beebafb04c 100644
--- a/src/test/ui/array-slice-vec/array_const_index-1.stderr
+++ b/src/test/ui/array-slice-vec/array_const_index-1.stderr
@@ -12,3 +12,16 @@ LL | const B: i32 = A[1];
error: aborting due to previous error
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/array_const_index-1.rs:2:16
+ |
+LL | const B: i32 = A[1];
+ | ---------------^^^^-
+ | |
+ | index out of bounds: the length is 0 but the index is 1
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr
index 7406b2ddee9..f04ea0b7477 100644
--- a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr
+++ b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr
@@ -29,3 +29,28 @@ LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/defaults-not-assumed-fail.rs:8:19
+ |
+LL | const B: u8 = Self::A + 1;
+ | --------------^^^^^^^^^^^-
+ | |
+ | attempt to compute `u8::MAX + 1_u8`, which would overflow
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: erroneous constant used
+ --> $DIR/defaults-not-assumed-fail.rs:34:5
+ |
+LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/src/test/ui/associated-item/associated-item-duplicate-names-2.stderr b/src/test/ui/associated-item/associated-item-duplicate-names-2.stderr
index ea475ffc554..ad21b38d07e 100644
--- a/src/test/ui/associated-item/associated-item-duplicate-names-2.stderr
+++ b/src/test/ui/associated-item/associated-item-duplicate-names-2.stderr
@@ -4,7 +4,7 @@ error[E0201]: duplicate definitions with name `bar`:
LL | const bar: bool = true;
| ----------------------- previous definition of `bar` here
LL | fn bar() {}
- | ^^^^^^^^^^^ duplicate definition
+ | ^^^^^^^^ duplicate definition
error: aborting due to previous error
diff --git a/src/test/ui/associated-item/issue-48027.stderr b/src/test/ui/associated-item/issue-48027.stderr
index 9ae25a8c222..5487af1a835 100644
--- a/src/test/ui/associated-item/issue-48027.stderr
+++ b/src/test/ui/associated-item/issue-48027.stderr
@@ -1,15 +1,3 @@
-error[E0283]: type annotations needed
- --> $DIR/issue-48027.rs:3:32
- |
-LL | fn return_n(&self) -> [u8; Bar::X];
- | ^^^^^^
- | |
- | cannot infer type
- | help: use the fully qualified path to an implementation: `<Type as Bar>::X`
- |
- = note: cannot satisfy `_: Bar`
- = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
-
error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/issue-48027.rs:6:6
|
@@ -25,6 +13,18 @@ LL | const X: usize;
| ^ ...because it contains this associated `const`
= help: consider moving `X` to another trait
+error[E0283]: type annotations needed
+ --> $DIR/issue-48027.rs:3:32
+ |
+LL | fn return_n(&self) -> [u8; Bar::X];
+ | ^^^^^^
+ | |
+ | cannot infer type
+ | help: use the fully qualified path to an implementation: `<Type as Bar>::X`
+ |
+ = note: cannot satisfy `_: Bar`
+ = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
+
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0038, E0283.
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
index da79c7ac77f..bd3ee2abd2c 100644
--- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
+++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
@@ -1,3 +1,9 @@
+error[E0277]: the trait bound `(T, U): Get` is not satisfied
+ --> $DIR/associated-types-no-suitable-supertrait.rs:22:40
+ |
+LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
+
error[E0277]: the trait bound `Self: Get` is not satisfied
--> $DIR/associated-types-no-suitable-supertrait.rs:17:40
|
@@ -9,12 +15,6 @@ help: consider further restricting `Self`
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
| +++++++++++++++
-error[E0277]: the trait bound `(T, U): Get` is not satisfied
- --> $DIR/associated-types-no-suitable-supertrait.rs:22:40
- |
-LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
- | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
-
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-2.rs b/src/test/ui/associated-types/hr-associated-type-bound-2.rs
index 2eb956c8dbb..a89f61a81a5 100644
--- a/src/test/ui/associated-types/hr-associated-type-bound-2.rs
+++ b/src/test/ui/associated-types/hr-associated-type-bound-2.rs
@@ -12,7 +12,7 @@ impl X<'_> for u32 //~ overflow evaluating the requirement `for<'b> u32: X<'b>`
where
for<'b> <Self as X<'b>>::U: Clone,
{
- type U = str; //~ overflow evaluating the requirement `for<'b> u32: X<'b>`
+ type U = str;
}
fn main() {
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-2.stderr b/src/test/ui/associated-types/hr-associated-type-bound-2.stderr
index fe9b4d630b9..1d3b7097da6 100644
--- a/src/test/ui/associated-types/hr-associated-type-bound-2.stderr
+++ b/src/test/ui/associated-types/hr-associated-type-bound-2.stderr
@@ -18,21 +18,6 @@ LL | impl X<'_> for u32
= note: 128 redundant requirements hidden
= note: required because of the requirements on the impl of `for<'b> X<'b>` for `u32`
-error[E0275]: overflow evaluating the requirement `for<'b> u32: X<'b>`
- --> $DIR/hr-associated-type-bound-2.rs:15:5
- |
-LL | type U = str;
- | ^^^^^^^^^^^^^
- |
- = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`hr_associated_type_bound_2`)
-note: required because of the requirements on the impl of `for<'b> X<'b>` for `u32`
- --> $DIR/hr-associated-type-bound-2.rs:11:6
- |
-LL | impl X<'_> for u32
- | ^^^^^ ^^^
- = note: 128 redundant requirements hidden
- = note: required because of the requirements on the impl of `for<'b> X<'b>` for `u32`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-2.stderr b/src/test/ui/associated-types/hr-associated-type-bound-param-2.stderr
index 5809c407a5f..52294f8c94a 100644
--- a/src/test/ui/associated-types/hr-associated-type-bound-param-2.stderr
+++ b/src/test/ui/associated-types/hr-associated-type-bound-param-2.stderr
@@ -15,10 +15,10 @@ LL | for<'b> <T as Z<'b, u16>>::W: Clone,
| ^^^^^ required by this bound in `Z`
error[E0277]: the trait bound `str: Clone` is not satisfied
- --> $DIR/hr-associated-type-bound-param-2.rs:3:8
+ --> $DIR/hr-associated-type-bound-param-2.rs:15:14
|
-LL | T: Z<'a, u16>,
- | ^^^^^^^^^^ the trait `Clone` is not implemented for `str`
+LL | type W = str;
+ | ^^^ the trait `Clone` is not implemented for `str`
|
= help: the trait `Clone` is implemented for `String`
note: required by a bound in `Z`
@@ -31,10 +31,10 @@ LL | for<'b> <T as Z<'b, u16>>::W: Clone,
| ^^^^^ required by this bound in `Z`
error[E0277]: the trait bound `str: Clone` is not satisfied
- --> $DIR/hr-associated-type-bound-param-2.rs:15:14
+ --> $DIR/hr-associated-type-bound-param-2.rs:3:8
|
-LL | type W = str;
- | ^^^ the trait `Clone` is not implemented for `str`
+LL | T: Z<'a, u16>,
+ | ^^^^^^^^^^ the trait `Clone` is not implemented for `str`
|
= help: the trait `Clone` is implemented for `String`
note: required by a bound in `Z`
diff --git a/src/test/ui/associated-types/impl-wf-cycle-1.rs b/src/test/ui/associated-types/impl-wf-cycle-1.rs
index ba074210a2b..365eddaed13 100644
--- a/src/test/ui/associated-types/impl-wf-cycle-1.rs
+++ b/src/test/ui/associated-types/impl-wf-cycle-1.rs
@@ -13,16 +13,14 @@ trait Grault {
}
impl<T: Grault> Grault for (T,)
+//~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
where
Self::A: Baz,
Self::B: Fiz,
{
type A = ();
- //~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
type B = bool;
- //~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
}
-//~^^^^^^^^^^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
fn main() {
let x: <(_,) as Grault>::A = ();
diff --git a/src/test/ui/associated-types/impl-wf-cycle-1.stderr b/src/test/ui/associated-types/impl-wf-cycle-1.stderr
index 73167d08311..6f60128b8ef 100644
--- a/src/test/ui/associated-types/impl-wf-cycle-1.stderr
+++ b/src/test/ui/associated-types/impl-wf-cycle-1.stderr
@@ -2,11 +2,11 @@ error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
--> $DIR/impl-wf-cycle-1.rs:15:1
|
LL | / impl<T: Grault> Grault for (T,)
+LL | |
LL | | where
LL | | Self::A: Baz,
-LL | | Self::B: Fiz,
... |
-LL | |
+LL | | type B = bool;
LL | | }
| |_^
|
@@ -18,34 +18,6 @@ LL | impl<T: Grault> Grault for (T,)
= note: 1 redundant requirement hidden
= note: required because of the requirements on the impl of `Grault` for `(T,)`
-error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
- --> $DIR/impl-wf-cycle-1.rs:20:5
- |
-LL | type A = ();
- | ^^^^^^^^^^^^
- |
-note: required because of the requirements on the impl of `Grault` for `(T,)`
- --> $DIR/impl-wf-cycle-1.rs:15:17
- |
-LL | impl<T: Grault> Grault for (T,)
- | ^^^^^^ ^^^^
- = note: 1 redundant requirement hidden
- = note: required because of the requirements on the impl of `Grault` for `(T,)`
-
-error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
- --> $DIR/impl-wf-cycle-1.rs:22:5
- |
-LL | type B = bool;
- | ^^^^^^^^^^^^^^
- |
-note: required because of the requirements on the impl of `Grault` for `(T,)`
- --> $DIR/impl-wf-cycle-1.rs:15:17
- |
-LL | impl<T: Grault> Grault for (T,)
- | ^^^^^^ ^^^^
- = note: 1 redundant requirement hidden
- = note: required because of the requirements on the impl of `Grault` for `(T,)`
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/associated-types/impl-wf-cycle-2.rs b/src/test/ui/associated-types/impl-wf-cycle-2.rs
index 6fccc54f229..f2f3072e344 100644
--- a/src/test/ui/associated-types/impl-wf-cycle-2.rs
+++ b/src/test/ui/associated-types/impl-wf-cycle-2.rs
@@ -5,12 +5,11 @@ trait Grault {
}
impl<T: Grault> Grault for (T,)
+//~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
where
Self::A: Copy,
{
type A = ();
- //~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
}
-//~^^^^^^^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
fn main() {}
diff --git a/src/test/ui/associated-types/impl-wf-cycle-2.stderr b/src/test/ui/associated-types/impl-wf-cycle-2.stderr
index a17e63f28fe..ba14ffefae5 100644
--- a/src/test/ui/associated-types/impl-wf-cycle-2.stderr
+++ b/src/test/ui/associated-types/impl-wf-cycle-2.stderr
@@ -2,11 +2,11 @@ error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
--> $DIR/impl-wf-cycle-2.rs:7:1
|
LL | / impl<T: Grault> Grault for (T,)
+LL | |
LL | | where
LL | | Self::A: Copy,
LL | | {
LL | | type A = ();
-LL | |
LL | | }
| |_^
|
@@ -16,18 +16,6 @@ note: required because of the requirements on the impl of `Grault` for `(T,)`
LL | impl<T: Grault> Grault for (T,)
| ^^^^^^ ^^^^
-error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
- --> $DIR/impl-wf-cycle-2.rs:11:5
- |
-LL | type A = ();
- | ^^^^^^^^^^^^
- |
-note: required because of the requirements on the impl of `Grault` for `(T,)`
- --> $DIR/impl-wf-cycle-2.rs:7:17
- |
-LL | impl<T: Grault> Grault for (T,)
- | ^^^^^^ ^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/associated-types/issue-59324.stderr b/src/test/ui/associated-types/issue-59324.stderr
index 45d2dfb5375..5cd781d9a0c 100644
--- a/src/test/ui/associated-types/issue-59324.stderr
+++ b/src/test/ui/associated-types/issue-59324.stderr
@@ -46,6 +46,12 @@ help: consider further restricting this bound
LL | pub trait ThriftService<Bug: NotFoo + Foo>:
| +++++
+error[E0277]: the trait bound `(): Foo` is not satisfied
+ --> $DIR/issue-59324.rs:23:29
+ |
+LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
+ | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
+
error[E0277]: the trait bound `Bug: Foo` is not satisfied
--> $DIR/issue-59324.rs:19:10
|
@@ -57,12 +63,6 @@ help: consider further restricting this bound
LL | pub trait ThriftService<Bug: NotFoo + Foo>:
| +++++
-error[E0277]: the trait bound `(): Foo` is not satisfied
- --> $DIR/issue-59324.rs:23:29
- |
-LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
- | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
-
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/borrowck/issue-81899.stderr b/src/test/ui/borrowck/issue-81899.stderr
index 92ebd5a220d..e7345ff3f9a 100644
--- a/src/test/ui/borrowck/issue-81899.stderr
+++ b/src/test/ui/borrowck/issue-81899.stderr
@@ -27,3 +27,16 @@ LL | const _CONST: &[u8] = &f(&[], |_| {});
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/issue-81899.rs:4:23
+ |
+LL | const _CONST: &[u8] = &f(&[], |_| {});
+ | ----------------------^^^^^^^^^^^^^^^-
+ | |
+ | referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/borrowck/issue-88434-minimal-example.stderr b/src/test/ui/borrowck/issue-88434-minimal-example.stderr
index d46cd862e34..47d83c65355 100644
--- a/src/test/ui/borrowck/issue-88434-minimal-example.stderr
+++ b/src/test/ui/borrowck/issue-88434-minimal-example.stderr
@@ -27,3 +27,16 @@ LL | const _CONST: &() = &f(&|_| {});
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/issue-88434-minimal-example.rs:3:21
+ |
+LL | const _CONST: &() = &f(&|_| {});
+ | --------------------^^^^^^^^^^^-
+ | |
+ | referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr
index e6b07aba74d..b08a7cfc7fe 100644
--- a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr
+++ b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr
@@ -27,3 +27,16 @@ LL | const _CONST: &[u8] = &f(&[], |_| {});
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/issue-88434-removal-index-should-be-less.rs:3:23
+ |
+LL | const _CONST: &[u8] = &f(&[], |_| {});
+ | ----------------------^^^^^^^^^^^^^^^-
+ | |
+ | referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/chalkify/bugs/async.rs b/src/test/ui/chalkify/bugs/async.rs
index 58fc93064ed..ae5224dbd6f 100644
--- a/src/test/ui/chalkify/bugs/async.rs
+++ b/src/test/ui/chalkify/bugs/async.rs
@@ -1,5 +1,5 @@
// check-fail
-// known-bug
+// known-bug: unknown
// compile-flags: -Z chalk --edition=2021
fn main() -> () {}
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr
index 91289148079..c364c707ff9 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr
+++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr
@@ -1,3 +1,15 @@
+error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
+ --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
+ |
+LL | impl !Marker1 for dyn Object + Marker2 { }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
+
+error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
+ --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:17:1
+ |
+LL | impl !Marker2 for dyn Object + Marker2 { }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
+
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:23:1
|
@@ -21,18 +33,6 @@ error[E0321]: cross-crate traits with a default impl, like `Send`, can only be i
LL | impl !Send for dyn Object + Marker2 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
-error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
- --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
- |
-LL | impl !Marker1 for dyn Object + Marker2 { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
-
-error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
- --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:17:1
- |
-LL | impl !Marker2 for dyn Object + Marker2 { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
-
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0117, E0321, E0371.
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr
index 056198374a4..b80429794f9 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr
+++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr
@@ -1,3 +1,15 @@
+error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
+ --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:15:1
+ |
+LL | impl Marker1 for dyn Object + Marker2 { }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
+
+error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
+ --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:17:1
+ |
+LL | impl Marker2 for dyn Object + Marker2 { }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
+
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:23:1
|
@@ -21,18 +33,6 @@ error[E0321]: cross-crate traits with a default impl, like `Send`, can only be i
LL | unsafe impl Send for dyn Object + Marker2 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
-error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
- --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:15:1
- |
-LL | impl Marker1 for dyn Object + Marker2 { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
-
-error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
- --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:17:1
- |
-LL | impl Marker2 for dyn Object + Marker2 { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
-
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0117, E0321, E0371.
diff --git a/src/test/ui/coherence/coherence-impls-copy.stderr b/src/test/ui/coherence/coherence-impls-copy.stderr
index b3ca354c633..86356af2564 100644
--- a/src/test/ui/coherence/coherence-impls-copy.stderr
+++ b/src/test/ui/coherence/coherence-impls-copy.stderr
@@ -9,49 +9,49 @@ LL | impl Copy for i32 {}
|
= note: define and implement a trait or new type instead
+error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync`
+ --> $DIR/coherence-impls-copy.rs:28:1
+ |
+LL | impl Copy for &'static NotSync {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: conflicting implementation in crate `core`:
+ - impl<T> Copy for &T
+ where T: ?Sized;
+
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
- --> $DIR/coherence-impls-copy.rs:25:1
+ --> $DIR/coherence-impls-copy.rs:33:1
|
-LL | impl Copy for (MyType, MyType) {}
- | ^^^^^^^^^^^^^^----------------
+LL | impl Copy for &'static [NotSync] {}
+ | ^^^^^^^^^^^^^^------------------
| | |
- | | this is not defined in the current crate because tuples are always foreign
+ | | this is not defined in the current crate because slices are always foreign
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
- --> $DIR/coherence-impls-copy.rs:30:1
+ --> $DIR/coherence-impls-copy.rs:25:1
|
-LL | impl Copy for [MyType] {}
- | ^^^^^^^^^^^^^^--------
+LL | impl Copy for (MyType, MyType) {}
+ | ^^^^^^^^^^^^^^----------------
| | |
- | | this is not defined in the current crate because slices are always foreign
+ | | this is not defined in the current crate because tuples are always foreign
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
- --> $DIR/coherence-impls-copy.rs:33:1
+ --> $DIR/coherence-impls-copy.rs:30:1
|
-LL | impl Copy for &'static [NotSync] {}
- | ^^^^^^^^^^^^^^------------------
+LL | impl Copy for [MyType] {}
+ | ^^^^^^^^^^^^^^--------
| | |
| | this is not defined in the current crate because slices are always foreign
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
-error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync`
- --> $DIR/coherence-impls-copy.rs:28:1
- |
-LL | impl Copy for &'static NotSync {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: conflicting implementation in crate `core`:
- - impl<T> Copy for &T
- where T: ?Sized;
-
error[E0206]: the trait `Copy` may not be implemented for this type
--> $DIR/coherence-impls-copy.rs:21:15
|
diff --git a/src/test/ui/coherence/coherence-impls-send.stderr b/src/test/ui/coherence/coherence-impls-send.stderr
index dd1fd1b0dce..e1071846e14 100644
--- a/src/test/ui/coherence/coherence-impls-send.stderr
+++ b/src/test/ui/coherence/coherence-impls-send.stderr
@@ -1,4 +1,15 @@
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
+ --> $DIR/coherence-impls-send.rs:25:1
+ |
+LL | unsafe impl Send for &'static [NotSync] {}
+ | ^^^^^^^^^^^^^^^^^^^^^------------------
+ | | |
+ | | this is not defined in the current crate because slices are always foreign
+ | impl doesn't use only types from inside the current crate
+ |
+ = note: define and implement a trait or new type instead
+
+error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impls-send.rs:16:1
|
LL | unsafe impl Send for (MyType, MyType) {}
@@ -26,17 +37,6 @@ LL | unsafe impl Send for [MyType] {}
|
= note: define and implement a trait or new type instead
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
- --> $DIR/coherence-impls-send.rs:25:1
- |
-LL | unsafe impl Send for &'static [NotSync] {}
- | ^^^^^^^^^^^^^^^^^^^^^------------------
- | | |
- | | this is not defined in the current crate because slices are always foreign
- | impl doesn't use only types from inside the current crate
- |
- = note: define and implement a trait or new type instead
-
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0117, E0321.
diff --git a/src/test/ui/coherence/coherence-impls-sized.stderr b/src/test/ui/coherence/coherence-impls-sized.stderr
index e1e4acd4cd8..17a7544521d 100644
--- a/src/test/ui/coherence/coherence-impls-sized.stderr
+++ b/src/test/ui/coherence/coherence-impls-sized.stderr
@@ -1,36 +1,3 @@
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
- --> $DIR/coherence-impls-sized.rs:20:1
- |
-LL | impl Sized for (MyType, MyType) {}
- | ^^^^^^^^^^^^^^^----------------
- | | |
- | | this is not defined in the current crate because tuples are always foreign
- | impl doesn't use only types from inside the current crate
- |
- = note: define and implement a trait or new type instead
-
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
- --> $DIR/coherence-impls-sized.rs:27:1
- |
-LL | impl Sized for [MyType] {}
- | ^^^^^^^^^^^^^^^--------
- | | |
- | | this is not defined in the current crate because slices are always foreign
- | impl doesn't use only types from inside the current crate
- |
- = note: define and implement a trait or new type instead
-
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
- --> $DIR/coherence-impls-sized.rs:31:1
- |
-LL | impl Sized for &'static [NotSync] {}
- | ^^^^^^^^^^^^^^^------------------
- | | |
- | | this is not defined in the current crate because slices are always foreign
- | impl doesn't use only types from inside the current crate
- |
- = note: define and implement a trait or new type instead
-
error[E0322]: explicit impls for the `Sized` trait are not permitted
--> $DIR/coherence-impls-sized.rs:14:1
|
@@ -49,6 +16,17 @@ error[E0322]: explicit impls for the `Sized` trait are not permitted
LL | impl Sized for (MyType, MyType) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed
+error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
+ --> $DIR/coherence-impls-sized.rs:20:1
+ |
+LL | impl Sized for (MyType, MyType) {}
+ | ^^^^^^^^^^^^^^^----------------
+ | | |
+ | | this is not defined in the current crate because tuples are always foreign
+ | impl doesn't use only types from inside the current crate
+ |
+ = note: define and implement a trait or new type instead
+
error[E0322]: explicit impls for the `Sized` trait are not permitted
--> $DIR/coherence-impls-sized.rs:24:1
|
@@ -61,12 +39,34 @@ error[E0322]: explicit impls for the `Sized` trait are not permitted
LL | impl Sized for [MyType] {}
| ^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed
+error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
+ --> $DIR/coherence-impls-sized.rs:27:1
+ |
+LL | impl Sized for [MyType] {}
+ | ^^^^^^^^^^^^^^^--------
+ | | |
+ | | this is not defined in the current crate because slices are always foreign
+ | impl doesn't use only types from inside the current crate
+ |
+ = note: define and implement a trait or new type instead
+
error[E0322]: explicit impls for the `Sized` trait are not permitted
--> $DIR/coherence-impls-sized.rs:31:1
|
LL | impl Sized for &'static [NotSync] {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed
+error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
+ --> $DIR/coherence-impls-sized.rs:31:1
+ |
+LL | impl Sized for &'static [NotSync] {}
+ | ^^^^^^^^^^^^^^^------------------
+ | | |
+ | | this is not defined in the current crate because slices are always foreign
+ | impl doesn't use only types from inside the current crate
+ |
+ = note: define and implement a trait or new type instead
+
error: aborting due to 9 previous errors
Some errors have detailed explanations: E0117, E0322.
diff --git a/src/test/ui/coherence/coherence-with-closure.stderr b/src/test/ui/coherence/coherence-with-closure.stderr
index 20b986cee69..d2ca63fa146 100644
--- a/src/test/ui/coherence/coherence-with-closure.stderr
+++ b/src/test/ui/coherence/coherence-with-closure.stderr
@@ -1,3 +1,12 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
+ --> $DIR/coherence-with-closure.rs:12:1
+ |
+LL | impl Trait for Wrapper<OpaqueClosure> {}
+ | ------------------------------------- first implementation here
+LL |
+LL | impl<T: Sync> Trait for Wrapper<T> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueClosure>`
+
error: cannot implement trait on type alias impl trait
--> $DIR/coherence-with-closure.rs:10:24
|
@@ -10,15 +19,6 @@ note: type alias impl trait defined here
LL | type OpaqueClosure = impl Sized;
| ^^^^^^^^^^
-error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
- --> $DIR/coherence-with-closure.rs:12:1
- |
-LL | impl Trait for Wrapper<OpaqueClosure> {}
- | ------------------------------------- first implementation here
-LL |
-LL | impl<T: Sync> Trait for Wrapper<T> {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueClosure>`
-
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-with-generator.stderr b/src/test/ui/coherence/coherence-with-generator.stderr
index 249ad3cb9ec..804bc1c3a6d 100644
--- a/src/test/ui/coherence/coherence-with-generator.stderr
+++ b/src/test/ui/coherence/coherence-with-generator.stderr
@@ -1,3 +1,12 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>`
+ --> $DIR/coherence-with-generator.rs:16:1
+ |
+LL | impl Trait for Wrapper<OpaqueGenerator> {}
+ | --------------------------------------- first implementation here
+LL |
+LL | impl<T: Sync> Trait for Wrapper<T> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueGenerator>`
+
error: cannot implement trait on type alias impl trait
--> $DIR/coherence-with-generator.rs:14:24
|
@@ -10,15 +19,6 @@ note: type alias impl trait defined here
LL | type OpaqueGenerator = impl Sized;
| ^^^^^^^^^^
-error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>`
- --> $DIR/coherence-with-generator.rs:16:1
- |
-LL | impl Trait for Wrapper<OpaqueGenerator> {}
- | --------------------------------------- first implementation here
-LL |
-LL | impl<T: Sync> Trait for Wrapper<T> {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueGenerator>`
-
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.min.stderr b/src/test/ui/const-generics/const-param-elided-lifetime.min.stderr
index 48d85e7ff64..4bba42c7782 100644
--- a/src/test/ui/const-generics/const-param-elided-lifetime.min.stderr
+++ b/src/test/ui/const-generics/const-param-elided-lifetime.min.stderr
@@ -47,15 +47,6 @@ LL | impl<const N: &u8> A<N> {
= help: more complex types are supported with `#![feature(adt_const_params)]`
error: `&'static u8` is forbidden as the type of a const generic parameter
- --> $DIR/const-param-elided-lifetime.rs:17:21
- |
-LL | fn foo<const M: &u8>(&self) {}
- | ^^^
- |
- = note: the only supported types are integers, `bool` and `char`
- = help: more complex types are supported with `#![feature(adt_const_params)]`
-
-error: `&'static u8` is forbidden as the type of a const generic parameter
--> $DIR/const-param-elided-lifetime.rs:22:15
|
LL | impl<const N: &u8> B for A<N> {}
@@ -73,6 +64,15 @@ LL | fn bar<const N: &u8>() {}
= note: the only supported types are integers, `bool` and `char`
= help: more complex types are supported with `#![feature(adt_const_params)]`
+error: `&'static u8` is forbidden as the type of a const generic parameter
+ --> $DIR/const-param-elided-lifetime.rs:17:21
+ |
+LL | fn foo<const M: &u8>(&self) {}
+ | ^^^
+ |
+ = note: the only supported types are integers, `bool` and `char`
+ = help: more complex types are supported with `#![feature(adt_const_params)]`
+
error: aborting due to 10 previous errors
For more information about this error, try `rustc --explain E0637`.
diff --git a/src/test/ui/consts/assert-type-intrinsics.stderr b/src/test/ui/consts/assert-type-intrinsics.stderr
index bb57ee82cc1..89f8f2ffc55 100644
--- a/src/test/ui/consts/assert-type-intrinsics.stderr
+++ b/src/test/ui/consts/assert-type-intrinsics.stderr
@@ -37,3 +37,45 @@ LL | | };
error: aborting due to 3 previous errors
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/assert-type-intrinsics.rs:14:9
+ |
+LL | / const _BAD1: () = unsafe {
+LL | | MaybeUninit::<!>::uninit().assume_init();
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
+LL | | };
+ | |______-
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/assert-type-intrinsics.rs:17:9
+ |
+LL | / const _BAD2: () = unsafe {
+LL | | intrinsics::assert_uninit_valid::<bool>();
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `bool` uninitialized, which is invalid
+LL | | };
+ | |______-
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/assert-type-intrinsics.rs:20:9
+ |
+LL | / const _BAD3: () = unsafe {
+LL | | intrinsics::assert_zero_valid::<&'static i32>();
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `&i32`, which is invalid
+LL | | };
+ | |______-
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/assoc_const_generic_impl.stderr b/src/test/ui/consts/assoc_const_generic_impl.stderr
index 96cb904fa1b..cccf62a8ff6 100644
--- a/src/test/ui/consts/assoc_const_generic_impl.stderr
+++ b/src/test/ui/consts/assoc_const_generic_impl.stderr
@@ -22,3 +22,20 @@ LL | let () = Self::I_AM_ZERO_SIZED;
error: aborting due to previous error; 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/assoc_const_generic_impl.rs:11:34
+ |
+LL | const I_AM_ZERO_SIZED: () = [()][std::mem::size_of::<Self>()];
+ | -----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | index out of bounds: the length is 1 but the index is 4
+ |
+note: the lint level is defined here
+ --> $DIR/assoc_const_generic_impl.rs:3:9
+ |
+LL | #![warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-err-early.stderr b/src/test/ui/consts/const-err-early.stderr
index 2b3d8817387..385e770eb4f 100644
--- a/src/test/ui/consts/const-err-early.stderr
+++ b/src/test/ui/consts/const-err-early.stderr
@@ -60,3 +60,88 @@ LL | pub const E: u8 = [5u8][1];
error: aborting due to 5 previous errors
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-err-early.rs:3:19
+ |
+LL | pub const A: i8 = -i8::MIN;
+ | ------------------^^^^^^^^-
+ | |
+ | attempt to negate `i8::MIN`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/const-err-early.rs:1:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-err-early.rs:5:19
+ |
+LL | pub const B: u8 = 200u8 + 200u8;
+ | ------------------^^^^^^^^^^^^^-
+ | |
+ | attempt to compute `200_u8 + 200_u8`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/const-err-early.rs:1:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-err-early.rs:7:19
+ |
+LL | pub const C: u8 = 200u8 * 4;
+ | ------------------^^^^^^^^^-
+ | |
+ | attempt to compute `200_u8 * 4_u8`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/const-err-early.rs:1:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-err-early.rs:9:19
+ |
+LL | pub const D: u8 = 42u8 - (42u8 + 1);
+ | ------------------^^^^^^^^^^^^^^^^^-
+ | |
+ | attempt to compute `42_u8 - 43_u8`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/const-err-early.rs:1:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-err-early.rs:11:19
+ |
+LL | pub const E: u8 = [5u8][1];
+ | ------------------^^^^^^^^-
+ | |
+ | index out of bounds: the length is 1 but the index is 1
+ |
+note: the lint level is defined here
+ --> $DIR/const-err-early.rs:1:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-err-multi.stderr b/src/test/ui/consts/const-err-multi.stderr
index c8172e83d10..a195459ff08 100644
--- a/src/test/ui/consts/const-err-multi.stderr
+++ b/src/test/ui/consts/const-err-multi.stderr
@@ -49,3 +49,71 @@ LL | pub const D: i8 = 50 - A;
error: aborting due to 4 previous errors
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-err-multi.rs:3:19
+ |
+LL | pub const A: i8 = -i8::MIN;
+ | ------------------^^^^^^^^-
+ | |
+ | attempt to negate `i8::MIN`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/const-err-multi.rs:1:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-err-multi.rs:6:19
+ |
+LL | pub const B: i8 = A;
+ | ------------------^-
+ | |
+ | referenced constant has errors
+ |
+note: the lint level is defined here
+ --> $DIR/const-err-multi.rs:1:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-err-multi.rs:9:19
+ |
+LL | pub const C: u8 = A as u8;
+ | ------------------^-------
+ | |
+ | referenced constant has errors
+ |
+note: the lint level is defined here
+ --> $DIR/const-err-multi.rs:1:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-err-multi.rs:12:24
+ |
+LL | pub const D: i8 = 50 - A;
+ | -----------------------^-
+ | |
+ | referenced constant has errors
+ |
+note: the lint level is defined here
+ --> $DIR/const-err-multi.rs:1:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-err.stderr b/src/test/ui/consts/const-err.stderr
index 0c963874a84..3b03e702dc4 100644
--- a/src/test/ui/consts/const-err.stderr
+++ b/src/test/ui/consts/const-err.stderr
@@ -29,3 +29,20 @@ LL | black_box((FOO, FOO));
error: aborting due to 2 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/const-err.rs:11:17
+ |
+LL | const FOO: u8 = [5u8][1];
+ | ----------------^^^^^^^^-
+ | |
+ | index out of bounds: the length is 1 but the index is 1
+ |
+note: the lint level is defined here
+ --> $DIR/const-err.rs:5:9
+ |
+LL | #![warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/conditional_array_execution.stderr b/src/test/ui/consts/const-eval/conditional_array_execution.stderr
index 9dc40030a6f..f88bf445426 100644
--- a/src/test/ui/consts/const-eval/conditional_array_execution.stderr
+++ b/src/test/ui/consts/const-eval/conditional_array_execution.stderr
@@ -33,3 +33,36 @@ LL | println!("{}", FOO);
error: aborting due to previous error; 2 warnings emitted
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/conditional_array_execution.rs:7:19
+ |
+LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+ | ------------------^^^^^---------------------------
+ | |
+ | attempt to compute `5_u32 - 6_u32`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/conditional_array_execution.rs:3:9
+ |
+LL | #![warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+warning: erroneous constant used
+ --> $DIR/conditional_array_execution.rs:12:20
+ |
+LL | println!("{}", FOO);
+ | ^^^ referenced constant has errors
+ |
+note: the lint level is defined here
+ --> $DIR/conditional_array_execution.rs:3:9
+ |
+LL | #![warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = note: this warning originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr
index 26728cf5415..1c74b978827 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr
@@ -12,3 +12,20 @@ LL | NEG_NEG_128 => println!("A"),
error: aborting due to 2 previous errors
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/const-eval-overflow-2.rs:11:25
+ |
+LL | const NEG_NEG_128: i8 = -NEG_128;
+ | ------------------------^^^^^^^^-
+ | |
+ | attempt to negate `i8::MIN`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow-2.rs:4:36
+ |
+LL | #![allow(unused_imports, warnings, const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2.stderr
index 66e86c352d1..948ead521ea 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow2.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow2.stderr
@@ -107,3 +107,153 @@ LL | | );
error: aborting due to 8 previous errors
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2.rs:14:6
+ |
+LL | / const VALS_I8: (i8,) =
+LL | | (
+LL | | i8::MIN - 1,
+ | | ^^^^^^^^^^^ attempt to compute `i8::MIN - 1_i8`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2.rs:21:6
+ |
+LL | / const VALS_I16: (i16,) =
+LL | | (
+LL | | i16::MIN - 1,
+ | | ^^^^^^^^^^^^ attempt to compute `i16::MIN - 1_i16`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2.rs:28:6
+ |
+LL | / const VALS_I32: (i32,) =
+LL | | (
+LL | | i32::MIN - 1,
+ | | ^^^^^^^^^^^^ attempt to compute `i32::MIN - 1_i32`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2.rs:35:6
+ |
+LL | / const VALS_I64: (i64,) =
+LL | | (
+LL | | i64::MIN - 1,
+ | | ^^^^^^^^^^^^ attempt to compute `i64::MIN - 1_i64`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2.rs:42:6
+ |
+LL | / const VALS_U8: (u8,) =
+LL | | (
+LL | | u8::MIN - 1,
+ | | ^^^^^^^^^^^ attempt to compute `0_u8 - 1_u8`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2.rs:48:6
+ |
+LL | / const VALS_U16: (u16,) = (
+LL | | u16::MIN - 1,
+ | | ^^^^^^^^^^^^ attempt to compute `0_u16 - 1_u16`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2.rs:54:6
+ |
+LL | / const VALS_U32: (u32,) = (
+LL | | u32::MIN - 1,
+ | | ^^^^^^^^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2.rs:61:6
+ |
+LL | / const VALS_U64: (u64,) =
+LL | | (
+LL | | u64::MIN - 1,
+ | | ^^^^^^^^^^^^ attempt to compute `0_u64 - 1_u64`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr
index 3401ba47765..5db6a49a98b 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr
@@ -107,3 +107,153 @@ LL | | );
error: aborting due to 8 previous errors
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2b.rs:14:6
+ |
+LL | / const VALS_I8: (i8,) =
+LL | | (
+LL | | i8::MAX + 1,
+ | | ^^^^^^^^^^^ attempt to compute `i8::MAX + 1_i8`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2b.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2b.rs:21:6
+ |
+LL | / const VALS_I16: (i16,) =
+LL | | (
+LL | | i16::MAX + 1,
+ | | ^^^^^^^^^^^^ attempt to compute `i16::MAX + 1_i16`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2b.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2b.rs:28:6
+ |
+LL | / const VALS_I32: (i32,) =
+LL | | (
+LL | | i32::MAX + 1,
+ | | ^^^^^^^^^^^^ attempt to compute `i32::MAX + 1_i32`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2b.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2b.rs:35:6
+ |
+LL | / const VALS_I64: (i64,) =
+LL | | (
+LL | | i64::MAX + 1,
+ | | ^^^^^^^^^^^^ attempt to compute `i64::MAX + 1_i64`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2b.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2b.rs:42:6
+ |
+LL | / const VALS_U8: (u8,) =
+LL | | (
+LL | | u8::MAX + 1,
+ | | ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2b.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2b.rs:48:6
+ |
+LL | / const VALS_U16: (u16,) = (
+LL | | u16::MAX + 1,
+ | | ^^^^^^^^^^^^ attempt to compute `u16::MAX + 1_u16`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2b.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2b.rs:54:6
+ |
+LL | / const VALS_U32: (u32,) = (
+LL | | u32::MAX + 1,
+ | | ^^^^^^^^^^^^ attempt to compute `u32::MAX + 1_u32`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2b.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2b.rs:61:6
+ |
+LL | / const VALS_U64: (u64,) =
+LL | | (
+LL | | u64::MAX + 1,
+ | | ^^^^^^^^^^^^ attempt to compute `u64::MAX + 1_u64`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2b.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr
index 93c64090f0e..ec3f3c11059 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr
@@ -107,3 +107,153 @@ LL | | );
error: aborting due to 8 previous errors
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2c.rs:14:6
+ |
+LL | / const VALS_I8: (i8,) =
+LL | | (
+LL | | i8::MIN * 2,
+ | | ^^^^^^^^^^^ attempt to compute `i8::MIN * 2_i8`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2c.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2c.rs:21:6
+ |
+LL | / const VALS_I16: (i16,) =
+LL | | (
+LL | | i16::MIN * 2,
+ | | ^^^^^^^^^^^^ attempt to compute `i16::MIN * 2_i16`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2c.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2c.rs:28:6
+ |
+LL | / const VALS_I32: (i32,) =
+LL | | (
+LL | | i32::MIN * 2,
+ | | ^^^^^^^^^^^^ attempt to compute `i32::MIN * 2_i32`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2c.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2c.rs:35:6
+ |
+LL | / const VALS_I64: (i64,) =
+LL | | (
+LL | | i64::MIN * 2,
+ | | ^^^^^^^^^^^^ attempt to compute `i64::MIN * 2_i64`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2c.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2c.rs:42:6
+ |
+LL | / const VALS_U8: (u8,) =
+LL | | (
+LL | | u8::MAX * 2,
+ | | ^^^^^^^^^^^ attempt to compute `u8::MAX * 2_u8`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2c.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2c.rs:48:6
+ |
+LL | / const VALS_U16: (u16,) = (
+LL | | u16::MAX * 2,
+ | | ^^^^^^^^^^^^ attempt to compute `u16::MAX * 2_u16`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2c.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2c.rs:54:6
+ |
+LL | / const VALS_U32: (u32,) = (
+LL | | u32::MAX * 2,
+ | | ^^^^^^^^^^^^ attempt to compute `u32::MAX * 2_u32`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2c.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-eval-overflow2c.rs:61:6
+ |
+LL | / const VALS_U64: (u64,) =
+LL | | (
+LL | | u64::MAX * 2,
+ | | ^^^^^^^^^^^^ attempt to compute `u64::MAX * 2_u64`, which would overflow
+LL | | );
+ | |_______-
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-overflow2c.rs:8:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr
index b74d5a2722b..bbec2a830e6 100644
--- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr
@@ -35,3 +35,31 @@ query stack during panic:
#1 [optimized_mir] optimizing MIR for `main`
#2 [collect_and_partition_mono_items] collect_and_partition_mono_items
end of query stack
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/const-eval-query-stack.rs:19:16
+ |
+LL | const X: i32 = 1 / 0;
+ | ---------------^^^^^-
+ | |
+ | attempt to divide `1_i32` by zero
+ |
+note: the lint level is defined here
+ --> $DIR/const-eval-query-stack.rs:18:8
+ |
+LL | #[warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: erroneous constant used
+ --> $DIR/const-eval-query-stack.rs:23:27
+ |
+LL | let x: &'static i32 = &X;
+ | ^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr
index c19f6342b5b..b004637fd83 100644
--- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr
+++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr
@@ -321,3 +321,354 @@ LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.charact
error: aborting due to 29 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:26:49
+ |
+LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u };
+ | --------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:30:43
+ |
+LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 };
+ | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:34:45
+ |
+LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 };
+ | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:38:45
+ |
+LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 };
+ | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:42:45
+ |
+LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 };
+ | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:49:43
+ |
+LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
+ | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:53:45
+ |
+LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 };
+ | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:57:45
+ |
+LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 };
+ | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:61:45
+ |
+LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
+ | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:68:45
+ |
+LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
+ | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:72:45
+ |
+LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
+ | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:76:47
+ |
+LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey };
+ | ------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:80:47
+ |
+LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character };
+ | ------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:84:39
+ |
+LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
+ | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:88:41
+ |
+LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 };
+ | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:92:41
+ |
+LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 };
+ | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:96:41
+ |
+LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
+ | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:100:43
+ |
+LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 };
+ | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:104:39
+ |
+LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
+ | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:108:41
+ |
+LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
+ | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:112:41
+ |
+LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
+ | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:116:41
+ |
+LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
+ | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:120:43
+ |
+LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 };
+ | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:124:41
+ |
+LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 };
+ | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:128:41
+ |
+LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
+ | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:132:43
+ |
+LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey };
+ | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-pointer-values-in-various-types.rs:136:43
+ |
+LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character };
+ | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
index c17166263ba..daf3d8927c1 100644
--- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
+++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
@@ -21,3 +21,79 @@ LL | x(y)
error: aborting due to 2 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/const_fn_ptr_fail2.rs:12:5
+ |
+LL | x(y)
+ | ^^^^
+ | |
+ | calling non-const function `double`
+ | inside `bar` at $DIR/const_fn_ptr_fail2.rs:12:5
+ | inside `Y` at $DIR/const_fn_ptr_fail2.rs:15:18
+...
+LL | const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday
+ | ---------------------------
+ |
+note: the lint level is defined here
+ --> $DIR/const_fn_ptr_fail2.rs:4:10
+ |
+LL | #![allow(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/const_fn_ptr_fail2.rs:12:5
+ |
+LL | x(y)
+ | ^^^^
+ | |
+ | calling non-const function `double`
+ | inside `bar` at $DIR/const_fn_ptr_fail2.rs:12:5
+ | inside `Z` at $DIR/const_fn_ptr_fail2.rs:16:18
+...
+LL | const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday
+ | --------------------------------
+ |
+note: the lint level is defined here
+ --> $DIR/const_fn_ptr_fail2.rs:4:10
+ |
+LL | #![allow(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+warning: erroneous constant used
+ --> $DIR/const_fn_ptr_fail2.rs:19:5
+ |
+LL | assert_eq!(Y, 4);
+ | ^^^^^^^^^^^^^^^^ referenced constant has errors
+ |
+note: the lint level is defined here
+ --> $DIR/const_fn_ptr_fail2.rs:4:10
+ |
+LL | #![allow(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = note: this warning originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+warning: erroneous constant used
+ --> $DIR/const_fn_ptr_fail2.rs:21:5
+ |
+LL | assert_eq!(Z, 4);
+ | ^^^^^^^^^^^^^^^^ referenced constant has errors
+ |
+note: the lint level is defined here
+ --> $DIR/const_fn_ptr_fail2.rs:4:10
+ |
+LL | #![allow(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = note: this warning originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/src/test/ui/consts/const-eval/erroneous-const.stderr b/src/test/ui/consts/const-eval/erroneous-const.stderr
index 7e2a60929c7..9057b58ded9 100644
--- a/src/test/ui/consts/const-eval/erroneous-const.stderr
+++ b/src/test/ui/consts/const-eval/erroneous-const.stderr
@@ -41,3 +41,20 @@ LL | pub static FOO: () = no_codegen::<i32>();
error: aborting due to previous error; 2 warnings emitted
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/erroneous-const.rs:6:22
+ |
+LL | const VOID: () = [()][2];
+ | -----------------^^^^^^^-
+ | |
+ | index out of bounds: the length is 1 but the index is 2
+ |
+note: the lint level is defined here
+ --> $DIR/erroneous-const.rs:2:9
+ |
+LL | #![warn(const_err, unconditional_panic)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/erroneous-const2.stderr b/src/test/ui/consts/const-eval/erroneous-const2.stderr
index 813d3ee249f..bf6cc8410a7 100644
--- a/src/test/ui/consts/const-eval/erroneous-const2.stderr
+++ b/src/test/ui/consts/const-eval/erroneous-const2.stderr
@@ -35,3 +35,20 @@ LL | let _ = PrintName::<i32>::VOID;
error: aborting due to previous error; 2 warnings emitted
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/erroneous-const2.rs:6:22
+ |
+LL | const VOID: () = [()][2];
+ | -----------------^^^^^^^-
+ | |
+ | index out of bounds: the length is 1 but the index is 2
+ |
+note: the lint level is defined here
+ --> $DIR/erroneous-const2.rs:2:9
+ |
+LL | #![warn(const_err, unconditional_panic)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/format.stderr b/src/test/ui/consts/const-eval/format.stderr
index 44f436ae4e3..b00cadcea99 100644
--- a/src/test/ui/consts/const-eval/format.stderr
+++ b/src/test/ui/consts/const-eval/format.stderr
@@ -76,3 +76,49 @@ LL | println!("{:?}", 0);
error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0015`.
+Future incompatibility report: Future breakage diagnostic:
+error: erroneous constant used
+ --> $DIR/format.rs:2:12
+ |
+LL | panic!("{:?}", 0);
+ | ^^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: erroneous constant used
+ --> $DIR/format.rs:2:20
+ |
+LL | panic!("{:?}", 0);
+ | ^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = note: this error originates in the macro `$crate::const_format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+error: erroneous constant used
+ --> $DIR/format.rs:11:14
+ |
+LL | println!("{:?}", 0);
+ | ^^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: erroneous constant used
+ --> $DIR/format.rs:11:22
+ |
+LL | println!("{:?}", 0);
+ | ^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr
index 73664fa49d1..7b3e46fccca 100644
--- a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr
+++ b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr
@@ -22,3 +22,20 @@ LL | let _ = PrintName::<T>::VOID;
error: aborting due to previous error; 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/index-out-of-bounds-never-type.rs:10:61
+ |
+LL | const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] };
+ | --------------------------------------------------------^^^^^---
+ | |
+ | index out of bounds: the length is 0 but the index is 0
+ |
+note: the lint level is defined here
+ --> $DIR/index-out-of-bounds-never-type.rs:4:9
+ |
+LL | #![warn(const_err, unconditional_panic)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/issue-43197.stderr b/src/test/ui/consts/const-eval/issue-43197.stderr
index 32ab7c74b89..53ed32638ce 100644
--- a/src/test/ui/consts/const-eval/issue-43197.stderr
+++ b/src/test/ui/consts/const-eval/issue-43197.stderr
@@ -60,3 +60,69 @@ LL | println!("{} {}", X, Y);
error: aborting due to 2 previous errors; 4 warnings emitted
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/issue-43197.rs:10:20
+ |
+LL | const X: u32 = 0 - 1;
+ | ---------------^^^^^-
+ | |
+ | attempt to compute `0_u32 - 1_u32`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/issue-43197.rs:3:9
+ |
+LL | #![warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/issue-43197.rs:13:24
+ |
+LL | const Y: u32 = foo(0 - 1);
+ | -------------------^^^^^--
+ | |
+ | attempt to compute `0_u32 - 1_u32`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/issue-43197.rs:3:9
+ |
+LL | #![warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+warning: erroneous constant used
+ --> $DIR/issue-43197.rs:16:23
+ |
+LL | println!("{} {}", X, Y);
+ | ^ referenced constant has errors
+ |
+note: the lint level is defined here
+ --> $DIR/issue-43197.rs:3:9
+ |
+LL | #![warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = note: this warning originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+warning: erroneous constant used
+ --> $DIR/issue-43197.rs:16:26
+ |
+LL | println!("{} {}", X, Y);
+ | ^ referenced constant has errors
+ |
+note: the lint level is defined here
+ --> $DIR/issue-43197.rs:3:9
+ |
+LL | #![warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = note: this warning originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/src/test/ui/consts/const-eval/issue-44578.stderr b/src/test/ui/consts/const-eval/issue-44578.stderr
index bff9f40f82b..5ecdb7ef556 100644
--- a/src/test/ui/consts/const-eval/issue-44578.stderr
+++ b/src/test/ui/consts/const-eval/issue-44578.stderr
@@ -7,3 +7,36 @@ LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/issue-44578.rs:15:24
+ |
+LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
+ | -------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | index out of bounds: the length is 1 but the index is 1
+ |
+note: the lint level is defined here
+ --> $DIR/issue-44578.rs:3:10
+ |
+LL | #![allow(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+warning: erroneous constant used
+ --> $DIR/issue-44578.rs:27:20
+ |
+LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ |
+note: the lint level is defined here
+ --> $DIR/issue-44578.rs:3:10
+ |
+LL | #![allow(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = note: this warning originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/src/test/ui/consts/const-eval/issue-50814-2.stderr b/src/test/ui/consts/const-eval/issue-50814-2.stderr
index 298f0a4a446..67af3b2b1d3 100644
--- a/src/test/ui/consts/const-eval/issue-50814-2.stderr
+++ b/src/test/ui/consts/const-eval/issue-50814-2.stderr
@@ -25,3 +25,16 @@ LL | println!("{:x}", foo::<()>() as *const usize as usize);
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/issue-50814-2.rs:14:24
+ |
+LL | const BAR: usize = [5, 6, 7][T::BOO];
+ | -------------------^^^^^^^^^^^^^^^^^-
+ | |
+ | index out of bounds: the length is 3 but the index is 42
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/issue-50814.stderr b/src/test/ui/consts/const-eval/issue-50814.stderr
index 87bea28e763..b82bc9ca2f8 100644
--- a/src/test/ui/consts/const-eval/issue-50814.stderr
+++ b/src/test/ui/consts/const-eval/issue-50814.stderr
@@ -25,3 +25,16 @@ LL | foo(0);
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/issue-50814.rs:15:21
+ |
+LL | const MAX: u8 = A::MAX + B::MAX;
+ | ----------------^^^^^^^^^^^^^^^-
+ | |
+ | attempt to compute `u8::MAX + u8::MAX`, which would overflow
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/issue-85907.rs b/src/test/ui/consts/const-eval/issue-85907.rs
new file mode 100644
index 00000000000..6ae40ae6ddb
--- /dev/null
+++ b/src/test/ui/consts/const-eval/issue-85907.rs
@@ -0,0 +1,7 @@
+const fn hey() -> usize {
+ panic!(123); //~ ERROR argument to `panic!()` in a const context must have type `&str`
+}
+
+fn main() {
+ let _: [u8; hey()] = todo!();
+}
diff --git a/src/test/ui/consts/const-eval/issue-85907.stderr b/src/test/ui/consts/const-eval/issue-85907.stderr
new file mode 100644
index 00000000000..381f2fd1114
--- /dev/null
+++ b/src/test/ui/consts/const-eval/issue-85907.stderr
@@ -0,0 +1,10 @@
+error: argument to `panic!()` in a const context must have type `&str`
+ --> $DIR/issue-85907.rs:2:5
+ |
+LL | panic!(123);
+ | ^^^^^^^^^^^
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr b/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr
index a18c7e78d95..1a7d3861420 100644
--- a/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr
+++ b/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr
@@ -18,3 +18,22 @@ LL | | };
error: aborting due to previous error
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/partial_ptr_overwrite.rs:8:9
+ |
+LL | / const PARTIAL_OVERWRITE: () = {
+LL | | let mut p = &42;
+LL | | unsafe {
+LL | | let ptr: *mut _ = &mut p;
+LL | | *(ptr as *mut u8) = 123;
+ | | ^^^^^^^^^^^^^^^^^^^^^^^ unable to overwrite parts of a pointer in memory at alloc4
+... |
+LL | | let x = *p;
+LL | | };
+ | |__-
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr b/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr
index 5bfd4ef92a9..be845339dfe 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr
@@ -85,3 +85,53 @@ LL | | };
warning: 7 warnings emitted
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/promoted_errors.rs:15:5
+ |
+LL | 0 - 1
+ | ^^^^^
+ | |
+ | attempt to compute `0_u32 - 1_u32`, which would overflow
+ | inside `overflow` at $DIR/promoted_errors.rs:15:5
+ | inside `X` at $DIR/promoted_errors.rs:43:29
+...
+LL | / const X: () = {
+LL | | let _x: &'static u32 = &overflow();
+LL | |
+LL | |
+... |
+LL | | let _x: &'static i32 = &oob();
+LL | | };
+ | |__-
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:11:9
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/promoted_errors.rs:43:28
+ |
+LL | / const X: () = {
+LL | | let _x: &'static u32 = &overflow();
+ | | ^^^^^^^^^^^ referenced constant has errors
+LL | |
+LL | |
+... |
+LL | | let _x: &'static i32 = &oob();
+LL | | };
+ | |__-
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:11:9
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/promoted_errors.opt.stderr b/src/test/ui/consts/const-eval/promoted_errors.opt.stderr
index 0a8a8aef3cf..c91d52336c3 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.opt.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors.opt.stderr
@@ -86,3 +86,54 @@ LL | | };
warning: 7 warnings emitted
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/promoted_errors.rs:21:5
+ |
+LL | 1 / 0
+ | ^^^^^
+ | |
+ | attempt to divide `1_i32` by zero
+ | inside `div_by_zero1` at $DIR/promoted_errors.rs:21:5
+ | inside `X` at $DIR/promoted_errors.rs:46:29
+...
+LL | / const X: () = {
+LL | | let _x: &'static u32 = &overflow();
+LL | |
+LL | |
+... |
+LL | | let _x: &'static i32 = &oob();
+LL | | };
+ | |__-
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:11:9
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/promoted_errors.rs:46:28
+ |
+LL | / const X: () = {
+LL | | let _x: &'static u32 = &overflow();
+LL | |
+LL | |
+LL | | let _x: &'static i32 = &div_by_zero1();
+ | | ^^^^^^^^^^^^^^^ referenced constant has errors
+... |
+LL | | let _x: &'static i32 = &oob();
+LL | | };
+ | |__-
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:11:9
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr b/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr
index 5bfd4ef92a9..be845339dfe 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr
@@ -85,3 +85,53 @@ LL | | };
warning: 7 warnings emitted
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/promoted_errors.rs:15:5
+ |
+LL | 0 - 1
+ | ^^^^^
+ | |
+ | attempt to compute `0_u32 - 1_u32`, which would overflow
+ | inside `overflow` at $DIR/promoted_errors.rs:15:5
+ | inside `X` at $DIR/promoted_errors.rs:43:29
+...
+LL | / const X: () = {
+LL | | let _x: &'static u32 = &overflow();
+LL | |
+LL | |
+... |
+LL | | let _x: &'static i32 = &oob();
+LL | | };
+ | |__-
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:11:9
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/promoted_errors.rs:43:28
+ |
+LL | / const X: () = {
+LL | | let _x: &'static u32 = &overflow();
+ | | ^^^^^^^^^^^ referenced constant has errors
+LL | |
+LL | |
+... |
+LL | | let _x: &'static i32 = &oob();
+LL | | };
+ | |__-
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:11:9
+ |
+LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/pub_const_err.stderr b/src/test/ui/consts/const-eval/pub_const_err.stderr
index dd47dca2b2e..56d66827626 100644
--- a/src/test/ui/consts/const-eval/pub_const_err.stderr
+++ b/src/test/ui/consts/const-eval/pub_const_err.stderr
@@ -16,3 +16,20 @@ LL | #![warn(const_err)]
warning: 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/pub_const_err.rs:6:20
+ |
+LL | pub const Z: u32 = 0 - 1;
+ | -------------------^^^^^-
+ | |
+ | attempt to compute `0_u32 - 1_u32`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/pub_const_err.rs:2:9
+ |
+LL | #![warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/pub_const_err_bin.stderr b/src/test/ui/consts/const-eval/pub_const_err_bin.stderr
index 9f413fb8fd7..202ea781e97 100644
--- a/src/test/ui/consts/const-eval/pub_const_err_bin.stderr
+++ b/src/test/ui/consts/const-eval/pub_const_err_bin.stderr
@@ -16,3 +16,20 @@ LL | #![warn(const_err)]
warning: 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/pub_const_err_bin.rs:4:20
+ |
+LL | pub const Z: u32 = 0 - 1;
+ | -------------------^^^^^-
+ | |
+ | attempt to compute `0_u32 - 1_u32`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/pub_const_err_bin.rs:2:9
+ |
+LL | #![warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr b/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr
index 83ac6c90a43..a55fd8c156e 100644
--- a/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr
@@ -24,3 +24,16 @@ LL | 10..=BAR => {},
error: aborting due to 3 previous errors
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ref_to_int_match.rs:25:27
+ |
+LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
+ | --------------------------^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr b/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr
index 83ac6c90a43..a55fd8c156e 100644
--- a/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr
@@ -24,3 +24,16 @@ LL | 10..=BAR => {},
error: aborting due to 3 previous errors
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ref_to_int_match.rs:25:27
+ |
+LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
+ | --------------------------^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr
index c6fa14d0534..2440cd2272c 100644
--- a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr
@@ -125,3 +125,58 @@ LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe {
error: aborting due to 13 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-enum.rs:26:1
+ |
+LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-enum.rs:30:1
+ |
+LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-enum.rs:45:1
+ |
+LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-enum.rs:49:1
+ |
+LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-enum.rs:63:1
+ |
+LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr
index 25be593ab83..e9b4023068e 100644
--- a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr
@@ -125,3 +125,58 @@ LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe {
error: aborting due to 13 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-enum.rs:26:1
+ |
+LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-enum.rs:30:1
+ |
+LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-enum.rs:45:1
+ |
+LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-enum.rs:49:1
+ |
+LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-enum.rs:63:1
+ |
+LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
index 8a4f23c033e..10a0ccd552b 100644
--- a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
@@ -176,3 +176,66 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
error: aborting due to 16 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-ref-ptr.rs:31:1
+ |
+LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-ref-ptr.rs:35:39
+ |
+LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
+ | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-ref-ptr.rs:35:38
+ |
+LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
+ | -------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-ref-ptr.rs:41:86
+ |
+LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
+ | -------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^----
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-ref-ptr.rs:41:85
+ |
+LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
+ | ------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^----
+ | |
+ | referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
index da1c6d1a07f..e9fcefe12c7 100644
--- a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
@@ -176,3 +176,66 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
error: aborting due to 16 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-ref-ptr.rs:31:1
+ |
+LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-ref-ptr.rs:35:39
+ |
+LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
+ | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-ref-ptr.rs:35:38
+ |
+LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
+ | -------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-ref-ptr.rs:41:86
+ |
+LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
+ | -------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^----
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-ref-ptr.rs:41:85
+ |
+LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
+ | ------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^----
+ | |
+ | referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
index a78cff11589..0c398f5bfd4 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
@@ -344,3 +344,86 @@ LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
error: aborting due to 32 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-wide-ptr.rs:42:1
+ |
+LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-wide-ptr.rs:46:1
+ |
+LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-wide-ptr.rs:75:1
+ |
+LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-wide-ptr.rs:82:1
+ |
+LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-wide-ptr.rs:87:40
+ |
+LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
+ | ---------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-wide-ptr.rs:95:42
+ |
+LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
+ | -----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-wide-ptr.rs:100:42
+ |
+LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
+ | -----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
index 69a61d9caed..bf53995d956 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
@@ -344,3 +344,86 @@ LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
error: aborting due to 32 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-wide-ptr.rs:42:1
+ |
+LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-wide-ptr.rs:46:1
+ |
+LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-wide-ptr.rs:75:1
+ |
+LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-wide-ptr.rs:82:1
+ |
+LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-wide-ptr.rs:87:40
+ |
+LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
+ | ---------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-wide-ptr.rs:95:42
+ |
+LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
+ | -----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ub-wide-ptr.rs:100:42
+ |
+LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
+ | -----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-eval/unused-broken-const.stderr b/src/test/ui/consts/const-eval/unused-broken-const.stderr
index 2ce60ec16a3..bfc076aa5e6 100644
--- a/src/test/ui/consts/const-eval/unused-broken-const.stderr
+++ b/src/test/ui/consts/const-eval/unused-broken-const.stderr
@@ -12,3 +12,16 @@ LL | const FOO: i32 = [][0];
error: aborting due to previous error
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/unused-broken-const.rs:5:18
+ |
+LL | const FOO: i32 = [][0];
+ | -----------------^^^^^-
+ | |
+ | index out of bounds: the length is 0 but the index is 0
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-external-macro-const-err.stderr b/src/test/ui/consts/const-external-macro-const-err.stderr
index a66d79a1616..205ee92dfd7 100644
--- a/src/test/ui/consts/const-external-macro-const-err.stderr
+++ b/src/test/ui/consts/const-external-macro-const-err.stderr
@@ -11,3 +11,15 @@ LL | static_assert!(2 + 2 == 5);
error: aborting due to previous error
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-external-macro-const-err.rs:12:5
+ |
+LL | static_assert!(2 + 2 == 5);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = note: this error originates in the macro `static_assert` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/src/test/ui/consts/const-float-bits-reject-conv.stderr b/src/test/ui/consts/const-float-bits-reject-conv.stderr
index f3fd098e848..d822171df72 100644
--- a/src/test/ui/consts/const-float-bits-reject-conv.stderr
+++ b/src/test/ui/consts/const-float-bits-reject-conv.stderr
@@ -214,3 +214,115 @@ LL | const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);
error: aborting due to 12 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-float-bits-reject-conv.rs:30:34
+ |
+LL | const _: () = assert!($a);
+ | --------------------------
+...
+LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan());
+ | ^^^^^^^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-float-bits-reject-conv.rs:33:34
+ |
+LL | const _: () = assert!($a);
+ | --------------------------
+...
+LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan());
+ | ^^^^^^^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-float-bits-reject-conv.rs:41:38
+ |
+LL | const _: () = assert!($a == $b);
+ | --------------------------------
+...
+LL | const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1);
+ | ^^^^^^^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-float-bits-reject-conv.rs:44:38
+ |
+LL | const _: () = assert!($a == $b);
+ | --------------------------------
+...
+LL | const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);
+ | ^^^^^^^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-float-bits-reject-conv.rs:57:34
+ |
+LL | const _: () = assert!($a);
+ | --------------------------
+...
+LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan());
+ | ^^^^^^^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-float-bits-reject-conv.rs:60:34
+ |
+LL | const _: () = assert!($a);
+ | --------------------------
+...
+LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan());
+ | ^^^^^^^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-float-bits-reject-conv.rs:66:38
+ |
+LL | const _: () = assert!($a == $b);
+ | --------------------------------
+...
+LL | const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1);
+ | ^^^^^^^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-float-bits-reject-conv.rs:69:38
+ |
+LL | const _: () = assert!($a == $b);
+ | --------------------------------
+...
+LL | const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);
+ | ^^^^^^^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-len-underflow-separate-spans.stderr b/src/test/ui/consts/const-len-underflow-separate-spans.stderr
index 70f645a6c40..0c10783476a 100644
--- a/src/test/ui/consts/const-len-underflow-separate-spans.stderr
+++ b/src/test/ui/consts/const-len-underflow-separate-spans.stderr
@@ -19,3 +19,16 @@ LL | let a: [i8; LEN] = unimplemented!();
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-len-underflow-separate-spans.rs:7:20
+ |
+LL | const LEN: usize = ONE - TWO;
+ | -------------------^^^^^^^^^-
+ | |
+ | attempt to compute `1_usize - 2_usize`, which would overflow
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-prop-read-static-in-const.stderr b/src/test/ui/consts/const-prop-read-static-in-const.stderr
index 94d3f1c6145..a60cd16f05a 100644
--- a/src/test/ui/consts/const-prop-read-static-in-const.stderr
+++ b/src/test/ui/consts/const-prop-read-static-in-const.stderr
@@ -20,3 +20,16 @@ LL | const TEST: u8 = MY_STATIC;
error: aborting due to previous error; 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-prop-read-static-in-const.rs:5:18
+ |
+LL | const TEST: u8 = MY_STATIC;
+ | -----------------^^^^^^^^^-
+ | |
+ | constant accesses static
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr b/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr
index a9211c17a6b..c6e0b321124 100644
--- a/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr
+++ b/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr
@@ -23,3 +23,29 @@ LL | const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const
error: aborting due to 2 previous errors
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-size_of_val-align_of_val-extern-type.rs:11:31
+ |
+LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) };
+ | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | `extern type` does not have known layout
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-size_of_val-align_of_val-extern-type.rs:13:32
+ |
+LL | const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) };
+ | -------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | `extern type` does not have known layout
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const-slice-oob.stderr b/src/test/ui/consts/const-slice-oob.stderr
index 6d2c79034d3..c9f949727bc 100644
--- a/src/test/ui/consts/const-slice-oob.stderr
+++ b/src/test/ui/consts/const-slice-oob.stderr
@@ -12,3 +12,16 @@ LL | const BAR: u32 = FOO[5];
error: aborting due to previous error
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const-slice-oob.rs:4:18
+ |
+LL | const BAR: u32 = FOO[5];
+ | -----------------^^^^^^-
+ | |
+ | index out of bounds: the length is 3 but the index is 5
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr b/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr
index 5e706a4466e..ee95b0d5180 100644
--- a/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr
+++ b/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr
@@ -17,3 +17,21 @@ LL | | };
error: aborting due to previous error
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/const_eval_limit_reached.rs:6:11
+ |
+LL | / const X: usize = {
+LL | | let mut x = 0;
+LL | | while x != 1000 {
+ | | ^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
+LL | |
+... |
+LL | | x
+LL | | };
+ | |__-
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/invalid-union.32bit.stderr b/src/test/ui/consts/invalid-union.32bit.stderr
index 38c38d1ae67..bd7c95342f7 100644
--- a/src/test/ui/consts/invalid-union.32bit.stderr
+++ b/src/test/ui/consts/invalid-union.32bit.stderr
@@ -22,3 +22,14 @@ LL | let _: &'static _ = &C;
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: erroneous constant used
+ --> $DIR/invalid-union.rs:41:25
+ |
+LL | let _: &'static _ = &C;
+ | ^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/invalid-union.64bit.stderr b/src/test/ui/consts/invalid-union.64bit.stderr
index 6bfa97a2fde..0d8b8ffcc16 100644
--- a/src/test/ui/consts/invalid-union.64bit.stderr
+++ b/src/test/ui/consts/invalid-union.64bit.stderr
@@ -22,3 +22,14 @@ LL | let _: &'static _ = &C;
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: erroneous constant used
+ --> $DIR/invalid-union.rs:41:25
+ |
+LL | let _: &'static _ = &C;
+ | ^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/issue-56164.stderr b/src/test/ui/consts/issue-56164.stderr
index 3b80b3486a8..73a0f8ec0d0 100644
--- a/src/test/ui/consts/issue-56164.stderr
+++ b/src/test/ui/consts/issue-56164.stderr
@@ -26,3 +26,14 @@ LL | const fn foo() { (||{})() }
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0015`.
+Future incompatibility report: Future breakage diagnostic:
+error: erroneous constant used
+ --> $DIR/issue-56164.rs:1:18
+ |
+LL | const fn foo() { (||{})() }
+ | ^^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/issue-66693.stderr b/src/test/ui/consts/issue-66693.stderr
index b8257684983..929f905ae91 100644
--- a/src/test/ui/consts/issue-66693.stderr
+++ b/src/test/ui/consts/issue-66693.stderr
@@ -34,3 +34,14 @@ LL | panic!(&1);
error: aborting due to 4 previous errors
+Future incompatibility report: Future breakage diagnostic:
+error: erroneous constant used
+ --> $DIR/issue-66693.rs:11:12
+ |
+LL | panic!(&1);
+ | ^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/issue-miri-1910.stderr b/src/test/ui/consts/issue-miri-1910.stderr
index 87882449c73..e76a1f96b46 100644
--- a/src/test/ui/consts/issue-miri-1910.stderr
+++ b/src/test/ui/consts/issue-miri-1910.stderr
@@ -24,3 +24,28 @@ LL | | };
error: aborting due to previous error
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ |
+LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | unable to turn pointer into raw bytes
+ | inside `std::ptr::read::<u8>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ | inside `ptr::const_ptr::<impl *const u8>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | inside `C` at $DIR/issue-miri-1910.rs:7:5
+ |
+ ::: $DIR/issue-miri-1910.rs:4:1
+ |
+LL | / const C: () = unsafe {
+LL | | let foo = Some(&42 as *const i32);
+LL | | let one_and_a_half_pointers = std::mem::size_of::<*const i32>()/2*3;
+LL | | (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read();
+LL | | };
+ | |__-
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/miri_unleashed/assoc_const.stderr b/src/test/ui/consts/miri_unleashed/assoc_const.stderr
index 193a49bb266..1765c9ed10a 100644
--- a/src/test/ui/consts/miri_unleashed/assoc_const.stderr
+++ b/src/test/ui/consts/miri_unleashed/assoc_const.stderr
@@ -15,3 +15,28 @@ LL | const F: u32 = (U::X, 42).1;
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ |
+LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | calling non-const function `<Vec<u32> as Drop>::drop`
+ | inside `std::ptr::drop_in_place::<Vec<u32>> - shim(Some(Vec<u32>))` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ | inside `std::ptr::drop_in_place::<(Vec<u32>, u32)> - shim(Some((Vec<u32>, u32)))` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ | inside `<String as Bar<Vec<u32>, String>>::F` at $DIR/assoc_const.rs:14:31
+ |
+ ::: $DIR/assoc_const.rs:14:5
+ |
+LL | const F: u32 = (U::X, 42).1;
+ | ----------------------------
+ |
+note: the lint level is defined here
+ --> $DIR/assoc_const.rs:4:10
+ |
+LL | #![allow(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr b/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr
index e15717979c5..f7be42de03f 100644
--- a/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr
+++ b/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr
@@ -7,3 +7,20 @@ LL | let y = <String as Bar<String>>::F;
error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/assoc_const_2.rs:12:20
+ |
+LL | const F: u32 = 100 / U::X;
+ | ---------------^^^^^^^^^^-
+ | |
+ | attempt to divide `100_u32` by zero
+ |
+note: the lint level is defined here
+ --> $DIR/assoc_const_2.rs:3:10
+ |
+LL | #![allow(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr
index c48f59fe848..98d4dff648a 100644
--- a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr
+++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr
@@ -47,3 +47,58 @@ LL | const READ_MUT: u32 = unsafe { MUTABLE };
error: aborting due to 3 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/const_refers_to_static.rs:13:5
+ |
+LL | / const MUTATE_INTERIOR_MUT: usize = {
+LL | | static FOO: AtomicUsize = AtomicUsize::new(0);
+LL | | FOO.fetch_add(1, Ordering::Relaxed)
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling non-const function `AtomicUsize::fetch_add`
+LL | | };
+ | |__-
+ |
+note: the lint level is defined here
+ --> $DIR/const_refers_to_static.rs:3:10
+ |
+LL | #![allow(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/const_refers_to_static.rs:18:14
+ |
+LL | / const READ_INTERIOR_MUT: usize = {
+LL | | static FOO: AtomicUsize = AtomicUsize::new(0);
+LL | | unsafe { *(&FOO as *const _ as *const usize) }
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
+LL | | };
+ | |__-
+ |
+note: the lint level is defined here
+ --> $DIR/const_refers_to_static.rs:3:10
+ |
+LL | #![allow(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/const_refers_to_static.rs:22:32
+ |
+LL | const READ_MUT: u32 = unsafe { MUTABLE };
+ | -------------------------------^^^^^^^---
+ | |
+ | constant accesses static
+ |
+note: the lint level is defined here
+ --> $DIR/const_refers_to_static.rs:3:10
+ |
+LL | #![allow(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
index 186c5b1856b..2a0766294d3 100644
--- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
+++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
@@ -170,3 +170,45 @@ LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None =>
error: aborting due to 10 previous errors; 3 warnings emitted
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/const_refers_to_static_cross_crate.rs:25:15
+ |
+LL | / const U8_MUT2: &u8 = {
+LL | | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
+LL | |
+LL | |
+LL | |
+LL | | };
+ | |__-
+ |
+note: the lint level is defined here
+ --> $DIR/const_refers_to_static_cross_crate.rs:23:8
+ |
+LL | #[warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/const_refers_to_static_cross_crate.rs:32:20
+ |
+LL | / const U8_MUT3: &u8 = {
+LL | | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
+LL | |
+LL | |
+LL | |
+LL | | };
+ | |__-
+ |
+note: the lint level is defined here
+ --> $DIR/const_refers_to_static_cross_crate.rs:30:8
+ |
+LL | #[warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
index 7a64abd7b9c..2d4f038d914 100644
--- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
+++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
@@ -170,3 +170,45 @@ LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None =>
error: aborting due to 10 previous errors; 3 warnings emitted
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/const_refers_to_static_cross_crate.rs:25:15
+ |
+LL | / const U8_MUT2: &u8 = {
+LL | | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
+LL | |
+LL | |
+LL | |
+LL | | };
+ | |__-
+ |
+note: the lint level is defined here
+ --> $DIR/const_refers_to_static_cross_crate.rs:23:8
+ |
+LL | #[warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/const_refers_to_static_cross_crate.rs:32:20
+ |
+LL | / const U8_MUT3: &u8 = {
+LL | | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
+LL | |
+LL | |
+LL | |
+LL | | };
+ | |__-
+ |
+note: the lint level is defined here
+ --> $DIR/const_refers_to_static_cross_crate.rs:30:8
+ |
+LL | #[warn(const_err)]
+ | ^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/ptr_comparisons.stderr b/src/test/ui/consts/ptr_comparisons.stderr
index 12f6ca0b51a..594576fe2cf 100644
--- a/src/test/ui/consts/ptr_comparisons.stderr
+++ b/src/test/ui/consts/ptr_comparisons.stderr
@@ -44,3 +44,29 @@ LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ptr_comparisons.rs:65:27
+ |
+LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
+ | --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/ptr_comparisons.rs:70:27
+ |
+LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
+ | --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------
+ | |
+ | unable to turn pointer into raw bytes
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/recursive.stderr b/src/test/ui/consts/recursive.stderr
index 31ac1fff4e8..8d1e10d4176 100644
--- a/src/test/ui/consts/recursive.stderr
+++ b/src/test/ui/consts/recursive.stderr
@@ -29,3 +29,22 @@ LL | const X: () = f(1);
error: aborting due to previous error; 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/recursive.rs:4:5
+ |
+LL | f(x);
+ | ^^^^
+ | |
+ | reached the configured maximum number of stack frames
+ | inside `f::<i32>` at $DIR/recursive.rs:4:5
+ | [... 126 additional calls inside `f::<i32>` at $DIR/recursive.rs:4:5 ...]
+ | inside `X` at $DIR/recursive.rs:9:15
+...
+LL | const X: () = f(1);
+ | -------------------
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.stderr b/src/test/ui/consts/uninhabited-const-issue-61744.stderr
index e98eefc11c3..17dd6131436 100644
--- a/src/test/ui/consts/uninhabited-const-issue-61744.stderr
+++ b/src/test/ui/consts/uninhabited-const-issue-61744.stderr
@@ -150,3 +150,147 @@ LL | dbg!(i32::CONSTANT);
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+ | |
+ | reached the configured maximum number of stack frames
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5
+ | inside `fake_type::<i32>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `<i32 as Const>::CONSTANT` at $DIR/uninhabited-const-issue-61744.rs:13:36
+...
+LL | const CONSTANT: i32 = unsafe { fake_type() };
+ | ---------------------------------------------
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/error-codes/E0201.stderr b/src/test/ui/error-codes/E0201.stderr
index 89cfd402423..af029603fa1 100644
--- a/src/test/ui/error-codes/E0201.stderr
+++ b/src/test/ui/error-codes/E0201.stderr
@@ -2,17 +2,17 @@ error[E0201]: duplicate definitions with name `bar`:
--> $DIR/E0201.rs:5:5
|
LL | fn bar(&self) -> bool { self.0 > 5 }
- | ------------------------------------ previous definition of `bar` here
+ | --------------------- previous definition of `bar` here
LL | fn bar() {}
- | ^^^^^^^^^^^ duplicate definition
+ | ^^^^^^^^ duplicate definition
error[E0201]: duplicate definitions with name `baz`:
--> $DIR/E0201.rs:17:5
|
LL | fn baz(&self) -> bool { true }
- | ------------------------------ previous definition of `baz` here
+ | --------------------- previous definition of `baz` here
LL | fn baz(&self) -> bool { self.0 > 5 }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definition
+ | ^^^^^^^^^^^^^^^^^^^^^ duplicate definition
error[E0201]: duplicate definitions with name `Quux`:
--> $DIR/E0201.rs:18:5
diff --git a/src/test/ui/feature-gates/feature-gate-arbitrary-self-types.stderr b/src/test/ui/feature-gates/feature-gate-arbitrary-self-types.stderr
index a06c4b2b483..a1c69a5afb6 100644
--- a/src/test/ui/feature-gates/feature-gate-arbitrary-self-types.stderr
+++ b/src/test/ui/feature-gates/feature-gate-arbitrary-self-types.stderr
@@ -1,13 +1,3 @@
-error[E0658]: `Ptr<Self>` cannot be used as the type of `self` without the `arbitrary_self_types` feature
- --> $DIR/feature-gate-arbitrary-self-types.rs:16:18
- |
-LL | fn foo(self: Ptr<Self>);
- | ^^^^^^^^^
- |
- = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
- = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
- = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
-
error[E0658]: `Ptr<Bar>` cannot be used as the type of `self` without the `arbitrary_self_types` feature
--> $DIR/feature-gate-arbitrary-self-types.rs:22:18
|
@@ -28,6 +18,16 @@ LL | fn bar(self: Box<Ptr<Self>>) {}
= help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+error[E0658]: `Ptr<Self>` cannot be used as the type of `self` without the `arbitrary_self_types` feature
+ --> $DIR/feature-gate-arbitrary-self-types.rs:16:18
+ |
+LL | fn foo(self: Ptr<Self>);
+ | ^^^^^^^^^
+ |
+ = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
+ = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
+ = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr b/src/test/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr
index f9c53a66c4b..a9f611b8745 100644
--- a/src/test/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr
+++ b/src/test/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr
@@ -8,20 +8,20 @@ LL | fn foo(self: *const Self) {}
= help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
-error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types` feature
- --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:9:18
+error[E0658]: `*const ()` cannot be used as the type of `self` without the `arbitrary_self_types` feature
+ --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:14:18
|
-LL | fn bar(self: *const Self);
+LL | fn bar(self: *const Self) {}
| ^^^^^^^^^^^
|
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
= help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
-error[E0658]: `*const ()` cannot be used as the type of `self` without the `arbitrary_self_types` feature
- --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:14:18
+error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types` feature
+ --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:9:18
|
-LL | fn bar(self: *const Self) {}
+LL | fn bar(self: *const Self);
| ^^^^^^^^^^^
|
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.rs b/src/test/ui/generic-associated-types/bugs/issue-80626.rs
index a637da6cf6f..14f27aff1cc 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-80626.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-80626.rs
@@ -1,5 +1,5 @@
// check-fail
-// known-bug
+// known-bug: #80626
// This should pass, but it requires `Sized` to be coinductive.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
index 8b0cc78e999..487b83dfa3f 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
@@ -4,16 +4,11 @@ error[E0275]: overflow evaluating the requirement `LinkedList<A>: Sized`
LL | Next(A::Allocated<Self>)
| ^^^^^^^^^^^^^^^^^^
|
- = note: no field of an enum variant may have a dynamically sized type
- = help: change the field's type to have a statically known size
-help: borrowed types always have a statically known size
+note: required by a bound in `Allocator::Allocated`
+ --> $DIR/issue-80626.rs:9:20
|
-LL | Next(&A::Allocated<Self>)
- | +
-help: the `Box` type always has a statically known size and allocates its contents in the heap
- |
-LL | Next(Box<A::Allocated<Self>>)
- | ++++ +
+LL | type Allocated<T>;
+ | ^ required by this bound in `Allocator::Allocated`
error: aborting due to previous error
diff --git a/src/test/ui/generic-associated-types/bugs/issue-86218.rs b/src/test/ui/generic-associated-types/bugs/issue-86218.rs
index 68cd0fd7efc..fb62c10a9e3 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-86218.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-86218.rs
@@ -1,5 +1,5 @@
// check-fail
-// known-bug
+// known-bug: #86218
// This should pass, but seems to run into a TAIT issue.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87735.rs b/src/test/ui/generic-associated-types/bugs/issue-87735.rs
index 53e3ad7fe69..0844d84c34f 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87735.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-87735.rs
@@ -1,5 +1,5 @@
// check-fail
-// known-bug
+// known-bug: #87735, #88526
// This should pass, but we need an extension of implied bounds (probably).
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87748.rs b/src/test/ui/generic-associated-types/bugs/issue-87748.rs
index 6e7cd45bdb1..a3d00ee03b1 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87748.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-87748.rs
@@ -1,5 +1,5 @@
// check-fail
-// known-bug
+// known-bug: #87748
// This should pass, but unnormalized input args aren't treated as implied.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87755.rs b/src/test/ui/generic-associated-types/bugs/issue-87755.rs
index 31cea12a3e2..efa487d624f 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87755.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-87755.rs
@@ -1,5 +1,5 @@
// check-fail
-// known-bug
+// known-bug: #87755
// This should pass.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87803.rs b/src/test/ui/generic-associated-types/bugs/issue-87803.rs
index 57a4b028d93..a8a111c99ef 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87803.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-87803.rs
@@ -1,5 +1,5 @@
// check-fail
-// known-bug
+// known-bug: #87803
// This should pass, but using a type alias vs a reference directly
// changes late-bound -> early-bound.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88382.rs b/src/test/ui/generic-associated-types/bugs/issue-88382.rs
index c9f34240527..5493b9b9391 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88382.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-88382.rs
@@ -1,5 +1,5 @@
// check-fail
-// known-bug
+// known-bug: #88382
// This should pass, but has a missed normalization due to HRTB.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88460.rs b/src/test/ui/generic-associated-types/bugs/issue-88460.rs
index b31d012d2fc..f1c3b226915 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88460.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-88460.rs
@@ -1,5 +1,5 @@
// check-fail
-// known-bug
+// known-bug: #88460
// This should pass, but has a missed normalization due to HRTB.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88526.rs b/src/test/ui/generic-associated-types/bugs/issue-88526.rs
index c72a450b926..15363ad04bf 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88526.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-88526.rs
@@ -1,5 +1,5 @@
// check-fail
-// known-bug
+// known-bug: #88526
// This should pass, but requires more logic.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-89008.rs b/src/test/ui/generic-associated-types/bugs/issue-89008.rs
index 1581b7105a8..79c28b0d221 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-89008.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-89008.rs
@@ -1,6 +1,6 @@
// check-fail
// edition:2021
-// known-bug
+// known-bug: #88908
// This should pass, but seems to run into a TAIT bug.
diff --git a/src/test/ui/generic-associated-types/issue-91883.rs b/src/test/ui/generic-associated-types/issue-91883.rs
new file mode 100644
index 00000000000..3d4585a44df
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-91883.rs
@@ -0,0 +1,42 @@
+#![feature(generic_associated_types)]
+
+use std::fmt::Debug;
+use std::marker::PhantomData;
+
+#[derive(Debug)]
+pub struct TransactionImpl<'db> {
+ _marker: PhantomData<&'db ()>,
+}
+
+#[derive(Debug)]
+pub struct CursorImpl<'txn> {
+ _marker: PhantomData<&'txn ()>,
+}
+
+pub trait Cursor<'txn> {}
+
+pub trait Transaction<'db>: Send + Sync + Debug + Sized {
+ type Cursor<'tx>: Cursor<'tx>
+ where
+ 'db: 'tx,
+ Self: 'tx;
+
+ fn cursor<'tx>(&'tx self) -> Result<Self::Cursor<'tx>, ()>
+ where
+ 'db: 'tx;
+}
+
+impl<'tx> Cursor<'tx> for CursorImpl<'tx> {}
+
+impl<'db> Transaction<'db> for TransactionImpl<'db> {
+ type Cursor<'tx> = CursorImpl<'tx>; //~ ERROR lifetime bound not satisfied
+
+ fn cursor<'tx>(&'tx self) -> Result<Self::Cursor<'tx>, ()>
+ where
+ 'db: 'tx,
+ {
+ loop {}
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-91883.stderr b/src/test/ui/generic-associated-types/issue-91883.stderr
new file mode 100644
index 00000000000..ed700876e02
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-91883.stderr
@@ -0,0 +1,26 @@
+error[E0478]: lifetime bound not satisfied
+ --> $DIR/issue-91883.rs:32:24
+ |
+LL | / type Cursor<'tx>: Cursor<'tx>
+LL | | where
+LL | | 'db: 'tx,
+LL | | Self: 'tx;
+ | |__________________- definition of `Cursor` from trait
+...
+LL | type Cursor<'tx> = CursorImpl<'tx>;
+ | ^^^^^^^^^^^^^^^- help: try copying these clauses from the trait: `where 'db: 'tx, Self: 'tx`
+ |
+note: lifetime parameter instantiated with the lifetime `'db` as defined here
+ --> $DIR/issue-91883.rs:31:6
+ |
+LL | impl<'db> Transaction<'db> for TransactionImpl<'db> {
+ | ^^^
+note: but lifetime parameter must outlive the lifetime `'tx` as defined here
+ --> $DIR/issue-91883.rs:32:17
+ |
+LL | type Cursor<'tx> = CursorImpl<'tx>;
+ | ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0478`.
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
index 7f45fb83cef..a6858154dfb 100644
--- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
@@ -19,44 +19,44 @@ LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext`
error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
- --> $DIR/issue-89118.rs:22:20
+ --> $DIR/issue-89118.rs:29:9
|
-LL | type Handler = Ctx<C::Dispatcher>;
- | ^^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
+LL | impl<C> EthernetWorker<C> {}
+ | ^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
|
note: required because of the requirements on the impl of `for<'a> BufferUdpStateContext<&'a ()>` for `Ctx<()>`
--> $DIR/issue-89118.rs:5:23
|
LL | impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ ^
-note: required by a bound in `StackContext`
- --> $DIR/issue-89118.rs:9:14
+note: required by a bound in `EthernetWorker`
+ --> $DIR/issue-89118.rs:28:14
|
-LL | trait StackContext
- | ------------ required by a bound in this
+LL | struct EthernetWorker<C>(C)
+ | -------------- required by a bound in this
LL | where
-LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext`
+LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `EthernetWorker`
error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
- --> $DIR/issue-89118.rs:29:9
+ --> $DIR/issue-89118.rs:22:20
|
-LL | impl<C> EthernetWorker<C> {}
- | ^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
+LL | type Handler = Ctx<C::Dispatcher>;
+ | ^^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
|
note: required because of the requirements on the impl of `for<'a> BufferUdpStateContext<&'a ()>` for `Ctx<()>`
--> $DIR/issue-89118.rs:5:23
|
LL | impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ ^
-note: required by a bound in `EthernetWorker`
- --> $DIR/issue-89118.rs:28:14
+note: required by a bound in `StackContext`
+ --> $DIR/issue-89118.rs:9:14
|
-LL | struct EthernetWorker<C>(C)
- | -------------- required by a bound in this
+LL | trait StackContext
+ | ------------ required by a bound in this
LL | where
-LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `EthernetWorker`
+LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/hrtb/issue-95034.rs b/src/test/ui/hrtb/issue-95034.rs
index aee6fe61ba8..d8edbe7e56b 100644
--- a/src/test/ui/hrtb/issue-95034.rs
+++ b/src/test/ui/hrtb/issue-95034.rs
@@ -1,4 +1,4 @@
-// known-bug
+// known-bug: #95034
// failure-status: 101
// compile-flags: --edition=2021 --crate-type=lib
// rustc-env:RUST_BACKTRACE=0
diff --git a/src/test/ui/impl-duplicate-methods.stderr b/src/test/ui/impl-duplicate-methods.stderr
index b6dc4882fc8..c19702a5bf0 100644
--- a/src/test/ui/impl-duplicate-methods.stderr
+++ b/src/test/ui/impl-duplicate-methods.stderr
@@ -2,9 +2,9 @@ error[E0201]: duplicate definitions with name `orange`:
--> $DIR/impl-duplicate-methods.rs:5:5
|
LL | fn orange(&self) {}
- | ------------------- previous definition of `orange` here
+ | ---------------- previous definition of `orange` here
LL | fn orange(&self) {}
- | ^^^^^^^^^^^^^^^^^^^ duplicate definition
+ | ^^^^^^^^^^^^^^^^ duplicate definition
error: aborting due to previous error
diff --git a/src/test/ui/impl-trait/auto-trait.stderr b/src/test/ui/impl-trait/auto-trait.stderr
index 3b360f492b7..5e10272b0db 100644
--- a/src/test/ui/impl-trait/auto-trait.stderr
+++ b/src/test/ui/impl-trait/auto-trait.stderr
@@ -1,3 +1,12 @@
+error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
+ --> $DIR/auto-trait.rs:21:1
+ |
+LL | impl<T: Send> AnotherTrait for T {}
+ | -------------------------------- first implementation here
+...
+LL | impl AnotherTrait for D<OpaqueType> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
+
error: cannot implement trait on type alias impl trait
--> $DIR/auto-trait.rs:21:25
|
@@ -10,15 +19,6 @@ note: type alias impl trait defined here
LL | type OpaqueType = impl OpaqueTrait;
| ^^^^^^^^^^^^^^^^
-error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
- --> $DIR/auto-trait.rs:21:1
- |
-LL | impl<T: Send> AnotherTrait for T {}
- | -------------------------------- first implementation here
-...
-LL | impl AnotherTrait for D<OpaqueType> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
-
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/impl-trait/negative-reasoning.stderr b/src/test/ui/impl-trait/negative-reasoning.stderr
index 98f9fbd8fef..479b451855d 100644
--- a/src/test/ui/impl-trait/negative-reasoning.stderr
+++ b/src/test/ui/impl-trait/negative-reasoning.stderr
@@ -1,3 +1,14 @@
+error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
+ --> $DIR/negative-reasoning.rs:19:1
+ |
+LL | impl<T: std::fmt::Debug> AnotherTrait for T {}
+ | ------------------------------------------- first implementation here
+...
+LL | impl AnotherTrait for D<OpaqueType> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
+ |
+ = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions
+
error: cannot implement trait on type alias impl trait
--> $DIR/negative-reasoning.rs:19:25
|
@@ -10,17 +21,6 @@ note: type alias impl trait defined here
LL | type OpaqueType = impl OpaqueTrait;
| ^^^^^^^^^^^^^^^^
-error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
- --> $DIR/negative-reasoning.rs:19:1
- |
-LL | impl<T: std::fmt::Debug> AnotherTrait for T {}
- | ------------------------------------------- first implementation here
-...
-LL | impl AnotherTrait for D<OpaqueType> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
- |
- = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions
-
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/impl-trait/nested-return-type2.rs b/src/test/ui/impl-trait/nested-return-type2.rs
index 39928d543e1..279641a46c3 100644
--- a/src/test/ui/impl-trait/nested-return-type2.rs
+++ b/src/test/ui/impl-trait/nested-return-type2.rs
@@ -1,5 +1,3 @@
-// check-pass
-
trait Duh {}
impl Duh for i32 {}
@@ -20,11 +18,9 @@ impl<R: Duh, F: FnMut() -> R> Trait for F {
// the hidden type. We already have obligations registered on the inference
// var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
// type does not implement `Duh`, even if its hidden type does.
-// Lazy TAIT would error out, but we inserted a hack to make it work again,
-// keeping backwards compatibility.
fn foo() -> impl Trait<Assoc = impl Send> {
+ //~^ ERROR `impl Send: Duh` is not satisfied
|| 42
}
-fn main() {
-}
+fn main() {}
diff --git a/src/test/ui/impl-trait/nested-return-type2.stderr b/src/test/ui/impl-trait/nested-return-type2.stderr
new file mode 100644
index 00000000000..f996e99de07
--- /dev/null
+++ b/src/test/ui/impl-trait/nested-return-type2.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `impl Send: Duh` is not satisfied
+ --> $DIR/nested-return-type2.rs:21:13
+ |
+LL | fn foo() -> impl Trait<Assoc = impl Send> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Duh` is not implemented for `impl Send`
+ |
+ = help: the trait `Duh` is implemented for `i32`
+note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2.rs:23:5: 23:10]`
+ --> $DIR/nested-return-type2.rs:12:31
+ |
+LL | impl<R: Duh, F: FnMut() -> R> Trait for F {
+ | ^^^^^ ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-20413.rs b/src/test/ui/issues/issue-20413.rs
index a4345ccdfbe..138a235e675 100644
--- a/src/test/ui/issues/issue-20413.rs
+++ b/src/test/ui/issues/issue-20413.rs
@@ -1,5 +1,5 @@
trait Foo {
- fn answer(self);
+ fn answer(self);
}
struct NoData<T>;
@@ -7,18 +7,17 @@ struct NoData<T>;
impl<T> Foo for T where NoData<T>: Foo {
//~^ ERROR: overflow evaluating the requirement
- //~| ERROR: overflow evaluating the requirement
fn answer(self) {
let val: NoData<T> = NoData;
}
}
trait Bar {
- fn answer(self);
+ fn answer(self);
}
trait Baz {
- fn answer(self);
+ fn answer(self);
}
struct AlmostNoData<T>(Option<T>);
@@ -27,7 +26,6 @@ struct EvenLessData<T>(Option<T>);
impl<T> Bar for T where EvenLessData<T>: Baz {
//~^ ERROR: overflow evaluating the requirement
-//~| ERROR: overflow evaluating the requirement
fn answer(self) {
let val: EvenLessData<T> = EvenLessData(None);
}
@@ -35,7 +33,6 @@ impl<T> Bar for T where EvenLessData<T>: Baz {
impl<T> Baz for T where AlmostNoData<T>: Bar {
//~^ ERROR: overflow evaluating the requirement
-//~| ERROR: overflow evaluating the requirement
fn answer(self) {
let val: NoData<T> = AlmostNoData(None);
}
diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr
index 29352141404..ea493c58a33 100644
--- a/src/test/ui/issues/issue-20413.stderr
+++ b/src/test/ui/issues/issue-20413.stderr
@@ -22,102 +22,47 @@ LL | impl<T> Foo for T where NoData<T>: Foo {
= note: 127 redundant requirements hidden
= note: required because of the requirements on the impl of `Foo` for `NoData<T>`
-error[E0275]: overflow evaluating the requirement `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo`
- --> $DIR/issue-20413.rs:8:36
- |
-LL | impl<T> Foo for T where NoData<T>: Foo {
- | ^^^
- |
- = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required because of the requirements on the impl of `Foo` for `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
- --> $DIR/issue-20413.rs:8:9
- |
-LL | impl<T> Foo for T where NoData<T>: Foo {
- | ^^^ ^
- = note: 127 redundant requirements hidden
- = note: required because of the requirements on the impl of `Foo` for `NoData<T>`
-
error[E0275]: overflow evaluating the requirement `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Baz`
- --> $DIR/issue-20413.rs:28:42
+ --> $DIR/issue-20413.rs:27:42
|
LL | impl<T> Bar for T where EvenLessData<T>: Baz {
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
note: required because of the requirements on the impl of `Bar` for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
- --> $DIR/issue-20413.rs:28:9
+ --> $DIR/issue-20413.rs:27:9
|
LL | impl<T> Bar for T where EvenLessData<T>: Baz {
| ^^^ ^
note: required because of the requirements on the impl of `Baz` for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
- --> $DIR/issue-20413.rs:36:9
+ --> $DIR/issue-20413.rs:34:9
|
LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
| ^^^ ^
= note: 126 redundant requirements hidden
= note: required because of the requirements on the impl of `Baz` for `EvenLessData<T>`
-error[E0275]: overflow evaluating the requirement `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Baz`
- --> $DIR/issue-20413.rs:28:42
- |
-LL | impl<T> Bar for T where EvenLessData<T>: Baz {
- | ^^^
- |
- = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required because of the requirements on the impl of `Bar` for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
- --> $DIR/issue-20413.rs:28:9
- |
-LL | impl<T> Bar for T where EvenLessData<T>: Baz {
- | ^^^ ^
-note: required because of the requirements on the impl of `Baz` for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
- --> $DIR/issue-20413.rs:36:9
- |
-LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
- | ^^^ ^
- = note: 126 redundant requirements hidden
- = note: required because of the requirements on the impl of `Baz` for `EvenLessData<T>`
-
-error[E0275]: overflow evaluating the requirement `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Bar`
- --> $DIR/issue-20413.rs:36:42
- |
-LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
- | ^^^
- |
- = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required because of the requirements on the impl of `Baz` for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
- --> $DIR/issue-20413.rs:36:9
- |
-LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
- | ^^^ ^
-note: required because of the requirements on the impl of `Bar` for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
- --> $DIR/issue-20413.rs:28:9
- |
-LL | impl<T> Bar for T where EvenLessData<T>: Baz {
- | ^^^ ^
- = note: 126 redundant requirements hidden
- = note: required because of the requirements on the impl of `Bar` for `AlmostNoData<T>`
-
error[E0275]: overflow evaluating the requirement `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Bar`
- --> $DIR/issue-20413.rs:36:42
+ --> $DIR/issue-20413.rs:34:42
|
LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
note: required because of the requirements on the impl of `Baz` for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
- --> $DIR/issue-20413.rs:36:9
+ --> $DIR/issue-20413.rs:34:9
|
LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
| ^^^ ^
note: required because of the requirements on the impl of `Bar` for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
- --> $DIR/issue-20413.rs:28:9
+ --> $DIR/issue-20413.rs:27:9
|
LL | impl<T> Bar for T where EvenLessData<T>: Baz {
| ^^^ ^
= note: 126 redundant requirements hidden
= note: required because of the requirements on the impl of `Bar` for `AlmostNoData<T>`
-error: aborting due to 7 previous errors
+error: aborting due to 4 previous errors
Some errors have detailed explanations: E0275, E0392.
For more information about an error, try `rustc --explain E0275`.
diff --git a/src/test/ui/issues/issue-4265.stderr b/src/test/ui/issues/issue-4265.stderr
index acdf963ed3b..27e83d49574 100644
--- a/src/test/ui/issues/issue-4265.stderr
+++ b/src/test/ui/issues/issue-4265.stderr
@@ -1,14 +1,11 @@
error[E0201]: duplicate definitions with name `bar`:
--> $DIR/issue-4265.rs:10:5
|
-LL | / fn bar() {
-LL | | Foo { baz: 0 }.bar();
-LL | | }
- | |_____- previous definition of `bar` here
-LL |
-LL | / fn bar() {
-LL | | }
- | |_____^ duplicate definition
+LL | fn bar() {
+ | -------- previous definition of `bar` here
+...
+LL | fn bar() {
+ | ^^^^^^^^ duplicate definition
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-47511.rs b/src/test/ui/issues/issue-47511.rs
index 98c141b6c6a..eb4860e75d7 100644
--- a/src/test/ui/issues/issue-47511.rs
+++ b/src/test/ui/issues/issue-47511.rs
@@ -1,5 +1,5 @@
// check-fail
-// known-bug
+// known-bug: #47511
// Regression test for #47511: anonymous lifetimes can appear
// unconstrained in a return type, but only if they appear just once
diff --git a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr
index 33f6c498b6f..affb4e8d044 100644
--- a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr
+++ b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr
@@ -10,6 +10,28 @@ LL | struct Foo<T: 'static> {
| +++++++++
error[E0309]: the parameter type `K` may not live long enough
+ --> $DIR/lifetime-doesnt-live-long-enough.rs:41:33
+ |
+LL | fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
+ | ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<K>` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | impl<K: 'a> Nested<K> {
+ | ++++
+
+error[E0309]: the parameter type `M` may not live long enough
+ --> $DIR/lifetime-doesnt-live-long-enough.rs:44:36
+ |
+LL | fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
+ | ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<M>` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b + 'a>() {
+ | ++++
+
+error[E0309]: the parameter type `K` may not live long enough
--> $DIR/lifetime-doesnt-live-long-enough.rs:24:19
|
LL | fn foo<'a, L: X<&'a Nested<K>>>();
@@ -40,28 +62,6 @@ help: consider adding an explicit lifetime bound...
LL | fn baz<'a, L: 'a, M: X<&'a Nested<L>>>() {
| ++++
-error[E0309]: the parameter type `K` may not live long enough
- --> $DIR/lifetime-doesnt-live-long-enough.rs:41:33
- |
-LL | fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
- | ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<K>` does not outlive the data it points at
- |
-help: consider adding an explicit lifetime bound...
- |
-LL | impl<K: 'a> Nested<K> {
- | ++++
-
-error[E0309]: the parameter type `M` may not live long enough
- --> $DIR/lifetime-doesnt-live-long-enough.rs:44:36
- |
-LL | fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
- | ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<M>` does not outlive the data it points at
- |
-help: consider adding an explicit lifetime bound...
- |
-LL | fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b + 'a>() {
- | ++++
-
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0309, E0310.
diff --git a/src/test/ui/limits/issue-55878.stderr b/src/test/ui/limits/issue-55878.stderr
index 90411353f08..1402d138703 100644
--- a/src/test/ui/limits/issue-55878.stderr
+++ b/src/test/ui/limits/issue-55878.stderr
@@ -23,3 +23,15 @@ LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: erroneous constant used
+ --> $DIR/issue-55878.rs:7:26
+ |
+LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+ = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr b/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr
index af6308f0d1b..c14529a7d09 100644
--- a/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr
@@ -12,3 +12,16 @@ LL | const C: i32 = 1 / 0;
warning: 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/allowed-cli-deny-by-default-lint.rs:6:16
+ |
+LL | const C: i32 = 1 / 0;
+ | ---------------^^^^^-
+ | |
+ | attempt to divide `1_i32` by zero
+ |
+ = note: requested on the command line with `--force-warn const-err`
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr b/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr
index 05656afd22d..dd71a168960 100644
--- a/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr
@@ -12,3 +12,16 @@ LL | const C: i32 = 1 / 0;
warning: 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/allowed-deny-by-default-lint.rs:7:16
+ |
+LL | const C: i32 = 1 / 0;
+ | ---------------^^^^^-
+ | |
+ | attempt to divide `1_i32` by zero
+ |
+ = note: requested on the command line with `--force-warn const-err`
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/lint/force-warn/deny-by-default-lint.stderr b/src/test/ui/lint/force-warn/deny-by-default-lint.stderr
index ef295f99e64..d4e80584669 100644
--- a/src/test/ui/lint/force-warn/deny-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/deny-by-default-lint.stderr
@@ -12,3 +12,16 @@ LL | const C: i32 = 1 / 0;
warning: 1 warning emitted
+Future incompatibility report: Future breakage diagnostic:
+warning: any use of this value will cause an error
+ --> $DIR/deny-by-default-lint.rs:5:16
+ |
+LL | const C: i32 = 1 / 0;
+ | ---------------^^^^^-
+ | |
+ | attempt to divide `1_i32` by zero
+ |
+ = note: requested on the command line with `--force-warn const-err`
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.rs b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.rs
index c79c1daf774..0e0d604ae04 100644
--- a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.rs
+++ b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.rs
@@ -20,43 +20,43 @@ fn main() {
// AcqRel is always forbidden as a failure ordering
let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Relaxed, Ordering::AcqRel);
- //~^ ERROR compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Acquire, Ordering::AcqRel);
- //~^ ERROR compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::AcqRel);
- //~^ ERROR compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::AcqRel, Ordering::AcqRel);
- //~^ ERROR compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::SeqCst, Ordering::AcqRel);
- //~^ ERROR compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`
// Release is always forbidden as a failure ordering
let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::Release);
- //~^ ERROR compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Acquire, Ordering::Release);
- //~^ ERROR compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Release, Ordering::Release);
- //~^ ERROR compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::AcqRel, Ordering::Release);
- //~^ ERROR compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::SeqCst, Ordering::Release);
- //~^ ERROR compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`
// Release success order forbids failure order of Acquire or SeqCst
let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::Acquire);
- //~^ ERROR compare_exchange_weak's failure ordering may not be stronger
+ //~^ ERROR `compare_exchange_weak`'s success ordering must be at least as strong as
let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::SeqCst);
- //~^ ERROR compare_exchange_weak's failure ordering may not be stronger
+ //~^ ERROR `compare_exchange_weak`'s success ordering must be at least as strong as
// Relaxed success order also forbids failure order of Acquire or SeqCst
let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::SeqCst);
- //~^ ERROR compare_exchange_weak's failure ordering may not be stronger
+ //~^ ERROR `compare_exchange_weak`'s success ordering must be at least as strong as
let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::Acquire);
- //~^ ERROR compare_exchange_weak's failure ordering may not be stronger
+ //~^ ERROR `compare_exchange_weak`'s success ordering must be at least as strong as
// Acquire/AcqRel forbids failure order of SeqCst
let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Acquire, Ordering::SeqCst);
- //~^ ERROR compare_exchange_weak's failure ordering may not be stronger
+ //~^ ERROR `compare_exchange_weak`'s success ordering must be at least as strong as
let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::AcqRel, Ordering::SeqCst);
- //~^ ERROR compare_exchange_weak's failure ordering may not be stronger
+ //~^ ERROR `compare_exchange_weak`'s success ordering must be at least as strong as
}
diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr
index 13350ab0b9c..d5e53418b6f 100644
--- a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr
+++ b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr
@@ -1,131 +1,137 @@
-error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange_weak` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:22:67
|
LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Relaxed, Ordering::AcqRel);
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
= note: `#[deny(invalid_atomic_ordering)]` on by default
- = help: consider using ordering mode `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange_weak` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:24:67
|
LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Acquire, Ordering::AcqRel);
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange_weak` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:26:67
|
LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::AcqRel);
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering mode `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange_weak` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:28:66
|
LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::AcqRel, Ordering::AcqRel);
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange_weak` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:30:66
|
LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::SeqCst, Ordering::AcqRel);
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange_weak` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:34:67
|
LL | let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::Release);
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering mode `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange_weak` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:36:67
|
LL | let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Acquire, Ordering::Release);
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange_weak` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:38:67
|
LL | let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Release, Ordering::Release);
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering mode `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange_weak` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:40:66
|
LL | let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::AcqRel, Ordering::Release);
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange_weak's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange_weak` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:42:66
|
LL | let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::SeqCst, Ordering::Release);
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange_weak's failure ordering may not be stronger than the success ordering of `Release`
- --> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:46:67
+error: `compare_exchange_weak`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:46:48
|
LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::Acquire);
- | ^^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering mode `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ----------------- `Acquire` failure ordering
+ | |
+ | `Release` success ordering
+ | help: consider using `AcqRel` success ordering instead
-error: compare_exchange_weak's failure ordering may not be stronger than the success ordering of `Release`
- --> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:48:67
+error: `compare_exchange_weak`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:48:48
|
LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Release, Ordering::SeqCst);
- | ^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering mode `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ---------------- `SeqCst` failure ordering
+ | |
+ | `Release` success ordering
+ | help: consider using `SeqCst` success ordering instead
-error: compare_exchange_weak's failure ordering may not be stronger than the success ordering of `Relaxed`
- --> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:52:67
+error: `compare_exchange_weak`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:52:48
|
LL | let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::SeqCst);
- | ^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering mode `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ---------------- `SeqCst` failure ordering
+ | |
+ | `Relaxed` success ordering
+ | help: consider using `SeqCst` success ordering instead
-error: compare_exchange_weak's failure ordering may not be stronger than the success ordering of `Relaxed`
- --> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:54:67
+error: `compare_exchange_weak`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:54:48
|
LL | let _ = x.compare_exchange_weak(ptr, ptr2, Ordering::Relaxed, Ordering::Acquire);
- | ^^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering mode `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ----------------- `Acquire` failure ordering
+ | |
+ | `Relaxed` success ordering
+ | help: consider using `Acquire` success ordering instead
-error: compare_exchange_weak's failure ordering may not be stronger than the success ordering of `Acquire`
- --> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:58:67
+error: `compare_exchange_weak`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:58:48
|
LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Acquire, Ordering::SeqCst);
- | ^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ---------------- `SeqCst` failure ordering
+ | |
+ | `Acquire` success ordering
+ | help: consider using `SeqCst` success ordering instead
-error: compare_exchange_weak's failure ordering may not be stronger than the success ordering of `AcqRel`
- --> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:60:66
+error: `compare_exchange_weak`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:60:48
|
LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::AcqRel, Ordering::SeqCst);
- | ^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^ ---------------- `SeqCst` failure ordering
+ | |
+ | `AcqRel` success ordering
+ | help: consider using `SeqCst` success ordering instead
error: aborting due to 16 previous errors
diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.rs b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.rs
index 8ef3a400cf0..da98d854262 100644
--- a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.rs
+++ b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.rs
@@ -18,43 +18,43 @@ fn main() {
// AcqRel is always forbidden as a failure ordering
let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::AcqRel);
- //~^ ERROR compare_exchange's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::AcqRel);
- //~^ ERROR compare_exchange's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::AcqRel);
- //~^ ERROR compare_exchange's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::AcqRel);
- //~^ ERROR compare_exchange's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::AcqRel);
- //~^ ERROR compare_exchange's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`
// Release is always forbidden as a failure ordering
let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::Release);
- //~^ ERROR compare_exchange's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::Release);
- //~^ ERROR compare_exchange's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::Release);
- //~^ ERROR compare_exchange's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::Release);
- //~^ ERROR compare_exchange's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::Release);
- //~^ ERROR compare_exchange's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`
// Release success order forbids failure order of Acquire or SeqCst
let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::Acquire);
- //~^ ERROR compare_exchange's failure ordering may not be stronger
+ //~^ ERROR `compare_exchange`'s success ordering must be at least as strong as
let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::SeqCst);
- //~^ ERROR compare_exchange's failure ordering may not be stronger
+ //~^ ERROR `compare_exchange`'s success ordering must be at least as strong as
// Relaxed success order also forbids failure order of Acquire or SeqCst
let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::SeqCst);
- //~^ ERROR compare_exchange's failure ordering may not be stronger
+ //~^ ERROR `compare_exchange`'s success ordering must be at least as strong as
let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::Acquire);
- //~^ ERROR compare_exchange's failure ordering may not be stronger
+ //~^ ERROR `compare_exchange`'s success ordering must be at least as strong as
// Acquire/AcqRel forbids failure order of SeqCst
let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::SeqCst);
- //~^ ERROR compare_exchange's failure ordering may not be stronger
+ //~^ ERROR `compare_exchange`'s success ordering must be at least as strong as
let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::SeqCst);
- //~^ ERROR compare_exchange's failure ordering may not be stronger
+ //~^ ERROR `compare_exchange`'s success ordering must be at least as strong as
}
diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.stderr
index daedfec7430..41121a20dee 100644
--- a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.stderr
+++ b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.stderr
@@ -1,131 +1,137 @@
-error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange.rs:20:57
|
LL | let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::AcqRel);
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
= note: `#[deny(invalid_atomic_ordering)]` on by default
- = help: consider using ordering mode `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange.rs:22:57
|
LL | let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::AcqRel);
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange.rs:24:57
|
LL | let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::AcqRel);
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering mode `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange.rs:26:56
|
LL | let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::AcqRel);
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange.rs:28:56
|
LL | let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::AcqRel);
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange.rs:32:57
|
LL | let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::Release);
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering mode `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange.rs:34:57
|
LL | let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::Release);
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange.rs:36:57
|
LL | let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::Release);
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering mode `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange.rs:38:56
|
LL | let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::Release);
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange's failure ordering may not be `Release` or `AcqRel`
+error: `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-exchange.rs:40:56
|
LL | let _ = x.compare_exchange(0, 0, Ordering::SeqCst, Ordering::Release);
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: compare_exchange's failure ordering may not be stronger than the success ordering of `Release`
- --> $DIR/lint-invalid-atomic-ordering-exchange.rs:44:57
+error: `compare_exchange`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-exchange.rs:44:38
|
LL | let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::Acquire);
- | ^^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering mode `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ----------------- `Acquire` failure ordering
+ | |
+ | `Release` success ordering
+ | help: consider using `AcqRel` success ordering instead
-error: compare_exchange's failure ordering may not be stronger than the success ordering of `Release`
- --> $DIR/lint-invalid-atomic-ordering-exchange.rs:46:57
+error: `compare_exchange`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-exchange.rs:46:38
|
LL | let _ = x.compare_exchange(0, 0, Ordering::Release, Ordering::SeqCst);
- | ^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering mode `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ---------------- `SeqCst` failure ordering
+ | |
+ | `Release` success ordering
+ | help: consider using `SeqCst` success ordering instead
-error: compare_exchange's failure ordering may not be stronger than the success ordering of `Relaxed`
- --> $DIR/lint-invalid-atomic-ordering-exchange.rs:50:57
+error: `compare_exchange`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-exchange.rs:50:38
|
LL | let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::SeqCst);
- | ^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering mode `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ---------------- `SeqCst` failure ordering
+ | |
+ | `Relaxed` success ordering
+ | help: consider using `SeqCst` success ordering instead
-error: compare_exchange's failure ordering may not be stronger than the success ordering of `Relaxed`
- --> $DIR/lint-invalid-atomic-ordering-exchange.rs:52:57
+error: `compare_exchange`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-exchange.rs:52:38
|
LL | let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::Acquire);
- | ^^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering mode `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ----------------- `Acquire` failure ordering
+ | |
+ | `Relaxed` success ordering
+ | help: consider using `Acquire` success ordering instead
-error: compare_exchange's failure ordering may not be stronger than the success ordering of `Acquire`
- --> $DIR/lint-invalid-atomic-ordering-exchange.rs:56:57
+error: `compare_exchange`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-exchange.rs:56:38
|
LL | let _ = x.compare_exchange(0, 0, Ordering::Acquire, Ordering::SeqCst);
- | ^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ---------------- `SeqCst` failure ordering
+ | |
+ | `Acquire` success ordering
+ | help: consider using `SeqCst` success ordering instead
-error: compare_exchange's failure ordering may not be stronger than the success ordering of `AcqRel`
- --> $DIR/lint-invalid-atomic-ordering-exchange.rs:58:56
+error: `compare_exchange`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-exchange.rs:58:38
|
LL | let _ = x.compare_exchange(0, 0, Ordering::AcqRel, Ordering::SeqCst);
- | ^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^ ---------------- `SeqCst` failure ordering
+ | |
+ | `AcqRel` success ordering
+ | help: consider using `SeqCst` success ordering instead
error: aborting due to 16 previous errors
diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.rs b/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.rs
index 938ca0359f8..73eda182aa8 100644
--- a/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.rs
+++ b/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.rs
@@ -18,43 +18,43 @@ fn main() {
// AcqRel is always forbidden as a failure ordering
let _ = x.fetch_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.fetch_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.fetch_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.fetch_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.fetch_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
// Release is always forbidden as a failure ordering
let _ = x.fetch_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.fetch_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.fetch_update(Ordering::Release, Ordering::Release, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.fetch_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
let _ = x.fetch_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be `Release` or `AcqRel`
+ //~^ ERROR `fetch_update`'s failure ordering may not be `Release` or `AcqRel`
// Release success order forbids failure order of Acquire or SeqCst
let _ = x.fetch_update(Ordering::Release, Ordering::Acquire, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be stronger
+ //~^ ERROR `fetch_update`'s success ordering must be at least as strong as
let _ = x.fetch_update(Ordering::Release, Ordering::SeqCst, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be stronger
+ //~^ ERROR `fetch_update`'s success ordering must be at least as strong as
// Relaxed success order also forbids failure order of Acquire or SeqCst
let _ = x.fetch_update(Ordering::Relaxed, Ordering::SeqCst, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be stronger
+ //~^ ERROR `fetch_update`'s success ordering must be at least as strong as
let _ = x.fetch_update(Ordering::Relaxed, Ordering::Acquire, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be stronger
+ //~^ ERROR `fetch_update`'s success ordering must be at least as strong as
// Acquire/AcqRel forbids failure order of SeqCst
let _ = x.fetch_update(Ordering::Acquire, Ordering::SeqCst, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be stronger
+ //~^ ERROR `fetch_update`'s success ordering must be at least as strong as
let _ = x.fetch_update(Ordering::AcqRel, Ordering::SeqCst, |old| Some(old + 1));
- //~^ ERROR fetch_update's failure ordering may not be stronger
+ //~^ ERROR `fetch_update`'s success ordering must be at least as strong as
}
diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr
index dabc1da7e55..7bea56d57fb 100644
--- a/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr
+++ b/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr
@@ -1,131 +1,137 @@
-error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:20:47
|
LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
= note: `#[deny(invalid_atomic_ordering)]` on by default
- = help: consider using ordering mode `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:22:47
|
LL | let _ = x.fetch_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:24:47
|
LL | let _ = x.fetch_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering mode `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:26:46
|
LL | let _ = x.fetch_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:28:46
|
LL | let _ = x.fetch_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:32:47
|
LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering mode `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:34:47
|
LL | let _ = x.fetch_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:36:47
|
LL | let _ = x.fetch_update(Ordering::Release, Ordering::Release, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering mode `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:38:46
|
LL | let _ = x.fetch_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: fetch_update's failure ordering may not be `Release` or `AcqRel`
+error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write
--> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:40:46
|
LL | let _ = x.fetch_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^ invalid failure ordering
|
- = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` instead
+ = help: consider using `Acquire` or `Relaxed` failure ordering instead
-error: fetch_update's failure ordering may not be stronger than the success ordering of `Release`
- --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:44:47
+error: `fetch_update`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:44:28
|
LL | let _ = x.fetch_update(Ordering::Release, Ordering::Acquire, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering mode `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ----------------- `Acquire` failure ordering
+ | |
+ | `Release` success ordering
+ | help: consider using `AcqRel` success ordering instead
-error: fetch_update's failure ordering may not be stronger than the success ordering of `Release`
- --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:46:47
+error: `fetch_update`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:46:28
|
LL | let _ = x.fetch_update(Ordering::Release, Ordering::SeqCst, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering mode `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ---------------- `SeqCst` failure ordering
+ | |
+ | `Release` success ordering
+ | help: consider using `SeqCst` success ordering instead
-error: fetch_update's failure ordering may not be stronger than the success ordering of `Relaxed`
- --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:50:47
+error: `fetch_update`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:50:28
|
LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::SeqCst, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering mode `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ---------------- `SeqCst` failure ordering
+ | |
+ | `Relaxed` success ordering
+ | help: consider using `SeqCst` success ordering instead
-error: fetch_update's failure ordering may not be stronger than the success ordering of `Relaxed`
- --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:52:47
+error: `fetch_update`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:52:28
|
LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::Acquire, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering mode `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ----------------- `Acquire` failure ordering
+ | |
+ | `Relaxed` success ordering
+ | help: consider using `Acquire` success ordering instead
-error: fetch_update's failure ordering may not be stronger than the success ordering of `Acquire`
- --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:56:47
+error: `fetch_update`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:56:28
|
LL | let _ = x.fetch_update(Ordering::Acquire, Ordering::SeqCst, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^^ ---------------- `SeqCst` failure ordering
+ | |
+ | `Acquire` success ordering
+ | help: consider using `SeqCst` success ordering instead
-error: fetch_update's failure ordering may not be stronger than the success ordering of `AcqRel`
- --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:58:46
+error: `fetch_update`'s success ordering must be at least as strong as its failure ordering
+ --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:58:28
|
LL | let _ = x.fetch_update(Ordering::AcqRel, Ordering::SeqCst, |old| Some(old + 1));
- | ^^^^^^^^^^^^^^^^
- |
- = help: consider using ordering modes `Acquire` or `Relaxed` instead
+ | ^^^^^^^^^^^^^^^^ ---------------- `SeqCst` failure ordering
+ | |
+ | `AcqRel` success ordering
+ | help: consider using `SeqCst` success ordering instead
error: aborting due to 16 previous errors
diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.rs b/src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.rs
deleted file mode 100644
index 1db9d33c72a..00000000000
--- a/src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// check-pass
-// compile-flags: -Z unpretty=expanded
-
-#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
-
-fn main() {
- let elem = 1i32;
- assert!(elem == 1);
-}
diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.stdout b/src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.stdout
deleted file mode 100644
index a590eb32232..00000000000
--- a/src/test/ui/macros/rfc-2011-nicer-assert-messages/codegen.stdout
+++ /dev/null
@@ -1,29 +0,0 @@
-#![feature(prelude_import)]
-#![no_std]
-// check-pass
-// compile-flags: -Z unpretty=expanded
-
-#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
-#[prelude_import]
-use ::std::prelude::rust_2015::*;
-#[macro_use]
-extern crate std;
-
-fn main() {
- let elem = 1i32;
- {
- #[allow(unused_imports)]
- use ::core::asserting::{TryCaptureGeneric, TryCapturePrintable};
- let mut __capture0 = ::core::asserting::Capture::new();
- let __local_bind0 = &elem;
- if !(*{
- (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
- __local_bind0
- } == 1) {
- {
- ::std::rt::panic_fmt(::core::fmt::Arguments::new_v1(&["Assertion failed: elem == 1\nWith captures:\n elem = ",
- "\n"], &[::core::fmt::ArgumentV1::new_debug(&__capture0)]))
- }
- }
- };
-}
diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.rs b/src/test/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.rs
new file mode 100644
index 00000000000..5ec84b08ff8
--- /dev/null
+++ b/src/test/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.rs
@@ -0,0 +1,32 @@
+// check-pass
+// compile-flags: -Z unpretty=expanded
+
+#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
+
+fn arbitrary_consuming_method_for_demonstration_purposes() {
+ let elem = 1i32;
+ assert!(elem as usize);
+}
+
+fn addr_of() {
+ let elem = 1i32;
+ assert!(&elem);
+}
+
+fn binary() {
+ let elem = 1i32;
+ assert!(elem == 1);
+ assert!(elem >= 1);
+ assert!(elem > 0);
+ assert!(elem < 3);
+ assert!(elem <= 3);
+ assert!(elem != 3);
+}
+
+fn unary() {
+ let elem = &1i32;
+ assert!(*elem);
+}
+
+fn main() {
+}
diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout b/src/test/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout
new file mode 100644
index 00000000000..90f858f80e6
--- /dev/null
+++ b/src/test/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout
@@ -0,0 +1,147 @@
+#![feature(prelude_import)]
+#![no_std]
+// check-pass
+// compile-flags: -Z unpretty=expanded
+
+#![feature(core_intrinsics, generic_assert, generic_assert_internals)]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+
+fn arbitrary_consuming_method_for_demonstration_purposes() {
+ let elem = 1i32;
+ {
+ #[allow(unused_imports)]
+ use ::core::asserting::{TryCaptureGeneric, TryCapturePrintable};
+ let mut __capture0 = ::core::asserting::Capture::new();
+ let __local_bind0 = &elem;
+ if ::core::intrinsics::unlikely(!(*{
+ (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
+ __local_bind0
+ } as usize)) {
+
+
+
+
+ {
+ ::std::rt::panic_fmt(::core::fmt::Arguments::new_v1(&["Assertion failed: elem as usize\nWith captures:\n elem = ",
+ "\n"], &[::core::fmt::ArgumentV1::new_debug(&__capture0)]))
+ }
+ }
+ };
+}
+fn addr_of() {
+ let elem = 1i32;
+ {
+ #[allow(unused_imports)]
+ use ::core::asserting::{TryCaptureGeneric, TryCapturePrintable};
+ let mut __capture0 = ::core::asserting::Capture::new();
+ let __local_bind0 = &elem;
+ if ::core::intrinsics::unlikely(!&*__local_bind0) {
+ (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
+ {
+ ::std::rt::panic_fmt(::core::fmt::Arguments::new_v1(&["Assertion failed: &elem\nWith captures:\n elem = ",
+ "\n"], &[::core::fmt::ArgumentV1::new_debug(&__capture0)]))
+ }
+ }
+ };
+}
+fn binary() {
+ let elem = 1i32;
+ {
+ #[allow(unused_imports)]
+ use ::core::asserting::{TryCaptureGeneric, TryCapturePrintable};
+ let mut __capture0 = ::core::asserting::Capture::new();
+ let __local_bind0 = &elem;
+ if ::core::intrinsics::unlikely(!(*__local_bind0 == 1)) {
+ (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
+ {
+ ::std::rt::panic_fmt(::core::fmt::Arguments::new_v1(&["Assertion failed: elem == 1\nWith captures:\n elem = ",
+ "\n"], &[::core::fmt::ArgumentV1::new_debug(&__capture0)]))
+ }
+ }
+ };
+ {
+ #[allow(unused_imports)]
+ use ::core::asserting::{TryCaptureGeneric, TryCapturePrintable};
+ let mut __capture0 = ::core::asserting::Capture::new();
+ let __local_bind0 = &elem;
+ if ::core::intrinsics::unlikely(!(*__local_bind0 >= 1)) {
+ (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
+ {
+ ::std::rt::panic_fmt(::core::fmt::Arguments::new_v1(&["Assertion failed: elem >= 1\nWith captures:\n elem = ",
+ "\n"], &[::core::fmt::ArgumentV1::new_debug(&__capture0)]))
+ }
+ }
+ };
+ {
+ #[allow(unused_imports)]
+ use ::core::asserting::{TryCaptureGeneric, TryCapturePrintable};
+ let mut __capture0 = ::core::asserting::Capture::new();
+ let __local_bind0 = &elem;
+ if ::core::intrinsics::unlikely(!(*__local_bind0 > 0)) {
+ (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
+ {
+ ::std::rt::panic_fmt(::core::fmt::Arguments::new_v1(&["Assertion failed: elem > 0\nWith captures:\n elem = ",
+ "\n"], &[::core::fmt::ArgumentV1::new_debug(&__capture0)]))
+ }
+ }
+ };
+ {
+ #[allow(unused_imports)]
+ use ::core::asserting::{TryCaptureGeneric, TryCapturePrintable};
+ let mut __capture0 = ::core::asserting::Capture::new();
+ let __local_bind0 = &elem;
+ if ::core::intrinsics::unlikely(!(*__local_bind0 < 3)) {
+ (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
+ {
+ ::std::rt::panic_fmt(::core::fmt::Arguments::new_v1(&["Assertion failed: elem < 3\nWith captures:\n elem = ",
+ "\n"], &[::core::fmt::ArgumentV1::new_debug(&__capture0)]))
+ }
+ }
+ };
+ {
+ #[allow(unused_imports)]
+ use ::core::asserting::{TryCaptureGeneric, TryCapturePrintable};
+ let mut __capture0 = ::core::asserting::Capture::new();
+ let __local_bind0 = &elem;
+ if ::core::intrinsics::unlikely(!(*__local_bind0 <= 3)) {
+ (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
+ {
+ ::std::rt::panic_fmt(::core::fmt::Arguments::new_v1(&["Assertion failed: elem <= 3\nWith captures:\n elem = ",
+ "\n"], &[::core::fmt::ArgumentV1::new_debug(&__capture0)]))
+ }
+ }
+ };
+ {
+ #[allow(unused_imports)]
+ use ::core::asserting::{TryCaptureGeneric, TryCapturePrintable};
+ let mut __capture0 = ::core::asserting::Capture::new();
+ let __local_bind0 = &elem;
+ if ::core::intrinsics::unlikely(!(*__local_bind0 != 3)) {
+ (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
+ {
+ ::std::rt::panic_fmt(::core::fmt::Arguments::new_v1(&["Assertion failed: elem != 3\nWith captures:\n elem = ",
+ "\n"], &[::core::fmt::ArgumentV1::new_debug(&__capture0)]))
+ }
+ }
+ };
+}
+fn unary() {
+ let elem = &1i32;
+ {
+ #[allow(unused_imports)]
+ use ::core::asserting::{TryCaptureGeneric, TryCapturePrintable};
+ let mut __capture0 = ::core::asserting::Capture::new();
+ let __local_bind0 = &elem;
+ if ::core::intrinsics::unlikely(!**__local_bind0) {
+ (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0);
+ {
+ ::std::rt::panic_fmt(::core::fmt::Arguments::new_v1(&["Assertion failed: *elem\nWith captures:\n elem = ",
+ "\n"], &[::core::fmt::ArgumentV1::new_debug(&__capture0)]))
+ }
+ }
+ };
+}
+fn main() {}
diff --git a/src/test/ui/methods/method-macro-backtrace.stderr b/src/test/ui/methods/method-macro-backtrace.stderr
index 7860365476a..7ae00835c96 100644
--- a/src/test/ui/methods/method-macro-backtrace.stderr
+++ b/src/test/ui/methods/method-macro-backtrace.stderr
@@ -2,9 +2,9 @@ error[E0201]: duplicate definitions with name `bar`:
--> $DIR/method-macro-backtrace.rs:22:5
|
LL | fn bar(&self) { }
- | ----------------- previous definition of `bar` here
+ | ------------- previous definition of `bar` here
LL | fn bar(&self) { }
- | ^^^^^^^^^^^^^^^^^ duplicate definition
+ | ^^^^^^^^^^^^^ duplicate definition
error: aborting due to previous error
diff --git a/src/test/ui/mir/issue-92893.rs b/src/test/ui/mir/issue-92893.rs
index d2bbb4f1101..635050f376c 100644
--- a/src/test/ui/mir/issue-92893.rs
+++ b/src/test/ui/mir/issue-92893.rs
@@ -1,6 +1,7 @@
struct Bug<A = [(); (let a = (), 1).1]> {
//~^ `let` expressions are not supported here
- //~^^ `let` expressions in this position are unstable [E0658]
+ //~| `let` expressions in this position are unstable [E0658]
+ //~| expected expression, found `let` statement
a: A
}
diff --git a/src/test/ui/mir/issue-92893.stderr b/src/test/ui/mir/issue-92893.stderr
index 063b5d66feb..4a0fcce31d7 100644
--- a/src/test/ui/mir/issue-92893.stderr
+++ b/src/test/ui/mir/issue-92893.stderr
@@ -1,3 +1,9 @@
+error: expected expression, found `let` statement
+ --> $DIR/issue-92893.rs:1:22
+ |
+LL | struct Bug<A = [(); (let a = (), 1).1]> {
+ | ^^^
+
error: `let` expressions are not supported here
--> $DIR/issue-92893.rs:1:22
|
@@ -15,6 +21,6 @@ LL | struct Bug<A = [(); (let a = (), 1).1]> {
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
= help: add `#![feature(let_chains)]` to the crate attributes to enable
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
index 4a36515b991..bb1aff70d89 100644
--- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
+++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
@@ -58,8 +58,10 @@ fn _macros() {
}
use_expr!((let 0 = 1 && 0 == 0));
//~^ ERROR `let` expressions in this position are unstable
+ //~| ERROR expected expression, found `let` statement
use_expr!((let 0 = 1));
//~^ ERROR `let` expressions in this position are unstable
+ //~| ERROR expected expression, found `let` statement
match () {
#[cfg(FALSE)]
() if let 0 = 1 => {}
diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
index 8d93fb87f7a..370a57318fd 100644
--- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
+++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
@@ -1,5 +1,17 @@
+error: expected expression, found `let` statement
+ --> $DIR/feature-gate.rs:59:16
+ |
+LL | use_expr!((let 0 = 1 && 0 == 0));
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/feature-gate.rs:62:16
+ |
+LL | use_expr!((let 0 = 1));
+ | ^^^
+
error: no rules expected the token `let`
- --> $DIR/feature-gate.rs:69:15
+ --> $DIR/feature-gate.rs:71:15
|
LL | macro_rules! use_expr {
| --------------------- when calling this macro
@@ -58,7 +70,7 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
error[E0658]: `if let` guards are experimental
- --> $DIR/feature-gate.rs:65:12
+ --> $DIR/feature-gate.rs:67:12
|
LL | () if let 0 = 1 => {}
| ^^^^^^^^^^^^
@@ -203,7 +215,7 @@ LL | use_expr!((let 0 = 1 && 0 == 0));
= help: add `#![feature(let_chains)]` to the crate attributes to enable
error[E0658]: `let` expressions in this position are unstable
- --> $DIR/feature-gate.rs:61:16
+ --> $DIR/feature-gate.rs:62:16
|
LL | use_expr!((let 0 = 1));
| ^^^^^^^^^
@@ -211,6 +223,6 @@ LL | use_expr!((let 0 = 1));
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
= help: add `#![feature(let_chains)]` to the crate attributes to enable
-error: aborting due to 23 previous errors
+error: aborting due to 25 previous errors
For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
index 1bd8b74240e..36b730505c2 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
@@ -81,9 +81,11 @@ fn _macros() {
use_expr!((let 0 = 1 && 0 == 0));
//~^ ERROR `let` expressions are not supported here
//~| ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
use_expr!((let 0 = 1));
//~^ ERROR `let` expressions are not supported here
//~| ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
}
fn nested_within_if_expr() {
@@ -147,7 +149,8 @@ fn nested_within_if_expr() {
//~| ERROR mismatched types
//~| ERROR mismatched types
- if let true = let true = true {} //~ ERROR `let` expressions are not supported here
+ if let true = let true = true {}
+ //~^ ERROR `let` expressions are not supported here
}
fn nested_within_while_expr() {
@@ -211,7 +214,8 @@ fn nested_within_while_expr() {
//~| ERROR mismatched types
//~| ERROR mismatched types
- while let true = let true = true {} //~ ERROR `let` expressions are not supported here
+ while let true = let true = true {}
+ //~^ ERROR `let` expressions are not supported here
}
fn not_error_because_clarified_intent() {
@@ -225,45 +229,85 @@ fn not_error_because_clarified_intent() {
}
fn outside_if_and_while_expr() {
- &let 0 = 0; //~ ERROR `let` expressions are not supported here
+ &let 0 = 0;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
- !let 0 = 0; //~ ERROR `let` expressions are not supported here
- *let 0 = 0; //~ ERROR `let` expressions are not supported here
- //~^ ERROR type `bool` cannot be dereferenced
- -let 0 = 0; //~ ERROR `let` expressions are not supported here
- //~^ ERROR cannot apply unary operator `-` to type `bool`
+ !let 0 = 0;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ *let 0 = 0;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR type `bool` cannot be dereferenced
+ //~| ERROR expected expression, found `let` statement
+ -let 0 = 0;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR cannot apply unary operator `-` to type `bool`
+ //~| ERROR expected expression, found `let` statement
fn _check_try_binds_tighter() -> Result<(), ()> {
let 0 = 0?;
//~^ ERROR the `?` operator can only be applied to values that implement `Try`
Ok(())
}
- (let 0 = 0)?; //~ ERROR `let` expressions are not supported here
- //~^ ERROR the `?` operator can only be used in a function that returns `Result`
+ (let 0 = 0)?;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR the `?` operator can only be used in a function that returns `Result`
//~| ERROR the `?` operator can only be applied to values that implement `Try`
+ //~| ERROR expected expression, found `let` statement
- true || let 0 = 0; //~ ERROR `let` expressions are not supported here
- (true || let 0 = 0); //~ ERROR `let` expressions are not supported here
- true && (true || let 0 = 0); //~ ERROR `let` expressions are not supported here
+ true || let 0 = 0;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ (true || let 0 = 0);
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ true && (true || let 0 = 0);
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
let mut x = true;
- x = let 0 = 0; //~ ERROR `let` expressions are not supported here
+ x = let 0 = 0;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
- true..(let 0 = 0); //~ ERROR `let` expressions are not supported here
- ..(let 0 = 0); //~ ERROR `let` expressions are not supported here
- (let 0 = 0)..; //~ ERROR `let` expressions are not supported here
+ true..(let 0 = 0);
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ ..(let 0 = 0);
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ (let 0 = 0)..;
+ //~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
(let Range { start: _, end: _ } = true..true || false);
//~^ ERROR `let` expressions are not supported here
//~| ERROR mismatched types
+ //~| ERROR expected expression, found `let` statement
(let true = let true = true);
//~^ ERROR `let` expressions are not supported here
+ //~| ERROR expected expression, found `let` statement
+ //~| ERROR expected expression, found `let` statement
+
+ {
+ #[cfg(FALSE)]
+ let x = true && let y = 1;
+ //~^ ERROR expected expression, found `let` statement
+ }
+
+ #[cfg(FALSE)]
+ {
+ [1, 2, 3][let _ = ()]
+ //~^ ERROR expected expression, found `let` statement
+ }
// Check function tail position.
&let 0 = 0
//~^ ERROR `let` expressions are not supported here
//~| ERROR mismatched types
+ //~| ERROR expected expression, found `let` statement
}
// Let's make sure that `let` inside const generic arguments are considered.
@@ -335,4 +379,14 @@ fn with_parenthesis() {
let fun = || true;
if let true = (true && fun()) && (true) {
}
+
+ #[cfg(FALSE)]
+ let x = (true && let y = 1);
+ //~^ ERROR expected expression, found `let` statement
+
+ #[cfg(FALSE)]
+ {
+ ([1, 2, 3][let _ = ()])
+ //~^ ERROR expected expression, found `let` statement
+ }
}
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
index f7f39bd0b9a..5cf06cf4b27 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
@@ -1,5 +1,113 @@
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:232:6
+ |
+LL | &let 0 = 0;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:236:6
+ |
+LL | !let 0 = 0;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:239:6
+ |
+LL | *let 0 = 0;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:243:6
+ |
+LL | -let 0 = 0;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:253:6
+ |
+LL | (let 0 = 0)?;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:259:13
+ |
+LL | true || let 0 = 0;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:262:14
+ |
+LL | (true || let 0 = 0);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:265:22
+ |
+LL | true && (true || let 0 = 0);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:270:9
+ |
+LL | x = let 0 = 0;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:274:12
+ |
+LL | true..(let 0 = 0);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:277:8
+ |
+LL | ..(let 0 = 0);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:280:6
+ |
+LL | (let 0 = 0)..;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:284:6
+ |
+LL | (let Range { start: _, end: _ } = true..true || false);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:289:6
+ |
+LL | (let true = let true = true);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:289:17
+ |
+LL | (let true = let true = true);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:296:25
+ |
+LL | let x = true && let y = 1;
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:302:19
+ |
+LL | [1, 2, 3][let _ = ()]
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:307:6
+ |
+LL | &let 0 = 0
+ | ^^^
+
error: expressions must be enclosed in braces to be used as const generic arguments
- --> $DIR/disallowed-positions.rs:293:9
+ --> $DIR/disallowed-positions.rs:337:9
|
LL | true && let 1 = 1
| ^^^^^^^^^^^^^^^^^
@@ -9,6 +117,30 @@ help: enclose the `const` expression in braces
LL | { true && let 1 = 1 }
| + +
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:384:22
+ |
+LL | let x = (true && let y = 1);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:389:20
+ |
+LL | ([1, 2, 3][let _ = ()])
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:81:16
+ |
+LL | use_expr!((let 0 = 1 && 0 == 0));
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/disallowed-positions.rs:85:16
+ |
+LL | use_expr!((let 0 = 1));
+ | ^^^
+
error: `let` expressions are not supported here
--> $DIR/disallowed-positions.rs:29:9
|
@@ -270,33 +402,33 @@ LL | use_expr!((let 0 = 1 && 0 == 0));
| ^^^^^^^^^^^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:84:16
+ --> $DIR/disallowed-positions.rs:85:16
|
LL | use_expr!((let 0 = 1));
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:84:16
+ --> $DIR/disallowed-positions.rs:85:16
|
LL | use_expr!((let 0 = 1));
| ^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:84:16
+ --> $DIR/disallowed-positions.rs:85:16
|
LL | use_expr!((let 0 = 1));
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:84:16
+ --> $DIR/disallowed-positions.rs:85:16
|
LL | use_expr!((let 0 = 1));
| ^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:90:9
+ --> $DIR/disallowed-positions.rs:92:9
|
LL | if &let 0 = 0 {}
| ^^^^^^^^^
@@ -304,7 +436,7 @@ LL | if &let 0 = 0 {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:93:9
+ --> $DIR/disallowed-positions.rs:95:9
|
LL | if !let 0 = 0 {}
| ^^^^^^^^^
@@ -312,7 +444,7 @@ LL | if !let 0 = 0 {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:94:9
+ --> $DIR/disallowed-positions.rs:96:9
|
LL | if *let 0 = 0 {}
| ^^^^^^^^^
@@ -320,7 +452,7 @@ LL | if *let 0 = 0 {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:96:9
+ --> $DIR/disallowed-positions.rs:98:9
|
LL | if -let 0 = 0 {}
| ^^^^^^^^^
@@ -328,72 +460,72 @@ LL | if -let 0 = 0 {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:104:9
+ --> $DIR/disallowed-positions.rs:106:9
|
LL | if (let 0 = 0)? {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:104:9
+ --> $DIR/disallowed-positions.rs:106:9
|
LL | if (let 0 = 0)? {}
| ^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:108:16
+ --> $DIR/disallowed-positions.rs:110:16
|
LL | if true || let 0 = 0 {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `||` operators are not supported in let chain expressions
- --> $DIR/disallowed-positions.rs:108:13
+ --> $DIR/disallowed-positions.rs:110:13
|
LL | if true || let 0 = 0 {}
| ^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:109:17
+ --> $DIR/disallowed-positions.rs:111:17
|
LL | if (true || let 0 = 0) {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `||` operators are not supported in let chain expressions
- --> $DIR/disallowed-positions.rs:109:14
+ --> $DIR/disallowed-positions.rs:111:14
|
LL | if (true || let 0 = 0) {}
| ^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:110:25
+ --> $DIR/disallowed-positions.rs:112:25
|
LL | if true && (true || let 0 = 0) {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `||` operators are not supported in let chain expressions
- --> $DIR/disallowed-positions.rs:110:22
+ --> $DIR/disallowed-positions.rs:112:22
|
LL | if true && (true || let 0 = 0) {}
| ^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:111:25
+ --> $DIR/disallowed-positions.rs:113:25
|
LL | if true || (true && let 0 = 0) {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:111:17
+ --> $DIR/disallowed-positions.rs:113:17
|
LL | if true || (true && let 0 = 0) {}
| ^^^^^^^^^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:114:12
+ --> $DIR/disallowed-positions.rs:116:12
|
LL | if x = let 0 = 0 {}
| ^^^^^^^^^
@@ -401,46 +533,46 @@ LL | if x = let 0 = 0 {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:117:15
+ --> $DIR/disallowed-positions.rs:119:15
|
LL | if true..(let 0 = 0) {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:117:15
+ --> $DIR/disallowed-positions.rs:119:15
|
LL | if true..(let 0 = 0) {}
| ^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:119:11
+ --> $DIR/disallowed-positions.rs:121:11
|
LL | if ..(let 0 = 0) {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:119:11
+ --> $DIR/disallowed-positions.rs:121:11
|
LL | if ..(let 0 = 0) {}
| ^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:121:9
+ --> $DIR/disallowed-positions.rs:123:9
|
LL | if (let 0 = 0).. {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:121:9
+ --> $DIR/disallowed-positions.rs:123:9
|
LL | if (let 0 = 0).. {}
| ^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:125:8
+ --> $DIR/disallowed-positions.rs:127:8
|
LL | if let Range { start: _, end: _ } = true..true && false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -448,7 +580,7 @@ LL | if let Range { start: _, end: _ } = true..true && false {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:129:8
+ --> $DIR/disallowed-positions.rs:131:8
|
LL | if let Range { start: _, end: _ } = true..true || false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -456,7 +588,7 @@ LL | if let Range { start: _, end: _ } = true..true || false {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:136:8
+ --> $DIR/disallowed-positions.rs:138:8
|
LL | if let Range { start: F, end } = F..|| true {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -464,7 +596,7 @@ LL | if let Range { start: F, end } = F..|| true {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:144:8
+ --> $DIR/disallowed-positions.rs:146:8
|
LL | if let Range { start: true, end } = t..&&false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -472,7 +604,7 @@ LL | if let Range { start: true, end } = t..&&false {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:150:19
+ --> $DIR/disallowed-positions.rs:152:19
|
LL | if let true = let true = true {}
| ^^^^^^^^^^^^^^^
@@ -480,7 +612,7 @@ LL | if let true = let true = true {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:154:12
+ --> $DIR/disallowed-positions.rs:157:12
|
LL | while &let 0 = 0 {}
| ^^^^^^^^^
@@ -488,7 +620,7 @@ LL | while &let 0 = 0 {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:157:12
+ --> $DIR/disallowed-positions.rs:160:12
|
LL | while !let 0 = 0 {}
| ^^^^^^^^^
@@ -496,7 +628,7 @@ LL | while !let 0 = 0 {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:158:12
+ --> $DIR/disallowed-positions.rs:161:12
|
LL | while *let 0 = 0 {}
| ^^^^^^^^^
@@ -504,7 +636,7 @@ LL | while *let 0 = 0 {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:160:12
+ --> $DIR/disallowed-positions.rs:163:12
|
LL | while -let 0 = 0 {}
| ^^^^^^^^^
@@ -512,72 +644,72 @@ LL | while -let 0 = 0 {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:168:12
+ --> $DIR/disallowed-positions.rs:171:12
|
LL | while (let 0 = 0)? {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:168:12
+ --> $DIR/disallowed-positions.rs:171:12
|
LL | while (let 0 = 0)? {}
| ^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:172:19
+ --> $DIR/disallowed-positions.rs:175:19
|
LL | while true || let 0 = 0 {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `||` operators are not supported in let chain expressions
- --> $DIR/disallowed-positions.rs:172:16
+ --> $DIR/disallowed-positions.rs:175:16
|
LL | while true || let 0 = 0 {}
| ^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:173:20
+ --> $DIR/disallowed-positions.rs:176:20
|
LL | while (true || let 0 = 0) {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `||` operators are not supported in let chain expressions
- --> $DIR/disallowed-positions.rs:173:17
+ --> $DIR/disallowed-positions.rs:176:17
|
LL | while (true || let 0 = 0) {}
| ^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:174:28
+ --> $DIR/disallowed-positions.rs:177:28
|
LL | while true && (true || let 0 = 0) {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `||` operators are not supported in let chain expressions
- --> $DIR/disallowed-positions.rs:174:25
+ --> $DIR/disallowed-positions.rs:177:25
|
LL | while true && (true || let 0 = 0) {}
| ^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:175:28
+ --> $DIR/disallowed-positions.rs:178:28
|
LL | while true || (true && let 0 = 0) {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:175:20
+ --> $DIR/disallowed-positions.rs:178:20
|
LL | while true || (true && let 0 = 0) {}
| ^^^^^^^^^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:178:15
+ --> $DIR/disallowed-positions.rs:181:15
|
LL | while x = let 0 = 0 {}
| ^^^^^^^^^
@@ -585,46 +717,46 @@ LL | while x = let 0 = 0 {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:181:18
+ --> $DIR/disallowed-positions.rs:184:18
|
LL | while true..(let 0 = 0) {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:181:18
+ --> $DIR/disallowed-positions.rs:184:18
|
LL | while true..(let 0 = 0) {}
| ^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:183:14
+ --> $DIR/disallowed-positions.rs:186:14
|
LL | while ..(let 0 = 0) {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:183:14
+ --> $DIR/disallowed-positions.rs:186:14
|
LL | while ..(let 0 = 0) {}
| ^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:185:12
+ --> $DIR/disallowed-positions.rs:188:12
|
LL | while (let 0 = 0).. {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:185:12
+ --> $DIR/disallowed-positions.rs:188:12
|
LL | while (let 0 = 0).. {}
| ^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:189:11
+ --> $DIR/disallowed-positions.rs:192:11
|
LL | while let Range { start: _, end: _ } = true..true && false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -632,7 +764,7 @@ LL | while let Range { start: _, end: _ } = true..true && false {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:193:11
+ --> $DIR/disallowed-positions.rs:196:11
|
LL | while let Range { start: _, end: _ } = true..true || false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -640,7 +772,7 @@ LL | while let Range { start: _, end: _ } = true..true || false {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:200:11
+ --> $DIR/disallowed-positions.rs:203:11
|
LL | while let Range { start: F, end } = F..|| true {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -648,7 +780,7 @@ LL | while let Range { start: F, end } = F..|| true {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:208:11
+ --> $DIR/disallowed-positions.rs:211:11
|
LL | while let Range { start: true, end } = t..&&false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -656,7 +788,7 @@ LL | while let Range { start: true, end } = t..&&false {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:214:22
+ --> $DIR/disallowed-positions.rs:217:22
|
LL | while let true = let true = true {}
| ^^^^^^^^^^^^^^^
@@ -664,7 +796,7 @@ LL | while let true = let true = true {}
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:228:6
+ --> $DIR/disallowed-positions.rs:232:6
|
LL | &let 0 = 0;
| ^^^^^^^^^
@@ -672,7 +804,7 @@ LL | &let 0 = 0;
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:230:6
+ --> $DIR/disallowed-positions.rs:236:6
|
LL | !let 0 = 0;
| ^^^^^^^^^
@@ -680,7 +812,7 @@ LL | !let 0 = 0;
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:231:6
+ --> $DIR/disallowed-positions.rs:239:6
|
LL | *let 0 = 0;
| ^^^^^^^^^
@@ -688,7 +820,7 @@ LL | *let 0 = 0;
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:233:6
+ --> $DIR/disallowed-positions.rs:243:6
|
LL | -let 0 = 0;
| ^^^^^^^^^
@@ -696,59 +828,59 @@ LL | -let 0 = 0;
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:241:6
+ --> $DIR/disallowed-positions.rs:253:6
|
LL | (let 0 = 0)?;
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:241:6
+ --> $DIR/disallowed-positions.rs:253:6
|
LL | (let 0 = 0)?;
| ^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:245:13
+ --> $DIR/disallowed-positions.rs:259:13
|
LL | true || let 0 = 0;
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `||` operators are not supported in let chain expressions
- --> $DIR/disallowed-positions.rs:245:10
+ --> $DIR/disallowed-positions.rs:259:10
|
LL | true || let 0 = 0;
| ^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:246:14
+ --> $DIR/disallowed-positions.rs:262:14
|
LL | (true || let 0 = 0);
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `||` operators are not supported in let chain expressions
- --> $DIR/disallowed-positions.rs:246:11
+ --> $DIR/disallowed-positions.rs:262:11
|
LL | (true || let 0 = 0);
| ^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:247:22
+ --> $DIR/disallowed-positions.rs:265:22
|
LL | true && (true || let 0 = 0);
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `||` operators are not supported in let chain expressions
- --> $DIR/disallowed-positions.rs:247:19
+ --> $DIR/disallowed-positions.rs:265:19
|
LL | true && (true || let 0 = 0);
| ^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:250:9
+ --> $DIR/disallowed-positions.rs:270:9
|
LL | x = let 0 = 0;
| ^^^^^^^^^
@@ -756,46 +888,46 @@ LL | x = let 0 = 0;
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:252:12
+ --> $DIR/disallowed-positions.rs:274:12
|
LL | true..(let 0 = 0);
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:252:12
+ --> $DIR/disallowed-positions.rs:274:12
|
LL | true..(let 0 = 0);
| ^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:253:8
+ --> $DIR/disallowed-positions.rs:277:8
|
LL | ..(let 0 = 0);
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:253:8
+ --> $DIR/disallowed-positions.rs:277:8
|
LL | ..(let 0 = 0);
| ^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:254:6
+ --> $DIR/disallowed-positions.rs:280:6
|
LL | (let 0 = 0)..;
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:254:6
+ --> $DIR/disallowed-positions.rs:280:6
|
LL | (let 0 = 0)..;
| ^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:256:6
+ --> $DIR/disallowed-positions.rs:284:6
|
LL | (let Range { start: _, end: _ } = true..true || false);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -803,20 +935,20 @@ LL | (let Range { start: _, end: _ } = true..true || false);
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:260:6
+ --> $DIR/disallowed-positions.rs:289:6
|
LL | (let true = let true = true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:260:6
+ --> $DIR/disallowed-positions.rs:289:6
|
LL | (let true = let true = true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:264:6
+ --> $DIR/disallowed-positions.rs:307:6
|
LL | &let 0 = 0
| ^^^^^^^^^
@@ -824,7 +956,7 @@ LL | &let 0 = 0
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:275:17
+ --> $DIR/disallowed-positions.rs:319:17
|
LL | true && let 1 = 1
| ^^^^^^^^^
@@ -832,7 +964,7 @@ LL | true && let 1 = 1
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:279:17
+ --> $DIR/disallowed-positions.rs:323:17
|
LL | true && let 1 = 1
| ^^^^^^^^^
@@ -840,7 +972,7 @@ LL | true && let 1 = 1
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:283:17
+ --> $DIR/disallowed-positions.rs:327:17
|
LL | true && let 1 = 1
| ^^^^^^^^^
@@ -848,7 +980,7 @@ LL | true && let 1 = 1
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:293:17
+ --> $DIR/disallowed-positions.rs:337:17
|
LL | true && let 1 = 1
| ^^^^^^^^^
@@ -856,124 +988,124 @@ LL | true && let 1 = 1
= note: only supported directly in conditions of `if` and `while` expressions
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:302:9
+ --> $DIR/disallowed-positions.rs:346:9
|
LL | if (let Some(a) = opt && true) {
| ^^^^^^^^^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:302:9
+ --> $DIR/disallowed-positions.rs:346:9
|
LL | if (let Some(a) = opt && true) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:306:9
+ --> $DIR/disallowed-positions.rs:350:9
|
LL | if (let Some(a) = opt) && true {
| ^^^^^^^^^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:306:9
+ --> $DIR/disallowed-positions.rs:350:9
|
LL | if (let Some(a) = opt) && true {
| ^^^^^^^^^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:309:9
+ --> $DIR/disallowed-positions.rs:353:9
|
LL | if (let Some(a) = opt) && (let Some(b) = a) {
| ^^^^^^^^^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:309:9
+ --> $DIR/disallowed-positions.rs:353:9
|
LL | if (let Some(a) = opt) && (let Some(b) = a) {
| ^^^^^^^^^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:309:32
+ --> $DIR/disallowed-positions.rs:353:32
|
LL | if (let Some(a) = opt) && (let Some(b) = a) {
| ^^^^^^^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:309:32
+ --> $DIR/disallowed-positions.rs:353:32
|
LL | if (let Some(a) = opt) && (let Some(b) = a) {
| ^^^^^^^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:316:9
+ --> $DIR/disallowed-positions.rs:360:9
|
LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
| ^^^^^^^^^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:316:9
+ --> $DIR/disallowed-positions.rs:360:9
|
LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:316:31
+ --> $DIR/disallowed-positions.rs:360:31
|
LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
| ^^^^^^^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:316:31
+ --> $DIR/disallowed-positions.rs:360:31
|
LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
| ^^^^^^^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:320:9
+ --> $DIR/disallowed-positions.rs:364:9
|
LL | if (let Some(a) = opt && (let Some(b) = a)) && true {
| ^^^^^^^^^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:320:9
+ --> $DIR/disallowed-positions.rs:364:9
|
LL | if (let Some(a) = opt && (let Some(b) = a)) && true {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:320:31
+ --> $DIR/disallowed-positions.rs:364:31
|
LL | if (let Some(a) = opt && (let Some(b) = a)) && true {
| ^^^^^^^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:320:31
+ --> $DIR/disallowed-positions.rs:364:31
|
LL | if (let Some(a) = opt && (let Some(b) = a)) && true {
| ^^^^^^^^^^^^^^^
error: `let` expressions are not supported here
- --> $DIR/disallowed-positions.rs:324:9
+ --> $DIR/disallowed-positions.rs:368:9
|
LL | if (let Some(a) = opt && (true)) && true {
| ^^^^^^^^^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
- --> $DIR/disallowed-positions.rs:324:9
+ --> $DIR/disallowed-positions.rs:368:9
|
LL | if (let Some(a) = opt && (true)) && true {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:90:8
+ --> $DIR/disallowed-positions.rs:92:8
|
LL | if &let 0 = 0 {}
| ^^^^^^^^^^ expected `bool`, found `&bool`
@@ -985,19 +1117,19 @@ LL + if let 0 = 0 {}
|
error[E0614]: type `bool` cannot be dereferenced
- --> $DIR/disallowed-positions.rs:94:8
+ --> $DIR/disallowed-positions.rs:96:8
|
LL | if *let 0 = 0 {}
| ^^^^^^^^^^
error[E0600]: cannot apply unary operator `-` to type `bool`
- --> $DIR/disallowed-positions.rs:96:8
+ --> $DIR/disallowed-positions.rs:98:8
|
LL | if -let 0 = 0 {}
| ^^^^^^^^^^ cannot apply unary operator `-`
error[E0277]: the `?` operator can only be applied to values that implement `Try`
- --> $DIR/disallowed-positions.rs:104:8
+ --> $DIR/disallowed-positions.rs:106:8
|
LL | if (let 0 = 0)? {}
| ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
@@ -1005,7 +1137,7 @@ LL | if (let 0 = 0)? {}
= help: the trait `Try` is not implemented for `bool`
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
- --> $DIR/disallowed-positions.rs:104:19
+ --> $DIR/disallowed-positions.rs:106:19
|
LL | / fn nested_within_if_expr() {
LL | | if &let 0 = 0 {}
@@ -1015,14 +1147,14 @@ LL | |
LL | | if (let 0 = 0)? {}
| | ^ cannot use the `?` operator in a function that returns `()`
... |
-LL | | if let true = let true = true {}
+LL | |
LL | | }
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<_>` is not implemented for `()`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:114:8
+ --> $DIR/disallowed-positions.rs:116:8
|
LL | if x = let 0 = 0 {}
| ^^^^^^^^^^^^^ expected `bool`, found `()`
@@ -1033,7 +1165,7 @@ LL | if x == let 0 = 0 {}
| ~~
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:117:8
+ --> $DIR/disallowed-positions.rs:119:8
|
LL | if true..(let 0 = 0) {}
| ^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1042,7 +1174,7 @@ LL | if true..(let 0 = 0) {}
found struct `std::ops::Range<bool>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:119:8
+ --> $DIR/disallowed-positions.rs:121:8
|
LL | if ..(let 0 = 0) {}
| ^^^^^^^^^^^^^ expected `bool`, found struct `RangeTo`
@@ -1051,7 +1183,7 @@ LL | if ..(let 0 = 0) {}
found struct `RangeTo<bool>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:121:8
+ --> $DIR/disallowed-positions.rs:123:8
|
LL | if (let 0 = 0).. {}
| ^^^^^^^^^^^^^ expected `bool`, found struct `RangeFrom`
@@ -1060,7 +1192,7 @@ LL | if (let 0 = 0).. {}
found struct `RangeFrom<bool>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:125:12
+ --> $DIR/disallowed-positions.rs:127:12
|
LL | if let Range { start: _, end: _ } = true..true && false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
@@ -1071,7 +1203,7 @@ LL | if let Range { start: _, end: _ } = true..true && false {}
found struct `std::ops::Range<_>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:125:8
+ --> $DIR/disallowed-positions.rs:127:8
|
LL | if let Range { start: _, end: _ } = true..true && false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1080,7 +1212,7 @@ LL | if let Range { start: _, end: _ } = true..true && false {}
found struct `std::ops::Range<bool>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:129:12
+ --> $DIR/disallowed-positions.rs:131:12
|
LL | if let Range { start: _, end: _ } = true..true || false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
@@ -1091,7 +1223,7 @@ LL | if let Range { start: _, end: _ } = true..true || false {}
found struct `std::ops::Range<_>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:129:8
+ --> $DIR/disallowed-positions.rs:131:8
|
LL | if let Range { start: _, end: _ } = true..true || false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1100,7 +1232,7 @@ LL | if let Range { start: _, end: _ } = true..true || false {}
found struct `std::ops::Range<bool>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:136:12
+ --> $DIR/disallowed-positions.rs:138:12
|
LL | if let Range { start: F, end } = F..|| true {}
| ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `fn() -> bool`
@@ -1111,20 +1243,20 @@ LL | if let Range { start: F, end } = F..|| true {}
found struct `std::ops::Range<_>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:136:41
+ --> $DIR/disallowed-positions.rs:138:41
|
LL | if let Range { start: F, end } = F..|| true {}
| ^^^^^^^ expected `bool`, found closure
|
= note: expected type `bool`
- found closure `[closure@$DIR/disallowed-positions.rs:136:41: 136:48]`
+ found closure `[closure@$DIR/disallowed-positions.rs:138:41: 138:48]`
help: use parentheses to call this closure
|
LL | if let Range { start: F, end } = F..(|| true)() {}
| + +++
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:136:8
+ --> $DIR/disallowed-positions.rs:138:8
|
LL | if let Range { start: F, end } = F..|| true {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1133,7 +1265,7 @@ LL | if let Range { start: F, end } = F..|| true {}
found struct `std::ops::Range<bool>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:144:12
+ --> $DIR/disallowed-positions.rs:146:12
|
LL | if let Range { start: true, end } = t..&&false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool`
@@ -1144,7 +1276,7 @@ LL | if let Range { start: true, end } = t..&&false {}
found struct `std::ops::Range<_>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:144:44
+ --> $DIR/disallowed-positions.rs:146:44
|
LL | if let Range { start: true, end } = t..&&false {}
| ^^^^^^^ expected `bool`, found `&&bool`
@@ -1156,7 +1288,7 @@ LL + if let Range { start: true, end } = t..false {}
|
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:144:8
+ --> $DIR/disallowed-positions.rs:146:8
|
LL | if let Range { start: true, end } = t..&&false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1165,7 +1297,7 @@ LL | if let Range { start: true, end } = t..&&false {}
found struct `std::ops::Range<bool>`
error[E0277]: the `?` operator can only be applied to values that implement `Try`
- --> $DIR/disallowed-positions.rs:100:20
+ --> $DIR/disallowed-positions.rs:102:20
|
LL | if let 0 = 0? {}
| ^^ the `?` operator cannot be applied to type `{integer}`
@@ -1173,7 +1305,7 @@ LL | if let 0 = 0? {}
= help: the trait `Try` is not implemented for `{integer}`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:154:11
+ --> $DIR/disallowed-positions.rs:157:11
|
LL | while &let 0 = 0 {}
| ^^^^^^^^^^ expected `bool`, found `&bool`
@@ -1185,19 +1317,19 @@ LL + while let 0 = 0 {}
|
error[E0614]: type `bool` cannot be dereferenced
- --> $DIR/disallowed-positions.rs:158:11
+ --> $DIR/disallowed-positions.rs:161:11
|
LL | while *let 0 = 0 {}
| ^^^^^^^^^^
error[E0600]: cannot apply unary operator `-` to type `bool`
- --> $DIR/disallowed-positions.rs:160:11
+ --> $DIR/disallowed-positions.rs:163:11
|
LL | while -let 0 = 0 {}
| ^^^^^^^^^^ cannot apply unary operator `-`
error[E0277]: the `?` operator can only be applied to values that implement `Try`
- --> $DIR/disallowed-positions.rs:168:11
+ --> $DIR/disallowed-positions.rs:171:11
|
LL | while (let 0 = 0)? {}
| ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
@@ -1205,7 +1337,7 @@ LL | while (let 0 = 0)? {}
= help: the trait `Try` is not implemented for `bool`
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
- --> $DIR/disallowed-positions.rs:168:22
+ --> $DIR/disallowed-positions.rs:171:22
|
LL | / fn nested_within_while_expr() {
LL | | while &let 0 = 0 {}
@@ -1215,14 +1347,14 @@ LL | |
LL | | while (let 0 = 0)? {}
| | ^ cannot use the `?` operator in a function that returns `()`
... |
-LL | | while let true = let true = true {}
+LL | |
LL | | }
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<_>` is not implemented for `()`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:178:11
+ --> $DIR/disallowed-positions.rs:181:11
|
LL | while x = let 0 = 0 {}
| ^^^^^^^^^^^^^ expected `bool`, found `()`
@@ -1233,7 +1365,7 @@ LL | while x == let 0 = 0 {}
| ~~
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:181:11
+ --> $DIR/disallowed-positions.rs:184:11
|
LL | while true..(let 0 = 0) {}
| ^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1242,7 +1374,7 @@ LL | while true..(let 0 = 0) {}
found struct `std::ops::Range<bool>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:183:11
+ --> $DIR/disallowed-positions.rs:186:11
|
LL | while ..(let 0 = 0) {}
| ^^^^^^^^^^^^^ expected `bool`, found struct `RangeTo`
@@ -1251,7 +1383,7 @@ LL | while ..(let 0 = 0) {}
found struct `RangeTo<bool>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:185:11
+ --> $DIR/disallowed-positions.rs:188:11
|
LL | while (let 0 = 0).. {}
| ^^^^^^^^^^^^^ expected `bool`, found struct `RangeFrom`
@@ -1260,7 +1392,7 @@ LL | while (let 0 = 0).. {}
found struct `RangeFrom<bool>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:189:15
+ --> $DIR/disallowed-positions.rs:192:15
|
LL | while let Range { start: _, end: _ } = true..true && false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
@@ -1271,7 +1403,7 @@ LL | while let Range { start: _, end: _ } = true..true && false {}
found struct `std::ops::Range<_>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:189:11
+ --> $DIR/disallowed-positions.rs:192:11
|
LL | while let Range { start: _, end: _ } = true..true && false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1280,7 +1412,7 @@ LL | while let Range { start: _, end: _ } = true..true && false {}
found struct `std::ops::Range<bool>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:193:15
+ --> $DIR/disallowed-positions.rs:196:15
|
LL | while let Range { start: _, end: _ } = true..true || false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
@@ -1291,7 +1423,7 @@ LL | while let Range { start: _, end: _ } = true..true || false {}
found struct `std::ops::Range<_>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:193:11
+ --> $DIR/disallowed-positions.rs:196:11
|
LL | while let Range { start: _, end: _ } = true..true || false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1300,7 +1432,7 @@ LL | while let Range { start: _, end: _ } = true..true || false {}
found struct `std::ops::Range<bool>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:200:15
+ --> $DIR/disallowed-positions.rs:203:15
|
LL | while let Range { start: F, end } = F..|| true {}
| ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `fn() -> bool`
@@ -1311,20 +1443,20 @@ LL | while let Range { start: F, end } = F..|| true {}
found struct `std::ops::Range<_>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:200:44
+ --> $DIR/disallowed-positions.rs:203:44
|
LL | while let Range { start: F, end } = F..|| true {}
| ^^^^^^^ expected `bool`, found closure
|
= note: expected type `bool`
- found closure `[closure@$DIR/disallowed-positions.rs:200:44: 200:51]`
+ found closure `[closure@$DIR/disallowed-positions.rs:203:44: 203:51]`
help: use parentheses to call this closure
|
LL | while let Range { start: F, end } = F..(|| true)() {}
| + +++
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:200:11
+ --> $DIR/disallowed-positions.rs:203:11
|
LL | while let Range { start: F, end } = F..|| true {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1333,7 +1465,7 @@ LL | while let Range { start: F, end } = F..|| true {}
found struct `std::ops::Range<bool>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:208:15
+ --> $DIR/disallowed-positions.rs:211:15
|
LL | while let Range { start: true, end } = t..&&false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool`
@@ -1344,7 +1476,7 @@ LL | while let Range { start: true, end } = t..&&false {}
found struct `std::ops::Range<_>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:208:47
+ --> $DIR/disallowed-positions.rs:211:47
|
LL | while let Range { start: true, end } = t..&&false {}
| ^^^^^^^ expected `bool`, found `&&bool`
@@ -1356,7 +1488,7 @@ LL + while let Range { start: true, end } = t..false {}
|
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:208:11
+ --> $DIR/disallowed-positions.rs:211:11
|
LL | while let Range { start: true, end } = t..&&false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1365,7 +1497,7 @@ LL | while let Range { start: true, end } = t..&&false {}
found struct `std::ops::Range<bool>`
error[E0277]: the `?` operator can only be applied to values that implement `Try`
- --> $DIR/disallowed-positions.rs:164:23
+ --> $DIR/disallowed-positions.rs:167:23
|
LL | while let 0 = 0? {}
| ^^ the `?` operator cannot be applied to type `{integer}`
@@ -1373,19 +1505,19 @@ LL | while let 0 = 0? {}
= help: the trait `Try` is not implemented for `{integer}`
error[E0614]: type `bool` cannot be dereferenced
- --> $DIR/disallowed-positions.rs:231:5
+ --> $DIR/disallowed-positions.rs:239:5
|
LL | *let 0 = 0;
| ^^^^^^^^^^
error[E0600]: cannot apply unary operator `-` to type `bool`
- --> $DIR/disallowed-positions.rs:233:5
+ --> $DIR/disallowed-positions.rs:243:5
|
LL | -let 0 = 0;
| ^^^^^^^^^^ cannot apply unary operator `-`
error[E0277]: the `?` operator can only be applied to values that implement `Try`
- --> $DIR/disallowed-positions.rs:241:5
+ --> $DIR/disallowed-positions.rs:253:5
|
LL | (let 0 = 0)?;
| ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
@@ -1393,12 +1525,12 @@ LL | (let 0 = 0)?;
= help: the trait `Try` is not implemented for `bool`
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
- --> $DIR/disallowed-positions.rs:241:16
+ --> $DIR/disallowed-positions.rs:253:16
|
LL | / fn outside_if_and_while_expr() {
LL | | &let 0 = 0;
LL | |
-LL | | !let 0 = 0;
+LL | |
... |
LL | | (let 0 = 0)?;
| | ^ cannot use the `?` operator in a function that returns `()`
@@ -1410,7 +1542,7 @@ LL | | }
= help: the trait `FromResidual<_>` is not implemented for `()`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:256:10
+ --> $DIR/disallowed-positions.rs:284:10
|
LL | (let Range { start: _, end: _ } = true..true || false);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
@@ -1421,7 +1553,7 @@ LL | (let Range { start: _, end: _ } = true..true || false);
found struct `std::ops::Range<_>`
error[E0308]: mismatched types
- --> $DIR/disallowed-positions.rs:264:5
+ --> $DIR/disallowed-positions.rs:307:5
|
LL | fn outside_if_and_while_expr() {
| - help: try adding a return type: `-> &bool`
@@ -1430,14 +1562,14 @@ LL | &let 0 = 0
| ^^^^^^^^^^ expected `()`, found `&bool`
error[E0277]: the `?` operator can only be applied to values that implement `Try`
- --> $DIR/disallowed-positions.rs:237:17
+ --> $DIR/disallowed-positions.rs:249:17
|
LL | let 0 = 0?;
| ^^ the `?` operator cannot be applied to type `{integer}`
|
= help: the trait `Try` is not implemented for `{integer}`
-error: aborting due to 134 previous errors
+error: aborting due to 156 previous errors
Some errors have detailed explanations: E0277, E0308, E0600, E0614.
For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs
index e66caa19ec9..12befc637c7 100644
--- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs
@@ -17,6 +17,7 @@ fn main() {
//~| ERROR `let` expressions are not supported here
//~| ERROR mismatched types
//~| ERROR mismatched types
+ //~| ERROR expected expression, found `let` statement
return;
};
diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr
index eea8ed0c963..498a112fa9b 100644
--- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr
@@ -9,6 +9,12 @@ help: wrap the expression in parentheses
LL | let Some(n) = (opt && n == 1) else {
| + +
+error: expected expression, found `let` statement
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:26
+ |
+LL | let Some(n) = opt && let another = n else {
+ | ^^^
+
error: a `&&` expression cannot be directly assigned in `let...else`
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:19
|
@@ -21,43 +27,43 @@ LL | let Some(n) = (opt && let another = n) else {
| + +
error: this `if` expression is missing a block after the condition
- --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:23:5
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:24:5
|
LL | if let Some(n) = opt else {
| ^^
|
help: add a block here
- --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:23:25
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:24:25
|
LL | if let Some(n) = opt else {
| ^
error: this `if` expression is missing a block after the condition
- --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:27:5
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:28:5
|
LL | if let Some(n) = opt && n == 1 else {
| ^^
|
help: add a block here
- --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:27:35
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:28:35
|
LL | if let Some(n) = opt && n == 1 else {
| ^
error: this `if` expression is missing a block after the condition
- --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:31:5
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:32:5
|
LL | if let Some(n) = opt && let another = n else {
| ^^
|
help: add a block here
- --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:31:44
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:32:44
|
LL | if let Some(n) = opt && let another = n else {
| ^
error: expected `{`, found keyword `else`
- --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:37:33
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:38:33
|
LL | while let Some(n) = opt else {
| ----- ----------------- ^^^^ expected `{`
@@ -66,7 +72,7 @@ LL | while let Some(n) = opt else {
| while parsing the body of this `while` expression
error: expected `{`, found keyword `else`
- --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:43:43
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:44:43
|
LL | while let Some(n) = opt && n == 1 else {
| ----- --------------------------- ^^^^ expected `{`
@@ -75,7 +81,7 @@ LL | while let Some(n) = opt && n == 1 else {
| while parsing the body of this `while` expression
error: expected `{`, found keyword `else`
- --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:49:52
+ --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:50:52
|
LL | while let Some(n) = opt && let another = n else {
| ----- ------------------------------------ ^^^^ expected `{`
@@ -131,6 +137,6 @@ LL | let Some(n) = opt && let another = n else {
= note: expected type `bool`
found enum `Option<_>`
-error: aborting due to 13 previous errors
+error: aborting due to 14 previous errors
For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs b/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs
index ac60bc7e57f..87718211308 100644
--- a/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs
@@ -39,6 +39,7 @@ fn _macros() {
noop_expr!((let 0 = 1));
//~^ ERROR `let` expressions in this position are unstable [E0658]
+ //~| ERROR expected expression, found `let` statement
macro_rules! use_expr {
($e:expr) => {
@@ -48,9 +49,9 @@ fn _macros() {
}
#[cfg(FALSE)] (let 0 = 1);
//~^ ERROR `let` expressions in this position are unstable [E0658]
+ //~| ERROR expected expression, found `let` statement
use_expr!(let 0 = 1);
//~^ ERROR no rules expected the token `let`
- // ^--- FIXME(53667): Consider whether `Let` can be added to `ident_can_begin_expr`.
}
fn main() {}
diff --git a/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr
index 1eabee47c64..bcea8bbaa73 100644
--- a/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr
@@ -1,5 +1,17 @@
+error: expected expression, found `let` statement
+ --> $DIR/feature-gate.rs:50:20
+ |
+LL | #[cfg(FALSE)] (let 0 = 1);
+ | ^^^
+
+error: expected expression, found `let` statement
+ --> $DIR/feature-gate.rs:40:17
+ |
+LL | noop_expr!((let 0 = 1));
+ | ^^^
+
error: no rules expected the token `let`
- --> $DIR/feature-gate.rs:51:15
+ --> $DIR/feature-gate.rs:53:15
|
LL | macro_rules! use_expr {
| --------------------- when calling this macro
@@ -62,7 +74,7 @@ LL | while let Range { start: _, end: _ } = (true..true) && false {}
= help: add `#![feature(let_chains)]` to the crate attributes to enable
error[E0658]: `let` expressions in this position are unstable
- --> $DIR/feature-gate.rs:49:20
+ --> $DIR/feature-gate.rs:50:20
|
LL | #[cfg(FALSE)] (let 0 = 1);
| ^^^^^^^^^
@@ -79,6 +91,6 @@ LL | noop_expr!((let 0 = 1));
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
= help: add `#![feature(let_chains)]` to the crate attributes to enable
-error: aborting due to 9 previous errors
+error: aborting due to 11 previous errors
For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs b/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs
new file mode 100644
index 00000000000..6cc53a1935b
--- /dev/null
+++ b/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs
@@ -0,0 +1,17 @@
+// check-pass
+// known-bug
+
+#![feature(let_chains)]
+
+fn main() {
+ let _opt = Some(1i32);
+
+ #[cfg(FALSE)]
+ {
+ if let Some(elem) = _opt && {
+ [1, 2, 3][let _ = ()];
+ true
+ } {
+ }
+ }
+}
diff --git a/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr b/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr
index 40b4b42f742..b77c8c7fd5b 100644
--- a/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr
+++ b/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr
@@ -1,3 +1,29 @@
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+ --> $DIR/adt-param-with-implicit-sized-bound.rs:25:9
+ |
+LL | struct Struct5<T: ?Sized>{
+ | - this type parameter needs to be `std::marker::Sized`
+LL | _t: X<T>,
+ | ^^^^ doesn't have a size known at compile-time
+ |
+note: required by a bound in `X`
+ --> $DIR/adt-param-with-implicit-sized-bound.rs:18:10
+ |
+LL | struct X<T>(T);
+ | ^ required by this bound in `X`
+help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
+ --> $DIR/adt-param-with-implicit-sized-bound.rs:18:10
+ |
+LL | struct X<T>(T);
+ | ^ - ...if indirection were used here: `Box<T>`
+ | |
+ | this could be changed to `T: ?Sized`...
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - struct Struct5<T: ?Sized>{
+LL + struct Struct5<T>{
+ |
+
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> $DIR/adt-param-with-implicit-sized-bound.rs:2:19
|
@@ -81,32 +107,6 @@ help: consider relaxing the implicit `Sized` restriction
LL | struct Struct4<T: ?Sized>{
| ++++++++
-error[E0277]: the size for values of type `T` cannot be known at compilation time
- --> $DIR/adt-param-with-implicit-sized-bound.rs:25:9
- |
-LL | struct Struct5<T: ?Sized>{
- | - this type parameter needs to be `std::marker::Sized`
-LL | _t: X<T>,
- | ^^^^ doesn't have a size known at compile-time
- |
-note: required by a bound in `X`
- --> $DIR/adt-param-with-implicit-sized-bound.rs:18:10
- |
-LL | struct X<T>(T);
- | ^ required by this bound in `X`
-help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
- --> $DIR/adt-param-with-implicit-sized-bound.rs:18:10
- |
-LL | struct X<T>(T);
- | ^ - ...if indirection were used here: `Box<T>`
- | |
- | this could be changed to `T: ?Sized`...
-help: consider removing the `?Sized` bound to make the type parameter `Sized`
- |
-LL - struct Struct5<T: ?Sized>{
-LL + struct Struct5<T>{
- |
-
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/auxiliary/not-object-safe.rs b/src/test/ui/suggestions/auxiliary/not-object-safe.rs
new file mode 100644
index 00000000000..7c9829b823e
--- /dev/null
+++ b/src/test/ui/suggestions/auxiliary/not-object-safe.rs
@@ -0,0 +1,6 @@
+use std::sync::Arc;
+
+pub trait A {
+ fn f();
+ fn f2(self: &Arc<Self>);
+}
diff --git a/src/test/ui/suggestions/issue-98500.rs b/src/test/ui/suggestions/issue-98500.rs
new file mode 100644
index 00000000000..a2717fd9206
--- /dev/null
+++ b/src/test/ui/suggestions/issue-98500.rs
@@ -0,0 +1,14 @@
+// aux-build:not-object-safe.rs
+
+extern crate not_object_safe;
+
+pub trait B where
+ Self: not_object_safe::A,
+{
+ fn f2(&self);
+}
+
+struct S(Box<dyn B>);
+//~^ ERROR the trait `B` cannot be made into an object
+
+fn main() {}
diff --git a/src/test/ui/suggestions/issue-98500.stderr b/src/test/ui/suggestions/issue-98500.stderr
new file mode 100644
index 00000000000..e7251d735e3
--- /dev/null
+++ b/src/test/ui/suggestions/issue-98500.stderr
@@ -0,0 +1,24 @@
+error[E0038]: the trait `B` cannot be made into an object
+ --> $DIR/issue-98500.rs:11:14
+ |
+LL | struct S(Box<dyn B>);
+ | ^^^^^ `B` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/auxiliary/not-object-safe.rs:4:8
+ |
+LL | fn f();
+ | ^ ...because associated function `f` has no `self` parameter
+LL | fn f2(self: &Arc<Self>);
+ | ^^ ...because method `f2`'s `self` parameter cannot be dispatched on
+ |
+ ::: $DIR/issue-98500.rs:5:11
+ |
+LL | pub trait B where
+ | - this trait cannot be made into an object...
+ = help: consider moving `f` to another trait
+ = help: consider moving `f2` to another trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed
index 73bb6725f5a..69487c565c9 100644
--- a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed
+++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed
@@ -2,7 +2,7 @@
#![allow(unused_variables, dead_code)]
trait Trait {
- fn foo(&self) where Self: Other, Self: Sized, { }
+ fn foo(&self) where Self: Other, Self: Sized { }
fn bar(self: &Self) {} //~ ERROR invalid `self` parameter type
}
diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
index 74237e6e6c6..c0dc71df06e 100644
--- a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
+++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
@@ -1,12 +1,3 @@
-error[E0307]: invalid `self` parameter type: ()
- --> $DIR/object-unsafe-trait-should-use-where-sized.rs:6:18
- |
-LL | fn bar(self: ()) {}
- | ^^
- |
- = note: type of `self` must be `Self` or a type that dereferences to it
- = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
-
error[E0038]: the trait `Trait` cannot be made into an object
--> $DIR/object-unsafe-trait-should-use-where-sized.rs:9:12
|
@@ -28,13 +19,22 @@ LL | fn foo(&self) where Self: Other, { }
| +++++
help: alternatively, consider constraining `foo` so it does not apply to trait objects
|
-LL | fn foo() where Self: Other, Self: Sized, { }
- | +++++++++++++
+LL | fn foo() where Self: Other, Self: Sized { }
+ | ~~~~~~~~~~~~~
help: consider changing method `bar`'s `self` parameter to be `&self`
|
LL | fn bar(self: &Self) {}
| ~~~~~
+error[E0307]: invalid `self` parameter type: ()
+ --> $DIR/object-unsafe-trait-should-use-where-sized.rs:6:18
+ |
+LL | fn bar(self: ()) {}
+ | ^^
+ |
+ = note: type of `self` must be `Self` or a type that dereferences to it
+ = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0038, E0307.
diff --git a/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.rs b/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.rs
index 288b2098b4c..fd975aaaee4 100644
--- a/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.rs
+++ b/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.rs
@@ -1,4 +1,4 @@
-// known-bug
+// known-bug: #93008
// build-fail
// failure-status: 101
// compile-flags:--crate-type=lib -Zmir-opt-level=3
diff --git a/src/test/ui/traits/alias/issue-83613.stderr b/src/test/ui/traits/alias/issue-83613.stderr
index bbc240b6aec..b9d93160192 100644
--- a/src/test/ui/traits/alias/issue-83613.stderr
+++ b/src/test/ui/traits/alias/issue-83613.stderr
@@ -1,3 +1,11 @@
+error[E0119]: conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
+ --> $DIR/issue-83613.rs:10:1
+ |
+LL | impl<T: Send> AnotherTrait for T {}
+ | -------------------------------- first implementation here
+LL | impl AnotherTrait for OpaqueType {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType`
+
error: cannot implement trait on type alias impl trait
--> $DIR/issue-83613.rs:10:23
|
@@ -10,14 +18,6 @@ note: type alias impl trait defined here
LL | type OpaqueType = impl OpaqueTrait;
| ^^^^^^^^^^^^^^^^
-error[E0119]: conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
- --> $DIR/issue-83613.rs:10:1
- |
-LL | impl<T: Send> AnotherTrait for T {}
- | -------------------------------- first implementation here
-LL | impl AnotherTrait for OpaqueType {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType`
-
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/traits/issue-78372.rs b/src/test/ui/traits/issue-78372.rs
index 77a8c92c81c..92f9f4b467a 100644
--- a/src/test/ui/traits/issue-78372.rs
+++ b/src/test/ui/traits/issue-78372.rs
@@ -4,7 +4,6 @@ impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {} //~ ERROR cannot find type `U`
//~^ ERROR cannot find type `MISC` in this scope
//~| ERROR use of unstable library feature 'dispatch_from_dyn'
//~| ERROR the trait `DispatchFromDyn` may only be implemented for a coercion between structures
-//~| ERROR type parameter `T` must be covered by another type when it appears before the first
trait Foo: X<u32> {}
trait X<T> {
fn foo(self: Smaht<Self, T>);
diff --git a/src/test/ui/traits/issue-78372.stderr b/src/test/ui/traits/issue-78372.stderr
index 49a9f479368..7574c9107d9 100644
--- a/src/test/ui/traits/issue-78372.stderr
+++ b/src/test/ui/traits/issue-78372.stderr
@@ -50,22 +50,13 @@ LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
|
= help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable
-error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Smaht<[type error], [type error]>`)
- --> $DIR/issue-78372.rs:3:6
- |
-LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
- | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Smaht<[type error], [type error]>`)
- |
- = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
- = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
-
error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
--> $DIR/issue-78372.rs:3:1
|
LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: aborting due to 7 previous errors
+error: aborting due to 6 previous errors
-Some errors have detailed explanations: E0210, E0378, E0412, E0658.
-For more information about an error, try `rustc --explain E0210`.
+Some errors have detailed explanations: E0378, E0412, E0658.
+For more information about an error, try `rustc --explain E0378`.
diff --git a/src/test/ui/traits/issue-8153.stderr b/src/test/ui/traits/issue-8153.stderr
index 4389c3dc288..b76bbc0235f 100644
--- a/src/test/ui/traits/issue-8153.stderr
+++ b/src/test/ui/traits/issue-8153.stderr
@@ -2,9 +2,9 @@ error[E0201]: duplicate definitions with name `bar`:
--> $DIR/issue-8153.rs:11:5
|
LL | fn bar(&self) -> isize {1}
- | -------------------------- previous definition of `bar` here
+ | ---------------------- previous definition of `bar` here
LL | fn bar(&self) -> isize {2}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definition
+ | ^^^^^^^^^^^^^^^^^^^^^^ duplicate definition
error: aborting due to previous error
diff --git a/src/test/ui/traits/issue-87558.rs b/src/test/ui/traits/issue-87558.rs
new file mode 100644
index 00000000000..c5d86bd637b
--- /dev/null
+++ b/src/test/ui/traits/issue-87558.rs
@@ -0,0 +1,9 @@
+struct ErrorKind;
+struct Error(ErrorKind);
+impl Fn(&isize) for Error {
+ //~^ ERROR manual implementations of `Fn` are experimental
+ //~| ERROR associated type bindings are not allowed here
+ fn from() {} //~ ERROR method `from` is not a member of trait `Fn`
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/issue-87558.stderr b/src/test/ui/traits/issue-87558.stderr
new file mode 100644
index 00000000000..494274d8c30
--- /dev/null
+++ b/src/test/ui/traits/issue-87558.stderr
@@ -0,0 +1,24 @@
+error[E0407]: method `from` is not a member of trait `Fn`
+ --> $DIR/issue-87558.rs:6:5
+ |
+LL | fn from() {}
+ | ^^^^^^^^^^^^ not a member of trait `Fn`
+
+error[E0183]: manual implementations of `Fn` are experimental
+ --> $DIR/issue-87558.rs:3:6
+ |
+LL | impl Fn(&isize) for Error {
+ | ^^^^^^^^^^ manual implementations of `Fn` are experimental
+ |
+ = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
+
+error[E0229]: associated type bindings are not allowed here
+ --> $DIR/issue-87558.rs:3:6
+ |
+LL | impl Fn(&isize) for Error {
+ | ^^^^^^^^^^ associated type not allowed here
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0183, E0229, E0407.
+For more information about an error, try `rustc --explain E0183`.
diff --git a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs
index 179f525de52..328096d44b4 100644
--- a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs
+++ b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs
@@ -1,4 +1,4 @@
-// known-bug
+// known-bug: #96572
// compile-flags: --edition=2021 --crate-type=lib
// rustc-env:RUST_BACKTRACE=0
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
index 9c4e6c5496f..067ed7ea1e5 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
@@ -1,7 +1,7 @@
// Regression test for issue #57611
// Ensures that we don't ICE
// FIXME: This should compile, but it currently doesn't
-// known-bug
+// known-bug: unknown
#![feature(trait_alias)]
#![feature(type_alias_impl_trait)]
diff --git a/src/test/ui/union/issue-81199.stderr b/src/test/ui/union/issue-81199.stderr
index f26bfe3a0b0..5bb98675361 100644
--- a/src/test/ui/union/issue-81199.stderr
+++ b/src/test/ui/union/issue-81199.stderr
@@ -1,28 +1,18 @@
-error[E0277]: the trait bound `T: Pointee` is not satisfied in `PtrComponents<T>`
+error[E0277]: the trait bound `T: Pointee` is not satisfied
--> $DIR/issue-81199.rs:5:17
|
LL | components: PtrComponents<T>,
- | ^^^^^^^^^^^^^^^^ within `PtrComponents<T>`, the trait `Pointee` is not implemented for `T`
+ | ^^^^^^^^^^^^^^^^ the trait `Pointee` is not implemented for `T`
|
-note: required because it appears within the type `PtrComponents<T>`
- --> $DIR/issue-81199.rs:10:8
+note: required by a bound in `PtrComponents`
+ --> $DIR/issue-81199.rs:10:25
|
LL | struct PtrComponents<T: Pointee + ?Sized> {
- | ^^^^^^^^^^^^^
- = note: no field of a union may have a dynamically sized type
- = help: change the field's type to have a statically known size
+ | ^^^^^^^ required by this bound in `PtrComponents`
help: consider further restricting this bound
|
LL | union PtrRepr<T: ?Sized + Pointee> {
| +++++++++
-help: borrowed types always have a statically known size
- |
-LL | components: &PtrComponents<T>,
- | +
-help: the `Box` type always has a statically known size and allocates its contents in the heap
- |
-LL | components: Box<PtrComponents<T>>,
- | ++++ +
error: aborting due to previous error
diff --git a/src/test/ui/wf/issue-96810.rs b/src/test/ui/wf/issue-96810.rs
new file mode 100644
index 00000000000..c2948086b20
--- /dev/null
+++ b/src/test/ui/wf/issue-96810.rs
@@ -0,0 +1,12 @@
+struct S<T: Tr>(T::Assoc);
+
+trait Tr {
+ type Assoc;
+}
+
+struct Hoge<K> {
+ s: S<K>, //~ ERROR the trait bound `K: Tr` is not satisfied
+ a: u32,
+}
+
+fn main() {}
diff --git a/src/test/ui/wf/issue-96810.stderr b/src/test/ui/wf/issue-96810.stderr
new file mode 100644
index 00000000000..1407e62b1e1
--- /dev/null
+++ b/src/test/ui/wf/issue-96810.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `K: Tr` is not satisfied
+ --> $DIR/issue-96810.rs:8:8
+ |
+LL | s: S<K>,
+ | ^^^^ the trait `Tr` is not implemented for `K`
+ |
+note: required by a bound in `S`
+ --> $DIR/issue-96810.rs:1:13
+ |
+LL | struct S<T: Tr>(T::Assoc);
+ | ^^ required by this bound in `S`
+help: consider restricting type parameter `K`
+ |
+LL | struct Hoge<K: Tr> {
+ | ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs b/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
index f447940ea3b..8ae84dbb3dc 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
@@ -1,4 +1,4 @@
-use clippy_utils::diagnostics::span_lint_and_sugg_for_edges;
+use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_trait_method;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_type_diagnostic_item;
@@ -14,17 +14,14 @@ use super::MAP_FLATTEN;
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, map_arg: &Expr<'_>, map_span: Span) {
if let Some((caller_ty_name, method_to_use)) = try_get_caller_ty_name_and_method_name(cx, expr, recv, map_arg) {
let mut applicability = Applicability::MachineApplicable;
- let help_msgs = [
- &format!("try replacing `map` with `{}`", method_to_use),
- "and remove the `.flatten()`",
- ];
+
let closure_snippet = snippet_with_applicability(cx, map_arg.span, "..", &mut applicability);
- span_lint_and_sugg_for_edges(
+ span_lint_and_sugg(
cx,
MAP_FLATTEN,
expr.span.with_lo(map_span.lo()),
&format!("called `map(..).flatten()` on `{}`", caller_ty_name),
- &help_msgs,
+ &format!("try replacing `map` with `{}` and remove the `.flatten()`", method_to_use),
format!("{}({})", method_to_use, closure_snippet),
applicability,
);
diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
index 448dc4e6147..3d1208824fa 100644
--- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
@@ -4,7 +4,6 @@ use clippy_utils::source::{snippet, snippet_with_applicability, snippet_with_mac
use clippy_utils::ty::{implements_trait, match_type};
use clippy_utils::{contains_return, is_trait_item, last_path_segment, paths};
use if_chain::if_chain;
-use rustc_errors::emitter::MAX_SUGGESTION_HIGHLIGHT_LINES;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
@@ -33,7 +32,6 @@ pub(super) fn check<'tcx>(
arg: &hir::Expr<'_>,
or_has_args: bool,
span: Span,
- method_span: Span,
) -> bool {
let is_default_default = || is_trait_item(cx, fun, sym::Default);
@@ -56,19 +54,14 @@ pub(super) fn check<'tcx>(
then {
let mut applicability = Applicability::MachineApplicable;
let hint = "unwrap_or_default()";
- let mut sugg_span = span;
+ let sugg_span = span;
- let mut sugg: String = format!(
+ let sugg: String = format!(
"{}.{}",
snippet_with_applicability(cx, self_expr.span, "..", &mut applicability),
hint
);
- if sugg.lines().count() > MAX_SUGGESTION_HIGHLIGHT_LINES {
- sugg_span = method_span.with_hi(span.hi());
- sugg = hint.to_string();
- }
-
span_lint_and_sugg(
cx,
OR_FUN_CALL,
@@ -178,7 +171,7 @@ pub(super) fn check<'tcx>(
match inner_arg.kind {
hir::ExprKind::Call(fun, or_args) => {
let or_has_args = !or_args.is_empty();
- if !check_unwrap_or_default(cx, name, fun, self_arg, arg, or_has_args, expr.span, method_span) {
+ if !check_unwrap_or_default(cx, name, fun, self_arg, arg, or_has_args, expr.span) {
let fun_span = if or_has_args { None } else { Some(fun.span) };
check_general_case(cx, name, method_span, self_arg, arg, expr.span, fun_span);
}
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
index 99e9e3275ab..2564099f4db 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
@@ -112,7 +112,6 @@ const LINT_EMISSION_FUNCTIONS: [&[&str]; 8] = [
&["clippy_utils", "diagnostics", "span_lint_and_sugg"],
&["clippy_utils", "diagnostics", "span_lint_and_then"],
&["clippy_utils", "diagnostics", "span_lint_hir_and_then"],
- &["clippy_utils", "diagnostics", "span_lint_and_sugg_for_edges"],
];
const SUGGESTION_DIAGNOSTIC_BUILDER_METHODS: [(&str, bool); 9] = [
("span_suggestion", false),
diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs
index 39595f589c7..7f55db3b31f 100644
--- a/src/tools/clippy/clippy_utils/src/diagnostics.rs
+++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs
@@ -8,7 +8,7 @@
//! Thank you!
//! ~The `INTERNAL_METADATA_COLLECTOR` lint
-use rustc_errors::{emitter::MAX_SUGGESTION_HIGHLIGHT_LINES, Applicability, Diagnostic, MultiSpan};
+use rustc_errors::{Applicability, Diagnostic, MultiSpan};
use rustc_hir::HirId;
use rustc_lint::{LateContext, Lint, LintContext};
use rustc_span::source_map::Span;
@@ -219,95 +219,6 @@ pub fn span_lint_and_sugg<'a, T: LintContext>(
});
}
-/// Like [`span_lint_and_sugg`] with a focus on the edges. The output will either
-/// emit single span or multispan suggestion depending on the number of its lines.
-///
-/// If the given suggestion string has more lines than the maximum display length defined by
-/// [`MAX_SUGGESTION_HIGHLIGHT_LINES`][`rustc_errors::emitter::MAX_SUGGESTION_HIGHLIGHT_LINES`],
-/// this function will split the suggestion and span to showcase the change for the top and
-/// bottom edge of the code. For normal suggestions, in one display window, the help message
-/// will be combined with a colon.
-///
-/// Multipart suggestions like the one being created here currently cannot be
-/// applied by rustfix (See [rustfix#141](https://github.com/rust-lang/rustfix/issues/141)).
-/// Testing rustfix with this lint emission function might require a file with
-/// suggestions that can be fixed and those that can't. See
-/// [clippy#8520](https://github.com/rust-lang/rust-clippy/pull/8520/files) for
-/// an example and of this.
-///
-/// # Example for a long suggestion
-///
-/// ```text
-/// error: called `map(..).flatten()` on `Option`
-/// --> $DIR/map_flatten.rs:8:10
-/// |
-/// LL | .map(|x| {
-/// | __________^
-/// LL | | if x <= 5 {
-/// LL | | Some(x)
-/// LL | | } else {
-/// ... |
-/// LL | | })
-/// LL | | .flatten();
-/// | |__________________^
-/// |
-/// = note: `-D clippy::map-flatten` implied by `-D warnings`
-/// help: try replacing `map` with `and_then`
-/// |
-/// LL ~ .and_then(|x| {
-/// LL + if x <= 5 {
-/// LL + Some(x)
-/// |
-/// help: and remove the `.flatten()`
-/// |
-/// LL + None
-/// LL + }
-/// LL ~ });
-/// |
-/// ```
-pub fn span_lint_and_sugg_for_edges(
- cx: &LateContext<'_>,
- lint: &'static Lint,
- sp: Span,
- msg: &str,
- helps: &[&str; 2],
- sugg: String,
- applicability: Applicability,
-) {
- span_lint_and_then(cx, lint, sp, msg, |diag| {
- let sugg_lines_count = sugg.lines().count();
- if sugg_lines_count > MAX_SUGGESTION_HIGHLIGHT_LINES {
- let sm = cx.sess().source_map();
- if let (Ok(line_upper), Ok(line_bottom)) =
- (sm.lookup_line(sp.lo()), sm.lookup_line(sp.hi()))
- {
- let split_idx = MAX_SUGGESTION_HIGHLIGHT_LINES / 2;
- let span_upper = sm.span_until_char(
- sp.with_hi(line_upper.sf.lines(|lines| lines[line_upper.line + split_idx])),
- '\n',
- );
- let span_bottom = sp.with_lo(line_bottom.sf.lines(|lines| lines[line_bottom.line - split_idx]));
-
- let sugg_lines_vec = sugg.lines().collect::<Vec<&str>>();
- let sugg_upper = sugg_lines_vec[..split_idx].join("\n");
- let sugg_bottom = sugg_lines_vec[sugg_lines_count - split_idx..].join("\n");
-
- diag.span_suggestion(span_upper, helps[0], sugg_upper, applicability);
- diag.span_suggestion(span_bottom, helps[1], sugg_bottom, applicability);
-
- return;
- }
- }
- diag.span_suggestion_with_style(
- sp,
- &helps.join(", "),
- sugg,
- applicability,
- rustc_errors::SuggestionStyle::ShowAlways,
- );
- });
-}
-
/// Create a suggestion made from several `span → replacement`.
///
/// Note: in the JSON format (used by `compiletest_rs`), the help message will
diff --git a/src/tools/clippy/tests/ui/map_flatten.stderr b/src/tools/clippy/tests/ui/map_flatten.stderr
index c9c60df838f..4b2630d6858 100644
--- a/src/tools/clippy/tests/ui/map_flatten.stderr
+++ b/src/tools/clippy/tests/ui/map_flatten.stderr
@@ -12,14 +12,12 @@ LL | | .flatten();
| |__________________^
|
= note: `-D clippy::map-flatten` implied by `-D warnings`
-help: try replacing `map` with `and_then`
+help: try replacing `map` with `and_then` and remove the `.flatten()`
|
LL ~ .and_then(|x| {
LL + if x <= 5 {
LL + Some(x)
- |
-help: and remove the `.flatten()`
- |
+LL + } else {
LL + None
LL + }
LL ~ });
@@ -38,14 +36,12 @@ LL | | })
LL | | .flatten();
| |__________________^
|
-help: try replacing `map` with `and_then`
+help: try replacing `map` with `and_then` and remove the `.flatten()`
|
LL ~ .and_then(|x| {
LL + if x == 1 {
LL + Ok(x)
- |
-help: and remove the `.flatten()`
- |
+LL + } else {
LL + Err(0)
LL + }
LL ~ });
@@ -64,14 +60,13 @@ LL | | })
LL | | .flatten();
| |__________________^
|
-help: try replacing `map` with `and_then`
+help: try replacing `map` with `and_then` and remove the `.flatten()`
|
LL ~ .and_then(|res| {
LL + if res > 0 {
LL + do_something();
- |
-help: and remove the `.flatten()`
- |
+LL + Ok(res)
+LL + } else {
LL + Err(0)
LL + }
LL ~ });
@@ -90,14 +85,12 @@ LL | | })
LL | | .flatten()
| |__________________^
|
-help: try replacing `map` with `filter_map`
+help: try replacing `map` with `filter_map` and remove the `.flatten()`
|
LL ~ .filter_map(|some_value| {
LL + if some_value > 3 {
LL + Some(some_value)
- |
-help: and remove the `.flatten()`
- |
+LL + } else {
LL + None
LL + }
LL + })
diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.fixed b/src/tools/clippy/tests/ui/map_flatten_fixable.fixed
index 928e5bd509c..e9b41354c58 100644
--- a/src/tools/clippy/tests/ui/map_flatten_fixable.fixed
+++ b/src/tools/clippy/tests/ui/map_flatten_fixable.fixed
@@ -59,8 +59,6 @@ fn issue8878() {
.and_then(|_| {
// we need some newlines
// so that the span is big enough
-// we need some newlines
-// so that the span is big enough
// for a splitted output of the diagnostic
Some("")
// whitespace beforehand is important as well
diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.stderr b/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
index 828e24acaad..f3b82ad08d0 100644
--- a/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
+++ b/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
@@ -2,79 +2,45 @@ error: called `map(..).flatten()` on `Iterator`
--> $DIR/map_flatten_fixable.rs:18:47
|
LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id).flatten().collect();
- | ^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id)`
|
= note: `-D clippy::map-flatten` implied by `-D warnings`
-help: try replacing `map` with `filter_map`, and remove the `.flatten()`
- |
-LL | let _: Vec<_> = vec![5_i8; 6].into_iter().filter_map(option_id).collect();
- | ~~~~~~~~~~~~~~~~~~~~~
error: called `map(..).flatten()` on `Iterator`
--> $DIR/map_flatten_fixable.rs:19:47
|
LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_ref).flatten().collect();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-help: try replacing `map` with `filter_map`, and remove the `.flatten()`
- |
-LL | let _: Vec<_> = vec![5_i8; 6].into_iter().filter_map(option_id_ref).collect();
- | ~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id_ref)`
error: called `map(..).flatten()` on `Iterator`
--> $DIR/map_flatten_fixable.rs:20:47
|
LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_closure).flatten().collect();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-help: try replacing `map` with `filter_map`, and remove the `.flatten()`
- |
-LL | let _: Vec<_> = vec![5_i8; 6].into_iter().filter_map(option_id_closure).collect();
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id_closure)`
error: called `map(..).flatten()` on `Iterator`
--> $DIR/map_flatten_fixable.rs:21:47
|
LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| x.checked_add(1)).flatten().collect();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-help: try replacing `map` with `filter_map`, and remove the `.flatten()`
- |
-LL | let _: Vec<_> = vec![5_i8; 6].into_iter().filter_map(|x| x.checked_add(1)).collect();
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(|x| x.checked_add(1))`
error: called `map(..).flatten()` on `Iterator`
--> $DIR/map_flatten_fixable.rs:24:47
|
LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect();
- | ^^^^^^^^^^^^^^^^^^^^^^^
- |
-help: try replacing `map` with `flat_map`, and remove the `.flatten()`
- |
-LL | let _: Vec<_> = vec![5_i8; 6].into_iter().flat_map(|x| 0..x).collect();
- | ~~~~~~~~~~~~~~~~~~
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `flat_map` and remove the `.flatten()`: `flat_map(|x| 0..x)`
error: called `map(..).flatten()` on `Option`
--> $DIR/map_flatten_fixable.rs:27:40
|
LL | let _: Option<_> = (Some(Some(1))).map(|x| x).flatten();
- | ^^^^^^^^^^^^^^^^^^^^
- |
-help: try replacing `map` with `and_then`, and remove the `.flatten()`
- |
-LL | let _: Option<_> = (Some(Some(1))).and_then(|x| x);
- | ~~~~~~~~~~~~~~~
+ | ^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `and_then` and remove the `.flatten()`: `and_then(|x| x)`
error: called `map(..).flatten()` on `Result`
--> $DIR/map_flatten_fixable.rs:30:42
|
LL | let _: Result<_, &str> = (Ok(Ok(1))).map(|x| x).flatten();
- | ^^^^^^^^^^^^^^^^^^^^
- |
-help: try replacing `map` with `and_then`, and remove the `.flatten()`
- |
-LL | let _: Result<_, &str> = (Ok(Ok(1))).and_then(|x| x);
- | ~~~~~~~~~~~~~~~
+ | ^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `and_then` and remove the `.flatten()`: `and_then(|x| x)`
error: called `map(..).flatten()` on `Option`
--> $DIR/map_flatten_fixable.rs:59:10
@@ -89,14 +55,12 @@ LL | | })
LL | | .flatten();
| |__________________^
|
-help: try replacing `map` with `and_then`
+help: try replacing `map` with `and_then` and remove the `.flatten()`
|
LL ~ .and_then(|_| {
LL + // we need some newlines
LL + // so that the span is big enough
- |
-help: and remove the `.flatten()`
- |
+LL + // for a splitted output of the diagnostic
LL + Some("")
LL + // whitespace beforehand is important as well
LL ~ });
diff --git a/src/tools/clippy/tests/ui/or_fun_call.fixed b/src/tools/clippy/tests/ui/or_fun_call.fixed
index 3208048e0d5..123aed40251 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.fixed
+++ b/src/tools/clippy/tests/ui/or_fun_call.fixed
@@ -185,8 +185,7 @@ mod issue8239 {
.reduce(|mut acc, f| {
acc.push_str(&f);
acc
- })
- .unwrap_or_default();
+ }).unwrap_or_default();
}
fn more_to_max_suggestion_highest_lines_1() {
@@ -198,8 +197,7 @@ mod issue8239 {
let _ = "";
acc.push_str(&f);
acc
- })
- .unwrap_or_default();
+ }).unwrap_or_default();
}
fn equal_to_max_suggestion_highest_lines() {
diff --git a/src/tools/clippy/tests/ui/or_fun_call.stderr b/src/tools/clippy/tests/ui/or_fun_call.stderr
index 549b00ae3c4..dfe15654bc3 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.stderr
+++ b/src/tools/clippy/tests/ui/or_fun_call.stderr
@@ -109,16 +109,50 @@ LL | None.unwrap_or( unsafe { ptr_to_ref(s) } );
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })`
error: use of `unwrap_or` followed by a call to `new`
- --> $DIR/or_fun_call.rs:189:14
+ --> $DIR/or_fun_call.rs:182:9
+ |
+LL | / frames
+LL | | .iter()
+LL | | .map(|f: &String| f.to_lowercase())
+LL | | .reduce(|mut acc, f| {
+... |
+LL | | })
+LL | | .unwrap_or(String::new());
+ | |_____________________________________^
+ |
+help: try this
+ |
+LL ~ frames
+LL + .iter()
+LL + .map(|f: &String| f.to_lowercase())
+LL + .reduce(|mut acc, f| {
+LL + acc.push_str(&f);
+LL + acc
+LL ~ }).unwrap_or_default();
|
-LL | .unwrap_or(String::new());
- | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()`
error: use of `unwrap_or` followed by a call to `new`
- --> $DIR/or_fun_call.rs:202:14
+ --> $DIR/or_fun_call.rs:195:9
+ |
+LL | / iter.map(|f: &String| f.to_lowercase())
+LL | | .reduce(|mut acc, f| {
+LL | | let _ = "";
+LL | | let _ = "";
+... |
+LL | | })
+LL | | .unwrap_or(String::new());
+ | |_____________________________________^
+ |
+help: try this
+ |
+LL ~ iter.map(|f: &String| f.to_lowercase())
+LL + .reduce(|mut acc, f| {
+LL + let _ = "";
+LL + let _ = "";
+LL + acc.push_str(&f);
+LL + acc
+LL ~ }).unwrap_or_default();
|
-LL | .unwrap_or(String::new());
- | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()`
error: use of `unwrap_or` followed by a call to `new`
--> $DIR/or_fun_call.rs:208:9
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 5352f7c6fe0..31e979a574b 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -395,7 +395,29 @@ impl TestProps {
);
config.set_name_directive(ln, STDERR_PER_BITWIDTH, &mut self.stderr_per_bitwidth);
config.set_name_directive(ln, INCREMENTAL, &mut self.incremental);
- config.set_name_directive(ln, KNOWN_BUG, &mut self.known_bug);
+
+ // Unlike the other `name_value_directive`s this needs to be handled manually,
+ // because it sets a `bool` flag.
+ if let Some(known_bug) = config.parse_name_value_directive(ln, KNOWN_BUG) {
+ let known_bug = known_bug.trim();
+ if known_bug == "unknown"
+ || known_bug.split(',').all(|issue_ref| {
+ issue_ref
+ .trim()
+ .split_once('#')
+ .filter(|(_, number)| {
+ number.chars().all(|digit| digit.is_numeric())
+ })
+ .is_some()
+ })
+ {
+ self.known_bug = true;
+ } else {
+ panic!(
+ "Invalid known-bug value: {known_bug}\nIt requires comma-separated issue references (`#000` or `chalk#000`) or `unknown`."
+ );
+ }
+ }
config.set_name_value_directive(ln, MIR_UNIT_TEST, &mut self.mir_unit_test, |s| {
s.trim().to_string()
});
diff --git a/src/tools/miri b/src/tools/miri
-Subproject 655eed35b7ca7cae08f21ead6151b9dfb69794f
+Subproject 9e2dac4787e5470ecd9e245420e8da9528620ed
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 04a1d257bc0..fe5195738c1 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -30,7 +30,7 @@ except ImportError:
# These should be collaborators of the rust-lang/rust repository (with at least
# read privileges on it). CI will fail otherwise.
MAINTAINERS = {
- 'miri': {'oli-obk', 'RalfJung', 'eddyb'},
+ 'miri': {'oli-obk', 'RalfJung'},
'rls': {'Xanewok'},
'rustfmt': {'topecongiro', 'calebcartwright'},
'book': {'carols10cents', 'steveklabnik'},
diff --git a/triagebot.toml b/triagebot.toml
index cef78cc3b33..8aefb1f620b 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -215,3 +215,108 @@ changelog-path = "RELEASES.md"
changelog-branch = "master"
[shortcut]
+
+
+[mentions."compiler/rustc_apfloat"]
+message = """
+Changes rustc_apfloat. rustc_apfloat is currently in limbo and you almost
+certainly don't want to change it (see #55993).
+"""
+cc = ["@eddyb"]
+
+[mentions."compiler/rustc_codegen_cranelift"]
+cc = ["@bjorn3"]
+
+[mentions."compiler/rustc_codegen_gcc"]
+cc = ["@antoyo"]
+
+[mentions."compiler/rustc_const_eval/src/interpret"]
+message = "Some changes occurred to the CTFE / Miri engine"
+cc = ["@rust-lang/miri"]
+
+[mentions."compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs"]
+message = "Some changes occurred in need_type_info.rs"
+cc = ["@lcnr"]
+
+[mentions."compiler/rustc_middle/src/mir/interpret"]
+message = "Some changes occurred to the CTFE / Miri engine"
+cc = ["@rust-lang/miri"]
+
+[mentions."compiler/rustc_mir_transform/src/"]
+message = "Some changes occurred to MIR optimizations"
+cc = ["@rust-lang/mir-opt"]
+
+[mentions."compiler/rustc_trait_selection/src/traits/const_evaluatable.rs"]
+message = "Some changes occurred in const_evaluatable.rs"
+cc = ["@lcnr"]
+
+[mentions."compiler/rustc_error_codes/src/error_codes.rs"]
+message = "Some changes occurred in diagnostic error codes"
+cc = ["@GuillaumeGomez"]
+
+[mentions."library"]
+message = """
+Hey! It looks like you've submitted a new PR for the library teams!
+
+If this PR contains changes to any `rust-lang/rust` public library APIs then
+please comment with `@rustbot label +T-libs-api -T-libs` to tag it
+appropriately. If this PR contains changes to any unstable APIs please edit
+the PR description to add a link to the relevant [API Change
+Proposal](https://std-dev-guide.rust-lang.org/feature-lifecycle/api-change-proposals.html)
+or [create one](https://github.com/rust-lang/libs-team/issues/new?assignees=&labels=api-change-proposal%2C+T-libs-api&template=api-change-proposal.md&title=%28My+API+Change+Proposal%29)
+if you haven't already. If you're unsure where your change falls no worries,
+just leave it as is and the reviewer will take a look and make a decision to
+forward on if necessary.
+
+Examples of `T-libs-api` changes:
+
+* Stabilizing library features
+* Introducing insta-stable changes such as new implementations of existing
+ stable traits on existing stable types
+* Introducing new or changing existing unstable library APIs (excluding
+ permanently unstable features / features without a tracking issue)
+* Changing public documentation in ways that create new stability guarantees
+* Changing observable runtime behavior of library APIs
+"""
+
+[mentions."src/librustdoc/clean/types.rs"]
+cc = ["@camelid"]
+
+[mentions."src/librustdoc/html/static"]
+message = "Some changes occurred in HTML/CSS/JS."
+cc = [
+ "@GuillaumeGomez",
+ "@Folyd",
+ "@jsha",
+]
+
+[mentions."src/librustdoc/html/static/css/themes"]
+message = "Some changes occurred in HTML/CSS themes."
+cc = ["@GuillaumeGomez"]
+
+[mentions."src/librustdoc/html/static/css/themes/ayu.css"]
+message = "A change occurred in the Ayu theme."
+cc = ["@Cldfire"]
+
+[mentions."src/rustdoc-json-types"]
+message = """
+rustdoc-json-types is a **public** (although nightly-only) API.
+If possible, consider changing `src/librustdoc/json/conversions.rs`;
+otherwise, make sure you bump the `FORMAT_VERSION` constant.
+"""
+cc = [
+ "@CraftSpider",
+ "@aDotInTheVoid",
+]
+
+[mentions."src/tools/cargo"]
+cc = ["@ehuss"]
+
+[mentions."src/tools/clippy"]
+cc = ["@rust-lang/clippy"]
+
+[mentions."src/tools/miri"]
+cc = ["@rust-lang/miri"]
+
+[mentions."src/tools/rustfmt"]
+cc = ["@rust-lang/rustfmt"]